Skip to content

Commit

Permalink
Add core option to set a maximum limit to the emulated CPU speed when…
Browse files Browse the repository at this point in the history
… running with auto adjusting cycles
  • Loading branch information
schellingb committed Aug 9, 2024
1 parent 3e3993f commit ff213d5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
23 changes: 22 additions & 1 deletion core_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,31 @@ static retro_core_option_v2_definition option_defs[] =
},
"auto"
},
{
"dosbox_pure_cycles_max",
"Detailed > Maximum Emulated Performance", NULL,
"With dynamic CPU speed (AUTO or MAX above), the maximum emulated performance level.", NULL,
"Performance",
{
{ "none", "Unlimited" },
{ "315", "8086/8088, 4.77 MHz from 1980 (315 cps)" },
{ "1320", "286, 6 MHz from 1982 (1320 cps)" },
{ "2750", "286, 12.5 MHz from 1985 (2750 cps)" },
{ "4720", "386, 20 MHz from 1987 (4720 cps)" },
{ "7800", "386DX, 33 MHz from 1989 (7800 cps)" },
{ "13400", "486DX, 33 MHz from 1990 (13400 cps)" },
{ "26800", "486DX2, 66 MHz from 1992 (26800 cps)" },
{ "77000", "Pentium, 100 MHz from 1995 (77000 cps)" },
{ "200000", "Pentium II, 300 MHz from 1997 (200000 cps)" },
{ "500000", "Pentium III, 600 MHz from 1999 (500000 cps)" },
{ "1000000", "AMD Athlon, 1.2 GHz from 2000 (1000000 cps)" },
},
"auto"
},
{
"dosbox_pure_cycles_scale",
"Detailed > Performance Scale", NULL,
"Fine tune the emulated performance for specific needs." "\n\n", NULL, //end of Performance > Detailed section
"Fine tune the emulated performance for specific needs.", NULL,
"Performance",
{
{ "0.2", "20%" }, { "0.25", "25%" }, { "0.3", "30%" }, { "0.35", "35%" }, { "0.4", "40%" }, { "0.45", "45%" },
Expand Down
46 changes: 29 additions & 17 deletions dosbox_pure_libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,17 +588,23 @@ static void DBP_ThreadControl(DBP_ThreadCtlMode m)

void DBP_SetRealModeCycles()
{
if (cpu.pmode || CPU_CycleAutoAdjust || !(CPU_AutoDetermineMode & CPU_AUTODETERMINE_CYCLES) || render.frameskip.max > 1) return;
if (cpu.pmode || !(CPU_AutoDetermineMode & CPU_AUTODETERMINE_CYCLES) || render.frameskip.max > 1) return;

int year = (dbp_game_running ? dbp_content_year : 0);
CPU_CycleMax =
Bit32s cpu_cycles =
(year <= 1970 ? 3000 : // Unknown year, dosbox default
(year < 1981 ? 500 : // Very early 8086/8088 CPU
(year > 1999 ? 500000 : // Pentium III, 600 MHz and later
Cycles1981to1999[year - 1981]))); // Matching speed for year

// Switch to dynamic core for newer real mode games
if (CPU_CycleMax >= 8192 && (CPU_AutoDetermineMode & CPU_AUTODETERMINE_CORE))
// When auto switching to a high-speed CPU, use cycle limit instead of hard max so low spec hardware is allowed to throttle down
if (year > 1995)
{ CPU_CycleLimit = cpu_cycles; CPU_CycleAutoAdjust = true; }
else if (!CPU_CycleAutoAdjust)
CPU_CycleMax = cpu_cycles;

// Switch to dynamic core for newer real mode games
if (cpu_cycles >= 8192 && (CPU_AutoDetermineMode & CPU_AUTODETERMINE_CORE))
{
#if (C_DYNAMIC_X86)
if (cpudecoder != CPU_Core_Dyn_X86_Run) { void CPU_Core_Dyn_X86_Cache_Init(bool); CPU_Core_Dyn_X86_Cache_Init(true); cpudecoder = CPU_Core_Dyn_X86_Run; }
Expand Down Expand Up @@ -2220,6 +2226,7 @@ static bool GFX_Events_AdvanceFrame(bool force_skip)
if (CPU_CycleMax < (cpu.pmode ? 10000 : 1000)) CPU_CycleMax = (cpu.pmode ? 10000 : 1000);
if (CPU_CycleMax > 4000000) CPU_CycleMax = 4000000;
if (CPU_CycleMax > (Bit64s)recentEmulator * 280) CPU_CycleMax = (Bit32s)(recentEmulator * 280);
if (CPU_CycleLimit > 0 && CPU_CycleMax > CPU_CycleLimit) CPU_CycleMax = CPU_CycleLimit;
}

//log_cb(RETRO_LOG_INFO, "[DBPTIMERS%4d] - EMU: %5d - FE: %5d - TARGET: %5d - EffectiveCycles: %6d - Limit: %6d|%6d - CycleMax: %6d - Scale: %5d\n",
Expand Down Expand Up @@ -2652,7 +2659,7 @@ static bool check_variables(bool is_startup = false)
}
}

char buf[16];
char buf[32];
unsigned options_ver = 0;
if (environ_cb) environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &options_ver);
bool show_advanced = (options_ver != 1 || retro_get_variable("dosbox_pure_advanced", "false")[0] != 'f');
Expand Down Expand Up @@ -2765,13 +2772,20 @@ static bool check_variables(bool is_startup = false)

