mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
external: Update few submodule and remove unicorn.
- Remove all Unicorn references from language files and project as it’s deprecated and unused. - Update SPIRV-Cross to vulkan-sdk-1.4.321. - Update YAML to latest master. - Fix CMake minimum version requirement errors by ensuring minimum version 3.5.
This commit is contained in:
@@ -51,9 +51,6 @@
|
||||
[submodule "external/stb"]
|
||||
path = external/stb
|
||||
url = https://github.com/nothings/stb
|
||||
[submodule "external/unicorn"]
|
||||
path = external/unicorn
|
||||
url = https://github.com/Vita3K/unicorn.git
|
||||
[submodule "external/vita-toolchain"]
|
||||
path = external/vita-toolchain
|
||||
url = https://github.com/vitasdk/vita-toolchain.git
|
||||
|
||||
Vendored
-3
@@ -136,9 +136,6 @@ if(MSVC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(UNICORN_ARCH "arm")
|
||||
add_subdirectory(unicorn EXCLUDE_FROM_ALL)
|
||||
|
||||
add_library(vita-toolchain INTERFACE)
|
||||
target_include_directories(vita-toolchain INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/vita-toolchain/src")
|
||||
|
||||
|
||||
Vendored
+1
-1
Submodule external/SPIRV-Cross updated: bccaa94db8...d8e3e2b141
Vendored
-1
Submodule external/unicorn deleted from 9c816e02de
Vendored
+1
-1
Submodule external/yaml-cpp updated: f732014112...2f86d13775
@@ -608,9 +608,6 @@ Please download and install the last PS Vita firmware.</no_modules>
|
||||
<manual_description>Select Manual mode to load selected modules from the list below.</manual_description>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn (deprecated)</unicorn>
|
||||
<cpu_backend>CPU Backend</cpu_backend>
|
||||
<select_cpu_backend>Select your preferred CPU backend.</select_cpu_backend>
|
||||
<cpu_opt>Enable optimizations</cpu_opt>
|
||||
<cpu_opt_description>Check the box to enable additional CPU JIT optimizations.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -608,9 +608,6 @@ Please download and install the last PS Vita firmware.</no_modules>
|
||||
<manual_description>Select Manual mode to load selected modules from the list below.</manual_description>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn (deprecated)</unicorn>
|
||||
<cpu_backend>CPU Backend</cpu_backend>
|
||||
<select_cpu_backend>Select your preferred CPU backend.</select_cpu_backend>
|
||||
<cpu_opt>Enable optimizations</cpu_opt>
|
||||
<cpu_opt_description>Check the box to enable additional CPU JIT optimizations.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -589,9 +589,6 @@ Proszę pobrać i zainstalować najnowsze oprogramowanie systemu PS Vita.</no_mo
|
||||
<refresh_list>Odśwież listę</refresh_list>
|
||||
</core>
|
||||
<cpu name="Procesor">
|
||||
<unicorn>Unicorn (porzucone)</unicorn>
|
||||
<cpu_backend>Backend procesora</cpu_backend>
|
||||
<select_cpu_backend>Wybierz preferowany backend procesora.</select_cpu_backend>
|
||||
<cpu_opt>Włącz optymalizacje</cpu_opt>
|
||||
<cpu_opt_description>Zaznacz, aby włączyć dodatkowe optymalizacje CPU JIT.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -590,9 +590,6 @@
|
||||
<manual_description>Выберите Ручной режим для загрузки только выбранных модулей из списка ниже.</manual_description>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn (устарел)</unicorn>
|
||||
<cpu_backend>CPU бэкенд</cpu_backend>
|
||||
<select_cpu_backend>Выберите бэкенд процессора.</select_cpu_backend>
|
||||
<cpu_opt>Включить оптимизацию</cpu_opt>
|
||||
<cpu_opt_description>Установите флажок, чтобы включить дополнительные JIT-оптимизации процессора.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -606,9 +606,6 @@
|
||||
<refresh_list>刷新列表</refresh_list>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn(已弃用)</unicorn>
|
||||
<cpu_backend>CPU后端</cpu_backend>
|
||||
<select_cpu_backend>选择您喜欢的CPU后端。</select_cpu_backend>
|
||||
<cpu_opt>启用优化</cpu_opt>
|
||||
<cpu_opt_description>勾选此项启用额外的CPU JIT优化。</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -606,9 +606,6 @@
|
||||
<refresh_list>更新列表</refresh_list>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn(已棄用)</unicorn>
|
||||
<cpu_backend>CPU後端</cpu_backend>
|
||||
<select_cpu_backend>選擇您喜歡的CPU後端。</select_cpu_backend>
|
||||
<cpu_opt>啟用最佳化</cpu_opt>
|
||||
<cpu_opt_description>勾選此項啟用額外的CPU JIT最佳化。</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -549,9 +549,6 @@ Silakan download dan install firmware PS Vita terakhir.</no_modules>
|
||||
<refresh_list>Perbarui Daftar</refresh_list>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn (tidak digunakan lagi)</unicorn>
|
||||
<cpu_backend>Bagian Belakang CPU</cpu_backend>
|
||||
<select_cpu_backend>Pilih perender backend pilihan kamu.</select_cpu_backend>
|
||||
<cpu_opt>Aktifkan Pengoptimalan</cpu_opt>
|
||||
<cpu_opt_description>Centang kotak untuk mengaktifkan optimasi CPU JIT tambahan.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -553,9 +553,6 @@ Sila muat turun dan pasang PS Vita yang terakhir firmware.</no_modules>
|
||||
<refresh_list>Muat Semula Senarai</refresh_list>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn (tidak digunakan lagi)</unicorn>
|
||||
<cpu_backend>CPU Bahagian Belakang</cpu_backend>
|
||||
<select_cpu_backend>Pilih bahagian belakang CPU pilihan awak.</select_cpu_backend>
|
||||
<cpu_opt>Dayakan pengoptimuman</cpu_opt>
|
||||
<cpu_opt_description>Tandai kotak untuk mendayakan pengoptimuman CPU JIT tambahan.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -556,9 +556,6 @@
|
||||
<refresh_list>Оновити список</refresh_list>
|
||||
</core>
|
||||
<cpu>
|
||||
<unicorn>Unicorn (застарілий)</unicorn>
|
||||
<cpu_backend>Бекенд центрального процесора</cpu_backend>
|
||||
<select_cpu_backend>Оберіть бажаний бекенд центрального процесора.</select_cpu_backend>
|
||||
<cpu_opt>Дозволити оптимізації</cpu_opt>
|
||||
<cpu_opt_description>Оберіть цей пункт, аби дозволити додаткові JIT-оптимізації процесора.</cpu_opt_description>
|
||||
</cpu>
|
||||
|
||||
@@ -392,9 +392,6 @@ bool late_init(EmuEnvState &state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state.mem.use_page_table && state.kernel.cpu_backend == CPUBackend::Unicorn)
|
||||
LOG_CRITICAL("Unicorn backend is not supported with a page table");
|
||||
|
||||
const ResumeAudioThread resume_thread = [&state](SceUID thread_id) {
|
||||
const auto thread = state.kernel.get_thread(thread_id);
|
||||
const std::lock_guard<std::mutex> lock(thread->mutex);
|
||||
|
||||
@@ -100,7 +100,6 @@ enum ScreenshotFormat {
|
||||
code(int, "delay-start", 10, delay_start) \
|
||||
code(float, "background-alpha", .300f, background_alpha) \
|
||||
code(int, "log-level", 0 /*SPDLOG_LEVEL_TRACE*/, log_level) \
|
||||
code(std::string, "cpu-backend", "Dynarmic", cpu_backend) \
|
||||
code(bool, "cpu-opt", true, cpu_opt) \
|
||||
code(std::string, "pref-path", std::string{}, pref_path) \
|
||||
code(bool, "discord-rich-presence", true, discord_rich_presence) \
|
||||
|
||||
@@ -58,7 +58,6 @@ struct Config {
|
||||
* All the settings that appear in this struct can be adjusted using app-specific custom config files.
|
||||
*/
|
||||
struct CurrentConfig {
|
||||
std::string cpu_backend;
|
||||
bool cpu_opt = true;
|
||||
int modules_mode = ModulesMode::AUTOMATIC;
|
||||
std::vector<std::string> lle_modules = {};
|
||||
|
||||
@@ -4,14 +4,12 @@ include/cpu/common.h
|
||||
include/cpu/functions.h
|
||||
include/cpu/impl/dynarmic_cpu.h
|
||||
include/cpu/impl/interface.h
|
||||
include/cpu/impl/unicorn_cpu.h
|
||||
include/cpu/disasm/functions.h
|
||||
include/cpu/disasm/state.h
|
||||
|
||||
src/disasm.cpp
|
||||
src/cpu.cpp
|
||||
src/dynarmic_cpu.cpp
|
||||
src/unicorn_cpu.cpp
|
||||
)
|
||||
|
||||
add_library(
|
||||
@@ -24,4 +22,4 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_LIST})
|
||||
|
||||
target_include_directories(cpu PUBLIC include)
|
||||
target_link_libraries(cpu PUBLIC mem util)
|
||||
target_link_libraries(cpu PRIVATE dynarmic unicorn capstone merry::mcl)
|
||||
target_link_libraries(cpu PRIVATE dynarmic capstone merry::mcl)
|
||||
|
||||
@@ -106,11 +106,6 @@ struct CPUContext {
|
||||
}
|
||||
};
|
||||
|
||||
enum class CPUBackend {
|
||||
Dynarmic,
|
||||
Unicorn,
|
||||
};
|
||||
|
||||
union DoubleReg {
|
||||
double d;
|
||||
float f[2];
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
struct MemState;
|
||||
|
||||
CPUStatePtr init_cpu(CPUBackend backend, bool cpu_opt, SceUID thread_id, std::size_t processor_id, MemState &mem, CPUProtocolBase *protocol);
|
||||
CPUStatePtr init_cpu(bool cpu_opt, SceUID thread_id, std::size_t processor_id, MemState &mem, CPUProtocolBase *protocol);
|
||||
int run(CPUState &state);
|
||||
int step(CPUState &state);
|
||||
void stop(CPUState &state);
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2025 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cpu/impl/interface.h>
|
||||
|
||||
#include <cpu/state.h>
|
||||
#include <unicorn/unicorn.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
|
||||
typedef std::unique_ptr<uc_struct, std::function<void(uc_struct *)>> UnicornPtr;
|
||||
|
||||
struct CPUState;
|
||||
|
||||
class UnicornCPU : public CPUInterface {
|
||||
UnicornPtr uc;
|
||||
|
||||
CPUState *parent;
|
||||
|
||||
Address ep;
|
||||
uc_hook memory_read_hook_handle = 0;
|
||||
uc_hook memory_write_hook_handle = 0;
|
||||
uc_hook code_hook_handle = 0;
|
||||
|
||||
bool is_inside_intr_hook = false;
|
||||
|
||||
std::stack<Address> lr_stack;
|
||||
|
||||
bool returning = false;
|
||||
bool did_break = false;
|
||||
bool did_inject = false;
|
||||
|
||||
void log_error_details(uc_err code);
|
||||
|
||||
static void intr_hook(uc_engine *uc, uint32_t intno, void *user_data);
|
||||
static void code_hook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data);
|
||||
static void read_hook(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data);
|
||||
static void write_hook(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data);
|
||||
void log_memory_access(uc_engine *uc, const char *type, Address address, int size, int64_t value, MemState &mem, CPUState &cpu, Address offset);
|
||||
|
||||
public:
|
||||
UnicornCPU(CPUState *state);
|
||||
|
||||
int execute_instructions_no_check(int num);
|
||||
|
||||
int run() override;
|
||||
int step() override;
|
||||
|
||||
void stop() override;
|
||||
|
||||
uint32_t get_reg(uint8_t idx) override;
|
||||
void set_reg(uint8_t idx, uint32_t val) override;
|
||||
|
||||
uint32_t get_sp() override;
|
||||
void set_sp(uint32_t val) override;
|
||||
|
||||
uint32_t get_pc() override;
|
||||
void set_pc(uint32_t val) override;
|
||||
|
||||
uint32_t get_lr() override;
|
||||
void set_lr(uint32_t val) override;
|
||||
|
||||
uint32_t get_cpsr() override;
|
||||
void set_cpsr(uint32_t val) override;
|
||||
|
||||
uint32_t get_tpidruro() override;
|
||||
void set_tpidruro(uint32_t val) override;
|
||||
|
||||
uint32_t get_fpscr() override;
|
||||
void set_fpscr(uint32_t val) override;
|
||||
|
||||
float get_float_reg(uint8_t idx) override;
|
||||
void set_float_reg(uint8_t idx, float val) override;
|
||||
|
||||
bool is_thumb_mode() override;
|
||||
|
||||
CPUContext save_context() override;
|
||||
void load_context(const CPUContext &ctx) override;
|
||||
void invalidate_jit_cache(Address start, size_t length) override;
|
||||
|
||||
bool hit_breakpoint() override;
|
||||
void trigger_breakpoint() override;
|
||||
void set_log_code(bool log) override;
|
||||
void set_log_mem(bool log) override;
|
||||
bool get_log_code() override;
|
||||
bool get_log_mem() override;
|
||||
};
|
||||
+1
-13
@@ -19,7 +19,6 @@
|
||||
#include <cpu/functions.h>
|
||||
#include <cpu/impl/dynarmic_cpu.h>
|
||||
#include <cpu/impl/interface.h>
|
||||
#include <cpu/impl/unicorn_cpu.h>
|
||||
#include <cpu/state.h>
|
||||
#include <mem/ptr.h>
|
||||
#include <util/types.h>
|
||||
@@ -39,7 +38,7 @@ SceUID get_thread_id(CPUState &state) {
|
||||
return state.thread_id;
|
||||
}
|
||||
|
||||
CPUStatePtr init_cpu(CPUBackend backend, bool cpu_opt, SceUID thread_id, std::size_t processor_id, MemState &mem, CPUProtocolBase *protocol) {
|
||||
CPUStatePtr init_cpu(bool cpu_opt, SceUID thread_id, std::size_t processor_id, MemState &mem, CPUProtocolBase *protocol) {
|
||||
CPUStatePtr state(new CPUState(), delete_cpu_state);
|
||||
state->mem = &mem;
|
||||
state->protocol = protocol;
|
||||
@@ -57,19 +56,8 @@ CPUStatePtr init_cpu(CPUBackend backend, bool cpu_opt, SceUID thread_id, std::si
|
||||
return CPUStatePtr();
|
||||
}
|
||||
|
||||
switch (backend) {
|
||||
case CPUBackend::Dynarmic: {
|
||||
Dynarmic::ExclusiveMonitor *monitor = static_cast<Dynarmic::ExclusiveMonitor *>(protocol->get_exclusive_monitor());
|
||||
state->cpu = std::make_unique<DynarmicCPU>(state.get(), processor_id, monitor, cpu_opt);
|
||||
break;
|
||||
}
|
||||
case CPUBackend::Unicorn: {
|
||||
state->cpu = std::make_unique<UnicornCPU>(state.get());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,446 +0,0 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2025 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#include <cpu/functions.h>
|
||||
#include <cpu/impl/unicorn_cpu.h>
|
||||
#include <mem/functions.h>
|
||||
#include <mem/ptr.h>
|
||||
#include <mem/util.h>
|
||||
#include <util/log.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cpu/disasm/functions.h>
|
||||
|
||||
#include <util/string_utils.h>
|
||||
|
||||
constexpr bool TRACE_RETURN_VALUES = true;
|
||||
constexpr bool LOG_REGISTERS = false;
|
||||
|
||||
static inline void func_trace(CPUState &state) {
|
||||
if (TRACE_RETURN_VALUES)
|
||||
if (is_returning(state.disasm))
|
||||
LOG_TRACE("Returning, r0: {}", log_hex(read_reg(state, 0)));
|
||||
}
|
||||
|
||||
void UnicornCPU::code_hook(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) {
|
||||
UnicornCPU &state = *static_cast<UnicornCPU *>(user_data);
|
||||
std::string disassembly = disassemble(*state.parent, address);
|
||||
if (LOG_REGISTERS) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
auto reg_name = fmt::format("r{}", i);
|
||||
auto reg_name_with_value = fmt::format("{}({})", reg_name, log_hex(state.get_reg(i)));
|
||||
string_utils::replace(disassembly, reg_name, reg_name_with_value);
|
||||
}
|
||||
|
||||
string_utils::replace(disassembly, "lr", fmt::format("lr({})", log_hex(state.get_lr())));
|
||||
string_utils::replace(disassembly, "sp", fmt::format("sp({})", log_hex(state.get_sp())));
|
||||
}
|
||||
|
||||
LOG_TRACE("{} ({}): {} {}", log_hex((uint64_t)uc), state.parent->thread_id, log_hex(address), disassembly);
|
||||
|
||||
func_trace(*state.parent);
|
||||
}
|
||||
|
||||
void UnicornCPU::read_hook(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) {
|
||||
assert(value == 0);
|
||||
|
||||
UnicornCPU &state = *static_cast<UnicornCPU *>(user_data);
|
||||
MemState &mem = *state.parent->mem;
|
||||
auto start = state.parent->protocol->get_watch_memory_addr(address);
|
||||
if (start) {
|
||||
memcpy(&value, Ptr<const void>(static_cast<Address>(address)).get(mem), size);
|
||||
state.log_memory_access(uc, "Read", start, size, value, mem, *state.parent, address - start);
|
||||
}
|
||||
}
|
||||
|
||||
void UnicornCPU::write_hook(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) {
|
||||
UnicornCPU &state = *static_cast<UnicornCPU *>(user_data);
|
||||
auto start = state.parent->protocol->get_watch_memory_addr(address);
|
||||
if (start) {
|
||||
MemState &mem = *state.parent->mem;
|
||||
state.log_memory_access(uc, "Write", start, size, value, mem, *state.parent, address - start);
|
||||
}
|
||||
}
|
||||
|
||||
void UnicornCPU::log_memory_access(uc_engine *uc, const char *type, Address address, int size, int64_t value, MemState &mem, CPUState &cpu, Address offset) {
|
||||
const char *const name = mem_name(address, mem);
|
||||
auto pc = get_pc();
|
||||
LOG_TRACE("{} ({}): {} {} bytes, address {} + {} ({}, {}), value {} at {}", log_hex((uint64_t)uc), cpu.thread_id, type, size, log_hex(address), log_hex(offset), log_hex(address + offset), name, log_hex(value), log_hex(pc));
|
||||
}
|
||||
|
||||
constexpr uint32_t INT_SVC = 2;
|
||||
constexpr uint32_t INT_BKPT = 7;
|
||||
|
||||
void UnicornCPU::intr_hook(uc_engine *uc, uint32_t intno, void *user_data) {
|
||||
assert(intno == INT_SVC || intno == INT_BKPT);
|
||||
UnicornCPU &state = *static_cast<UnicornCPU *>(user_data);
|
||||
uint32_t pc = state.get_pc();
|
||||
state.is_inside_intr_hook = true;
|
||||
if (intno == INT_SVC) {
|
||||
assert(!state.is_thumb_mode());
|
||||
const Address svc_address = pc - 4;
|
||||
uint32_t svc_instruction = 0;
|
||||
const auto err = uc_mem_read(uc, svc_address, &svc_instruction, sizeof(svc_instruction));
|
||||
assert(err == UC_ERR_OK);
|
||||
const uint32_t svc = state.is_thumb_mode() ? (svc_instruction & 0xff0000) >> 16 : svc_instruction & 0xffffff;
|
||||
state.parent->svc_called = true;
|
||||
state.parent->svc = svc;
|
||||
state.stop();
|
||||
} else if (intno == INT_BKPT) {
|
||||
state.stop();
|
||||
state.did_break = true;
|
||||
}
|
||||
state.is_inside_intr_hook = false;
|
||||
}
|
||||
|
||||
static void enable_vfp_fpu(uc_engine *uc) {
|
||||
uint64_t c1_c0_2 = 0;
|
||||
uc_err err = uc_reg_read(uc, UC_ARM_REG_C1_C0_2, &c1_c0_2);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
c1_c0_2 |= (0xf << 20);
|
||||
|
||||
err = uc_reg_write(uc, UC_ARM_REG_C1_C0_2, &c1_c0_2);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
const uint64_t fpexc = 0xf0000000;
|
||||
|
||||
err = uc_reg_write(uc, UC_ARM_REG_FPEXC, &fpexc);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
void UnicornCPU::log_error_details(uc_err code) {
|
||||
// I don't especially want the time logged for every line, but I also want it to print to the log file...
|
||||
LOG_ERROR("Unicorn error {}. {}\n{}", log_hex(code), uc_strerror(code), this->save_context().description());
|
||||
|
||||
auto pc = this->get_pc();
|
||||
if (pc < parent->mem->page_size)
|
||||
LOG_CRITICAL("PC is 0x{:x}", pc);
|
||||
else
|
||||
LOG_WARN("Executing: {}", disassemble(*parent, pc, nullptr));
|
||||
}
|
||||
|
||||
UnicornCPU::UnicornCPU(CPUState *state)
|
||||
: parent(state) {
|
||||
uc_engine *temp_uc = nullptr;
|
||||
uc_err err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &temp_uc);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
uc = UnicornPtr(temp_uc, uc_close);
|
||||
temp_uc = nullptr;
|
||||
|
||||
uc_hook hh = 0;
|
||||
|
||||
err = uc_hook_add(uc.get(), &hh, UC_HOOK_INTR, reinterpret_cast<void *>(&intr_hook), this, 1, 0);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
// Don't map the null page into unicorn so that unicorn returns access error instead of
|
||||
// crashing the whole emulator on invalid access
|
||||
err = uc_mem_map_ptr(uc.get(), state->mem->page_size, GiB(4) - state->mem->page_size, UC_PROT_ALL, &state->mem->memory[state->mem->page_size]);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
enable_vfp_fpu(uc.get());
|
||||
}
|
||||
|
||||
int UnicornCPU::execute_instructions_no_check(int num) {
|
||||
std::uint32_t pc = get_pc();
|
||||
bool thumb_mode = is_thumb_mode();
|
||||
if (thumb_mode) {
|
||||
pc |= 1;
|
||||
}
|
||||
|
||||
uc_err err = uc_emu_start(uc.get(), pc, 1ULL << 63, 0, num);
|
||||
|
||||
if (err != UC_ERR_OK) {
|
||||
log_error_details(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UnicornCPU::run() {
|
||||
uint32_t pc = get_pc();
|
||||
bool thumb_mode = is_thumb_mode();
|
||||
did_break = false;
|
||||
parent->svc_called = false;
|
||||
|
||||
pc = get_pc();
|
||||
if (thumb_mode) {
|
||||
pc |= 1;
|
||||
}
|
||||
|
||||
uc_err err = uc_emu_start(uc.get(), pc, 0, 0, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
log_error_details(err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pc = get_pc();
|
||||
thumb_mode = is_thumb_mode();
|
||||
if (thumb_mode) {
|
||||
pc |= 1;
|
||||
}
|
||||
|
||||
return parent->halt_instruction_pc <= pc && pc <= parent->halt_instruction_pc + 4;
|
||||
}
|
||||
|
||||
int UnicornCPU::step() {
|
||||
uint32_t pc = get_pc();
|
||||
bool thumb_mode = is_thumb_mode();
|
||||
|
||||
did_break = false;
|
||||
parent->svc_called = false;
|
||||
|
||||
pc = get_pc();
|
||||
if (thumb_mode) {
|
||||
pc |= 1;
|
||||
}
|
||||
|
||||
uc_err err = uc_emu_start(uc.get(), pc, 0, 0, 1);
|
||||
|
||||
if (err != UC_ERR_OK) {
|
||||
log_error_details(err);
|
||||
return -1;
|
||||
}
|
||||
pc = get_pc();
|
||||
thumb_mode = is_thumb_mode();
|
||||
if (thumb_mode) {
|
||||
pc |= 1;
|
||||
}
|
||||
|
||||
return parent->halt_instruction_pc <= pc && pc <= parent->halt_instruction_pc + 4;
|
||||
}
|
||||
|
||||
void UnicornCPU::stop() {
|
||||
const uc_err err = uc_emu_stop(uc.get());
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_reg(uint8_t idx) {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_R0 + static_cast<int>(idx), &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_reg(uint8_t idx, uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_R0 + static_cast<int>(idx), &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_sp() {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_SP, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_sp(uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_SP, &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_pc() {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_PC, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_pc(uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_PC, &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_lr() {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_LR, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_lr(uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_LR, &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_cpsr() {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_CPSR, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_cpsr(uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_CPSR, &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_tpidruro() {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_C13_C0_3, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_tpidruro(uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_C13_C0_3, &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
uint32_t UnicornCPU::get_fpscr() {
|
||||
uint32_t value = 0;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_FPSCR, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_fpscr(uint32_t val) {
|
||||
const uc_err err = uc_reg_write(uc.get(), UC_ARM_REG_FPSCR, &val);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
float UnicornCPU::get_float_reg(uint8_t idx) {
|
||||
DoubleReg value;
|
||||
|
||||
const int single_index = idx / 2;
|
||||
const uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_D0 + single_index, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
return value.f[idx % 2];
|
||||
}
|
||||
|
||||
void UnicornCPU::set_float_reg(uint8_t idx, float val) {
|
||||
DoubleReg value;
|
||||
|
||||
const int single_index = idx / 2;
|
||||
uc_err err = uc_reg_read(uc.get(), UC_ARM_REG_D0 + single_index, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
value.f[idx % 2] = val;
|
||||
|
||||
err = uc_reg_write(uc.get(), UC_ARM_REG_D0 + single_index, &value);
|
||||
assert(err == UC_ERR_OK);
|
||||
}
|
||||
|
||||
bool UnicornCPU::is_thumb_mode() {
|
||||
size_t mode = 0;
|
||||
const uc_err err = uc_query(uc.get(), UC_QUERY_MODE, &mode);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
return mode & UC_MODE_THUMB;
|
||||
}
|
||||
|
||||
CPUContext UnicornCPU::save_context() {
|
||||
CPUContext ctx;
|
||||
for (size_t i = 0; i < 13; i++) {
|
||||
ctx.cpu_registers[i] = get_reg(i);
|
||||
}
|
||||
ctx.cpu_registers[13] = get_sp();
|
||||
ctx.cpu_registers[14] = get_lr();
|
||||
ctx.set_pc(is_thumb_mode() ? get_pc() | 1 : get_pc());
|
||||
|
||||
for (size_t i = 0; i < ctx.fpu_registers.size(); i++) {
|
||||
ctx.fpu_registers[i] = get_float_reg(i);
|
||||
}
|
||||
|
||||
// Unicorn doesn't like tweaking cpsr
|
||||
// ctx.cpsr = get_cpsr();
|
||||
// ctx.fpscr = get_fpscr();
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void UnicornCPU::load_context(const CPUContext &ctx) {
|
||||
for (size_t i = 0; i < ctx.fpu_registers.size(); i++) {
|
||||
set_float_reg(i, ctx.fpu_registers[i]);
|
||||
}
|
||||
|
||||
// Unicorn doesn't like tweaking cpsr
|
||||
// set_cpsr(ctx.cpsr);
|
||||
// set_fpscr(ctx.fpscr);
|
||||
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
set_reg(i, ctx.cpu_registers[i]);
|
||||
}
|
||||
set_sp(ctx.get_sp());
|
||||
set_lr(ctx.get_lr());
|
||||
set_pc(ctx.thumb() ? ctx.get_pc() | 1 : ctx.get_pc());
|
||||
}
|
||||
|
||||
void UnicornCPU::invalidate_jit_cache(Address start, size_t length) {
|
||||
uc_ctl_remove_cache(uc.get(), start, start + length);
|
||||
}
|
||||
|
||||
bool UnicornCPU::hit_breakpoint() {
|
||||
return did_break;
|
||||
}
|
||||
|
||||
void UnicornCPU::trigger_breakpoint() {
|
||||
stop();
|
||||
did_break = true;
|
||||
}
|
||||
|
||||
void UnicornCPU::set_log_code(bool log) {
|
||||
if (get_log_code() == log) {
|
||||
return;
|
||||
}
|
||||
if (log) {
|
||||
const uc_err err = uc_hook_add(uc.get(), &code_hook_handle, UC_HOOK_CODE, reinterpret_cast<void *>(&code_hook), this, 1, 0);
|
||||
|
||||
assert(err == UC_ERR_OK);
|
||||
} else {
|
||||
auto err = uc_hook_del(uc.get(), code_hook_handle);
|
||||
assert(err == UC_ERR_OK);
|
||||
code_hook_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UnicornCPU::set_log_mem(bool log) {
|
||||
if (get_log_mem() == log) {
|
||||
return;
|
||||
}
|
||||
if (log) {
|
||||
uc_err err = uc_hook_add(uc.get(), &memory_read_hook_handle, UC_HOOK_MEM_READ, reinterpret_cast<void *>(&read_hook), this, 1, 0);
|
||||
assert(err == UC_ERR_OK);
|
||||
|
||||
err = uc_hook_add(uc.get(), &memory_write_hook_handle, UC_HOOK_MEM_WRITE, reinterpret_cast<void *>(&write_hook), this, 1, 0);
|
||||
assert(err == UC_ERR_OK);
|
||||
} else {
|
||||
auto err = uc_hook_del(uc.get(), memory_read_hook_handle);
|
||||
assert(err == UC_ERR_OK);
|
||||
memory_read_hook_handle = 0;
|
||||
|
||||
err = uc_hook_del(uc.get(), memory_write_hook_handle);
|
||||
assert(err == UC_ERR_OK);
|
||||
memory_write_hook_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool UnicornCPU::get_log_code() {
|
||||
return code_hook_handle != 0;
|
||||
}
|
||||
|
||||
bool UnicornCPU::get_log_mem() {
|
||||
return memory_read_hook_handle != 0 && memory_write_hook_handle != 0;
|
||||
}
|
||||
@@ -54,7 +54,6 @@ std::vector<std::string>::iterator get_live_area_current_open_apps_list_index(Gu
|
||||
std::map<DateTime, std::string> get_date_time(GuiState &gui, EmuEnvState &emuenv, const tm &date_time);
|
||||
std::string get_unit_size(const size_t size);
|
||||
void get_app_param(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path);
|
||||
std::string get_cpu_backend(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path);
|
||||
void get_firmware_file(EmuEnvState &emuenv);
|
||||
void get_modules_list(GuiState &gui, EmuEnvState &emuenv);
|
||||
void get_notice_list(EmuEnvState &emuenv);
|
||||
|
||||
@@ -343,8 +343,8 @@ void draw_app_context_menu(GuiState &gui, EmuEnvState &emuenv, const std::string
|
||||
if (has_state_report) {
|
||||
const auto copy_vita3k_summary = [&]() {
|
||||
const auto vita3k_summary = fmt::format(
|
||||
"# Vita3K summary\n- Version: {}\n- Build number: {}\n- Commit hash: https://github.com/vita3k/vita3k/commit/{}\n- CPU backend: {}\n- GPU backend: {}",
|
||||
app_version, app_number, app_hash, get_cpu_backend(gui, emuenv, app_path), emuenv.cfg.backend_renderer);
|
||||
"# Vita3K summary\n- Version: {}\n- Build number: {}\n- Commit hash: https://github.com/vita3k/vita3k/commit/{}\n- GPU backend: {}",
|
||||
app_version, app_number, app_hash, emuenv.cfg.backend_renderer);
|
||||
ImGui::LogToClipboard();
|
||||
ImGui::LogText("%s", vita3k_summary.c_str());
|
||||
ImGui::LogFinish();
|
||||
@@ -385,8 +385,8 @@ void draw_app_context_menu(GuiState &gui, EmuEnvState &emuenv, const std::string
|
||||
|
||||
// Create Vita3K summary
|
||||
const auto vita3k_summary = fmt::format(
|
||||
"%23 Vita3K summary%0A- Version: {}%0A- Build number: {}%0A- Commit hash: https://github.com/vita3k/vita3k/commit/{}%0A- CPU backend: {}%0A- GPU backend: {}",
|
||||
app_version, app_number, app_hash, get_cpu_backend(gui, emuenv, app_path), emuenv.cfg.backend_renderer);
|
||||
"%23 Vita3K summary%0A- Version: {}%0A- Build number: {}%0A- Commit hash: https://github.com/vita3k/vita3k/commit/{}%0A- GPU backend: {}",
|
||||
app_version, app_number, app_hash, emuenv.cfg.backend_renderer);
|
||||
|
||||
#ifdef _WIN32
|
||||
const auto user = std::getenv("USERNAME");
|
||||
|
||||
@@ -123,8 +123,6 @@ static void change_emulator_path(GuiState &gui, EmuEnvState &emuenv) {
|
||||
}
|
||||
}
|
||||
|
||||
static CPUBackend config_cpu_backend;
|
||||
|
||||
/**
|
||||
* @brief Set up `config` with the values contained in the custom config file of a certain PlayStation Vita application
|
||||
*
|
||||
@@ -160,7 +158,6 @@ static bool get_custom_config(GuiState &gui, EmuEnvState &emuenv, const std::str
|
||||
// Load CPU Config
|
||||
if (!config_child.child("cpu").empty()) {
|
||||
const auto cpu_child = config_child.child("cpu");
|
||||
config.cpu_backend = cpu_child.attribute("cpu-backend").as_string();
|
||||
config.cpu_opt = cpu_child.attribute("cpu-opt").as_bool();
|
||||
}
|
||||
|
||||
@@ -216,10 +213,6 @@ static bool get_custom_config(GuiState &gui, EmuEnvState &emuenv, const std::str
|
||||
return false;
|
||||
}
|
||||
|
||||
static CPUBackend set_cpu_backend(std::string &cpu_backend) {
|
||||
return cpu_backend == "Dynarmic" ? CPUBackend::Dynarmic : CPUBackend::Unicorn;
|
||||
}
|
||||
|
||||
static int current_aniso_filter_log, max_aniso_filter_log, audio_backend_idx, current_user_lang;
|
||||
static std::vector<std::string> list_user_lang;
|
||||
|
||||
@@ -234,7 +227,6 @@ void init_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path
|
||||
// If no app-specific config file is being used for the initialized application,
|
||||
// set up `config` with the values set in the global emulator configuration
|
||||
if (!get_custom_config(gui, emuenv, app_path)) {
|
||||
config.cpu_backend = emuenv.cfg.cpu_backend;
|
||||
config.cpu_opt = emuenv.cfg.cpu_opt;
|
||||
config.modules_mode = emuenv.cfg.modules_mode;
|
||||
config.lle_modules = emuenv.cfg.lle_modules;
|
||||
@@ -276,7 +268,6 @@ void init_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path
|
||||
get_modules_list(gui, emuenv);
|
||||
config.stretch_the_display_area = emuenv.cfg.stretch_the_display_area;
|
||||
config.fullscreen_hd_res_pixel_perfect = emuenv.cfg.fullscreen_hd_res_pixel_perfect;
|
||||
config_cpu_backend = set_cpu_backend(config.cpu_backend);
|
||||
current_aniso_filter_log = static_cast<int>(log2f(static_cast<float>(config.anisotropic_filtering)));
|
||||
max_aniso_filter_log = static_cast<int>(log2f(static_cast<float>(emuenv.renderer->get_max_anisotropic_filtering())));
|
||||
audio_backend_idx = (emuenv.cfg.audio_backend == "SDL") ? 0 : 1;
|
||||
@@ -318,7 +309,6 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) {
|
||||
|
||||
// CPU
|
||||
auto cpu_child = config_child.append_child("cpu");
|
||||
cpu_child.append_attribute("cpu-backend") = config.cpu_backend.c_str();
|
||||
cpu_child.append_attribute("cpu-opt") = config.cpu_opt;
|
||||
|
||||
// GPU
|
||||
@@ -357,7 +347,6 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) {
|
||||
if (!save_xml)
|
||||
LOG_ERROR("Failed to save custom config xml for app path: {}, in path: {}", emuenv.app_path, CONFIG_PATH);
|
||||
} else {
|
||||
emuenv.cfg.cpu_backend = config.cpu_backend;
|
||||
emuenv.cfg.cpu_opt = config.cpu_opt;
|
||||
emuenv.cfg.modules_mode = config.modules_mode;
|
||||
emuenv.cfg.lle_modules = config.lle_modules;
|
||||
@@ -398,13 +387,6 @@ static void save_config(GuiState &gui, EmuEnvState &emuenv) {
|
||||
config::serialize_config(emuenv.cfg, emuenv.cfg.config_path);
|
||||
}
|
||||
|
||||
std::string get_cpu_backend(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path) {
|
||||
if (!get_custom_config(gui, emuenv, app_path))
|
||||
return emuenv.cfg.cpu_backend;
|
||||
|
||||
return config.cpu_backend;
|
||||
}
|
||||
|
||||
static void set_vsync_state(const bool &state) {
|
||||
if (state) {
|
||||
// Try adaptive vsync first, falling back to regular vsync.
|
||||
@@ -433,7 +415,6 @@ void set_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path)
|
||||
emuenv.cfg.current_config = config;
|
||||
else {
|
||||
// Else inherit the values from the global emulator config
|
||||
emuenv.cfg.current_config.cpu_backend = emuenv.cfg.cpu_backend;
|
||||
emuenv.cfg.current_config.cpu_opt = emuenv.cfg.cpu_opt;
|
||||
emuenv.cfg.current_config.modules_mode = emuenv.cfg.modules_mode;
|
||||
emuenv.cfg.current_config.lle_modules = emuenv.cfg.lle_modules;
|
||||
@@ -482,7 +463,6 @@ void set_config(GuiState &gui, EmuEnvState &emuenv, const std::string &app_path)
|
||||
|
||||
// No change it if app already running
|
||||
if (emuenv.io.title_id.empty()) {
|
||||
emuenv.kernel.cpu_backend = set_cpu_backend(emuenv.cfg.current_config.cpu_backend);
|
||||
emuenv.kernel.cpu_opt = emuenv.cfg.current_config.cpu_opt;
|
||||
emuenv.audio.set_backend(emuenv.cfg.audio_backend);
|
||||
}
|
||||
@@ -575,18 +555,9 @@ void draw_settings_dialog(GuiState &gui, EmuEnvState &emuenv) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, GUI_COLOR_TEXT_MENUBAR);
|
||||
if (ImGui::BeginTabItem("CPU")) {
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Spacing();
|
||||
static const char *LIST_CPU_BACKEND[] = { "Dynarmic", "Unicorn" };
|
||||
const char *LIST_CPU_BACKEND_DISPLAY[] = { "Dynarmic", lang.cpu["unicorn"].c_str() };
|
||||
ImGui::TextColored(GUI_COLOR_TEXT_TITLE, "%s", lang.cpu["cpu_backend"].c_str());
|
||||
if (ImGui::Combo("##cpu_backend", reinterpret_cast<int *>(&config_cpu_backend), LIST_CPU_BACKEND_DISPLAY, IM_ARRAYSIZE(LIST_CPU_BACKEND_DISPLAY)))
|
||||
config.cpu_backend = LIST_CPU_BACKEND[static_cast<int>(config_cpu_backend)];
|
||||
SetTooltipEx(lang.cpu["select_cpu_backend"].c_str());
|
||||
if (config_cpu_backend == CPUBackend::Dynarmic) {
|
||||
ImGui::Spacing();
|
||||
ImGui::Checkbox(lang.cpu["cpu_opt"].c_str(), &config.cpu_opt);
|
||||
SetTooltipEx(lang.cpu["cpu_opt_description"].c_str());
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
} else
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
@@ -391,7 +391,7 @@ static ExitCode load_app_impl(SceUID &main_module_id, EmuEnvState &emuenv) {
|
||||
const auto call_import = [&emuenv](CPUState &cpu, uint32_t nid, SceUID thread_id) {
|
||||
::call_import(emuenv, cpu, nid, thread_id);
|
||||
};
|
||||
if (!emuenv.kernel.init(emuenv.mem, call_import, emuenv.kernel.cpu_backend, emuenv.kernel.cpu_opt)) {
|
||||
if (!emuenv.kernel.init(emuenv.mem, call_import, emuenv.kernel.cpu_opt)) {
|
||||
LOG_WARN("Failed to init kernel!");
|
||||
return KernelInitFailed;
|
||||
}
|
||||
@@ -405,8 +405,7 @@ static ExitCode load_app_impl(SceUID &main_module_id, EmuEnvState &emuenv) {
|
||||
logging::set_level(static_cast<spdlog::level::level_enum>(emuenv.cfg.log_level));
|
||||
}
|
||||
|
||||
LOG_INFO("cpu-backend: {}", emuenv.cfg.current_config.cpu_backend);
|
||||
LOG_INFO_IF(emuenv.kernel.cpu_backend == CPUBackend::Dynarmic, "CPU Optimisation state: {}", emuenv.cfg.current_config.cpu_opt);
|
||||
LOG_INFO("CPU Optimisation state: {}", emuenv.cfg.current_config.cpu_opt);
|
||||
LOG_INFO("ngs state: {}", emuenv.cfg.current_config.ngs_enable);
|
||||
LOG_INFO("Resolution multiplier: {}", emuenv.cfg.resolution_multiplier);
|
||||
if (emuenv.ctrl.controllers_num) {
|
||||
|
||||
@@ -131,7 +131,6 @@ struct KernelState {
|
||||
ModuleUidByNid module_uid_by_nid;
|
||||
|
||||
bool cpu_opt;
|
||||
CPUBackend cpu_backend;
|
||||
CorenumAllocator corenum_allocator;
|
||||
CPUProtocolPtr cpu_protocol;
|
||||
ExclusiveMonitorPtr exclusive_monitor;
|
||||
@@ -148,7 +147,7 @@ struct KernelState {
|
||||
return next_uid++;
|
||||
}
|
||||
|
||||
bool init(MemState &mem, const CallImportFunc &call_import, CPUBackend cpu_backend, bool cpu_opt);
|
||||
bool init(MemState &mem, const CallImportFunc &call_import, bool cpu_opt);
|
||||
void load_process_param(MemState &mem, Ptr<uint32_t> ptr);
|
||||
ThreadStatePtr create_thread(MemState &mem, const char *name, Ptr<const void> entry_point = Ptr<const void>(0));
|
||||
ThreadStatePtr create_thread(MemState &mem, const char *name, Ptr<const void> entry_point, int init_priority, SceInt32 affinity_mask, int stack_size, const SceKernelThreadOptParam *option);
|
||||
|
||||
@@ -82,7 +82,7 @@ KernelState::KernelState()
|
||||
: debugger(*this) {
|
||||
}
|
||||
|
||||
bool KernelState::init(MemState &mem, const CallImportFunc &call_import, CPUBackend cpu_backend, bool cpu_opt) {
|
||||
bool KernelState::init(MemState &mem, const CallImportFunc &call_import, bool cpu_opt) {
|
||||
constexpr std::size_t MAX_CORE_COUNT = 150;
|
||||
|
||||
corenum_allocator.set_max_core_count(MAX_CORE_COUNT);
|
||||
@@ -90,7 +90,6 @@ bool KernelState::init(MemState &mem, const CallImportFunc &call_import, CPUBack
|
||||
start_tick = rtc_get_ticks(rtc_base_ticks());
|
||||
base_tick = { rtc_base_ticks() };
|
||||
cpu_protocol = std::make_unique<CPUProtocol>(*this, mem, call_import);
|
||||
this->cpu_backend = cpu_backend;
|
||||
this->cpu_opt = cpu_opt;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -71,7 +71,7 @@ int ThreadState::init(const char *name, Ptr<const void> entry_point, int init_pr
|
||||
start_tick = rtc_get_ticks(kernel.base_tick.tick);
|
||||
last_vblank_waited = 0;
|
||||
|
||||
cpu = init_cpu(kernel.cpu_backend, kernel.cpu_opt, id, static_cast<std::size_t>(core_num), mem, kernel.cpu_protocol.get());
|
||||
cpu = init_cpu(kernel.cpu_opt, id, static_cast<std::size_t>(core_num), mem, kernel.cpu_protocol.get());
|
||||
if (!cpu) {
|
||||
return SCE_KERNEL_ERROR_ERROR;
|
||||
}
|
||||
|
||||
@@ -531,9 +531,6 @@ struct LangState {
|
||||
{ "manual_description", "Select Manual mode to load selected modules from the list below." }
|
||||
};
|
||||
std::map<std::string, std::string> cpu = {
|
||||
{ "unicorn", "Unicorn (deprecated)" },
|
||||
{ "cpu_backend", "CPU Backend" },
|
||||
{ "select_cpu_backend", "Select your preferred CPU backend." },
|
||||
{ "cpu_opt", "Enable optimizations" },
|
||||
{ "cpu_opt_description", "Check the box to enable additional CPU JIT optimizations." }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user