mirror of https://github.com/PCSX2/pcsx2.git
Compare commits
5 Commits
3e22dd38e9
...
3697ddd194
Author | SHA1 | Date |
---|---|---|
chaoticgd | 3697ddd194 | |
shockdude | fbe0c8b9cc | |
Ziemas | 2e3501366f | |
Ziemas | ef7169dbbf | |
chaoticgd | 690c6dc812 |
|
@ -97,11 +97,20 @@ void SymbolImporter::OnElfChanged(std::vector<u8> elf, const std::string& elf_fi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalyseElf(std::move(elf), elf_file_name, EmuConfig.DebuggerAnalysis);
|
AnalyseElf(std::move(elf), elf_file_name, EmuConfig.DebuggerAnalysis, true);
|
||||||
|
|
||||||
m_symbol_table_loaded_on_boot = true;
|
m_symbol_table_loaded_on_boot = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SymbolImporter::OnElfLoadedInMemory()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_elf_loaded_in_memory_mutex);
|
||||||
|
m_elf_loaded_in_memory = true;
|
||||||
|
}
|
||||||
|
m_elf_loaded_in_memory_condition_variable.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
void SymbolImporter::OnDebuggerOpened()
|
void SymbolImporter::OnDebuggerOpened()
|
||||||
{
|
{
|
||||||
m_debugger_open = true;
|
m_debugger_open = true;
|
||||||
|
@ -165,11 +174,23 @@ void SymbolImporter::LoadAndAnalyseElf(Pcsx2Config::DebugAnalysisOptions options
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalyseElf(elfo.ReleaseData(), elf_path, options);
|
AnalyseElf(elfo.ReleaseData(), elf_path, options, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SymbolImporterThreadParameters
|
||||||
|
{
|
||||||
|
std::vector<u8> elf;
|
||||||
|
std::string elf_file_name;
|
||||||
|
std::string nocash_path;
|
||||||
|
Pcsx2Config::DebugAnalysisOptions options;
|
||||||
|
bool wait_until_elf_is_loaded;
|
||||||
|
};
|
||||||
|
|
||||||
void SymbolImporter::AnalyseElf(
|
void SymbolImporter::AnalyseElf(
|
||||||
std::vector<u8> elf, const std::string& elf_file_name, Pcsx2Config::DebugAnalysisOptions options)
|
std::vector<u8> elf,
|
||||||
|
const std::string& elf_file_name,
|
||||||
|
Pcsx2Config::DebugAnalysisOptions options,
|
||||||
|
bool wait_until_elf_is_loaded)
|
||||||
{
|
{
|
||||||
// Search for a .sym file to load symbols from.
|
// Search for a .sym file to load symbols from.
|
||||||
std::string nocash_path;
|
std::string nocash_path;
|
||||||
|
@ -185,38 +206,63 @@ void SymbolImporter::AnalyseElf(
|
||||||
nocash_path = iso_file_path.substr(0, n) + ".sym";
|
nocash_path = iso_file_path.substr(0, n) + ".sym";
|
||||||
}
|
}
|
||||||
|
|
||||||
ccc::Result<ccc::ElfFile> parsed_elf = ccc::ElfFile::parse(std::move(elf));
|
SymbolImporterThreadParameters parameters;
|
||||||
if (!parsed_elf.success())
|
parameters.elf = std::move(elf);
|
||||||
{
|
parameters.elf_file_name = elf_file_name;
|
||||||
ccc::report_error(parsed_elf.error());
|
parameters.nocash_path = std::move(nocash_path);
|
||||||
return;
|
parameters.options = std::move(options);
|
||||||
}
|
parameters.wait_until_elf_is_loaded = wait_until_elf_is_loaded;
|
||||||
|
|
||||||
ccc::ElfSymbolFile symbol_file(std::move(*parsed_elf), std::move(elf_file_name));
|
|
||||||
|
|
||||||
ShutdownWorkerThread();
|
ShutdownWorkerThread();
|
||||||
|
|
||||||
m_import_thread = std::thread([this, nocash_path, options, worker_symbol_file = std::move(symbol_file), builtins = m_builtin_types]() {
|
m_import_thread = std::thread([this, params = std::move(parameters)]() {
|
||||||
Threading::SetNameOfCurrentThread("Symbol Worker");
|
Threading::SetNameOfCurrentThread("Symbol Worker");
|
||||||
|
|
||||||
|
ccc::Result<ccc::ElfFile> parsed_elf = ccc::ElfFile::parse(std::move(params.elf));
|
||||||
|
if (!parsed_elf.success())
|
||||||
|
{
|
||||||
|
ccc::report_error(parsed_elf.error());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccc::ElfSymbolFile symbol_file(std::move(*parsed_elf), std::move(params.elf_file_name));
|
||||||
|
|
||||||
ccc::SymbolDatabase temp_database;
|
ccc::SymbolDatabase temp_database;
|
||||||
|
|
||||||
ImportSymbols(temp_database, worker_symbol_file, nocash_path, options, builtins, &m_interrupt_import_thread);
|
ImportSymbols(
|
||||||
|
temp_database,
|
||||||
|
symbol_file,
|
||||||
|
params.nocash_path,
|
||||||
|
params.options,
|
||||||
|
m_builtin_types,
|
||||||
|
&m_interrupt_import_thread);
|
||||||
|
|
||||||
if (m_interrupt_import_thread)
|
if (m_interrupt_import_thread)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (options.GenerateFunctionHashes)
|
if (params.options.GenerateFunctionHashes)
|
||||||
{
|
{
|
||||||
ElfMemoryReader reader(worker_symbol_file.elf());
|
ElfMemoryReader reader(symbol_file.elf());
|
||||||
SymbolGuardian::GenerateFunctionHashes(temp_database, reader);
|
SymbolGuardian::GenerateFunctionHashes(temp_database, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_interrupt_import_thread)
|
if (m_interrupt_import_thread)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (params.wait_until_elf_is_loaded && params.options.FunctionScanMode == DebugFunctionScanMode::SCAN_MEMORY)
|
||||||
|
{
|
||||||
|
// Wait for the entry point to start compiling on the CPU thread so
|
||||||
|
// we know the functions we want to scan are loaded in memory.
|
||||||
|
std::unique_lock lock(m_elf_loaded_in_memory_mutex);
|
||||||
|
m_elf_loaded_in_memory_condition_variable.wait(lock,
|
||||||
|
[this]() { return m_elf_loaded_in_memory; });
|
||||||
|
|
||||||
|
if (m_interrupt_import_thread)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_guardian.ReadWrite([&](ccc::SymbolDatabase& database) {
|
m_guardian.ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||||
ClearExistingSymbols(database, options);
|
ClearExistingSymbols(database, params.options);
|
||||||
|
|
||||||
if (m_interrupt_import_thread)
|
if (m_interrupt_import_thread)
|
||||||
return;
|
return;
|
||||||
|
@ -229,7 +275,7 @@ void SymbolImporter::AnalyseElf(
|
||||||
// The function scanner has to be run on the main database so that
|
// The function scanner has to be run on the main database so that
|
||||||
// functions created before the importer was run are still
|
// functions created before the importer was run are still
|
||||||
// considered. Otherwise, duplicate functions will be created.
|
// considered. Otherwise, duplicate functions will be created.
|
||||||
ScanForFunctions(database, worker_symbol_file, options);
|
ScanForFunctions(database, symbol_file, params.options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -239,9 +285,23 @@ void SymbolImporter::ShutdownWorkerThread()
|
||||||
if (m_import_thread.joinable())
|
if (m_import_thread.joinable())
|
||||||
{
|
{
|
||||||
m_interrupt_import_thread = true;
|
m_interrupt_import_thread = true;
|
||||||
|
|
||||||
|
// Make sure the import thread is woken up so we can shut it down.
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_elf_loaded_in_memory_mutex);
|
||||||
|
m_elf_loaded_in_memory = true;
|
||||||
|
}
|
||||||
|
m_elf_loaded_in_memory_condition_variable.notify_one();
|
||||||
|
|
||||||
m_import_thread.join();
|
m_import_thread.join();
|
||||||
|
|
||||||
m_interrupt_import_thread = false;
|
m_interrupt_import_thread = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_elf_loaded_in_memory_mutex);
|
||||||
|
m_elf_loaded_in_memory = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolImporter::ClearExistingSymbols(ccc::SymbolDatabase& database, const Pcsx2Config::DebugAnalysisOptions& options)
|
void SymbolImporter::ClearExistingSymbols(ccc::SymbolDatabase& database, const Pcsx2Config::DebugAnalysisOptions& options)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "SymbolGuardian.h"
|
#include "SymbolGuardian.h"
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
class DebugInterface;
|
class DebugInterface;
|
||||||
|
|
||||||
class SymbolImporter
|
class SymbolImporter
|
||||||
|
@ -17,6 +19,7 @@ public:
|
||||||
// that are used to determine when symbol tables should be loaded, and
|
// that are used to determine when symbol tables should be loaded, and
|
||||||
// should be called from the CPU thread.
|
// should be called from the CPU thread.
|
||||||
void OnElfChanged(std::vector<u8> elf, const std::string& elf_file_name);
|
void OnElfChanged(std::vector<u8> elf, const std::string& elf_file_name);
|
||||||
|
void OnElfLoadedInMemory();
|
||||||
void OnDebuggerOpened();
|
void OnDebuggerOpened();
|
||||||
void OnDebuggerClosed();
|
void OnDebuggerClosed();
|
||||||
|
|
||||||
|
@ -30,7 +33,11 @@ public:
|
||||||
|
|
||||||
// Import symbols from the ELF file, nocash symbols, and scan for functions.
|
// Import symbols from the ELF file, nocash symbols, and scan for functions.
|
||||||
// Should be called from the CPU thread.
|
// Should be called from the CPU thread.
|
||||||
void AnalyseElf(std::vector<u8> elf, const std::string& elf_file_name, Pcsx2Config::DebugAnalysisOptions options);
|
void AnalyseElf(
|
||||||
|
std::vector<u8> elf,
|
||||||
|
const std::string& elf_file_name,
|
||||||
|
Pcsx2Config::DebugAnalysisOptions options,
|
||||||
|
bool wait_until_elf_is_loaded);
|
||||||
|
|
||||||
// Interrupt the import thread. Should be called from the CPU thread.
|
// Interrupt the import thread. Should be called from the CPU thread.
|
||||||
void ShutdownWorkerThread();
|
void ShutdownWorkerThread();
|
||||||
|
@ -77,6 +84,10 @@ protected:
|
||||||
std::thread m_import_thread;
|
std::thread m_import_thread;
|
||||||
std::atomic_bool m_interrupt_import_thread = false;
|
std::atomic_bool m_interrupt_import_thread = false;
|
||||||
|
|
||||||
|
std::mutex m_elf_loaded_in_memory_mutex;
|
||||||
|
std::condition_variable m_elf_loaded_in_memory_condition_variable;
|
||||||
|
bool m_elf_loaded_in_memory = false;
|
||||||
|
|
||||||
std::map<std::string, ccc::DataTypeHandle> m_builtin_types;
|
std::map<std::string, ccc::DataTypeHandle> m_builtin_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Counters.h"
|
#include "Counters.h"
|
||||||
#include "DebugTools/Breakpoints.h"
|
#include "DebugTools/Breakpoints.h"
|
||||||
|
#include "DebugTools/SymbolImporter.h"
|
||||||
#include "Elfheader.h"
|
#include "Elfheader.h"
|
||||||
#include "GS.h"
|
#include "GS.h"
|
||||||
#include "GS/GS.h"
|
#include "GS/GS.h"
|
||||||
|
@ -80,6 +81,9 @@ static void PostLoadPrep()
|
||||||
CBreakPoints::SetSkipFirst(BREAKPOINT_IOP, 0);
|
CBreakPoints::SetSkipFirst(BREAKPOINT_IOP, 0);
|
||||||
|
|
||||||
UpdateVSyncRate(true);
|
UpdateVSyncRate(true);
|
||||||
|
|
||||||
|
if (VMManager::Internal::HasBootedELF())
|
||||||
|
R5900SymbolImporter.OnElfLoadedInMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -93,19 +93,19 @@ namespace usb_pad
|
||||||
u8 right_turntable = 0x80;
|
u8 right_turntable = 0x80;
|
||||||
if (data.left_turntable_ccw > 0)
|
if (data.left_turntable_ccw > 0)
|
||||||
{
|
{
|
||||||
left_turntable -= static_cast<u8>(std::min<int>(data.left_turntable_ccw * turntable_multiplier, 0x7F));
|
left_turntable -= static_cast<u8>(std::min<int>(data.left_turntable_ccw, 0x7F));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
left_turntable += static_cast<u8>(std::min<int>(data.left_turntable_cw * turntable_multiplier, 0x7F));
|
left_turntable += static_cast<u8>(std::min<int>(data.left_turntable_cw, 0x7F));
|
||||||
}
|
}
|
||||||
if (data.right_turntable_ccw > 0)
|
if (data.right_turntable_ccw > 0)
|
||||||
{
|
{
|
||||||
right_turntable -= static_cast<u8>(std::min<int>(data.right_turntable_ccw * turntable_multiplier, 0x7F));
|
right_turntable -= static_cast<u8>(std::min<int>(data.right_turntable_ccw, 0x7F));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
right_turntable += static_cast<u8>(std::min<int>(data.right_turntable_cw * turntable_multiplier, 0x7F));
|
right_turntable += static_cast<u8>(std::min<int>(data.right_turntable_cw, 0x7F));
|
||||||
}
|
}
|
||||||
buf[3] = 0x80;
|
buf[3] = 0x80;
|
||||||
buf[4] = 0x80;
|
buf[4] = 0x80;
|
||||||
|
@ -369,19 +369,19 @@ namespace usb_pad
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_LEFT_TURNTABLE_CW:
|
case CID_DJ_LEFT_TURNTABLE_CW:
|
||||||
s->data.left_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.left_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_LEFT_TURNTABLE_CCW:
|
case CID_DJ_LEFT_TURNTABLE_CCW:
|
||||||
s->data.left_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.left_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_RIGHT_TURNTABLE_CW:
|
case CID_DJ_RIGHT_TURNTABLE_CW:
|
||||||
s->data.right_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.right_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_RIGHT_TURNTABLE_CCW:
|
case CID_DJ_RIGHT_TURNTABLE_CCW:
|
||||||
s->data.right_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128));
|
s->data.right_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CID_DJ_DPAD_UP:
|
case CID_DJ_DPAD_UP:
|
||||||
|
@ -446,8 +446,8 @@ namespace usb_pad
|
||||||
{"EffectsKnobRight", TRANSLATE_NOOP("USB", "Effects Knob Right"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_EFFECTSKNOB_RIGHT, GenericInputBinding::RightStickRight},
|
{"EffectsKnobRight", TRANSLATE_NOOP("USB", "Effects Knob Right"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_EFFECTSKNOB_RIGHT, GenericInputBinding::RightStickRight},
|
||||||
{"LeftTurntableCW", TRANSLATE_NOOP("USB", "Left Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CW, GenericInputBinding::LeftStickRight},
|
{"LeftTurntableCW", TRANSLATE_NOOP("USB", "Left Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CW, GenericInputBinding::LeftStickRight},
|
||||||
{"LeftTurntableCCW", TRANSLATE_NOOP("USB", "Left Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CCW, GenericInputBinding::LeftStickLeft},
|
{"LeftTurntableCCW", TRANSLATE_NOOP("USB", "Left Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CCW, GenericInputBinding::LeftStickLeft},
|
||||||
{"RightTurntableCW", TRANSLATE_NOOP("USB", "Right Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CW, GenericInputBinding::LeftStickDown},
|
{"RightTurntableCW", TRANSLATE_NOOP("USB", "Right Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CW, GenericInputBinding::LeftStickUp},
|
||||||
{"RightTurntableCCW", TRANSLATE_NOOP("USB", "Right Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CCW, GenericInputBinding::LeftStickUp},
|
{"RightTurntableCCW", TRANSLATE_NOOP("USB", "Right Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CCW, GenericInputBinding::LeftStickDown},
|
||||||
{"LeftTurntableGreen", TRANSLATE_NOOP("USB", "Left Turntable Green"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_GREEN, GenericInputBinding::Unknown},
|
{"LeftTurntableGreen", TRANSLATE_NOOP("USB", "Left Turntable Green"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_GREEN, GenericInputBinding::Unknown},
|
||||||
{"LeftTurntableRed", TRANSLATE_NOOP("USB", "Left Turntable Red"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_RED, GenericInputBinding::Unknown},
|
{"LeftTurntableRed", TRANSLATE_NOOP("USB", "Left Turntable Red"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_RED, GenericInputBinding::Unknown},
|
||||||
{"LeftTurntableBlue", TRANSLATE_NOOP("USB", "Left Turntable Blue"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_BLUE, GenericInputBinding::Unknown},
|
{"LeftTurntableBlue", TRANSLATE_NOOP("USB", "Left Turntable Blue"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_BLUE, GenericInputBinding::Unknown},
|
||||||
|
@ -464,8 +464,8 @@ namespace usb_pad
|
||||||
{
|
{
|
||||||
static constexpr const SettingInfo info[] = {
|
static constexpr const SettingInfo info[] = {
|
||||||
{SettingInfo::Type::Float, "TurntableMultiplier", TRANSLATE_NOOP("USB", "Turntable Multiplier"),
|
{SettingInfo::Type::Float, "TurntableMultiplier", TRANSLATE_NOOP("USB", "Turntable Multiplier"),
|
||||||
TRANSLATE_NOOP("USB", "Apply a multiplier to the turntable"),
|
TRANSLATE_NOOP("USB", "Apply a sensitivity multiplier to turntable rotation.\nXbox 360 turntables require a 256x multiplier, most other turntables can use the default 1x multiplier."),
|
||||||
"1.00", "0.00", "100.0", "1.0", "%.0fx", nullptr, nullptr, 1.0f}};
|
"1.00", "0.00", "512.0", "1.0", "%.0fx", nullptr, nullptr, 1.0f}};
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2779,6 +2779,8 @@ void VMManager::Internal::EntryPointCompilingOnCPUThread()
|
||||||
// Toss all the recs, we're going to be executing new code.
|
// Toss all the recs, we're going to be executing new code.
|
||||||
mmap_ResetBlockTracking();
|
mmap_ResetBlockTracking();
|
||||||
ClearCPUExecutionCaches();
|
ClearCPUExecutionCaches();
|
||||||
|
|
||||||
|
R5900SymbolImporter.OnElfLoadedInMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMManager::Internal::VSyncOnCPUThread()
|
void VMManager::Internal::VSyncOnCPUThread()
|
||||||
|
|
|
@ -1595,6 +1595,14 @@ static void iopRecRecompile(const u32 startpc)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
BASEBLOCK* pblock = PSX_GETBLOCK(i);
|
||||||
|
if (i != startpc && pblock->GetFnptr() != (uptr)iopJITCompile)
|
||||||
|
{
|
||||||
|
// branch = 3
|
||||||
|
willbranch3 = 1;
|
||||||
|
s_nEndBlock = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
psxRegs.code = iopMemRead32(i);
|
psxRegs.code = iopMemRead32(i);
|
||||||
|
|
||||||
|
|
|
@ -2294,6 +2294,8 @@ static void recRecompile(const u32 startpc)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
BASEBLOCK* pblock = PC_GETBLOCK(i);
|
||||||
|
|
||||||
// stop before breakpoints
|
// stop before breakpoints
|
||||||
if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0)
|
if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0)
|
||||||
{
|
{
|
||||||
|
@ -2311,6 +2313,13 @@ static void recRecompile(const u32 startpc)
|
||||||
eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4);
|
eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pblock->GetFnptr() != (uptr)JITCompile)
|
||||||
|
{
|
||||||
|
willbranch3 = 1;
|
||||||
|
s_nEndBlock = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
|
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
|
||||||
|
@ -2614,6 +2623,34 @@ StartRecomp:
|
||||||
pxAssert((pc - startpc) >> 2 <= 0xffff);
|
pxAssert((pc - startpc) >> 2 <= 0xffff);
|
||||||
s_pCurBlockEx->size = (pc - startpc) >> 2;
|
s_pCurBlockEx->size = (pc - startpc) >> 2;
|
||||||
|
|
||||||
|
if (HWADDR(pc) <= Ps2MemSize::ExposedRam)
|
||||||
|
{
|
||||||
|
BASEBLOCKEX* oldBlock;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = recBlocks.LastIndex(HWADDR(pc) - 4);
|
||||||
|
while ((oldBlock = recBlocks[i--]))
|
||||||
|
{
|
||||||
|
if (oldBlock == s_pCurBlockEx)
|
||||||
|
continue;
|
||||||
|
if (oldBlock->startpc >= HWADDR(pc))
|
||||||
|
continue;
|
||||||
|
if ((oldBlock->startpc + oldBlock->size * 4) <= HWADDR(startpc))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (memcmp(&recRAMCopy[oldBlock->startpc / 4], PSM(oldBlock->startpc),
|
||||||
|
oldBlock->size * 4))
|
||||||
|
{
|
||||||
|
recClear(startpc, (pc - startpc) / 4);
|
||||||
|
s_pCurBlockEx = recBlocks.Get(HWADDR(startpc));
|
||||||
|
pxAssert(s_pCurBlockEx->startpc == HWADDR(startpc));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&recRAMCopy[HWADDR(startpc) / 4], PSM(startpc), pc - startpc);
|
||||||
|
}
|
||||||
|
|
||||||
s_pCurBlock->SetFnptr((uptr)recPtr);
|
s_pCurBlock->SetFnptr((uptr)recPtr);
|
||||||
|
|
||||||
if (!(pc & 0x10000000))
|
if (!(pc & 0x10000000))
|
||||||
|
|
Loading…
Reference in New Issue