Browse Source

add 68k overclocking support

notaz 6 years ago
parent
commit
35f2b65ef7

+ 1 - 0
pico/pico.h

@@ -96,6 +96,7 @@ typedef struct
 	unsigned short autoRgnOrder;   // packed priority list of regions, for example 0x148 means this detection order: EUR, USA, JAP
 
 	unsigned short quirks;         // game-specific quirks: PQUIRK_*
+	unsigned short overclockM68k;  // overclock the emulated 68k, in %
 } PicoInterface;
 
 extern PicoInterface PicoIn;

+ 11 - 2
pico/pico_cmn.c

@@ -81,7 +81,7 @@ static void do_timing_hacks_as(struct PicoVideo *pv, int vdp_slots)
 
 static void do_timing_hacks_vb(void)
 {
-  if (Pico.m.dma_xfers)
+  if (unlikely(Pico.m.dma_xfers))
     SekCyclesBurn(CheckDMA());
 }
 
@@ -272,7 +272,7 @@ static int PicoFrameHints(void)
 
     PAD_DELAY();
 
-    if ((pv->status & PVS_ACTIVE) && --hint < 0)
+    if (unlikely(pv->status & PVS_ACTIVE) && --hint < 0)
     {
       hint = pv->reg[10]; // Reload H-Int counter
       do_hint(pv);
@@ -287,6 +287,15 @@ static int PicoFrameHints(void)
     pevt_log_m68k_o(EVT_NEXT_LINE);
   }
 
+  if (unlikely(PicoIn.overclockM68k)) {
+    unsigned int l = PicoIn.overclockM68k * lines / 100;
+    while (l-- > 0) {
+      Pico.t.m68c_cnt -= CYCLES_M68K_LINE;
+      do_timing_hacks_vb();
+      SekSyncM68k();
+    }
+  }
+
   pv->status &= ~(SR_VB | PVS_VB2);
   pv->status |= ((pv->reg[1] >> 3) ^ SR_VB) & SR_VB; // forced blanking
 

+ 2 - 0
pico/pico_port.h

@@ -10,9 +10,11 @@
 #ifdef __GNUC__
 #define NOINLINE    __attribute__((noinline))
 #define ALIGNED(n)  __attribute__((aligned(n)))
+#define unlikely(x) __builtin_expect((x), 0)
 #else
 #define NOINLINE
 #define ALIGNED(n)
+#define unlikely(x) (x)
 #endif
 
 #ifdef _MSC_VER

+ 1 - 0
platform/common/emu.c

@@ -652,6 +652,7 @@ int emu_read_config(const char *rom_fname, int no_defaults)
 	}
 
 	pemu_validate_config();
+	PicoIn.overclockM68k = currentConfig.overclock_68k;
 
 	// some sanity checks
 #ifdef PSP

+ 1 - 0
platform/common/emu.h

@@ -74,6 +74,7 @@ typedef struct _currentConfig_t {
 	int analog_deadzone;
 	int msh2_khz;
 	int ssh2_khz;
+	int overclock_68k;
 } currentConfig_t;
 
 extern currentConfig_t currentConfig, defaultConfig;

+ 6 - 0
platform/common/menu_pico.c

@@ -488,10 +488,13 @@ static int menu_loop_32x_options(int id, int keys)
 
 // ------------ adv options menu ------------
 
+static const char h_ovrclk[] = "Will break some games, keep at 0";
+
 static menu_entry e_menu_adv_options[] =
 {
 	mee_onoff     ("SRAM/BRAM saves",          MA_OPT_SRAM_STATES,    currentConfig.EmuOpt, EOPT_EN_SRAM),
 	mee_onoff     ("Disable sprite limit",     MA_OPT2_NO_SPRITE_LIM, PicoIn.opt, POPT_DIS_SPRITE_LIM),
+	mee_range_h   ("Overclock M68k (%)",       MA_OPT2_OVERCLOCK_M68K,currentConfig.overclock_68k, 0, 1000, h_ovrclk),
 	mee_onoff     ("Emulate Z80",              MA_OPT2_ENABLE_Z80,    PicoIn.opt, POPT_EN_Z80),
 	mee_onoff     ("Emulate YM2612 (FM)",      MA_OPT2_ENABLE_YM2612, PicoIn.opt, POPT_EN_FM),
 	mee_onoff     ("Emulate SN76496 (PSG)",    MA_OPT2_ENABLE_SN76496,PicoIn.opt, POPT_EN_PSG),
@@ -508,7 +511,10 @@ static menu_entry e_menu_adv_options[] =
 static int menu_loop_adv_options(int id, int keys)
 {
 	static int sel = 0;
+
 	me_loop(e_menu_adv_options, &sel);
+	PicoIn.overclockM68k = currentConfig.overclock_68k; // int vs short
+
 	return 0;
 }
 

+ 1 - 0
platform/common/menu_pico.h

@@ -57,6 +57,7 @@ typedef enum
 	MA_OPT2_DYNARECS,
 	MA_OPT2_NO_SPRITE_LIM,
 	MA_OPT2_NO_IDLE_LOOPS,
+	MA_OPT2_OVERCLOCK_M68K,
 	MA_OPT2_DONE,
 	MA_OPT3_SCALE,		/* psp (all OPT3) */
 	MA_OPT3_HSCALE32,

+ 10 - 0
platform/libretro/libretro.c

@@ -10,6 +10,7 @@
 
 #define _GNU_SOURCE 1 // mremap
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
 #ifndef _WIN32
@@ -527,6 +528,7 @@ void retro_set_environment(retro_environment_t cb)
       { "picodrive_region",      "Region; Auto|Japan NTSC|Japan PAL|US|Europe" },
       { "picodrive_aspect",      "Core-provided aspect ratio; PAR|4/3|CRT" },
       { "picodrive_overscan",    "Show Overscan; disabled|enabled" },
+      { "picodrive_overclk68k",  "68k overclock; disabled|+25%|+50%|+75%|+100%|+200%|+400%" },
 #ifdef DRC_SH2
       { "picodrive_drc", "Dynamic recompilers; enabled|disabled" },
 #endif
@@ -1295,6 +1297,14 @@ static void update_variables(void)
       environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info);
    }
 
+   var.value = NULL;
+   var.key = "picodrive_overclk68k";
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+      PicoIn.overclockM68k = 0;
+      if (var.value[0] == '+')
+         PicoIn.overclockM68k = atoi(var.value + 1);
+   }
+
 #ifdef DRC_SH2
    var.value = NULL;
    var.key = "picodrive_drc";