drc: add some hack options
authornotaz <notasas@gmail.com>
Sun, 23 Oct 2011 01:17:42 +0000 (04:17 +0300)
committernotaz <notasas@gmail.com>
Sun, 30 Oct 2011 21:48:08 +0000 (23:48 +0200)
intended for caanoo/Wiz, some users want to trade glitches for
performance boost.

frontend/menu.c
libpcsxcore/new_dynarec/assem_arm.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/new_dynarec/new_dynarec.c
libpcsxcore/new_dynarec/new_dynarec.h

index 5d40d96..2a0de56 100644 (file)
@@ -185,6 +185,7 @@ static void menu_set_defconfig(void)
        frameskip = 0;
        analog_deadzone = 70;
        psx_clock = DEFAULT_PSX_CLOCK;
        frameskip = 0;
        analog_deadzone = 70;
        psx_clock = DEFAULT_PSX_CLOCK;
+       new_dynarec_hacks = 0;
 
        region = 0;
        in_type_sel1 = in_type_sel2 = 0;
 
        region = 0;
        in_type_sel1 = in_type_sel2 = 0;
@@ -282,6 +283,7 @@ static const struct {
        CE_INTVAL(in_evdev_allow_abs_only),
        CE_INTVAL(volume_boost),
        CE_INTVAL(psx_clock),
        CE_INTVAL(in_evdev_allow_abs_only),
        CE_INTVAL(volume_boost),
        CE_INTVAL(psx_clock),
+       CE_INTVAL(new_dynarec_hacks),
 };
 
 static char *get_cd_label(void)
 };
 
 static char *get_cd_label(void)
@@ -1203,6 +1205,27 @@ static int menu_loop_plugin_options(int id, int keys)
 
 // ------------ adv options menu ------------
 
 
 // ------------ adv options menu ------------
 
+static const char h_cfg_psxclk[]  = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n";
+static const char h_cfg_nosmc[]   = "Will cause crashes when loading";
+static const char h_cfg_gteunn[]  = "May cause graphical glitches";
+static const char h_cfg_gteflgs[] = "Will cause graphical glitches";
+
+static menu_entry e_menu_speed_hacks[] =
+{
+       mee_range_h   ("PSX CPU clock, %%",        0, psx_clock, 1, 500, h_cfg_psxclk),
+       mee_onoff_h   ("Disable SMC checks",       0, new_dynarec_hacks, NDHACK_NO_SMC_CHECK, h_cfg_nosmc),
+       mee_onoff_h   ("Assume GTE regs unneeded", 0, new_dynarec_hacks, NDHACK_GTE_UNNEEDED, h_cfg_gteunn),
+       mee_onoff_h   ("Disable GTE flags",        0, new_dynarec_hacks, NDHACK_GTE_NO_FLAGS, h_cfg_gteflgs),
+       mee_end,
+};
+
+static int menu_loop_speed_hacks(int id, int keys)
+{
+       static int sel = 0;
+       me_loop(e_menu_speed_hacks, &sel);
+       return 0;
+}
+
 static const char *men_cfg_cdrr[] = { "Auto", "ON", "OFF", NULL };
 static const char h_cfg_cpul[]   = "Shows CPU usage in %";
 static const char h_cfg_spu[]    = "Shows active SPU channels\n"
 static const char *men_cfg_cdrr[] = { "Auto", "ON", "OFF", NULL };
 static const char h_cfg_cpul[]   = "Shows CPU usage in %";
 static const char h_cfg_spu[]    = "Shows active SPU channels\n"
@@ -1217,12 +1240,11 @@ static const char h_cfg_rcnt1[]  = "Parasite Eve 2, Vandal Hearts 1/2 Fix\n"
                                   "(timing hack, breaks other games)";
 static const char h_cfg_rcnt2[]  = "InuYasha Sengoku Battle Fix\n"
                                   "(timing hack, breaks other games)";
                                   "(timing hack, breaks other games)";
 static const char h_cfg_rcnt2[]  = "InuYasha Sengoku Battle Fix\n"
                                   "(timing hack, breaks other games)";
-static const char h_cfg_cdrr[]   = "Compatibility tweak (fixes Team Buddies, maybe more)\n"
-                                  "(CD timing hack, breaks FMVs)";
-static const char h_cfg_psxclk[] = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n"
-                                  "(may break games, must reload game to take effect)";
+static const char h_cfg_cdrr[]   = "Compatibility tweak (CD timing hack, breaks FMVs)";
 static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpreter\n"
                                   "Might be useful to overcome some dynarec bugs";
 static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpreter\n"
                                   "Might be useful to overcome some dynarec bugs";
