CORE: Some more try on new_dynarec (no effect it seems
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / r4300.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - r4300.c                                                 *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2002 Hacktarux                                          *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "api/m64p_types.h"
26 #include "api/callbacks.h"
27 #include "api/debugger.h"
28 #include "memory/memory.h"
29 #include "main/main.h"
30 #include "main/rom.h"
31
32 #include "r4300.h"
33 #include "ops.h"
34 #include "exception.h"
35 #include "interupt.h"
36 #include "macros.h"
37 #include "recomp.h"
38 #include "recomph.h"
39 #include "new_dynarec/new_dynarec.h"
40
41 #ifdef DBG
42 #include "debugger/dbg_types.h"
43 #include "debugger/debugger.h"
44 #endif
45
46 unsigned int r4300emu = 0;
47 int no_compiled_jump = 0;
48 int llbit, rompause;
49 #if NEW_DYNAREC != NEW_DYNAREC_ARM
50 int stop;
51 long long int reg[32], hi, lo;
52 unsigned int reg_cop0[32];
53 float *reg_cop1_simple[32];
54 double *reg_cop1_double[32];
55 int FCR0, FCR31;
56 unsigned int next_interupt;
57 precomp_instr *PC;
58 #endif
59 long long int local_rs;
60 long long int reg_cop1_fgr_64[32];
61 tlb tlb_e[32];
62 unsigned int delay_slot, skip_jump = 0, dyna_interp = 0, last_addr;
63 unsigned int CIC_Chip;
64 char invalid_code[0x100000];
65
66 precomp_block *blocks[0x100000], *actual;
67 int rounding_mode = 0x33F, trunc_mode = 0xF3F, round_mode = 0x33F,
68     ceil_mode = 0xB3F, floor_mode = 0x73F;
69
70 // -----------------------------------------------------------
71 // Cached interpreter functions (and fallback for dynarec).
72 // -----------------------------------------------------------
73 #ifdef DBG
74 #define UPDATE_DEBUGGER() if (g_DebuggerActive) update_debugger(PC->addr)
75 #else
76 #define UPDATE_DEBUGGER() do { } while(0)
77 #endif
78
79 #define PCADDR PC->addr
80 #define ADD_TO_PC(x) PC += x;
81 #define DECLARE_INSTRUCTION(name) static void name(void)
82
83 #define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \
84    static void name(void) \
85    { \
86       const int take_jump = (condition); \
87       const unsigned int jump_target = (destination); \
88       long long int *link_register = (link); \
89       if (cop1 && check_cop1_unusable()) return; \
90       if (!likely || take_jump) \
91       { \
92          PC++; \
93          delay_slot=1; \
94          UPDATE_DEBUGGER(); \
95          PC->ops(); \
96          update_count(); \
97          delay_slot=0; \
98          if (take_jump && !skip_jump) \
99          { \
100             if (link_register != &reg[0]) \
101             { \
102                *link_register=PC->addr; \
103                sign_extended(*link_register); \
104             } \
105             PC=actual->block+((jump_target-actual->start)>>2); \
106          } \
107       } \
108       else \
109       { \
110          PC += 2; \
111          update_count(); \
112       } \
113       last_addr = PC->addr; \
114       if (next_interupt <= Count) gen_interupt(); \
115    } \
116    static void name##_OUT(void) \
117    { \
118       const int take_jump = (condition); \
119       const unsigned int jump_target = (destination); \
120       long long int *link_register = (link); \
121       if (cop1 && check_cop1_unusable()) return; \
122       if (!likely || take_jump) \
123       { \
124          PC++; \
125          delay_slot=1; \
126          UPDATE_DEBUGGER(); \
127          PC->ops(); \
128          update_count(); \
129          delay_slot=0; \
130          if (take_jump && !skip_jump) \
131          { \
132             if (link_register != &reg[0]) \
133             { \
134                *link_register=PC->addr; \
135                sign_extended(*link_register); \
136             } \
137             jump_to(jump_target); \
138          } \
139       } \
140       else \
141       { \
142          PC += 2; \
143          update_count(); \
144       } \
145       last_addr = PC->addr; \
146       if (next_interupt <= Count) gen_interupt(); \
147    } \
148    static void name##_IDLE(void) \
149    { \
150       const int take_jump = (condition); \
151       int skip; \
152       if (cop1 && check_cop1_unusable()) return; \
153       if (take_jump) \
154       { \
155          update_count(); \
156          skip = next_interupt - Count; \
157          if (skip > 3) Count += (skip & 0xFFFFFFFC); \
158          else name(); \
159       } \
160       else name(); \
161    }
162
163 #define CHECK_MEMORY() \
164    if (!invalid_code[address>>12]) \
165       if (blocks[address>>12]->block[(address&0xFFF)/4].ops != \
166           current_instruction_table.NOTCOMPILED) \
167          invalid_code[address>>12] = 1;
168
169 #include "interpreter.def"
170
171 // two functions are defined from the macros above but never used
172 // these prototype declarations will prevent a warning
173 #if defined(__GNUC__)
174   void JR_IDLE(void) __attribute__((used));
175   void JALR_IDLE(void) __attribute__((used));
176 #endif
177
178 // -----------------------------------------------------------
179 // Flow control 'fake' instructions
180 // -----------------------------------------------------------
181 static void FIN_BLOCK(void)
182 {
183    if (!delay_slot)
184      {
185     jump_to((PC-1)->addr+4);
186 /*#ifdef DBG
187             if (g_DebuggerActive) update_debugger(PC->addr);
188 #endif
189 Used by dynarec only, check should be unnecessary
190 */
191     PC->ops();
192     if (r4300emu == CORE_DYNAREC) dyna_jump();
193      }
194    else
195      {
196     precomp_block *blk = actual;
197     precomp_instr *inst = PC;
198     jump_to((PC-1)->addr+4);
199     
200 /*#ifdef DBG
201             if (g_DebuggerActive) update_debugger(PC->addr);
202 #endif
203 Used by dynarec only, check should be unnecessary
204 */
205     if (!skip_jump)
206       {
207          PC->ops();
208          actual = blk;
209          PC = inst+1;
210       }
211     else
212       PC->ops();
213     
214     if (r4300emu == CORE_DYNAREC) dyna_jump();
215      }
216 }
217
218 static void NOTCOMPILED(void)
219 {
220    unsigned int *mem = fast_mem_access(blocks[PC->addr>>12]->start);
221 #ifdef CORE_DBG
222    DebugMessage(M64MSG_INFO, "NOTCOMPILED: addr = %x ops = %lx", PC->addr, (long) PC->ops);
223 #endif
224
225    if (mem != NULL)
226       recompile_block((int *)mem, blocks[PC->addr >> 12], PC->addr);
227    else
228       DebugMessage(M64MSG_ERROR, "not compiled exception");
229
230 /*#ifdef DBG
231             if (g_DebuggerActive) update_debugger(PC->addr);
232 #endif
233 The preceeding update_debugger SHOULD be unnecessary since it should have been
234 called before NOTCOMPILED would have been executed
235 */
236    PC->ops();
237    if (r4300emu == CORE_DYNAREC)
238      dyna_jump();
239 }
240
241 static void NOTCOMPILED2(void)
242 {
243    NOTCOMPILED();
244 }
245
246 // -----------------------------------------------------------
247 // Cached interpreter instruction table
248 // -----------------------------------------------------------
249 const cpu_instruction_table cached_interpreter_table = {
250    LB,
251    LBU,
252    LH,
253    LHU,
254    LW,
255    LWL,
256    LWR,
257    SB,
258    SH,
259    SW,
260    SWL,
261    SWR,
262
263    LD,
264    LDL,
265    LDR,
266    LL,
267    LWU,
268    SC,
269    SD,
270    SDL,
271    SDR,
272    SYNC,
273
274    ADDI,
275    ADDIU,
276    SLTI,
277    SLTIU,
278    ANDI,
279    ORI,
280    XORI,
281    LUI,
282
283    DADDI,
284    DADDIU,
285
286    ADD,
287    ADDU,
288    SUB,
289    SUBU,
290    SLT,
291    SLTU,
292    AND,
293    OR,
294    XOR,
295    NOR,
296
297    DADD,
298    DADDU,
299    DSUB,
300    DSUBU,
301
302    MULT,
303    MULTU,
304    DIV,
305    DIVU,
306    MFHI,
307    MTHI,
308    MFLO,
309    MTLO,
310
311    DMULT,
312    DMULTU,
313    DDIV,
314    DDIVU,
315
316    J,
317    J_OUT,
318    J_IDLE,
319    JAL,
320    JAL_OUT,
321    JAL_IDLE,
322    // Use the _OUT versions of JR and JALR, since we don't know
323    // until runtime if they're going to jump inside or outside the block
324    JR_OUT,
325    JALR_OUT,
326    BEQ,
327    BEQ_OUT,
328    BEQ_IDLE,
329    BNE,
330    BNE_OUT,
331    BNE_IDLE,
332    BLEZ,
333    BLEZ_OUT,
334    BLEZ_IDLE,
335    BGTZ,
336    BGTZ_OUT,
337    BGTZ_IDLE,
338    BLTZ,
339    BLTZ_OUT,
340    BLTZ_IDLE,
341    BGEZ,
342    BGEZ_OUT,
343    BGEZ_IDLE,
344    BLTZAL,
345    BLTZAL_OUT,
346    BLTZAL_IDLE,
347    BGEZAL,
348    BGEZAL_OUT,
349    BGEZAL_IDLE,
350
351    BEQL,
352    BEQL_OUT,
353    BEQL_IDLE,
354    BNEL,
355    BNEL_OUT,
356    BNEL_IDLE,
357    BLEZL,
358    BLEZL_OUT,
359    BLEZL_IDLE,
360    BGTZL,
361    BGTZL_OUT,
362    BGTZL_IDLE,
363    BLTZL,
364    BLTZL_OUT,
365    BLTZL_IDLE,
366    BGEZL,
367    BGEZL_OUT,
368    BGEZL_IDLE,
369    BLTZALL,
370    BLTZALL_OUT,
371    BLTZALL_IDLE,
372    BGEZALL,
373    BGEZALL_OUT,
374    BGEZALL_IDLE,
375    BC1TL,
376    BC1TL_OUT,
377    BC1TL_IDLE,
378    BC1FL,
379    BC1FL_OUT,
380    BC1FL_IDLE,
381
382    SLL,
383    SRL,
384    SRA,
385    SLLV,
386    SRLV,
387    SRAV,
388
389    DSLL,
390    DSRL,
391    DSRA,
392    DSLLV,
393    DSRLV,
394    DSRAV,
395    DSLL32,
396    DSRL32,
397    DSRA32,
398
399    MTC0,
400    MFC0,
401
402    TLBR,
403    TLBWI,
404    TLBWR,
405    TLBP,
406    CACHE,
407    ERET,
408
409    LWC1,
410    SWC1,
411    MTC1,
412    MFC1,
413    CTC1,
414    CFC1,
415    BC1T,
416    BC1T_OUT,
417    BC1T_IDLE,
418    BC1F,
419    BC1F_OUT,
420    BC1F_IDLE,
421
422    DMFC1,
423    DMTC1,
424    LDC1,
425    SDC1,
426
427    CVT_S_D,
428    CVT_S_W,
429    CVT_S_L,
430    CVT_D_S,
431    CVT_D_W,
432    CVT_D_L,
433    CVT_W_S,
434    CVT_W_D,
435    CVT_L_S,
436    CVT_L_D,
437
438    ROUND_W_S,
439    ROUND_W_D,
440    ROUND_L_S,
441    ROUND_L_D,
442
443    TRUNC_W_S,
444    TRUNC_W_D,
445    TRUNC_L_S,
446    TRUNC_L_D,
447
448    CEIL_W_S,
449    CEIL_W_D,
450    CEIL_L_S,
451    CEIL_L_D,
452
453    FLOOR_W_S,
454    FLOOR_W_D,
455    FLOOR_L_S,
456    FLOOR_L_D,
457
458    ADD_S,
459    ADD_D,
460
461    SUB_S,
462    SUB_D,
463
464    MUL_S,
465    MUL_D,
466
467    DIV_S,
468    DIV_D,
469    
470    ABS_S,
471    ABS_D,
472
473    MOV_S,
474    MOV_D,
475
476    NEG_S,
477    NEG_D,
478
479    SQRT_S,
480    SQRT_D,
481
482    C_F_S,
483    C_F_D,
484    C_UN_S,
485    C_UN_D,
486    C_EQ_S,
487    C_EQ_D,
488    C_UEQ_S,
489    C_UEQ_D,
490    C_OLT_S,
491    C_OLT_D,
492    C_ULT_S,
493    C_ULT_D,
494    C_OLE_S,
495    C_OLE_D,
496    C_ULE_S,
497    C_ULE_D,
498    C_SF_S,
499    C_SF_D,
500    C_NGLE_S,
501    C_NGLE_D,
502    C_SEQ_S,
503    C_SEQ_D,
504    C_NGL_S,
505    C_NGL_D,
506    C_LT_S,
507    C_LT_D,
508    C_NGE_S,
509    C_NGE_D,
510    C_LE_S,
511    C_LE_D,
512    C_NGT_S,
513    C_NGT_D,
514
515    SYSCALL,
516
517    TEQ,
518
519    NOP,
520    RESERVED,
521    NI,
522
523    FIN_BLOCK,
524    NOTCOMPILED,
525    NOTCOMPILED2
526 };
527
528 cpu_instruction_table current_instruction_table;
529
530 static unsigned int update_invalid_addr(unsigned int addr)
531 {
532    if (addr >= 0x80000000 && addr < 0xa0000000)
533      {
534     if (invalid_code[addr>>12]) invalid_code[(addr+0x20000000)>>12] = 1;
535     if (invalid_code[(addr+0x20000000)>>12]) invalid_code[addr>>12] = 1;
536     return addr;
537      }
538    else if (addr >= 0xa0000000 && addr < 0xc0000000)
539      {
540     if (invalid_code[addr>>12]) invalid_code[(addr-0x20000000)>>12] = 1;
541     if (invalid_code[(addr-0x20000000)>>12]) invalid_code[addr>>12] = 1;
542     return addr;
543      }
544    else
545      {
546     unsigned int paddr = virtual_to_physical_address(addr, 2);
547     if (paddr)
548       {
549          unsigned int beg_paddr = paddr - (addr - (addr&~0xFFF));
550          update_invalid_addr(paddr);
551          if (invalid_code[(beg_paddr+0x000)>>12]) invalid_code[addr>>12] = 1;
552          if (invalid_code[(beg_paddr+0xFFC)>>12]) invalid_code[addr>>12] = 1;
553          if (invalid_code[addr>>12]) invalid_code[(beg_paddr+0x000)>>12] = 1;
554          if (invalid_code[addr>>12]) invalid_code[(beg_paddr+0xFFC)>>12] = 1;
555       }
556     return paddr;
557      }
558 }
559
560 #define addr jump_to_address
561 unsigned int jump_to_address;
562 void jump_to_func(void)
563 {
564    unsigned int paddr;
565    if (skip_jump) return;
566    paddr = update_invalid_addr(addr);
567    if (!paddr) return;
568    actual = blocks[addr>>12];
569    if (invalid_code[addr>>12])
570      {
571     if (!blocks[addr>>12])
572       {
573          blocks[addr>>12] = (precomp_block *) malloc(sizeof(precomp_block));
574          actual = blocks[addr>>12];
575          blocks[addr>>12]->code = NULL;
576          blocks[addr>>12]->block = NULL;
577          blocks[addr>>12]->jumps_table = NULL;
578          blocks[addr>>12]->riprel_table = NULL;
579       }
580     blocks[addr>>12]->start = addr & ~0xFFF;
581     blocks[addr>>12]->end = (addr & ~0xFFF) + 0x1000;
582     init_block(blocks[addr>>12]);
583      }
584    PC=actual->block+((addr-actual->start)>>2);
585    
586    if (r4300emu == CORE_DYNAREC) dyna_jump();
587 }
588 #undef addr
589
590 void generic_jump_to(unsigned int address)
591 {
592    if (r4300emu == CORE_PURE_INTERPRETER)
593       PC->addr = address;
594    else {
595 #ifdef NEW_DYNAREC
596       if (r4300emu == CORE_DYNAREC)
597          last_addr = pcaddr;
598       else
599          jump_to(address);
600 #else
601       jump_to(address);
602 #endif
603    }
604 }
605
606 /* Refer to Figure 6-2 on page 155 and explanation on page B-11
607    of MIPS R4000 Microprocessor User's Manual (Second Edition)
608    by Joe Heinrich.
609 */
610 void shuffle_fpr_data(int oldStatus, int newStatus)
611 {
612 #if defined(M64P_BIG_ENDIAN)
613     const int isBigEndian = 1;
614 #else
615     const int isBigEndian = 0;
616 #endif
617
618     if ((newStatus & 0x04000000) != (oldStatus & 0x04000000))
619     {
620         int i;
621         int temp_fgr_32[32];
622
623         // pack or unpack the FGR register data
624         if (newStatus & 0x04000000)
625         {   // switching into 64-bit mode
626             // retrieve 32 FPR values from packed 32-bit FGR registers
627             for (i = 0; i < 32; i++)
628             {
629                 temp_fgr_32[i] = *((int *) &reg_cop1_fgr_64[i>>1] + ((i & 1) ^ isBigEndian));
630             }
631             // unpack them into 32 64-bit registers, taking the high 32-bits from their temporary place in the upper 16 FGRs
632             for (i = 0; i < 32; i++)
633             {
634                 int high32 = *((int *) &reg_cop1_fgr_64[(i>>1)+16] + (i & 1));
635                 *((int *) &reg_cop1_fgr_64[i] + isBigEndian)     = temp_fgr_32[i];
636                 *((int *) &reg_cop1_fgr_64[i] + (isBigEndian^1)) = high32;
637             }
638         }
639         else
640         {   // switching into 32-bit mode
641             // retrieve the high 32 bits from each 64-bit FGR register and store in temp array
642             for (i = 0; i < 32; i++)
643             {
644                 temp_fgr_32[i] = *((int *) &reg_cop1_fgr_64[i] + (isBigEndian^1));
645             }
646             // take the low 32 bits from each register and pack them together into 64-bit pairs
647             for (i = 0; i < 16; i++)
648             {
649                 unsigned int least32 = *((unsigned int *) &reg_cop1_fgr_64[i*2] + isBigEndian);
650                 unsigned int most32 = *((unsigned int *) &reg_cop1_fgr_64[i*2+1] + isBigEndian);
651                 reg_cop1_fgr_64[i] = ((unsigned long long) most32 << 32) | (unsigned long long) least32;
652             }
653             // store the high bits in the upper 16 FGRs, which wont be accessible in 32-bit mode
654             for (i = 0; i < 32; i++)
655             {
656                 *((int *) &reg_cop1_fgr_64[(i>>1)+16] + (i & 1)) = temp_fgr_32[i];
657             }
658         }
659     }
660 }
661
662 void set_fpr_pointers(int newStatus)
663 {
664     int i;
665 #if defined(M64P_BIG_ENDIAN)
666     const int isBigEndian = 1;
667 #else
668     const int isBigEndian = 0;
669 #endif
670
671     // update the FPR register pointers
672     if (newStatus & 0x04000000)
673     {
674         for (i = 0; i < 32; i++)
675         {
676             reg_cop1_double[i] = (double*) &reg_cop1_fgr_64[i];
677             reg_cop1_simple[i] = ((float*) &reg_cop1_fgr_64[i]) + isBigEndian;
678         }
679     }
680     else
681     {
682         for (i = 0; i < 32; i++)
683         {
684             reg_cop1_double[i] = (double*) &reg_cop1_fgr_64[i>>1];
685             reg_cop1_simple[i] = ((float*) &reg_cop1_fgr_64[i>>1]) + ((i & 1) ^ isBigEndian);
686         }
687     }
688 }
689
690 int check_cop1_unusable(void)
691 {
692    if (!(Status & 0x20000000))
693      {
694     Cause = (11 << 2) | 0x10000000;
695     exception_general();
696     return 1;
697      }
698    return 0;
699 }
700
701 void update_count(void)
702 {
703 #ifdef NEW_DYNAREC
704     if (r4300emu != CORE_DYNAREC)
705     {
706 #endif
707         Count = Count + (PC->addr - last_addr)/2;
708         last_addr = PC->addr;
709 #ifdef NEW_DYNAREC
710     }
711 #endif
712
713 #ifdef COMPARE_CORE
714    if (delay_slot)
715      CoreCompareCallback();
716 #endif
717 /*#ifdef DBG
718    if (g_DebuggerActive && !delay_slot) update_debugger(PC->addr);
719 #endif
720 */
721 }
722
723 void init_blocks(void)
724 {
725    int i;
726    for (i=0; i<0x100000; i++)
727    {
728       invalid_code[i] = 1;
729       blocks[i] = NULL;
730    }
731 }
732
733 void free_blocks(void)
734 {
735    int i;
736    for (i=0; i<0x100000; i++)
737    {
738         if (blocks[i])
739         {
740             free_block(blocks[i]);
741             free(blocks[i]);
742             blocks[i] = NULL;
743         }
744     }
745 }
746
747 /* this hard reset function simulates the boot-up state of the R4300 CPU */
748 void r4300_reset_hard(void)
749 {
750     unsigned int i;
751
752     // clear r4300 registers and TLB entries
753     for (i = 0; i < 32; i++)
754     {
755         reg[i]=0;
756         reg_cop0[i]=0;
757         reg_cop1_fgr_64[i]=0;
758
759         // --------------tlb------------------------
760         tlb_e[i].mask=0;
761         tlb_e[i].vpn2=0;
762         tlb_e[i].g=0;
763         tlb_e[i].asid=0;
764         tlb_e[i].pfn_even=0;
765         tlb_e[i].c_even=0;
766         tlb_e[i].d_even=0;
767         tlb_e[i].v_even=0;
768         tlb_e[i].pfn_odd=0;
769         tlb_e[i].c_odd=0;
770         tlb_e[i].d_odd=0;
771         tlb_e[i].v_odd=0;
772         tlb_e[i].r=0;
773         //tlb_e[i].check_parity_mask=0x1000;
774
775         tlb_e[i].start_even=0;
776         tlb_e[i].end_even=0;
777         tlb_e[i].phys_even=0;
778         tlb_e[i].start_odd=0;
779         tlb_e[i].end_odd=0;
780         tlb_e[i].phys_odd=0;
781     }
782     for (i=0; i<0x100000; i++)
783     {
784         tlb_LUT_r[i] = 0;
785         tlb_LUT_w[i] = 0;
786     }
787     llbit=0;
788     hi=0;
789     lo=0;
790     FCR0=0x511;
791     FCR31=0;
792
793     // set COP0 registers
794     Random = 31;
795     Status= 0x34000000;
796     set_fpr_pointers(Status);
797     Config= 0x6e463;
798     PRevID = 0xb00;
799     Count = 0x5000;
800     Cause = 0x5C;
801     Context = 0x7FFFF0;
802     EPC = 0xFFFFFFFF;
803     BadVAddr = 0xFFFFFFFF;
804     ErrorEPC = 0xFFFFFFFF;
805    
806     rounding_mode = 0x33F;
807 }
808
809 /* this soft reset function simulates the actions of the PIF ROM, which may vary by region
810  * TODO: accurately simulate the effects of the PIF ROM in the case of a soft reset
811  *       (e.g. Goldeneye crashes) */
812 void r4300_reset_soft(void)
813 {
814     long long CRC = 0;
815     unsigned int i;
816
817     // copy boot code from ROM to SP_DMEM
818     memcpy((char *)SP_DMEM+0x40, rom+0x40, 0xFC0);
819
820    // the following values are extracted from the pj64 source code
821    // thanks to Zilmar and Jabo
822    
823    reg[6] = 0xFFFFFFFFA4001F0CLL;
824    reg[7] = 0xFFFFFFFFA4001F08LL;
825    reg[8] = 0x00000000000000C0LL;
826    reg[10]= 0x0000000000000040LL;
827    reg[11]= 0xFFFFFFFFA4000040LL;
828    reg[29]= 0xFFFFFFFFA4001FF0LL;
829    
830     // figure out which ROM type is loaded
831    for (i = 0x40/4; i < (0x1000/4); i++)
832      CRC += SP_DMEM[i];
833    switch(CRC) {
834     case 0x000000D0027FDF31LL:
835     case 0x000000CFFB631223LL:
836       CIC_Chip = 1;
837       break;
838     case 0x000000D057C85244LL:
839       CIC_Chip = 2;
840       break;
841     case 0x000000D6497E414BLL:
842       CIC_Chip = 3;
843       break;
844     case 0x0000011A49F60E96LL:
845       CIC_Chip = 5;
846       break;
847     case 0x000000D6D5BE5580LL:
848       CIC_Chip = 6;
849       break;
850     default:
851       CIC_Chip = 2;
852    }
853
854    switch(ROM_PARAMS.systemtype)
855      {
856       case SYSTEM_PAL:
857     switch (CIC_Chip) {
858      case 2:
859        reg[5] = 0xFFFFFFFFC0F1D859LL;
860        reg[14]= 0x000000002DE108EALL;
861        break;
862      case 3:
863        reg[5] = 0xFFFFFFFFD4646273LL;
864        reg[14]= 0x000000001AF99984LL;
865        break;
866      case 5:
867        SP_IMEM[1] = 0xBDA807FC;
868        reg[5] = 0xFFFFFFFFDECAAAD1LL;
869        reg[14]= 0x000000000CF85C13LL;
870        reg[24]= 0x0000000000000002LL;
871        break;
872      case 6:
873        reg[5] = 0xFFFFFFFFB04DC903LL;
874        reg[14]= 0x000000001AF99984LL;
875        reg[24]= 0x0000000000000002LL;
876        break;
877     }
878     reg[23]= 0x0000000000000006LL;
879     reg[31]= 0xFFFFFFFFA4001554LL;
880     break;
881       case SYSTEM_NTSC:
882       default:
883     switch (CIC_Chip) {
884      case 2:
885        reg[5] = 0xFFFFFFFFC95973D5LL;
886        reg[14]= 0x000000002449A366LL;
887        break;
888      case 3:
889        reg[5] = 0xFFFFFFFF95315A28LL;
890        reg[14]= 0x000000005BACA1DFLL;
891        break;
892      case 5:
893        SP_IMEM[1] = 0x8DA807FC;
894        reg[5] = 0x000000005493FB9ALL;
895        reg[14]= 0xFFFFFFFFC2C20384LL;
896        break;
897      case 6:
898        reg[5] = 0xFFFFFFFFE067221FLL;
899        reg[14]= 0x000000005CD2B70FLL;
900        break;
901     }
902     reg[20]= 0x0000000000000001LL;
903     reg[24]= 0x0000000000000003LL;
904     reg[31]= 0xFFFFFFFFA4001550LL;
905      }
906    switch (CIC_Chip) {
907     case 1:
908       reg[22]= 0x000000000000003FLL;
909       break;
910     case 2:
911       reg[1] = 0x0000000000000001LL;
912       reg[2] = 0x000000000EBDA536LL;
913       reg[3] = 0x000000000EBDA536LL;
914       reg[4] = 0x000000000000A536LL;
915       reg[12]= 0xFFFFFFFFED10D0B3LL;
916       reg[13]= 0x000000001402A4CCLL;
917       reg[15]= 0x000000003103E121LL;
918       reg[22]= 0x000000000000003FLL;
919       reg[25]= 0xFFFFFFFF9DEBB54FLL;
920       break;
921     case 3:
922       reg[1] = 0x0000000000000001LL;
923       reg[2] = 0x0000000049A5EE96LL;
924       reg[3] = 0x0000000049A5EE96LL;
925       reg[4] = 0x000000000000EE96LL;
926       reg[12]= 0xFFFFFFFFCE9DFBF7LL;
927       reg[13]= 0xFFFFFFFFCE9DFBF7LL;
928       reg[15]= 0x0000000018B63D28LL;
929       reg[22]= 0x0000000000000078LL;
930       reg[25]= 0xFFFFFFFF825B21C9LL;
931       break;
932     case 5:
933       SP_IMEM[0] = 0x3C0DBFC0;
934       SP_IMEM[2] = 0x25AD07C0;
935       SP_IMEM[3] = 0x31080080;
936       SP_IMEM[4] = 0x5500FFFC;
937       SP_IMEM[5] = 0x3C0DBFC0;
938       SP_IMEM[6] = 0x8DA80024;
939       SP_IMEM[7] = 0x3C0BB000;
940       reg[2] = 0xFFFFFFFFF58B0FBFLL;
941       reg[3] = 0xFFFFFFFFF58B0FBFLL;
942       reg[4] = 0x0000000000000FBFLL;
943       reg[12]= 0xFFFFFFFF9651F81ELL;
944       reg[13]= 0x000000002D42AAC5LL;
945       reg[15]= 0x0000000056584D60LL;
946       reg[22]= 0x0000000000000091LL;
947       reg[25]= 0xFFFFFFFFCDCE565FLL;
948       break;
949     case 6:
950       reg[2] = 0xFFFFFFFFA95930A4LL;
951       reg[3] = 0xFFFFFFFFA95930A4LL;
952       reg[4] = 0x00000000000030A4LL;
953       reg[12]= 0xFFFFFFFFBCB59510LL;
954       reg[13]= 0xFFFFFFFFBCB59510LL;
955       reg[15]= 0x000000007A3C07F4LL;
956       reg[22]= 0x0000000000000085LL;
957       reg[25]= 0x00000000465E3F72LL;
958       break;
959    }
960
961 }
962
963 #if !defined(NO_ASM)
964 static void dynarec_setup_code(void)
965 {
966    // The dynarec jumps here after we call dyna_start and it prepares
967    // Here we need to prepare the initial code block and jump to it
968    jump_to(0xa4000040);
969
970    // Prevent segfault on failed jump_to
971    if (!actual->block || !actual->code)
972       dyna_stop();
973 }
974 #endif
975
976 void r4300_execute(void)
977 {
978 #if defined(COUNT_INSTR) || (defined(DYNAREC) && defined(PROFILE_R4300))
979     unsigned int i;
980 #endif
981
982     current_instruction_table = cached_interpreter_table;
983
984     delay_slot=0;
985     stop = 0;
986     rompause = 0;
987
988     /* clear instruction counters */
989 #if defined(COUNT_INSTR)
990     for (i = 0; i < 131; i++)
991         instr_count[i] = 0;
992 #endif
993
994     last_addr = 0xa4000040;
995     next_interupt = 624999;
996     init_interupt();
997
998     if (r4300emu == CORE_PURE_INTERPRETER)
999     {
1000         DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Pure Interpreter");
1001         r4300emu = CORE_PURE_INTERPRETER;
1002         pure_interpreter();
1003     }
1004 #if defined(DYNAREC)
1005     else if (r4300emu >= 2)
1006     {
1007         DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Dynamic Recompiler");
1008         r4300emu = CORE_DYNAREC;
1009         init_blocks();
1010
1011 #ifdef NEW_DYNAREC
1012         new_dynarec_init();
1013         new_dyna_start();
1014         new_dynarec_cleanup();
1015 #else
1016         dyna_start(dynarec_setup_code);
1017         PC++;
1018 #endif
1019 #if defined(PROFILE_R4300)
1020         pfProfile = fopen("instructionaddrs.dat", "ab");
1021         for (i=0; i<0x100000; i++)
1022             if (invalid_code[i] == 0 && blocks[i] != NULL && blocks[i]->code != NULL && blocks[i]->block != NULL)
1023             {
1024                 unsigned char *x86addr;
1025                 int mipsop;
1026                 // store final code length for this block
1027                 mipsop = -1; /* -1 == end of x86 code block */
1028                 x86addr = blocks[i]->code + blocks[i]->code_length;
1029                 if (fwrite(&mipsop, 1, 4, pfProfile) != 4 ||
1030                     fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *))
1031                     DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
1032             }
1033         fclose(pfProfile);
1034         pfProfile = NULL;
1035 #endif
1036         free_blocks();
1037     }
1038 #endif
1039     else /* if (r4300emu == CORE_INTERPRETER) */
1040     {
1041         DebugMessage(M64MSG_INFO, "Starting R4300 emulator: Cached Interpreter");
1042         r4300emu = CORE_INTERPRETER;
1043         init_blocks();
1044         jump_to(0xa4000040);
1045
1046         /* Prevent segfault on failed jump_to */
1047         if (!actual->block)
1048             return;
1049
1050         last_addr = PC->addr;
1051         while (!stop)
1052         {
1053 #ifdef COMPARE_CORE
1054             if (PC->ops == FIN_BLOCK && (PC->addr < 0x80000000 || PC->addr >= 0xc0000000))
1055                 virtual_to_physical_address(PC->addr, 2);
1056             CoreCompareCallback();
1057 #endif
1058 #ifdef DBG
1059             if (g_DebuggerActive) update_debugger(PC->addr);
1060 #endif
1061             PC->ops();
1062         }
1063
1064         free_blocks();
1065     }
1066
1067     DebugMessage(M64MSG_INFO, "R4300 emulator finished.");
1068
1069     /* print instruction counts */
1070 #if defined(COUNT_INSTR)
1071     if (r4300emu == CORE_DYNAREC)
1072     {
1073         unsigned int iTypeCount[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1074         unsigned int iTotal = 0;
1075         char line[128], param[24];
1076         DebugMessage(M64MSG_INFO, "Instruction counters:");
1077         line[0] = 0;
1078         for (i = 0; i < 131; i++)
1079         {
1080             sprintf(param, "%8s: %08i  ", instr_name[i], instr_count[i]);
1081             strcat(line, param);
1082             if (i % 5 == 4)
1083             {
1084                 DebugMessage(M64MSG_INFO, "%s", line);
1085                 line[0] = 0;
1086             }
1087             iTypeCount[instr_type[i]] += instr_count[i];
1088             iTotal += instr_count[i];
1089         }
1090         DebugMessage(M64MSG_INFO, "Instruction type summary (total instructions = %i)", iTotal);
1091         for (i = 0; i < 11; i++)
1092         {
1093             DebugMessage(M64MSG_INFO, "%20s: %04.1f%% (%i)", instr_typename[i], (float) iTypeCount[i] * 100.0 / iTotal, iTypeCount[i]);
1094         }
1095     }
1096 #endif
1097 }