diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt
index 2f1212ee21..4791e91023 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt
@@ -20,6 +20,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
EMULATE_BGR565("emulate_bgr565"),
RESCALE_HACK("rescale_hack"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
+ RELOCATE_36BIT_ADDRESS_SPACE("relocate_36bit_address_space"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
index 7ce309d764..6fbb6006ca 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
@@ -846,6 +846,13 @@ abstract class SettingsItem(
descriptionId = R.string.cpuopt_unsafe_host_mmu_description
)
)
+ put(
+ SwitchSetting(
+ BooleanSetting.RELOCATE_36BIT_ADDRESS_SPACE,
+ titleId = R.string.relocate_36bit_address_space,
+ descriptionId = R.string.relocate_36bit_address_space_description
+ )
+ )
put(
SwitchSetting(
BooleanSetting.RENDERER_REACTIVE_FLUSHING,
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index 74c7fc41cf..85bb1c3fab 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -1527,6 +1527,7 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.cpu))
add(IntSetting.CPU_BACKEND.key)
+ add(BooleanSetting.RELOCATE_36BIT_ADDRESS_SPACE.key)
add(IntSetting.CPU_ACCURACY.key)
add(BooleanSetting.USE_AUTO_STUB.key)
add(SettingsItem.FASTMEM_COMBINED)
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index b24cbceb18..1cbe8b6216 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -105,6 +105,8 @@
Synchronize the core tick speed to the maximum speed percentage to improve performance without altering the game\'s actual speed.
Enable Host MMU Emulation
This optimization speeds up memory accesses by the guest program. Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host\'s MMU. Disabling this forces all memory accesses to use Software MMU Emulation.
+ Run 36-bit games natively
+ Gives games built for the 36-bit address space the 39-bit layout so they can run with NCE instead of the JIT. Experimental: a game that relies on 36-bit addresses can crash.
Debug knobs
For development use only.
0 to 65535
diff --git a/src/common/settings.h b/src/common/settings.h
index a924007205..5f316061f9 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -259,6 +259,8 @@ struct Values {
Category::Cpu};
SwitchableSetting cpu_accuracy{linkage, CpuAccuracy::Auto,
"cpu_accuracy", Category::Cpu};
+ SwitchableSetting relocate_36bit_address_space{
+ linkage, false, "relocate_36bit_address_space", Category::Cpu};
SwitchableSetting cpu_clock{linkage,
CpuClock::Normal,
"fast_cpu_time",
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index 63ca9d3fe3..d84c24f286 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -147,6 +147,10 @@ ProgramAddressSpaceType ProgramMetadata::GetAddressSpaceType() const {
return npdm_header.address_space_type;
}
+void ProgramMetadata::SetAddressSpaceType(ProgramAddressSpaceType address_space) {
+ npdm_header.address_space_type.Assign(address_space);
+}
+
u8 ProgramMetadata::GetMainThreadPriority() const {
return npdm_header.main_thread_priority;
}
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h
index 115e6d6cd1..7f5853567e 100644
--- a/src/core/file_sys/program_metadata.h
+++ b/src/core/file_sys/program_metadata.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -73,6 +76,7 @@ public:
bool Is64BitProgram() const;
ProgramAddressSpaceType GetAddressSpaceType() const;
+ void SetAddressSpaceType(ProgramAddressSpaceType address_space);
u8 GetMainThreadPriority() const;
u8 GetMainThreadCore() const;
u32 GetMainThreadStackSize() const;
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 5e2ec7e0b9..b04da7e84f 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -182,6 +182,12 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
}
metadata.Print();
+ if (Settings::values.relocate_36bit_address_space.GetValue() &&
+ Settings::values.cpu_backend.GetValue() == Settings::CpuBackend::Nce &&
+ metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
+ metadata.SetAddressSpaceType(FileSys::ProgramAddressSpaceType::Is39Bit);
+ }
+
// Enable NCE only for applications with 39-bit address space.
const bool is_39bit =
metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit;