feat: make per instruction cycle table optional

makes the nov 2022 change regarding the instruction cycle table thing toggleable inside Debug->CPU Settings.
This commit is contained in:
ApfelTeeSaft
2026-07-06 17:46:23 +02:00
parent ad0dde0725
commit 3eb504d67c
9 changed files with 84 additions and 36 deletions
+1
View File
@@ -9,6 +9,7 @@ foreach(KEY IN ITEMS
"use_artic_base_controller"
"enable_gamemode"
"use_cpu_jit"
"cpu_legacy_instruction_ticks"
"cpu_clock_percentage"
"is_new_3ds"
"lle_applets"
+11
View File
@@ -436,6 +436,17 @@ bool Source::DequeueBuffer() {
// Because our interpolation consumes samples instead of using an index,
// let's just consume the samples up to the current sample number.
// Guard like the partial-embedded-buffer path in ParseConfig: a play_position
// beyond the decoded length would otherwise erase past the end (undefined
// behavior). Log when this triggers so affected titles can be identified.
if (state.current_sample_number > state.current_buffer.size()) {
LOG_WARNING(Audio_DSP,
"source_id={} buffer_id={} play_position={} exceeds decoded buffer "
"size={}; resetting to 0",
source_id, buf.buffer_id, state.current_sample_number,
state.current_buffer.size());
state.current_sample_number = 0;
}
state.current_buffer.erase(
state.current_buffer.begin(),
std::next(state.current_buffer.begin(), state.current_sample_number));
+2
View File
@@ -474,6 +474,7 @@ void QtConfig::ReadCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
ReadGlobalSetting(Settings::values.cpu_clock_percentage);
ReadGlobalSetting(Settings::values.cpu_legacy_instruction_ticks);
if (global) {
ReadBasicSetting(Settings::values.use_cpu_jit);
@@ -1071,6 +1072,7 @@ void QtConfig::SaveCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
WriteGlobalSetting(Settings::values.cpu_clock_percentage);
WriteGlobalSetting(Settings::values.cpu_legacy_instruction_ticks);
if (global) {
WriteBasicSetting(Settings::values.use_cpu_jit);
@@ -143,6 +143,8 @@ void ConfigureDebug::SetConfiguration() {
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue());
ui->toggle_pica_debugging->setChecked(Settings::values.pica_debugging.GetValue());
ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers.GetValue());
ui->toggle_cpu_legacy_instruction_ticks->setChecked(
Settings::values.cpu_legacy_instruction_ticks.GetValue());
if (!Settings::IsConfiguringGlobal()) {
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
@@ -192,6 +194,9 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.dump_command_buffers = ui->toggle_dump_command_buffers->isChecked();
Settings::values.instant_debug_log = ui->instant_debug_log->isChecked();
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpu_legacy_instruction_ticks,
ui->toggle_cpu_legacy_instruction_ticks,
cpu_legacy_instruction_ticks);
ConfigurationShared::ApplyPerGameSetting(
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
[this](s32) { return SliderToSettings(ui->slider_clock_speed->value()); });
@@ -201,9 +206,15 @@ void ConfigureDebug::SetupPerGameUI() {
// Block the global settings if a game is currently running that overrides them
if (Settings::IsConfiguringGlobal()) {
ui->slider_clock_speed->setEnabled(Settings::values.cpu_clock_percentage.UsingGlobal());
ui->toggle_cpu_legacy_instruction_ticks->setEnabled(
Settings::values.cpu_legacy_instruction_ticks.UsingGlobal());
return;
}
ConfigurationShared::SetColoredTristate(ui->toggle_cpu_legacy_instruction_ticks,
Settings::values.cpu_legacy_instruction_ticks,
cpu_legacy_instruction_ticks);
connect(ui->clock_speed_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
ui->slider_clock_speed->setEnabled(index == 1);
ConfigurationShared::SetHighlight(ui->clock_speed_widget, index == 1);
+6 -1
View File
@@ -7,8 +7,12 @@
#include <memory>
#include <QWidget>
namespace ConfigurationShared {
enum class CheckState;
}
namespace Ui {
class ConfigureDebug;
class ConfigureDebug;
}
class ConfigureDebug : public QWidget {
@@ -26,4 +30,5 @@ public:
private:
std::unique_ptr<Ui::ConfigureDebug> ui;
bool is_powered_on;
ConfigurationShared::CheckState cpu_legacy_instruction_ticks;
};
+45 -35
View File
@@ -61,11 +61,11 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="debug_next_process">
<property name="text">
<string>Pause next non-sysmodule process at start</string>
</property>
</widget>
<widget class="QCheckBox" name="debug_next_process">
<property name="text">
<string>Pause next non-sysmodule process at start</string>
</property>
</widget>
</item>
</layout>
</widget>
@@ -125,14 +125,14 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="instant_debug_log">
<property name="text">
<string>Flush log output on every message</string>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;body&gt;Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut.&lt;br&gt;Enabling this feature will decrease performance, only use it for debugging purposes.&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QCheckBox" name="instant_debug_log">
<property name="text">
<string>Flush log output on every message</string>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;body&gt;Immediately commits the debug log to file. Use this if Azahar crashes and the log output is being cut.&lt;br&gt;Enabling this feature will decrease performance, only use it for debugging purposes.&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
@@ -226,13 +226,13 @@
<item row="2" column="0">
<widget class="QLabel" name="label_cpu_clock_info">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;Underclocking can increase performance but may cause the application to freeze.&lt;br/&gt;Overclocking may reduce lag in applications but also might cause freezes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;Underclocking can increase performance but may cause the application to freeze.&lt;br/&gt;Overclocking may reduce lag in applications but also might cause freezes&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="toggle_cpu_jit">
<property name="toolTip">
@@ -243,6 +243,16 @@
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="toggle_cpu_legacy_instruction_ticks">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Counts every ARM instruction as a single cycle instead of using the per-instruction timing table. A few applications contain scripted logic that is sensitive to the emulated CPU speed and only progresses correctly with this enabled (e.g. the rooftop chase in LEGO City Undercover: The Chase Begins). Leave unchecked unless an application misbehaves. Requires restarting the application to fully apply.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use legacy CPU cycle timing (1 tick per instruction)</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="toggle_renderer_debug">
<property name="text">
@@ -250,13 +260,13 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="toggle_pica_debugging">
<property name="text">
<string>Enable PICA200 debugging</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="toggle_pica_debugging">
<property name="text">
<string>Enable PICA200 debugging</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="toggle_dump_command_buffers">
<property name="text">
@@ -304,14 +314,14 @@
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="enable_rpc_server">
<property name="text">
<string>Enable RPC server</string>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enables the RPC server on port 45987. This allows remotely reading/writing guest memory, do not enable if you don't know what you are doing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QCheckBox" name="enable_rpc_server">
<property name="text">
<string>Enable RPC server</string>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enables the RPC server on port 45987. This allows remotely reading/writing guest memory, do not enable if you don't know what you are doing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="break_on_unmapped_memory_access">
+2
View File
@@ -88,6 +88,8 @@ void LogSettings() {
LOG_INFO(Config, "Azahar Configuration:");
log_setting("Core_UseCpuJit", values.use_cpu_jit.GetValue());
log_setting("Core_CPUClockPercentage", values.cpu_clock_percentage.GetValue());
log_setting("Core_CpuLegacyInstructionTicks",
values.cpu_legacy_instruction_ticks.GetValue());
log_setting("Controller_UseArticController", values.use_artic_base_controller.GetValue());
log_setting("Renderer_UseGLES", values.use_gles.GetValue());
log_setting("Renderer_GraphicsAPI", GetGraphicsAPIName(values.graphics_api.GetValue()));
+2
View File
@@ -482,6 +482,8 @@ struct Values {
// Core
Setting<bool> use_cpu_jit{true, Keys::use_cpu_jit};
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, Keys::cpu_clock_percentage};
SwitchableSetting<bool> cpu_legacy_instruction_ticks{false,
Keys::cpu_legacy_instruction_ticks};
SwitchableSetting<bool> is_new_3ds{true, Keys::is_new_3ds};
SwitchableSetting<bool> lle_applets{true, Keys::lle_applets};
SwitchableSetting<bool> deterministic_async_operations{false,
+4
View File
@@ -8,6 +8,7 @@
#include <dynarmic/interface/optimization_flags.h>
#include "common/assert.h"
#include "common/microprofile.h"
#include "common/settings.h"
#include "core/arm/dynarmic/arm_dynarmic.h"
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
@@ -159,6 +160,9 @@ public:
return static_cast<u64>(ticks <= 0 ? 0 : ticks);
}
std::uint64_t GetTicksForCode(bool is_thumb, VAddr, std::uint32_t instruction) override {
if (Settings::values.cpu_legacy_instruction_ticks.GetValue()) [[unlikely]] {
return 1;
}
return Core::TicksForInstruction(is_thumb, instruction);
}