const char* cycles = retro_get_variable("dosbox_pure_cycles", "auto");
bool cycles_numeric = (cycles[0] >= '0' && cycles[0] <= '9');
retro_set_visibility("dosbox_pure_cycles_scale", cycles_numeric);
int cycles_max = (cycles_numeric ? 0 : atoi(retro_get_variable("dosbox_pure_cycles_max", "none")));
retro_set_visibility("dosbox_pure_cycles_max", !cycles_numeric);
retro_set_visibility("dosbox_pure_cycles_scale", cycles_numeric || cycles_max);
retro_set_visibility("dosbox_pure_cycle_limit", !cycles_numeric);
if (cycles_numeric)
{
snprintf(buf, sizeof(buf), "%d", (int)(atoi(cycles) * (float)atof(retro_get_variable("dosbox_pure_cycles_scale", "1.0")) + .499));
cycles = buf;
}
else if (cycles_max)
{
snprintf(buf, sizeof(buf), "%s limit %d", cycles, (int)(cycles_max * (float)atof(retro_get_variable("dosbox_pure_cycles_scale", "1.0")) + .499));
cycles = buf;
}
visibility_changed |= Variables::DosBoxSet("cpu", "cycles", cycles);

dbp_auto_target =
Expand Down Expand Up @@ -2914,7 +2928,7 @@ static void init_dosbox_load_dos_yml(const std::string& yml, Section** ref_autoe
struct Local
{
const char *Key, *End, *Next, *KeyX, *Val, *ValX;
int cpu_cycles = 0, cpu_hz = 0, cpu_year = 0;
int cpu_cycles = 0, cpu_hz = 0, cpu_year = 0, cpu_set_max = 0;
bool Parse(const char *yml_key, const char* db_section, const char* db_key, ...)
{
if (yml_key && (strncmp(yml_key, Key, (size_t)(KeyX - Key)) || yml_key[KeyX - Key])) return false;
Expand Down Expand Up @@ -2958,14 +2972,12 @@ static void init_dosbox_load_dos_yml(const std::string& yml, Section** ref_autoe
bool ParseCPU(const char *yml_key)
{
if (strncmp(yml_key, Key, (size_t)(KeyX - Key)) || yml_key[KeyX - Key]) return false;
switch (yml_key[4])
again: switch (yml_key[4])
{
case 'c': // cpu_cycles
return ((cpu_cycles = atoi(Val)) >= 100);
case 'h': // cpu_hz
return ((cpu_hz = atoi(Val)) >= 500);
case 'y': // cpu_year
return ((cpu_year = atoi(Val)) >= 1970);
case 'm': cpu_set_max = 1; yml_key += 4; goto again; // cpu_max_*
case 'c': return ((cpu_cycles = atoi(Val)) >= 100); // cpu_cycles
case 'h': return ((cpu_hz = atoi(Val)) >= 500); // cpu_hz
case 'y': return ((cpu_year = atoi(Val)) >= 1970); // cpu_year
}
return false;
}
Expand Down Expand Up @@ -3025,7 +3037,7 @@ static void init_dosbox_load_dos_yml(const std::string& yml, Section** ref_autoe
case 'c':
if (0
||l.Parse("cpu_type", "cpu", "cputype" , "auto","auto" , "generic_386","386" , "generic_486","486_slow" , "generic_pentium","pentium_slow" , "")
||l.ParseCPU("cpu_cycles")||l.ParseCPU("cpu_hz")||l.ParseCPU("cpu_year")
||l.ParseCPU("cpu_cycles")||l.ParseCPU("cpu_hz")||l.ParseCPU("cpu_year")||l.ParseCPU("cpu_max_cycles")||l.ParseCPU("cpu_max_hz")||l.ParseCPU("cpu_max_year")
) break; else goto syntaxerror;
case 'm':
if (0
Expand Down Expand Up @@ -3090,8 +3102,8 @@ static void init_dosbox_load_dos_yml(const std::string& yml, Section** ref_autoe
l.cpu_cycles = (int)(l.cpu_hz * cycle_per_hz + .4999f);
}
char buf[32];
l.ValX = (l.Val = buf) + sprintf(buf, "%d", (int)l.cpu_cycles);
if (l.Parse(NULL, "cpu", "cycles", "~") && l.cpu_cycles >= 8192) // Switch to dynamic core for newer real mode games
l.ValX = (l.Val = buf) + sprintf(buf, "%s%d", (l.cpu_set_max ? "max limit " : ""), (int)l.cpu_cycles);
if (l.Parse(NULL, "cpu", "cycles", "~") && l.cpu_cycles >= 8192) // Switch to dynamic core for newer real mode games
{ l.ValX = (l.Val = "dynamic") + 7; l.Parse(NULL, "cpu", "core", "~"); }
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/cpu/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2603,6 +2603,12 @@ void DBP_CPU_ModifyCycles(const char* val, const char* params)
if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT;
}
CPU_CycleLeft = CPU_Cycles = 0;
const char* limit = strstr((params ? params : val), "limit ");
if (limit)
{
CPU_CycleLimit = atoi(limit + 6);
if (CPU_CycleLimit < CPU_CYCLES_LOWER_LIMIT) CPU_CycleLimit = -1;
}
}

#include <dbp_serialize.h>
Expand Down

0 comments on commit ff213d5

Please sign in to comment.