+static const char h_cfg_shacks[] = "Breaks games but may give better performance\n"
+                                  "must reload game for any change to take effect";
 
 static menu_entry e_menu_adv_options[] =
 {
 
 static menu_entry e_menu_adv_options[] =
 {
@@ -1236,8 +1258,8 @@ static menu_entry e_menu_adv_options[] =
        //mee_onoff_h   ("Rootcounter hack",       0, Config.RCntFix, 1, h_cfg_rcnt1),
        mee_onoff_h   ("Rootcounter hack 2",     0, Config.VSyncWA, 1, h_cfg_rcnt2),
        mee_enum_h    ("CD read reschedule hack",0, Config.CdrReschedule, men_cfg_cdrr, h_cfg_cdrr),
        //mee_onoff_h   ("Rootcounter hack",       0, Config.RCntFix, 1, h_cfg_rcnt1),
        mee_onoff_h   ("Rootcounter hack 2",     0, Config.VSyncWA, 1, h_cfg_rcnt2),
        mee_enum_h    ("CD read reschedule hack",0, Config.CdrReschedule, men_cfg_cdrr, h_cfg_cdrr),
-       mee_range_h   ("PSX CPU clock, %%",      0, psx_clock, 1, 500, h_cfg_psxclk),
        mee_onoff_h   ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
        mee_onoff_h   ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
+       mee_handler_h ("[Speed hacks]",             menu_loop_speed_hacks, h_cfg_shacks),
        mee_end,
 };
 
        mee_end,
 };
 
index 6b663e5..9440bb8 100644 (file)
@@ -4494,10 +4494,8 @@ static void c2op_assemble(int i,struct regstat *i_regs)
     need_ir=(gte_unneeded[i+1]&0xe00)!=0xe00;
     assem_debug("gte unneeded %016llx, need_flags %d, need_ir %d\n",
       gte_unneeded[i+1],need_flags,need_ir);
     need_ir=(gte_unneeded[i+1]&0xe00)!=0xe00;
     assem_debug("gte unneeded %016llx, need_flags %d, need_ir %d\n",
       gte_unneeded[i+1],need_flags,need_ir);
-#ifdef ARMv5_ONLY
-    // let's take more risk here
-    need_flags=need_flags&&gte_reads_flags;
-#endif
+    if(new_dynarec_hacks&NDHACK_GTE_NO_FLAGS)
+      need_flags=0;
     int shift = (source[i] >> 19) & 1;
     int lm = (source[i] >> 10) & 1;
     switch(c2op) {
     int shift = (source[i] >> 19) & 1;
     int lm = (source[i] >> 10) & 1;
     switch(c2op) {
index b3bcc29..3cd4f8e 100644 (file)
@@ -379,6 +379,7 @@ int pending_exception, stop;
 unsigned int next_interupt;
 int new_dynarec_did_compile;
 int cycle_multiplier;
 unsigned int next_interupt;
 int new_dynarec_did_compile;
 int cycle_multiplier;
+int new_dynarec_hacks;
 void *psxH_ptr;
 void *zeromem_ptr;
 u8 zero_mem[0x1000];
 void *psxH_ptr;
 void *zeromem_ptr;
 u8 zero_mem[0x1000];
index 353179a..b2eb21b 100644 (file)
@@ -92,7 +92,6 @@ struct ll_entry
   static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs
   static uint64_t gte_rt[MAXBLOCK];
   static uint64_t gte_unneeded[MAXBLOCK];
   static uint64_t gte_rs[MAXBLOCK]; // gte: 32 data and 32 ctl regs
   static uint64_t gte_rt[MAXBLOCK];
   static uint64_t gte_unneeded[MAXBLOCK];
-  static int gte_reads_flags; // gte flag read encountered
   static u_int smrv[32]; // speculated MIPS register values
   static u_int smrv_strong; // mask or regs that are likely to have correct values
   static u_int smrv_weak; // same, but somewhat less likely
   static u_int smrv[32]; // speculated MIPS register values
   static u_int smrv_strong; // mask or regs that are likely to have correct values
   static u_int smrv_weak; // same, but somewhat less likely
@@ -145,6 +144,7 @@ struct ll_entry
   static const u_int using_tlb=0;
 #endif
   int new_dynarec_did_compile;
   static const u_int using_tlb=0;
 #endif
   int new_dynarec_did_compile;
+  int new_dynarec_hacks;
   u_int stop_after_jal;
   extern u_char restore_candidate[512];
   extern int cycle_count;
   u_int stop_after_jal;
   extern u_char restore_candidate[512];
   extern int cycle_count;
@@ -3300,7 +3300,7 @@ void store_assemble(int i,struct regstat *i_regs)
     jaddr=0;
   }
 #endif
     jaddr=0;
   }
 #endif
