mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-10-05 03:37:20 -04:00
Feature/iop emulator (#244)
* refactor: from guest threads to EE scheduler * feat: bad wip mpeg fix for code veronica * feat: cheap copy from host feat: small perf o vsync tick * feat: added EE clock Hz fix: fix MPEG out of sync with new EE refactor * fix: fix lotr tests * fix: fix cri dtx loading fix: fix wrong mmi instruction translation fix: fix thread info params feat: added EE timers decoder and consumer feat: split SFI and IOP memory to prevent collision and overrides * feat: revert wrong changes * refactor: change GS architecture * feat: IOP emulator refactor: codegen to catch callbacks on mips code feat: added a lot of entries or IOP emulator * feat: analyzer resolve the complete constant-producing sequence with five-instruction backward scan stopped at LUI and therefore * feat: remove recompiled version of GetRomName refactor: split IOP emulator logic feat: added more HLE IOP modules feat: added ps2_path * eat: enhance ELF parser with improved callable entry detection and control flow analysis * feat: update memory hint handling and enhance entry point discovery logic * feat: add SET_GPR_ZE32 macro for zero-extending loads with unsigned semantics * refactor: Refactor PS2 IOP Host Adapter and Memory Management feat: Added PS2Vfs for virtual file system operations, including file opening, reading, writing, and path resolution. feat: Improve VIF1 data processing to handle GIF image packets more efficiently. * feat: added a lot of tests * fix: fix texture caching feat: wip multi version on dbcman * feat: remove LLE IOPs
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
#include "iop_module_manager.h"
|
||||
|
||||
#include "ps2x/iop/ps2_path.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ps2x::iop::detail
|
||||
{
|
||||
IopModuleManager::IopModuleManager()
|
||||
{
|
||||
// ROM modules that the no-BIOS HLE environment can legitimately provide.
|
||||
// Entries with RPC services become routable only after load.
|
||||
constexpr std::string_view modules[] = {
|
||||
"sysmem",
|
||||
"loadcore",
|
||||
"intrman",
|
||||
"sifman",
|
||||
"sifcmd",
|
||||
"sifinit",
|
||||
"ioman",
|
||||
"iomanx",
|
||||
"modload",
|
||||
"stdio",
|
||||
"sysclib",
|
||||
"thbase",
|
||||
"thevent",
|
||||
"thsemap",
|
||||
"thmsgbx",
|
||||
"timrman",
|
||||
"vblank",
|
||||
"secrman",
|
||||
"sio2man",
|
||||
"xsio2man",
|
||||
"sio2d",
|
||||
"padman",
|
||||
"xpadman",
|
||||
"mcman",
|
||||
"xmcman",
|
||||
"mcserv",
|
||||
"libsd",
|
||||
"cdvdman",
|
||||
"cdvdfsv",
|
||||
"dev9",
|
||||
"usbd",
|
||||
"usbhdfsd",
|
||||
"udnl",
|
||||
"fileio",
|
||||
"poweroff",
|
||||
"netman",
|
||||
"ps2ip",
|
||||
"dbcman",
|
||||
"dbcm",
|
||||
};
|
||||
for (const std::string_view module : modules)
|
||||
m_builtinKeys.emplace(module);
|
||||
}
|
||||
|
||||
void IopModuleManager::reset()
|
||||
{
|
||||
m_records.clear();
|
||||
m_hleIdsByKey.clear();
|
||||
m_loadedKeyReferences.clear();
|
||||
m_nextHleId = 0x40000000;
|
||||
}
|
||||
|
||||
void IopModuleManager::setServiceModuleKeys(std::vector<std::string> keys)
|
||||
{
|
||||
m_serviceKeys.clear();
|
||||
for (std::string &key : keys)
|
||||
{
|
||||
const std::string normalized = ps2PathLeafKey(key);
|
||||
if (!normalized.empty())
|
||||
m_serviceKeys.emplace(normalized);
|
||||
}
|
||||
}
|
||||
|
||||
ModuleLoadResult IopModuleManager::loadHle(std::string_view path)
|
||||
{
|
||||
ModuleLoadResult result{true, -1, -1};
|
||||
const std::string key = ps2PathLeafKey(path);
|
||||
if (key.empty() || (!m_builtinKeys.contains(key) && !m_serviceKeys.contains(key)))
|
||||
return result;
|
||||
|
||||
const auto existing = m_hleIdsByKey.find(key);
|
||||
if (existing != m_hleIdsByKey.end())
|
||||
{
|
||||
Record &record = m_records[existing->second];
|
||||
++record.references;
|
||||
addLoadedKey(key);
|
||||
result.moduleId = existing->second;
|
||||
result.startResult = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (m_nextHleId <= 0)
|
||||
return result;
|
||||
const int32_t id = m_nextHleId++;
|
||||
m_records.emplace(id, Record{key, 1u, false});
|
||||
m_hleIdsByKey.emplace(key, id);
|
||||
addLoadedKey(key);
|
||||
result.moduleId = id;
|
||||
result.startResult = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void IopModuleManager::observePhysicalLoad(int32_t moduleId, std::string_view path)
|
||||
{
|
||||
if (moduleId <= 0)
|
||||
return;
|
||||
const std::string key = ps2PathLeafKey(path);
|
||||
if (key.empty())
|
||||
return;
|
||||
m_records[moduleId] = Record{key, 1u, true};
|
||||
addLoadedKey(key);
|
||||
}
|
||||
|
||||
bool IopModuleManager::stopHle(int32_t moduleId, int32_t *result)
|
||||
{
|
||||
const auto found = m_records.find(moduleId);
|
||||
if (found == m_records.end() || found->second.physical)
|
||||
return false;
|
||||
|
||||
Record &record = found->second;
|
||||
removeLoadedKey(record.key);
|
||||
if (record.references > 1u)
|
||||
{
|
||||
--record.references;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hleIdsByKey.erase(record.key);
|
||||
m_records.erase(found);
|
||||
}
|
||||
if (result)
|
||||
*result = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void IopModuleManager::observePhysicalStop(int32_t moduleId)
|
||||
{
|
||||
const auto found = m_records.find(moduleId);
|
||||
if (found == m_records.end() || !found->second.physical)
|
||||
return;
|
||||
removeLoadedKey(found->second.key);
|
||||
m_records.erase(found);
|
||||
}
|
||||
|
||||
bool IopModuleManager::isLoaded(std::span<const std::string_view> aliases) const
|
||||
{
|
||||
if (aliases.empty())
|
||||
return true;
|
||||
return std::any_of(aliases.begin(), aliases.end(), [&](std::string_view alias)
|
||||
{
|
||||
const std::string key = ps2PathLeafKey(alias);
|
||||
const auto found = m_loadedKeyReferences.find(key);
|
||||
return found != m_loadedKeyReferences.end() && found->second != 0u; });
|
||||
}
|
||||
|
||||
bool IopModuleManager::recognizes(std::string_view path) const
|
||||
{
|
||||
const std::string key = ps2PathLeafKey(path);
|
||||
return m_builtinKeys.contains(key) || m_serviceKeys.contains(key);
|
||||
}
|
||||
|
||||
void IopModuleManager::addLoadedKey(std::string_view key)
|
||||
{
|
||||
++m_loadedKeyReferences[std::string(key)];
|
||||
}
|
||||
|
||||
void IopModuleManager::removeLoadedKey(std::string_view key)
|
||||
{
|
||||
const auto found = m_loadedKeyReferences.find(std::string(key));
|
||||
if (found == m_loadedKeyReferences.end())
|
||||
return;
|
||||
if (found->second > 1u)
|
||||
--found->second;
|
||||
else
|
||||
m_loadedKeyReferences.erase(found);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user