Guest User

Muphen64 pure_interp.c hack to backtrace

a guest
Dec 24th, 2015
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 79.50 KB | None | 0 0
  1. ELABORATION: From 64.vg. Credit for marshall/zzt32 for this modification
  2.  
  3. Every good programmer knows that an essential debugging facility is the good ol' backtrace. Release builds of N64 games do not preserve the stack pointer in a way that makes backtracing possible - at least not from within the software.
  4.  
  5. Thus, I have modified the pure interpreter core of Mupen64plus to keep track of which functions are called, when they return, and most importantly: to which thread they belong.
  6.  
  7. Since this code is so game-specific, it will only work with the debugger's build of Master Quest. Yes, the name might lead you to believe that it has backtracing facilities built-in, but unfortunately it does not. Modify the 'watch' variable on line 58 to the address of the function you wish to monitor. Boot up the game with the pure interpreter core (--emumode 0), and when the function is called a backtrace will be printed in your terminal. Thereafter, press enter to continue running the game.
  8.  
  9.  
  10.  
  11. It does help give you some much needed perspective over how the game works internally. "SRC" indicates where in the parent function the child was called, "ARG" is a dump of the four argument registers.
  12.  
  13. =========================================================================================================================
  14.  
  15. SOURCE:
  16.  
  17. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  18. * Mupen64plus - pure_interp.c *
  19. * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
  20. * Copyright (C) 2002 Hacktarux *
  21. * *
  22. * This program is free software; you can redistribute it and/or modify *
  23. * it under the terms of the GNU General Public License as published by *
  24. * the Free Software Foundation; either version 2 of the License, or *
  25. * (at your option) any later version. *
  26. * *
  27. * This program is distributed in the hope that it will be useful, *
  28. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  29. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  30. * GNU General Public License for more details. *
  31. * *
  32. * You should have received a copy of the GNU General Public License *
  33. * along with this program; if not, write to the *
  34. * Free Software Foundation, Inc., *
  35. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
  36. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  37.  
  38. #include <stdlib.h>
  39. #include <math.h>
  40. #include <stdio.h>
  41. #include <stdint.h>
  42.  
  43. #include "api/m64p_types.h"
  44. #include "api/callbacks.h"
  45. #include "api/debugger.h"
  46. #include "memory/memory.h"
  47. #include "main/rom.h"
  48. #include "osal/preproc.h"
  49.  
  50. #include "r4300.h"
  51. #include "exception.h"
  52. #include "macros.h"
  53. #include "interupt.h"
  54.  
  55. #ifdef DBG
  56. #include "debugger/dbg_types.h"
  57. #include "debugger/debugger.h"
  58. #endif
  59.  
  60. #define check_r0_rd() { if (PC->f.r.rd == reg) { interp_addr+=4; return; } }
  61. #define check_r0_rt() { if (PC->f.r.rt == reg) { interp_addr+=4; return; } }
  62. #define check_r0_irt() { if (PC->f.i.rt == reg) { interp_addr+=4; return; } }
  63.  
  64. unsigned int interp_addr;
  65. unsigned int op;
  66. static int skip;
  67.  
  68. void prefetch(void);
  69.  
  70. extern void (*interp_ops[64])(void);
  71.  
  72. extern unsigned int next_vi;
  73.  
  74. static const unsigned watch = 0x800FC2C0UL;
  75.  
  76. static unsigned tp = 0x0000AD50;
  77.  
  78.  
  79. struct thread_strace_t
  80. {
  81. uint32_t trace[1024];
  82. uint32_t from[1024];
  83. uint32_t reta[1024];
  84. uint32_t args[1024][4];
  85. int count;
  86. }
  87. tracers[64];
  88.  
  89.  
  90. static void error ( void )
  91. {
  92. uint32_t a;
  93.  
  94. a = rdram[tp / 4];
  95.  
  96. printf(
  97. "0x%08X -> 0x%08X\n",
  98. (unsigned int)a,
  99. rdram[(a & 0x00FFFFFF) / 4 + 0x14/4]
  100. );
  101. fflush( stdout );
  102. }
  103.  
  104. void
  105. push_function ( int thread, uint32_t addr, uint32_t from )
  106. {
  107. if( tracers[thread].count > 1024 )
  108. {
  109. printf( "Stack overflow.\n" );
  110. error();
  111. abort();
  112. }
  113.  
  114. tracers[thread].trace[tracers[thread].count] = addr;
  115. tracers[thread].from[tracers[thread].count] = from;
  116. tracers[thread].args[tracers[thread].count][0] = (uint32_t)reg[4];
  117. tracers[thread].args[tracers[thread].count][1] = (uint32_t)reg[5];
  118. tracers[thread].args[tracers[thread].count][2] = (uint32_t)reg[6];
  119. tracers[thread].args[tracers[thread].count][3] = (uint32_t)reg[7];
  120. tracers[thread].count++;
  121. }
  122.  
  123.  
  124. static void stack_trace ( void );
  125.  
  126.  
  127. uint32_t
  128. pop_function ( int thread, uint32_t from )
  129. {
  130. if( tracers[thread].count == 0 )
  131. {
  132. /*printf( "Negative function call stack!\n" );
  133. error();
  134. stack_trace();
  135. abort();*/
  136. return 0;
  137. }
  138.  
  139. tracers[thread].reta[tracers[thread].count] = from;
  140.  
  141. return tracers[thread].trace[--tracers[thread].count];
  142. }
  143.  
  144.  
  145. static void initstrace ( void )
  146. {
  147. static int initd;
  148. int i;
  149.  
  150. return;
  151.  
  152. if( !initd )
  153. initd = 1;
  154. else
  155. return;
  156.  
  157. for( i = 0; i < 64; i++ )
  158. tracers[i].count = 1;
  159. }
  160.  
  161.  
  162. static int _getcurthread ( void )
  163. {
  164. uint32_t * threadp, threadpp;
  165.  
  166. threadpp = rdram[(tp & 0x003FFFFF) / sizeof(int)];
  167.  
  168. if( !threadpp || threadpp == 0x8000AD40 )
  169. return -1;
  170.  
  171. threadp = (unsigned int*)&rdram[(threadpp & 0x003FFFFF) / sizeof(int)];
  172.  
  173. if( !threadp )
  174. return -1;
  175.  
  176. return *(threadp + (0x14 / 4));
  177. }
  178.  
  179. static int getcurthread ( void )
  180. {
  181. int thread;
  182.  
  183. initstrace();
  184.  
  185. thread = _getcurthread();
  186.  
  187. if( thread >= 64 )
  188. {
  189. printf( "Incorrect thread value obtained.\n0x%08X\n",
  190. (unsigned)rdram[(tp & 0x003FFFFF) / sizeof(int)] );
  191. error();
  192. fflush( stdout );
  193. getchar();
  194. exit( -1 );
  195. }
  196.  
  197. return thread;
  198. }
  199.  
  200.  
  201. static void note_call ( uint32_t pc, uint32_t dest )
  202. {
  203. int thread;
  204.  
  205. if( !(Status & 1) )
  206. return;
  207.  
  208. thread = getcurthread();
  209.  
  210. if( thread >= 0 )
  211. push_function( thread, dest, pc );
  212. }
  213.  
  214. static void note_return ( uint32_t pc )
  215. {
  216. int thread;
  217.  
  218. if( !(Status & 1) )
  219. return;
  220.  
  221. thread = getcurthread();
  222.  
  223. if( thread >= 0 )
  224. pop_function( thread, pc );
  225. }
  226.  
  227.  
  228. static void stack_trace ( void )
  229. {
  230. int thread, amount, i;
  231.  
  232. if( !(Status & 1) )
  233. return;
  234.  
  235. thread = getcurthread();
  236. amount = tracers[thread].count;
  237.  
  238. if( thread == -1 )
  239. printf( "Invalid thread.\n" );
  240. else
  241. {
  242. printf(
  243. "Stack trace for thread %i (0x%08X):\n",
  244. thread,
  245. (unsigned int)rdram[(tp & 0x003FFFFF) / sizeof(int)]
  246. );
  247.  
  248. for( i = amount - 1; i >= 0; i-- )
  249. printf(
  250. "#%02i 0x%08X SRC:0x%08X ARG:{0x%08X,0x%08X,0x%08X,0x%08X}\n",
  251. amount - i - 1,
  252. tracers[thread].trace[i],
  253. tracers[thread].from[i],
  254. tracers[thread].args[i][0],
  255. tracers[thread].args[i][1],
  256. tracers[thread].args[i][2],
  257. tracers[thread].args[i][3]
  258. );
  259.  
  260. fflush( stdout );
  261. getchar();
  262. }
  263. }
  264.  
  265.  
  266. static void NI(void)
  267. {
  268. DebugMessage(M64MSG_ERROR, "NI:%x", (unsigned int)op);
  269. stop=1;
  270. }
  271.  
  272. static void SLL(void)
  273. {
  274. check_r0_rd();
  275. rrd32 = (unsigned int)(rrt32) << rsa;
  276. sign_extended(rrd);
  277. interp_addr+=4;
  278. }
  279.  
  280. static void SRL(void)
  281. {
  282. check_r0_rd();
  283. rrd32 = (unsigned int)rrt32 >> rsa;
  284. sign_extended(rrd);
  285. interp_addr+=4;
  286. }
  287.  
  288. static void SRA(void)
  289. {
  290. check_r0_rd();
  291. rrd32 = (signed int)rrt32 >> rsa;
  292. sign_extended(rrd);
  293. interp_addr+=4;
  294. }
  295.  
  296. static void SLLV(void)
  297. {
  298. check_r0_rd();
  299. rrd32 = (unsigned int)(rrt32) << (rrs32&0x1F);
  300. sign_extended(rrd);
  301. interp_addr+=4;
  302. }
  303.  
  304. static void SRLV(void)
  305. {
  306. check_r0_rd();
  307. rrd32 = (unsigned int)rrt32 >> (rrs32 & 0x1F);
  308. sign_extended(rrd);
  309. interp_addr+=4;
  310. }
  311.  
  312. static void SRAV(void)
  313. {
  314. check_r0_rd();
  315. rrd32 = (signed int)rrt32 >> (rrs32 & 0x1F);
  316. sign_extended(rrd);
  317. interp_addr+=4;
  318. }
  319.  
  320. static void JR(void)
  321. {
  322. local_rs32 = irs32;
  323. if( ((op >> 21) & 0x3F) == 31 )
  324. note_return( interp_addr );
  325. interp_addr+=4;
  326. delay_slot=1;
  327. prefetch();
  328. interp_ops[((op >> 26) & 0x3F)]();
  329. update_count();
  330. delay_slot=0;
  331. interp_addr = local_rs32;
  332. last_addr = interp_addr;
  333. if (next_interupt <= Count) gen_interupt();
  334. }
  335.  
  336. static void JALR(void)
  337. {
  338. unsigned long long *dest = (unsigned long long *) PC->f.r.rd;
  339. local_rs32 = rrs32;
  340. interp_addr+=4;
  341. delay_slot=1;
  342.  
  343. prefetch();
  344. interp_ops[((op >> 26) & 0x3F)]();
  345. update_count();
  346. delay_slot=0;
  347.  
  348. if( ((op >> 11) & 0x3F) == 31 )
  349. note_call( interp_addr - 8, local_rs32 );
  350.  
  351. if (!skip_jump)
  352. {
  353. *dest = interp_addr;
  354. sign_extended(*dest);
  355.  
  356. interp_addr = local_rs32;
  357. }
  358. last_addr = interp_addr;
  359. if (next_interupt <= Count) gen_interupt();
  360. }
  361.  
  362. static void SYSCALL(void)
  363. {
  364. Cause = 8 << 2;
  365. exception_general();
  366. }
  367.  
  368. static void SYNC(void)
  369. {
  370. interp_addr+=4;
  371. }
  372.  
  373. static void MFHI(void)
  374. {
  375. check_r0_rd();
  376. rrd = hi;
  377. interp_addr+=4;
  378. }
  379.  
  380. static void MTHI(void)
  381. {
  382. hi = rrs;
  383. interp_addr+=4;
  384. }
  385.  
  386. static void MFLO(void)
  387. {
  388. check_r0_rd();
  389. rrd = lo;
  390. interp_addr+=4;
  391. }
  392.  
  393. static void MTLO(void)
  394. {
  395. lo = rrs;
  396. interp_addr+=4;
  397. }
  398.  
  399. static void DSLLV(void)
  400. {
  401. check_r0_rd();
  402. rrd = rrt << (rrs32&0x3F);
  403. interp_addr+=4;
  404. }
  405.  
  406. static void DSRLV(void)
  407. {
  408. check_r0_rd();
  409. rrd = (unsigned long long)rrt >> (rrs32 & 0x3F);
  410. interp_addr+=4;
  411. }
  412.  
  413. static void DSRAV(void)
  414. {
  415. check_r0_rd();
  416. rrd = (long long)rrt >> (rrs32 & 0x3F);
  417. interp_addr+=4;
  418. }
  419.  
  420. static void MULT(void)
  421. {
  422. long long int temp;
  423. temp = rrs * rrt;
  424. hi = temp >> 32;
  425. lo = temp;
  426. sign_extended(lo);
  427. interp_addr+=4;
  428. }
  429.  
  430. static void MULTU(void)
  431. {
  432. unsigned long long int temp;
  433. temp = (unsigned int)rrs * (unsigned long long)((unsigned int)rrt);
  434. hi = (long long)temp >> 32;
  435. lo = temp;
  436. sign_extended(lo);
  437. interp_addr+=4;
  438. }
  439.  
  440. static void DIV(void)
  441. {
  442. if (rrt32)
  443. {
  444. lo = rrs32 / rrt32;
  445. hi = rrs32 % rrt32;
  446. sign_extended(lo);
  447. sign_extended(hi);
  448. }
  449. else DebugMessage(M64MSG_ERROR, "DIV: divide by 0");
  450. interp_addr+=4;
  451. }
  452.  
  453. static void DIVU(void)
  454. {
  455. if (rrt32)
  456. {
  457. lo = (unsigned int)rrs32 / (unsigned int)rrt32;
  458. hi = (unsigned int)rrs32 % (unsigned int)rrt32;
  459. sign_extended(lo);
  460. sign_extended(hi);
  461. }
  462. else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0");
  463. interp_addr+=4;
  464. }
  465.  
  466. static void DMULT(void)
  467. {
  468. unsigned long long int op1, op2, op3, op4;
  469. unsigned long long int result1, result2, result3, result4;
  470. unsigned long long int temp1, temp2, temp3, temp4;
  471. int sign = 0;
  472.  
  473. if (rrs < 0)
  474. {
  475. op2 = -rrs;
  476. sign = 1 - sign;
  477. }
  478. else op2 = rrs;
  479. if (rrt < 0)
  480. {
  481. op4 = -rrt;
  482. sign = 1 - sign;
  483. }
  484. else op4 = rrt;
  485.  
  486. op1 = op2 & 0xFFFFFFFF;
  487. op2 = (op2 >> 32) & 0xFFFFFFFF;
  488. op3 = op4 & 0xFFFFFFFF;
  489. op4 = (op4 >> 32) & 0xFFFFFFFF;
  490.  
  491. temp1 = op1 * op3;
  492. temp2 = (temp1 >> 32) + op1 * op4;
  493. temp3 = op2 * op3;
  494. temp4 = (temp3 >> 32) + op2 * op4;
  495.  
  496. result1 = temp1 & 0xFFFFFFFF;
  497. result2 = temp2 + (temp3 & 0xFFFFFFFF);
  498. result3 = (result2 >> 32) + temp4;
  499. result4 = (result3 >> 32);
  500.  
  501. lo = result1 | (result2 << 32);
  502. hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
  503. if (sign)
  504. {
  505. hi = ~hi;
  506. if (!lo) hi++;
  507. else lo = ~lo + 1;
  508. }
  509. interp_addr+=4;
  510. }
  511.  
  512. static void DMULTU(void)
  513. {
  514. unsigned long long int op1, op2, op3, op4;
  515. unsigned long long int result1, result2, result3, result4;
  516. unsigned long long int temp1, temp2, temp3, temp4;
  517.  
  518. op1 = rrs & 0xFFFFFFFF;
  519. op2 = (rrs >> 32) & 0xFFFFFFFF;
  520. op3 = rrt & 0xFFFFFFFF;
  521. op4 = (rrt >> 32) & 0xFFFFFFFF;
  522.  
  523. temp1 = op1 * op3;
  524. temp2 = (temp1 >> 32) + op1 * op4;
  525. temp3 = op2 * op3;
  526. temp4 = (temp3 >> 32) + op2 * op4;
  527.  
  528. result1 = temp1 & 0xFFFFFFFF;
  529. result2 = temp2 + (temp3 & 0xFFFFFFFF);
  530. result3 = (result2 >> 32) + temp4;
  531. result4 = (result3 >> 32);
  532.  
  533. lo = result1 | (result2 << 32);
  534. hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
  535.  
  536. interp_addr+=4;
  537. }
  538.  
  539. static void DDIV(void)
  540. {
  541. if (rrt)
  542. {
  543. lo = (long long int)rrs / (long long int)rrt;
  544. hi = (long long int)rrs % (long long int)rrt;
  545. }
  546. else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0");
  547. interp_addr+=4;
  548. }
  549.  
  550. static void DDIVU(void)
  551. {
  552. if (rrt)
  553. {
  554. lo = (unsigned long long int)rrs / (unsigned long long int)rrt;
  555. hi = (unsigned long long int)rrs % (unsigned long long int)rrt;
  556. }
  557. else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0");
  558. interp_addr+=4;
  559. }
  560.  
  561. static void ADD(void)
  562. {
  563. check_r0_rd();
  564. rrd32 = rrs32 + rrt32;
  565. sign_extended(rrd);
  566. interp_addr+=4;
  567. }
  568.  
  569. static void ADDU(void)
  570. {
  571. check_r0_rd();
  572. rrd32 = rrs32 + rrt32;
  573. sign_extended(rrd);
  574. interp_addr+=4;
  575. }
  576.  
  577. static void SUB(void)
  578. {
  579. check_r0_rd();
  580. rrd32 = rrs32 - rrt32;
  581. sign_extended(rrd);
  582. interp_addr+=4;
  583. }
  584.  
  585. static void SUBU(void)
  586. {
  587. check_r0_rd();
  588. rrd32 = rrs32 - rrt32;
  589. sign_extended(rrd);
  590. interp_addr+=4;
  591. }
  592.  
  593. static void AND(void)
  594. {
  595. check_r0_rd();
  596. rrd = rrs & rrt;
  597. interp_addr+=4;
  598. }
  599.  
  600. static void OR(void)
  601. {
  602. check_r0_rd();
  603. rrd = rrs | rrt;
  604. interp_addr+=4;
  605. }
  606.  
  607. static void XOR(void)
  608. {
  609. check_r0_rd();
  610. rrd = rrs ^ rrt;
  611. interp_addr+=4;
  612. }
  613.  
  614. static void NOR(void)
  615. {
  616. check_r0_rd();
  617. rrd = ~(rrs | rrt);
  618. interp_addr+=4;
  619. }
  620.  
  621. static void SLT(void)
  622. {
  623. check_r0_rd();
  624. if (rrs < rrt) rrd = 1;
  625. else rrd = 0;
  626. interp_addr+=4;
  627. }
  628.  
  629. static void SLTU(void)
  630. {
  631. check_r0_rd();
  632. if ((unsigned long long)rrs < (unsigned long long)rrt)
  633. rrd = 1;
  634. else rrd = 0;
  635. interp_addr+=4;
  636. }
  637.  
  638. static void DADD(void)
  639. {
  640. check_r0_rd();
  641. rrd = rrs + rrt;
  642. interp_addr+=4;
  643. }
  644.  
  645. static void DADDU(void)
  646. {
  647. check_r0_rd();
  648. rrd = rrs + rrt;
  649. interp_addr+=4;
  650. }
  651.  
  652. static void DSUB(void)
  653. {
  654. check_r0_rd();
  655. rrd = rrs - rrt;
  656. interp_addr+=4;
  657. }
  658.  
  659. static void DSUBU(void)
  660. {
  661. check_r0_rd();
  662. rrd = rrs - rrt;
  663. interp_addr+=4;
  664. }
  665.  
  666. static void TEQ(void)
  667. {
  668. if (rrs == rrt)
  669. {
  670. DebugMessage(M64MSG_ERROR, "trap exception in TEQ");
  671. stop=1;
  672. }
  673. interp_addr+=4;
  674. }
  675.  
  676. static void DSLL(void)
  677. {
  678. check_r0_rd();
  679. rrd = rrt << rsa;
  680. interp_addr+=4;
  681. }
  682.  
  683. static void DSRL(void)
  684. {
  685. check_r0_rd();
  686. rrd = (unsigned long long)rrt >> rsa;
  687. interp_addr+=4;
  688. }
  689.  
  690. static void DSRA(void)
  691. {
  692. check_r0_rd();
  693. rrd = rrt >> rsa;
  694. interp_addr+=4;
  695. }
  696.  
  697. static void DSLL32(void)
  698. {
  699. check_r0_rd();
  700. rrd = rrt << (32+rsa);
  701. interp_addr+=4;
  702. }
  703.  
  704. static void DSRL32(void)
  705. {
  706. check_r0_rd();
  707. rrd = (unsigned long long int)rrt >> (32+rsa);
  708. interp_addr+=4;
  709. }
  710.  
  711. static void DSRA32(void)
  712. {
  713. check_r0_rd();
  714. rrd = (signed long long int)rrt >> (32+rsa);
  715. interp_addr+=4;
  716. }
  717.  
  718. static void (*interp_special[64])(void) =
  719. {
  720. SLL , NI , SRL , SRA , SLLV , NI , SRLV , SRAV ,
  721. JR , JALR , NI , NI , SYSCALL, NI , NI , SYNC ,
  722. MFHI, MTHI , MFLO, MTLO, DSLLV , NI , DSRLV , DSRAV ,
  723. MULT, MULTU, DIV , DIVU, DMULT , DMULTU, DDIV , DDIVU ,
  724. ADD , ADDU , SUB , SUBU, AND , OR , XOR , NOR ,
  725. NI , NI , SLT , SLTU, DADD , DADDU , DSUB , DSUBU ,
  726. NI , NI , NI , NI , TEQ , NI , NI , NI ,
  727. DSLL, NI , DSRL, DSRA, DSLL32 , NI , DSRL32, DSRA32
  728. };
  729.  
  730. static void BLTZ(void)
  731. {
  732. short local_immediate = iimmediate;
  733. local_rs = irs;
  734. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  735. if (local_rs < 0)
  736. {
  737. if (probe_nop(interp_addr+4))
  738. {
  739. update_count();
  740. skip = next_interupt - Count;
  741. if (skip > 3)
  742. {
  743. Count += (skip & 0xFFFFFFFC);
  744. return;
  745. }
  746. }
  747. }
  748. interp_addr+=4;
  749. delay_slot=1;
  750. prefetch();
  751. interp_ops[((op >> 26) & 0x3F)]();
  752. update_count();
  753. delay_slot=0;
  754. if (local_rs < 0)
  755. interp_addr += (local_immediate-1)*4;
  756. last_addr = interp_addr;
  757. if (next_interupt <= Count) gen_interupt();
  758. }
  759.  
  760. static void BGEZ(void)
  761. {
  762. short local_immediate = iimmediate;
  763. local_rs = irs;
  764. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  765. if (local_rs >= 0)
  766. {
  767. if (probe_nop(interp_addr+4))
  768. {
  769. update_count();
  770. skip = next_interupt - Count;
  771. if (skip > 3)
  772. {
  773. Count += (skip & 0xFFFFFFFC);
  774. return;
  775. }
  776. }
  777. }
  778. interp_addr+=4;
  779. delay_slot=1;
  780. prefetch();
  781. interp_ops[((op >> 26) & 0x3F)]();
  782. update_count();
  783. delay_slot=0;
  784. if (local_rs >= 0)
  785. interp_addr += (local_immediate-1)*4;
  786. last_addr = interp_addr;
  787. if (next_interupt <= Count) gen_interupt();
  788. }
  789.  
  790. static void BLTZL(void)
  791. {
  792. short local_immediate = iimmediate;
  793. local_rs = irs;
  794. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  795. if (irs < 0)
  796. {
  797. if (probe_nop(interp_addr+4))
  798. {
  799. update_count();
  800. skip = next_interupt - Count;
  801. if (skip > 3)
  802. {
  803. Count += (skip & 0xFFFFFFFC);
  804. return;
  805. }
  806. }
  807. }
  808. if (irs < 0)
  809. {
  810. interp_addr+=4;
  811. delay_slot=1;
  812. prefetch();
  813. interp_ops[((op >> 26) & 0x3F)]();
  814. update_count();
  815. delay_slot=0;
  816. interp_addr += (local_immediate-1)*4;
  817. }
  818. else interp_addr+=8;
  819. last_addr = interp_addr;
  820. if (next_interupt <= Count) gen_interupt();
  821. }
  822.  
  823. static void BGEZL(void)
  824. {
  825. short local_immediate = iimmediate;
  826. local_rs = irs;
  827. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  828. if (irs >= 0)
  829. {
  830. if (probe_nop(interp_addr+4))
  831. {
  832. update_count();
  833. skip = next_interupt - Count;
  834. if (skip > 3)
  835. {
  836. Count += (skip & 0xFFFFFFFC);
  837. return;
  838. }
  839. }
  840. }
  841. if (irs >= 0)
  842. {
  843. interp_addr+=4;
  844. delay_slot=1;
  845. prefetch();
  846. interp_ops[((op >> 26) & 0x3F)]();
  847. update_count();
  848. delay_slot=0;
  849. interp_addr += (local_immediate-1)*4;
  850. }
  851. else interp_addr+=8;
  852. last_addr = interp_addr;
  853. if (next_interupt <= Count) gen_interupt();
  854. }
  855.  
  856. static void BLTZAL(void)
  857. {
  858. short local_immediate = iimmediate;
  859. local_rs = irs;
  860. reg[31]=interp_addr+8;
  861. if((&irs)!=(reg+31))
  862. {
  863. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  864. if (local_rs < 0)
  865. {
  866. if (probe_nop(interp_addr+4))
  867. {
  868. update_count();
  869. skip = next_interupt - Count;
  870. if (skip > 3)
  871. {
  872. Count += (skip & 0xFFFFFFFC);
  873. return;
  874. }
  875. }
  876. }
  877. interp_addr+=4;
  878. delay_slot=1;
  879. prefetch();
  880. interp_ops[((op >> 26) & 0x3F)]();
  881. update_count();
  882. delay_slot=0;
  883. if(local_rs < 0)
  884. interp_addr += (local_immediate-1)*4;
  885. }
  886. else DebugMessage(M64MSG_ERROR, "error in BLTZAL");
  887. last_addr = interp_addr;
  888. if (next_interupt <= Count) gen_interupt();
  889. }
  890.  
  891. static void BGEZAL(void)
  892. {
  893. short local_immediate = iimmediate;
  894. local_rs = irs;
  895. reg[31]=interp_addr+8;
  896. if((&irs)!=(reg+31))
  897. {
  898. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  899. if (local_rs >= 0)
  900. {
  901. if (probe_nop(interp_addr+4))
  902. {
  903. update_count();
  904. skip = next_interupt - Count;
  905. if (skip > 3)
  906. {
  907. Count += (skip & 0xFFFFFFFC);
  908. return;
  909. }
  910. }
  911. }
  912. interp_addr+=4;
  913. delay_slot=1;
  914. prefetch();
  915. interp_ops[((op >> 26) & 0x3F)]();
  916. update_count();
  917. delay_slot=0;
  918. if(local_rs >= 0)
  919. interp_addr += (local_immediate-1)*4;
  920. }
  921. else DebugMessage(M64MSG_ERROR, "error in BGEZAL");
  922. last_addr = interp_addr;
  923. if (next_interupt <= Count) gen_interupt();
  924. }
  925.  
  926. static void BLTZALL(void)
  927. {
  928. short local_immediate = iimmediate;
  929. local_rs = irs;
  930. reg[31]=interp_addr+8;
  931. if((&irs)!=(reg+31))
  932. {
  933. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  934. if (local_rs < 0)
  935. {
  936. if (probe_nop(interp_addr+4))
  937. {
  938. update_count();
  939. skip = next_interupt - Count;
  940. if (skip > 3)
  941. {
  942. Count += (skip & 0xFFFFFFFC);
  943. return;
  944. }
  945. }
  946. }
  947. if (local_rs < 0)
  948. {
  949. interp_addr+=4;
  950. delay_slot=1;
  951. prefetch();
  952. interp_ops[((op >> 26) & 0x3F)]();
  953. update_count();
  954. delay_slot=0;
  955. interp_addr += (local_immediate-1)*4;
  956. }
  957. else interp_addr+=8;
  958. }
  959. else DebugMessage(M64MSG_ERROR, "error in BLTZALL");
  960. last_addr = interp_addr;
  961. if (next_interupt <= Count) gen_interupt();
  962. }
  963.  
  964. static void BGEZALL(void)
  965. {
  966. short local_immediate = iimmediate;
  967. local_rs = irs;
  968. reg[31]=interp_addr+8;
  969. if((&irs)!=(reg+31))
  970. {
  971. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  972. if (local_rs >= 0)
  973. {
  974. if (probe_nop(interp_addr+4))
  975. {
  976. update_count();
  977. skip = next_interupt - Count;
  978. if (skip > 3)
  979. {
  980. Count += (skip & 0xFFFFFFFC);
  981. return;
  982. }
  983. }
  984. }
  985. if (local_rs >= 0)
  986. {
  987. interp_addr+=4;
  988. delay_slot=1;
  989. prefetch();
  990. interp_ops[((op >> 26) & 0x3F)]();
  991. update_count();
  992. delay_slot=0;
  993. interp_addr += (local_immediate-1)*4;
  994. }
  995. else interp_addr+=8;
  996. }
  997. else DebugMessage(M64MSG_ERROR, "error in BGEZALL");
  998. last_addr = interp_addr;
  999. if (next_interupt <= Count) gen_interupt();
  1000. }
  1001.  
  1002. static void (*interp_regimm[32])(void) =
  1003. {
  1004. BLTZ , BGEZ , BLTZL , BGEZL , NI, NI, NI, NI,
  1005. NI , NI , NI , NI , NI, NI, NI, NI,
  1006. BLTZAL, BGEZAL, BLTZALL, BGEZALL, NI, NI, NI, NI,
  1007. NI , NI , NI , NI , NI, NI, NI, NI
  1008. };
  1009.  
  1010. static void TLBR(void)
  1011. {
  1012. int index;
  1013. index = Index & 0x1F;
  1014. PageMask = tlb_e[index].mask << 13;
  1015. EntryHi = ((tlb_e[index].vpn2 << 13) | tlb_e[index].asid);
  1016. EntryLo0 = (tlb_e[index].pfn_even << 6) | (tlb_e[index].c_even << 3)
  1017. | (tlb_e[index].d_even << 2) | (tlb_e[index].v_even << 1)
  1018. | tlb_e[index].g;
  1019. EntryLo1 = (tlb_e[index].pfn_odd << 6) | (tlb_e[index].c_odd << 3)
  1020. | (tlb_e[index].d_odd << 2) | (tlb_e[index].v_odd << 1)
  1021. | tlb_e[index].g;
  1022. interp_addr+=4;
  1023. }
  1024.  
  1025. static void TLBWI(void)
  1026. {
  1027. unsigned int i;
  1028.  
  1029. if (tlb_e[Index&0x3F].v_even)
  1030. {
  1031. for (i=tlb_e[Index&0x3F].start_even; i<tlb_e[Index&0x3F].end_even; i++)
  1032. tlb_LUT_r[i>>12] = 0;
  1033. if (tlb_e[Index&0x3F].d_even)
  1034. for (i=tlb_e[Index&0x3F].start_even; i<tlb_e[Index&0x3F].end_even; i++)
  1035. tlb_LUT_w[i>>12] = 0;
  1036. }
  1037. if (tlb_e[Index&0x3F].v_odd)
  1038. {
  1039. for (i=tlb_e[Index&0x3F].start_odd; i<tlb_e[Index&0x3F].end_odd; i++)
  1040. tlb_LUT_r[i>>12] = 0;
  1041. if (tlb_e[Index&0x3F].d_odd)
  1042. for (i=tlb_e[Index&0x3F].start_odd; i<tlb_e[Index&0x3F].end_odd; i++)
  1043. tlb_LUT_w[i>>12] = 0;
  1044. }
  1045. tlb_e[Index&0x3F].g = (EntryLo0 & EntryLo1 & 1);
  1046. tlb_e[Index&0x3F].pfn_even = (EntryLo0 & 0x3FFFFFC0) >> 6;
  1047. tlb_e[Index&0x3F].pfn_odd = (EntryLo1 & 0x3FFFFFC0) >> 6;
  1048. tlb_e[Index&0x3F].c_even = (EntryLo0 & 0x38) >> 3;
  1049. tlb_e[Index&0x3F].c_odd = (EntryLo1 & 0x38) >> 3;
  1050. tlb_e[Index&0x3F].d_even = (EntryLo0 & 0x4) >> 2;
  1051. tlb_e[Index&0x3F].d_odd = (EntryLo1 & 0x4) >> 2;
  1052. tlb_e[Index&0x3F].v_even = (EntryLo0 & 0x2) >> 1;
  1053. tlb_e[Index&0x3F].v_odd = (EntryLo1 & 0x2) >> 1;
  1054. tlb_e[Index&0x3F].asid = (EntryHi & 0xFF);
  1055. tlb_e[Index&0x3F].vpn2 = (EntryHi & 0xFFFFE000) >> 13;
  1056. //tlb_e[Index&0x3F].r = (EntryHi & 0xC000000000000000LL) >> 62;
  1057. tlb_e[Index&0x3F].mask = (PageMask & 0x1FFE000) >> 13;
  1058.  
  1059. tlb_e[Index&0x3F].start_even = tlb_e[Index&0x3F].vpn2 << 13;
  1060. tlb_e[Index&0x3F].end_even = tlb_e[Index&0x3F].start_even+
  1061. (tlb_e[Index&0x3F].mask << 12) + 0xFFF;
  1062. tlb_e[Index&0x3F].phys_even = tlb_e[Index&0x3F].pfn_even << 12;
  1063.  
  1064. if (tlb_e[Index&0x3F].v_even)
  1065. {
  1066. if (tlb_e[Index&0x3F].start_even < tlb_e[Index&0x3F].end_even &&
  1067. !(tlb_e[Index&0x3F].start_even >= 0x80000000 &&
  1068. tlb_e[Index&0x3F].end_even < 0xC0000000) &&
  1069. tlb_e[Index&0x3F].phys_even < 0x20000000)
  1070. {
  1071. for (i=tlb_e[Index&0x3F].start_even;i<tlb_e[Index&0x3F].end_even;i++)
  1072. tlb_LUT_r[i>>12] = 0x80000000 |
  1073. (tlb_e[Index&0x3F].phys_even + (i - tlb_e[Index&0x3F].start_even));
  1074. if (tlb_e[Index&0x3F].d_even)
  1075. for (i=tlb_e[Index&0x3F].start_even;i<tlb_e[Index&0x3F].end_even;i++)
  1076. tlb_LUT_w[i>>12] = 0x80000000 |
  1077. (tlb_e[Index&0x3F].phys_even + (i - tlb_e[Index&0x3F].start_even));
  1078. }
  1079. }
  1080.  
  1081. tlb_e[Index&0x3F].start_odd = tlb_e[Index&0x3F].end_even+1;
  1082. tlb_e[Index&0x3F].end_odd = tlb_e[Index&0x3F].start_odd+
  1083. (tlb_e[Index&0x3F].mask << 12) + 0xFFF;
  1084. tlb_e[Index&0x3F].phys_odd = tlb_e[Index&0x3F].pfn_odd << 12;
  1085.  
  1086. if (tlb_e[Index&0x3F].v_odd)
  1087. {
  1088. if (tlb_e[Index&0x3F].start_odd < tlb_e[Index&0x3F].end_odd &&
  1089. !(tlb_e[Index&0x3F].start_odd >= 0x80000000 &&
  1090. tlb_e[Index&0x3F].end_odd < 0xC0000000) &&
  1091. tlb_e[Index&0x3F].phys_odd < 0x20000000)
  1092. {
  1093. for (i=tlb_e[Index&0x3F].start_odd;i<tlb_e[Index&0x3F].end_odd;i++)
  1094. tlb_LUT_r[i>>12] = 0x80000000 |
  1095. (tlb_e[Index&0x3F].phys_odd + (i - tlb_e[Index&0x3F].start_odd));
  1096. if (tlb_e[Index&0x3F].d_odd)
  1097. for (i=tlb_e[Index&0x3F].start_odd;i<tlb_e[Index&0x3F].end_odd;i++)
  1098. tlb_LUT_w[i>>12] = 0x80000000 |
  1099. (tlb_e[Index&0x3F].phys_odd + (i - tlb_e[Index&0x3F].start_odd));
  1100. }
  1101. }
  1102. interp_addr+=4;
  1103. }
  1104.  
  1105. static void TLBWR(void)
  1106. {
  1107. unsigned int i;
  1108. update_count();
  1109. Random = (Count/2 % (32 - Wired)) + Wired;
  1110. if (tlb_e[Random].v_even)
  1111. {
  1112. for (i=tlb_e[Random].start_even; i<tlb_e[Random].end_even; i++)
  1113. tlb_LUT_r[i>>12] = 0;
  1114. if (tlb_e[Random].d_even)
  1115. for (i=tlb_e[Random].start_even; i<tlb_e[Random].end_even; i++)
  1116. tlb_LUT_w[i>>12] = 0;
  1117. }
  1118. if (tlb_e[Random].v_odd)
  1119. {
  1120. for (i=tlb_e[Random].start_odd; i<tlb_e[Random].end_odd; i++)
  1121. tlb_LUT_r[i>>12] = 0;
  1122. if (tlb_e[Random].d_odd)
  1123. for (i=tlb_e[Random].start_odd; i<tlb_e[Random].end_odd; i++)
  1124. tlb_LUT_w[i>>12] = 0;
  1125. }
  1126. tlb_e[Random].g = (EntryLo0 & EntryLo1 & 1);
  1127. tlb_e[Random].pfn_even = (EntryLo0 & 0x3FFFFFC0) >> 6;
  1128. tlb_e[Random].pfn_odd = (EntryLo1 & 0x3FFFFFC0) >> 6;
  1129. tlb_e[Random].c_even = (EntryLo0 & 0x38) >> 3;
  1130. tlb_e[Random].c_odd = (EntryLo1 & 0x38) >> 3;
  1131. tlb_e[Random].d_even = (EntryLo0 & 0x4) >> 2;
  1132. tlb_e[Random].d_odd = (EntryLo1 & 0x4) >> 2;
  1133. tlb_e[Random].v_even = (EntryLo0 & 0x2) >> 1;
  1134. tlb_e[Random].v_odd = (EntryLo1 & 0x2) >> 1;
  1135. tlb_e[Random].asid = (EntryHi & 0xFF);
  1136. tlb_e[Random].vpn2 = (EntryHi & 0xFFFFE000) >> 13;
  1137. //tlb_e[Random].r = (EntryHi & 0xC000000000000000LL) >> 62;
  1138. tlb_e[Random].mask = (PageMask & 0x1FFE000) >> 13;
  1139.  
  1140. tlb_e[Random].start_even = tlb_e[Random].vpn2 << 13;
  1141. tlb_e[Random].end_even = tlb_e[Random].start_even+
  1142. (tlb_e[Random].mask << 12) + 0xFFF;
  1143. tlb_e[Random].phys_even = tlb_e[Random].pfn_even << 12;
  1144.  
  1145. if (tlb_e[Random].v_even)
  1146. {
  1147. if (tlb_e[Random].start_even < tlb_e[Random].end_even &&
  1148. !(tlb_e[Random].start_even >= 0x80000000 &&
  1149. tlb_e[Random].end_even < 0xC0000000) &&
  1150. tlb_e[Random].phys_even < 0x20000000)
  1151. {
  1152. for (i=tlb_e[Random].start_even;i<tlb_e[Random].end_even;i++)
  1153. tlb_LUT_r[i>>12] = 0x80000000 |
  1154. (tlb_e[Random].phys_even + (i - tlb_e[Random].start_even));
  1155. if (tlb_e[Random].d_even)
  1156. for (i=tlb_e[Random].start_even;i<tlb_e[Random].end_even;i++)
  1157. tlb_LUT_w[i>>12] = 0x80000000 |
  1158. (tlb_e[Random].phys_even + (i - tlb_e[Random].start_even));
  1159. }
  1160. }
  1161. tlb_e[Random].start_odd = tlb_e[Random].end_even+1;
  1162. tlb_e[Random].end_odd = tlb_e[Random].start_odd+
  1163. (tlb_e[Random].mask << 12) + 0xFFF;
  1164. tlb_e[Random].phys_odd = tlb_e[Random].pfn_odd << 12;
  1165.  
  1166. if (tlb_e[Random].v_odd)
  1167. {
  1168. if (tlb_e[Random].start_odd < tlb_e[Random].end_odd &&
  1169. !(tlb_e[Random].start_odd >= 0x80000000 &&
  1170. tlb_e[Random].end_odd < 0xC0000000) &&
  1171. tlb_e[Random].phys_odd < 0x20000000)
  1172. {
  1173. for (i=tlb_e[Random].start_odd;i<tlb_e[Random].end_odd;i++)
  1174. tlb_LUT_r[i>>12] = 0x80000000 |
  1175. (tlb_e[Random].phys_odd + (i - tlb_e[Random].start_odd));
  1176. if (tlb_e[Random].d_odd)
  1177. for (i=tlb_e[Random].start_odd;i<tlb_e[Random].end_odd;i++)
  1178. tlb_LUT_w[i>>12] = 0x80000000 |
  1179. (tlb_e[Random].phys_odd + (i - tlb_e[Random].start_odd));
  1180. }
  1181. }
  1182. interp_addr+=4;
  1183. }
  1184.  
  1185. static void TLBP(void)
  1186. {
  1187. int i;
  1188. Index |= 0x80000000;
  1189. for (i=0; i<32; i++)
  1190. {
  1191. if (((tlb_e[i].vpn2 & (~tlb_e[i].mask)) ==
  1192. (((EntryHi & 0xFFFFE000) >> 13) & (~tlb_e[i].mask))) &&
  1193. ((tlb_e[i].g) ||
  1194. (tlb_e[i].asid == (EntryHi & 0xFF))))
  1195. {
  1196. Index = i;
  1197. break;
  1198. }
  1199. }
  1200. interp_addr+=4;
  1201. }
  1202.  
  1203. static void ERET(void)
  1204. {
  1205. update_count();
  1206. if (Status & 0x4)
  1207. {
  1208. DebugMessage(M64MSG_ERROR, "error in ERET");
  1209. stop=1;
  1210. }
  1211. else
  1212. {
  1213. Status &= 0xFFFFFFFD;
  1214. interp_addr = EPC;
  1215. }
  1216. llbit = 0;
  1217. check_interupt();
  1218. last_addr = interp_addr;
  1219. if (next_interupt <= Count) gen_interupt();
  1220. }
  1221.  
  1222. static void (*interp_tlb[64])(void) =
  1223. {
  1224. NI , TLBR, TLBWI, NI, NI, NI, TLBWR, NI,
  1225. TLBP, NI , NI , NI, NI, NI, NI , NI,
  1226. NI , NI , NI , NI, NI, NI, NI , NI,
  1227. ERET, NI , NI , NI, NI, NI, NI , NI,
  1228. NI , NI , NI , NI, NI, NI, NI , NI,
  1229. NI , NI , NI , NI, NI, NI, NI , NI,
  1230. NI , NI , NI , NI, NI, NI, NI , NI,
  1231. NI , NI , NI , NI, NI, NI, NI , NI
  1232. };
  1233.  
  1234. static void MFC0(void)
  1235. {
  1236. switch(PC->f.r.nrd)
  1237. {
  1238. case 1:
  1239. DebugMessage(M64MSG_ERROR, "MFC0 reading un-implemented Random register");
  1240. stop=1;
  1241. default:
  1242. check_r0_rt();
  1243. rrt32 = reg_cop0[PC->f.r.nrd];
  1244. sign_extended(rrt);
  1245. }
  1246. interp_addr+=4;
  1247. }
  1248.  
  1249. static void MTC0(void)
  1250. {
  1251. switch(PC->f.r.nrd)
  1252. {
  1253. case 0: // Index
  1254. Index = (unsigned int) rrt & 0x8000003F;
  1255. if ((Index & 0x3F) > 31)
  1256. {
  1257. DebugMessage(M64MSG_ERROR, "MTC0 writing Index register with TLB index > 31");
  1258. stop=1;
  1259. }
  1260. break;
  1261. case 1: // Random
  1262. break;
  1263. case 2: // EntryLo0
  1264. EntryLo0 = (unsigned int) rrt & 0x3FFFFFFF;
  1265. break;
  1266. case 3: // EntryLo1
  1267. EntryLo1 = (unsigned int) rrt & 0x3FFFFFFF;
  1268. break;
  1269. case 4: // Context
  1270. Context = ((unsigned int) rrt & 0xFF800000) | (Context & 0x007FFFF0);
  1271. break;
  1272. case 5: // PageMask
  1273. PageMask = (unsigned int) rrt & 0x01FFE000;
  1274. break;
  1275. case 6: // Wired
  1276. Wired = (unsigned int) rrt;
  1277. Random = 31;
  1278. break;
  1279. case 8: // BadVAddr
  1280. break;
  1281. case 9: // Count
  1282. update_count();
  1283. if (next_interupt <= Count) gen_interupt();
  1284. debug_count += Count;
  1285. translate_event_queue((unsigned int) rrt & 0xFFFFFFFF);
  1286. Count = (unsigned int) rrt & 0xFFFFFFFF;
  1287. debug_count -= Count;
  1288. break;
  1289. case 10: // EntryHi
  1290. EntryHi = (unsigned int) rrt & 0xFFFFE0FF;
  1291. break;
  1292. case 11: // Compare
  1293. update_count();
  1294. remove_event(COMPARE_INT);
  1295. add_interupt_event_count(COMPARE_INT, (unsigned int)rrt);
  1296. Compare = (unsigned int) rrt;
  1297. Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear
  1298. break;
  1299. case 12: // Status
  1300. if((rrt & 0x04000000) != (Status & 0x04000000))
  1301. {
  1302. shuffle_fpr_data(Status, (unsigned int) rrt);
  1303. set_fpr_pointers((unsigned int) rrt);
  1304. }
  1305. Status = (unsigned int) rrt;
  1306. interp_addr+=4;
  1307. check_interupt();
  1308. update_count();
  1309. if (next_interupt <= Count) gen_interupt();
  1310. interp_addr-=4;
  1311. break;
  1312. case 13: // Cause
  1313. if (rrt!=0)
  1314. {
  1315. DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value");
  1316. stop = 1;
  1317. }
  1318. else Cause = (unsigned int) rrt;
  1319. break;
  1320. case 14: // EPC
  1321. EPC = (unsigned int) rrt;
  1322. break;
  1323. case 15: // PRevID
  1324. break;
  1325. case 16: // Config
  1326. Config = (unsigned int) rrt;
  1327. break;
  1328. case 18: // WatchLo
  1329. WatchLo = (unsigned int) rrt & 0xFFFFFFFF;
  1330. break;
  1331. case 19: // WatchHi
  1332. WatchHi = (unsigned int) rrt & 0xFFFFFFFF;
  1333. break;
  1334. case 27: // CacheErr
  1335. break;
  1336. case 28: // TagLo
  1337. TagLo = (unsigned int) rrt & 0x0FFFFFC0;
  1338. break;
  1339. case 29: // TagHi
  1340. TagHi =0;
  1341. break;
  1342. default:
  1343. DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", PC->f.r.nrd);
  1344. stop=1;
  1345. }
  1346. interp_addr+=4;
  1347. }
  1348.  
  1349. static void TLB(void)
  1350. {
  1351. interp_tlb[(op & 0x3F)]();
  1352. }
  1353.  
  1354. static void (*interp_cop0[32])(void) =
  1355. {
  1356. MFC0, NI, NI, NI, MTC0, NI, NI, NI,
  1357. NI , NI, NI, NI, NI , NI, NI, NI,
  1358. TLB , NI, NI, NI, NI , NI, NI, NI,
  1359. NI , NI, NI, NI, NI , NI, NI, NI
  1360. };
  1361.  
  1362. static void BC1F(void)
  1363. {
  1364. short local_immediate = iimmediate;
  1365. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  1366. if ((FCR31 & 0x800000)==0)
  1367. {
  1368. if (probe_nop(interp_addr+4))
  1369. {
  1370. update_count();
  1371. skip = next_interupt - Count;
  1372. if (skip > 3)
  1373. {
  1374. Count += (skip & 0xFFFFFFFC);
  1375. return;
  1376. }
  1377. }
  1378. }
  1379. interp_addr+=4;
  1380. delay_slot=1;
  1381. prefetch();
  1382. interp_ops[((op >> 26) & 0x3F)]();
  1383. update_count();
  1384. delay_slot=0;
  1385. if ((FCR31 & 0x800000)==0)
  1386. interp_addr += (local_immediate-1)*4;
  1387. last_addr = interp_addr;
  1388. if (next_interupt <= Count) gen_interupt();
  1389. }
  1390.  
  1391. static void BC1T(void)
  1392. {
  1393. short local_immediate = iimmediate;
  1394. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  1395. if ((FCR31 & 0x800000)!=0)
  1396. {
  1397. if (probe_nop(interp_addr+4))
  1398. {
  1399. update_count();
  1400. skip = next_interupt - Count;
  1401. if (skip > 3)
  1402. {
  1403. Count += (skip & 0xFFFFFFFC);
  1404. return;
  1405. }
  1406. }
  1407. }
  1408. interp_addr+=4;
  1409. delay_slot=1;
  1410. prefetch();
  1411. interp_ops[((op >> 26) & 0x3F)]();
  1412. update_count();
  1413. delay_slot=0;
  1414. if ((FCR31 & 0x800000)!=0)
  1415. interp_addr += (local_immediate-1)*4;
  1416. last_addr = interp_addr;
  1417. if (next_interupt <= Count) gen_interupt();
  1418. }
  1419.  
  1420. static void BC1FL(void)
  1421. {
  1422. short local_immediate = iimmediate;
  1423. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  1424. if ((FCR31 & 0x800000)==0)
  1425. {
  1426. if (probe_nop(interp_addr+4))
  1427. {
  1428. update_count();
  1429. skip = next_interupt - Count;
  1430. if (skip > 3)
  1431. {
  1432. Count += (skip & 0xFFFFFFFC);
  1433. return;
  1434. }
  1435. }
  1436. }
  1437. if ((FCR31 & 0x800000)==0)
  1438. {
  1439. interp_addr+=4;
  1440. delay_slot=1;
  1441. prefetch();
  1442. interp_ops[((op >> 26) & 0x3F)]();
  1443. update_count();
  1444. delay_slot=0;
  1445. interp_addr += (local_immediate-1)*4;
  1446. }
  1447. else
  1448. interp_addr+=8;
  1449. last_addr = interp_addr;
  1450. if (next_interupt <= Count) gen_interupt();
  1451. }
  1452.  
  1453. static void BC1TL(void)
  1454. {
  1455. short local_immediate = iimmediate;
  1456. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  1457. if ((FCR31 & 0x800000)!=0)
  1458. {
  1459. if (probe_nop(interp_addr+4))
  1460. {
  1461. update_count();
  1462. skip = next_interupt - Count;
  1463. if (skip > 3)
  1464. {
  1465. Count += (skip & 0xFFFFFFFC);
  1466. return;
  1467. }
  1468. }
  1469. }
  1470. if ((FCR31 & 0x800000)!=0)
  1471. {
  1472. interp_addr+=4;
  1473. delay_slot=1;
  1474. prefetch();
  1475. interp_ops[((op >> 26) & 0x3F)]();
  1476. update_count();
  1477. delay_slot=0;
  1478. interp_addr += (local_immediate-1)*4;
  1479. }
  1480. else
  1481. interp_addr+=8;
  1482. last_addr = interp_addr;
  1483. if (next_interupt <= Count) gen_interupt();
  1484. }
  1485.  
  1486. static void (*interp_cop1_bc[4])(void) =
  1487. {
  1488. BC1F , BC1T,
  1489. BC1FL, BC1TL
  1490. };
  1491.  
  1492. static void ADD_S(void)
  1493. {
  1494. set_rounding();
  1495. *reg_cop1_simple[cffd] = *reg_cop1_simple[cffs] +
  1496. *reg_cop1_simple[cfft];
  1497. interp_addr+=4;
  1498. }
  1499.  
  1500. static void SUB_S(void)
  1501. {
  1502. set_rounding();
  1503. *reg_cop1_simple[cffd] = *reg_cop1_simple[cffs] -
  1504. *reg_cop1_simple[cfft];
  1505. interp_addr+=4;
  1506. }
  1507.  
  1508. static void MUL_S(void)
  1509. {
  1510. set_rounding();
  1511. *reg_cop1_simple[cffd] = *reg_cop1_simple[cffs] *
  1512. *reg_cop1_simple[cfft];
  1513. interp_addr+=4;
  1514. }
  1515.  
  1516. static void DIV_S(void)
  1517. {
  1518. if((FCR31 & 0x400) && *reg_cop1_simple[cfft] == 0)
  1519. {
  1520. DebugMessage(M64MSG_ERROR, "DIV_S by 0");
  1521. }
  1522. set_rounding();
  1523. *reg_cop1_simple[cffd] = *reg_cop1_simple[cffs] /
  1524. *reg_cop1_simple[cfft];
  1525. interp_addr+=4;
  1526. }
  1527.  
  1528. static void SQRT_S(void)
  1529. {
  1530. set_rounding();
  1531. *reg_cop1_simple[cffd] = (float) sqrt(*reg_cop1_simple[cffs]);
  1532. interp_addr+=4;
  1533. }
  1534.  
  1535. static void ABS_S(void)
  1536. {
  1537. set_rounding();
  1538. *reg_cop1_simple[cffd] = (float) fabs(*reg_cop1_simple[cffs]);
  1539. interp_addr+=4;
  1540. }
  1541.  
  1542. static void MOV_S(void)
  1543. {
  1544. set_rounding();
  1545. *reg_cop1_simple[cffd] = *reg_cop1_simple[cffs];
  1546. interp_addr+=4;
  1547. }
  1548.  
  1549. static void NEG_S(void)
  1550. {
  1551. set_rounding();
  1552. *reg_cop1_simple[cffd] = -(*reg_cop1_simple[cffs]);
  1553. interp_addr+=4;
  1554. }
  1555.  
  1556. static void ROUND_L_S(void)
  1557. {
  1558. set_round();
  1559. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_simple[cffs];
  1560. interp_addr+=4;
  1561. }
  1562.  
  1563. static void TRUNC_L_S(void)
  1564. {
  1565. set_trunc();
  1566. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_simple[cffs];
  1567. interp_addr+=4;
  1568. }
  1569.  
  1570. static void CEIL_L_S(void)
  1571. {
  1572. set_ceil();
  1573. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_simple[cffs];
  1574. interp_addr+=4;
  1575. }
  1576.  
  1577. static void FLOOR_L_S(void)
  1578. {
  1579. set_floor();
  1580. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_simple[cffs];
  1581. interp_addr+=4;
  1582. }
  1583.  
  1584. static void ROUND_W_S(void)
  1585. {
  1586. set_round();
  1587. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_simple[cffs];
  1588. interp_addr+=4;
  1589. }
  1590.  
  1591. static void TRUNC_W_S(void)
  1592. {
  1593. set_trunc();
  1594. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_simple[cffs];
  1595. interp_addr+=4;
  1596. }
  1597.  
  1598. static void CEIL_W_S(void)
  1599. {
  1600. set_ceil();
  1601. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_simple[cffs];
  1602. interp_addr+=4;
  1603. }
  1604.  
  1605. static void FLOOR_W_S(void)
  1606. {
  1607. set_floor();
  1608. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_simple[cffs];
  1609. interp_addr+=4;
  1610. }
  1611.  
  1612. static void CVT_D_S(void)
  1613. {
  1614. set_rounding();
  1615. *reg_cop1_double[cffd] = *reg_cop1_simple[cffs];
  1616. interp_addr+=4;
  1617. }
  1618.  
  1619. static void CVT_W_S(void)
  1620. {
  1621. set_rounding();
  1622. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_simple[cffs];
  1623. interp_addr+=4;
  1624. }
  1625.  
  1626. static void CVT_L_S(void)
  1627. {
  1628. set_rounding();
  1629. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_simple[cffs];
  1630. interp_addr+=4;
  1631. }
  1632.  
  1633. static void C_F_S(void)
  1634. {
  1635. FCR31 &= ~0x800000;
  1636. interp_addr+=4;
  1637. }
  1638.  
  1639. static void C_UN_S(void)
  1640. {
  1641. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1642. FCR31 |= 0x800000;
  1643. else FCR31 &= ~0x800000;
  1644. interp_addr+=4;
  1645. }
  1646.  
  1647. static void C_EQ_S(void)
  1648. {
  1649. if (!isnan(*reg_cop1_simple[cffs]) && !isnan(*reg_cop1_simple[cfft]) &&
  1650. *reg_cop1_simple[cffs] == *reg_cop1_simple[cfft])
  1651. FCR31 |= 0x800000;
  1652. else FCR31 &= ~0x800000;
  1653. interp_addr+=4;
  1654. }
  1655.  
  1656. static void C_UEQ_S(void)
  1657. {
  1658. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]) ||
  1659. *reg_cop1_simple[cffs] == *reg_cop1_simple[cfft])
  1660. FCR31 |= 0x800000;
  1661. else FCR31 &= ~0x800000;
  1662. interp_addr+=4;
  1663. }
  1664.  
  1665. static void C_OLT_S(void)
  1666. {
  1667. if (!isnan(*reg_cop1_simple[cffs]) && !isnan(*reg_cop1_simple[cfft]) &&
  1668. *reg_cop1_simple[cffs] < *reg_cop1_simple[cfft])
  1669. FCR31 |= 0x800000;
  1670. else FCR31 &= ~0x800000;
  1671. interp_addr+=4;
  1672. }
  1673.  
  1674. static void C_ULT_S(void)
  1675. {
  1676. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]) ||
  1677. *reg_cop1_simple[cffs] < *reg_cop1_simple[cfft])
  1678. FCR31 |= 0x800000;
  1679. else FCR31 &= ~0x800000;
  1680. interp_addr+=4;
  1681. }
  1682.  
  1683. static void C_OLE_S(void)
  1684. {
  1685. if (!isnan(*reg_cop1_simple[cffs]) && !isnan(*reg_cop1_simple[cfft]) &&
  1686. *reg_cop1_simple[cffs] <= *reg_cop1_simple[cfft])
  1687. FCR31 |= 0x800000;
  1688. else FCR31 &= ~0x800000;
  1689. interp_addr+=4;
  1690. }
  1691.  
  1692. static void C_ULE_S(void)
  1693. {
  1694. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]) ||
  1695. *reg_cop1_simple[cffs] <= *reg_cop1_simple[cfft])
  1696. FCR31 |= 0x800000;
  1697. else FCR31 &= ~0x800000;
  1698. interp_addr+=4;
  1699. }
  1700.  
  1701. static void C_SF_S(void)
  1702. {
  1703. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1704. {
  1705. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1706. stop=1;
  1707. }
  1708. FCR31 &= ~0x800000;
  1709. interp_addr+=4;
  1710. }
  1711.  
  1712. static void C_NGLE_S(void)
  1713. {
  1714. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1715. {
  1716. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1717. stop=1;
  1718. }
  1719. FCR31 &= ~0x800000;
  1720. interp_addr+=4;
  1721. }
  1722.  
  1723. static void C_SEQ_S(void)
  1724. {
  1725. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1726. {
  1727. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1728. stop=1;
  1729. }
  1730. if (*reg_cop1_simple[cffs] == *reg_cop1_simple[cfft])
  1731. FCR31 |= 0x800000;
  1732. else FCR31 &= ~0x800000;
  1733. interp_addr+=4;
  1734. }
  1735.  
  1736. static void C_NGL_S(void)
  1737. {
  1738. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1739. {
  1740. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1741. stop=1;
  1742. }
  1743. if (*reg_cop1_simple[cffs] == *reg_cop1_simple[cfft])
  1744. FCR31 |= 0x800000;
  1745. else FCR31 &= ~0x800000;
  1746. interp_addr+=4;
  1747. }
  1748.  
  1749. static void C_LT_S(void)
  1750. {
  1751. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1752. {
  1753. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1754. stop=1;
  1755. }
  1756. if (*reg_cop1_simple[cffs] < *reg_cop1_simple[cfft])
  1757. FCR31 |= 0x800000;
  1758. else FCR31 &= ~0x800000;
  1759. interp_addr+=4;
  1760. }
  1761.  
  1762. static void C_NGE_S(void)
  1763. {
  1764. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1765. {
  1766. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1767. stop=1;
  1768. }
  1769. if (*reg_cop1_simple[cffs] < *reg_cop1_simple[cfft])
  1770. FCR31 |= 0x800000;
  1771. else FCR31 &= ~0x800000;
  1772. interp_addr+=4;
  1773. }
  1774.  
  1775. static void C_LE_S(void)
  1776. {
  1777. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1778. {
  1779. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1780. stop=1;
  1781. }
  1782. if (*reg_cop1_simple[cffs] <= *reg_cop1_simple[cfft])
  1783. FCR31 |= 0x800000;
  1784. else FCR31 &= ~0x800000;
  1785. interp_addr+=4;
  1786. }
  1787.  
  1788. static void C_NGT_S(void)
  1789. {
  1790. if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
  1791. {
  1792. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  1793. stop=1;
  1794. }
  1795. if (*reg_cop1_simple[cffs] <= *reg_cop1_simple[cfft])
  1796. FCR31 |= 0x800000;
  1797. else FCR31 &= ~0x800000;
  1798. interp_addr+=4;
  1799. }
  1800.  
  1801. static void (*interp_cop1_s[64])(void) =
  1802. {
  1803. ADD_S ,SUB_S ,MUL_S ,DIV_S ,SQRT_S ,ABS_S ,MOV_S ,NEG_S ,
  1804. ROUND_L_S,TRUNC_L_S,CEIL_L_S,FLOOR_L_S,ROUND_W_S,TRUNC_W_S,CEIL_W_S,FLOOR_W_S,
  1805. NI ,NI ,NI ,NI ,NI ,NI ,NI ,NI ,
  1806. NI ,NI ,NI ,NI ,NI ,NI ,NI ,NI ,
  1807. NI ,CVT_D_S ,NI ,NI ,CVT_W_S ,CVT_L_S ,NI ,NI ,
  1808. NI ,NI ,NI ,NI ,NI ,NI ,NI ,NI ,
  1809. C_F_S ,C_UN_S ,C_EQ_S ,C_UEQ_S ,C_OLT_S ,C_ULT_S ,C_OLE_S ,C_ULE_S ,
  1810. C_SF_S ,C_NGLE_S ,C_SEQ_S ,C_NGL_S ,C_LT_S ,C_NGE_S ,C_LE_S ,C_NGT_S
  1811. };
  1812.  
  1813. static void ADD_D(void)
  1814. {
  1815. set_rounding();
  1816. *reg_cop1_double[cffd] = *reg_cop1_double[cffs] +
  1817. *reg_cop1_double[cfft];
  1818. interp_addr+=4;
  1819. }
  1820.  
  1821. static void SUB_D(void)
  1822. {
  1823. set_rounding();
  1824. *reg_cop1_double[cffd] = *reg_cop1_double[cffs] -
  1825. *reg_cop1_double[cfft];
  1826. interp_addr+=4;
  1827. }
  1828.  
  1829. static void MUL_D(void)
  1830. {
  1831. set_rounding();
  1832. *reg_cop1_double[cffd] = *reg_cop1_double[cffs] *
  1833. *reg_cop1_double[cfft];
  1834. interp_addr+=4;
  1835. }
  1836.  
  1837. static void DIV_D(void)
  1838. {
  1839. if((FCR31 & 0x400) && *reg_cop1_double[cfft] == 0)
  1840. {
  1841. //FCR31 |= 0x8020;
  1842. /*FCR31 |= 0x8000;
  1843. Cause = 15 << 2;
  1844. exception_general();*/
  1845. DebugMessage(M64MSG_ERROR, "DIV_D by 0");
  1846. //return;
  1847. }
  1848. set_rounding();
  1849. *reg_cop1_double[cffd] = *reg_cop1_double[cffs] /
  1850. *reg_cop1_double[cfft];
  1851. interp_addr+=4;
  1852. }
  1853.  
  1854. static void SQRT_D(void)
  1855. {
  1856. set_rounding();
  1857. *reg_cop1_double[cffd] = sqrt(*reg_cop1_double[cffs]);
  1858. interp_addr+=4;
  1859. }
  1860.  
  1861. static void ABS_D(void)
  1862. {
  1863. set_rounding();
  1864. *reg_cop1_double[cffd] = fabs(*reg_cop1_double[cffs]);
  1865. interp_addr+=4;
  1866. }
  1867.  
  1868. static void MOV_D(void)
  1869. {
  1870. set_rounding();
  1871. *reg_cop1_double[cffd] = *reg_cop1_double[cffs];
  1872. interp_addr+=4;
  1873. }
  1874.  
  1875. static void NEG_D(void)
  1876. {
  1877. set_rounding();
  1878. *reg_cop1_double[cffd] = -(*reg_cop1_double[cffs]);
  1879. interp_addr+=4;
  1880. }
  1881.  
  1882. static void ROUND_L_D(void)
  1883. {
  1884. set_round();
  1885. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_double[cffs];
  1886. interp_addr+=4;
  1887. }
  1888.  
  1889. static void TRUNC_L_D(void)
  1890. {
  1891. set_trunc();
  1892. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_double[cffs];
  1893. interp_addr+=4;
  1894. }
  1895.  
  1896. static void CEIL_L_D(void)
  1897. {
  1898. set_ceil();
  1899. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_double[cffs];
  1900. interp_addr+=4;
  1901. }
  1902.  
  1903. static void FLOOR_L_D(void)
  1904. {
  1905. set_floor();
  1906. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_double[cffs];
  1907. interp_addr+=4;
  1908. }
  1909.  
  1910. static void ROUND_W_D(void)
  1911. {
  1912. set_round();
  1913. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_double[cffs];
  1914. interp_addr+=4;
  1915. }
  1916.  
  1917. static void TRUNC_W_D(void)
  1918. {
  1919. set_trunc();
  1920. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_double[cffs];
  1921. interp_addr+=4;
  1922. }
  1923.  
  1924. static void CEIL_W_D(void)
  1925. {
  1926. set_ceil();
  1927. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_double[cffs];
  1928. interp_addr+=4;
  1929. }
  1930.  
  1931. static void FLOOR_W_D(void)
  1932. {
  1933. set_floor();
  1934. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_double[cffs];
  1935. interp_addr+=4;
  1936. }
  1937.  
  1938. static void CVT_S_D(void)
  1939. {
  1940. set_rounding();
  1941. *reg_cop1_simple[cffd] = (float) *reg_cop1_double[cffs];
  1942. interp_addr+=4;
  1943. }
  1944.  
  1945. static void CVT_W_D(void)
  1946. {
  1947. set_rounding();
  1948. *((int*)reg_cop1_simple[cffd]) = (int) *reg_cop1_double[cffs];
  1949. interp_addr+=4;
  1950. }
  1951.  
  1952. static void CVT_L_D(void)
  1953. {
  1954. set_rounding();
  1955. *((long long*)(reg_cop1_double[cffd])) = (long long) *reg_cop1_double[cffs];
  1956. interp_addr+=4;
  1957. }
  1958.  
  1959. static void C_F_D(void)
  1960. {
  1961. FCR31 &= ~0x800000;
  1962. interp_addr+=4;
  1963. }
  1964.  
  1965. static void C_UN_D(void)
  1966. {
  1967. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  1968. FCR31 |= 0x800000;
  1969. else FCR31 &= ~0x800000;
  1970. interp_addr+=4;
  1971. }
  1972.  
  1973. static void C_EQ_D(void)
  1974. {
  1975. if (!isnan(*reg_cop1_double[cffs]) && !isnan(*reg_cop1_double[cfft]) &&
  1976. *reg_cop1_double[cffs] == *reg_cop1_double[cfft])
  1977. FCR31 |= 0x800000;
  1978. else FCR31 &= ~0x800000;
  1979. interp_addr+=4;
  1980. }
  1981.  
  1982. static void C_UEQ_D(void)
  1983. {
  1984. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]) ||
  1985. *reg_cop1_double[cffs] == *reg_cop1_double[cfft])
  1986. FCR31 |= 0x800000;
  1987. else FCR31 &= ~0x800000;
  1988. interp_addr+=4;
  1989. }
  1990.  
  1991. static void C_OLT_D(void)
  1992. {
  1993. if (!isnan(*reg_cop1_double[cffs]) && !isnan(*reg_cop1_double[cfft]) &&
  1994. *reg_cop1_double[cffs] < *reg_cop1_double[cfft])
  1995. FCR31 |= 0x800000;
  1996. else FCR31 &= ~0x800000;
  1997. interp_addr+=4;
  1998. }
  1999.  
  2000. static void C_ULT_D(void)
  2001. {
  2002. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]) ||
  2003. *reg_cop1_double[cffs] < *reg_cop1_double[cfft])
  2004. FCR31 |= 0x800000;
  2005. else FCR31 &= ~0x800000;
  2006. interp_addr+=4;
  2007. }
  2008.  
  2009. static void C_OLE_D(void)
  2010. {
  2011. if (!isnan(*reg_cop1_double[cffs]) && !isnan(*reg_cop1_double[cfft]) &&
  2012. *reg_cop1_double[cffs] <= *reg_cop1_double[cfft])
  2013. FCR31 |= 0x800000;
  2014. else FCR31 &= ~0x800000;
  2015. interp_addr+=4;
  2016. }
  2017.  
  2018. static void C_ULE_D(void)
  2019. {
  2020. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]) ||
  2021. *reg_cop1_double[cffs] <= *reg_cop1_double[cfft])
  2022. FCR31 |= 0x800000;
  2023. else FCR31 &= ~0x800000;
  2024. interp_addr+=4;
  2025. }
  2026.  
  2027. static void C_SF_D(void)
  2028. {
  2029. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2030. {
  2031. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2032. stop=1;
  2033. }
  2034. FCR31 &= ~0x800000;
  2035. interp_addr+=4;
  2036. }
  2037.  
  2038. static void C_NGLE_D(void)
  2039. {
  2040. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2041. {
  2042. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2043. stop=1;
  2044. }
  2045. FCR31 &= ~0x800000;
  2046. interp_addr+=4;
  2047. }
  2048.  
  2049. static void C_SEQ_D(void)
  2050. {
  2051. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2052. {
  2053. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2054. stop=1;
  2055. }
  2056. if (*reg_cop1_double[cffs] == *reg_cop1_double[cfft])
  2057. FCR31 |= 0x800000;
  2058. else FCR31 &= ~0x800000;
  2059. interp_addr+=4;
  2060. }
  2061.  
  2062. static void C_NGL_D(void)
  2063. {
  2064. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2065. {
  2066. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2067. stop=1;
  2068. }
  2069. if (*reg_cop1_double[cffs] == *reg_cop1_double[cfft])
  2070. FCR31 |= 0x800000;
  2071. else FCR31 &= ~0x800000;
  2072. interp_addr+=4;
  2073. }
  2074.  
  2075. static void C_LT_D(void)
  2076. {
  2077. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2078. {
  2079. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2080. stop=1;
  2081. }
  2082. if (*reg_cop1_double[cffs] < *reg_cop1_double[cfft])
  2083. FCR31 |= 0x800000;
  2084. else FCR31 &= ~0x800000;
  2085. interp_addr+=4;
  2086. }
  2087.  
  2088. static void C_NGE_D(void)
  2089. {
  2090. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2091. {
  2092. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2093. stop=1;
  2094. }
  2095. if (*reg_cop1_double[cffs] < *reg_cop1_double[cfft])
  2096. FCR31 |= 0x800000;
  2097. else FCR31 &= ~0x800000;
  2098. interp_addr+=4;
  2099. }
  2100.  
  2101. static void C_LE_D(void)
  2102. {
  2103. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2104. {
  2105. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2106. stop=1;
  2107. }
  2108. if (*reg_cop1_double[cffs] <= *reg_cop1_double[cfft])
  2109. FCR31 |= 0x800000;
  2110. else FCR31 &= ~0x800000;
  2111. interp_addr+=4;
  2112. }
  2113.  
  2114. static void C_NGT_D(void)
  2115. {
  2116. if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
  2117. {
  2118. DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
  2119. stop=1;
  2120. }
  2121. if (*reg_cop1_double[cffs] <= *reg_cop1_double[cfft])
  2122. FCR31 |= 0x800000;
  2123. else FCR31 &= ~0x800000;
  2124. interp_addr+=4;
  2125. }
  2126.  
  2127. static void (*interp_cop1_d[64])(void) =
  2128. {
  2129. ADD_D ,SUB_D ,MUL_D ,DIV_D ,SQRT_D ,ABS_D ,MOV_D ,NEG_D ,
  2130. ROUND_L_D,TRUNC_L_D,CEIL_L_D,FLOOR_L_D,ROUND_W_D,TRUNC_W_D,CEIL_W_D,FLOOR_W_D,
  2131. NI ,NI ,NI ,NI ,NI ,NI ,NI ,NI ,
  2132. NI ,NI ,NI ,NI ,NI ,NI ,NI ,NI ,
  2133. CVT_S_D ,NI ,NI ,NI ,CVT_W_D ,CVT_L_D ,NI ,NI ,
  2134. NI ,NI ,NI ,NI ,NI ,NI ,NI ,NI ,
  2135. C_F_D ,C_UN_D ,C_EQ_D ,C_UEQ_D ,C_OLT_D ,C_ULT_D ,C_OLE_D ,C_ULE_D ,
  2136. C_SF_D ,C_NGLE_D ,C_SEQ_D ,C_NGL_D ,C_LT_D ,C_NGE_D ,C_LE_D ,C_NGT_D
  2137. };
  2138.  
  2139. static void CVT_S_W(void)
  2140. {
  2141. set_rounding();
  2142. *reg_cop1_simple[cffd] = (float) *((int*)reg_cop1_simple[cffs]);
  2143. interp_addr+=4;
  2144. }
  2145.  
  2146. static void CVT_D_W(void)
  2147. {
  2148. set_rounding();
  2149. *reg_cop1_double[cffd] = *((int*)reg_cop1_simple[cffs]);
  2150. interp_addr+=4;
  2151. }
  2152.  
  2153. static void (*interp_cop1_w[64])(void) =
  2154. {
  2155. NI , NI , NI, NI, NI, NI, NI, NI,
  2156. NI , NI , NI, NI, NI, NI, NI, NI,
  2157. NI , NI , NI, NI, NI, NI, NI, NI,
  2158. NI , NI , NI, NI, NI, NI, NI, NI,
  2159. CVT_S_W, CVT_D_W, NI, NI, NI, NI, NI, NI,
  2160. NI , NI , NI, NI, NI, NI, NI, NI,
  2161. NI , NI , NI, NI, NI, NI, NI, NI,
  2162. NI , NI , NI, NI, NI, NI, NI, NI
  2163. };
  2164.  
  2165. static void CVT_S_L(void)
  2166. {
  2167. set_rounding();
  2168. *reg_cop1_simple[cffd] = (float) *((long long*)(reg_cop1_double[cffs]));
  2169. interp_addr+=4;
  2170. }
  2171.  
  2172. static void CVT_D_L(void)
  2173. {
  2174. set_rounding();
  2175. *reg_cop1_double[cffd] = (double) *((long long*)(reg_cop1_double[cffs]));
  2176. interp_addr+=4;
  2177. }
  2178.  
  2179. static void (*interp_cop1_l[64])(void) =
  2180. {
  2181. NI , NI , NI, NI, NI, NI, NI, NI,
  2182. NI , NI , NI, NI, NI, NI, NI, NI,
  2183. NI , NI , NI, NI, NI, NI, NI, NI,
  2184. NI , NI , NI, NI, NI, NI, NI, NI,
  2185. CVT_S_L, CVT_D_L, NI, NI, NI, NI, NI, NI,
  2186. NI , NI , NI, NI, NI, NI, NI, NI,
  2187. NI , NI , NI, NI, NI, NI, NI, NI,
  2188. NI , NI , NI, NI, NI, NI, NI, NI
  2189. };
  2190.  
  2191. static void MFC1(void)
  2192. {
  2193. check_r0_rt();
  2194. rrt32 = *((int*)reg_cop1_simple[rfs]);
  2195. sign_extended(rrt);
  2196. interp_addr+=4;
  2197. }
  2198.  
  2199. static void DMFC1(void)
  2200. {
  2201. check_r0_rt();
  2202. rrt = *((long long*)(reg_cop1_double[rfs]));
  2203. interp_addr+=4;
  2204. }
  2205.  
  2206. static void CFC1(void)
  2207. {
  2208. check_r0_rt();
  2209. if (rfs==31)
  2210. {
  2211. rrt32 = FCR31;
  2212. sign_extended(rrt);
  2213. }
  2214. if (rfs==0)
  2215. {
  2216. rrt32 = FCR0;
  2217. sign_extended(rrt);
  2218. }
  2219. interp_addr+=4;
  2220. }
  2221.  
  2222. static void MTC1(void)
  2223. {
  2224. *((int*)reg_cop1_simple[rfs]) = rrt32;
  2225. interp_addr+=4;
  2226. }
  2227.  
  2228. static void DMTC1(void)
  2229. {
  2230. *((long long*)reg_cop1_double[rfs]) = rrt;
  2231. interp_addr+=4;
  2232. }
  2233.  
  2234. static void CTC1(void)
  2235. {
  2236. if (rfs==31)
  2237. FCR31 = rrt32;
  2238. switch((FCR31 & 3))
  2239. {
  2240. case 0:
  2241. rounding_mode = 0x33F;
  2242. break;
  2243. case 1:
  2244. rounding_mode = 0xF3F;
  2245. break;
  2246. case 2:
  2247. rounding_mode = 0xB3F;
  2248. break;
  2249. case 3:
  2250. rounding_mode = 0x73F;
  2251. break;
  2252. }
  2253. //if ((FCR31 >> 7) & 0x1F) printf("FPU Exception enabled : %x\n",
  2254. // (int)((FCR31 >> 7) & 0x1F));
  2255. interp_addr+=4;
  2256. }
  2257.  
  2258. static void BC(void)
  2259. {
  2260. interp_cop1_bc[(op >> 16) & 3]();
  2261. }
  2262.  
  2263. static void S(void)
  2264. {
  2265. interp_cop1_s[(op & 0x3F)]();
  2266. }
  2267.  
  2268. static void D(void)
  2269. {
  2270. interp_cop1_d[(op & 0x3F)]();
  2271. }
  2272.  
  2273. static void W(void)
  2274. {
  2275. interp_cop1_w[(op & 0x3F)]();
  2276. }
  2277.  
  2278. static void L(void)
  2279. {
  2280. interp_cop1_l[(op & 0x3F)]();
  2281. }
  2282.  
  2283. static void (*interp_cop1[32])(void) =
  2284. {
  2285. MFC1, DMFC1, CFC1, NI, MTC1, DMTC1, CTC1, NI,
  2286. BC , NI , NI , NI, NI , NI , NI , NI,
  2287. S , D , NI , NI, W , L , NI , NI,
  2288. NI , NI , NI , NI, NI , NI , NI , NI
  2289. };
  2290.  
  2291. static void SPECIAL(void)
  2292. {
  2293. interp_special[(op & 0x3F)]();
  2294. }
  2295.  
  2296. static void REGIMM(void)
  2297. {
  2298. interp_regimm[((op >> 16) & 0x1F)]();
  2299. }
  2300.  
  2301. static void J(void)
  2302. {
  2303. unsigned int naddr = (PC->f.j.inst_index<<2) | (interp_addr & 0xF0000000);
  2304. if (naddr == interp_addr)
  2305. {
  2306. if (probe_nop(interp_addr+4))
  2307. {
  2308. update_count();
  2309. skip = next_interupt - Count;
  2310. if (skip > 3)
  2311. {
  2312. Count += (skip & 0xFFFFFFFC);
  2313. return;
  2314. }
  2315. }
  2316. }
  2317. interp_addr+=4;
  2318. delay_slot=1;
  2319. prefetch();
  2320. interp_ops[((op >> 26) & 0x3F)]();
  2321. update_count();
  2322. delay_slot=0;
  2323. interp_addr = naddr;
  2324. last_addr = interp_addr;
  2325. if (next_interupt <= Count) gen_interupt();
  2326. }
  2327.  
  2328. static void JAL(void)
  2329. {
  2330. unsigned int naddr = (PC->f.j.inst_index<<2) | (interp_addr & 0xF0000000);
  2331. if (naddr == interp_addr)
  2332. {
  2333. if (probe_nop(interp_addr+4))
  2334. {
  2335. update_count();
  2336. skip = next_interupt - Count;
  2337. if (skip > 3)
  2338. {
  2339. Count += (skip & 0xFFFFFFFC);
  2340. return;
  2341. }
  2342. }
  2343. }
  2344.  
  2345. interp_addr+=4;
  2346. delay_slot=1;
  2347. prefetch();
  2348. interp_ops[((op >> 26) & 0x3F)]();
  2349. update_count();
  2350. delay_slot=0;
  2351.  
  2352. note_call( interp_addr - 8, naddr );
  2353.  
  2354. if( naddr == watch )
  2355. stack_trace();
  2356.  
  2357. if (!skip_jump)
  2358. {
  2359. reg[31]=interp_addr;
  2360. sign_extended(reg[31]);
  2361.  
  2362. interp_addr = naddr;
  2363. }
  2364. last_addr = interp_addr;
  2365. if (next_interupt <= Count) gen_interupt();
  2366. }
  2367.  
  2368. static void BEQ(void)
  2369. {
  2370. short local_immediate = iimmediate;
  2371. local_rs = irs;
  2372. local_rt = irt;
  2373. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2374. if (local_rs == local_rt)
  2375. {
  2376. if (probe_nop(interp_addr+4))
  2377. {
  2378. update_count();
  2379. skip = next_interupt - Count;
  2380. if (skip > 3)
  2381. {
  2382. Count += (skip & 0xFFFFFFFC);
  2383. return;
  2384. }
  2385. }
  2386. }
  2387. interp_addr+=4;
  2388. delay_slot=1;
  2389. prefetch();
  2390. interp_ops[((op >> 26) & 0x3F)]();
  2391. update_count();
  2392. delay_slot=0;
  2393. if (local_rs == local_rt)
  2394. interp_addr += (local_immediate-1)*4;
  2395. last_addr = interp_addr;
  2396. if (next_interupt <= Count) gen_interupt();
  2397. }
  2398.  
  2399. static void BNE(void)
  2400. {
  2401. short local_immediate = iimmediate;
  2402. local_rs = irs;
  2403. local_rt = irt;
  2404. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2405. if (local_rs != local_rt)
  2406. {
  2407. if (probe_nop(interp_addr+4))
  2408. {
  2409. update_count();
  2410. skip = next_interupt - Count;
  2411. if (skip > 3)
  2412. {
  2413. Count += (skip & 0xFFFFFFFC);
  2414. return;
  2415. }
  2416. }
  2417. }
  2418. interp_addr+=4;
  2419. delay_slot=1;
  2420. prefetch();
  2421. interp_ops[((op >> 26) & 0x3F)]();
  2422. update_count();
  2423. delay_slot=0;
  2424. if (local_rs != local_rt)
  2425. interp_addr += (local_immediate-1)*4;
  2426. last_addr = interp_addr;
  2427. if (next_interupt <= Count) gen_interupt();
  2428. }
  2429.  
  2430. static void BLEZ(void)
  2431. {
  2432. short local_immediate = iimmediate;
  2433. local_rs = irs;
  2434. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2435. if (local_rs <= 0)
  2436. {
  2437. if (probe_nop(interp_addr+4))
  2438. {
  2439. update_count();
  2440. skip = next_interupt - Count;
  2441. if (skip > 3)
  2442. {
  2443. Count += (skip & 0xFFFFFFFC);
  2444. return;
  2445. }
  2446. }
  2447. }
  2448. interp_addr+=4;
  2449. delay_slot=1;
  2450. prefetch();
  2451. interp_ops[((op >> 26) & 0x3F)]();
  2452. update_count();
  2453. delay_slot=0;
  2454. if (local_rs <= 0)
  2455. interp_addr += (local_immediate-1)*4;
  2456. last_addr = interp_addr;
  2457. if (next_interupt <= Count) gen_interupt();
  2458. }
  2459.  
  2460. static void BGTZ(void)
  2461. {
  2462. short local_immediate = iimmediate;
  2463. local_rs = irs;
  2464. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2465. if (local_rs > 0)
  2466. {
  2467. if (probe_nop(interp_addr+4))
  2468. {
  2469. update_count();
  2470. skip = next_interupt - Count;
  2471. if (skip > 3)
  2472. {
  2473. Count += (skip & 0xFFFFFFFC);
  2474. return;
  2475. }
  2476. }
  2477. }
  2478. interp_addr+=4;
  2479. delay_slot=1;
  2480. prefetch();
  2481. interp_ops[((op >> 26) & 0x3F)]();
  2482. update_count();
  2483. delay_slot=0;
  2484. if (local_rs > 0)
  2485. interp_addr += (local_immediate-1)*4;
  2486. last_addr = interp_addr;
  2487. if (next_interupt <= Count) gen_interupt();
  2488. }
  2489.  
  2490. static void ADDI(void)
  2491. {
  2492. check_r0_irt();
  2493. irt32 = irs32 + iimmediate;
  2494. sign_extended(irt);
  2495. interp_addr+=4;
  2496. }
  2497.  
  2498. static void ADDIU(void)
  2499. {
  2500. check_r0_irt();
  2501. irt32 = irs32 + iimmediate;
  2502. sign_extended(irt);
  2503. interp_addr+=4;
  2504. }
  2505.  
  2506. static void SLTI(void)
  2507. {
  2508. check_r0_irt();
  2509. if (irs < iimmediate) irt = 1;
  2510. else irt = 0;
  2511. interp_addr+=4;
  2512. }
  2513.  
  2514. static void SLTIU(void)
  2515. {
  2516. check_r0_irt();
  2517. if ((unsigned long long)irs < (unsigned long long)((long long)iimmediate))
  2518. irt = 1;
  2519. else irt = 0;
  2520. interp_addr+=4;
  2521. }
  2522.  
  2523. static void ANDI(void)
  2524. {
  2525. check_r0_irt();
  2526. irt = irs & (unsigned short)iimmediate;
  2527. interp_addr+=4;
  2528. }
  2529.  
  2530. static void ORI(void)
  2531. {
  2532. check_r0_irt();
  2533. irt = irs | (unsigned short)iimmediate;
  2534. interp_addr+=4;
  2535. }
  2536.  
  2537. static void XORI(void)
  2538. {
  2539. check_r0_irt();
  2540. irt = irs ^ (unsigned short)iimmediate;
  2541. interp_addr+=4;
  2542. }
  2543.  
  2544. static void LUI(void)
  2545. {
  2546. check_r0_irt();
  2547. irt32 = iimmediate << 16;
  2548. sign_extended(irt);
  2549. interp_addr+=4;
  2550. }
  2551.  
  2552. static void COP0(void)
  2553. {
  2554. interp_cop0[((op >> 21) & 0x1F)]();
  2555. }
  2556.  
  2557. static void COP1(void)
  2558. {
  2559. if (check_cop1_unusable()) return;
  2560. interp_cop1[((op >> 21) & 0x1F)]();
  2561. }
  2562.  
  2563. static void BEQL(void)
  2564. {
  2565. short local_immediate = iimmediate;
  2566. local_rs = irs;
  2567. local_rt = irt;
  2568. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2569. if (irs == irt)
  2570. {
  2571. if (probe_nop(interp_addr+4))
  2572. {
  2573. update_count();
  2574. skip = next_interupt - Count;
  2575. if (skip > 3)
  2576. {
  2577. Count += (skip & 0xFFFFFFFC);
  2578. return;
  2579. }
  2580. }
  2581. }
  2582. if (local_rs == local_rt)
  2583. {
  2584. interp_addr+=4;
  2585. delay_slot=1;
  2586. prefetch();
  2587. interp_ops[((op >> 26) & 0x3F)]();
  2588. update_count();
  2589. delay_slot=0;
  2590. interp_addr += (local_immediate-1)*4;
  2591. }
  2592. else
  2593. {
  2594. interp_addr+=8;
  2595. update_count();
  2596. }
  2597. last_addr = interp_addr;
  2598. if (next_interupt <= Count) gen_interupt();
  2599. }
  2600.  
  2601. static void BNEL(void)
  2602. {
  2603. short local_immediate = iimmediate;
  2604. local_rs = irs;
  2605. local_rt = irt;
  2606. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2607. if (irs != irt)
  2608. {
  2609. if (probe_nop(interp_addr+4))
  2610. {
  2611. update_count();
  2612. skip = next_interupt - Count;
  2613. if (skip > 3)
  2614. {
  2615. Count += (skip & 0xFFFFFFFC);
  2616. return;
  2617. }
  2618. }
  2619. }
  2620. if (local_rs != local_rt)
  2621. {
  2622. interp_addr+=4;
  2623. delay_slot=1;
  2624. prefetch();
  2625. interp_ops[((op >> 26) & 0x3F)]();
  2626. update_count();
  2627. delay_slot=0;
  2628. interp_addr += (local_immediate-1)*4;
  2629. }
  2630. else
  2631. {
  2632. interp_addr+=8;
  2633. update_count();
  2634. }
  2635. last_addr = interp_addr;
  2636. if (next_interupt <= Count) gen_interupt();
  2637. }
  2638.  
  2639. static void BLEZL(void)
  2640. {
  2641. short local_immediate = iimmediate;
  2642. local_rs = irs;
  2643. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2644. if (irs <= 0)
  2645. {
  2646. if (probe_nop(interp_addr+4))
  2647. {
  2648. update_count();
  2649. skip = next_interupt - Count;
  2650. if (skip > 3)
  2651. {
  2652. Count += (skip & 0xFFFFFFFC);
  2653. return;
  2654. }
  2655. }
  2656. }
  2657. if (local_rs <= 0)
  2658. {
  2659. interp_addr+=4;
  2660. delay_slot=1;
  2661. prefetch();
  2662. interp_ops[((op >> 26) & 0x3F)]();
  2663. update_count();
  2664. delay_slot=0;
  2665. interp_addr += (local_immediate-1)*4;
  2666. }
  2667. else
  2668. {
  2669. interp_addr+=8;
  2670. update_count();
  2671. }
  2672. last_addr = interp_addr;
  2673. if (next_interupt <= Count) gen_interupt();
  2674. }
  2675.  
  2676. static void BGTZL(void)
  2677. {
  2678. short local_immediate = iimmediate;
  2679. local_rs = irs;
  2680. if ((interp_addr + (local_immediate+1)*4) == interp_addr)
  2681. if (irs > 0)
  2682. {
  2683. if (probe_nop(interp_addr+4))
  2684. {
  2685. update_count();
  2686. skip = next_interupt - Count;
  2687. if (skip > 3)
  2688. {
  2689. Count += (skip & 0xFFFFFFFC);
  2690. return;
  2691. }
  2692. }
  2693. }
  2694. if (local_rs > 0)
  2695. {
  2696. interp_addr+=4;
  2697. delay_slot=1;
  2698. prefetch();
  2699. interp_ops[((op >> 26) & 0x3F)]();
  2700. update_count();
  2701. delay_slot=0;
  2702. interp_addr += (local_immediate-1)*4;
  2703. }
  2704. else
  2705. {
  2706. interp_addr+=8;
  2707. update_count();
  2708. }
  2709. last_addr = interp_addr;
  2710. if (next_interupt <= Count) gen_interupt();
  2711. }
  2712.  
  2713. static void DADDI(void)
  2714. {
  2715. check_r0_irt();
  2716. irt = irs + iimmediate;
  2717. interp_addr+=4;
  2718. }
  2719.  
  2720. static void DADDIU(void)
  2721. {
  2722. check_r0_irt();
  2723. irt = irs + iimmediate;
  2724. interp_addr+=4;
  2725. }
  2726.  
  2727. static void LDL(void)
  2728. {
  2729. unsigned long long int word = 0;
  2730. check_r0_irt();
  2731. interp_addr+=4;
  2732. switch ((iimmediate + irs32) & 7)
  2733. {
  2734. case 0:
  2735. address = iimmediate + irs32;
  2736. rdword = (unsigned long long *) &irt;
  2737. read_dword_in_memory();
  2738. break;
  2739. case 1:
  2740. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2741. rdword = &word;
  2742. read_dword_in_memory();
  2743. irt = (irt & 0xFF) | (word << 8);
  2744. break;
  2745. case 2:
  2746. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2747. rdword = &word;
  2748. read_dword_in_memory();
  2749. irt = (irt & 0xFFFF) | (word << 16);
  2750. break;
  2751. case 3:
  2752. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2753. rdword = &word;
  2754. read_dword_in_memory();
  2755. irt = (irt & 0xFFFFFF) | (word << 24);
  2756. break;
  2757. case 4:
  2758. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2759. rdword = &word;
  2760. read_dword_in_memory();
  2761. irt = (irt & 0xFFFFFFFF) | (word << 32);
  2762. break;
  2763. case 5:
  2764. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2765. rdword = &word;
  2766. read_dword_in_memory();
  2767. irt = (irt & 0xFFFFFFFFFFLL) | (word << 40);
  2768. break;
  2769. case 6:
  2770. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2771. rdword = &word;
  2772. read_dword_in_memory();
  2773. irt = (irt & 0xFFFFFFFFFFFFLL) | (word << 48);
  2774. break;
  2775. case 7:
  2776. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2777. rdword = &word;
  2778. read_dword_in_memory();
  2779. irt = (irt & 0xFFFFFFFFFFFFFFLL) | (word << 56);
  2780. break;
  2781. }
  2782. }
  2783.  
  2784. static void LDR(void)
  2785. {
  2786. unsigned long long int word = 0;
  2787. check_r0_irt();
  2788. interp_addr+=4;
  2789. switch ((iimmediate + irs32) & 7)
  2790. {
  2791. case 0:
  2792. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2793. rdword = &word;
  2794. read_dword_in_memory();
  2795. irt = (irt & 0xFFFFFFFFFFFFFF00LL) | (word >> 56);
  2796. break;
  2797. case 1:
  2798. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2799. rdword = &word;
  2800. read_dword_in_memory();
  2801. irt = (irt & 0xFFFFFFFFFFFF0000LL) | (word >> 48);
  2802. break;
  2803. case 2:
  2804. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2805. rdword = &word;
  2806. read_dword_in_memory();
  2807. irt = (irt & 0xFFFFFFFFFF000000LL) | (word >> 40);
  2808. break;
  2809. case 3:
  2810. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2811. rdword = &word;
  2812. read_dword_in_memory();
  2813. irt = (irt & 0xFFFFFFFF00000000LL) | (word >> 32);
  2814. break;
  2815. case 4:
  2816. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2817. rdword = &word;
  2818. read_dword_in_memory();
  2819. irt = (irt & 0xFFFFFF0000000000LL) | (word >> 24);
  2820. break;
  2821. case 5:
  2822. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2823. rdword = &word;
  2824. read_dword_in_memory();
  2825. irt = (irt & 0xFFFF000000000000LL) | (word >> 16);
  2826. break;
  2827. case 6:
  2828. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2829. rdword = &word;
  2830. read_dword_in_memory();
  2831. irt = (irt & 0xFF00000000000000LL) | (word >> 8);
  2832. break;
  2833. case 7:
  2834. address = (iimmediate + irs32) & 0xFFFFFFF8;
  2835. rdword = (unsigned long long *) &irt;
  2836. read_dword_in_memory();
  2837. break;
  2838. }
  2839. }
  2840.  
  2841. static void LB(void)
  2842. {
  2843. check_r0_irt();
  2844. interp_addr+=4;
  2845. address = iimmediate + irs32;
  2846. rdword = (unsigned long long *) &irt;
  2847. read_byte_in_memory();
  2848. sign_extendedb(irt);
  2849. }
  2850.  
  2851. static void LH(void)
  2852. {
  2853. check_r0_irt();
  2854. interp_addr+=4;
  2855. address = iimmediate + irs32;
  2856. rdword = (unsigned long long *) &irt;
  2857. read_hword_in_memory();
  2858. sign_extendedh(irt);
  2859. }
  2860.  
  2861. static void LWL(void)
  2862. {
  2863. unsigned long long int word = 0;
  2864. check_r0_irt();
  2865. interp_addr+=4;
  2866. switch ((iimmediate + irs32) & 3)
  2867. {
  2868. case 0:
  2869. address = iimmediate + irs32;
  2870. rdword = (unsigned long long *) &irt;
  2871. read_word_in_memory();
  2872. break;
  2873. case 1:
  2874. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2875. rdword = &word;
  2876. read_word_in_memory();
  2877. irt = (irt & 0xFF) | (word << 8);
  2878. break;
  2879. case 2:
  2880. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2881. rdword = &word;
  2882. read_word_in_memory();
  2883. irt = (irt & 0xFFFF) | (word << 16);
  2884. break;
  2885. case 3:
  2886. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2887. rdword = &word;
  2888. read_word_in_memory();
  2889. irt = (irt & 0xFFFFFF) | (word << 24);
  2890. break;
  2891. }
  2892. sign_extended(irt);
  2893. }
  2894.  
  2895. static void LW(void)
  2896. {
  2897. check_r0_irt();
  2898. address = iimmediate + irs32;
  2899. rdword = (unsigned long long *) &irt;
  2900. interp_addr+=4;
  2901. read_word_in_memory();
  2902. sign_extended(irt);
  2903. }
  2904.  
  2905. static void LBU(void)
  2906. {
  2907. check_r0_irt();
  2908. interp_addr+=4;
  2909. address = iimmediate + irs32;
  2910. rdword = (unsigned long long *) &irt;
  2911. read_byte_in_memory();
  2912. }
  2913.  
  2914. static void LHU(void)
  2915. {
  2916. check_r0_irt();
  2917. interp_addr+=4;
  2918. address = iimmediate + irs32;
  2919. rdword = (unsigned long long *) &irt;
  2920. read_hword_in_memory();
  2921. }
  2922.  
  2923. static void LWR(void)
  2924. {
  2925. unsigned long long int word = 0;
  2926. check_r0_irt();
  2927. interp_addr+=4;
  2928. switch ((iimmediate + irs32) & 3)
  2929. {
  2930. case 0:
  2931. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2932. rdword = &word;
  2933. read_word_in_memory();
  2934. irt = (irt & 0xFFFFFFFFFFFFFF00LL) | ((word >> 24) & 0xFF);
  2935. break;
  2936. case 1:
  2937. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2938. rdword = &word;
  2939. read_word_in_memory();
  2940. irt = (irt & 0xFFFFFFFFFFFF0000LL) | ((word >> 16) & 0xFFFF);
  2941. break;
  2942. case 2:
  2943. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2944. rdword = &word;
  2945. read_word_in_memory();
  2946. irt = (irt & 0xFFFFFFFFFF000000LL) | ((word >> 8) & 0xFFFFFF);
  2947. break;
  2948. case 3:
  2949. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2950. rdword = (unsigned long long *) &irt;
  2951. read_word_in_memory();
  2952. sign_extended(irt);
  2953. }
  2954. }
  2955.  
  2956. static void LWU(void)
  2957. {
  2958. check_r0_irt();
  2959. address = iimmediate + irs32;
  2960. rdword = (unsigned long long *) &irt;
  2961. interp_addr+=4;
  2962. read_word_in_memory();
  2963. }
  2964.  
  2965. static void SB(void)
  2966. {
  2967. interp_addr+=4;
  2968. address = iimmediate + irs32;
  2969. cpu_byte = (unsigned char)(irt & 0xFF);
  2970. write_byte_in_memory();
  2971. }
  2972.  
  2973. static void SH(void)
  2974. {
  2975. interp_addr+=4;
  2976. address = iimmediate + irs32;
  2977. hword = (unsigned short)(irt & 0xFFFF);
  2978. write_hword_in_memory();
  2979. }
  2980.  
  2981. static void SWL(void)
  2982. {
  2983. unsigned long long int old_word = 0;
  2984. interp_addr+=4;
  2985. switch ((iimmediate + irs32) & 3)
  2986. {
  2987. case 0:
  2988. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2989. word = (unsigned int)irt;
  2990. write_word_in_memory();
  2991. break;
  2992. case 1:
  2993. address = (iimmediate + irs32) & 0xFFFFFFFC;
  2994. rdword = &old_word;
  2995. read_word_in_memory();
  2996. word = ((unsigned int)irt >> 8) | ((unsigned int) old_word & 0xFF000000);
  2997. write_word_in_memory();
  2998. break;
  2999. case 2:
  3000. address = (iimmediate + irs32) & 0xFFFFFFFC;
  3001. rdword = &old_word;
  3002. read_word_in_memory();
  3003. word = ((unsigned int)irt >> 16) | ((unsigned int) old_word & 0xFFFF0000);
  3004. write_word_in_memory();
  3005. break;
  3006. case 3:
  3007. address = iimmediate + irs32;
  3008. cpu_byte = (unsigned char)(irt >> 24);
  3009. write_byte_in_memory();
  3010. break;
  3011. }
  3012. }
  3013.  
  3014. static void SW(void)
  3015. {
  3016. interp_addr+=4;
  3017. address = iimmediate + irs32;
  3018. word = (unsigned int)(irt & 0xFFFFFFFF);
  3019. write_word_in_memory();
  3020. }
  3021.  
  3022. static void SDL(void)
  3023. {
  3024. unsigned long long int old_word = 0;
  3025. interp_addr+=4;
  3026. switch ((iimmediate + irs32) & 7)
  3027. {
  3028. case 0:
  3029. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3030. dword = irt;
  3031. write_dword_in_memory();
  3032. break;
  3033. case 1:
  3034. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3035. rdword = &old_word;
  3036. read_dword_in_memory();
  3037. dword = ((unsigned long long)irt >> 8)|(old_word & 0xFF00000000000000LL);
  3038. write_dword_in_memory();
  3039. break;
  3040. case 2:
  3041. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3042. rdword = &old_word;
  3043. read_dword_in_memory();
  3044. dword = ((unsigned long long)irt >> 16)|(old_word & 0xFFFF000000000000LL);
  3045. write_dword_in_memory();
  3046. break;
  3047. case 3:
  3048. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3049. rdword = &old_word;
  3050. read_dword_in_memory();
  3051. dword = ((unsigned long long)irt >> 24)|(old_word & 0xFFFFFF0000000000LL);
  3052. write_dword_in_memory();
  3053. break;
  3054. case 4:
  3055. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3056. rdword = &old_word;
  3057. read_dword_in_memory();
  3058. dword = ((unsigned long long)irt >> 32)|(old_word & 0xFFFFFFFF00000000LL);
  3059. write_dword_in_memory();
  3060. break;
  3061. case 5:
  3062. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3063. rdword = &old_word;
  3064. read_dword_in_memory();
  3065. dword = ((unsigned long long)irt >> 40)|(old_word & 0xFFFFFFFFFF000000LL);
  3066. write_dword_in_memory();
  3067. break;
  3068. case 6:
  3069. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3070. rdword = &old_word;
  3071. read_dword_in_memory();
  3072. dword = ((unsigned long long)irt >> 48)|(old_word & 0xFFFFFFFFFFFF0000LL);
  3073. write_dword_in_memory();
  3074. break;
  3075. case 7:
  3076. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3077. rdword = &old_word;
  3078. read_dword_in_memory();
  3079. dword = ((unsigned long long)irt >> 56)|(old_word & 0xFFFFFFFFFFFFFF00LL);
  3080. write_dword_in_memory();
  3081. break;
  3082. }
  3083. }
  3084.  
  3085. static void SDR(void)
  3086. {
  3087. unsigned long long int old_word = 0;
  3088. interp_addr+=4;
  3089. switch ((iimmediate + irs32) & 7)
  3090. {
  3091. case 0:
  3092. address = iimmediate + irs32;
  3093. rdword = &old_word;
  3094. read_dword_in_memory();
  3095. dword = (irt << 56) | (old_word & 0x00FFFFFFFFFFFFFFLL);
  3096. write_dword_in_memory();
  3097. break;
  3098. case 1:
  3099. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3100. rdword = &old_word;
  3101. read_dword_in_memory();
  3102. dword = (irt << 48) | (old_word & 0x0000FFFFFFFFFFFFLL);
  3103. write_dword_in_memory();
  3104. break;
  3105. case 2:
  3106. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3107. rdword = &old_word;
  3108. read_dword_in_memory();
  3109. dword = (irt << 40) | (old_word & 0x000000FFFFFFFFFFLL);
  3110. write_dword_in_memory();
  3111. break;
  3112. case 3:
  3113. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3114. rdword = &old_word;
  3115. read_dword_in_memory();
  3116. dword = (irt << 32) | (old_word & 0x00000000FFFFFFFFLL);
  3117. write_dword_in_memory();
  3118. break;
  3119. case 4:
  3120. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3121. rdword = &old_word;
  3122. read_dword_in_memory();
  3123. dword = (irt << 24) | (old_word & 0x0000000000FFFFFFLL);
  3124. write_dword_in_memory();
  3125. break;
  3126. case 5:
  3127. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3128. rdword = &old_word;
  3129. read_dword_in_memory();
  3130. dword = (irt << 16) | (old_word & 0x000000000000FFFFLL);
  3131. write_dword_in_memory();
  3132. break;
  3133. case 6:
  3134. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3135. rdword = &old_word;
  3136. read_dword_in_memory();
  3137. dword = (irt << 8) | (old_word & 0x00000000000000FFLL);
  3138. write_dword_in_memory();
  3139. break;
  3140. case 7:
  3141. address = (iimmediate + irs32) & 0xFFFFFFF8;
  3142. dword = irt;
  3143. write_dword_in_memory();
  3144. break;
  3145. }
  3146. }
  3147.  
  3148. static void SWR(void)
  3149. {
  3150. unsigned long long int old_word = 0;
  3151. interp_addr+=4;
  3152. switch ((iimmediate + irs32) & 3)
  3153. {
  3154. case 0:
  3155. address = iimmediate + irs32;
  3156. rdword = &old_word;
  3157. read_word_in_memory();
  3158. word = ((unsigned int)irt << 24) | ((unsigned int) old_word & 0x00FFFFFF);
  3159. write_word_in_memory();
  3160. break;
  3161. case 1:
  3162. address = (iimmediate + irs32) & 0xFFFFFFFC;
  3163. rdword = &old_word;
  3164. read_word_in_memory();
  3165. word = ((unsigned int)irt << 16) | ((unsigned int) old_word & 0x0000FFFF);
  3166. write_word_in_memory();
  3167. break;
  3168. case 2:
  3169. address = (iimmediate + irs32) & 0xFFFFFFFC;
  3170. rdword = &old_word;
  3171. read_word_in_memory();
  3172. word = ((unsigned int)irt << 8) | ((unsigned int) old_word & 0x000000FF);
  3173. write_word_in_memory();
  3174. break;
  3175. case 3:
  3176. address = (iimmediate + irs32) & 0xFFFFFFFC;
  3177. word = (unsigned int)irt;
  3178. write_word_in_memory();
  3179. break;
  3180. }
  3181. }
  3182.  
  3183. static void CACHE(void)
  3184. {
  3185. interp_addr+=4;
  3186. }
  3187.  
  3188. static void LL(void)
  3189. {
  3190. check_r0_irt();
  3191. address = iimmediate + irs32;
  3192. rdword = (unsigned long long *) &irt;
  3193. interp_addr+=4;
  3194. read_word_in_memory();
  3195. sign_extended(irt);
  3196. llbit = 1;
  3197. }
  3198.  
  3199. static void LWC1(void)
  3200. {
  3201. unsigned long long int temp;
  3202. if (check_cop1_unusable()) return;
  3203. interp_addr+=4;
  3204. address = (unsigned int) (lfoffset + reg[lfbase]);
  3205. rdword = &temp;
  3206. read_word_in_memory();
  3207. *((int*)reg_cop1_simple[lfft]) = (int) *rdword;
  3208. }
  3209.  
  3210. static void LDC1(void)
  3211. {
  3212. if (check_cop1_unusable()) return;
  3213. interp_addr+=4;
  3214. address = (unsigned int) (lfoffset + reg[lfbase]);
  3215. rdword = (unsigned long long*) reg_cop1_double[lfft];
  3216. read_dword_in_memory();
  3217. }
  3218.  
  3219. static void LD(void)
  3220. {
  3221. check_r0_irt();
  3222. interp_addr+=4;
  3223. address = iimmediate + irs32;
  3224. rdword = (unsigned long long *) &irt;
  3225. read_dword_in_memory();
  3226. }
  3227.  
  3228. static void SC(void)
  3229. {
  3230. check_r0_irt();
  3231. interp_addr+=4;
  3232. if(llbit)
  3233. {
  3234. address = iimmediate + irs32;
  3235. word = (unsigned int)(irt & 0xFFFFFFFF);
  3236. write_word_in_memory();
  3237. llbit = 0;
  3238. irt = 1;
  3239. }
  3240. else
  3241. {
  3242. irt = 0;
  3243. }
  3244. }
  3245.  
  3246. static void SWC1(void)
  3247. {
  3248. if (check_cop1_unusable()) return;
  3249. interp_addr+=4;
  3250. address = (unsigned int) (lfoffset + reg[lfbase]);
  3251. word = *((int*)reg_cop1_simple[lfft]);
  3252. write_word_in_memory();
  3253. }
  3254.  
  3255. static void SDC1(void)
  3256. {
  3257. if (check_cop1_unusable()) return;
  3258. interp_addr+=4;
  3259. address = (unsigned int) (lfoffset + reg[lfbase]);
  3260. dword = *((unsigned long long*)reg_cop1_double[lfft]);
  3261. write_dword_in_memory();
  3262. }
  3263.  
  3264. static void SD(void)
  3265. {
  3266. interp_addr+=4;
  3267. address = iimmediate + irs32;
  3268. dword = irt;
  3269. write_dword_in_memory();
  3270. }
  3271.  
  3272. void (*interp_ops[64])(void) =
  3273. {
  3274. SPECIAL, REGIMM, J , JAL , BEQ , BNE , BLEZ , BGTZ ,
  3275. ADDI , ADDIU , SLTI, SLTIU, ANDI, ORI , XORI , LUI ,
  3276. COP0 , COP1 , NI , NI , BEQL, BNEL, BLEZL, BGTZL,
  3277. DADDI , DADDIU, LDL , LDR , NI , NI , NI , NI ,
  3278. LB , LH , LWL , LW , LBU , LHU , LWR , LWU ,
  3279. SB , SH , SWL , SW , SDL , SDR , SWR , CACHE,
  3280. LL , LWC1 , NI , NI , NI , LDC1, NI , LD ,
  3281. SC , SWC1 , NI , NI , NI , SDC1, NI , SD
  3282. };
  3283.  
  3284. void prefetch(void)
  3285. {
  3286. if ((interp_addr >= 0x80000000) && (interp_addr < 0xc0000000))
  3287. {
  3288. if ((interp_addr >= 0x80000000) && (interp_addr < 0x80800000))
  3289. {
  3290. op = rdram[(interp_addr&0xFFFFFF)/4];
  3291. prefetch_opcode(op);
  3292. }
  3293. else if ((interp_addr >= 0xa4000000) && (interp_addr < 0xa4001000))
  3294. {
  3295. op = SP_DMEM[(interp_addr&0xFFF)/4];
  3296. prefetch_opcode(op);
  3297. }
  3298. else if ((interp_addr > 0xb0000000))
  3299. {
  3300. op = ((unsigned int*)rom)[(interp_addr & 0xFFFFFFF)/4];
  3301. prefetch_opcode(op);
  3302. }
  3303. else
  3304. {
  3305. DebugMessage(M64MSG_ERROR, "prefetch() execute address :%x", (int)interp_addr);
  3306. stop=1;
  3307. }
  3308. }
  3309. else
  3310. {
  3311. unsigned int addr = interp_addr, phys;
  3312. phys = virtual_to_physical_address(interp_addr, 2);
  3313. if (phys != 0x00000000) interp_addr = phys;
  3314. else
  3315. {
  3316. prefetch();
  3317. //tlb_used = 0;
  3318. return;
  3319. }
  3320. //tlb_used = 1;
  3321. prefetch();
  3322. //tlb_used = 0;
  3323. interp_addr = addr;
  3324. }
  3325. }
  3326.  
  3327. void pure_interpreter(void)
  3328. {
  3329. interp_addr = 0xa4000040;
  3330. stop=0;
  3331. PC = (precomp_instr *) malloc(sizeof(precomp_instr));
  3332. PC->addr = last_addr = interp_addr;
  3333.  
  3334. /*#ifdef DBG
  3335. if (g_DebuggerActive)
  3336. update_debugger(PC->addr);
  3337. #endif*/
  3338.  
  3339. while (!stop)
  3340. {
  3341. prefetch();
  3342. #ifdef COMPARE_CORE
  3343. CoreCompareCallback();
  3344. #endif
  3345. #ifdef DBG
  3346. PC->addr = interp_addr;
  3347. if (g_DebuggerActive) update_debugger(PC->addr);
  3348. #endif
  3349. interp_ops[((op >> 26) & 0x3F)]();
  3350. }
  3351. PC->addr = interp_addr;
  3352. }
Add Comment
Please, Sign In to add comment