-  if(!using_tlb&&!(i_regs->waswritten&(1<<rs1[i]))) {
+  if(!using_tlb&&!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
     if(!c||memtarget) {
       #ifdef DESTRUCTIVE_SHIFT
       // The x86 shift operation is 'destructive'; it overwrites the
     if(!c||memtarget) {
       #ifdef DESTRUCTIVE_SHIFT
       // The x86 shift operation is 'destructive'; it overwrites the
@@ -3574,7 +3574,7 @@ void storelr_assemble(int i,struct regstat *i_regs)
   }
   if(!c||!memtarget)
     add_stub(STORELR_STUB,jaddr,(int)out,i,(int)i_regs,temp,ccadj[i],reglist);
   }
   if(!c||!memtarget)
     add_stub(STORELR_STUB,jaddr,(int)out,i,(int)i_regs,temp,ccadj[i],reglist);
-  if(!using_tlb&&!(i_regs->waswritten&(1<<rs1[i]))) {
+  if(!using_tlb&&!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
     #ifdef RAM_OFFSET
     int map=get_reg(i_regs->regmap,ROREG);
     if(map<0) map=HOST_TEMPREG;
     #ifdef RAM_OFFSET
     int map=get_reg(i_regs->regmap,ROREG);
     if(map<0) map=HOST_TEMPREG;
@@ -3752,7 +3752,7 @@ void c1ls_assemble(int i,struct regstat *i_regs)
     emit_writedword_indexed_tlb(th,tl,0,offset||c||s<0?temp:s,map,temp);
     type=STORED_STUB;
   }
     emit_writedword_indexed_tlb(th,tl,0,offset||c||s<0?temp:s,map,temp);
     type=STORED_STUB;
   }
-  if(!using_tlb&&!(i_regs->waswritten&(1<<rs1[i]))) {
+  if(!using_tlb&&!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
     if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1
       #ifndef DESTRUCTIVE_SHIFT
       temp=offset||c||s<0?ar:s;
     if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1
       #ifndef DESTRUCTIVE_SHIFT
       temp=offset||c||s<0?ar:s;
@@ -3871,7 +3871,8 @@ void c2ls_assemble(int i,struct regstat *i_regs)
   }
   if(jaddr2)
     add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist);
   }
   if(jaddr2)
     add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist);
