From 35f2b65ef708e7afc922ceda8d00b716de289610 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 20 Oct 2017 00:41:12 +0300 Subject: [PATCH] add 68k overclocking support --- pico/pico.h | 1 + pico/pico_cmn.c | 13 +++++++++++-- pico/pico_port.h | 2 ++ platform/common/emu.c | 1 + platform/common/emu.h | 1 + platform/common/menu_pico.c | 6 ++++++ platform/common/menu_pico.h | 1 + platform/libretro/libretro.c | 10 ++++++++++ 8 files changed, 33 insertions(+), 2 deletions(-) diff --git a/pico/pico.h b/pico/pico.h index be02ef3..2d63d18 100644 --- a/pico/pico.h +++ b/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; diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 50b8ced..fc12a76 100644 --- a/pico/pico_cmn.c +++ b/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 diff --git a/pico/pico_port.h b/pico/pico_port.h index 605778d..7080220 100644 --- a/pico/pico_port.h +++ b/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 diff --git a/platform/common/emu.c b/platform/common/emu.c index 822fec7..407ed59 100644 --- a/platform/common/emu.c +++ b/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 diff --git a/platform/common/emu.h b/platform/common/emu.h index 6e7c399..9a5ae66 100644 --- a/platform/common/emu.h +++ b/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; diff --git a/platform/common/menu_pico.c b/platform/common/menu_pico.c index bd2b915..1d73d4a 100644 --- a/platform/common/menu_pico.c +++ b/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; } diff --git a/platform/common/menu_pico.h b/platform/common/menu_pico.h index c5edde3..595989e 100644 --- a/platform/common/menu_pico.h +++ b/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, diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 33ede0d..99f0f3b 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -10,6 +10,7 @@ #define _GNU_SOURCE 1 // mremap #include +#include #include #include #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"; -- 2.39.2