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