-  if (!(i_regs->waswritten&(1<<rs1[i]))&&opcode[i]==0x3a) { // SWC2
+  if(opcode[i]==0x3a) // SWC2
+  if(!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
 #if defined(HOST_IMM8)
     int ir=get_reg(i_regs->regmap,INVCP);
     assert(ir>=0);
 #if defined(HOST_IMM8)
     int ir=get_reg(i_regs->regmap,INVCP);
     assert(ir>=0);
@@ -6770,16 +6771,20 @@ void unneeded_registers(int istart,int iend,int r)
 {
   int i;
   uint64_t u,uu,gte_u,b,bu,gte_bu;
 {
   int i;
   uint64_t u,uu,gte_u,b,bu,gte_bu;
-  uint64_t temp_u,temp_uu,temp_gte_u;
+  uint64_t temp_u,temp_uu,temp_gte_u=0;
   uint64_t tdep;
   uint64_t tdep;
+  uint64_t gte_u_unknown=0;
+  if(new_dynarec_hacks&NDHACK_GTE_UNNEEDED)
+    gte_u_unknown=~0ll;
   if(iend==slen-1) {
     u=1;uu=1;
   if(iend==slen-1) {
     u=1;uu=1;
+    gte_u=gte_u_unknown;
   }else{
     u=unneeded_reg[iend+1];
     uu=unneeded_reg_upper[iend+1];
     u=1;uu=1;
   }else{
     u=unneeded_reg[iend+1];
     uu=unneeded_reg_upper[iend+1];
     u=1;uu=1;
+    gte_u=gte_unneeded[iend+1];
   }
   }
-  gte_u=temp_gte_u=0;
 
   for (i=iend;i>=istart;i--)
   {
 
   for (i=iend;i>=istart;i--)
   {
@@ -6794,7 +6799,7 @@ void unneeded_registers(int istart,int iend,int r)
         // Branch out of this block, flush all regs
         u=1;
         uu=1;
         // Branch out of this block, flush all regs
         u=1;
         uu=1;
-        gte_u=0;
+        gte_u=gte_u_unknown;
         /* Hexagon hack 
         if(itype[i]==UJUMP&&rt1[i]==31)
         {
         /* Hexagon hack 
         if(itype[i]==UJUMP&&rt1[i]==31)
         {
@@ -6840,7 +6845,7 @@ void unneeded_registers(int istart,int iend,int r)
           {
             u=1;
             uu=1;
           {
             u=1;
             uu=1;
-            gte_u=0;
+            gte_u=gte_u_unknown;
           }
         }
       }
           }
         }
       }
@@ -6883,7 +6888,7 @@ void unneeded_registers(int istart,int iend,int r)
             {
               temp_u=1;
               temp_uu=1;
             {
               temp_u=1;
               temp_uu=1;
-              temp_gte_u=0;
+              temp_gte_u=gte_u_unknown;
             }
           }
           tdep=(~temp_uu>>rt1[i])&1;
             }
           }
           tdep=(~temp_uu>>rt1[i])&1;
@@ -6905,7 +6910,7 @@ void unneeded_registers(int istart,int iend,int r)
           }else{
             unneeded_reg[(ba[i]-start)>>2]=1;
             unneeded_reg_upper[(ba[i]-start)>>2]=1;
           }else{
             unneeded_reg[(ba[i]-start)>>2]=1;
             unneeded_reg_upper[(ba[i]-start)>>2]=1;
-            gte_unneeded[(ba[i]-start)>>2]=0;
+            gte_unneeded[(ba[i]-start)>>2]=gte_u_unknown;
           }
         } /*else*/ if(1) {
           if(itype[i]==RJUMP||itype[i]==UJUMP||(source[i]>>16)==0x1000)
           }
         } /*else*/ if(1) {
           if(itype[i]==RJUMP||itype[i]==UJUMP||(source[i]>>16)==0x1000)
@@ -7944,7 +7949,6 @@ void new_dynarec_clear_full()
   literalcount=0;
   stop_after_jal=0;
   inv_code_start=inv_code_end=~0;
   literalcount=0;
   stop_after_jal=0;
   inv_code_start=inv_code_end=~0;
-  gte_reads_flags=0;
   // TLB
 #ifndef DISABLE_TLB
   using_tlb=0;
   // TLB
 #ifndef DISABLE_TLB
   using_tlb=0;
@@ -8654,12 +8658,7 @@ int new_recompile_block(int addr)
         {
           case 0x00: gte_rs[i]=1ll<<gr; break; // MFC2
           case 0x04: gte_rt[i]=1ll<<gr; break; // MTC2
         {
           case 0x00: gte_rs[i]=1ll<<gr; break; // MFC2
           case 0x04: gte_rt[i]=1ll<<gr; break; // MTC2
-          case 0x02: gte_rs[i]=1ll<<(gr+32); // CFC2
-            if(gr==31&&!gte_reads_flags) {
-              assem_debug("gte flag read encountered @%08x\n",addr + i*4);
-              gte_reads_flags=1;
-            }
-            break;
+          case 0x02: gte_rs[i]=1ll<<(gr+32); break; // CFC2
           case 0x06: gte_rt[i]=1ll<<(gr+32); break; // CTC2
         }
         break;
           case 0x06: gte_rt[i]=1ll<<(gr+32); break; // CTC2
         }
         break;
index db1f389..1396ef8 100644 (file)
@@ -6,6 +6,11 @@ extern int stop;
 extern int new_dynarec_did_compile;
 extern int cycle_multiplier; // 100 for 1.0
 
 extern int new_dynarec_did_compile;
 extern int cycle_multiplier; // 100 for 1.0
 
+#define NDHACK_NO_SMC_CHECK    (1<<0)
+#define NDHACK_GTE_UNNEEDED    (1<<1)
+#define NDHACK_GTE_NO_FLAGS    (1<<2)
+extern int new_dynarec_hacks;
+
 void new_dynarec_init();
 void new_dynarec_cleanup();
 void new_dynarec_clear_full();
 void new_dynarec_init();
 void new_dynarec_cleanup();
 void new_dynarec_clear_full();