diff --git a/Utilities/AutoPause.cpp b/Utilities/AutoPause.cpp index fc2e26ad6d..5a604f0749 100644 --- a/Utilities/AutoPause.cpp +++ b/Utilities/AutoPause.cpp @@ -1,5 +1,8 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "AutoPause.h" +#include "Utilities/Log.h" +#include "Emu/System.h" using namespace Debug; diff --git a/Utilities/AutoPause.h b/Utilities/AutoPause.h index 208097a55d..cf871b46cb 100644 --- a/Utilities/AutoPause.h +++ b/Utilities/AutoPause.h @@ -1,7 +1,4 @@ #pragma once -#include "Utilities/Log.h" -#include "Utilities/rFile.h" -#include "Emu/System.h" //Regarded as a Debugger Enchantment namespace Debug { diff --git a/Utilities/BEType.h b/Utilities/BEType.h index 8c2880c71b..8322b804f8 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -1,17 +1,14 @@ #pragma once -#include "Utilities/GNU.h" - #include using std::min; using std::max; -//#define re(val) MemoryBase::Reverse(val) -#define re64(val) MemoryBase::Reverse64(val) -#define re32(val) MemoryBase::Reverse32(val) -#define re16(val) MemoryBase::Reverse16(val) -#define re128(val) MemoryBase::Reverse128(val) +#define re16(val) _byteswap_ushort(val) +#define re32(val) _byteswap_ulong(val) +#define re64(val) _byteswap_uint64(val) +#define re128(val) u128::byteswap(val) template struct se_t; template struct se_t { static __forceinline void func(T& dst, const T src) { (u8&)dst = (u8&)src; } }; diff --git a/Utilities/GNU.h b/Utilities/GNU.h index 89cb3a1cfa..58074f9835 100644 --- a/Utilities/GNU.h +++ b/Utilities/GNU.h @@ -7,9 +7,9 @@ #endif #ifdef _WIN32 -#define noinline __declspec(noinline) +#define __noinline __declspec(noinline) #else -#define noinline __attribute__((noinline)) +#define __noinline __attribute__((noinline)) #endif template diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index 4613e39e8a..4d0749426e 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "rPlatform.h" #include "Log.h" +#include "rMsgBox.h" #include #include #include diff --git a/Utilities/SMutex.cpp b/Utilities/SMutex.cpp index fe853c191e..efee7801f2 100644 --- a/Utilities/SMutex.cpp +++ b/Utilities/SMutex.cpp @@ -1,12 +1,15 @@ #include -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/CPU/CPUThread.h" #include "Utilities/SMutex.h" -__forceinline void SM_Sleep() +bool SM_IsAborted() +{ + return Emu.IsStopped(); +} + +void SM_Sleep() { if (NamedThreadBase* t = GetCurrentNamedThread()) { @@ -20,12 +23,12 @@ __forceinline void SM_Sleep() thread_local size_t g_this_thread_id = 0; -__forceinline size_t SM_GetCurrentThreadId() +size_t SM_GetCurrentThreadId() { return g_this_thread_id ? g_this_thread_id : g_this_thread_id = std::hash()(std::this_thread::get_id()); } -__forceinline u32 SM_GetCurrentCPUThreadId() +u32 SM_GetCurrentCPUThreadId() { if (CPUThread* t = GetCurrentCPUThread()) { @@ -34,7 +37,7 @@ __forceinline u32 SM_GetCurrentCPUThreadId() return 0; } -__forceinline be_t SM_GetCurrentCPUThreadIdBE() +be_t SM_GetCurrentCPUThreadIdBE() { return be_t::MakeFromLE(SM_GetCurrentCPUThreadId()); } diff --git a/Utilities/SMutex.h b/Utilities/SMutex.h index c67578d7b2..efd99b840f 100644 --- a/Utilities/SMutex.h +++ b/Utilities/SMutex.h @@ -1,11 +1,10 @@ #pragma once -#include "BEType.h" -#include "Emu/System.h" -extern void SM_Sleep(); -extern size_t SM_GetCurrentThreadId(); -extern u32 SM_GetCurrentCPUThreadId(); -extern be_t SM_GetCurrentCPUThreadIdBE(); +bool SM_IsAborted(); +void SM_Sleep(); +size_t SM_GetCurrentThreadId(); +u32 SM_GetCurrentCPUThreadId(); +be_t SM_GetCurrentCPUThreadIdBE(); enum SMutexResult { @@ -66,7 +65,7 @@ public: SMutexResult trylock(T tid) { - if (Emu.IsStopped()) + if (SM_IsAborted()) { return SMR_ABORT; } @@ -90,7 +89,7 @@ public: SMutexResult unlock(T tid, T to = GetFreeValue()) { - if (Emu.IsStopped()) + if (SM_IsAborted()) { return SMR_ABORT; } @@ -148,10 +147,9 @@ public: { if (!tid) { - if (!Emu.IsStopped()) + if (!SM_IsAborted()) { - LOG_ERROR(HLE, "SMutexLockerBase: thread id == 0"); - Emu.Pause(); + assert(!"SMutexLockerBase: thread id == 0"); } return; } diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index 9aa7e58356..83d7adc3dd 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -1,5 +1,7 @@ #pragma once +#include "Utilities/SMutex.h" + template class SQueue { diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index a98d8c6b63..5eedcc0fcd 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -12,6 +12,11 @@ NamedThreadBase* GetCurrentNamedThread() return g_tls_this_thread; } +void SetCurrentNamedThread(NamedThreadBase* value) +{ + g_tls_this_thread = value; +} + std::string NamedThreadBase::GetThreadName() const { return m_name; @@ -47,32 +52,27 @@ void ThreadBase::Start() m_destroy = false; m_alive = true; - m_executor = new std::thread( - [this]() + m_executor = new std::thread([this]() + { + SetCurrentNamedThread(this); + g_thread_count++; + + try { - g_tls_this_thread = this; - g_thread_count++; + Task(); + } + catch (const std::string& e) + { + LOG_ERROR(GENERAL, "Exception: %s", e.c_str()); + } + catch (const char* e) + { + LOG_ERROR(GENERAL, "Exception: %s", e); + } - try - { - Task(); - } - catch (const std::string& e) - { - LOG_ERROR(GENERAL, "Exception: %s", e.c_str()); - } - catch (const char* e) - { - LOG_ERROR(GENERAL, "Exception: %s", e); - } - catch (int exitcode) - { - LOG_SUCCESS(GENERAL, "Exit Code: %d", exitcode); - } - - m_alive = false; - g_thread_count--; - }); + m_alive = false; + g_thread_count--; + }); } void ThreadBase::Stop(bool wait, bool send_destroy) @@ -141,7 +141,7 @@ void thread::start(std::function func) m_thr = std::thread([func, name]() { NamedThreadBase info(name); - g_tls_this_thread = &info; + SetCurrentNamedThread(&info); g_thread_count++; try diff --git a/Utilities/Thread.h b/Utilities/Thread.h index f38ff73162..83401da110 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -5,7 +5,7 @@ #include #include #include -#include +//#include static std::thread::id main_thread; @@ -48,6 +48,7 @@ public: }; NamedThreadBase* GetCurrentNamedThread(); +void SetCurrentNamedThread(NamedThreadBase* value); class ThreadBase : public NamedThreadBase { diff --git a/Utilities/rFile.cpp b/Utilities/rFile.cpp index 83cad71cd0..6fcd4b4066 100644 --- a/Utilities/rFile.cpp +++ b/Utilities/rFile.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Log.h" #include #ifdef _WIN32 diff --git a/Utilities/rMsgBox.cpp b/Utilities/rMsgBox.cpp index 716464a156..cabb309e19 100644 --- a/Utilities/rMsgBox.cpp +++ b/Utilities/rMsgBox.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "rMsgBox.h" #ifndef QT_UI rMessageDialog::rMessageDialog(void *parent, const std::string& msg, const std::string& title , long style ) diff --git a/Utilities/rTime.cpp b/Utilities/rTime.cpp index 21aba77740..a550516501 100644 --- a/Utilities/rTime.cpp +++ b/Utilities/rTime.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "rTime.h" #include diff --git a/rpcs3/Crypto/key_vault.cpp b/rpcs3/Crypto/key_vault.cpp index 8565addb4d..90bd043a09 100644 --- a/rpcs3/Crypto/key_vault.cpp +++ b/rpcs3/Crypto/key_vault.cpp @@ -1,6 +1,20 @@ #include "stdafx.h" +#include "utils.h" +#include "aes.h" #include "key_vault.h" +SELF_KEY::SELF_KEY(u64 ver, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct) +{ + version = ver; + revision = rev; + self_type = type; + hex_to_bytes(erk, e.c_str()); + hex_to_bytes(riv, r.c_str()); + hex_to_bytes(pub, pb.c_str()); + hex_to_bytes(priv, pr.c_str()); + curve_type = ct; +} + KeyVault::KeyVault() { } diff --git a/rpcs3/Crypto/key_vault.h b/rpcs3/Crypto/key_vault.h index 3f78228e9e..d5fabaf829 100644 --- a/rpcs3/Crypto/key_vault.h +++ b/rpcs3/Crypto/key_vault.h @@ -1,5 +1,4 @@ #pragma once -#include "utils.h" enum SELF_KEY_TYPE { KEY_LV0 = 1, @@ -22,17 +21,7 @@ struct SELF_KEY { u8 priv[0x15]; u32 curve_type; - SELF_KEY(u64 ver, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct) - { - version = ver; - revision = rev; - self_type = type; - hex_to_bytes(erk, e.c_str()); - hex_to_bytes(riv, r.c_str()); - hex_to_bytes(pub, pb.c_str()); - hex_to_bytes(priv, pr.c_str()); - curve_type = ct; - } + SELF_KEY(u64 ver, u16 rev, u32 type, const std::string& e, const std::string& r, const std::string& pb, const std::string& pr, u32 ct); }; static u8 PKG_AES_KEY[0x10] = { diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index 94c997e745..9c4c96414e 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -1,4 +1,6 @@ #include "stdafx.h" +#include "utils.h" +#include "key_vault.h" #include "unedat.h" #include "Utilities/Log.h" diff --git a/rpcs3/Crypto/unedat.h b/rpcs3/Crypto/unedat.h index 990f8deca3..7efc8b3808 100644 --- a/rpcs3/Crypto/unedat.h +++ b/rpcs3/Crypto/unedat.h @@ -1,6 +1,4 @@ #pragma once -#include "utils.h" -#include "key_vault.h" #define SDAT_FLAG 0x01000000 #define EDAT_COMPRESSED_FLAG 0x00000001 diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index c08a3b5eab..f762f35804 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -1,4 +1,8 @@ #include "stdafx.h" +#include "utils.h" +#include "aes.h" +#include "sha1.h" +#include "key_vault.h" #include "unpkg.h" #include diff --git a/rpcs3/Crypto/unpkg.h b/rpcs3/Crypto/unpkg.h index 6a0e7bda28..886ffe3216 100644 --- a/rpcs3/Crypto/unpkg.h +++ b/rpcs3/Crypto/unpkg.h @@ -1,6 +1,4 @@ #pragma once -#include "utils.h" -#include "key_vault.h" // Constants #define PKG_HEADER_SIZE 0xC0 //sizeof(pkg_header) + sizeof(pkg_unk_checksum) diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index d03091dae1..10cc0200c7 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -1,8 +1,317 @@ #include "stdafx.h" #include "Utilities/Log.h" +#include "aes.h" +#include "sha1.h" +#include "utils.h" #include "Emu/FS/vfsLocalFile.h" #include "unself.h" +#include +#include + +void AppInfo::Load(vfsStream& f) +{ + authid = Read64(f); + vendor_id = Read32(f); + self_type = Read32(f); + version = Read64(f); + padding = Read64(f); +} + +void AppInfo::Show() +{ + LOG_NOTICE(LOADER, "AuthID: 0x%llx", authid); + LOG_NOTICE(LOADER, "VendorID: 0x%08x", vendor_id); + LOG_NOTICE(LOADER, "SELF type: 0x%08x", self_type); + LOG_NOTICE(LOADER, "Version: 0x%llx", version); +} + +void SectionInfo::Load(vfsStream& f) +{ + offset = Read64(f); + size = Read64(f); + compressed = Read32(f); + unknown1 = Read32(f); + unknown2 = Read32(f); + encrypted = Read32(f); +} + +void SectionInfo::Show() +{ + LOG_NOTICE(LOADER, "Offset: 0x%llx", offset); + LOG_NOTICE(LOADER, "Size: 0x%llx", size); + LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed); + LOG_NOTICE(LOADER, "Unknown1: 0x%08x", unknown1); + LOG_NOTICE(LOADER, "Unknown2: 0x%08x", unknown2); + LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted); +} + +void SCEVersionInfo::Load(vfsStream& f) +{ + subheader_type = Read32(f); + present = Read32(f); + size = Read32(f); + unknown = Read32(f); +} + +void SCEVersionInfo::Show() +{ + LOG_NOTICE(LOADER, "Sub-header type: 0x%08x", subheader_type); + LOG_NOTICE(LOADER, "Present: 0x%08x", present); + LOG_NOTICE(LOADER, "Size: 0x%08x", size); + LOG_NOTICE(LOADER, "Unknown: 0x%08x", unknown); +} + +void ControlInfo::Load(vfsStream& f) +{ + type = Read32(f); + size = Read32(f); + next = Read64(f); + + if (type == 1) + { + control_flags.ctrl_flag1 = Read32(f); + control_flags.unknown1 = Read32(f); + control_flags.unknown2 = Read32(f); + control_flags.unknown3 = Read32(f); + control_flags.unknown4 = Read32(f); + control_flags.unknown5 = Read32(f); + control_flags.unknown6 = Read32(f); + control_flags.unknown7 = Read32(f); + } + else if (type == 2) + { + if (size == 0x30) + { + f.Read(file_digest_30.digest, 20); + file_digest_30.unknown = Read64(f); + } + else if (size == 0x40) + { + f.Read(file_digest_40.digest1, 20); + f.Read(file_digest_40.digest2, 20); + file_digest_40.unknown = Read64(f); + } + } + else if (type == 3) + { + npdrm.magic = Read32(f); + npdrm.unknown1 = Read32(f); + npdrm.license = Read32(f); + npdrm.type = Read32(f); + f.Read(npdrm.content_id, 48); + f.Read(npdrm.digest, 16); + f.Read(npdrm.invdigest, 16); + f.Read(npdrm.xordigest, 16); + npdrm.unknown2 = Read64(f); + npdrm.unknown3 = Read64(f); + } +} + +void ControlInfo::Show() +{ + LOG_NOTICE(LOADER, "Type: 0x%08x", type); + LOG_NOTICE(LOADER, "Size: 0x%08x", size); + LOG_NOTICE(LOADER, "Next: 0x%llx", next); + + if (type == 1) + { + LOG_NOTICE(LOADER, "Control flag 1: 0x%08x", control_flags.ctrl_flag1); + LOG_NOTICE(LOADER, "Unknown1: 0x%08x", control_flags.unknown1); + LOG_NOTICE(LOADER, "Unknown2: 0x%08x", control_flags.unknown2); + LOG_NOTICE(LOADER, "Unknown3: 0x%08x", control_flags.unknown3); + LOG_NOTICE(LOADER, "Unknown4: 0x%08x", control_flags.unknown4); + LOG_NOTICE(LOADER, "Unknown5: 0x%08x", control_flags.unknown5); + LOG_NOTICE(LOADER, "Unknown6: 0x%08x", control_flags.unknown6); + LOG_NOTICE(LOADER, "Unknown7: 0x%08x", control_flags.unknown7); + } + else if (type == 2) + { + if (size == 0x30) + { + std::string digest_str; + for (int i = 0; i < 20; i++) + digest_str += fmt::Format("%02x", file_digest_30.digest[i]); + + LOG_NOTICE(LOADER, "Digest: %s", digest_str.c_str()); + LOG_NOTICE(LOADER, "Unknown: 0x%llx", file_digest_30.unknown); + } + else if (size == 0x40) + { + std::string digest_str1; + std::string digest_str2; + for (int i = 0; i < 20; i++) + { + digest_str1 += fmt::Format("%02x", file_digest_40.digest1[i]); + digest_str2 += fmt::Format("%02x", file_digest_40.digest2[i]); + } + + LOG_NOTICE(LOADER, "Digest1: %s", digest_str1.c_str()); + LOG_NOTICE(LOADER, "Digest2: %s", digest_str2.c_str()); + LOG_NOTICE(LOADER, "Unknown: 0x%llx", file_digest_40.unknown); + } + } + else if (type == 3) + { + std::string contentid_str; + std::string digest_str; + std::string invdigest_str; + std::string xordigest_str; + for (int i = 0; i < 48; i++) + contentid_str += fmt::Format("%02x", npdrm.content_id[i]); + for (int i = 0; i < 16; i++) + { + digest_str += fmt::Format("%02x", npdrm.digest[i]); + invdigest_str += fmt::Format("%02x", npdrm.invdigest[i]); + xordigest_str += fmt::Format("%02x", npdrm.xordigest[i]); + } + + LOG_NOTICE(LOADER, "Magic: 0x%08x", npdrm.magic); + LOG_NOTICE(LOADER, "Unknown1: 0x%08x", npdrm.unknown1); + LOG_NOTICE(LOADER, "License: 0x%08x", npdrm.license); + LOG_NOTICE(LOADER, "Type: 0x%08x", npdrm.type); + LOG_NOTICE(LOADER, "ContentID: %s", contentid_str.c_str()); + LOG_NOTICE(LOADER, "Digest: %s", digest_str.c_str()); + LOG_NOTICE(LOADER, "Inverse digest: %s", invdigest_str.c_str()); + LOG_NOTICE(LOADER, "XOR digest: %s", xordigest_str.c_str()); + LOG_NOTICE(LOADER, "Unknown2: 0x%llx", npdrm.unknown2); + LOG_NOTICE(LOADER, "Unknown3: 0x%llx", npdrm.unknown3); + } +} + +void MetadataInfo::Load(u8* in) +{ + memcpy(key, in, 0x10); + memcpy(key_pad, in + 0x10, 0x10); + memcpy(iv, in + 0x20, 0x10); + memcpy(iv_pad, in + 0x30, 0x10); +} + +void MetadataInfo::Show() +{ + std::string key_str; + std::string key_pad_str; + std::string iv_str; + std::string iv_pad_str; + for (int i = 0; i < 0x10; i++) + { + key_str += fmt::Format("%02x", key[i]); + key_pad_str += fmt::Format("%02x", key_pad[i]); + iv_str += fmt::Format("%02x", iv[i]); + iv_pad_str += fmt::Format("%02x", iv_pad[i]); + } + + LOG_NOTICE(LOADER, "Key: %s", key_str.c_str()); + LOG_NOTICE(LOADER, "Key pad: %s", key_pad_str.c_str()); + LOG_NOTICE(LOADER, "IV: %s", iv_str.c_str()); + LOG_NOTICE(LOADER, "IV pad: %s", iv_pad_str.c_str()); +} + +void MetadataHeader::Load(u8* in) +{ + memcpy(&signature_input_length, in, 8); + memcpy(&unknown1, in + 8, 4); + memcpy(§ion_count, in + 12, 4); + memcpy(&key_count, in + 16, 4); + memcpy(&opt_header_size, in + 20, 4); + memcpy(&unknown2, in + 24, 4); + memcpy(&unknown3, in + 28, 4); + + // Endian swap. + signature_input_length = swap64(signature_input_length); + unknown1 = swap32(unknown1); + section_count = swap32(section_count); + key_count = swap32(key_count); + opt_header_size = swap32(opt_header_size); + unknown2 = swap32(unknown2); + unknown3 = swap32(unknown3); +} + +void MetadataHeader::Show() +{ + LOG_NOTICE(LOADER, "Signature input length: 0x%llx", signature_input_length); + LOG_NOTICE(LOADER, "Unknown1: 0x%08x", unknown1); + LOG_NOTICE(LOADER, "Section count: 0x%08x", section_count); + LOG_NOTICE(LOADER, "Key count: 0x%08x", key_count); + LOG_NOTICE(LOADER, "Optional header size: 0x%08x", opt_header_size); + LOG_NOTICE(LOADER, "Unknown2: 0x%08x", unknown2); + LOG_NOTICE(LOADER, "Unknown3: 0x%08x", unknown3); +} + +void MetadataSectionHeader::Load(u8* in) +{ + memcpy(&data_offset, in, 8); + memcpy(&data_size, in + 8, 8); + memcpy(&type, in + 16, 4); + memcpy(&program_idx, in + 20, 4); + memcpy(&hashed, in + 24, 4); + memcpy(&sha1_idx, in + 28, 4); + memcpy(&encrypted, in + 32, 4); + memcpy(&key_idx, in + 36, 4); + memcpy(&iv_idx, in + 40, 4); + memcpy(&compressed, in + 44, 4); + + // Endian swap. + data_offset = swap64(data_offset); + data_size = swap64(data_size); + type = swap32(type); + program_idx = swap32(program_idx); + hashed = swap32(hashed); + sha1_idx = swap32(sha1_idx); + encrypted = swap32(encrypted); + key_idx = swap32(key_idx); + iv_idx = swap32(iv_idx); + compressed = swap32(compressed); +} + +void MetadataSectionHeader::Show() +{ + LOG_NOTICE(LOADER, "Data offset: 0x%llx", data_offset); + LOG_NOTICE(LOADER, "Data size: 0x%llx", data_size); + LOG_NOTICE(LOADER, "Type: 0x%08x", type); + LOG_NOTICE(LOADER, "Program index: 0x%08x", program_idx); + LOG_NOTICE(LOADER, "Hashed: 0x%08x", hashed); + LOG_NOTICE(LOADER, "SHA1 index: 0x%08x", sha1_idx); + LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted); + LOG_NOTICE(LOADER, "Key index: 0x%08x", key_idx); + LOG_NOTICE(LOADER, "IV index: 0x%08x", iv_idx); + LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed); +} + +void SectionHash::Load(vfsStream& f) +{ + f.Read(sha1, 20); + f.Read(padding, 12); + f.Read(hmac_key, 64); +} + +void CapabilitiesInfo::Load(vfsStream& f) +{ + type = Read32(f); + capabilities_size = Read32(f); + next = Read32(f); + unknown1 = Read32(f); + unknown2 = Read64(f); + unknown3 = Read64(f); + flags = Read64(f); + unknown4 = Read32(f); + unknown5 = Read32(f); +} + +void Signature::Load(vfsStream& f) +{ + f.Read(r, 21); + f.Read(s, 21); + f.Read(padding, 6); +} + +void SelfSection::Load(vfsStream& f) +{ + *data = Read32(f); + size = Read64(f); + offset = Read64(f); +} + SELFDecrypter::SELFDecrypter(vfsStream& s) : self_f(s), key_v(), data_buf_length(0) { diff --git a/rpcs3/Crypto/unself.h b/rpcs3/Crypto/unself.h index 860d71e826..947904e13a 100644 --- a/rpcs3/Crypto/unself.h +++ b/rpcs3/Crypto/unself.h @@ -1,10 +1,8 @@ #pragma once -#include "utils.h" -#include "key_vault.h" -#include "Loader/ELF.h" + #include "Loader/SELF.h" -#include -#include +#include "Loader/ELF.h" +#include "key_vault.h" struct AppInfo { @@ -14,22 +12,9 @@ struct AppInfo u64 version; u64 padding; - void Load(vfsStream& f) - { - authid = Read64(f); - vendor_id = Read32(f); - self_type = Read32(f); - version = Read64(f); - padding = Read64(f); - } + void Load(vfsStream& f); - void Show() - { - LOG_NOTICE(LOADER, "AuthID: 0x%llx", authid); - LOG_NOTICE(LOADER, "VendorID: 0x%08x", vendor_id); - LOG_NOTICE(LOADER, "SELF type: 0x%08x", self_type); - LOG_NOTICE(LOADER, "Version: 0x%llx", version); - } + void Show(); }; struct SectionInfo @@ -41,25 +26,9 @@ struct SectionInfo u32 unknown2; u32 encrypted; - void Load(vfsStream& f) - { - offset = Read64(f); - size = Read64(f); - compressed = Read32(f); - unknown1 = Read32(f); - unknown2 = Read32(f); - encrypted = Read32(f); - } + void Load(vfsStream& f); - void Show() - { - LOG_NOTICE(LOADER, "Offset: 0x%llx", offset); - LOG_NOTICE(LOADER, "Size: 0x%llx", size); - LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed); - LOG_NOTICE(LOADER, "Unknown1: 0x%08x", unknown1); - LOG_NOTICE(LOADER, "Unknown2: 0x%08x", unknown2); - LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted); - } + void Show(); }; struct SCEVersionInfo @@ -69,21 +38,9 @@ struct SCEVersionInfo u32 size; u32 unknown; - void Load(vfsStream& f) - { - subheader_type = Read32(f); - present = Read32(f); - size = Read32(f); - unknown = Read32(f); - } + void Load(vfsStream& f); - void Show() - { - LOG_NOTICE(LOADER, "Sub-header type: 0x%08x", subheader_type); - LOG_NOTICE(LOADER, "Present: 0x%08x", present); - LOG_NOTICE(LOADER, "Size: 0x%08x", size); - LOG_NOTICE(LOADER, "Unknown: 0x%08x", unknown); - } + void Show(); }; struct ControlInfo @@ -133,122 +90,9 @@ struct ControlInfo } npdrm; }; - void Load(vfsStream& f) - { - type = Read32(f); - size = Read32(f); - next = Read64(f); + void Load(vfsStream& f); - if (type == 1) - { - control_flags.ctrl_flag1 = Read32(f); - control_flags.unknown1 = Read32(f); - control_flags.unknown2 = Read32(f); - control_flags.unknown3 = Read32(f); - control_flags.unknown4 = Read32(f); - control_flags.unknown5 = Read32(f); - control_flags.unknown6 = Read32(f); - control_flags.unknown7 = Read32(f); - } - else if (type == 2) - { - if (size == 0x30) - { - f.Read(file_digest_30.digest, 20); - file_digest_30.unknown = Read64(f); - } - else if (size == 0x40) - { - f.Read(file_digest_40.digest1, 20); - f.Read(file_digest_40.digest2, 20); - file_digest_40.unknown = Read64(f); - } - } - else if (type == 3) - { - npdrm.magic = Read32(f); - npdrm.unknown1 = Read32(f); - npdrm.license = Read32(f); - npdrm.type = Read32(f); - f.Read(npdrm.content_id, 48); - f.Read(npdrm.digest, 16); - f.Read(npdrm.invdigest, 16); - f.Read(npdrm.xordigest, 16); - npdrm.unknown2 = Read64(f); - npdrm.unknown3 = Read64(f); - } - } - - void Show() - { - LOG_NOTICE(LOADER, "Type: 0x%08x", type); - LOG_NOTICE(LOADER, "Size: 0x%08x", size); - LOG_NOTICE(LOADER, "Next: 0x%llx", next); - - if (type == 1) - { - LOG_NOTICE(LOADER, "Control flag 1: 0x%08x", control_flags.ctrl_flag1); - LOG_NOTICE(LOADER, "Unknown1: 0x%08x", control_flags.unknown1); - LOG_NOTICE(LOADER, "Unknown2: 0x%08x", control_flags.unknown2); - LOG_NOTICE(LOADER, "Unknown3: 0x%08x", control_flags.unknown3); - LOG_NOTICE(LOADER, "Unknown4: 0x%08x", control_flags.unknown4); - LOG_NOTICE(LOADER, "Unknown5: 0x%08x", control_flags.unknown5); - LOG_NOTICE(LOADER, "Unknown6: 0x%08x", control_flags.unknown6); - LOG_NOTICE(LOADER, "Unknown7: 0x%08x", control_flags.unknown7); - } - else if (type == 2) - { - if (size == 0x30) - { - std::string digest_str; - for (int i = 0; i < 20; i++) - digest_str += fmt::Format("%02x", file_digest_30.digest[i]); - - LOG_NOTICE(LOADER, "Digest: %s", digest_str.c_str()); - LOG_NOTICE(LOADER, "Unknown: 0x%llx", file_digest_30.unknown); - } - else if (size == 0x40) - { - std::string digest_str1; - std::string digest_str2; - for (int i = 0; i < 20; i++) - { - digest_str1 += fmt::Format("%02x", file_digest_40.digest1[i]); - digest_str2 += fmt::Format("%02x", file_digest_40.digest2[i]); - } - - LOG_NOTICE(LOADER, "Digest1: %s", digest_str1.c_str()); - LOG_NOTICE(LOADER, "Digest2: %s", digest_str2.c_str()); - LOG_NOTICE(LOADER, "Unknown: 0x%llx", file_digest_40.unknown); - } - } - else if (type == 3) - { - std::string contentid_str; - std::string digest_str; - std::string invdigest_str; - std::string xordigest_str; - for (int i = 0; i < 48; i++) - contentid_str += fmt::Format("%02x", npdrm.content_id[i]); - for (int i = 0; i < 16; i++) - { - digest_str += fmt::Format("%02x", npdrm.digest[i]); - invdigest_str += fmt::Format("%02x", npdrm.invdigest[i]); - xordigest_str += fmt::Format("%02x", npdrm.xordigest[i]); - } - - LOG_NOTICE(LOADER, "Magic: 0x%08x", npdrm.magic); - LOG_NOTICE(LOADER, "Unknown1: 0x%08x", npdrm.unknown1); - LOG_NOTICE(LOADER, "License: 0x%08x", npdrm.license); - LOG_NOTICE(LOADER, "Type: 0x%08x", npdrm.type); - LOG_NOTICE(LOADER, "ContentID: %s", contentid_str.c_str()); - LOG_NOTICE(LOADER, "Digest: %s", digest_str.c_str()); - LOG_NOTICE(LOADER, "Inverse digest: %s", invdigest_str.c_str()); - LOG_NOTICE(LOADER, "XOR digest: %s", xordigest_str.c_str()); - LOG_NOTICE(LOADER, "Unknown2: 0x%llx", npdrm.unknown2); - LOG_NOTICE(LOADER, "Unknown3: 0x%llx", npdrm.unknown3); - } - } + void Show(); }; @@ -259,33 +103,9 @@ struct MetadataInfo u8 iv[0x10]; u8 iv_pad[0x10]; - void Load(u8* in) - { - memcpy(key, in, 0x10); - memcpy(key_pad, in + 0x10, 0x10); - memcpy(iv, in + 0x20, 0x10); - memcpy(iv_pad, in + 0x30, 0x10); - } + void Load(u8* in); - void Show() - { - std::string key_str; - std::string key_pad_str; - std::string iv_str; - std::string iv_pad_str; - for (int i = 0; i < 0x10; i++) - { - key_str += fmt::Format("%02x", key[i]); - key_pad_str += fmt::Format("%02x", key_pad[i]); - iv_str += fmt::Format("%02x", iv[i]); - iv_pad_str += fmt::Format("%02x", iv_pad[i]); - } - - LOG_NOTICE(LOADER, "Key: %s", key_str.c_str()); - LOG_NOTICE(LOADER, "Key pad: %s", key_pad_str.c_str()); - LOG_NOTICE(LOADER, "IV: %s", iv_str.c_str()); - LOG_NOTICE(LOADER, "IV pad: %s", iv_pad_str.c_str()); - } + void Show(); }; struct MetadataHeader @@ -298,36 +118,9 @@ struct MetadataHeader u32 unknown2; u32 unknown3; - void Load(u8* in) - { - memcpy(&signature_input_length, in, 8); - memcpy(&unknown1, in + 8, 4); - memcpy(§ion_count, in + 12, 4); - memcpy(&key_count, in + 16, 4); - memcpy(&opt_header_size, in + 20, 4); - memcpy(&unknown2, in + 24, 4); - memcpy(&unknown3, in + 28, 4); + void Load(u8* in); - // Endian swap. - signature_input_length = swap64(signature_input_length); - unknown1 = swap32(unknown1); - section_count = swap32(section_count); - key_count = swap32(key_count); - opt_header_size = swap32(opt_header_size); - unknown2 = swap32(unknown2); - unknown3 = swap32(unknown3); - } - - void Show() - { - LOG_NOTICE(LOADER, "Signature input length: 0x%llx", signature_input_length); - LOG_NOTICE(LOADER, "Unknown1: 0x%08x", unknown1); - LOG_NOTICE(LOADER, "Section count: 0x%08x", section_count); - LOG_NOTICE(LOADER, "Key count: 0x%08x", key_count); - LOG_NOTICE(LOADER, "Optional header size: 0x%08x", opt_header_size); - LOG_NOTICE(LOADER, "Unknown2: 0x%08x", unknown2); - LOG_NOTICE(LOADER, "Unknown3: 0x%08x", unknown3); - } + void Show(); }; struct MetadataSectionHeader @@ -343,45 +136,9 @@ struct MetadataSectionHeader u32 iv_idx; u32 compressed; - void Load(u8* in) - { - memcpy(&data_offset, in, 8); - memcpy(&data_size, in + 8, 8); - memcpy(&type, in + 16, 4); - memcpy(&program_idx, in + 20, 4); - memcpy(&hashed, in + 24, 4); - memcpy(&sha1_idx, in + 28, 4); - memcpy(&encrypted, in + 32, 4); - memcpy(&key_idx, in + 36, 4); - memcpy(&iv_idx, in + 40, 4); - memcpy(&compressed, in + 44, 4); + void Load(u8* in); - // Endian swap. - data_offset = swap64(data_offset); - data_size = swap64(data_size); - type = swap32(type); - program_idx = swap32(program_idx); - hashed = swap32(hashed); - sha1_idx = swap32(sha1_idx); - encrypted = swap32(encrypted); - key_idx = swap32(key_idx); - iv_idx = swap32(iv_idx); - compressed = swap32(compressed); - } - - void Show() - { - LOG_NOTICE(LOADER, "Data offset: 0x%llx", data_offset); - LOG_NOTICE(LOADER, "Data size: 0x%llx", data_size); - LOG_NOTICE(LOADER, "Type: 0x%08x", type); - LOG_NOTICE(LOADER, "Program index: 0x%08x", program_idx); - LOG_NOTICE(LOADER, "Hashed: 0x%08x", hashed); - LOG_NOTICE(LOADER, "SHA1 index: 0x%08x", sha1_idx); - LOG_NOTICE(LOADER, "Encrypted: 0x%08x", encrypted); - LOG_NOTICE(LOADER, "Key index: 0x%08x", key_idx); - LOG_NOTICE(LOADER, "IV index: 0x%08x", iv_idx); - LOG_NOTICE(LOADER, "Compressed: 0x%08x", compressed); - } + void Show(); }; struct SectionHash { @@ -389,12 +146,7 @@ struct SectionHash { u8 padding[12]; u8 hmac_key[64]; - void Load(vfsStream& f) - { - f.Read(sha1, 20); - f.Read(padding, 12); - f.Read(hmac_key, 64); - } + void Load(vfsStream& f); }; struct CapabilitiesInfo @@ -409,18 +161,7 @@ struct CapabilitiesInfo u32 unknown4; u32 unknown5; - void Load(vfsStream& f) - { - type = Read32(f); - capabilities_size = Read32(f); - next = Read32(f); - unknown1 = Read32(f); - unknown2 = Read64(f); - unknown3 = Read64(f); - flags = Read64(f); - unknown4 = Read32(f); - unknown5 = Read32(f); - } + void Load(vfsStream& f); }; struct Signature @@ -429,12 +170,7 @@ struct Signature u8 s[21]; u8 padding[6]; - void Load(vfsStream& f) - { - f.Read(r, 21); - f.Read(s, 21); - f.Read(padding, 6); - } + void Load(vfsStream& f); }; struct SelfSection @@ -443,12 +179,7 @@ struct SelfSection u64 size; u64 offset; - void Load(vfsStream& f) - { - *data = Read32(f); - size = Read64(f); - offset = Read64(f); - } + void Load(vfsStream& f); }; class SELFDecrypter diff --git a/rpcs3/Crypto/utils.cpp b/rpcs3/Crypto/utils.cpp index a17013cda9..b395643f20 100644 --- a/rpcs3/Crypto/utils.cpp +++ b/rpcs3/Crypto/utils.cpp @@ -1,4 +1,6 @@ #include "stdafx.h" +#include "aes.h" +#include "sha1.h" #include "utils.h" // Endian swap auxiliary functions. diff --git a/rpcs3/Crypto/utils.h b/rpcs3/Crypto/utils.h index 17ec4e8f5a..4ae1466607 100644 --- a/rpcs3/Crypto/utils.h +++ b/rpcs3/Crypto/utils.h @@ -1,6 +1,4 @@ #pragma once -#include "aes.h" -#include "sha1.h" // Auxiliary functions (endian swap and xor). u16 swap16(u16 i); diff --git a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h index 03f99be552..ba59fc0a26 100644 --- a/rpcs3/Emu/ARMv7/ARMv7DisAsm.h +++ b/rpcs3/Emu/ARMv7/ARMv7DisAsm.h @@ -1,7 +1,6 @@ #pragma once #include "Emu/ARMv7/ARMv7Opcodes.h" #include "Emu/CPU/CPUDisAsm.h" -#include "Emu/Memory/Memory.h" static const char* g_arm_cond_name[16] = { diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index d4cdddc2c9..118857dc5e 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPCThread.h" #include "ARMv7Thread.h" #include "ARMv7Decoder.h" diff --git a/rpcs3/Emu/CPU/CPUDisAsm.h b/rpcs3/Emu/CPU/CPUDisAsm.h index f15a1c6258..4a7eca77c0 100644 --- a/rpcs3/Emu/CPU/CPUDisAsm.h +++ b/rpcs3/Emu/CPU/CPUDisAsm.h @@ -1,7 +1,5 @@ #pragma once -#include "Emu/Memory/Memory.h" - enum CPUDisAsmMode { CPUDisAsm_DumpMode, @@ -21,18 +19,18 @@ protected: { case CPUDisAsm_DumpMode: last_opcode = fmt::Format("\t%08llx:\t%02x %02x %02x %02x\t%s\n", dump_pc, - Memory.Read8(offset + dump_pc), - Memory.Read8(offset + dump_pc + 1), - Memory.Read8(offset + dump_pc + 2), - Memory.Read8(offset + dump_pc + 3), value.c_str()); + offset[dump_pc], + offset[dump_pc + 1], + offset[dump_pc + 2], + offset[dump_pc + 3], value.c_str()); break; case CPUDisAsm_InterpreterMode: last_opcode = fmt::Format("[%08llx] %02x %02x %02x %02x: %s", dump_pc, - Memory.Read8(offset + dump_pc), - Memory.Read8(offset + dump_pc + 1), - Memory.Read8(offset + dump_pc + 2), - Memory.Read8(offset + dump_pc + 3), value.c_str()); + offset[dump_pc], + offset[dump_pc + 1], + offset[dump_pc + 2], + offset[dump_pc + 3], value.c_str()); break; case CPUDisAsm_CompilerElfMode: @@ -44,7 +42,7 @@ protected: public: std::string last_opcode; u64 dump_pc; - u64 offset; + u8* offset; protected: CPUDisAsm(CPUDisAsmMode mode) diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 1f318b8abc..6cc990b777 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -1,16 +1,14 @@ #include "stdafx.h" -#include "Emu/SysCalls/ErrorCodes.h" +#include "rpcs3/Ini.h" #include "Emu/SysCalls/SysCalls.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/DbgCommand.h" -#include "rpcs3/Ini.h" +#include "CPUDecoder.h" #include "CPUThread.h" -reservation_struct reservation; - CPUThread* GetCurrentCPUThread() { return (CPUThread*)GetCurrentNamedThread(); @@ -38,6 +36,10 @@ CPUThread::~CPUThread() safe_delete(m_dec); } +bool CPUThread::IsRunning() const { return m_status == Running; } +bool CPUThread::IsPaused() const { return m_status == Paused; } +bool CPUThread::IsStopped() const { return m_status == Stopped; } + void CPUThread::Close() { ThreadBase::Stop(m_sync_wait); diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 2ecd40ad4a..e827ca77f2 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -1,30 +1,4 @@ #pragma once -#include "Emu/Memory/MemoryBlock.h" -#include "Emu/CPU/CPUDecoder.h" -#include "Utilities/SMutex.h" - -typedef SMutexBase SMutexR; -typedef SMutexLockerBase SMutexLockerR; - -struct reservation_struct -{ - SMutexR mutex; // mutex for updating reservation_owner and data - // std::mutex doesn't work because it probably wakes up waiting threads in the most unwanted order - // and doesn't give a chance to finish some work before losing the reservation - u32 owner; // id of thread that got reservation - u64 addr; - u32 size; - u32 data32; - u64 data64; - u128 data[8]; - - __forceinline void clear() - { - owner = 0; - } -}; - -extern reservation_struct reservation; enum CPUThreadType :unsigned char { @@ -45,6 +19,8 @@ enum CPUThreadStatus CPUThread_Step, }; +class CPUDecoder; + class CPUThread : public ThreadBase { protected: @@ -170,13 +146,13 @@ public: static std::vector ErrorToString(const u32 error); std::vector ErrorToString() { return ErrorToString(m_error); } - bool IsOk() const { return m_error == 0; } - bool IsRunning() const { return m_status == Running; } - bool IsPaused() const { return m_status == Paused; } - bool IsStopped() const { return m_status == Stopped; } + bool IsOk() const { return m_error == 0; } + bool IsRunning() const; + bool IsPaused() const; + bool IsStopped() const; bool IsJoinable() const { return m_joinable; } - bool IsJoining() const { return m_joining; } + bool IsJoining() const { return m_joining; } void SetJoinable(bool joinable) { m_joinable = joinable; } void SetJoining(bool joining) { m_joining = joining; } diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index d162bc493b..7d8c5c6072 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/DbgCommand.h" diff --git a/rpcs3/Emu/Cell/MFC.h b/rpcs3/Emu/Cell/MFC.h index 9f93ce6104..7bd4281f7c 100644 --- a/rpcs3/Emu/Cell/MFC.h +++ b/rpcs3/Emu/Cell/MFC.h @@ -1,5 +1,4 @@ #pragma once -#include enum { diff --git a/rpcs3/Emu/Cell/PPCDecoder.cpp b/rpcs3/Emu/Cell/PPCDecoder.cpp index 3b60ece5a2..a5df4c7f8c 100644 --- a/rpcs3/Emu/Cell/PPCDecoder.cpp +++ b/rpcs3/Emu/Cell/PPCDecoder.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "PPCDecoder.h" diff --git a/rpcs3/Emu/Cell/PPCDisAsm.h b/rpcs3/Emu/Cell/PPCDisAsm.h index 39541d28ca..2666033919 100644 --- a/rpcs3/Emu/Cell/PPCDisAsm.h +++ b/rpcs3/Emu/Cell/PPCDisAsm.h @@ -1,7 +1,6 @@ #pragma once #include "Emu/CPU/CPUDisAsm.h" -#include "Emu/Memory/Memory.h" class PPCDisAsm : public CPUDisAsm { diff --git a/rpcs3/Emu/Cell/PPCThread.cpp b/rpcs3/Emu/Cell/PPCThread.cpp index c8f5411432..96d9b732a2 100644 --- a/rpcs3/Emu/Cell/PPCThread.cpp +++ b/rpcs3/Emu/Cell/PPCThread.cpp @@ -1,8 +1,6 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "PPCThread.h" +#include "Emu/Memory/Memory.h" PPCThread* GetCurrentPPCThread() { diff --git a/rpcs3/Emu/Cell/PPCThread.h b/rpcs3/Emu/Cell/PPCThread.h index e7bc4ddbe1..e0fbd5888c 100644 --- a/rpcs3/Emu/Cell/PPCThread.h +++ b/rpcs3/Emu/Cell/PPCThread.h @@ -1,7 +1,5 @@ #pragma once -#include "Emu/Memory/MemoryBlock.h" #include "Emu/CPU/CPUThread.h" -#include "Emu/Cell/PPCDecoder.h" class PPCThread : public CPUThread { diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 5fafd6b474..34e51f7fb2 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -1,9 +1,6 @@ #pragma once -#include "Emu/Cell/PPUOpcodes.h" #include "Emu/Cell/PPCDisAsm.h" -#include "Emu/Cell/PPCThread.h" -#include "Emu/Memory/Memory.h" class PPUDisAsm : public PPUOpcodes diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 3f27b769ca..89524cfd27 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -1,9 +1,7 @@ #pragma once #include "Emu/Cell/PPUOpcodes.h" -#include "Emu/Memory/Memory.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SysCalls.h" + #include #ifdef _MSC_VER #include @@ -2104,6 +2102,7 @@ private: Emu.GetSFuncManager()[CPU.GPR[11]]->name, CPU.GPR[3], CPU.PC); } break; + case 0x4: CPU.FastStop(); break; case 0x22: UNK("HyperCall LV1"); break; default: UNK(fmt::Format("Unknown sc: %x", sc_code)); } @@ -2368,13 +2367,9 @@ private: } void LWARX(u32 rd, u32 ra, u32 rb) { - const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - - SMutexLockerR lock(reservation.mutex); - reservation.owner = lock.tid; - reservation.addr = addr; - reservation.size = 4; - reservation.data32 = CPU.GPR[rd] = Memory.Read32(addr); + CPU.R_ADDR = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; + CPU.R_VALUE = (u32&)Memory[CPU.R_ADDR]; + CPU.GPR[rd] = re32((u32)CPU.R_VALUE); } void LDX(u32 rd, u32 ra, u32 rb) { @@ -2523,13 +2518,9 @@ private: } void LDARX(u32 rd, u32 ra, u32 rb) { - const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - - SMutexLockerR lock(reservation.mutex); - reservation.owner = lock.tid; - reservation.addr = addr; - reservation.size = 8; - reservation.data64 = CPU.GPR[rd] = Memory.Read64(addr); + CPU.R_ADDR = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; + CPU.R_VALUE = (u64&)Memory[CPU.R_ADDR]; + CPU.GPR[rd] = re64(CPU.R_VALUE); } void DCBF(u32 ra, u32 rb) { @@ -2644,17 +2635,13 @@ private: { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - SMutexLockerR lock(reservation.mutex); - if (lock.tid == reservation.owner && reservation.addr == addr && reservation.size == 4) + if (CPU.R_ADDR == addr) { - // Memory.Write32(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile long*) (Memory + addr), re((u32) CPU.GPR[rs]), re(reservation.data32)) == re(reservation.data32)); - reservation.clear(); + CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile u32*)(Memory + addr), re32((u32)CPU.GPR[rs]), (u32)CPU.R_VALUE) == (u32)CPU.R_VALUE); } else { CPU.SetCR_EQ(0, false); - if (lock.tid == reservation.owner) reservation.clear(); } } void STWX(u32 rs, u32 ra, u32 rb) @@ -2705,17 +2692,13 @@ private: { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - SMutexLockerR lock(reservation.mutex); - if (lock.tid == reservation.owner && reservation.addr == addr && reservation.size == 8) + if (CPU.R_ADDR == addr) { - // Memory.Write64(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, InterlockedCompareExchange64((volatile long long*)(Memory + addr), re(CPU.GPR[rs]), re(reservation.data64)) == re(reservation.data64)); - reservation.clear(); + CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile u64*)(Memory + addr), re64(CPU.GPR[rs]), CPU.R_VALUE) == CPU.R_VALUE); } else { CPU.SetCR_EQ(0, false); - if (lock.tid == reservation.owner) reservation.clear(); } } void STBX(u32 rs, u32 ra, u32 rb) diff --git a/rpcs3/Emu/Cell/PPUProgramCompiler.cpp b/rpcs3/Emu/Cell/PPUProgramCompiler.cpp index 6c239fe1cc..5e64958d0b 100644 --- a/rpcs3/Emu/Cell/PPUProgramCompiler.cpp +++ b/rpcs3/Emu/Cell/PPUProgramCompiler.cpp @@ -1,7 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" - #include "PPUProgramCompiler.h" using namespace PPU_instr; @@ -83,7 +80,7 @@ SectionInfo::SectionInfo(const std::string& _name) void SectionInfo::SetDataSize(u32 size, u32 align) { if(align) shdr.sh_addralign = align; - if(shdr.sh_addralign) size = Memory.AlignAddr(size, shdr.sh_addralign); + if(shdr.sh_addralign) size = AlignAddr(size, shdr.sh_addralign); if(!code.empty()) { @@ -987,7 +984,7 @@ void CompilePPUProgram::Compile() elf_info.e_shnum = 15; elf_info.e_shstrndx = elf_info.e_shnum - 1; elf_info.e_phoff = elf_info.e_ehsize; - u32 section_offset = Memory.AlignAddr(elf_info.e_phoff + elf_info.e_phnum * elf_info.e_phentsize, 0x100); + u32 section_offset = AlignAddr(elf_info.e_phoff + elf_info.e_phnum * elf_info.e_phentsize, 0x100); static const u32 sceStub_text_block = 8 * 4; @@ -1145,7 +1142,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_sceStub_text; memset(&s_sceStub_text, 0, sizeof(Elf64_Shdr)); s_sceStub_text.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_sceStub_text.sh_addralign); + section_offset = AlignAddr(section_offset, s_sceStub_text.sh_addralign); s_sceStub_text.sh_type = 1; s_sceStub_text.sh_offset = section_offset; s_sceStub_text.sh_addr = section_offset + 0x10000; @@ -1169,7 +1166,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_lib_stub_top; memset(&s_lib_stub_top, 0, sizeof(Elf64_Shdr)); s_lib_stub_top.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_lib_stub_top.sh_addralign); + section_offset = AlignAddr(section_offset, s_lib_stub_top.sh_addralign); s_lib_stub_top.sh_type = 1; s_lib_stub_top.sh_name = section_name_offset; s_lib_stub_top.sh_offset = section_offset; @@ -1209,7 +1206,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_rodata_sceFNID; memset(&s_rodata_sceFNID, 0, sizeof(Elf64_Shdr)); s_rodata_sceFNID.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_rodata_sceFNID.sh_addralign); + section_offset = AlignAddr(section_offset, s_rodata_sceFNID.sh_addralign); s_rodata_sceFNID.sh_type = 1; s_rodata_sceFNID.sh_name = section_name_offset; s_rodata_sceFNID.sh_offset = section_offset; @@ -1223,7 +1220,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_rodata_sceResident; memset(&s_rodata_sceResident, 0, sizeof(Elf64_Shdr)); s_rodata_sceResident.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_rodata_sceResident.sh_addralign); + section_offset = AlignAddr(section_offset, s_rodata_sceResident.sh_addralign); s_rodata_sceResident.sh_type = 1; s_rodata_sceResident.sh_name = section_name_offset; s_rodata_sceResident.sh_offset = section_offset; @@ -1234,7 +1231,7 @@ void CompilePPUProgram::Compile() { s_rodata_sceResident.sh_size += module.m_name.length() + 1; } - s_rodata_sceResident.sh_size = Memory.AlignAddr(s_rodata_sceResident.sh_size, s_rodata_sceResident.sh_addralign); + s_rodata_sceResident.sh_size = AlignAddr(s_rodata_sceResident.sh_size, s_rodata_sceResident.sh_addralign); sections_names.push_back(".rodata.sceResident"); section_name_offset += std::string(".rodata.sceResident").length() + 1; section_offset += s_rodata_sceResident.sh_size; @@ -1242,7 +1239,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_lib_ent_top; memset(&s_lib_ent_top, 0, sizeof(Elf64_Shdr)); s_lib_ent_top.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_lib_ent_top.sh_addralign); + section_offset = AlignAddr(section_offset, s_lib_ent_top.sh_addralign); s_lib_ent_top.sh_size = 4; s_lib_ent_top.sh_flags = 2; s_lib_ent_top.sh_type = 1; @@ -1269,7 +1266,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_sys_proc_prx_param; memset(&s_sys_proc_prx_param, 0, sizeof(Elf64_Shdr)); s_sys_proc_prx_param.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_sys_proc_prx_param.sh_addralign); + section_offset = AlignAddr(section_offset, s_sys_proc_prx_param.sh_addralign); s_sys_proc_prx_param.sh_type = 1; s_sys_proc_prx_param.sh_size = sizeof(sys_proc_prx_param); s_sys_proc_prx_param.sh_name = section_name_offset; @@ -1282,14 +1279,14 @@ void CompilePPUProgram::Compile() const u32 prog_load_0_end = section_offset; - section_offset = Memory.AlignAddr(section_offset + 0x10000, 0x10000); + section_offset = AlignAddr(section_offset + 0x10000, 0x10000); const u32 prog_load_1_start = section_offset; Elf64_Shdr s_data_sceFStub; memset(&s_data_sceFStub, 0, sizeof(Elf64_Shdr)); s_data_sceFStub.sh_name = section_name_offset; s_data_sceFStub.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_data_sceFStub.sh_addralign); + section_offset = AlignAddr(section_offset, s_data_sceFStub.sh_addralign); s_data_sceFStub.sh_flags = 3; s_data_sceFStub.sh_type = 1; s_data_sceFStub.sh_offset = section_offset; @@ -1302,7 +1299,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_tbss; memset(&s_tbss, 0, sizeof(Elf64_Shdr)); s_tbss.sh_addralign = 4; - section_offset = Memory.AlignAddr(section_offset, s_tbss.sh_addralign); + section_offset = AlignAddr(section_offset, s_tbss.sh_addralign); s_tbss.sh_size = 4; s_tbss.sh_flags = 0x403; s_tbss.sh_type = 8; @@ -1316,7 +1313,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_opd; memset(&s_opd, 0, sizeof(Elf64_Shdr)); s_opd.sh_addralign = 8; - section_offset = Memory.AlignAddr(section_offset, s_opd.sh_addralign); + section_offset = AlignAddr(section_offset, s_opd.sh_addralign); s_opd.sh_size = 2*4; s_opd.sh_type = 1; s_opd.sh_offset = section_offset; @@ -1477,7 +1474,7 @@ void CompilePPUProgram::Compile() if(!m_file_path.empty() && !m_analyze && !m_error) { - s_opd.sh_size = Memory.AlignAddr(s_opd.sh_size, s_opd.sh_addralign); + s_opd.sh_size = AlignAddr(s_opd.sh_size, s_opd.sh_addralign); section_offset += s_opd.sh_size; const u32 prog_load_1_end = section_offset; @@ -1485,7 +1482,7 @@ void CompilePPUProgram::Compile() Elf64_Shdr s_shstrtab; memset(&s_shstrtab, 0, sizeof(Elf64_Shdr)); s_shstrtab.sh_addralign = 1; - section_offset = Memory.AlignAddr(section_offset, s_shstrtab.sh_addralign); + section_offset = AlignAddr(section_offset, s_shstrtab.sh_addralign); s_shstrtab.sh_name = section_name_offset; s_shstrtab.sh_type = 3; s_shstrtab.sh_offset = section_offset; @@ -1507,7 +1504,7 @@ void CompilePPUProgram::Compile() elf_info.e_machine = MACHINE_PPC64; //PowerPC64 elf_info.e_version = 1; //ver 1 elf_info.e_flags = 0x0; - elf_info.e_shoff = Memory.AlignAddr(section_offset, 4); + elf_info.e_shoff = AlignAddr(section_offset, 4); u8* opd_data = new u8[s_opd.sh_size]; u32 entry_point = s_text.sh_addr; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 0b039e4886..c76ffbb4d9 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1,12 +1,14 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/PPUThread.h" +#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Static.h" #include "Emu/Cell/PPUDecoder.h" #include "Emu/Cell/PPUInterpreter.h" -#include "Emu/Cell/PPUDisAsm.h" #include #include @@ -57,7 +59,7 @@ void PPUThread::DoReset() void PPUThread::AddArgv(const std::string& arg) { m_stack_point -= arg.length() + 1; - m_stack_point = Memory.AlignAddr(m_stack_point, 0x10) - 0x10; + m_stack_point = AlignAddr(m_stack_point, 0x10) - 0x10; m_argv_addr.push_back(m_stack_point); Memory.WriteString(m_stack_point, arg); } @@ -94,7 +96,7 @@ void PPUThread::InitRegs() } */ - m_stack_point = Memory.AlignAddr(m_stack_point, 0x200) - 0x200; + m_stack_point = AlignAddr(m_stack_point, 0x200) - 0x200; GPR[1] = m_stack_point; GPR[2] = rtoc; @@ -219,3 +221,52 @@ int FPRdouble::Cmp(PPCdouble a, PPCdouble b) return CR_SO; } + +u64 PPUThread::GetStackArg(s32 i) +{ + return Memory.Read64(GPR[1] + 0x70 + 0x8 * (i - 9)); +} + +u64 PPUThread::FastCall(u64 addr, u64 rtoc, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8) +{ + GPR[3] = arg1; + GPR[4] = arg2; + GPR[5] = arg3; + GPR[6] = arg4; + GPR[7] = arg5; + GPR[8] = arg6; + GPR[9] = arg7; + GPR[10] = arg8; + + return FastCall2(addr, rtoc); +} + +u64 PPUThread::FastCall2(u64 addr, u64 rtoc) +{ + auto old_status = m_status; + auto old_PC = PC; + auto old_rtoc = GPR[2]; + auto old_LR = LR; + auto old_thread = GetCurrentNamedThread(); + + m_status = Running; + PC = addr; + GPR[2] = rtoc; + LR = Emu.m_ppu_thr_stop; + SetCurrentNamedThread(this); + + Task(); + + m_status = old_status; + PC = old_PC; + GPR[2] = old_rtoc; + LR = old_LR; + SetCurrentNamedThread(old_thread); + + return GPR[3]; +} + +void PPUThread::FastStop() +{ + m_status = Stopped; +} \ No newline at end of file diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 1fe6fffd01..0e8ff47869 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -607,6 +607,9 @@ public: u64 cycle; + u64 R_ADDR; // reservation address + u64 R_VALUE; // reservation value (BE) + public: PPUThread(); virtual ~PPUThread(); @@ -839,6 +842,10 @@ public: public: virtual void InitRegs(); virtual u64 GetFreeStackSize() const; + u64 GetStackArg(s32 i); + u64 FastCall(u64 addr, u64 rtoc, u64 arg1 = 0, u64 arg2 = 0, u64 arg3 = 0, u64 arg4 = 0, u64 arg5 = 0, u64 arg6 = 0, u64 arg7 = 0, u64 arg8 = 0); + u64 FastCall2(u64 addr, u64 rtoc); + void FastStop(); protected: virtual void DoReset() override; @@ -860,3 +867,4 @@ protected: PPUThread& GetCurrentPPUThread(); +#define declCPU PPUThread& CPU = GetCurrentPPUThread diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index a1ad6c258a..023a946ea7 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/Cell/RawSPUThread.h" @@ -149,7 +148,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) else { LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RunCtrl, 0x%x): unknown value", m_index, value); - Emu.Pause(); + return false; } break; } diff --git a/rpcs3/Emu/Cell/RawSPUThread.h b/rpcs3/Emu/Cell/RawSPUThread.h index ec40d69ab4..cfea40b0bf 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.h +++ b/rpcs3/Emu/Cell/RawSPUThread.h @@ -6,11 +6,6 @@ __forceinline static u32 GetRawSPURegAddrByNum(int num, int offset) return RAW_SPU_OFFSET * num + RAW_SPU_BASE_ADDR + RAW_SPU_PROB_OFFSET + offset; } -__forceinline static u32 GetRawSPURegAddrById(int id, int offset) -{ - return GetRawSPURegAddrByNum(Emu.GetCPU().GetThreadNumById(CPU_THREAD_RAW_SPU, id), offset); -} - class RawSPUThread : public SPUThread , public MemoryBlock diff --git a/rpcs3/Emu/Cell/SPUDisAsm.h b/rpcs3/Emu/Cell/SPUDisAsm.h index 8df572bcf6..5998eb693a 100644 --- a/rpcs3/Emu/Cell/SPUDisAsm.h +++ b/rpcs3/Emu/Cell/SPUDisAsm.h @@ -2,8 +2,49 @@ #include "Emu/Cell/SPUOpcodes.h" #include "Emu/Cell/PPCDisAsm.h" -#include "Emu/Cell/SPUThread.h" -#include "Emu/Memory/Memory.h" + +static const char* spu_reg_name[128] = +{ + "$LR", "$SP", "$2", "$3", "$4", "$5", "$6", "$7", + "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", + "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", + "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", + "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", + "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", + "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", + "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", + "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", + "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", + "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", + "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", + "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", + "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", + "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", +}; + +static const char* spu_ch_name[128] = +{ + "$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_WrEventAck", "$SPU_RdSigNotify1", + "$SPU_RdSigNotify2", "$ch5", "$ch6", "$SPU_WrDec", "$SPU_RdDec", + "$MFC_WrMSSyncReq", "$ch10", "$SPU_RdEventMask", "$MFC_RdTagMask", "$SPU_RdMachStat", + "$SPU_WrSRR0", "$SPU_RdSRR0", "$MFC_LSA", "$MFC_EAH", "$MFC_EAL", "$MFC_Size", + "$MFC_TagID", "$MFC_Cmd", "$MFC_WrTagMask", "$MFC_WrTagUpdate", "$MFC_RdTagStat", + "$MFC_RdListStallStat", "$MFC_WrListStallAck", "$MFC_RdAtomicStat", + "$SPU_WrOutMbox", "$SPU_RdInMbox", "$SPU_WrOutIntrMbox", "$ch31", "$ch32", + "$ch33", "$ch34", "$ch35", "$ch36", "$ch37", "$ch38", "$ch39", "$ch40", + "$ch41", "$ch42", "$ch43", "$ch44", "$ch45", "$ch46", "$ch47", "$ch48", + "$ch49", "$ch50", "$ch51", "$ch52", "$ch53", "$ch54", "$ch55", "$ch56", + "$ch57", "$ch58", "$ch59", "$ch60", "$ch61", "$ch62", "$ch63", "$ch64", + "$ch65", "$ch66", "$ch67", "$ch68", "$ch69", "$ch70", "$ch71", "$ch72", + "$ch73", "$ch74", "$ch75", "$ch76", "$ch77", "$ch78", "$ch79", "$ch80", + "$ch81", "$ch82", "$ch83", "$ch84", "$ch85", "$ch86", "$ch87", "$ch88", + "$ch89", "$ch90", "$ch91", "$ch92", "$ch93", "$ch94", "$ch95", "$ch96", + "$ch97", "$ch98", "$ch99", "$ch100", "$ch101", "$ch102", "$ch103", "$ch104", + "$ch105", "$ch106", "$ch107", "$ch108", "$ch109", "$ch110", "$ch111", "$ch112", + "$ch113", "$ch114", "$ch115", "$ch116", "$ch117", "$ch118", "$ch119", "$ch120", + "$ch121", "$ch122", "$ch123", "$ch124", "$ch125", "$ch126", "$ch127", +}; class SPUDisAsm : public SPUOpcodes @@ -93,7 +134,7 @@ private: } void MFSPR(u32 rt, u32 sa) { - DisAsm("mfspr", spu_reg_name[rt], spu_reg_name[sa]); // Are SPR mapped on the GPR or are there 128 additional registers ? Yes, there are also 128 SPR making 256 registers total + DisAsm("mfspr", spu_reg_name[rt], spu_reg_name[sa]); } void RDCH(u32 rt, u32 ra) { @@ -223,19 +264,19 @@ private: { DisAsm("wrch", spu_ch_name[ra], spu_reg_name[rt]); } - void BIZ(u32 rt, u32 ra) + void BIZ(u32 intr, u32 rt, u32 ra) { DisAsm("biz", spu_reg_name[rt], spu_reg_name[ra]); } - void BINZ(u32 rt, u32 ra) + void BINZ(u32 intr, u32 rt, u32 ra) { DisAsm("binz", spu_reg_name[rt], spu_reg_name[ra]); } - void BIHZ(u32 rt, u32 ra) + void BIHZ(u32 intr, u32 rt, u32 ra) { DisAsm("bihz", spu_reg_name[rt], spu_reg_name[ra]); } - void BIHNZ(u32 rt, u32 ra) + void BIHNZ(u32 intr, u32 rt, u32 ra) { DisAsm("bihnz", spu_reg_name[rt], spu_reg_name[ra]); } @@ -247,11 +288,11 @@ private: { DisAsm("stqx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } - void BI(u32 ra) + void BI(u32 intr, u32 ra) { DisAsm("bi", spu_reg_name[ra]); } - void BISL(u32 rt, u32 ra) + void BISL(u32 intr, u32 rt, u32 ra) { DisAsm("bisl", spu_reg_name[rt], spu_reg_name[ra]); } @@ -259,7 +300,7 @@ private: { DisAsm("iret", spu_reg_name[ra]); } - void BISLED(u32 rt, u32 ra) + void BISLED(u32 intr, u32 rt, u32 ra) { DisAsm("bisled", spu_reg_name[rt], spu_reg_name[ra]); } diff --git a/rpcs3/Emu/Cell/SPUInstrTable.h b/rpcs3/Emu/Cell/SPUInstrTable.h index 2349f4aab6..267db8df8d 100644 --- a/rpcs3/Emu/Cell/SPUInstrTable.h +++ b/rpcs3/Emu/Cell/SPUInstrTable.h @@ -1,5 +1,4 @@ #pragma once -#include "PPCInstrTable.h" #include "PPCDecoder.h" #include "SPUOpcodes.h" @@ -88,16 +87,16 @@ namespace SPU_instr bind_instr(ri7_list, AVGB, RT, RA, RB); bind_instr(ri7_list, MTSPR, RT, RA); bind_instr(ri7_list, WRCH, RA, RT); - bind_instr(ri7_list, BIZ, RT, RA); - bind_instr(ri7_list, BINZ, RT, RA); - bind_instr(ri7_list, BIHZ, RT, RA); - bind_instr(ri7_list, BIHNZ, RT, RA); + bind_instr(ri7_list, BIZ, RB, RT, RA); + bind_instr(ri7_list, BINZ, RB, RT, RA); + bind_instr(ri7_list, BIHZ, RB, RT, RA); + bind_instr(ri7_list, BIHNZ, RB, RT, RA); bind_instr(ri7_list, STOPD, RT, RA, RB); bind_instr(ri7_list, STQX, RT, RA, RB); - bind_instr(ri7_list, BI, RA); - bind_instr(ri7_list, BISL, RT, RA); + bind_instr(ri7_list, BI, RB, RA); + bind_instr(ri7_list, BISL, RB, RT, RA); bind_instr(ri7_list, IRET, RA); - bind_instr(ri7_list, BISLED, RT, RA); + bind_instr(ri7_list, BISLED, RB, RT, RA); bind_instr(ri7_list, HBR, L_11, RO, RA); bind_instr(ri7_list, GB, RT, RA); bind_instr(ri7_list, GBH, RT, RA); diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index b5d80a691e..be42be1d3e 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -1,20 +1,7 @@ #pragma once -#include "Emu/Cell/SPUOpcodes.h" -#include "Emu/Memory/Memory.h" -#include "Emu/Cell/SPUThread.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Crypto/sha1.h" - #define UNIMPLEMENTED() UNK(__FUNCTION__) -/* typedef union _CRT_ALIGN(16) __u32x4 { - u32 _u32[4]; - __m128i m128i; - __m128 m128; - __m128d m128d; - } __u32x4; */ - #define MEM_AND_REG_HASH() \ unsigned char mem_h[20]; sha1(&Memory[CPU.dmac.ls_offset], 256*1024, mem_h); \ unsigned char reg_h[20]; sha1((const unsigned char*)CPU.GPR, sizeof(CPU.GPR), reg_h); \ @@ -42,7 +29,7 @@ private: //0 - 10 void STOP(u32 code) { - CPU.DoStop(code); + CPU.StopAndSignal(code); LOG2_OPCODE(); } void LNOP() @@ -60,18 +47,7 @@ private: } void MFSPR(u32 rt, u32 sa) { - UNIMPLEMENTED(); - //If register is a dummy register (register labeled 0x0) - if(sa == 0x0) - { - CPU.GPR[rt]._u128.hi = 0x0; - CPU.GPR[rt]._u128.lo = 0x0; - } - else - { - CPU.GPR[rt]._u128.hi = CPU.SPR[sa]._u128.hi; - CPU.GPR[rt]._u128.lo = CPU.SPR[sa]._u128.lo; - } + UNIMPLEMENTED(); // not used } void RDCH(u32 rt, u32 ra) { @@ -267,18 +243,20 @@ private: } void MTSPR(u32 rt, u32 sa) { - if(sa != 0) - { - CPU.SPR[sa]._u128.hi = CPU.GPR[rt]._u128.hi; - CPU.SPR[sa]._u128.lo = CPU.GPR[rt]._u128.lo; - } + UNIMPLEMENTED(); // not used } void WRCH(u32 ra, u32 rt) { CPU.WriteChannel(ra, CPU.GPR[rt]); } - void BIZ(u32 rt, u32 ra) + void BIZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0); if (CPU.GPR[rt]._u32[3] == 0) { @@ -290,8 +268,14 @@ private: LOG5_OPCODE("not taken (0x%llx)", target); } } - void BINZ(u32 rt, u32 ra) + void BINZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0); if (CPU.GPR[rt]._u32[3] != 0) { @@ -303,8 +287,14 @@ private: LOG5_OPCODE("not taken (0x%llx)", target); } } - void BIHZ(u32 rt, u32 ra) + void BIHZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0); if (CPU.GPR[rt]._u16[6] == 0) { @@ -316,8 +306,14 @@ private: LOG5_OPCODE("not taken (0x%llx)", target); } } - void BIHNZ(u32 rt, u32 ra) + void BIHNZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0); if (CPU.GPR[rt]._u16[6] != 0) { @@ -331,8 +327,7 @@ private: } void STOPD(u32 rc, u32 ra, u32 rb) { - UNIMPLEMENTED(); - Emu.Pause(); + UNIMPLEMENTED(); // not used } void STQX(u32 rt, u32 ra, u32 rb) { @@ -340,14 +335,26 @@ private: CPU.WriteLS128(lsa, CPU.GPR[rt]._u128); } - void BI(u32 ra) + void BI(u32 intr, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0); LOG5_OPCODE("branch (0x%llx)", target); CPU.SetBranch(target); } - void BISL(u32 rt, u32 ra) + void BISL(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0); CPU.GPR[rt].Reset(); CPU.GPR[rt]._u32[3] = CPU.PC + 4; @@ -356,12 +363,11 @@ private: } void IRET(u32 ra) { - UNIMPLEMENTED(); - //SetBranch(SRR0); + UNIMPLEMENTED(); // not used } - void BISLED(u32 rt, u32 ra) + void BISLED(u32 intr, u32 rt, u32 ra) { - UNIMPLEMENTED(); + UNIMPLEMENTED(); // not used } void HBR(u32 p, u32 ro, u32 ra) { @@ -771,8 +777,7 @@ private: } void DFCGT(u32 rt, u32 ra, u32 rb) { - CPU.GPR[rt]._u64[0] = CPU.GPR[ra]._d[0] > CPU.GPR[rb]._d[0] ? 0xffffffffffffffff : 0; - CPU.GPR[rt]._u64[1] = CPU.GPR[ra]._d[1] > CPU.GPR[rb]._d[1] ? 0xffffffffffffffff : 0; + UNIMPLEMENTED(); // cannot be used } void FA(u32 rt, u32 ra, u32 rb) { @@ -817,8 +822,7 @@ private: } void DFCMGT(u32 rt, u32 ra, u32 rb) { - CPU.GPR[rt]._u64[0] = fabs(CPU.GPR[ra]._d[0]) > fabs(CPU.GPR[rb]._d[0]) ? 0xffffffffffffffff : 0; - CPU.GPR[rt]._u64[1] = fabs(CPU.GPR[ra]._d[1]) > fabs(CPU.GPR[rb]._d[1]) ? 0xffffffffffffffff : 0; + UNIMPLEMENTED(); // cannot be used } void DFA(u32 rt, u32 ra, u32 rb) { @@ -890,11 +894,13 @@ private: } void CGX(u32 rt, u32 ra, u32 rb) { + // rarely used for (int w = 0; w < 4; w++) CPU.GPR[rt]._u32[w] = ((u64)CPU.GPR[ra]._u32[w] + (u64)CPU.GPR[rb]._u32[w] + (u64)(CPU.GPR[rt]._u32[w] & 1)) >> 32; } void BGX(u32 rt, u32 ra, u32 rb) { + // rarely used s64 nResult; for (int w = 0; w < 4; w++) @@ -917,10 +923,8 @@ private: void FSCRRD(u32 rt) { - /*CPU.GPR[rt]._u128.lo = - CPU.FPSCR.Exception0 << 20 & - CPU.FPSCR.*/ - UNIMPLEMENTED(); + // TODO (rarely used) + CPU.GPR[rt].Reset(); } void FESD(u32 rt, u32 ra) { @@ -936,60 +940,16 @@ private: } void FSCRWR(u32 rt, u32 ra) { - UNIMPLEMENTED(); + // TODO (rarely used) + if (CPU.GPR[ra]._u128) + { + LOG_ERROR(SPU, "FSCRWR(%d,%d): value = %s", rt, ra, CPU.GPR[ra].ToString().c_str()); + UNIMPLEMENTED(); + } } void DFTSV(u32 rt, u32 ra, s32 i7) { - const u64 DoubleExpMask = 0x7ff0000000000000; - const u64 DoubleFracMask = 0x000fffffffffffff; - const u64 DoubleSignMask = 0x8000000000000000; - const SPU_GPR_hdr temp = CPU.GPR[ra]; - CPU.GPR[rt].Reset(); - if (i7 & 1) //Negative Denorm Check (-, exp is zero, frac is non-zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] & DoubleFracMask) - if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == DoubleSignMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] & DoubleFracMask) - if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == 0) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == DoubleSignMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 8) //Positive Zero Check (+, exp is zero, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == 0) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == (DoubleSignMask | DoubleExpMask)) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == DoubleExpMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 64) //Not-a-Number Check (any sign, exp is 0x7ff, frac is non-zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] & DoubleFracMask) - if ((temp._u64[i] & DoubleExpMask) == DoubleExpMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } + UNIMPLEMENTED(); // cannot be used } void FCEQ(u32 rt, u32 ra, u32 rb) { @@ -1000,8 +960,7 @@ private: } void DFCEQ(u32 rt, u32 ra, u32 rb) { - CPU.GPR[rt]._u64[0] = CPU.GPR[ra]._d[0] == CPU.GPR[rb]._d[0] ? 0xffffffffffffffff : 0; - CPU.GPR[rt]._u64[1] = CPU.GPR[ra]._d[1] == CPU.GPR[rb]._d[1] ? 0xffffffffffffffff : 0; + UNIMPLEMENTED(); // cannot be used } void MPY(u32 rt, u32 ra, u32 rb) { @@ -1037,8 +996,7 @@ private: } void DFCMEQ(u32 rt, u32 ra, u32 rb) { - CPU.GPR[rt]._u64[0] = fabs(CPU.GPR[ra]._d[0]) == fabs(CPU.GPR[rb]._d[0]) ? 0xffffffffffffffff : 0; - CPU.GPR[rt]._u64[1] = fabs(CPU.GPR[ra]._d[1]) == fabs(CPU.GPR[rb]._d[1]) ? 0xffffffffffffffff : 0; + UNIMPLEMENTED(); // cannot be used } void MPYU(u32 rt, u32 ra, u32 rb) { @@ -1052,8 +1010,8 @@ private: } void FI(u32 rt, u32 ra, u32 rb) { - //Floating Interpolation: ra will be ignored. - //It should work correctly if result of preceding FREST or FRSQEST is sufficiently exact + // TODO: Floating Interpolation: ra will be ignored. + // It should work correctly if result of preceding FREST or FRSQEST is sufficiently exact CPU.GPR[rt] = CPU.GPR[rb]; } void HEQ(u32 rt, u32 ra, u32 rb) diff --git a/rpcs3/Emu/Cell/SPUOpcodes.h b/rpcs3/Emu/Cell/SPUOpcodes.h index d486ba7495..4c0901f45d 100644 --- a/rpcs3/Emu/Cell/SPUOpcodes.h +++ b/rpcs3/Emu/Cell/SPUOpcodes.h @@ -272,16 +272,16 @@ public: virtual void AVGB(u32 rt, u32 ra, u32 rb) = 0; virtual void MTSPR(u32 rt, u32 sa) = 0; virtual void WRCH(u32 ra, u32 rt) = 0; - virtual void BIZ(u32 rt, u32 ra) = 0; - virtual void BINZ(u32 rt, u32 ra) = 0; - virtual void BIHZ(u32 rt, u32 ra) = 0; - virtual void BIHNZ(u32 rt, u32 ra) = 0; + virtual void BIZ(u32 intr, u32 rt, u32 ra) = 0; + virtual void BINZ(u32 intr, u32 rt, u32 ra) = 0; + virtual void BIHZ(u32 intr, u32 rt, u32 ra) = 0; + virtual void BIHNZ(u32 intr, u32 rt, u32 ra) = 0; virtual void STOPD(u32 rc, u32 ra, u32 rb) = 0; virtual void STQX(u32 rt, u32 ra, u32 rb) = 0; - virtual void BI(u32 ra) = 0; - virtual void BISL(u32 rt, u32 ra) = 0; + virtual void BI(u32 intr, u32 ra) = 0; + virtual void BISL(u32 intr, u32 rt, u32 ra) = 0; virtual void IRET(u32 ra) = 0; - virtual void BISLED(u32 rt, u32 ra) = 0; + virtual void BISLED(u32 intr, u32 rt, u32 ra) = 0; virtual void HBR(u32 p, u32 ro, u32 ra) = 0; virtual void GB(u32 rt, u32 ra) = 0; virtual void GBH(u32 rt, u32 ra) = 0; diff --git a/rpcs3/Emu/Cell/SPURSManager.cpp b/rpcs3/Emu/Cell/SPURSManager.cpp index ab61442cb9..2e547dce37 100644 --- a/rpcs3/Emu/Cell/SPURSManager.cpp +++ b/rpcs3/Emu/Cell/SPURSManager.cpp @@ -1,7 +1,51 @@ #include "stdafx.h" -#include "SPURSManager.h" #include "Emu/Memory/Memory.h" +#include "SPURSManager.h" + +SPURSManagerAttribute::SPURSManagerAttribute(int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork) +{ + this->nSpus = nSpus; + this->spuThreadGroupPriority = spuPriority; + this->ppuThreadPriority = ppuPriority; + this->exitIfNoWork = exitIfNoWork; + + memset(this->namePrefix, 0, CELL_SPURS_NAME_MAX_LENGTH + 1); + this->threadGroupType = 0; + this->container = 0; +} + +int SPURSManagerAttribute::_setNamePrefix(const char *name, u32 size) +{ + strncpy(this->namePrefix, name, size); + this->namePrefix[0] = 0; + return 0; +} + +int SPURSManagerAttribute::_setSpuThreadGroupType(int type) +{ + this->threadGroupType = type; + return 0; +} + +int SPURSManagerAttribute::_setMemoryContainerForSpuThread(u32 container) +{ + this->container = container; + return 0; +} + +SPURSManagerEventFlag::SPURSManagerEventFlag(u32 flagClearMode, u32 flagDirection) +{ + this->flagClearMode = flagClearMode; + this->flagDirection = flagDirection; +} + +SPURSManagerTasksetAttribute::SPURSManagerTasksetAttribute(u64 args, mem8_t priority, u32 maxContention) +{ + this->args = args; + this->maxContention = maxContention; +} + SPURSManager::SPURSManager(SPURSManagerAttribute *attr) { this->attr = attr; @@ -26,4 +70,4 @@ SPURSManagerTaskset::SPURSManagerTaskset(u32 address, SPURSManagerTasksetAttribu { this->tattr = tattr; this->address = address; -} +} \ No newline at end of file diff --git a/rpcs3/Emu/Cell/SPURSManager.h b/rpcs3/Emu/Cell/SPURSManager.h index ff7a2b7ff5..210eda74cc 100644 --- a/rpcs3/Emu/Cell/SPURSManager.h +++ b/rpcs3/Emu/Cell/SPURSManager.h @@ -1,85 +1,18 @@ #pragma once -#include "Emu/Memory/Memory.h" - -// SPURS defines. -enum SPURSKernelInterfaces -{ - CELL_SPURS_MAX_SPU = 8, - CELL_SPURS_MAX_WORKLOAD = 16, - CELL_SPURS_MAX_WORKLOAD2 = 32, - CELL_SPURS_MAX_PRIORITY = 16, - CELL_SPURS_NAME_MAX_LENGTH = 15, - CELL_SPURS_SIZE = 4096, - CELL_SPURS_SIZE2 = 8192, - CELL_SPURS_ALIGN = 128, - CELL_SPURS_ATTRIBUTE_SIZE = 512, - CELL_SPURS_ATTRIBUTE_ALIGN = 8, - CELL_SPURS_INTERRUPT_VECTOR = 0x0, - CELL_SPURS_LOCK_LINE = 0x80, - CELL_SPURS_KERNEL_DMA_TAG_ID = 31, -}; - -enum RangeofEventQueuePortNumbers -{ - CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15, - CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16, - CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63, -}; - -enum SPURSTraceTypes -{ - CELL_SPURS_TRACE_TAG_LOAD = 0x2a, - CELL_SPURS_TRACE_TAG_MAP = 0x2b, - CELL_SPURS_TRACE_TAG_START = 0x2c, - CELL_SPURS_TRACE_TAG_STOP = 0x2d, - CELL_SPURS_TRACE_TAG_USER = 0x2e, - CELL_SPURS_TRACE_TAG_GUID = 0x2f, -}; - -// SPURS task defines. -enum TaskConstants -{ - CELL_SPURS_MAX_TASK = 128, - CELL_SPURS_TASK_TOP = 0x3000, - CELL_SPURS_TASK_BOTTOM = 0x40000, - CELL_SPURS_MAX_TASK_NAME_LENGTH = 32, -}; +#include "Emu/SysCalls/Modules/cellSpurs.h" // Internal class to shape a SPURS attribute. class SPURSManagerAttribute { public: - SPURSManagerAttribute(int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork) - { - this->nSpus = nSpus; - this->spuThreadGroupPriority = spuPriority; - this->ppuThreadPriority = ppuPriority; - this->exitIfNoWork = exitIfNoWork; + SPURSManagerAttribute(int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork); - memset(this->namePrefix, 0, CELL_SPURS_NAME_MAX_LENGTH + 1); - this->threadGroupType = 0; - this->container = 0; - } + int _setNamePrefix(const char *name, u32 size); - int _setNamePrefix(const char *name, u32 size) - { - strncpy(this->namePrefix, name, size); - this->namePrefix[0] = 0; - return 0; - } + int _setSpuThreadGroupType(int type); - int _setSpuThreadGroupType(int type) - { - this->threadGroupType = type; - return 0; - } - - int _setMemoryContainerForSpuThread(u32 container) - { - this->container = container; - return 0; - } + int _setMemoryContainerForSpuThread(u32 container); protected: be_t nSpus; @@ -94,11 +27,7 @@ protected: class SPURSManagerEventFlag { public: - SPURSManagerEventFlag(u32 flagClearMode, u32 flagDirection) - { - this->flagClearMode = flagClearMode; - this->flagDirection = flagDirection; - } + SPURSManagerEventFlag(u32 flagClearMode, u32 flagDirection); u32 _getDirection() { @@ -118,11 +47,7 @@ protected: class SPURSManagerTasksetAttribute { public: - SPURSManagerTasksetAttribute(u64 args, mem8_t priority, u32 maxContention) - { - this->args = args; - this->maxContention = maxContention; - } + SPURSManagerTasksetAttribute(u64 args, mem8_t priority, u32 maxContention); protected: be_t args; diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 6bdcddf1cb..2fc927b6f5 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -1,8 +1,4 @@ #pragma once -#include "Emu/Cell/SPUOpcodes.h" -#include "Emu/Memory/Memory.h" -#include "Emu/Cell/SPUThread.h" -#include "Emu/SysCalls/SysCalls.h" #define ASMJIT_STATIC @@ -438,7 +434,7 @@ private: static void STOP(u32 code) { SPUThread& CPU = *(SPUThread*)GetCurrentCPUThread(); - CPU.DoStop(code); + CPU.StopAndSignal(code); LOG2_OPCODE(); } }; @@ -471,17 +467,6 @@ private: void MFSPR(u32 rt, u32 sa) { UNIMPLEMENTED(); - //If register is a dummy register (register labeled 0x0) - if(sa == 0x0) - { - CPU.GPR[rt]._u128.hi = 0x0; - CPU.GPR[rt]._u128.lo = 0x0; - } - else - { - CPU.GPR[rt]._u128.hi = CPU.SPR[sa]._u128.hi; - CPU.GPR[rt]._u128.lo = CPU.SPR[sa]._u128.lo; - } } void RDCH(u32 rt, u32 ra) { @@ -1098,11 +1083,6 @@ private: void MTSPR(u32 rt, u32 sa) { UNIMPLEMENTED(); - if(sa != 0) - { - CPU.SPR[sa]._u128.hi = CPU.GPR[rt]._u128.hi; - CPU.SPR[sa]._u128.lo = CPU.GPR[rt]._u128.lo; - } } void WRCH(u32 ra, u32 rt) { @@ -1146,8 +1126,14 @@ private: } }*/ } - void BIZ(u32 rt, u32 ra) + void BIZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + c.mov(cpu_qword(PC), (u32)CPU.PC); do_finalize = true; @@ -1158,8 +1144,14 @@ private: c.shr(*pos_var, 2); LOG_OPCODE(); } - void BINZ(u32 rt, u32 ra) + void BINZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + c.mov(cpu_qword(PC), (u32)CPU.PC); do_finalize = true; @@ -1170,8 +1162,14 @@ private: c.shr(*pos_var, 2); LOG_OPCODE(); } - void BIHZ(u32 rt, u32 ra) + void BIHZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + c.mov(cpu_qword(PC), (u32)CPU.PC); do_finalize = true; @@ -1182,8 +1180,14 @@ private: c.shr(*pos_var, 2); LOG_OPCODE(); } - void BIHNZ(u32 rt, u32 ra) + void BIHNZ(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + c.mov(cpu_qword(PC), (u32)CPU.PC); do_finalize = true; @@ -1197,7 +1201,6 @@ private: void STOPD(u32 rc, u32 ra, u32 rb) { UNIMPLEMENTED(); - Emu.Pause(); } void STQX(u32 rt, u32 ra, u32 rb) { @@ -1226,8 +1229,14 @@ private: LOG_OPCODE(); } - void BI(u32 ra) + void BI(u32 intr, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + c.mov(cpu_qword(PC), (u32)CPU.PC); do_finalize = true; @@ -1235,8 +1244,14 @@ private: c.shr(*pos_var, 2); LOG_OPCODE(); } - void BISL(u32 rt, u32 ra) + void BISL(u32 intr, u32 rt, u32 ra) { + if (intr) + { + UNIMPLEMENTED(); + return; + } + XmmInvalidate(rt); c.mov(cpu_qword(PC), (u32)CPU.PC); @@ -1254,9 +1269,8 @@ private: void IRET(u32 ra) { UNIMPLEMENTED(); - //SetBranch(SRR0); } - void BISLED(u32 rt, u32 ra) + void BISLED(u32 intr, u32 rt, u32 ra) { UNIMPLEMENTED(); } @@ -2065,18 +2079,7 @@ private: } void DFCGT(u32 rt, u32 ra, u32 rb) { - // reverted less-than - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.cmppd(vb.get(), va->read(), 1); - } - else - { - c.cmppd(vb.get(), cpu_xmm(GPR[ra]), 1); - } - XmmFinalize(vb, rt); - LOG_OPCODE(); + UNIMPLEMENTED(); } void FA(u32 rt, u32 ra, u32 rb) { @@ -2206,15 +2209,7 @@ private: } void DFCMGT(u32 rt, u32 ra, u32 rb) { - // reverted less-than - const XmmLink& vb = XmmGet(rb, rt); - const XmmLink& va = XmmGet(ra); - c.andpd(vb.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs - c.andpd(va.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs - c.cmppd(vb.get(), va.get(), 1); - XmmFinalize(vb, rt); - XmmFinalize(va); - LOG_OPCODE(); + UNIMPLEMENTED(); } void DFA(u32 rt, u32 ra, u32 rb) { @@ -2476,7 +2471,11 @@ private: } void FSCRRD(u32 rt) { - UNIMPLEMENTED(); + // zero (hack) + const XmmLink& v0 = XmmAlloc(rt); + c.pxor(v0.get(), v0.get()); + XmmFinalize(v0, rt); + LOG_OPCODE(); } void FESD(u32 rt, u32 ra) { @@ -2496,62 +2495,12 @@ private: } void FSCRWR(u32 rt, u32 ra) { - UNIMPLEMENTED(); + // nop (not implemented) + LOG_OPCODE(); } - void DFTSV(u32 rt, u32 ra, s32 i7) //nf + void DFTSV(u32 rt, u32 ra, s32 i7) { - WRAPPER_BEGIN(rt, ra, i7, zz); - const u64 DoubleExpMask = 0x7ff0000000000000; - const u64 DoubleFracMask = 0x000fffffffffffff; - const u64 DoubleSignMask = 0x8000000000000000; - const SPU_GPR_hdr temp = CPU.GPR[ra]; - CPU.GPR[rt].Reset(); - if (i7 & 1) //Negative Denorm Check (-, exp is zero, frac is non-zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] & DoubleFracMask) - if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == DoubleSignMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] & DoubleFracMask) - if ((temp._u64[i] & (DoubleSignMask | DoubleExpMask)) == 0) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == DoubleSignMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 8) //Positive Zero Check (+, exp is zero, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == 0) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == (DoubleSignMask | DoubleExpMask)) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] == DoubleExpMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - if (i7 & 64) //Not-a-Number Check (any sign, exp is 0x7ff, frac is non-zero) - for (int i = 0; i < 2; i++) - { - if (temp._u64[i] & DoubleFracMask) - if ((temp._u64[i] & DoubleExpMask) == DoubleExpMask) - CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; - } - WRAPPER_END(rt, ra, i7, 0); + UNIMPLEMENTED(); } void FCEQ(u32 rt, u32 ra, u32 rb) { @@ -2570,18 +2519,7 @@ private: } void DFCEQ(u32 rt, u32 ra, u32 rb) { - // compare equal - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.cmppd(vb.get(), va->read(), 0); - } - else - { - c.cmppd(vb.get(), cpu_xmm(GPR[ra]), 0); - } - XmmFinalize(vb, rt); - LOG_OPCODE(); + UNIMPLEMENTED(); } void MPY(u32 rt, u32 ra, u32 rb) { @@ -2665,14 +2603,7 @@ private: } void DFCMEQ(u32 rt, u32 ra, u32 rb) { - const XmmLink& vb = XmmGet(rb, rt); - const XmmLink& va = XmmGet(ra); - c.andpd(vb.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs - c.andpd(va.get(), XmmConst(_mm_set_epi32(0x7fffffff, 0xffffffff, 0x7fffffff, 0xffffffff))); // abs - c.cmppd(vb.get(), va.get(), 0); // == - XmmFinalize(vb, rt); - XmmFinalize(va); - LOG_OPCODE(); + UNIMPLEMENTED(); } void MPYU(u32 rt, u32 ra, u32 rb) { diff --git a/rpcs3/Emu/Cell/SPURecompilerCore.cpp b/rpcs3/Emu/Cell/SPURecompilerCore.cpp index 72a59dc6cf..04997c8c39 100644 --- a/rpcs3/Emu/Cell/SPURecompilerCore.cpp +++ b/rpcs3/Emu/Cell/SPURecompilerCore.cpp @@ -3,8 +3,12 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/SysCalls/lv2/sys_time.h" + #include "SPUInstrTable.h" #include "SPUDisAsm.h" + +#include "SPUThread.h" #include "SPUInterpreter.h" #include "SPURecompiler.h" @@ -43,6 +47,7 @@ void SPURecompilerCore::Compile(u16 pos) u64 time0 = 0; SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode); + dis_asm.offset = Memory.GetMemFromAddr(CPU.dmac.ls_offset); StringLogger stringLogger; stringLogger.setOption(kLoggerOptionBinaryForm, true); @@ -102,7 +107,7 @@ void SPURecompilerCore::Compile(u16 pos) { const u64 stamp1 = get_system_time(); // disasm for logging: - dis_asm.dump_pc = CPU.dmac.ls_offset + pos * 4; + dis_asm.dump_pc = pos * 4; (*SPU_instr::rrr_list)(&dis_asm, opcode); compiler.addComment(fmt::Format("SPU data: PC=0x%05x %s", pos * 4, dis_asm.last_opcode.c_str()).c_str()); // compile single opcode: @@ -171,21 +176,28 @@ u8 SPURecompilerCore::DecodeMemory(const u64 address) { // check data (hard way) bool is_valid = true; - /*for (u32 i = pos; i < (u32)(entry[pos].count + pos); i++) - { - if (entry[i].valid != ls[i]) - { - is_valid = false; - break; - } - }*/ + //for (u32 i = pos; i < (u32)(entry[pos].count + pos); i++) + //{ + // if (entry[i].valid != ls[i]) + // { + // is_valid = false; + // break; + // } + //} // invalidate if necessary if (!is_valid) { - // TODO - LOG_ERROR(Log::SPU, "SPURecompilerCore::DecodeMemory(ls_addr=0x%x): code has changed", pos * sizeof(u32)); - Emu.Pause(); - return 0; + for (u32 i = 0; i < 0x10000; i++) + { + if (entry[i].pointer && + i + (u32)entry[i].count > (u32)pos && + i < (u32)pos + (u32)entry[pos].count) + { + runtime.release(entry[i].pointer); + entry[i].pointer = nullptr; + } + } + //LOG_ERROR(Log::SPU, "SPURecompilerCore::DecodeMemory(ls_addr=0x%x): code has changed", pos * sizeof(u32)); } } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 559861ddd3..0f87f2238f 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1,7 +1,16 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" +#include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/SysCalls/ErrorCodes.h" +#include "Emu/SysCalls/lv2/sys_spu.h" +#include "Emu/SysCalls/lv2/sys_event_flag.h" +#include "Emu/SysCalls/lv2/sys_time.h" +#include "Emu/Event.h" + +#include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" #include "Emu/Cell/SPUDecoder.h" #include "Emu/Cell/SPUInterpreter.h" @@ -81,6 +90,9 @@ void SPUThread::InitRegs() MFC1.TagStatus.SetValue(0); MFC2.TagStatus.SetValue(0); //PC = SPU.NPC.GetValue(); + + m_event_mask = 0; + m_events = 0; } u64 SPUThread::GetFreeStackSize() const @@ -137,3 +149,908 @@ void SPUThread::DoClose() } } } + +void SPUThread::WriteSNR(bool number, u32 value) +{ + if (cfg.value & ((u64)1 << (u64)number)) + { + SPU.SNR[number].PushUncond_OR(value); // logical OR + } + else + { + SPU.SNR[number].PushUncond(value); // overwrite + } +} + +#define LOG_DMAC(type, text) type(Log::SPU, "DMAC::ProcessCmd(cmd=0x%x, tag=0x%x, lsa=0x%x, ea=0x%llx, size=0x%x): " text, cmd, tag, lsa, ea, size) + +void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) +{ + if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); + + if (ea >= SYS_SPU_THREAD_BASE_LOW) + { + if (ea >= 0x100000000) + { + LOG_DMAC(LOG_ERROR, "Invalid external address"); + Emu.Pause(); + return; + } + else if (group) + { + // SPU Thread Group MMIO (LS and SNR) + u32 num = (ea & SYS_SPU_THREAD_BASE_MASK) / SYS_SPU_THREAD_OFFSET; // thread number in group + if (num >= group->list.size() || !group->list[num]) + { + LOG_DMAC(LOG_ERROR, "Invalid thread (SPU Thread Group MMIO)"); + Emu.Pause(); + return; + } + + SPUThread* spu = (SPUThread*)Emu.GetCPU().GetThread(group->list[num]); + + u32 addr = (ea & SYS_SPU_THREAD_BASE_MASK) % SYS_SPU_THREAD_OFFSET; + if ((addr <= 0x3ffff) && (addr + size <= 0x40000)) + { + // LS access + ea = spu->dmac.ls_offset + addr; + } + else if ((cmd & MFC_PUT_CMD) && size == 4 && (addr == SYS_SPU_THREAD_SNR1 || addr == SYS_SPU_THREAD_SNR2)) + { + spu->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, Memory.Read32(dmac.ls_offset + lsa)); + return; + } + else + { + LOG_DMAC(LOG_ERROR, "Invalid register (SPU Thread Group MMIO)"); + Emu.Pause(); + return; + } + } + else + { + LOG_DMAC(LOG_ERROR, "Thread group not set (SPU Thread Group MMIO)"); + Emu.Pause(); + return; + } + } + else if (ea >= RAW_SPU_BASE_ADDR && size == 4) + { + switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) + { + case MFC_PUT_CMD: + { + Memory.Write32(ea, ReadLS32(lsa)); + return; + } + + case MFC_GET_CMD: + { + WriteLS32(lsa, Memory.Read32(ea)); + return; + } + + default: + { + LOG_DMAC(LOG_ERROR, "Unknown DMA command"); + Emu.Pause(); + return; + } + } + } + + switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) + { + case MFC_PUT_CMD: + { + memcpy(Memory + ea, Memory + (dmac.ls_offset + lsa), size); + return; + } + + case MFC_GET_CMD: + { + memcpy(Memory + (dmac.ls_offset + lsa), Memory + ea, size); + return; + } + + default: + { + LOG_DMAC(LOG_ERROR, "Unknown DMA command"); + Emu.Pause(); + return; + } + } +} + +#undef LOG_CMD + +void SPUThread::ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFCArgs) +{ + u32 list_addr = ea & 0x3ffff; + u32 list_size = size / 8; + lsa &= 0x3fff0; + + struct list_element + { + be_t s; // Stall-and-Notify bit (0x8000) + be_t ts; // List Transfer Size + be_t ea; // External Address Low + }; + + u32 result = MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL; + + for (u32 i = 0; i < list_size; i++) + { + mem_ptr_t rec(dmac.ls_offset + list_addr + i * 8); + + u32 size = rec->ts; + if (size < 16 && size != 1 && size != 2 && size != 4 && size != 8) + { + LOG_ERROR(Log::SPU, "DMA List: invalid transfer size(%d)", size); + result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; + break; + } + + u32 addr = rec->ea; + ProcessCmd(cmd, tag, lsa | (addr & 0xf), addr, size); + + if (Ini.HLELogging.GetValue() || rec->s) + LOG_NOTICE(Log::SPU, "*** list element(%d/%d): s = 0x%x, ts = 0x%x, low ea = 0x%x (lsa = 0x%x)", + i, list_size, (u16)rec->s, (u16)rec->ts, (u32)rec->ea, lsa | (addr & 0xf)); + + lsa += std::max(size, (u32)16); + + if (rec->s & se16(0x8000)) + { + StallStat.PushUncond_OR(1 << tag); + + if (StallList[tag].MFCArgs) + { + LOG_ERROR(Log::SPU, "DMA List: existing stalled list found (tag=%d)", tag); + result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; + break; + } + StallList[tag].MFCArgs = &MFCArgs; + StallList[tag].cmd = cmd; + StallList[tag].ea = (ea & ~0xffffffff) | (list_addr + (i + 1) * 8); + StallList[tag].lsa = lsa; + StallList[tag].size = (list_size - i - 1) * 8; + + break; + } + } + + MFCArgs.CMDStatus.SetValue(result); +} + +void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) +{ + u32 cmd = MFCArgs.CMDStatus.GetValue(); + u16 op = cmd & MFC_MASK_CMD; + + u32 lsa = MFCArgs.LSA.GetValue(); + u64 ea = (u64)MFCArgs.EAL.GetValue() | ((u64)MFCArgs.EAH.GetValue() << 32); + u32 size_tag = MFCArgs.Size_Tag.GetValue(); + u16 tag = (u16)size_tag; + u16 size = size_tag >> 16; + + switch (op & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) + { + case MFC_PUT_CMD: + case MFC_PUTR_CMD: // ??? + case MFC_GET_CMD: + { + if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x, cmd = 0x%x", + (op & MFC_PUT_CMD ? "PUT" : "GET"), + (op & MFC_RESULT_MASK ? "R" : ""), + (op & MFC_BARRIER_MASK ? "B" : ""), + (op & MFC_FENCE_MASK ? "F" : ""), + lsa, ea, tag, size, cmd); + + ProcessCmd(cmd, tag, lsa, ea, size); + MFCArgs.CMDStatus.SetValue(MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL); + } + break; + + case MFC_PUTL_CMD: + case MFC_PUTRL_CMD: // ??? + case MFC_GETL_CMD: + { + if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa = 0x%x, list = 0x%llx, tag = 0x%x, size = 0x%x, cmd = 0x%x", + (op & MFC_PUT_CMD ? "PUT" : "GET"), + (op & MFC_RESULT_MASK ? "RL" : "L"), + (op & MFC_BARRIER_MASK ? "B" : ""), + (op & MFC_FENCE_MASK ? "F" : ""), + lsa, ea, tag, size, cmd); + + ListCmd(lsa, ea, tag, size, cmd, MFCArgs); + } + break; + + case MFC_GETLLAR_CMD: + case MFC_PUTLLC_CMD: + case MFC_PUTLLUC_CMD: + case MFC_PUTQLLUC_CMD: + { + if (Ini.HLELogging.GetValue() || size != 128) LOG_NOTICE(Log::SPU, "DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x", + (op == MFC_GETLLAR_CMD ? "GETLLAR" : + op == MFC_PUTLLC_CMD ? "PUTLLC" : + op == MFC_PUTLLUC_CMD ? "PUTLLUC" : "PUTQLLUC"), + lsa, ea, tag, size, cmd); + + if (op == MFC_GETLLAR_CMD) // get reservation + { + if (R_ADDR) + { + m_events |= SPU_EVENT_LR; + } + + R_ADDR = ea; + for (u32 i = 0; i < 16; i++) + { + R_DATA[i] = *(u64*)&Memory[R_ADDR + i * 8]; + *(u64*)&Memory[dmac.ls_offset + lsa + i * 8] = R_DATA[i]; + } + MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); + } + else if (op == MFC_PUTLLC_CMD) // store conditional + { + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + + if (R_ADDR == ea) + { + u32 changed = 0, mask = 0; + u64 buf[16]; + for (u32 i = 0; i < 16; i++) + { + buf[i] = *(u64*)&Memory[dmac.ls_offset + lsa + i * 8]; + if (buf[i] != R_DATA[i]) + { + changed++; + mask |= (0x3 << (i * 2)); + if (*(u64*)&Memory[R_ADDR + i * 8] != R_DATA[i]) + { + m_events |= SPU_EVENT_LR; + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + R_ADDR = 0; + return; + } + } + } + + for (u32 i = 0; i < 16; i++) + { + if (buf[i] != R_DATA[i]) + { + if (InterlockedCompareExchange64((volatile long long*)(Memory + (ea + i * 8)), buf[i], R_DATA[i]) != R_DATA[i]) + { + m_events |= SPU_EVENT_LR; + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + + if (changed > 1) + { + LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Memory corrupted (~x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", + changed, mask, op, cmd, lsa, ea, tag, size); + Emu.Pause(); + } + + break; + } + } + } + + if (changed > 1) + { + LOG_WARNING(Log::SPU, "MFC_PUTLLC_CMD: Reservation impossibru (~x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", + changed, mask, op, cmd, lsa, ea, tag, size); + + SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode); + for (s32 i = PC; i < PC + 4 * 7; i += 4) + { + dis_asm.dump_pc = i; + dis_asm.offset = Memory.GetMemFromAddr(dmac.ls_offset); + const u32 opcode = Memory.Read32(i + dmac.ls_offset); + (*SPU_instr::rrr_list)(&dis_asm, opcode); + if (i >= 0 && i < 0x40000) + { + LOG_NOTICE(Log::SPU, "*** %s", dis_asm.last_opcode.c_str()); + } + } + } + } + else + { + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + } + R_ADDR = 0; + } + else // store unconditional + { + if (R_ADDR) + { + m_events |= SPU_EVENT_LR; + } + + ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); + if (op == MFC_PUTLLUC_CMD) + { + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); + } + R_ADDR = 0; + } + } + break; + + default: + LOG_ERROR(Log::SPU, "Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", + op, cmd, lsa, ea, tag, size); + break; + } +} + +bool SPUThread::CheckEvents() +{ + // checks events: + // SPU_EVENT_LR: + { + for (u32 i = 0; i < 16; i++) + { + if (*(u64*)&Memory[R_ADDR + i * 8] != R_DATA[i]) + { + m_events |= SPU_EVENT_LR; + R_ADDR = 0; + break; + } + } + } + + return (m_events & m_event_mask) != 0; +} + +u32 SPUThread::GetChannelCount(u32 ch) +{ + switch (ch) + { + case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount(); + case SPU_WrOutIntrMbox: return SPU.Out_IntrMBox.GetFreeCount(); + case SPU_RdInMbox: return SPU.In_MBox.GetCount(); + case MFC_RdTagStat: return MFC1.TagStatus.GetCount(); + case MFC_RdListStallStat: return StallStat.GetCount(); + case MFC_WrTagUpdate: return MFC1.TagStatus.GetCount(); // hack + case SPU_RdSigNotify1: return SPU.SNR[0].GetCount(); + case SPU_RdSigNotify2: return SPU.SNR[1].GetCount(); + case MFC_RdAtomicStat: return MFC1.AtomicStat.GetCount(); + case SPU_RdEventStat: return CheckEvents() ? 1 : 0; + + default: + { + LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", + __FUNCTION__, ch, spu_ch_name[ch]); + return 0; + } + } +} + +void SPUThread::WriteChannel(u32 ch, const SPU_GPR_hdr& r) +{ + const u32 v = r._u32[3]; + + switch (ch) + { + case SPU_WrOutIntrMbox: + { + if (!group) // if RawSPU + { + if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "SPU_WrOutIntrMbox: interrupt(v=0x%x)", v); + while (!SPU.Out_IntrMBox.Push(v)) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (Emu.IsStopped()) + { + LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]); + return; + } + } + m_intrtag[2].stat |= 1; + if (CPUThread* t = Emu.GetCPU().GetThread(m_intrtag[2].thread)) + { + if (t->GetType() == CPU_THREAD_PPU && !t->IsAlive()) + { + PPUThread& ppu = *(PPUThread*)t; + ppu.FastStop(); + ppu.Run(); + ppu.FastCall(ppu.PC, ppu.GPR[2], ppu.m_interrupt_arg); + } + } + } + else + { + const u8 code = v >> 24; + if (code < 64) + { + /* ===== sys_spu_thread_send_event (used by spu_printf) ===== */ + + u8 spup = code & 63; + + u32 data; + if (!SPU.Out_MBox.Pop(data)) + { + LOG_ERROR(Log::SPU, "sys_spu_thread_send_event(v=0x%x, spup=%d): Out_MBox is empty", v, spup); + return; + } + + if (Ini.HLELogging.GetValue()) + { + LOG_NOTICE(Log::SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x)", spup, v & 0x00ffffff, data); + } + + EventPort& port = SPUPs[spup]; + + std::lock_guard lock(port.m_mutex); + + if (!port.eq) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x): event queue not connected", spup, (v & 0x00ffffff), data); + SPU.In_MBox.PushUncond(CELL_ENOTCONN); // TODO: check error passing + return; + } + + if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) + { + SPU.In_MBox.PushUncond(CELL_EBUSY); + return; + } + + SPU.In_MBox.PushUncond(CELL_OK); + return; + } + else if (code < 128) + { + /* ===== sys_spu_thread_throw_event ===== */ + + const u8 spup = code & 63; + + u32 data; + if (!SPU.Out_MBox.Pop(data)) + { + LOG_ERROR(Log::SPU, "sys_spu_thread_throw_event(v=0x%x, spup=%d): Out_MBox is empty", v, spup); + return; + } + + //if (Ini.HLELogging.GetValue()) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x)", spup, v & 0x00ffffff, data); + } + + EventPort& port = SPUPs[spup]; + + std::lock_guard lock(port.m_mutex); + + if (!port.eq) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x): event queue not connected", spup, (v & 0x00ffffff), data); + return; + } + + // TODO: check passing spup value + if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x) failed (queue is full)", spup, (v & 0x00ffffff), data); + return; + } + + return; + } + else if (code == 128) + { + /* ===== sys_event_flag_set_bit ===== */ + u32 flag = v & 0xffffff; + + u32 data; + if (!SPU.Out_MBox.Pop(data)) + { + LOG_ERROR(Log::SPU, "sys_event_flag_set_bit(v=0x%x (flag=%d)): Out_MBox is empty", v, flag); + return; + } + + if (flag > 63) + { + LOG_ERROR(Log::SPU, "sys_event_flag_set_bit(id=%d, v=0x%x): flag > 63", data, v, flag); + return; + } + + //if (Ini.HLELogging.GetValue()) + { + LOG_WARNING(Log::SPU, "sys_event_flag_set_bit(id=%d, v=0x%x (flag=%d))", data, v, flag); + } + + EventFlag* ef; + if (!Emu.GetIdManager().GetIDData(data, ef)) + { + LOG_ERROR(Log::SPU, "sys_event_flag_set_bit(id=%d, v=0x%x (flag=%d)): EventFlag not found", data, v, flag); + SPU.In_MBox.PushUncond(CELL_ESRCH); + return; + } + + u32 tid = GetCurrentCPUThread()->GetId(); + + ef->m_mutex.lock(tid); + ef->flags |= (u64)1 << flag; + if (u32 target = ef->check()) + { + // if signal, leave both mutexes locked... + ef->signal.lock(target); + ef->m_mutex.unlock(tid, target); + } + else + { + ef->m_mutex.unlock(tid); + } + + SPU.In_MBox.PushUncond(CELL_OK); + return; + } + else if (code == 192) + { + /* ===== sys_event_flag_set_bit_impatient ===== */ + u32 flag = v & 0xffffff; + + u32 data; + if (!SPU.Out_MBox.Pop(data)) + { + LOG_ERROR(Log::SPU, "sys_event_flag_set_bit_impatient(v=0x%x (flag=%d)): Out_MBox is empty", v, flag); + return; + } + + if (flag > 63) + { + LOG_ERROR(Log::SPU, "sys_event_flag_set_bit_impatient(id=%d, v=0x%x): flag > 63", data, v, flag); + return; + } + + //if (Ini.HLELogging.GetValue()) + { + LOG_WARNING(Log::SPU, "sys_event_flag_set_bit_impatient(id=%d, v=0x%x (flag=%d))", data, v, flag); + } + + EventFlag* ef; + if (!Emu.GetIdManager().GetIDData(data, ef)) + { + LOG_WARNING(Log::SPU, "sys_event_flag_set_bit_impatient(id=%d, v=0x%x (flag=%d)): EventFlag not found", data, v, flag); + return; + } + + u32 tid = GetCurrentCPUThread()->GetId(); + + ef->m_mutex.lock(tid); + ef->flags |= (u64)1 << flag; + if (u32 target = ef->check()) + { + // if signal, leave both mutexes locked... + ef->signal.lock(target); + ef->m_mutex.unlock(tid, target); + } + else + { + ef->m_mutex.unlock(tid); + } + + return; + } + else + { + u32 data; + if (SPU.Out_MBox.Pop(data)) + { + LOG_ERROR(Log::SPU, "SPU_WrOutIntrMbox: unknown data (v=0x%x); Out_MBox = 0x%x", v, data); + } + else + { + LOG_ERROR(Log::SPU, "SPU_WrOutIntrMbox: unknown data (v=0x%x)", v); + } + SPU.In_MBox.PushUncond(CELL_EINVAL); // ??? + return; + } + } + break; + } + + case SPU_WrOutMbox: + { + while (!SPU.Out_MBox.Push(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case MFC_WrTagMask: + { + MFC1.QueryMask.SetValue(v); + break; + } + + case MFC_WrTagUpdate: + { + MFC1.TagStatus.PushUncond(MFC1.QueryMask.GetValue()); + break; + } + + case MFC_LSA: + { + MFC1.LSA.SetValue(v); + break; + } + + case MFC_EAH: + { + MFC1.EAH.SetValue(v); + break; + } + + case MFC_EAL: + { + MFC1.EAL.SetValue(v); + break; + } + + case MFC_Size: + { + MFC1.Size_Tag.SetValue((MFC1.Size_Tag.GetValue() & 0xffff) | (v << 16)); + break; + } + + case MFC_TagID: + { + MFC1.Size_Tag.SetValue((MFC1.Size_Tag.GetValue() & ~0xffff) | (v & 0xffff)); + break; + } + + + case MFC_Cmd: + { + MFC1.CMDStatus.SetValue(v); + EnqMfcCmd(MFC1); + break; + } + + case MFC_WrListStallAck: + { + if (v >= 32) + { + LOG_ERROR(Log::SPU, "MFC_WrListStallAck error: invalid tag(%d)", v); + return; + } + StalledList temp = StallList[v]; + if (!temp.MFCArgs) + { + LOG_ERROR(Log::SPU, "MFC_WrListStallAck error: empty tag(%d)", v); + return; + } + StallList[v].MFCArgs = nullptr; + ListCmd(temp.lsa, temp.ea, temp.tag, temp.size, temp.cmd, *temp.MFCArgs); + break; + } + + case SPU_WrDec: + { + m_dec_start = get_time(); + m_dec_value = v; + break; + } + + case SPU_WrEventMask: + { + m_event_mask = v; + if (v & ~(SPU_EVENT_IMPLEMENTED)) LOG_ERROR(Log::SPU, "SPU_WrEventMask: unsupported event masked (0x%x)"); + break; + } + + case SPU_WrEventAck: + { + m_events &= ~v; + break; + } + + default: + { + LOG_ERROR(Log::SPU, "%s error (v=0x%x): unknown/illegal channel (%d [%s]).", __FUNCTION__, v, ch, spu_ch_name[ch]); + break; + } + } + + if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]); +} + +void SPUThread::ReadChannel(SPU_GPR_hdr& r, u32 ch) +{ + r.Reset(); + u32& v = r._u32[3]; + + switch (ch) + { + case SPU_RdInMbox: + { + while (!SPU.In_MBox.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case MFC_RdTagStat: + { + while (!MFC1.TagStatus.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case MFC_RdTagMask: + { + v = MFC1.QueryMask.GetValue(); + break; + } + + case SPU_RdSigNotify1: + { + while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case SPU_RdSigNotify2: + { + while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case MFC_RdAtomicStat: + { + while (!MFC1.AtomicStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case MFC_RdListStallStat: + { + while (!StallStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + break; + } + + case SPU_RdDec: + { + v = m_dec_value - (u32)(get_time() - m_dec_start); + break; + } + + case SPU_RdEventMask: + { + v = m_event_mask; + break; + } + + case SPU_RdEventStat: + { + while (!CheckEvents() && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + v = m_events & m_event_mask; + break; + } + + case SPU_RdMachStat: + { + v = 1; // hack (not isolated, interrupts enabled) + // TODO: check value + break; + } + + default: + { + LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); + break; + } + } + + if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]); +} + +void SPUThread::StopAndSignal(u32 code) +{ + SetExitStatus(code); // exit code (not status) + + switch (code) + { + case 0x110: /* ===== sys_spu_thread_receive_event ===== */ + { + u32 spuq = 0; + if (!SPU.Out_MBox.Pop(spuq)) + { + LOG_ERROR(Log::SPU, "sys_spu_thread_receive_event: cannot read Out_MBox"); + SPU.In_MBox.PushUncond(CELL_EINVAL); // ??? + return; + } + + if (SPU.In_MBox.GetCount()) + { + LOG_ERROR(Log::SPU, "sys_spu_thread_receive_event(spuq=0x%x): In_MBox is not empty", spuq); + SPU.In_MBox.PushUncond(CELL_EBUSY); // ??? + return; + } + + if (Ini.HLELogging.GetValue()) + { + LOG_NOTICE(Log::SPU, "sys_spu_thread_receive_event(spuq=0x%x)", spuq); + } + + EventQueue* eq; + if (!SPUQs.GetEventQueue(FIX_SPUQ(spuq), eq)) + { + SPU.In_MBox.PushUncond(CELL_EINVAL); // TODO: check error value + return; + } + + u32 tid = GetId(); + + eq->sq.push(tid); // add thread to sleep queue + + while (true) + { + switch (eq->owner.trylock(tid)) + { + case SMR_OK: + if (!eq->events.count()) + { + eq->owner.unlock(tid); + break; + } + else + { + u32 next = (eq->protocol == SYS_SYNC_FIFO) ? eq->sq.pop() : eq->sq.pop_prio(); + if (next != tid) + { + eq->owner.unlock(tid, next); + break; + } + } + case SMR_SIGNAL: + { + sys_event_data event; + eq->events.pop(event); + eq->owner.unlock(tid); + SPU.In_MBox.PushUncond(CELL_OK); + SPU.In_MBox.PushUncond(event.data1); + SPU.In_MBox.PushUncond(event.data2); + SPU.In_MBox.PushUncond(event.data3); + return; + } + case SMR_FAILED: break; + default: eq->sq.invalidate(tid); SPU.In_MBox.PushUncond(CELL_ECANCELED); return; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + if (Emu.IsStopped()) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_receive_event(spuq=0x%x) aborted", spuq); + eq->sq.invalidate(tid); + return; + } + } + } + break; + case 0x102: + if (!SPU.Out_MBox.GetCount()) + { + LOG_ERROR(Log::SPU, "sys_spu_thread_exit (no status, code 0x102)"); + } + else if (Ini.HLELogging.GetValue()) + { + // the real exit status + LOG_NOTICE(Log::SPU, "sys_spu_thread_exit (status=0x%x)", SPU.Out_MBox.GetValue()); + } + SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP); + Stop(); + break; + default: + if (!SPU.Out_MBox.GetCount()) + { + LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (no message)", code); + } + else + { + LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (message=0x%x)", code, SPU.Out_MBox.GetValue()); + } + SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP); + Stop(); + break; + } +} \ No newline at end of file diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index c6c3e95470..3829db3c65 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -1,75 +1,9 @@ #pragma once #include "PPCThread.h" #include "Emu/Event.h" -#include "Emu/SysCalls/lv2/sys_spu.h" -#include "Emu/SysCalls/lv2/sys_event_flag.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include "MFC.h" -#include "Emu/SysCalls/ErrorCodes.h" #include -static const char* spu_reg_name[128] = -{ - "$LR", "$SP", "$2", "$3", "$4", "$5", "$6", "$7", - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", - "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", - "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", - "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", - "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", - "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", - "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", - "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", - "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", - "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", - "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", - "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", - "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", -}; -//SPU reg $0 is a dummy reg, and is used for certain instructions. -static const char* spu_specialreg_name[128] = { - "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", - "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", - "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", - "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", - "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", - "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", - "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", - "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", - "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", - "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", - "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", - "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", - "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", -}; - -static const char* spu_ch_name[128] = -{ - "$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_WrEventAck", "$SPU_RdSigNotify1", - "$SPU_RdSigNotify2", "$ch5", "$ch6", "$SPU_WrDec", "$SPU_RdDec", - "$MFC_WrMSSyncReq", "$ch10", "$SPU_RdEventMask", "$MFC_RdTagMask", "$SPU_RdMachStat", - "$SPU_WrSRR0", "$SPU_RdSRR0", "$MFC_LSA", "$MFC_EAH", "$MFC_EAL", "$MFC_Size", - "$MFC_TagID", "$MFC_Cmd", "$MFC_WrTagMask", "$MFC_WrTagUpdate", "$MFC_RdTagStat", - "$MFC_RdListStallStat", "$MFC_WrListStallAck", "$MFC_RdAtomicStat", - "$SPU_WrOutMbox", "$SPU_RdInMbox", "$SPU_WrOutIntrMbox", "$ch31", "$ch32", - "$ch33", "$ch34", "$ch35", "$ch36", "$ch37", "$ch38", "$ch39", "$ch40", - "$ch41", "$ch42", "$ch43", "$ch44", "$ch45", "$ch46", "$ch47", "$ch48", - "$ch49", "$ch50", "$ch51", "$ch52", "$ch53", "$ch54", "$ch55", "$ch56", - "$ch57", "$ch58", "$ch59", "$ch60", "$ch61", "$ch62", "$ch63", "$ch64", - "$ch65", "$ch66", "$ch67", "$ch68", "$ch69", "$ch70", "$ch71", "$ch72", - "$ch73", "$ch74", "$ch75", "$ch76", "$ch77", "$ch78", "$ch79", "$ch80", - "$ch81", "$ch82", "$ch83", "$ch84", "$ch85", "$ch86", "$ch87", "$ch88", - "$ch89", "$ch90", "$ch91", "$ch92", "$ch93", "$ch94", "$ch95", "$ch96", - "$ch97", "$ch98", "$ch99", "$ch100", "$ch101", "$ch102", "$ch103", "$ch104", - "$ch105", "$ch106", "$ch107", "$ch108", "$ch109", "$ch110", "$ch111", "$ch112", - "$ch113", "$ch114", "$ch115", "$ch116", "$ch117", "$ch118", "$ch119", "$ch120", - "$ch121", "$ch122", "$ch123", "$ch124", "$ch125", "$ch126", "$ch127", -}; - enum SPUchannels { SPU_RdEventStat = 0, //Read event status with mask applied @@ -106,6 +40,24 @@ enum MFCchannels MFC_RdAtomicStat = 27, //Read completion status of last completed immediate MFC atomic update command }; +enum SPUEvents +{ + SPU_EVENT_MS = 0x1000, // multisource synchronization event + SPU_EVENT_A = 0x800, // privileged attention event + SPU_EVENT_LR = 0x400, // lock line reservation lost event + SPU_EVENT_S1 = 0x200, // signal notification register 1 available + SPU_EVENT_S2 = 0x100, // signal notification register 2 available + SPU_EVENT_LE = 0x80, // SPU outbound mailbox available + SPU_EVENT_ME = 0x40, // SPU outbound interrupt mailbox available + SPU_EVENT_TM = 0x20, // SPU decrementer became negative (?) + SPU_EVENT_MB = 0x10, // SPU inbound mailbox available + SPU_EVENT_QV = 0x4, // MFC SPU command queue available + SPU_EVENT_SN = 0x2, // MFC list command stall-and-notify event + SPU_EVENT_TG = 0x1, // MFC tag-group status update event + + SPU_EVENT_IMPLEMENTED = SPU_EVENT_LR, +}; + enum { SPU_RUNCNTL_STOP = 0, @@ -205,7 +157,7 @@ public: return this->low >> 22 & 0x3; default: - LOG_ERROR(SPU, "Unexpected slice value in FPSCR::checkSliceRounding(): %d", slice); + throw fmt::Format("Unexpected slice value in FPSCR::checkSliceRounding(): %d", slice); return 0; } } @@ -271,25 +223,6 @@ union SPU_GPR_hdr } }; -union SPU_SPR_hdr -{ - u32 _u32[4]; - u128 _u128; - s128 _i128; - - SPU_SPR_hdr() {} - - std::string ToString() const - { - return fmt::Format("%08x%08x%08x%08x", _u32[3], _u32[2], _u32[1], _u32[0]); - } - - void Reset() - { - memset(this, 0, sizeof(*this)); - } -}; - union SPU_SNRConfig_hdr { u64 value; @@ -307,13 +240,17 @@ union SPU_SNRConfig_hdr } }; +struct SpuGroupInfo; + class SPUThread : public PPCThread { public: - SPU_GPR_hdr GPR[128]; //General-Purpose Register - SPU_SPR_hdr SPR[128]; //Special-Purpose Registers + SPU_GPR_hdr GPR[128]; // General-Purpose Registers //FPSCR FPSCR; - SPU_SNRConfig_hdr cfg; //Signal Notification Registers Configuration (OR-mode enabled: 0x1 for SNR1, 0x2 for SNR2) + SPU_SNRConfig_hdr cfg; // Signal Notification Registers Configuration (OR-mode enabled: 0x1 for SNR1, 0x2 for SNR2) + + u64 R_ADDR; // reservation address + u64 R_DATA[16]; // lock line data (BE) EventPort SPUPs[64]; // SPU Thread Event Ports EventManager SPUQs; // SPU Queue Mapping @@ -322,6 +259,9 @@ public: u64 m_dec_start; // timestamp of writing decrementer value u32 m_dec_value; // written decrementer value + u32 m_event_mask; + u32 m_events; + struct IntrTag { u32 enabled; // 1 == true @@ -555,17 +495,7 @@ public: Channel<1> SNR[2]; } SPU; - void WriteSNR(bool number, u32 value) - { - if (cfg.value & ((u64)1 << (u64)number)) - { - SPU.SNR[number].PushUncond_OR(value); // logical OR - } - else - { - SPU.SNR[number].PushUncond(value); // overwrite - } - } + void WriteSNR(bool number, u32 value); u32 LSA; @@ -577,761 +507,21 @@ public: DMAC dmac; -#define LOG_DMAC(type, text) type(Log::SPU, "DMAC::ProcessCmd(cmd=0x%x, tag=0x%x, lsa=0x%x, ea=0x%llx, size=0x%x): " text, cmd, tag, lsa, ea, size) + void ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size); - void ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) - { - if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); + void ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFCArgs); - if (ea >= SYS_SPU_THREAD_BASE_LOW) - { - if (ea >= 0x100000000) - { - LOG_DMAC(LOG_ERROR, "Invalid external address"); - Emu.Pause(); - return; - } - else if (group) - { - // SPU Thread Group MMIO (LS and SNR) - u32 num = (ea & SYS_SPU_THREAD_BASE_MASK) / SYS_SPU_THREAD_OFFSET; // thread number in group - if (num >= group->list.size() || !group->list[num]) - { - LOG_DMAC(LOG_ERROR, "Invalid thread (SPU Thread Group MMIO)"); - Emu.Pause(); - return; - } + void EnqMfcCmd(MFCReg& MFCArgs); - SPUThread* spu = (SPUThread*)Emu.GetCPU().GetThread(group->list[num]); + bool CheckEvents(); - u32 addr = (ea & SYS_SPU_THREAD_BASE_MASK) % SYS_SPU_THREAD_OFFSET; - if ((addr <= 0x3ffff) && (addr + size <= 0x40000)) - { - // LS access - ea = spu->dmac.ls_offset + addr; - } - else if ((cmd & MFC_PUT_CMD) && size == 4 && (addr == SYS_SPU_THREAD_SNR1 || addr == SYS_SPU_THREAD_SNR2)) - { - spu->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, Memory.Read32(dmac.ls_offset + lsa)); - return; - } - else - { - LOG_DMAC(LOG_ERROR, "Invalid register (SPU Thread Group MMIO)"); - Emu.Pause(); - return; - } - } - else - { - LOG_DMAC(LOG_ERROR, "Thread group not set (SPU Thread Group MMIO)"); - Emu.Pause(); - return; - } - } - else if (ea >= RAW_SPU_BASE_ADDR && size == 4) - { - switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) - { - case MFC_PUT_CMD: - { - Memory.Write32(ea, ReadLS32(lsa)); - return; - } + u32 GetChannelCount(u32 ch); - case MFC_GET_CMD: - { - WriteLS32(lsa, Memory.Read32(ea)); - return; - } + void WriteChannel(u32 ch, const SPU_GPR_hdr& r); - default: - { - LOG_DMAC(LOG_ERROR, "Unknown DMA command"); - Emu.Pause(); - return; - } - } - } + void ReadChannel(SPU_GPR_hdr& r, u32 ch); - switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) - { - case MFC_PUT_CMD: - { - memcpy(Memory + ea, Memory + dmac.ls_offset + lsa, size); - return; - } - - case MFC_GET_CMD: - { - memcpy(Memory + dmac.ls_offset + lsa, Memory + ea, size); - return; - } - - default: - { - LOG_DMAC(LOG_ERROR, "Unknown DMA command"); - Emu.Pause(); - return; - } - } - } - -#undef LOG_CMD - - void ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFCArgs) - { - u32 list_addr = ea & 0x3ffff; - u32 list_size = size / 8; - lsa &= 0x3fff0; - - struct list_element - { - be_t s; // Stall-and-Notify bit (0x8000) - be_t ts; // List Transfer Size - be_t ea; // External Address Low - }; - - u32 result = MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL; - - for (u32 i = 0; i < list_size; i++) - { - mem_ptr_t rec(dmac.ls_offset + list_addr + i * 8); - - u32 size = rec->ts; - if (size < 16 && size != 1 && size != 2 && size != 4 && size != 8) - { - LOG_ERROR(Log::SPU, "DMA List: invalid transfer size(%d)", size); - result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; - break; - } - - u32 addr = rec->ea; - ProcessCmd(cmd, tag, lsa | (addr & 0xf), addr, size); - - if (Ini.HLELogging.GetValue() || rec->s) - LOG_NOTICE(Log::SPU, "*** list element(%d/%d): s = 0x%x, ts = 0x%x, low ea = 0x%x (lsa = 0x%x)", - i, list_size, (u16)rec->s, (u16)rec->ts, (u32)rec->ea, lsa | (addr & 0xf)); - - lsa += std::max(size, (u32)16); - - if (rec->s & se16(0x8000)) - { - StallStat.PushUncond_OR(1 << tag); - - if (StallList[tag].MFCArgs) - { - LOG_ERROR(Log::SPU, "DMA List: existing stalled list found (tag=%d)", tag); - result = MFC_PPU_DMA_CMD_SEQUENCE_ERROR; - break; - } - StallList[tag].MFCArgs = &MFCArgs; - StallList[tag].cmd = cmd; - StallList[tag].ea = (ea & ~0xffffffff) | (list_addr + (i + 1) * 8); - StallList[tag].lsa = lsa; - StallList[tag].size = (list_size - i - 1) * 8; - - break; - } - } - - MFCArgs.CMDStatus.SetValue(result); - } - - void EnqMfcCmd(MFCReg& MFCArgs) - { - u32 cmd = MFCArgs.CMDStatus.GetValue(); - u16 op = cmd & MFC_MASK_CMD; - - u32 lsa = MFCArgs.LSA.GetValue(); - u64 ea = (u64)MFCArgs.EAL.GetValue() | ((u64)MFCArgs.EAH.GetValue() << 32); - u32 size_tag = MFCArgs.Size_Tag.GetValue(); - u16 tag = (u16)size_tag; - u16 size = size_tag >> 16; - - switch(op & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) - { - case MFC_PUT_CMD: - case MFC_PUTR_CMD: // ??? - case MFC_GET_CMD: - { - if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x, cmd = 0x%x", - (op & MFC_PUT_CMD ? "PUT" : "GET"), - (op & MFC_RESULT_MASK ? "R" : ""), - (op & MFC_BARRIER_MASK ? "B" : ""), - (op & MFC_FENCE_MASK ? "F" : ""), - lsa, ea, tag, size, cmd); - - ProcessCmd(cmd, tag, lsa, ea, size); - MFCArgs.CMDStatus.SetValue(MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL); - } - break; - - case MFC_PUTL_CMD: - case MFC_PUTRL_CMD: // ??? - case MFC_GETL_CMD: - { - if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa = 0x%x, list = 0x%llx, tag = 0x%x, size = 0x%x, cmd = 0x%x", - (op & MFC_PUT_CMD ? "PUT" : "GET"), - (op & MFC_RESULT_MASK ? "RL" : "L"), - (op & MFC_BARRIER_MASK ? "B" : ""), - (op & MFC_FENCE_MASK ? "F" : ""), - lsa, ea, tag, size, cmd); - - ListCmd(lsa, ea, tag, size, cmd, MFCArgs); - } - break; - - case MFC_GETLLAR_CMD: - case MFC_PUTLLC_CMD: - case MFC_PUTLLUC_CMD: - case MFC_PUTQLLUC_CMD: - { - if (Ini.HLELogging.GetValue() || size != 128) LOG_NOTICE(Log::SPU, "DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x", - (op == MFC_GETLLAR_CMD ? "GETLLAR" : - op == MFC_PUTLLC_CMD ? "PUTLLC" : - op == MFC_PUTLLUC_CMD ? "PUTLLUC" : "PUTQLLUC"), - lsa, ea, tag, size, cmd); - - if (op == MFC_GETLLAR_CMD) // get reservation - { - SMutexLockerR lock(reservation.mutex); - reservation.owner = lock.tid; - reservation.addr = ea; - reservation.size = 128; - for (u32 i = 0; i < 8; i++) - { - reservation.data[i] = *(u128*)&Memory[(u32)ea + i * 16]; - *(u128*)&Memory[dmac.ls_offset + lsa + i * 16] = reservation.data[i]; - } - MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); - } - else if (op == MFC_PUTLLC_CMD) // store conditional - { - SMutexLockerR lock(reservation.mutex); - if (reservation.owner == lock.tid) // succeeded - { - if (reservation.addr == ea && reservation.size == 128) - { - u128 buf[8]; // data being written newly - u32 changed = 0, mask = 0, last = 0; - for (u32 i = 0; i < 8; i++) - { - buf[i] = *(u128*)&Memory[dmac.ls_offset + lsa + i * 16]; - if (buf[i] != reservation.data[i]) - { - changed++; - last = i; - mask |= (0xf << (i * 4)); - } - } - if (changed == 0) // nothing changed? - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - else if (changed == 1) - { - if (buf[last].hi != reservation.data[last].hi && buf[last].lo != reservation.data[last].lo) - { - LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 128bit compare and swap"); - Emu.Pause(); - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - else - { - const u32 last_q = (buf[last].hi == reservation.data[last].hi); - - if (InterlockedCompareExchange64((volatile long long*)(Memory + (u32)ea + last * 16 + last_q * 8), - buf[last]._u64[last_q], reservation.data[last]._u64[last_q]) == reservation.data[last]._u64[last_q]) - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - else - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); - } - } - } - else - { - ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); - LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Reservation Error: impossibru (~ 16x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", - changed, mask, op, cmd, lsa, ea, tag, size); - Emu.Pause(); - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); - } - } - else - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); - } - reservation.clear(); - } - else // failed - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); - } - } - else // store unconditional - { - SMutexLockerR lock(reservation.mutex); - ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); - if (op == MFC_PUTLLUC_CMD) - { - MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); - } - if ((reservation.addr + reservation.size > ea && reservation.addr <= ea + size) || - (ea + size > reservation.addr && ea <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - } - } - break; - - default: - LOG_ERROR( Log::SPU, "Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", - op, cmd, lsa, ea, tag, size); - break; - } - } - - u32 GetChannelCount(u32 ch) - { - switch(ch) - { - case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount(); - case SPU_WrOutIntrMbox: return SPU.Out_IntrMBox.GetFreeCount(); - case SPU_RdInMbox: return SPU.In_MBox.GetCount(); - case MFC_RdTagStat: return MFC1.TagStatus.GetCount(); - case MFC_RdListStallStat: return StallStat.GetCount(); - case MFC_WrTagUpdate: return MFC1.TagStatus.GetCount(); // hack - case SPU_RdSigNotify1: return SPU.SNR[0].GetCount(); - case SPU_RdSigNotify2: return SPU.SNR[1].GetCount(); - case MFC_RdAtomicStat: return MFC1.AtomicStat.GetCount(); - - default: - { - LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", - __FUNCTION__, ch, spu_ch_name[ch]); - return 0; - } - } - } - - void WriteChannel(u32 ch, const SPU_GPR_hdr& r) - { - const u32 v = r._u32[3]; - - switch(ch) - { - case SPU_WrOutIntrMbox: - { - if (!group) // if RawSPU - { - if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "SPU_WrOutIntrMbox: interrupt(v=0x%x)", v); - while (!SPU.Out_IntrMBox.Push(v)) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - if (Emu.IsStopped()) - { - LOG_WARNING(Log::SPU, "%s(%s) aborted (I)", __FUNCTION__, spu_ch_name[ch]); - return; - } - } - m_intrtag[2].stat |= 1; - if (CPUThread* t = Emu.GetCPU().GetThread(m_intrtag[2].thread)) - { - while (t->IsAlive()) // TODO: ??? - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - if (Emu.IsStopped()) - { - LOG_WARNING(Log::SPU, "%s(%s) aborted (II)", __FUNCTION__, spu_ch_name[ch]); - return; - } - } - t->SetArg(0, t->m_interrupt_arg); - t->Run(); - t->Exec(); - } - } - else - { - u8 code = v >> 24; - if (code < 64) - { - /* ===== sys_spu_thread_send_event ===== */ - - u8 spup = code & 63; - - u32 data; - if (!SPU.Out_MBox.Pop(data)) - { - LOG_ERROR(Log::SPU, "sys_spu_thread_send_event(v=0x%x, spup=%d): Out_MBox is empty", v, spup); - return; - } - - if (SPU.In_MBox.GetCount()) - { - LOG_ERROR(Log::SPU, "sys_spu_thread_send_event(v=0x%x, spup=%d): In_MBox is not empty", v, spup); - SPU.In_MBox.PushUncond(CELL_EBUSY); // ??? - return; - } - - if (Ini.HLELogging.GetValue()) - { - LOG_NOTICE(Log::SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x)", spup, v & 0x00ffffff, data); - } - - EventPort& port = SPUPs[spup]; - - std::lock_guard lock(port.m_mutex); - - if (!port.eq) - { - // spu_printf fails there - LOG_WARNING(Log::SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x): event queue not connected", spup, (v & 0x00ffffff), data); - SPU.In_MBox.PushUncond(CELL_ENOTCONN); // TODO: check error passing - return; - } - - if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)code << 32) | (v & 0x00ffffff), data)) - { - SPU.In_MBox.PushUncond(CELL_EBUSY); - return; - } - - SPU.In_MBox.PushUncond(CELL_OK); - return; - } - else if (code == 128) - { - /* ===== sys_event_flag_set_bit ===== */ - u32 flag = v & 0xffffff; - - u32 data; - if (!SPU.Out_MBox.Pop(data)) - { - LOG_ERROR(Log::SPU, "sys_event_flag_set_bit(v=0x%x (flag=%d)): Out_MBox is empty", v, flag); - return; - } - - if (flag > 63) - { - LOG_ERROR(Log::SPU, "sys_event_flag_set_bit(id=%d, v=0x%x): flag > 63", data, v, flag); - return; - } - - //if (Ini.HLELogging.GetValue()) - { - LOG_WARNING(Log::SPU, "sys_event_flag_set_bit(id=%d, v=0x%x (flag=%d))", data, v, flag); - } - - EventFlag* ef; - if (!Emu.GetIdManager().GetIDData(data, ef)) - { - LOG_ERROR(Log::SPU, "sys_event_flag_set_bit(id=%d, v=0x%x (flag=%d)): EventFlag not found", data, v, flag); - SPU.In_MBox.PushUncond(CELL_ESRCH); - return; - } - - u32 tid = GetCurrentCPUThread()->GetId(); - - ef->m_mutex.lock(tid); - ef->flags |= (u64)1 << flag; - if (u32 target = ef->check()) - { - // if signal, leave both mutexes locked... - ef->signal.lock(target); - ef->m_mutex.unlock(tid, target); - } - else - { - ef->m_mutex.unlock(tid); - } - - SPU.In_MBox.PushUncond(CELL_OK); - return; - } - else - { - u32 data; - if (SPU.Out_MBox.Pop(data)) - { - LOG_ERROR(Log::SPU, "SPU_WrOutIntrMbox: unknown data (v=0x%x); Out_MBox = 0x%x", v, data); - } - else - { - LOG_ERROR(Log::SPU, "SPU_WrOutIntrMbox: unknown data (v=0x%x)", v); - } - SPU.In_MBox.PushUncond(CELL_EINVAL); // ??? - return; - } - } - break; - } - - case SPU_WrOutMbox: - { - while (!SPU.Out_MBox.Push(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case MFC_WrTagMask: - { - MFC1.QueryMask.SetValue(v); - break; - } - - case MFC_WrTagUpdate: - { - MFC1.TagStatus.PushUncond(MFC1.QueryMask.GetValue()); - break; - } - - case MFC_LSA: - { - MFC1.LSA.SetValue(v); - break; - } - - case MFC_EAH: - { - MFC1.EAH.SetValue(v); - break; - } - - case MFC_EAL: - { - MFC1.EAL.SetValue(v); - break; - } - - case MFC_Size: - { - MFC1.Size_Tag.SetValue((MFC1.Size_Tag.GetValue() & 0xffff) | (v << 16)); - break; - } - - case MFC_TagID: - { - MFC1.Size_Tag.SetValue((MFC1.Size_Tag.GetValue() & ~0xffff) | (v & 0xffff)); - break; - } - - - case MFC_Cmd: - { - MFC1.CMDStatus.SetValue(v); - EnqMfcCmd(MFC1); - break; - } - - case MFC_WrListStallAck: - { - if (v >= 32) - { - LOG_ERROR(Log::SPU, "MFC_WrListStallAck error: invalid tag(%d)", v); - return; - } - StalledList temp = StallList[v]; - if (!temp.MFCArgs) - { - LOG_ERROR(Log::SPU, "MFC_WrListStallAck error: empty tag(%d)", v); - return; - } - StallList[v].MFCArgs = nullptr; - ListCmd(temp.lsa, temp.ea, temp.tag, temp.size, temp.cmd, *temp.MFCArgs); - break; - } - - case SPU_WrDec: - { - m_dec_start = get_time(); - m_dec_value = v; - break; - } - - default: - { - LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); - break; - } - } - - if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]); - } - - void ReadChannel(SPU_GPR_hdr& r, u32 ch) - { - r.Reset(); - u32& v = r._u32[3]; - - switch(ch) - { - case SPU_RdInMbox: - { - while (!SPU.In_MBox.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case MFC_RdTagStat: - { - while (!MFC1.TagStatus.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case SPU_RdSigNotify1: - { - while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case SPU_RdSigNotify2: - { - while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case MFC_RdAtomicStat: - { - while (!MFC1.AtomicStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case MFC_RdListStallStat: - { - while (!StallStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } - - case SPU_RdDec: - { - v = m_dec_value - (u32)(get_time() - m_dec_start); - break; - } - - default: - { - LOG_ERROR(Log::SPU, "%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]); - break; - } - } - - if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]); - } - - void DoStop(u32 code) - { - SetExitStatus(code); // exit code (not status) - - switch (code) - { - case 0x110: /* ===== sys_spu_thread_receive_event ===== */ - { - u32 spuq = 0; - if (!SPU.Out_MBox.Pop(spuq)) - { - LOG_ERROR(Log::SPU, "sys_spu_thread_receive_event: cannot read Out_MBox"); - SPU.In_MBox.PushUncond(CELL_EINVAL); // ??? - return; - } - - if (SPU.In_MBox.GetCount()) - { - LOG_ERROR(Log::SPU, "sys_spu_thread_receive_event(spuq=0x%x): In_MBox is not empty", spuq); - SPU.In_MBox.PushUncond(CELL_EBUSY); // ??? - return; - } - - if (Ini.HLELogging.GetValue()) - { - LOG_NOTICE(Log::SPU, "sys_spu_thread_receive_event(spuq=0x%x)", spuq); - } - - EventQueue* eq; - if (!SPUQs.GetEventQueue(FIX_SPUQ(spuq), eq)) - { - SPU.In_MBox.PushUncond(CELL_EINVAL); // TODO: check error value - return; - } - - u32 tid = GetId(); - - eq->sq.push(tid); // add thread to sleep queue - - while (true) - { - switch (eq->owner.trylock(tid)) - { - case SMR_OK: - if (!eq->events.count()) - { - eq->owner.unlock(tid); - break; - } - else - { - u32 next = (eq->protocol == SYS_SYNC_FIFO) ? eq->sq.pop() : eq->sq.pop_prio(); - if (next != tid) - { - eq->owner.unlock(tid, next); - break; - } - } - case SMR_SIGNAL: - { - sys_event_data event; - eq->events.pop(event); - eq->owner.unlock(tid); - SPU.In_MBox.PushUncond(CELL_OK); - SPU.In_MBox.PushUncond(event.data1); - SPU.In_MBox.PushUncond(event.data2); - SPU.In_MBox.PushUncond(event.data3); - return; - } - case SMR_FAILED: break; - default: eq->sq.invalidate(tid); SPU.In_MBox.PushUncond(CELL_ECANCELED); return; - } - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - if (Emu.IsStopped()) - { - LOG_WARNING(Log::SPU, "sys_spu_thread_receive_event(spuq=0x%x) aborted", spuq); - eq->sq.invalidate(tid); - return; - } - } - } - break; - case 0x102: - if (!SPU.Out_MBox.GetCount()) - { - LOG_ERROR(Log::SPU, "sys_spu_thread_exit (no status, code 0x102)"); - } - else if (Ini.HLELogging.GetValue()) - { - // the real exit status - LOG_NOTICE(Log::SPU, "sys_spu_thread_exit (status=0x%x)", SPU.Out_MBox.GetValue()); - } - SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP); - Stop(); - break; - default: - if (!SPU.Out_MBox.GetCount()) - { - LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (no message)", code); - } - else - { - LOG_ERROR(Log::SPU, "Unknown STOP code: 0x%x (message=0x%x)", code, SPU.Out_MBox.GetValue()); - } - SPU.Status.SetValue(SPU_STATUS_STOPPED_BY_STOP); - Stop(); - break; - } - } + void StopAndSignal(u32 code); virtual u8 ReadLS8 (const u32 lsa) const { return Memory.Read8 (lsa + m_offset); } virtual u16 ReadLS16 (const u32 lsa) const { return Memory.Read16 (lsa + m_offset); } diff --git a/rpcs3/Emu/Event.cpp b/rpcs3/Emu/Event.cpp index d5065e2a98..5dce5b6884 100644 --- a/rpcs3/Emu/Event.cpp +++ b/rpcs3/Emu/Event.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" +//#include "Emu/System.h" #include "Event.h" void EventManager::Init() diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 1776343ce8..8263fa1acb 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -1,5 +1,5 @@ #include "stdafx.h" -#include "Utilities/Log.h" +#include #include "VFS.h" #include "Emu/HDD/HDD.h" diff --git a/rpcs3/Emu/FS/vfsDir.cpp b/rpcs3/Emu/FS/vfsDir.cpp index e648745fe8..aaec50c1ff 100644 --- a/rpcs3/Emu/FS/vfsDir.cpp +++ b/rpcs3/Emu/FS/vfsDir.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/System.h" #include "vfsDir.h" diff --git a/rpcs3/Emu/FS/vfsFile.cpp b/rpcs3/Emu/FS/vfsFile.cpp index f30a2de9a5..a44d0f63f2 100644 --- a/rpcs3/Emu/FS/vfsFile.cpp +++ b/rpcs3/Emu/FS/vfsFile.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/System.h" #include "vfsFile.h" diff --git a/rpcs3/Emu/FS/vfsStreamMemory.cpp b/rpcs3/Emu/FS/vfsStreamMemory.cpp index d8534193f0..102f4b3f8c 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.cpp +++ b/rpcs3/Emu/FS/vfsStreamMemory.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "vfsStreamMemory.h" @@ -32,7 +31,7 @@ u64 vfsStreamMemory::Write(const void* src, u64 size) size = GetSize() - Tell(); } - memcpy(Memory + m_addr + Tell(), (void*)src, size); + memcpy(Memory + (m_addr + Tell()), (void*)src, size); return vfsStream::Write(src, size); } @@ -44,7 +43,7 @@ u64 vfsStreamMemory::Read(void* dst, u64 size) size = GetSize() - Tell(); } - memcpy(dst, Memory + m_addr + Tell(), size); + memcpy(dst, Memory + (m_addr + Tell()), size); return vfsStream::Read(dst, size); } diff --git a/rpcs3/Emu/HDD/HDD.cpp b/rpcs3/Emu/HDD/HDD.cpp index 27927c3218..80eda63429 100644 --- a/rpcs3/Emu/HDD/HDD.cpp +++ b/rpcs3/Emu/HDD/HDD.cpp @@ -2,6 +2,337 @@ #include "Utilities/Log.h" #include "HDD.h" +void vfsHDDManager::CreateBlock(vfsHDD_Block& block) +{ + block.is_used = true; + block.next_block = 0; +} + +void vfsHDDManager::CreateEntry(vfsHDD_Entry& entry) +{ + memset(&entry, 0, sizeof(vfsHDD_Entry)); + u64 ctime = time(nullptr); + entry.atime = ctime; + entry.ctime = ctime; + entry.mtime = ctime; + entry.access = vfsReadWrite; + CreateBlock(entry); +} + +void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size) +{ + rFile f(path, rFile::write); + + static const u64 cur_dir_block = 1; + + vfsHDD_Hdr hdr; + CreateBlock(hdr); + hdr.next_block = cur_dir_block; + hdr.magic = g_hdd_magic; + hdr.version = g_hdd_version; + hdr.block_count = (size + block_size) / block_size; + hdr.block_size = block_size; + f.Write(&hdr, sizeof(vfsHDD_Hdr)); + + { + vfsHDD_Entry entry; + CreateEntry(entry); + entry.type = vfsHDD_Entry_Dir; + entry.data_block = hdr.next_block; + entry.next_block = 0; + + f.Seek(cur_dir_block * hdr.block_size); + f.Write(&entry, sizeof(vfsHDD_Entry)); + f.Write("."); + } + + u8 null = 0; + f.Seek(hdr.block_count * hdr.block_size - sizeof(null)); + f.Write(&null, sizeof(null)); +} + +void vfsHDDManager::Format() +{ +} + +void vfsHDDManager::AppendEntry(vfsHDD_Entry entry) +{ +} + +bool vfsHDDFile::goto_block(u64 n) +{ + vfsHDD_Block block_info; + + if (m_info.data_block >= m_hdd_info.block_count) + { + return false; + } + + m_hdd.Seek(m_info.data_block * m_hdd_info.block_size); + block_info.next_block = m_info.data_block; + + for (u64 i = 0; i= m_hdd_info.block_count) + { + return false; + } + + m_hdd.Seek(block_info.next_block * m_hdd_info.block_size); + m_hdd.Read(&block_info, sizeof(vfsHDD_Block)); + } + + return true; +} + +void vfsHDDFile::RemoveBlocks(u64 start_block) +{ + vfsHDD_Block block_info; + block_info.next_block = start_block; + + while (block_info.next_block && block_info.is_used) + { + u64 offset = block_info.next_block * m_hdd_info.block_size; + + ReadBlock(offset, block_info); + WriteBlock(offset, g_null_block); + } +} + +void vfsHDDFile::WriteBlock(u64 block, const vfsHDD_Block& data) +{ + m_hdd.Seek(block * m_hdd_info.block_size); + m_hdd.Write(&data, sizeof(vfsHDD_Block)); +} + +void vfsHDDFile::ReadBlock(u64 block, vfsHDD_Block& data) +{ + m_hdd.Seek(block * m_hdd_info.block_size); + m_hdd.Read(&data, sizeof(vfsHDD_Block)); +} + +void vfsHDDFile::WriteEntry(u64 block, const vfsHDD_Entry& data) +{ + m_hdd.Seek(block * m_hdd_info.block_size); + m_hdd.Write(&data, sizeof(vfsHDD_Entry)); +} + +void vfsHDDFile::ReadEntry(u64 block, vfsHDD_Entry& data) +{ + m_hdd.Seek(block * m_hdd_info.block_size); + m_hdd.Read(&data, sizeof(vfsHDD_Entry)); +} + +void vfsHDDFile::ReadEntry(u64 block, vfsHDD_Entry& data, std::string& name) +{ + m_hdd.Seek(block * m_hdd_info.block_size); + m_hdd.Read(&data, sizeof(vfsHDD_Entry)); + name.resize(GetMaxNameLen()); + m_hdd.Read(&name.front(), GetMaxNameLen()); +} + +void vfsHDDFile::ReadEntry(u64 block, std::string& name) +{ + m_hdd.Seek(block * m_hdd_info.block_size + sizeof(vfsHDD_Entry)); + name.resize(GetMaxNameLen()); + m_hdd.Read(&name.front(), GetMaxNameLen()); +} + +void vfsHDDFile::WriteEntry(u64 block, const vfsHDD_Entry& data, const std::string& name) +{ + m_hdd.Seek(block * m_hdd_info.block_size); + m_hdd.Write(&data, sizeof(vfsHDD_Entry)); + m_hdd.Write(name.c_str(), std::min(GetMaxNameLen() - 1, name.length() + 1)); +} + +void vfsHDDFile::Open(u64 info_block) +{ + m_info_block = info_block; + ReadEntry(m_info_block, m_info); + m_position = 0; + m_cur_block = m_info.data_block; +} + +u64 vfsHDDFile::FindFreeBlock() +{ + vfsHDD_Block block_info; + + for (u64 i = 0; i(block_size - m_position, size); + + vfsHDD_Block cur_block_info; + m_hdd.Seek(m_cur_block * m_hdd_info.block_size); + m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block)); + m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block)+m_position); + m_hdd.Read(dst, rsize); + size -= rsize; + m_position += rsize; + if (!size) + { + return rsize; + } + + u64 offset = rsize; + + for (; size; size -= rsize, offset += rsize) + { + if (!cur_block_info.is_used || !cur_block_info.next_block || cur_block_info.next_block >= m_hdd_info.block_count) + { + return offset; + } + + m_cur_block = cur_block_info.next_block; + rsize = std::min(block_size, size); + + m_hdd.Seek(cur_block_info.next_block * m_hdd_info.block_size); + m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block)); + + if (m_hdd.Read((u8*)dst + offset, rsize) != rsize) + { + return offset; + } + } + + m_position = rsize; + + return offset; +} + +u64 vfsHDDFile::Write(const void* src, u64 size) +{ + if (!size) + return 0; + + //vfsDeviceLocker lock(m_hdd); + + const u32 block_size = m_hdd_info.block_size - sizeof(vfsHDD_Block); + + if (!m_cur_block) + { + if (!m_info.data_block) + { + u64 new_block = FindFreeBlock(); + + if (!new_block) + { + return 0; + } + + WriteBlock(new_block, g_used_block); + m_info.data_block = new_block; + m_info.size = 0; + SaveInfo(); + } + + m_cur_block = m_info.data_block; + m_position = 0; + } + + u64 wsize = std::min(block_size - m_position, size); + + vfsHDD_Block block_info; + ReadBlock(m_cur_block, block_info); + + if (wsize) + { + m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block)+m_position); + m_hdd.Write(src, wsize); + size -= wsize; + m_info.size += wsize; + m_position += wsize; + SaveInfo(); + + if (!size) + return wsize; + } + + u64 last_block = m_cur_block; + block_info.is_used = true; + u64 offset = wsize; + + for (; size; size -= wsize, offset += wsize, m_info.size += wsize) + { + u64 new_block = FindFreeBlock(); + + if (!new_block) + { + m_position = 0; + SaveInfo(); + return offset; + } + + m_cur_block = new_block; + wsize = std::min(block_size, size); + + block_info.next_block = m_cur_block; + m_hdd.Seek(last_block * m_hdd_info.block_size); + if (m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block)) + { + m_position = 0; + SaveInfo(); + return offset; + } + + block_info.next_block = 0; + m_hdd.Seek(m_cur_block * m_hdd_info.block_size); + if (m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block)) + { + m_position = 0; + SaveInfo(); + return offset; + } + if ((m_position = m_hdd.Write((u8*)src + offset, wsize)) != wsize) + { + m_info.size += wsize; + SaveInfo(); + return offset; + } + + last_block = m_cur_block; + } + + SaveInfo(); + m_position = wsize; + return offset; +} + vfsDeviceHDD::vfsDeviceHDD(const std::string& hdd_path) : m_hdd_path(hdd_path) { } @@ -15,3 +346,438 @@ vfsDirBase* vfsDeviceHDD::GetNewDirStream() { return nullptr; } + +vfsHDD::vfsHDD(vfsDevice* device, const std::string& hdd_path) + : m_hdd_file(device) + , m_file(m_hdd_file, m_hdd_info) + , m_hdd_path(hdd_path) + , vfsFileBase(device) +{ + m_hdd_file.Open(hdd_path, vfsReadWrite); + m_hdd_file.Read(&m_hdd_info, sizeof(vfsHDD_Hdr)); + m_cur_dir_block = m_hdd_info.next_block; + if (!m_hdd_info.block_size) + { + LOG_ERROR(HLE, "Bad block size!"); + m_hdd_info.block_size = 2048; + } + m_hdd_file.Seek(m_cur_dir_block * m_hdd_info.block_size); + m_hdd_file.Read(&m_cur_dir, sizeof(vfsHDD_Entry)); +} + +bool vfsHDD::SearchEntry(const std::string& name, u64& entry_block, u64* parent_block) +{ + u64 last_block = 0; + u64 block = m_cur_dir_block; + vfsHDD_Entry entry; + std::string buf; + + while (block) + { + ReadEntry(block, entry, buf); + + if (fmt::CmpNoCase(name, buf) == 0) + { + entry_block = block; + if (parent_block) + *parent_block = last_block; + + return true; + } + + last_block = block; + block = entry.is_used ? entry.next_block : 0ULL; + } + + return false; +} + +int vfsHDD::OpenDir(const std::string& name) +{ + LOG_WARNING(HLE, "OpenDir(%s)", name.c_str()); + u64 entry_block; + if (!SearchEntry(name, entry_block)) + return -1; + + m_hdd_file.Seek(entry_block * m_hdd_info.block_size); + vfsHDD_Entry entry; + m_hdd_file.Read(&entry, sizeof(vfsHDD_Entry)); + if (entry.type == vfsHDD_Entry_File) + return 1; + + m_cur_dir_block = entry.data_block; + ReadEntry(m_cur_dir_block, m_cur_dir); + + return 0; +} + +bool vfsHDD::Rename(const std::string& from, const std::string& to) +{ + u64 entry_block; + if (!SearchEntry(from, entry_block)) + { + return false; + } + + vfsHDD_Entry entry; + ReadEntry(entry_block, entry); + WriteEntry(entry_block, entry, to); + + return true; +} + +u64 vfsHDD::FindFreeBlock() +{ + vfsHDD_Block block_info; + + for (u64 i = 0; i(GetMaxNameLen() - 1, name.length() + 1)); +} + +bool vfsHDD::Create(vfsHDD_EntryType type, const std::string& name) +{ + if (HasEntry(name)) + { + return false; + } + + u64 new_block = FindFreeBlock(); + if (!new_block) + { + return false; + } + + LOG_NOTICE(HLE, "CREATING ENTRY AT 0x%llx", new_block); + WriteBlock(new_block, g_used_block); + + { + vfsHDD_Entry new_entry; + vfsHDDManager::CreateEntry(new_entry); + new_entry.next_block = 0; + new_entry.type = type; + + if (type == vfsHDD_Entry_Dir) + { + u64 block_cur = FindFreeBlock(); + + if (!block_cur) + { + return false; + } + + WriteBlock(block_cur, g_used_block); + + u64 block_last = FindFreeBlock(); + + if (!block_last) + { + return false; + } + + WriteBlock(block_last, g_used_block); + + vfsHDD_Entry entry_cur, entry_last; + vfsHDDManager::CreateEntry(entry_cur); + vfsHDDManager::CreateEntry(entry_last); + + entry_cur.type = vfsHDD_Entry_Dir; + entry_cur.data_block = block_cur; + entry_cur.next_block = block_last; + + entry_last.type = vfsHDD_Entry_Dir; + entry_last.data_block = m_cur_dir_block; + entry_last.next_block = 0; + + new_entry.data_block = block_cur; + + WriteEntry(block_cur, entry_cur, "."); + WriteEntry(block_last, entry_last, ".."); + } + + WriteEntry(new_block, new_entry, name); + } + + { + u64 block = m_cur_dir_block; + + vfsHDD_Block tmp; + while (block) + { + ReadBlock(block, tmp); + + if (!tmp.next_block) + break; + + block = tmp.next_block; + } + + tmp.next_block = new_block; + WriteBlock(block, tmp); + } + + return true; +} + +bool vfsHDD::GetFirstEntry(u64& block, vfsHDD_Entry& entry, std::string& name) +{ + if (!m_cur_dir_block) + { + return false; + } + + ReadEntry(m_cur_dir_block, entry, name); + block = entry.is_used ? entry.next_block : 0; + + return true; +} + +bool vfsHDD::GetNextEntry(u64& block, vfsHDD_Entry& entry, std::string& name) +{ + if (!block) + { + return false; + } + + ReadEntry(block, entry, name); + + block = entry.is_used ? entry.next_block : 0; + return true; +} + +bool vfsHDD::Open(const std::string& path, vfsOpenMode mode) +{ + const char* s = path.c_str(); + u64 from = 0; + u64 pos = 0; + u64 file_pos = -1; + + do + { + if (s[pos] == '\\' || s[pos] == '/' || s[pos] == '\0') // ??? + { + if (file_pos != -1) + { + return false; + } + + if (from != -1) + { + if (pos - from > 1) + { + int res = OpenDir(std::string(s + from, pos)); + if (res == -1) + { + return false; + } + + if (res == 1) + { + file_pos = from; + } + } + + from = pos; + } + else + { + from = pos; + } + } + } while (s[pos++] != '\0'); + + if (file_pos == -1) + { + return false; + } + + u64 file_block; + if (!SearchEntry(std::string(s + file_pos), file_block)) + { + return false; + } + + LOG_NOTICE(HLE, "ENTRY FOUND AT 0x%llx", file_block); + m_file.Open(file_block); + + return vfsFileBase::Open(path, mode); +} + +bool vfsHDD::HasEntry(const std::string& name) +{ + u64 file_block; + if (!SearchEntry(name, file_block)) + { + return false; + } + + return true; +} + +void vfsHDD::RemoveBlocksDir(u64 start_block) +{ + std::string name; + u64 block = start_block; + vfsHDD_Entry entry; + + while (block) + { + ReadEntry(block, entry, name); + WriteBlock(block, g_null_block); + + if (entry.type == vfsHDD_Entry_Dir && name != "." && name != "..") + { + LOG_WARNING(HLE, "Removing sub folder '%s'", name.c_str()); + RemoveBlocksDir(entry.data_block); + } + else if (entry.type == vfsHDD_Entry_File) + { + RemoveBlocksFile(entry.data_block); + } + + block = entry.next_block; + } +} + +void vfsHDD::RemoveBlocksFile(u64 start_block) +{ + u64 block = start_block; + vfsHDD_Block block_data; + + while (block) + { + ReadBlock(block, block_data); + WriteBlock(block, g_null_block); + + block = block_data.next_block; + } +} + +bool vfsHDD::RemoveEntry(const std::string& name) +{ + u64 entry_block, parent_entry; + if (!SearchEntry(name, entry_block, &parent_entry)) + { + return false; + } + + vfsHDD_Entry entry; + ReadEntry(entry_block, entry); + if (entry.type == vfsHDD_Entry_Dir) + { + RemoveBlocksDir(entry.data_block); + } + else if (entry.type == vfsHDD_Entry_File) + { + RemoveBlocksFile(entry.data_block); + } + + if (parent_entry) + { + u64 next = entry.next_block; + ReadEntry(parent_entry, entry); + entry.next_block = next; + WriteEntry(parent_entry, entry); + } + WriteBlock(entry_block, g_null_block); + return true; +} + +bool vfsHDD::Create(const std::string& path) +{ + return false; +} + +u32 vfsHDD::Write(const void* src, u32 size) +{ + return vfsFileBase::Write(src, m_file.Write(src, size)); +} + +u32 vfsHDD::Read(void* dst, u32 size) +{ + return vfsFileBase::Read(dst, m_file.Read(dst, size)); +} + +u64 vfsHDD::Seek(s64 offset, vfsSeekMode mode) +{ + switch (mode) + { + case vfsSeekCur: + m_file.Seek(Tell() + offset); + break; + + case vfsSeekSet: + m_file.Seek(offset); + break; + + case vfsSeekEnd: + m_file.Seek(m_file.GetSize() + offset); + break; + } + + return vfsFileBase::Seek(offset, mode); +} + +bool vfsHDD::Eof() +{ + return m_file.Eof(); +} + +u64 vfsHDD::GetSize() +{ + return m_file.GetSize(); +} \ No newline at end of file diff --git a/rpcs3/Emu/HDD/HDD.h b/rpcs3/Emu/HDD/HDD.h index d68f8dbbfc..1c7cba7c5f 100644 --- a/rpcs3/Emu/HDD/HDD.h +++ b/rpcs3/Emu/HDD/HDD.h @@ -44,62 +44,15 @@ struct vfsHDD_Entry : public vfsHDD_Block class vfsHDDManager { public: - static void CreateBlock(vfsHDD_Block& block) - { - block.is_used = true; - block.next_block = 0; - } + static void CreateBlock(vfsHDD_Block& block); - static void CreateEntry(vfsHDD_Entry& entry) - { - memset(&entry, 0, sizeof(vfsHDD_Entry)); - u64 ctime = time(nullptr); - entry.atime = ctime; - entry.ctime = ctime; - entry.mtime = ctime; - entry.access = vfsReadWrite; - CreateBlock(entry); - } + static void CreateEntry(vfsHDD_Entry& entry); - static void CreateHDD(const std::string& path, u64 size, u64 block_size) - { - rFile f(path, rFile::write); + static void CreateHDD(const std::string& path, u64 size, u64 block_size); - static const u64 cur_dir_block = 1; + void Format(); - vfsHDD_Hdr hdr; - CreateBlock(hdr); - hdr.next_block = cur_dir_block; - hdr.magic = g_hdd_magic; - hdr.version = g_hdd_version; - hdr.block_count = (size + block_size) / block_size; - hdr.block_size = block_size; - f.Write(&hdr, sizeof(vfsHDD_Hdr)); - - { - vfsHDD_Entry entry; - CreateEntry(entry); - entry.type = vfsHDD_Entry_Dir; - entry.data_block = hdr.next_block; - entry.next_block = 0; - - f.Seek(cur_dir_block * hdr.block_size); - f.Write(&entry, sizeof(vfsHDD_Entry)); - f.Write("."); - } - - u8 null = 0; - f.Seek(hdr.block_count * hdr.block_size - sizeof(null)); - f.Write(&null, sizeof(null)); - } - - void Format() - { - } - - void AppendEntry(vfsHDD_Entry entry) - { - } + void AppendEntry(vfsHDD_Entry entry); }; @@ -112,91 +65,23 @@ class vfsHDDFile u32 m_position; u64 m_cur_block; - bool goto_block(u64 n) - { - vfsHDD_Block block_info; + bool goto_block(u64 n); - if(m_info.data_block >= m_hdd_info.block_count) - { - return false; - } + void RemoveBlocks(u64 start_block); - m_hdd.Seek(m_info.data_block * m_hdd_info.block_size); - block_info.next_block = m_info.data_block; + void WriteBlock(u64 block, const vfsHDD_Block& data); - for(u64 i=0; i= m_hdd_info.block_count) - { - return false; - } + void ReadBlock(u64 block, vfsHDD_Block& data); - m_hdd.Seek(block_info.next_block * m_hdd_info.block_size); - m_hdd.Read(&block_info, sizeof(vfsHDD_Block)); - } + void WriteEntry(u64 block, const vfsHDD_Entry& data); - return true; - } + void ReadEntry(u64 block, vfsHDD_Entry& data); - void RemoveBlocks(u64 start_block) - { - vfsHDD_Block block_info; - block_info.next_block = start_block; + void ReadEntry(u64 block, vfsHDD_Entry& data, std::string& name); - while(block_info.next_block && block_info.is_used) - { - u64 offset = block_info.next_block * m_hdd_info.block_size; + void ReadEntry(u64 block, std::string& name); - ReadBlock(offset, block_info); - WriteBlock(offset, g_null_block); - } - } - - void WriteBlock(u64 block, const vfsHDD_Block& data) - { - m_hdd.Seek(block * m_hdd_info.block_size); - m_hdd.Write(&data, sizeof(vfsHDD_Block)); - } - - void ReadBlock(u64 block, vfsHDD_Block& data) - { - m_hdd.Seek(block * m_hdd_info.block_size); - m_hdd.Read(&data, sizeof(vfsHDD_Block)); - } - - void WriteEntry(u64 block, const vfsHDD_Entry& data) - { - m_hdd.Seek(block * m_hdd_info.block_size); - m_hdd.Write(&data, sizeof(vfsHDD_Entry)); - } - - void ReadEntry(u64 block, vfsHDD_Entry& data) - { - m_hdd.Seek(block * m_hdd_info.block_size); - m_hdd.Read(&data, sizeof(vfsHDD_Entry)); - } - - void ReadEntry(u64 block, vfsHDD_Entry& data, std::string& name) - { - m_hdd.Seek(block * m_hdd_info.block_size); - m_hdd.Read(&data, sizeof(vfsHDD_Entry)); - name.resize(GetMaxNameLen()); - m_hdd.Read(&name.front(), GetMaxNameLen()); - } - - void ReadEntry(u64 block, std::string& name) - { - m_hdd.Seek(block * m_hdd_info.block_size + sizeof(vfsHDD_Entry)); - name.resize(GetMaxNameLen()); - m_hdd.Read(&name.front(), GetMaxNameLen()); - } - - void WriteEntry(u64 block, const vfsHDD_Entry& data, const std::string& name) - { - m_hdd.Seek(block * m_hdd_info.block_size); - m_hdd.Write(&data, sizeof(vfsHDD_Entry)); - m_hdd.Write(name.c_str(), std::min(GetMaxNameLen() - 1, name.length() + 1)); - } + void WriteEntry(u64 block, const vfsHDD_Entry& data, const std::string& name); __forceinline u32 GetMaxNameLen() const { @@ -214,198 +99,22 @@ public: { } - void Open(u64 info_block) - { - m_info_block = info_block; - ReadEntry(m_info_block, m_info); - m_position = 0; - m_cur_block = m_info.data_block; - } + void Open(u64 info_block); - u64 FindFreeBlock() - { - vfsHDD_Block block_info; - - for(u64 i = 0; i(block_size - m_position, size); - - vfsHDD_Block cur_block_info; - m_hdd.Seek(m_cur_block * m_hdd_info.block_size); - m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block)); - m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block) + m_position); - m_hdd.Read(dst, rsize); - size -= rsize; - m_position += rsize; - if(!size) - { - return rsize; - } - - u64 offset = rsize; - - for(; size; size -= rsize, offset += rsize) - { - if(!cur_block_info.is_used || !cur_block_info.next_block || cur_block_info.next_block >= m_hdd_info.block_count) - { - return offset; - } - - m_cur_block = cur_block_info.next_block; - rsize = std::min(block_size, size); - - m_hdd.Seek(cur_block_info.next_block * m_hdd_info.block_size); - m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block)); - - if(m_hdd.Read((u8*)dst + offset, rsize) != rsize) - { - return offset; - } - } - - m_position = rsize; - - return offset; - } - - u64 Write(const void* src, u64 size) - { - if(!size) - return 0; - - //vfsDeviceLocker lock(m_hdd); - - const u32 block_size = m_hdd_info.block_size - sizeof(vfsHDD_Block); - - if(!m_cur_block) - { - if(!m_info.data_block) - { - u64 new_block = FindFreeBlock(); - - if(!new_block) - { - return 0; - } - - WriteBlock(new_block, g_used_block); - m_info.data_block = new_block; - m_info.size = 0; - SaveInfo(); - } - - m_cur_block = m_info.data_block; - m_position = 0; - } - - u64 wsize = std::min(block_size - m_position, size); - - vfsHDD_Block block_info; - ReadBlock(m_cur_block, block_info); - - if(wsize) - { - m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block) + m_position); - m_hdd.Write(src, wsize); - size -= wsize; - m_info.size += wsize; - m_position += wsize; - SaveInfo(); - - if(!size) - return wsize; - } - - u64 last_block = m_cur_block; - block_info.is_used = true; - u64 offset = wsize; - - for(; size; size -= wsize, offset += wsize, m_info.size += wsize) - { - u64 new_block = FindFreeBlock(); - - if(!new_block) - { - m_position = 0; - SaveInfo(); - return offset; - } - - m_cur_block = new_block; - wsize = std::min(block_size, size); - - block_info.next_block = m_cur_block; - m_hdd.Seek(last_block * m_hdd_info.block_size); - if(m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block)) - { - m_position = 0; - SaveInfo(); - return offset; - } - - block_info.next_block = 0; - m_hdd.Seek(m_cur_block * m_hdd_info.block_size); - if(m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block)) - { - m_position = 0; - SaveInfo(); - return offset; - } - if((m_position = m_hdd.Write((u8*)src + offset, wsize)) != wsize) - { - m_info.size += wsize; - SaveInfo(); - return offset; - } - - last_block = m_cur_block; - } - - SaveInfo(); - m_position = wsize; - return offset; - } + u64 Write(const void* src, u64 size); bool Eof() const { @@ -434,444 +143,60 @@ class vfsHDD : public vfsFileBase vfsHDDFile m_file; public: - vfsHDD(vfsDevice* device, const std::string& hdd_path) - : m_hdd_file(device) - , m_file(m_hdd_file, m_hdd_info) - , m_hdd_path(hdd_path) - , vfsFileBase(device) - { - m_hdd_file.Open(hdd_path, vfsReadWrite); - m_hdd_file.Read(&m_hdd_info, sizeof(vfsHDD_Hdr)); - m_cur_dir_block = m_hdd_info.next_block; - if(!m_hdd_info.block_size) - { - LOG_ERROR(HLE, "Bad block size!"); - m_hdd_info.block_size = 2048; - } - m_hdd_file.Seek(m_cur_dir_block * m_hdd_info.block_size); - m_hdd_file.Read(&m_cur_dir, sizeof(vfsHDD_Entry)); - } + vfsHDD(vfsDevice* device, const std::string& hdd_path); __forceinline u32 GetMaxNameLen() const { return m_hdd_info.block_size - sizeof(vfsHDD_Entry); } - bool SearchEntry(const std::string& name, u64& entry_block, u64* parent_block = nullptr) - { - u64 last_block = 0; - u64 block = m_cur_dir_block; - vfsHDD_Entry entry; - std::string buf; + bool SearchEntry(const std::string& name, u64& entry_block, u64* parent_block = nullptr); - while(block) - { - ReadEntry(block, entry, buf); + int OpenDir(const std::string& name); - if (fmt::CmpNoCase(name,buf) == 0) - { - entry_block = block; - if(parent_block) - *parent_block = last_block; + bool Rename(const std::string& from, const std::string& to); - return true; - } + u64 FindFreeBlock(); - last_block = block; - block = entry.is_used ? entry.next_block : 0ULL; - } + void WriteBlock(u64 block, const vfsHDD_Block& data); - return false; - } + void ReadBlock(u64 block, vfsHDD_Block& data); - int OpenDir(const std::string& name) - { - LOG_WARNING(HLE, "OpenDir(%s)", name.c_str()); - u64 entry_block; - if(!SearchEntry(name, entry_block)) - return -1; + void WriteEntry(u64 block, const vfsHDD_Entry& data); - m_hdd_file.Seek(entry_block * m_hdd_info.block_size); - vfsHDD_Entry entry; - m_hdd_file.Read(&entry, sizeof(vfsHDD_Entry)); - if(entry.type == vfsHDD_Entry_File) - return 1; + void ReadEntry(u64 block, vfsHDD_Entry& data); - m_cur_dir_block = entry.data_block; - ReadEntry(m_cur_dir_block, m_cur_dir); + void ReadEntry(u64 block, vfsHDD_Entry& data, std::string& name); - return 0; - } + void ReadEntry(u64 block, std::string& name); - bool Rename(const std::string& from, const std::string& to) - { - u64 entry_block; - if(!SearchEntry(from, entry_block)) - { - return false; - } + void WriteEntry(u64 block, const vfsHDD_Entry& data, const std::string& name); - vfsHDD_Entry entry; - ReadEntry(entry_block, entry); - WriteEntry(entry_block, entry, to); + bool Create(vfsHDD_EntryType type, const std::string& name); - return true; - } + bool GetFirstEntry(u64& block, vfsHDD_Entry& entry, std::string& name); - u64 FindFreeBlock() - { - vfsHDD_Block block_info; + bool GetNextEntry(u64& block, vfsHDD_Entry& entry, std::string& name); - for(u64 i = 0; i(GetMaxNameLen() - 1, name.length() + 1)); - } + virtual bool Eof(); - bool Create(vfsHDD_EntryType type, const std::string& name) - { - if(HasEntry(name)) - { - return false; - } - - u64 new_block = FindFreeBlock(); - if(!new_block) - { - return false; - } - - LOG_NOTICE(HLE, "CREATING ENTRY AT 0x%llx", new_block); - WriteBlock(new_block, g_used_block); - - { - vfsHDD_Entry new_entry; - vfsHDDManager::CreateEntry(new_entry); - new_entry.next_block = 0; - new_entry.type = type; - - if(type == vfsHDD_Entry_Dir) - { - u64 block_cur = FindFreeBlock(); - - if(!block_cur) - { - return false; - } - - WriteBlock(block_cur, g_used_block); - - u64 block_last = FindFreeBlock(); - - if(!block_last) - { - return false; - } - - WriteBlock(block_last, g_used_block); - - vfsHDD_Entry entry_cur, entry_last; - vfsHDDManager::CreateEntry(entry_cur); - vfsHDDManager::CreateEntry(entry_last); - - entry_cur.type = vfsHDD_Entry_Dir; - entry_cur.data_block = block_cur; - entry_cur.next_block = block_last; - - entry_last.type = vfsHDD_Entry_Dir; - entry_last.data_block = m_cur_dir_block; - entry_last.next_block = 0; - - new_entry.data_block = block_cur; - - WriteEntry(block_cur, entry_cur, "."); - WriteEntry(block_last, entry_last, ".."); - } - - WriteEntry(new_block, new_entry, name); - } - - { - u64 block = m_cur_dir_block; - - vfsHDD_Block tmp; - while(block) - { - ReadBlock(block, tmp); - - if(!tmp.next_block) - break; - - block = tmp.next_block; - } - - tmp.next_block = new_block; - WriteBlock(block, tmp); - } - - return true; - } - - bool GetFirstEntry(u64& block, vfsHDD_Entry& entry, std::string& name) - { - if(!m_cur_dir_block) - { - return false; - } - - ReadEntry(m_cur_dir_block, entry, name); - block = entry.is_used ? entry.next_block : 0; - - return true; - } - - bool GetNextEntry(u64& block, vfsHDD_Entry& entry, std::string& name) - { - if(!block) - { - return false; - } - - ReadEntry(block, entry, name); - - block = entry.is_used ? entry.next_block : 0; - return true; - } - - virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead) - { - const char* s = path.c_str(); - u64 from = 0; - u64 pos = 0; - u64 file_pos = -1; - - do - { - if(s[pos] == '\\' || s[pos] == '/' || s[pos] == '\0') // ??? - { - if(file_pos != -1) - { - return false; - } - - if(from != -1) - { - if(pos - from > 1) - { - int res = OpenDir(std::string(s + from, pos)); - if(res == -1) - { - return false; - } - - if(res == 1) - { - file_pos = from; - } - } - - from = pos; - } - else - { - from = pos; - } - } - } - while(s[pos++] != '\0'); - - if(file_pos == -1) - { - return false; - } - - u64 file_block; - if(!SearchEntry(std::string(s + file_pos), file_block)) - { - return false; - } - - LOG_NOTICE(HLE, "ENTRY FOUND AT 0x%llx", file_block); - m_file.Open(file_block); - - return vfsFileBase::Open(path, mode); - } - - bool HasEntry(const std::string& name) - { - u64 file_block; - if(!SearchEntry(name, file_block)) - { - return false; - } - - return true; - } - - void RemoveBlocksDir(u64 start_block) - { - std::string name; - u64 block = start_block; - vfsHDD_Entry entry; - - while(block) - { - ReadEntry(block, entry, name); - WriteBlock(block, g_null_block); - - if(entry.type == vfsHDD_Entry_Dir && name != "." && name != "..") - { - LOG_WARNING(HLE, "Removing sub folder '%s'", name.c_str()); - RemoveBlocksDir(entry.data_block); - } - else if(entry.type == vfsHDD_Entry_File) - { - RemoveBlocksFile(entry.data_block); - } - - block = entry.next_block; - } - } - - void RemoveBlocksFile(u64 start_block) - { - u64 block = start_block; - vfsHDD_Block block_data; - - while(block) - { - ReadBlock(block, block_data); - WriteBlock(block, g_null_block); - - block = block_data.next_block; - } - } - - bool RemoveEntry(const std::string& name) - { - u64 entry_block, parent_entry; - if(!SearchEntry(name, entry_block, &parent_entry)) - { - return false; - } - - vfsHDD_Entry entry; - ReadEntry(entry_block, entry); - if(entry.type == vfsHDD_Entry_Dir) - { - RemoveBlocksDir(entry.data_block); - } - else if(entry.type == vfsHDD_Entry_File) - { - RemoveBlocksFile(entry.data_block); - } - - if(parent_entry) - { - u64 next = entry.next_block; - ReadEntry(parent_entry, entry); - entry.next_block = next; - WriteEntry(parent_entry, entry); - } - WriteBlock(entry_block, g_null_block); - return true; - } - - virtual bool Create(const std::string& path) - { - return false; - } - - virtual u32 Write(const void* src, u32 size) - { - return vfsFileBase::Write(src, m_file.Write(src, size)); - } - - virtual u32 Read(void* dst, u32 size) - { - return vfsFileBase::Read(dst, m_file.Read(dst, size)); - } - - virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet) - { - switch(mode) - { - case vfsSeekCur: - m_file.Seek(Tell() + offset); - break; - - case vfsSeekSet: - m_file.Seek(offset); - break; - - case vfsSeekEnd: - m_file.Seek(m_file.GetSize() + offset); - break; - } - - return vfsFileBase::Seek(offset, mode); - } - - virtual bool Eof() - { - return m_file.Eof(); - } - - virtual u64 GetSize() - { - return m_file.GetSize(); - } + virtual u64 GetSize(); }; diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index b1170cce04..b985f886cc 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -1,5 +1,6 @@ #pragma once #include +#include #define rID_ANY -1 // was wxID_ANY diff --git a/rpcs3/Emu/Io/Keyboard.cpp b/rpcs3/Emu/Io/Keyboard.cpp index 03b0a72a50..f63c5530ca 100644 --- a/rpcs3/Emu/Io/Keyboard.cpp +++ b/rpcs3/Emu/Io/Keyboard.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "rpcs3/Ini.h" #include "Keyboard.h" #include "Null/NullKeyboardHandler.h" diff --git a/rpcs3/Emu/Io/Mouse.cpp b/rpcs3/Emu/Io/Mouse.cpp index 3c9d569125..fc0112e5e0 100644 --- a/rpcs3/Emu/Io/Mouse.cpp +++ b/rpcs3/Emu/Io/Mouse.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "rpcs3/Ini.h" #include "Mouse.h" #include "Null/NullMouseHandler.h" diff --git a/rpcs3/Emu/Io/Pad.cpp b/rpcs3/Emu/Io/Pad.cpp index 0e29f5a85b..55cdbf0e91 100644 --- a/rpcs3/Emu/Io/Pad.cpp +++ b/rpcs3/Emu/Io/Pad.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "rpcs3/Ini.h" #include "Pad.h" #include "Null/NullPadHandler.h" diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h index 053f28086c..edd1280808 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.h @@ -170,12 +170,12 @@ bool DynamicMemoryBlockBase::Free(u64 addr) } } - LOG_ERROR(MEMORY, "DynamicMemoryBlock::Free(addr=0x%llx): failed", addr); - for (u32 i = 0; i < m_allocated.size(); i++) - { - LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size); - } - assert(0); + //LOG_ERROR(MEMORY, "DynamicMemoryBlock::Free(addr=0x%llx): failed", addr); + //for (u32 i = 0; i < m_allocated.size(); i++) + //{ + // LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size); + //} + assert(!"DynamicMemoryBlock::Free() failed"); return false; } @@ -189,7 +189,6 @@ template bool DynamicMemoryBlockBase::IsLocked(u64 addr) { // TODO - LOG_ERROR(MEMORY, "IsLocked(0x%llx) not implemented", addr); assert(0); return false; } @@ -198,7 +197,6 @@ template bool DynamicMemoryBlockBase::Lock(u64 addr, u32 size) { // TODO - LOG_ERROR(MEMORY, "Lock(0x%llx, 0x%x) not implemented", addr, size); assert(0); return false; } @@ -207,7 +205,6 @@ template bool DynamicMemoryBlockBase::Unlock(u64 addr, u32 size) { // TODO - LOG_ERROR(MEMORY, "Unlock(0x%llx, 0x%x) not implemented", addr, size); assert(0); return false; } diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 8fbae6c536..79c6f293cb 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -4,10 +4,219 @@ #include "Utilities/Log.h" #include "Memory.h" #include "Emu/System.h" -#include "Ini.h" + +#ifndef _WIN32 +#include +#endif + +/* OS X uses MAP_ANON instead of MAP_ANONYMOUS */ +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif MemoryBase Memory; +void MemoryBase::InvalidAddress(const char* func, const u64 addr) +{ + LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", func, addr); +} + +void MemoryBase::RegisterPages(u64 addr, u32 size) +{ + std::lock_guard lock(m_mutex); + + //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size); + for (u64 i = addr / 4096; i < (addr + size) / 4096; i++) + { + if (i >= sizeof(m_pages) / sizeof(m_pages[0])) + { + InvalidAddress(__FUNCTION__, i * 4096); + break; + } + if (m_pages[i]) + { + LOG_ERROR(MEMORY, "Page already registered (addr=0x%llx)", i * 4096); + } + m_pages[i] = 1; // TODO: define page parameters + } +} + +void MemoryBase::UnregisterPages(u64 addr, u32 size) +{ + std::lock_guard lock(m_mutex); + + //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size); + for (u64 i = addr / 4096; i < (addr + size) / 4096; i++) + { + if (i >= sizeof(m_pages) / sizeof(m_pages[0])) + { + InvalidAddress(__FUNCTION__, i * 4096); + break; + } + if (!m_pages[i]) + { + LOG_ERROR(MEMORY, "Page not registered (addr=0x%llx)", i * 4096); + } + m_pages[i] = 0; // TODO: define page parameters + } +} + +u32 MemoryBase::InitRawSPU(MemoryBlock* raw_spu) +{ + std::lock_guard lock(m_mutex); + + u32 index; + for (index = 0; index < sizeof(RawSPUMem) / sizeof(RawSPUMem[0]); index++) + { + if (!RawSPUMem[index]) + { + RawSPUMem[index] = raw_spu; + break; + } + } + + MemoryBlocks.push_back(raw_spu->SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_PROB_OFFSET)); + return index; +} + +void MemoryBase::CloseRawSPU(MemoryBlock* raw_spu, const u32 num) +{ + std::lock_guard lock(m_mutex); + + for (int i = 0; i < MemoryBlocks.size(); ++i) + { + if (MemoryBlocks[i] == raw_spu) + { + MemoryBlocks.erase(MemoryBlocks.begin() + i); + break; + } + } + if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = nullptr; +} + +void MemoryBase::Init(MemoryType type) +{ + std::lock_guard lock(m_mutex); + + if (m_inited) return; + m_inited = true; + + memset(m_pages, 0, sizeof(m_pages)); + memset(RawSPUMem, 0, sizeof(RawSPUMem)); + +#ifdef _WIN32 + m_base_addr = VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); + if (!m_base_addr) +#else + m_base_addr = ::mmap(nullptr, 0x100000000, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + if (m_base_addr == (void*)-1) +#endif + { + m_base_addr = nullptr; + LOG_ERROR(MEMORY, "Initializing memory failed"); + assert(0); + return; + } + else + { + LOG_NOTICE(MEMORY, "Initializing memory: m_base_addr = 0x%llx", (u64)m_base_addr); + } + + switch (type) + { + case Memory_PS3: + MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x2FFF0000)); + MemoryBlocks.push_back(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000)); + MemoryBlocks.push_back(RSXCMDMem.SetRange(0x40000000, 0x10000000)); + MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000)); + MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000)); + MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000)); + break; + + case Memory_PSV: + MemoryBlocks.push_back(PSV.RAM.SetRange(0x81000000, 0x10000000)); + MemoryBlocks.push_back(UserMemory = PSV.Userspace.SetRange(0x91000000, 0x10000000)); + PSV.Init(GetBaseAddr()); + break; + + case Memory_PSP: + MemoryBlocks.push_back(PSP.Scratchpad.SetRange(0x00010000, 0x00004000)); + MemoryBlocks.push_back(PSP.VRAM.SetRange(0x04000000, 0x00200000)); + MemoryBlocks.push_back(PSP.RAM.SetRange(0x08000000, 0x02000000)); + MemoryBlocks.push_back(PSP.Kernel.SetRange(0x88000000, 0x00800000)); + MemoryBlocks.push_back(UserMemory = PSP.Userspace.SetRange(0x08800000, 0x01800000)); + PSP.Init(GetBaseAddr()); + break; + } + + LOG_NOTICE(MEMORY, "Memory initialized."); +} + +void MemoryBase::Close() +{ + std::lock_guard lock(m_mutex); + + if (!m_inited) return; + m_inited = false; + + LOG_NOTICE(MEMORY, "Closing memory..."); + + for (auto block : MemoryBlocks) + { + block->Delete(); + } + + RSXIOMem.Delete(); + + MemoryBlocks.clear(); + +#ifdef _WIN32 + if (!VirtualFree(m_base_addr, 0, MEM_RELEASE)) + { + LOG_ERROR(MEMORY, "VirtualFree(0x%llx) failed", (u64)m_base_addr); + } +#else + if (::munmap(m_base_addr, 0x100000000)) + { + LOG_ERROR(MEMORY, "::munmap(0x%llx) failed", (u64)m_base_addr); + } +#endif +} + +bool MemoryBase::Map(const u64 dst_addr, const u64 src_addr, const u32 size) +{ + std::lock_guard lock(m_mutex); + + if (IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) + { + return false; + } + + MemoryBlocks.push_back((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size)); + LOG_WARNING(MEMORY, "memory mapped 0x%llx to 0x%llx size=0x%x", src_addr, dst_addr, size); + return true; +} + +bool MemoryBase::Unmap(const u64 addr) +{ + std::lock_guard lock(m_mutex); + + bool result = false; + for (uint i = 0; iIsMirror()) + { + if (MemoryBlocks[i]->GetStartAddr() == addr) + { + delete MemoryBlocks[i]; + MemoryBlocks.erase(MemoryBlocks.begin() + i); + return true; + } + } + } + return false; +} + MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size) : MemInfo(_addr, PAGE_4K(_size)) { @@ -334,12 +543,6 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value) return true; } -// MemoryBase -template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; } -template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); } -template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); } -template<> __forceinline u64 MemoryBase::ReverseData<8>(u64 val) { return Reverse64(val); } - VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock(), m_reserve_size(0) { } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 0c230593d2..61f2e7ed73 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -1,17 +1,7 @@ #pragma once -#ifndef _WIN32 -#include -#endif - #include "MemoryBlock.h" #include "Emu/SysCalls/Callback.h" -#include - -/* OS X uses MAP_ANON instead of MAP_ANONYMOUS */ -#ifndef MAP_ANONYMOUS - #define MAP_ANONYMOUS MAP_ANON -#endif using std::nullptr_t; @@ -107,80 +97,11 @@ public: return m_base_addr; } - noinline void InvalidAddress(const char* func, const u64 addr) - { - LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", func, addr); - } + __noinline void InvalidAddress(const char* func, const u64 addr); - void RegisterPages(u64 addr, u32 size) - { - std::lock_guard lock(m_mutex); + void RegisterPages(u64 addr, u32 size); - //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size); - for (u64 i = addr / 4096; i < (addr + size) / 4096; i++) - { - if (i >= sizeof(m_pages) / sizeof(m_pages[0])) - { - InvalidAddress(__FUNCTION__, i * 4096); - break; - } - if (m_pages[i]) - { - LOG_ERROR(MEMORY, "Page already registered (addr=0x%llx)", i * 4096); - } - m_pages[i] = 1; // TODO: define page parameters - } - } - - void UnregisterPages(u64 addr, u32 size) - { - std::lock_guard lock(m_mutex); - - //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size); - for (u64 i = addr / 4096; i < (addr + size) / 4096; i++) - { - if (i >= sizeof(m_pages) / sizeof(m_pages[0])) - { - InvalidAddress(__FUNCTION__, i * 4096); - break; - } - if (!m_pages[i]) - { - LOG_ERROR(MEMORY, "Page not registered (addr=0x%llx)", i * 4096); - } - m_pages[i] = 0; // TODO: define page parameters - } - } - - static __forceinline u16 Reverse16(const u16 val) - { - return _byteswap_ushort(val); - } - - static __forceinline u32 Reverse32(const u32 val) - { - return _byteswap_ulong(val); - } - - static __forceinline u64 Reverse64(const u64 val) - { - return _byteswap_uint64(val); - } - - static __forceinline u128 Reverse128(const u128 val) - { - u128 ret; - ret.lo = _byteswap_uint64(val.hi); - ret.hi = _byteswap_uint64(val.lo); - return ret; - } - - template static __forceinline u64 ReverseData(u64 val); - - template static __forceinline T Reverse(T val) - { - return (T)ReverseData(val); - }; + void UnregisterPages(u64 addr, u32 size); template u8* GetMemFromAddr(const T addr) { @@ -210,100 +131,16 @@ public: } else { + assert(!addr); return 0; } } - u32 InitRawSPU(MemoryBlock* raw_spu) - { - std::lock_guard lock(m_mutex); + u32 InitRawSPU(MemoryBlock* raw_spu); - u32 index; - for (index = 0; index < sizeof(RawSPUMem) / sizeof(RawSPUMem[0]); index++) - { - if (!RawSPUMem[index]) - { - RawSPUMem[index] = raw_spu; - break; - } - } + void CloseRawSPU(MemoryBlock* raw_spu, const u32 num); - MemoryBlocks.push_back(raw_spu->SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_PROB_OFFSET)); - return index; - } - - void CloseRawSPU(MemoryBlock* raw_spu, const u32 num) - { - std::lock_guard lock(m_mutex); - - for (int i = 0; i < MemoryBlocks.size(); ++i) - { - if (MemoryBlocks[i] == raw_spu) - { - MemoryBlocks.erase(MemoryBlocks.begin() + i); - break; - } - } - if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = nullptr; - } - - void Init(MemoryType type) - { - std::lock_guard lock(m_mutex); - - if(m_inited) return; - m_inited = true; - - memset(m_pages, 0, sizeof(m_pages)); - memset(RawSPUMem, 0, sizeof(RawSPUMem)); - -#ifdef _WIN32 - m_base_addr = VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); - if (!m_base_addr) -#else - m_base_addr = ::mmap(nullptr, 0x100000000, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); - if (m_base_addr == (void*)-1) -#endif - { - m_base_addr = nullptr; - LOG_ERROR(MEMORY, "Initializing memory failed"); - assert(0); - return; - } - else - { - LOG_NOTICE(MEMORY, "Initializing memory: m_base_addr = 0x%llx", (u64)m_base_addr); - } - - switch(type) - { - case Memory_PS3: - MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x2FFF0000)); - MemoryBlocks.push_back(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000)); - MemoryBlocks.push_back(RSXCMDMem.SetRange(0x40000000, 0x10000000)); - MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000)); - MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000)); - MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000)); - break; - - case Memory_PSV: - MemoryBlocks.push_back(PSV.RAM.SetRange(0x81000000, 0x10000000)); - MemoryBlocks.push_back(UserMemory = PSV.Userspace.SetRange(0x91000000, 0x10000000)); - PSV.Init(GetBaseAddr()); - break; - - case Memory_PSP: - MemoryBlocks.push_back(PSP.Scratchpad.SetRange(0x00010000, 0x00004000)); - MemoryBlocks.push_back(PSP.VRAM.SetRange(0x04000000, 0x00200000)); - MemoryBlocks.push_back(PSP.RAM.SetRange(0x08000000, 0x02000000)); - MemoryBlocks.push_back(PSP.Kernel.SetRange(0x88000000, 0x00800000)); - MemoryBlocks.push_back(UserMemory = PSP.Userspace.SetRange(0x08800000, 0x01800000)); - PSP.Init(GetBaseAddr()); - break; - } - - LOG_NOTICE(MEMORY, "Memory initialized."); - } + void Init(MemoryType type); template bool IsGoodAddr(const T addr) { @@ -333,36 +170,7 @@ public: } } - void Close() - { - std::lock_guard lock(m_mutex); - - if(!m_inited) return; - m_inited = false; - - LOG_NOTICE(MEMORY, "Closing memory..."); - - for (auto block : MemoryBlocks) - { - block->Delete(); - } - - RSXIOMem.Delete(); - - MemoryBlocks.clear(); - -#ifdef _WIN32 - if (!VirtualFree(m_base_addr, 0, MEM_RELEASE)) - { - LOG_ERROR(MEMORY, "VirtualFree(0x%llx) failed", (u64)m_base_addr); - } -#else - if (::munmap(m_base_addr, 0x100000000)) - { - LOG_ERROR(MEMORY, "::munmap(0x%llx) failed", (u64)m_base_addr); - } -#endif - } + void Close(); //MemoryBase template void Write8(T addr, const u8 data) @@ -391,7 +199,7 @@ public: } } - noinline void WriteMMIO32(u32 addr, const u32 data) + __noinline void WriteMMIO32(u32 addr, const u32 data) { { std::lock_guard lock(m_mutex); @@ -478,7 +286,7 @@ public: } } - noinline u32 ReadMMIO32(u32 addr) + __noinline u32 ReadMMIO32(u32 addr) { u32 res; { @@ -588,11 +396,6 @@ public: strcpy((char*)GetMemFromAddr(addr), str.c_str()); } - static u64 AlignAddr(const u64 addr, const u64 align) - { - return (addr + (align-1)) & ~(align-1); - } - u32 GetUserMemTotalSize() { return UserMemory->GetSize(); @@ -623,49 +426,18 @@ public: return UserMemory->Unlock(addr, size); } - bool Map(const u64 dst_addr, const u64 src_addr, const u32 size) + bool Map(const u64 dst_addr, const u64 src_addr, const u32 size); + + bool Unmap(const u64 addr); + + template void* operator + (const T vaddr) { - std::lock_guard lock(m_mutex); - - if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) - { - return false; - } - - MemoryBlocks.push_back((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size)); - LOG_WARNING(MEMORY, "memory mapped 0x%llx to 0x%llx size=0x%x", src_addr, dst_addr, size); - return true; - } - - bool Unmap(const u64 addr) - { - std::lock_guard lock(m_mutex); - - bool result = false; - for(uint i=0; iIsMirror()) - { - if(MemoryBlocks[i]->GetStartAddr() == addr) - { - delete MemoryBlocks[i]; - MemoryBlocks.erase(MemoryBlocks.begin() + i); - return true; - } - } - } - return false; - } - - template u8* operator + (const T vaddr) - { - u8* ret = GetMemFromAddr(vaddr); - return ret; + return GetMemFromAddr(vaddr); } template u8& operator[] (const T vaddr) { - return *(*this + vaddr); + return *GetMemFromAddr(vaddr); } }; diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index fa5b913797..43c36df710 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -2,193 +2,9 @@ #define PAGE_4K(x) (x + 4095) & ~(4095) -union u128 -{ - struct - { - u64 hi; - u64 lo; - }; - - u64 _u64[2]; - u32 _u32[4]; - u16 _u16[8]; - u8 _u8[16]; - - operator u64() const { return _u64[0]; } - operator u32() const { return _u32[0]; } - operator u16() const { return _u16[0]; } - operator u8() const { return _u8[0]; } - - operator bool() const { return _u64[0] != 0 || _u64[1] != 0; } - - static u128 From128( u64 hi, u64 lo ) - { - u128 ret = {hi, lo}; - return ret; - } - - static u128 From64( u64 src ) - { - u128 ret = {0, src}; - return ret; - } - - static u128 From32( u32 src ) - { - u128 ret; - ret._u32[0] = src; - ret._u32[1] = 0; - ret._u32[2] = 0; - ret._u32[3] = 0; - return ret; - } - - static u128 FromBit ( u32 bit ) - { - u128 ret; - if (bit < 64) - { - ret.hi = 0; - ret.lo = (u64)1 << bit; - } - else if (bit < 128) - { - ret.hi = (u64)1 << (bit - 64); - ret.lo = 0; - } - else - { - ret.hi = 0; - ret.lo = 0; - } - return ret; - } - - bool operator == ( const u128& right ) const - { - return (lo == right.lo) && (hi == right.hi); - } - - bool operator != ( const u128& right ) const - { - return (lo != right.lo) || (hi != right.hi); - } - - u128 operator | ( const u128& right ) const - { - return From128(hi | right.hi, lo | right.lo); - } - - u128 operator & ( const u128& right ) const - { - return From128(hi & right.hi, lo & right.lo); - } - - u128 operator ^ ( const u128& right ) const - { - return From128(hi ^ right.hi, lo ^ right.lo); - } - - u128 operator ~ () const - { - return From128(~hi, ~lo); - } -}; - -union s128 -{ - struct - { - s64 hi; - s64 lo; - }; - - u64 _i64[2]; - u32 _i32[4]; - u16 _i16[8]; - u8 _i8[16]; - - operator s64() const { return _i64[0]; } - operator s32() const { return _i32[0]; } - operator s16() const { return _i16[0]; } - operator s8() const { return _i8[0]; } - - operator bool() const { return _i64[0] != 0 || _i64[1] != 0; } - - static s128 From64( s64 src ) - { - s128 ret = {src, 0}; - return ret; - } - - static s128 From32( s32 src ) - { - s128 ret; - ret._i32[0] = src; - ret._i32[1] = 0; - ret.hi = 0; - return ret; - } - - bool operator == ( const s128& right ) const - { - return (lo == right.lo) && (hi == right.hi); - } - - bool operator != ( const s128& right ) const - { - return (lo != right.lo) || (hi != right.hi); - } -}; - #include #include -//TODO: SSE style -/* -struct u128 -{ - __m128 m_val; - - u128 GetValue128() - { - u128 ret; - _mm_store_ps( (float*)&ret, m_val ); - return ret; - } - - u64 GetValue64() - { - u64 ret; - _mm_store_ps( (float*)&ret, m_val ); - return ret; - } - - u32 GetValue32() - { - u32 ret; - _mm_store_ps( (float*)&ret, m_val ); - return ret; - } - - u16 GetValue16() - { - u16 ret; - _mm_store_ps( (float*)&ret, m_val ); - return ret; - } - - u8 GetValue8() - { - u8 ret; - _mm_store_ps( (float*)&ret, m_val ); - return ret; - } -}; -*/ - - struct MemInfo { u64 addr; diff --git a/rpcs3/Emu/RSX/GL/GLBuffers.cpp b/rpcs3/Emu/RSX/GL/GLBuffers.cpp index 9dd2d35f76..c2fbd354b2 100644 --- a/rpcs3/Emu/RSX/GL/GLBuffers.cpp +++ b/rpcs3/Emu/RSX/GL/GLBuffers.cpp @@ -1,8 +1,5 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "GLBuffers.h" -#include "GLGSRender.h" GLBufferObject::GLBufferObject() { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index d4c0bfc3c3..23e72117cc 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1,9 +1,9 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GLGSRender.h" -#include "Emu/Cell/PPCInstrTable.h" #define CMD_DEBUG 0 #define DUMP_VERTEX_DATA 0 @@ -35,6 +35,731 @@ void printGlError(GLenum err, const std::string& situation) #define checkForGlError(x) /*x*/ #endif +void GLTexture::Create() +{ + if (m_id) + { + Delete(); + } + + if (!m_id) + { + glGenTextures(1, &m_id); + checkForGlError("GLTexture::Init() -> glGenTextures"); + Bind(); + } +} + +int GLTexture::GetGlWrap(int wrap) +{ + switch (wrap) + { + case CELL_GCM_TEXTURE_WRAP: return GL_REPEAT; + case CELL_GCM_TEXTURE_MIRROR: return GL_MIRRORED_REPEAT; + case CELL_GCM_TEXTURE_CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE; + case CELL_GCM_TEXTURE_BORDER: return GL_CLAMP_TO_BORDER; + case CELL_GCM_TEXTURE_CLAMP: return GL_CLAMP_TO_EDGE; + case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE: return GL_MIRROR_CLAMP_TO_EDGE_EXT; + case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return GL_MIRROR_CLAMP_TO_BORDER_EXT; + case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return GL_MIRROR_CLAMP_EXT; + } + + LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d).", wrap); + return GL_REPEAT; +} + +float GLTexture::GetMaxAniso(int aniso) +{ + switch (aniso) + { + case CELL_GCM_TEXTURE_MAX_ANISO_1: return 1.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_2: return 2.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_4: return 4.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_6: return 6.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_8: return 8.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_10: return 10.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12.0f; + case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16.0f; + } + + LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d).", aniso); + return 1.0f; +} + +void GLTexture::Init(RSXTexture& tex) +{ + if (tex.GetLocation() > 1) + return; + + Bind(); + + const u64 texaddr = GetAddress(tex.GetOffset(), tex.GetLocation()); + if (!Memory.IsGoodAddr(texaddr)) + { + LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr); + return; + } + //ConLog.Warning("texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", + // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod); + //TODO: safe init + checkForGlError("GLTexture::Init() -> glBindTexture"); + + int format = tex.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); + bool is_swizzled = !(tex.GetFormat() & CELL_GCM_TEXTURE_LN); + + const u8 *pixels = const_cast(Memory.GetMemFromAddr(texaddr)); + u8 *unswizzledPixels; + static const GLint glRemapStandard[4] = { GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE }; + // NOTE: This must be in ARGB order in all forms below. + const GLint *glRemap = glRemapStandard; + + switch (format) + { + case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_B8)"); + + static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; + glRemap = swizzleMaskB8; + } + break; + + case CELL_GCM_TEXTURE_A1R5G5B5: + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + + // TODO: texture swizzling + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A1R5G5B5)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_A1R5G5B5)"); + break; + + case CELL_GCM_TEXTURE_A4R4G4B4: + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A4R4G4B4)"); + + // We read it in as R4G4B4A4, so we need to remap each component. + static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; + glRemap = swizzleMaskA4R4G4B4; + } + break; + + case CELL_GCM_TEXTURE_R5G6B5: + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.GetWidth(), tex.GetHeight(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G6B5)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); + } + break; + + case CELL_GCM_TEXTURE_A8R8G8B8: + if (is_swizzled) + { + u32 *src, *dst; + u32 log2width, log2height; + + unswizzledPixels = (u8*)malloc(tex.GetWidth() * tex.GetHeight() * 4); + src = (u32*)pixels; + dst = (u32*)unswizzledPixels; + + log2width = log(tex.GetWidth()) / log(2); + log2height = log(tex.GetHeight()) / log(2); + + for (int i = 0; i glTexImage2D(CELL_GCM_TEXTURE_A8R8G8B8)"); + break; + + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes + { + u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 8; + + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); + checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT1)"); + } + break; + + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes + { + u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; + + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); + checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT23)"); + } + break; + + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes + { + u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; + + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); + checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT45)"); + } + break; + + case CELL_GCM_TEXTURE_G8B8: + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_G8B8)"); + + static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; + glRemap = swizzleMaskG8B8; + } + break; + + case CELL_GCM_TEXTURE_R6G5B5: + { + // TODO: Probably need to actually unswizzle if is_swizzled. + const u32 numPixels = tex.GetWidth() * tex.GetHeight(); + unswizzledPixels = (u8 *)malloc(numPixels * 4); + // TODO: Speed. + for (u32 i = 0; i < numPixels; ++i) { + u16 c = reinterpret_cast *>(pixels)[i]; + unswizzledPixels[i * 4 + 0] = Convert6To8((c >> 10) & 0x3F); + unswizzledPixels[i * 4 + 1] = Convert5To8((c >> 5) & 0x1F); + unswizzledPixels[i * 4 + 2] = Convert5To8((c >> 0) & 0x1F); + unswizzledPixels[i * 4 + 3] = 255; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R6G5B5)"); + + free(unswizzledPixels); + } + break; + + case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8)"); + break; + + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT)"); + break; + + case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16)"); + break; + + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16_FLOAT)"); + break; + + case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X16)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); + + static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; + glRemap = swizzleMaskX16; + } + break; + + case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); + + static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; + glRemap = swizzleMaskX32_Y16_X16; + } + break; + + case CELL_GCM_TEXTURE_R5G5B5A1: + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G5B5A1)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); + break; + + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_HALF_FLOAT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); + break; + + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_FLOAT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT)"); + break; + + case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_FLOAT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X32_FLOAT)"); + + static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; + glRemap = swizzleMaskX32_FLOAT; + } + break; + + case CELL_GCM_TEXTURE_D1R5G5B5: + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); + + // TODO: Texture swizzling + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D1R5G5B5)"); + + static const GLint swizzleMaskX32_D1R5G5B5[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; + glRemap = swizzleMaskX32_D1R5G5B5; + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); + } + break; + + case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D8R8G8B8)"); + + static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; + glRemap = swizzleMaskX32_D8R8G8B8; + } + break; + + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_HALF_FLOAT, pixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); + + static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; + glRemap = swizzleMaskX32_Y16_X16_FLOAT; + } + break; + + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) : + { + const u32 numPixels = tex.GetWidth() * tex.GetHeight(); + unswizzledPixels = (u8 *)malloc(numPixels * 4); + // TODO: Speed. + for (u32 i = 0; i < numPixels; i += 2) { + unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 3]; + unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 2]; + unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 0]; + unswizzledPixels[i * 4 + 0 + 3] = 255; + + // The second pixel is the same, except for red. + unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 1]; + unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 2]; + unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 0]; + unswizzledPixels[i * 4 + 4 + 3] = 255; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); + + free(unswizzledPixels); + } + break; + + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) : + { + const u32 numPixels = tex.GetWidth() * tex.GetHeight(); + unswizzledPixels = (u8 *)malloc(numPixels * 4); + // TODO: Speed. + for (u32 i = 0; i < numPixels; i += 2) { + unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 2]; + unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 3]; + unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 1]; + unswizzledPixels[i * 4 + 0 + 3] = 255; + + // The second pixel is the same, except for red. + unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 0]; + unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 3]; + unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 1]; + unswizzledPixels[i * 4 + 4 + 3] = 255; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); + checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); + + free(unswizzledPixels); + } + break; + + default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, + (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40); break; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.GetMipmap() > 1); + + if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT) + { + u8 remap_a = tex.GetRemap() & 0x3; + u8 remap_r = (tex.GetRemap() >> 2) & 0x3; + u8 remap_g = (tex.GetRemap() >> 4) & 0x3; + u8 remap_b = (tex.GetRemap() >> 6) & 0x3; + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]); + } + else + { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]); + } + + checkForGlError("GLTexture::Init() -> remap"); + + static const int gl_tex_zfunc[] = + { + GL_NEVER, + GL_LESS, + GL_EQUAL, + GL_LEQUAL, + GL_GREATER, + GL_NOTEQUAL, + GL_GEQUAL, + GL_ALWAYS, + }; + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.GetWrapS())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.GetWrapT())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.GetWrapR())); + + checkForGlError("GLTexture::Init() -> wrap"); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.GetZfunc()]); + + checkForGlError("GLTexture::Init() -> compare"); + + glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.GetBias()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.GetMinLOD() >> 8)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.GetMaxLOD() >> 8)); + + checkForGlError("GLTexture::Init() -> lod"); + + static const int gl_tex_min_filter[] = + { + GL_NEAREST, // unused + GL_NEAREST, + GL_LINEAR, + GL_NEAREST_MIPMAP_NEAREST, + GL_LINEAR_MIPMAP_NEAREST, + GL_NEAREST_MIPMAP_LINEAR, + GL_LINEAR_MIPMAP_LINEAR, + GL_NEAREST, // CELL_GCM_TEXTURE_CONVOLUTION_MIN + }; + + static const int gl_tex_mag_filter[] = { + GL_NEAREST, // unused + GL_NEAREST, + GL_LINEAR, + GL_NEAREST, // unused + GL_LINEAR // CELL_GCM_TEXTURE_CONVOLUTION_MAG + }; + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.GetMinFilter()]); + + checkForGlError("GLTexture::Init() -> min filters"); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.GetMagFilter()]); + + checkForGlError("GLTexture::Init() -> mag filters"); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GetMaxAniso(tex.GetMaxAniso())); + + checkForGlError("GLTexture::Init() -> max anisotropy"); + + //Unbind(); + + if (is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8) + { + free(unswizzledPixels); + } +} + +void GLTexture::Save(RSXTexture& tex, const std::string& name) +{ + if (!m_id || !tex.GetOffset() || !tex.GetWidth() || !tex.GetHeight()) return; + + const u32 texPixelCount = tex.GetWidth() * tex.GetHeight(); + + u32* alldata = new u32[texPixelCount]; + + Bind(); + + switch (tex.GetFormat() & ~(0x20 | 0x40)) + { + case CELL_GCM_TEXTURE_B8: + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata); + break; + + case CELL_GCM_TEXTURE_A8R8G8B8: + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, alldata); + break; + + default: + delete[] alldata; + return; + } + + { + rFile f(name + ".raw", rFile::write); + f.Write(alldata, texPixelCount * 4); + } + u8* data = new u8[texPixelCount * 3]; + u8* alpha = new u8[texPixelCount]; + + u8* src = (u8*)alldata; + u8* dst_d = data; + u8* dst_a = alpha; + for (u32 i = 0; i < texPixelCount; i++) + { + *dst_d++ = *src++; + *dst_d++ = *src++; + *dst_d++ = *src++; + *dst_a++ = *src++; + } + + rImage out; + out.Create(tex.GetWidth(), tex.GetHeight(), data, alpha); + out.SaveFile(name, rBITMAP_TYPE_PNG); + + delete[] alldata; + //free(data); + //free(alpha); +} + +void GLTexture::Save(RSXTexture& tex) +{ + static const std::string& dir_path = "textures"; + static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; + + if (!rExists(dir_path)) rMkdir(dir_path); + + u32 count = 0; + while (rExists(fmt::Format(file_fmt, count))) count++; + Save(tex, fmt::Format(file_fmt, count)); +} + +void GLTexture::Bind() +{ + glBindTexture(GL_TEXTURE_2D, m_id); +} + +void GLTexture::Unbind() +{ + glBindTexture(GL_TEXTURE_2D, 0); +} + +void GLTexture::Delete() +{ + if (m_id) + { + glDeleteTextures(1, &m_id); + m_id = 0; + } +} + +void PostDrawObj::Draw() +{ + static bool s_is_initialized = false; + + if (!s_is_initialized) + { + s_is_initialized = true; + Initialize(); + } + else + { + m_program.Use(); + } +} + +void PostDrawObj::Initialize() +{ + InitializeShaders(); + m_fp.Compile(); + m_vp.Compile(); + m_program.Create(m_vp.id, m_fp.GetId()); + m_program.Use(); + InitializeLocations(); +} + +void DrawCursorObj::Draw() +{ + checkForGlError("PostDrawObj : Unknown error."); + + PostDrawObj::Draw(); + checkForGlError("PostDrawObj::Draw"); + + if (!m_fbo.IsCreated()) + { + m_fbo.Create(); + checkForGlError("DrawCursorObj : m_fbo.Create"); + m_fbo.Bind(); + checkForGlError("DrawCursorObj : m_fbo.Bind"); + + m_rbo.Create(); + checkForGlError("DrawCursorObj : m_rbo.Create"); + m_rbo.Bind(); + checkForGlError("DrawCursorObj : m_rbo.Bind"); + m_rbo.Storage(GL_RGBA, m_width, m_height); + checkForGlError("DrawCursorObj : m_rbo.Storage"); + + m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId()); + checkForGlError("DrawCursorObj : m_fbo.Renderbuffer"); + } + + m_fbo.Bind(); + checkForGlError("DrawCursorObj : m_fbo.Bind"); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + checkForGlError("DrawCursorObj : glDrawBuffer"); + + m_program.Use(); + checkForGlError("DrawCursorObj : m_program.Use"); + + if (m_update_texture) + { + //m_update_texture = false; + + glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height); + checkForGlError("DrawCursorObj : glUniform2f"); + if (!m_tex_id) + { + glGenTextures(1, &m_tex_id); + checkForGlError("DrawCursorObj : glGenTextures"); + } + + glActiveTexture(GL_TEXTURE0); + checkForGlError("DrawCursorObj : glActiveTexture"); + glBindTexture(GL_TEXTURE_2D, m_tex_id); + checkForGlError("DrawCursorObj : glBindTexture"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels); + checkForGlError("DrawCursorObj : glTexImage2D"); + m_program.SetTex(0); + } + + if (m_update_pos) + { + //m_update_pos = false; + + glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f); + checkForGlError("DrawCursorObj : glUniform4f"); + } + + glDrawArrays(GL_QUADS, 0, 4); + checkForGlError("DrawCursorObj : glDrawArrays"); + + m_fbo.Bind(GL_READ_FRAMEBUFFER); + checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)"); + GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); + checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)"); + GLfbo::Blit( + 0, 0, m_width, m_height, + 0, 0, m_width, m_height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + checkForGlError("DrawCursorObj : GLfbo::Blit"); + m_fbo.Bind(); + checkForGlError("DrawCursorObj : m_fbo.Bind"); +} + +void DrawCursorObj::InitializeShaders() +{ + m_vp.shader = + "#version 330\n" + "\n" + "uniform vec4 in_pos;\n" + "uniform vec2 in_tc;\n" + "out vec2 tc;\n" + "\n" + "void main()\n" + "{\n" + " tc = in_tc;\n" + " gl_Position = in_pos;\n" + "}\n"; + + m_fp.SetShaderText( + "#version 330\n" + "\n" + "in vec2 tc;\n" + "uniform sampler2D tex0;\n" + "layout (location = 0) out vec4 res;\n" + "\n" + "void main()\n" + "{\n" + " res = texture(tex0, tc);\n" + "}\n"); +} + +void DrawCursorObj::SetTexture(void* pixels, int width, int height) +{ + m_pixels = pixels; + m_width = width; + m_height = height; + + m_update_texture = true; +} + +void DrawCursorObj::SetPosition(float x, float y, float z) +{ + m_pos_x = x; + m_pos_y = y; + m_pos_z = z; + m_update_pos = true; +} + +void DrawCursorObj::InitializeLocations() +{ + //ConLog.Warning("tex0 location = 0x%x", m_program.GetLocation("tex0")); +} + GLGSRender::GLGSRender() : GSRender() , m_frame(nullptr) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index e2cf5f9d6f..1a26aeaa13 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -1,6 +1,5 @@ #pragma once #include "Emu/RSX/GSRender.h" -#include "Emu/RSX/RSXThread.h" #include "Utilities/rPlatform.h" #include "GLBuffers.h" #include "GLProgramBuffer.h" @@ -29,56 +28,11 @@ public: { } - void Create() - { - if(m_id) - { - Delete(); - } + void Create(); - if(!m_id) - { - glGenTextures(1, &m_id); - checkForGlError("GLTexture::Init() -> glGenTextures"); - Bind(); - } - } + int GetGlWrap(int wrap); - int GetGlWrap(int wrap) - { - switch(wrap) - { - case CELL_GCM_TEXTURE_WRAP: return GL_REPEAT; - case CELL_GCM_TEXTURE_MIRROR: return GL_MIRRORED_REPEAT; - case CELL_GCM_TEXTURE_CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE; - case CELL_GCM_TEXTURE_BORDER: return GL_CLAMP_TO_BORDER; - case CELL_GCM_TEXTURE_CLAMP: return GL_CLAMP_TO_EDGE; - case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE: return GL_MIRROR_CLAMP_TO_EDGE_EXT; - case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return GL_MIRROR_CLAMP_TO_BORDER_EXT; - case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return GL_MIRROR_CLAMP_EXT; - } - - LOG_ERROR(RSX, "Texture wrap error: bad wrap (%d).", wrap); - return GL_REPEAT; - } - - float GetMaxAniso(int aniso) - { - switch (aniso) - { - case CELL_GCM_TEXTURE_MAX_ANISO_1: return 1.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_2: return 2.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_4: return 4.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_6: return 6.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_8: return 8.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_10: return 10.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12.0f; - case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16.0f; - } - - LOG_ERROR(RSX, "Texture anisotropy error: bad max aniso (%d).", aniso); - return 1.0f; - } + float GetMaxAniso(int aniso); inline static u8 Convert4To8(u8 v) { @@ -98,526 +52,17 @@ public: return (v << 2) | (v >> 4); } - void Init(RSXTexture& tex) - { - if (tex.GetLocation() > 1) - return; + void Init(RSXTexture& tex); - Bind(); + void Save(RSXTexture& tex, const std::string& name); - const u64 texaddr = GetAddress(tex.GetOffset(), tex.GetLocation()); - if (!Memory.IsGoodAddr(texaddr)) - { - LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr); - return; - } - //ConLog.Warning("texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", - // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod); - //TODO: safe init - checkForGlError("GLTexture::Init() -> glBindTexture"); + void Save(RSXTexture& tex); - int format = tex.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - bool is_swizzled = !(tex.GetFormat() & CELL_GCM_TEXTURE_LN); + void Bind(); - const u8 *pixels = const_cast(Memory.GetMemFromAddr(texaddr)); - u8 *unswizzledPixels; - static const GLint glRemapStandard[4] = {GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE}; - // NOTE: This must be in ARGB order in all forms below. - const GLint *glRemap = glRemapStandard; + void Unbind(); - switch(format) - { - case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_B8)"); - - static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE }; - glRemap = swizzleMaskB8; - } - break; - - case CELL_GCM_TEXTURE_A1R5G5B5: - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei"); - - // TODO: texture swizzling - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A1R5G5B5)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_A1R5G5B5)"); - break; - - case CELL_GCM_TEXTURE_A4R4G4B4: - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_A4R4G4B4)"); - - // We read it in as R4G4B4A4, so we need to remap each component. - static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN }; - glRemap = swizzleMaskA4R4G4B4; - } - break; - - case CELL_GCM_TEXTURE_R5G6B5: - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.GetWidth(), tex.GetHeight(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G6B5)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G6B5)"); - } - break; - - case CELL_GCM_TEXTURE_A8R8G8B8: - if(is_swizzled) - { - u32 *src, *dst; - u32 log2width, log2height; - - unswizzledPixels = (u8*)malloc(tex.GetWidth() * tex.GetHeight() * 4); - src = (u32*)pixels; - dst = (u32*)unswizzledPixels; - - log2width = log(tex.GetWidth())/log(2); - log2height = log(tex.GetHeight())/log(2); - - for(int i=0; i glTexImage2D(CELL_GCM_TEXTURE_A8R8G8B8)"); - break; - - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes - { - u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 8; - - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT1)"); - } - break; - - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes - { - u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; - - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT23)"); - } - break; - - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes - { - u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; - - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); - checkForGlError("GLTexture::Init() -> glCompressedTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_DXT45)"); - } - break; - - case CELL_GCM_TEXTURE_G8B8: - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_G8B8)"); - - static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; - glRemap = swizzleMaskG8B8; - } - break; - - case CELL_GCM_TEXTURE_R6G5B5: - { - // TODO: Probably need to actually unswizzle if is_swizzled. - const u32 numPixels = tex.GetWidth() * tex.GetHeight(); - unswizzledPixels = (u8 *)malloc(numPixels * 4); - // TODO: Speed. - for (u32 i = 0; i < numPixels; ++i) { - u16 c = reinterpret_cast *>(pixels)[i]; - unswizzledPixels[i * 4 + 0] = Convert6To8((c >> 10) & 0x3F); - unswizzledPixels[i * 4 + 1] = Convert5To8((c >> 5) & 0x1F); - unswizzledPixels[i * 4 + 2] = Convert5To8((c >> 0) & 0x1F); - unswizzledPixels[i * 4 + 3] = 255; - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R6G5B5)"); - - free(unswizzledPixels); - } - break; - - case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8)"); - break; - - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT)"); - break; - - case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16)"); - break; - - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.GetWidth(), tex.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_DEPTH16_FLOAT)"); - break; - - case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X16)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_X16)"); - - static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; - glRemap = swizzleMaskX16; - } - break; - - case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16)"); - - static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; - glRemap = swizzleMaskX32_Y16_X16; - } - break; - - case CELL_GCM_TEXTURE_R5G5B5A1: - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_R5G5B5A1)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_R5G5B5A1)"); - break; - - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_HALF_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT)"); - break; - - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT)"); - break; - - case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_X32_FLOAT)"); - - static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; - glRemap = swizzleMaskX32_FLOAT; - } - break; - - case CELL_GCM_TEXTURE_D1R5G5B5: - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); - - // TODO: Texture swizzling - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D1R5G5B5)"); - - static const GLint swizzleMaskX32_D1R5G5B5[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; - glRemap = swizzleMaskX32_D1R5G5B5; - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_D1R5G5B5)"); - } - break; - - case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_D8R8G8B8)"); - - static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE }; - glRemap = swizzleMaskX32_D8R8G8B8; - } - break; - - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_HALF_FLOAT, pixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - checkForGlError("GLTexture::Init() -> glPixelStorei(CELL_GCM_TEXTURE_Y16_X16_FLOAT)"); - - static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; - glRemap = swizzleMaskX32_Y16_X16_FLOAT; - } - break; - - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN): - { - const u32 numPixels = tex.GetWidth() * tex.GetHeight(); - unswizzledPixels = (u8 *)malloc(numPixels * 4); - // TODO: Speed. - for (u32 i = 0; i < numPixels; i += 2) { - unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 3]; - unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 2]; - unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 0]; - unswizzledPixels[i * 4 + 0 + 3] = 255; - - // The second pixel is the same, except for red. - unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 1]; - unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 2]; - unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 0]; - unswizzledPixels[i * 4 + 4 + 3] = 255; - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); - - free(unswizzledPixels); - } - break; - - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN): - { - const u32 numPixels = tex.GetWidth() * tex.GetHeight(); - unswizzledPixels = (u8 *)malloc(numPixels * 4); - // TODO: Speed. - for (u32 i = 0; i < numPixels; i += 2) { - unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 2]; - unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 3]; - unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 1]; - unswizzledPixels[i * 4 + 0 + 3] = 255; - - // The second pixel is the same, except for red. - unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 0]; - unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 3]; - unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 1]; - unswizzledPixels[i * 4 + 4 + 3] = 255; - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels); - checkForGlError("GLTexture::Init() -> glTexImage2D(CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN)"); - - free(unswizzledPixels); - } - break; - - default: LOG_ERROR(RSX, "Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, - (is_swizzled ? "swizzled" : "linear"), tex.GetFormat() & 0x40); break; - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.GetMipmap() > 1); - - if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT) - { - u8 remap_a = tex.GetRemap() & 0x3; - u8 remap_r = (tex.GetRemap() >> 2) & 0x3; - u8 remap_g = (tex.GetRemap() >> 4) & 0x3; - u8 remap_b = (tex.GetRemap() >> 6) & 0x3; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]); - } - else - { - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]); - } - - checkForGlError("GLTexture::Init() -> remap"); - - static const int gl_tex_zfunc[] = - { - GL_NEVER, - GL_LESS, - GL_EQUAL, - GL_LEQUAL, - GL_GREATER, - GL_NOTEQUAL, - GL_GEQUAL, - GL_ALWAYS, - }; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.GetWrapS())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.GetWrapT())); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.GetWrapR())); - - checkForGlError("GLTexture::Init() -> wrap"); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.GetZfunc()]); - - checkForGlError("GLTexture::Init() -> compare"); - - glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.GetBias()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.GetMinLOD() >> 8)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.GetMaxLOD() >> 8)); - - checkForGlError("GLTexture::Init() -> lod"); - - static const int gl_tex_min_filter[] = - { - GL_NEAREST, // unused - GL_NEAREST, - GL_LINEAR, - GL_NEAREST_MIPMAP_NEAREST, - GL_LINEAR_MIPMAP_NEAREST, - GL_NEAREST_MIPMAP_LINEAR, - GL_LINEAR_MIPMAP_LINEAR, - GL_NEAREST, // CELL_GCM_TEXTURE_CONVOLUTION_MIN - }; - - static const int gl_tex_mag_filter[] = { - GL_NEAREST, // unused - GL_NEAREST, - GL_LINEAR, - GL_NEAREST, // unused - GL_LINEAR // CELL_GCM_TEXTURE_CONVOLUTION_MAG - }; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.GetMinFilter()]); - - checkForGlError("GLTexture::Init() -> min filters"); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.GetMagFilter()]); - - checkForGlError("GLTexture::Init() -> mag filters"); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GetMaxAniso(tex.GetMaxAniso())); - - checkForGlError("GLTexture::Init() -> max anisotropy"); - - //Unbind(); - - if(is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8) - { - free(unswizzledPixels); - } - } - - void Save(RSXTexture& tex, const std::string& name) - { - if(!m_id || !tex.GetOffset() || !tex.GetWidth() || !tex.GetHeight()) return; - - const u32 texPixelCount = tex.GetWidth() * tex.GetHeight(); - - u32* alldata = new u32[texPixelCount]; - - Bind(); - - switch(tex.GetFormat() & ~(0x20 | 0x40)) - { - case CELL_GCM_TEXTURE_B8: - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata); - break; - - case CELL_GCM_TEXTURE_A8R8G8B8: - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, alldata); - break; - - default: - delete[] alldata; - return; - } - - { - rFile f(name + ".raw", rFile::write); - f.Write(alldata, texPixelCount * 4); - } - u8* data = new u8[texPixelCount * 3]; - u8* alpha = new u8[texPixelCount]; - - u8* src = (u8*)alldata; - u8* dst_d = data; - u8* dst_a = alpha; - for (u32 i = 0; i < texPixelCount; i++) - { - *dst_d++ = *src++; - *dst_d++ = *src++; - *dst_d++ = *src++; - *dst_a++ = *src++; - } - - rImage out; - out.Create(tex.GetWidth(), tex.GetHeight(), data, alpha); - out.SaveFile(name, rBITMAP_TYPE_PNG); - - delete[] alldata; - //free(data); - //free(alpha); - } - - void Save(RSXTexture& tex) - { - static const std::string& dir_path = "textures"; - static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; - - if(!rExists(dir_path)) rMkdir(dir_path); - - u32 count = 0; - while(rExists(fmt::Format(file_fmt, count))) count++; - Save(tex, fmt::Format(file_fmt, count)); - } - - void Bind() - { - glBindTexture(GL_TEXTURE_2D, m_id); - } - - void Unbind() - { - glBindTexture(GL_TEXTURE_2D, 0); - } - - void Delete() - { - if(m_id) - { - glDeleteTextures(1, &m_id); - m_id = 0; - } - } + void Delete(); }; class PostDrawObj @@ -630,33 +75,12 @@ protected: GLrbo m_rbo; public: - virtual void Draw() - { - static bool s_is_initialized = false; - - if(!s_is_initialized) - { - s_is_initialized = true; - Initialize(); - } - else - { - m_program.Use(); - } - } + virtual void Draw(); virtual void InitializeShaders() = 0; virtual void InitializeLocations() = 0; - void Initialize() - { - InitializeShaders(); - m_fp.Compile(); - m_vp.Compile(); - m_program.Create(m_vp.id, m_fp.GetId()); - m_program.Use(); - InitializeLocations(); - } + void Initialize(); }; class DrawCursorObj : public PostDrawObj @@ -675,133 +99,15 @@ public: { } - virtual void Draw() - { - checkForGlError("PostDrawObj : Unknown error."); + virtual void Draw(); - PostDrawObj::Draw(); - checkForGlError("PostDrawObj::Draw"); + virtual void InitializeShaders(); - if(!m_fbo.IsCreated()) - { - m_fbo.Create(); - checkForGlError("DrawCursorObj : m_fbo.Create"); - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); + void SetTexture(void* pixels, int width, int height); - m_rbo.Create(); - checkForGlError("DrawCursorObj : m_rbo.Create"); - m_rbo.Bind(); - checkForGlError("DrawCursorObj : m_rbo.Bind"); - m_rbo.Storage(GL_RGBA, m_width, m_height); - checkForGlError("DrawCursorObj : m_rbo.Storage"); + void SetPosition(float x, float y, float z = 0.0f); - m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId()); - checkForGlError("DrawCursorObj : m_fbo.Renderbuffer"); - } - - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - checkForGlError("DrawCursorObj : glDrawBuffer"); - - m_program.Use(); - checkForGlError("DrawCursorObj : m_program.Use"); - - if(m_update_texture) - { - //m_update_texture = false; - - glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height); - checkForGlError("DrawCursorObj : glUniform2f"); - if(!m_tex_id) - { - glGenTextures(1, &m_tex_id); - checkForGlError("DrawCursorObj : glGenTextures"); - } - - glActiveTexture(GL_TEXTURE0); - checkForGlError("DrawCursorObj : glActiveTexture"); - glBindTexture(GL_TEXTURE_2D, m_tex_id); - checkForGlError("DrawCursorObj : glBindTexture"); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels); - checkForGlError("DrawCursorObj : glTexImage2D"); - m_program.SetTex(0); - } - - if(m_update_pos) - { - //m_update_pos = false; - - glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f); - checkForGlError("DrawCursorObj : glUniform4f"); - } - - glDrawArrays(GL_QUADS, 0, 4); - checkForGlError("DrawCursorObj : glDrawArrays"); - - m_fbo.Bind(GL_READ_FRAMEBUFFER); - checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)"); - GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)"); - GLfbo::Blit( - 0, 0, m_width, m_height, - 0, 0, m_width, m_height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - checkForGlError("DrawCursorObj : GLfbo::Blit"); - m_fbo.Bind(); - checkForGlError("DrawCursorObj : m_fbo.Bind"); - } - - virtual void InitializeShaders() - { - m_vp.shader = - "#version 330\n" - "\n" - "uniform vec4 in_pos;\n" - "uniform vec2 in_tc;\n" - "out vec2 tc;\n" - "\n" - "void main()\n" - "{\n" - " tc = in_tc;\n" - " gl_Position = in_pos;\n" - "}\n"; - - m_fp.SetShaderText( - "#version 330\n" - "\n" - "in vec2 tc;\n" - "uniform sampler2D tex0;\n" - "layout (location = 0) out vec4 res;\n" - "\n" - "void main()\n" - "{\n" - " res = texture(tex0, tc);\n" - "}\n"); - } - - void SetTexture(void* pixels, int width, int height) - { - m_pixels = pixels; - m_width = width; - m_height = height; - - m_update_texture = true; - } - - void SetPosition(float x, float y, float z = 0.0f) - { - m_pos_x = x; - m_pos_y = y; - m_pos_z = z; - m_update_pos = true; - } - - void InitializeLocations() - { - //ConLog.Warning("tex0 location = 0x%x", m_program.GetLocation("tex0")); - } + void InitializeLocations(); }; class GLGSRender //TODO: find out why this used to inherit from wxWindow diff --git a/rpcs3/Emu/RSX/GL/GLProgram.cpp b/rpcs3/Emu/RSX/GL/GLProgram.cpp index e7e7fdaa0a..96e32f6be4 100644 --- a/rpcs3/Emu/RSX/GL/GLProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLProgram.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "GLProgram.h" #include "GLGSRender.h" diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 22d666cf6b..e460b06f35 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GLVertexProgram.h" diff --git a/rpcs3/Emu/RSX/GSManager.cpp b/rpcs3/Emu/RSX/GSManager.cpp index 0e24117f5b..17155bbbb3 100644 --- a/rpcs3/Emu/RSX/GSManager.cpp +++ b/rpcs3/Emu/RSX/GSManager.cpp @@ -1,12 +1,23 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "rpcs3/Ini.h" +#include "sysutil_video.h" + #include "GSManager.h" #include "Null/NullGSRender.h" #include "GL/GLGSRender.h" +void GSInfo::Init() +{ + mode.resolutionId = Ini.GSResolution.GetValue(); + mode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_INTERLACE; + mode.conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE; + mode.aspect = Ini.GSAspectRatio.GetValue(); + mode.refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_50HZ; + mode.format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8; + mode.pitch = 4; +} + GSManager::GSManager() : m_render(nullptr) { } diff --git a/rpcs3/Emu/RSX/GSManager.h b/rpcs3/Emu/RSX/GSManager.h index 11f7b3917f..68d9db987a 100644 --- a/rpcs3/Emu/RSX/GSManager.h +++ b/rpcs3/Emu/RSX/GSManager.h @@ -1,7 +1,5 @@ #pragma once -#include "sysutil_video.h" #include "GSRender.h" -#include "rpcs3/Ini.h" struct GSInfo { @@ -21,16 +19,7 @@ struct GSInfo { } - void Init() - { - mode.resolutionId = Ini.GSResolution.GetValue(); - mode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_INTERLACE; - mode.conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE; - mode.aspect = Ini.GSAspectRatio.GetValue(); - mode.refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_50HZ; - mode.format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8; - mode.pitch = 4; - } + void Init(); }; class GSManager diff --git a/rpcs3/Emu/RSX/GSRender.cpp b/rpcs3/Emu/RSX/GSRender.cpp index 6290d09893..b1111c19d7 100644 --- a/rpcs3/Emu/RSX/GSRender.cpp +++ b/rpcs3/Emu/RSX/GSRender.cpp @@ -1,10 +1,30 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GSRender.h" +GSLock::GSLock(GSRender& renderer, GSLockType type) + : m_renderer(renderer) + , m_type(type) +{ + switch (m_type) + { + case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.lock(); break; + case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.wait(); break; + case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.wait(); break; + } +} + +GSLock::~GSLock() +{ + switch (m_type) + { + case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.unlock(); break; + case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.post(); break; + case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.post(); break; + } +} + GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type) { } diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index f1b6b74082..2a58e463a1 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -1,5 +1,4 @@ #pragma once -#include "Emu/RSX/GCM.h" #include "Emu/RSX/RSXThread.h" struct GSRender : public RSXThread @@ -25,27 +24,9 @@ private: GSLockType m_type; public: - GSLock(GSRender& renderer, GSLockType type) - : m_renderer(renderer) - , m_type(type) - { - switch(m_type) - { - case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.lock(); break; - case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.wait(); break; - case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.wait(); break; - } - } + GSLock(GSRender& renderer, GSLockType type); - ~GSLock() - { - switch(m_type) - { - case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.unlock(); break; - case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.post(); break; - case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.post(); break; - } - } + ~GSLock(); }; struct GSLockCurrent : GSLock diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index c23c9499cf..c7d4d0bb8d 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -1,7 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" -#include "RSXThread.h" #include "RSXThread.h" #include "RSXTexture.h" diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 708a157839..bc261ca671 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "RSXThread.h" #include "Emu/SysCalls/lv2/sys_time.h" -#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args) : args[x].ToLE()) +#define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.GetAddr()) : args[x].ToLE()) u32 methodRegisters[0xffff]; @@ -139,8 +140,9 @@ u32 RSXVertexData::GetTypeSize() #define CMD_LOG(...) #endif -u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, mem32_ptr_t args) +u32 RSXThread::OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr) { + mem32_ptr_t args(args_addr); std::string debug = GetMethodName(cmd); debug += "("; for(u32 i=0; iget = get + (count + 1) * 4; //memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4); @@ -2252,3 +2256,33 @@ void RSXThread::Task() OnExitThread(); } + +void RSXThread::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) +{ + m_ctrl = (CellGcmControl*)&Memory[ctrlAddress]; + m_ioAddress = ioAddress; + m_ioSize = ioSize; + m_ctrlAddress = ctrlAddress; + m_local_mem_addr = localAddress; + + m_cur_vertex_prog = nullptr; + m_cur_shader_prog = nullptr; + m_cur_shader_prog_num = 0; + + m_used_gcm_commands.clear(); + + OnInit(); + ThreadBase::Start(); +} + +u32 RSXThread::ReadIO32(u32 addr) +{ + u32 value; + Memory.RSXIOMem.Read32(Memory.RSXIOMem.GetStartAddr() + addr, &value); + return value; +} + +void RSXThread::WriteIO32(u32 addr, u32 value) +{ + Memory.RSXIOMem.Write32(Memory.RSXIOMem.GetStartAddr() + addr, value); +} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index eb2c85e246..75aa31ffbe 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -4,7 +4,6 @@ #include "RSXVertexProgram.h" #include "RSXFragmentProgram.h" #include "Emu/SysCalls/Callback.h" -#include "Emu/Memory/Memory.h" #include #include // For tracking a list of used gcm commands @@ -611,8 +610,8 @@ protected: void Begin(u32 draw_mode); void End(); - u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, mem32_ptr_t args); - void DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32 count); + u32 OutOfArgsCount(const uint x, const u32 cmd, const u32 count, const u32 args_addr); + void DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 count); void nativeRescale(float width, float height); virtual void OnInit() = 0; @@ -636,33 +635,9 @@ protected: virtual void Task(); public: - void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) - { - m_ctrl = (CellGcmControl*)&Memory[ctrlAddress]; - m_ioAddress = ioAddress; - m_ioSize = ioSize; - m_ctrlAddress = ctrlAddress; - m_local_mem_addr = localAddress; + void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress); - m_cur_vertex_prog = nullptr; - m_cur_shader_prog = nullptr; - m_cur_shader_prog_num = 0; + u32 ReadIO32(u32 addr); - m_used_gcm_commands.clear(); - - OnInit(); - ThreadBase::Start(); - } - - u32 ReadIO32(u32 addr) - { - u32 value; - Memory.RSXIOMem.Read32(Memory.RSXIOMem.GetStartAddr() + addr, &value); - return value; - } - - void WriteIO32(u32 addr, u32 value) - { - Memory.RSXIOMem.Write32(Memory.RSXIOMem.GetStartAddr() + addr, value); - } + void WriteIO32(u32 addr, u32 value); }; diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index 69fa0e8033..f3af71d9b8 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -2,10 +2,9 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Callback.h" - #include "Emu/Cell/PPUThread.h" -#include "Emu/Cell/PPCThread.h" + +#include "Callback.h" Callback::Callback(u32 slot, u64 addr) : m_addr(addr) diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index c4760519c0..c2fc7cd378 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -1,10 +1,6 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "SysCalls.h" -#define FUNC_LOG_ERROR(x) LOG_ERROR(HLE, x); return 0 std::string SysCalls::GetHLEFuncName(const u32 fid) { switch(fid) diff --git a/rpcs3/Emu/SysCalls/LogBase.cpp b/rpcs3/Emu/SysCalls/LogBase.cpp new file mode 100644 index 0000000000..6a8f4a6bed --- /dev/null +++ b/rpcs3/Emu/SysCalls/LogBase.cpp @@ -0,0 +1,32 @@ +#include "stdafx.h" +#include "rpcs3/Ini.h" +#include "Utilities/Log.h" +#include "Emu/System.h" +#include "LogBase.h" + +bool LogBase::CheckLogging() const +{ + return Ini.HLELogging.GetValue(); +} + +void LogBase::LogOutput(LogType type, const char* info, const std::string& text) +{ + switch (type) + { + case LogNotice: LOG_NOTICE(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break; + case LogSuccess: LOG_SUCCESS(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break; + case LogWarning: LOG_WARNING(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break; + case LogError: LOG_ERROR(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break; + } +} + +void LogBase::LogOutput(LogType type, const u32 id, const char* info, const std::string& text) +{ + switch (type) + { + case LogNotice: LOG_NOTICE(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break; + case LogSuccess: LOG_SUCCESS(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break; + case LogWarning: LOG_WARNING(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break; + case LogError: LOG_ERROR(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break; + } +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/LogBase.h b/rpcs3/Emu/SysCalls/LogBase.h index 3c583aa8e6..dc3d280d43 100644 --- a/rpcs3/Emu/SysCalls/LogBase.h +++ b/rpcs3/Emu/SysCalls/LogBase.h @@ -3,6 +3,18 @@ class LogBase { bool m_logging; + bool CheckLogging() const; + + enum LogType + { + LogNotice, + LogSuccess, + LogWarning, + LogError, + }; + + void LogOutput(LogType type, const char* info, const std::string& text); + void LogOutput(LogType type, const u32 id, const char* info, const std::string& text); public: void SetLogging(bool value) @@ -10,12 +22,6 @@ public: m_logging = value; } - bool GetLogging() - { - //return m_logging; // TODO - return Ini.HLELogging.GetValue(); - } - LogBase() { SetLogging(false); @@ -25,17 +31,17 @@ public: template void Notice(const u32 id, const char* fmt, Targs... args) { - LOG_NOTICE(HLE, GetName() + fmt::Format("[%d]: ", id) + fmt::Format(fmt, args...)); + LogOutput(LogNotice, id, ": ", fmt::Format(fmt, args...)); } template void Notice(const char* fmt, Targs... args) { - LOG_NOTICE(HLE, GetName() + ": " + fmt::Format(fmt, args...)); + LogOutput(LogNotice, ": ", fmt::Format(fmt, args...)); } template __forceinline void Log(const char* fmt, Targs... args) { - if (GetLogging()) + if (CheckLogging()) { Notice(fmt, args...); } @@ -43,39 +49,49 @@ public: template __forceinline void Log(const u32 id, const char* fmt, Targs... args) { - if (GetLogging()) + if (CheckLogging()) { Notice(id, fmt, args...); } } + template void Success(const u32 id, const char* fmt, Targs... args) + { + LogOutput(LogSuccess, id, ": ", fmt::Format(fmt, args...)); + } + + template void Success(const char* fmt, Targs... args) + { + LogOutput(LogSuccess, ": ", fmt::Format(fmt, args...)); + } + template void Warning(const u32 id, const char* fmt, Targs... args) { - LOG_WARNING(HLE, GetName() + fmt::Format("[%d] warning: ", id) + fmt::Format(fmt, args...)); + LogOutput(LogWarning, id, " warning: ", fmt::Format(fmt, args...)); } template void Warning(const char* fmt, Targs... args) { - LOG_WARNING(HLE, GetName() + " warning: " + fmt::Format(fmt, args...)); + LogOutput(LogWarning, " warning: ", fmt::Format(fmt, args...)); } template void Error(const u32 id, const char* fmt, Targs... args) { - LOG_ERROR(HLE, GetName() + fmt::Format("[%d] error: ", id) + fmt::Format(fmt, args...)); + LogOutput(LogError, id, " error: ", fmt::Format(fmt, args...)); } template void Error(const char* fmt, Targs... args) { - LOG_ERROR(HLE, GetName() + " error: " + fmt::Format(fmt, args...)); + LogOutput(LogError, " error: ", fmt::Format(fmt, args...)); } template void Todo(const u32 id, const char* fmt, Targs... args) { - LOG_ERROR(HLE, GetName() + fmt::Format("[%d] TODO: ", id) + fmt::Format(fmt, args...)); + LogOutput(LogError, id, " TODO: ", fmt::Format(fmt, args...)); } template void Todo(const char* fmt, Targs... args) { - LOG_ERROR(HLE, GetName() + " TODO: " + fmt::Format(fmt, args...)); + LogOutput(LogError, " TODO: ", fmt::Format(fmt, args...)); } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 78b5d4ba8d..64d1bda99d 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -1,18 +1,24 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/Static.h" #include "Crypto/sha1.h" #include #include "ModuleManager.h" -u32 getFunctionId(const std::string& name) +u32 getFunctionId(const char* name) { const char* suffix = "\x67\x59\x65\x99\x04\x25\x04\x90\x56\x64\x27\x49\x94\x89\x74\x1A"; // Symbol name suffix - std::string input = name + suffix; - unsigned char output[20]; + u8 output[20]; + + // Compute SHA-1 hash + sha1_context ctx; + + sha1_starts(&ctx); + sha1_update(&ctx, (const u8*)name, strlen(name)); + sha1_update(&ctx, (const u8*)suffix, strlen(suffix)); + sha1_finish(&ctx, output); - sha1((unsigned char*)input.c_str(), input.length(), output); // Compute SHA-1 hash return (u32&)output[0]; } @@ -167,3 +173,18 @@ bool Module::CheckID(u32 id, ID*& _id) const { return Emu.GetIdManager().CheckID(id) && (_id = &Emu.GetIdManager().GetID(id))->m_name == GetName(); } + +bool Module::RemoveId(u32 id) +{ + return Emu.GetIdManager().RemoveID(id); +} + +IdManager& Module::GetIdManager() const +{ + return Emu.GetIdManager(); +} + +void Module::PushNewFuncSub(SFunc* func) +{ + Emu.GetSFuncManager().push_back(func); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 14f0bb3522..9472d235dd 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -1,6 +1,6 @@ #pragma once - #include "Emu/SysCalls/SC_FUNC.h" +#include "ErrorCodes.h" #include "LogBase.h" //TODO @@ -17,7 +17,7 @@ struct ModuleFunc ~ModuleFunc() { - safe_delete(func); + delete func; } }; @@ -38,10 +38,12 @@ struct SFunc ~SFunc() { - safe_delete(func); + delete func; } }; +class StaticFuncManager; + class Module : public LogBase { std::string m_name; @@ -50,6 +52,9 @@ class Module : public LogBase void (*m_load_func)(); void (*m_unload_func)(); + IdManager& GetIdManager() const; + void PushNewFuncSub(SFunc* func); + public: std::vector m_funcs_list; @@ -106,15 +111,17 @@ public: template u32 GetNewId(T* data, IDType type = TYPE_OTHER) { - return Emu.GetIdManager().GetNewID(GetName(), data, type); + return GetIdManager().GetNewID(GetName(), data, type); } + bool RemoveId(u32 id); + template __forceinline void AddFunc(u32 id, T func); - template __forceinline void AddFunc(const std::string& name, T func); + template __forceinline void AddFunc(const char* name, T func); template __forceinline void AddFuncSub(const char group[8], const u64 ops[], const char* name, T func); }; -u32 getFunctionId(const std::string& name); +u32 getFunctionId(const char* name); template __forceinline void Module::AddFunc(u32 id, T func) @@ -123,7 +130,7 @@ __forceinline void Module::AddFunc(u32 id, T func) } template -__forceinline void Module::AddFunc(const std::string& name, T func) +__forceinline void Module::AddFunc(const char* name, T func) { AddFunc(getFunctionId(name), func); } @@ -152,5 +159,13 @@ __forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], cons op.crc = re(op.crc); sf->ops.push_back(op); } - Emu.GetSFuncManager().push_back(sf); + PushNewFuncSub(sf); } + +#define REG_SUB(module, group, name, ...) \ + static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \ + module->AddFuncSub(group, name ## _table, #name, name) + +#define REG_FUNC(module, name) module->AddFunc(getFunctionId(#name), name) + +#define UNIMPLEMENTED_FUNC(module) module->Todo("%s", __FUNCTION__) \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/SC_Keyboard.cpp b/rpcs3/Emu/SysCalls/Modules/SC_Keyboard.cpp index c71dac97ad..8f529f6e17 100644 --- a/rpcs3/Emu/SysCalls/Modules/SC_Keyboard.cpp +++ b/rpcs3/Emu/SysCalls/Modules/SC_Keyboard.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "Emu/Io/Keyboard.h" extern Module *sys_io; diff --git a/rpcs3/Emu/SysCalls/Modules/SC_Mouse.cpp b/rpcs3/Emu/SysCalls/Modules/SC_Mouse.cpp index b4cee94fdb..99648ea32c 100644 --- a/rpcs3/Emu/SysCalls/Modules/SC_Mouse.cpp +++ b/rpcs3/Emu/SysCalls/Modules/SC_Mouse.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "Emu/Io/Mouse.h" extern Module *sys_io; diff --git a/rpcs3/Emu/SysCalls/Modules/SC_Pad.cpp b/rpcs3/Emu/SysCalls/Modules/SC_Pad.cpp index de2aecd3b7..c04cd67a01 100644 --- a/rpcs3/Emu/SysCalls/Modules/SC_Pad.cpp +++ b/rpcs3/Emu/SysCalls/Modules/SC_Pad.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "Emu/Io/Pad.h" extern Module *sys_io; @@ -383,8 +383,6 @@ int cellPadSetPortSetting(u32 port_no, u32 port_setting) { sys_io->Log("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; - if ((port_setting < CELL_PAD_SETTING_PRESS_ON) || port_setting >(CELL_PAD_SETTING_PRESS_ON | CELL_PAD_SETTING_SENSOR_ON) && port_setting != 0) - return CELL_PAD_ERROR_INVALID_PARAMETER; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; if (port_no >= rinfo.now_connect) return CELL_PAD_ERROR_NO_DEVICE; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 23e30c4efc..1e1b661111 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -1,10 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" -#include "cellPamf.h" extern std::mutex g_mutex_avcodec_open2; @@ -15,12 +12,77 @@ extern "C" #include "libswresample/swresample.h" } +#include "cellPamf.h" #include "cellAdec.h" //void cellAdec_init(); //Module cellAdec(0x0006, cellAdec_init); Module *cellAdec = nullptr; +AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg) + : type(type) + , memAddr(addr) + , memSize(size) + , memBias(0) + , cbFunc(func) + , cbArg(arg) + , adecCb(nullptr) + , is_running(false) + , is_finished(false) + , just_started(false) + , just_finished(false) + , ctx(nullptr) + , fmt(nullptr) +{ + AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); + if (!codec) + { + cellAdec->Error("AudioDecoder(): avcodec_find_decoder(ATRAC3P) failed"); + Emu.Pause(); + return; + } + fmt = avformat_alloc_context(); + if (!fmt) + { + cellAdec->Error("AudioDecoder(): avformat_alloc_context failed"); + Emu.Pause(); + return; + } + io_buf = (u8*)av_malloc(4096); + fmt->pb = avio_alloc_context(io_buf, 4096, 0, this, adecRead, NULL, NULL); + if (!fmt->pb) + { + cellAdec->Error("AudioDecoder(): avio_alloc_context failed"); + Emu.Pause(); + return; + } +} + +AudioDecoder::~AudioDecoder() +{ + // TODO: check finalization + if (ctx) + { + for (u32 i = frames.GetCount() - 1; ~i; i--) + { + AdecFrame& af = frames.Peek(i); + av_frame_unref(af.data); + av_frame_free(&af.data); + } + avcodec_close(ctx); + avformat_close_input(&fmt); + } + if (fmt) + { + if (io_buf) + { + av_free(io_buf); + } + if (fmt->pb) av_free(fmt->pb); + avformat_free_context(fmt); + } +} + int adecRawRead(void* opaque, u8* buf, int buf_size) { AudioDecoder& adec = *(AudioDecoder*)opaque; @@ -34,7 +96,7 @@ next: { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "adecRawRead(): aborted"); + cellAdec->Warning("adecRawRead(): aborted"); return 0; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -66,7 +128,7 @@ next: } break; default: - LOG_ERROR(HLE, "adecRawRead(): sequence error (task %d)", adec.job.Peek().type); + cellAdec->Error("adecRawRead(): sequence error (task %d)", adec.job.Peek().type); return -1; } @@ -101,7 +163,7 @@ int adecRead(void* opaque, u8* buf, int buf_size) { if (buf_size < (int)adec.reader.rem_size) { - LOG_ERROR(HLE, "adecRead(): too small buf_size (rem_size = %d, buf_size = %d)", adec.reader.rem_size, buf_size); + cellAdec->Error("adecRead(): too small buf_size (rem_size = %d, buf_size = %d)", adec.reader.rem_size, buf_size); Emu.Pause(); return 0; } @@ -121,7 +183,7 @@ int adecRead(void* opaque, u8* buf, int buf_size) if (adecRawRead(opaque, header, 8) < 8) break; if (header[0] != 0x0f || header[1] != 0xd0) { - LOG_ERROR(HLE, "adecRead(): 0x0FD0 header not found"); + cellAdec->Error("adecRead(): 0x0FD0 header not found"); Emu.Pause(); return -1; } @@ -131,7 +193,7 @@ int adecRead(void* opaque, u8* buf, int buf_size) OMAHeader oma(1 /* atrac3p id */, header[2], header[3]); if (buf_size < sizeof(oma) + 8) { - LOG_ERROR(HLE, "adecRead(): OMAHeader writing failed"); + cellAdec->Error("adecRead(): OMAHeader writing failed"); Emu.Pause(); return 0; } @@ -188,7 +250,7 @@ u32 adecOpen(AudioDecoder* data) thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [&]() { - LOG_NOTICE(HLE, "Audio Decoder thread started"); + cellAdec->Notice("Audio Decoder thread started"); AdecTask& task = adec.task; @@ -219,288 +281,288 @@ u32 adecOpen(AudioDecoder* data) switch (task.type) { case adecStartSeq: - { - // TODO: reset data - LOG_WARNING(HLE, "adecStartSeq:"); + { + // TODO: reset data + cellAdec->Warning("adecStartSeq:"); - adec.reader.addr = 0; - adec.reader.size = 0; - adec.reader.init = false; - if (adec.reader.rem) free(adec.reader.rem); - adec.reader.rem = nullptr; - adec.reader.rem_size = 0; - adec.is_running = true; - adec.just_started = true; - } - break; + adec.reader.addr = 0; + adec.reader.size = 0; + adec.reader.init = false; + if (adec.reader.rem) free(adec.reader.rem); + adec.reader.rem = nullptr; + adec.reader.rem_size = 0; + adec.is_running = true; + adec.just_started = true; + } + break; case adecEndSeq: - { - // TODO: finalize - LOG_WARNING(HLE, "adecEndSeq:"); + { + // TODO: finalize + cellAdec->Warning("adecEndSeq:"); - /*Callback cb; - cb.SetAddr(adec.cbFunc); - cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); - cb.Branch(true); // ???*/ - adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); + cb.Branch(true); // ???*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); - adec.is_running = false; - adec.just_finished = true; - } - break; + adec.is_running = false; + adec.just_finished = true; + } + break; case adecDecodeAu: + { + int err = 0; + + adec.reader.addr = task.au.addr; + adec.reader.size = task.au.size; + //LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts); + + if (adec.just_started) { - int err = 0; + adec.first_pts = task.au.pts; + adec.last_pts = task.au.pts - 0x10000; // hack + } - adec.reader.addr = task.au.addr; - adec.reader.size = task.au.size; - //LOG_NOTICE(HLE, "Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts); - - if (adec.just_started) + struct AVPacketHolder : AVPacket + { + AVPacketHolder(u32 size) { - adec.first_pts = task.au.pts; - adec.last_pts = task.au.pts - 0x10000; // hack + av_init_packet(this); + + if (size) + { + data = (u8*)av_calloc(1, size + FF_INPUT_BUFFER_PADDING_SIZE); + this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; + } + else + { + data = NULL; + size = 0; + } } - struct AVPacketHolder : AVPacket + ~AVPacketHolder() { - AVPacketHolder(u32 size) - { - av_init_packet(this); + av_free(data); + //av_free_packet(this); + } - if (size) - { - data = (u8*)av_calloc(1, size + FF_INPUT_BUFFER_PADDING_SIZE); - this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; - } - else - { - data = NULL; - size = 0; - } - } + } au(0); - ~AVPacketHolder() - { - av_free(data); - //av_free_packet(this); - } + /*{ + wxFile dump; + dump.Open(wxString::Format("audio pts-0x%llx.dump", task.au.pts), wxFile::write); + u8* buf = (u8*)malloc(task.au.size); + if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size); + free(buf); + dump.Close(); + }*/ - } au(0); + if (adec.just_started && adec.just_finished) + { + avcodec_flush_buffers(adec.ctx); + adec.reader.init = true; + adec.just_finished = false; + adec.just_started = false; + } + else if (adec.just_started) // deferred initialization + { + err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL); + if (err) + { + cellAdec->Error("adecDecodeAu: avformat_open_input() failed"); + Emu.Pause(); + break; + } + AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ??? + if (!codec) + { + cellAdec->Error("adecDecodeAu: avcodec_find_decoder() failed"); + Emu.Pause(); + break; + } + //err = avformat_find_stream_info(adec.fmt, NULL); + //if (err) + //{ + // cellAdec->Error("adecDecodeAu: avformat_find_stream_info() failed"); + // Emu.Pause(); + // break; + //} + //if (!adec.fmt->nb_streams) + //{ + // cellAdec->Error("adecDecodeAu: no stream found"); + // Emu.Pause(); + // break; + //} + if (!avformat_new_stream(adec.fmt, codec)) + { + cellAdec->Error("adecDecodeAu: avformat_new_stream() failed"); + Emu.Pause(); + break; + } + adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data - /*{ - wxFile dump; - dump.Open(wxString::Format("audio pts-0x%llx.dump", task.au.pts), wxFile::write); - u8* buf = (u8*)malloc(task.au.size); - if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size); - free(buf); - dump.Close(); + AVDictionary* opts = nullptr; + av_dict_set(&opts, "refcounted_frames", "1", 0); + { + std::lock_guard lock(g_mutex_avcodec_open2); + // not multithread-safe (???) + err = avcodec_open2(adec.ctx, codec, &opts); + } + if (err) + { + cellAdec->Error("adecDecodeAu: avcodec_open2() failed"); + Emu.Pause(); + break; + } + adec.just_started = false; + } + + bool last_frame = false; + + while (true) + { + if (Emu.IsStopped()) + { + cellAdec->Warning("adecDecodeAu: aborted"); + return; + } + + /*if (!adec.ctx) // fake + { + AdecFrame frame; + frame.pts = task.au.pts; + frame.auAddr = task.au.addr; + frame.auSize = task.au.size; + frame.userdata = task.au.userdata; + frame.size = 4096; + frame.data = nullptr; + adec.frames.Push(frame); + + adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + + break; }*/ - if (adec.just_started && adec.just_finished) + last_frame = av_read_frame(adec.fmt, &au) < 0; + if (last_frame) { - avcodec_flush_buffers(adec.ctx); - adec.reader.init = true; - adec.just_finished = false; - adec.just_started = false; - } - else if (adec.just_started) // deferred initialization - { - err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL); - if (err) - { - LOG_ERROR(HLE, "adecDecodeAu: avformat_open_input() failed"); - Emu.Pause(); - break; - } - AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ??? - if (!codec) - { - LOG_ERROR(HLE, "adecDecodeAu: avcodec_find_decoder() failed"); - Emu.Pause(); - break; - } - /*err = avformat_find_stream_info(adec.fmt, NULL); - if (err) - { - LOG_ERROR(HLE, "adecDecodeAu: avformat_find_stream_info() failed"); - Emu.Pause(); - break; - } - if (!adec.fmt->nb_streams) - { - LOG_ERROR(HLE, "adecDecodeAu: no stream found"); - Emu.Pause(); - break; - }*/ - if (!avformat_new_stream(adec.fmt, codec)) - { - LOG_ERROR(HLE, "adecDecodeAu: avformat_new_stream() failed"); - Emu.Pause(); - break; - } - adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data - - AVDictionary* opts = nullptr; - av_dict_set(&opts, "refcounted_frames", "1", 0); - { - std::lock_guard lock(g_mutex_avcodec_open2); - // not multithread-safe (???) - err = avcodec_open2(adec.ctx, codec, &opts); - } - if (err) - { - LOG_ERROR(HLE, "adecDecodeAu: avcodec_open2() failed"); - Emu.Pause(); - break; - } - adec.just_started = false; + //break; + av_free(au.data); + au.data = NULL; + au.size = 0; } - bool last_frame = false; - - while (true) + struct AdecFrameHolder : AdecFrame { - if (Emu.IsStopped()) + AdecFrameHolder() { - LOG_WARNING(HLE, "adecDecodeAu: aborted"); - return; + data = av_frame_alloc(); } - /*if (!adec.ctx) // fake + ~AdecFrameHolder() { - AdecFrame frame; - frame.pts = task.au.pts; - frame.auAddr = task.au.addr; - frame.auSize = task.au.size; - frame.userdata = task.au.userdata; - frame.size = 4096; - frame.data = nullptr; - adec.frames.Push(frame); + if (data) + { + av_frame_unref(data); + av_frame_free(&data); + } + } - adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + } frame; + if (!frame.data) + { + cellAdec->Error("adecDecodeAu: av_frame_alloc() failed"); + Emu.Pause(); + break; + } + + int got_frame = 0; + + int decode = avcodec_decode_audio4(adec.ctx, frame.data, &got_frame, &au); + + if (decode <= 0) + { + if (!last_frame && decode < 0) + { + cellAdec->Error("adecDecodeAu: AU decoding error(0x%x)", decode); + } + if (!got_frame && adec.reader.size == 0) break; + } + + if (got_frame) + { + u64 ts = av_frame_get_best_effort_timestamp(frame.data); + if (ts != AV_NOPTS_VALUE) + { + frame.pts = ts/* - adec.first_pts*/; + adec.last_pts = frame.pts; + } + else + { + adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; + frame.pts = adec.last_pts; + } + //frame.pts = adec.last_pts; + //adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; // ??? + frame.auAddr = task.au.addr; + frame.auSize = task.au.size; + frame.userdata = task.au.userdata; + frame.size = frame.data->nb_samples * frame.data->channels * sizeof(float); + + if (frame.data->format != AV_SAMPLE_FMT_FLTP) + { + cellAdec->Error("adecDecodeaAu: unsupported frame format(%d)", frame.data->format); + Emu.Pause(); break; - }*/ - - last_frame = av_read_frame(adec.fmt, &au) < 0; - if (last_frame) - { - //break; - av_free(au.data); - au.data = NULL; - au.size = 0; } - - struct AdecFrameHolder : AdecFrame + if (frame.data->channels != 2) { - AdecFrameHolder() - { - data = av_frame_alloc(); - } - - ~AdecFrameHolder() - { - if (data) - { - av_frame_unref(data); - av_frame_free(&data); - } - } - - } frame; - - if (!frame.data) - { - LOG_ERROR(HLE, "adecDecodeAu: av_frame_alloc() failed"); + cellAdec->Error("adecDecodeAu: unsupported channel count (%d)", frame.data->channels); Emu.Pause(); break; } - int got_frame = 0; + //LOG_NOTICE(HLE, "got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)", + //frame.pts, frame.data->nb_samples, frame.data->channels, frame.data->sample_rate, + //av_get_bytes_per_sample((AVSampleFormat)frame.data->format)); - int decode = avcodec_decode_audio4(adec.ctx, frame.data, &got_frame, &au); + adec.frames.Push(frame); + frame.data = nullptr; // to prevent destruction - if (decode <= 0) - { - if (!last_frame && decode < 0) - { - LOG_ERROR(HLE, "adecDecodeAu: AU decoding error(0x%x)", decode); - } - if (!got_frame && adec.reader.size == 0) break; - } - - if (got_frame) - { - u64 ts = av_frame_get_best_effort_timestamp(frame.data); - if (ts != AV_NOPTS_VALUE) - { - frame.pts = ts/* - adec.first_pts*/; - adec.last_pts = frame.pts; - } - else - { - adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; - frame.pts = adec.last_pts; - } - //frame.pts = adec.last_pts; - //adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; // ??? - frame.auAddr = task.au.addr; - frame.auSize = task.au.size; - frame.userdata = task.au.userdata; - frame.size = frame.data->nb_samples * frame.data->channels * sizeof(float); - - if (frame.data->format != AV_SAMPLE_FMT_FLTP) - { - LOG_ERROR(HLE, "adecDecodeaAu: unsupported frame format(%d)", frame.data->format); - Emu.Pause(); - break; - } - if (frame.data->channels != 2) - { - LOG_ERROR(HLE, "adecDecodeAu: unsupported channel count (%d)", frame.data->channels); - Emu.Pause(); - break; - } - - //LOG_NOTICE(HLE, "got audio frame (pts=0x%llx, nb_samples=%d, ch=%d, sample_rate=%d, nbps=%d)", - //frame.pts, frame.data->nb_samples, frame.data->channels, frame.data->sample_rate, - //av_get_bytes_per_sample((AVSampleFormat)frame.data->format)); - - adec.frames.Push(frame); - frame.data = nullptr; // to prevent destruction - - /*Callback cb; - cb.SetAddr(adec.cbFunc); - cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); - cb.Branch(false);*/ - adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); - } + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + cb.Branch(false);*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); } - - /*Callback cb; - cb.SetAddr(adec.cbFunc); - cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); - cb.Branch(false);*/ - adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); } - break; + + /*Callback cb; + cb.SetAddr(adec.cbFunc); + cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); + cb.Branch(false);*/ + adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); + } + break; case adecClose: - { - adec.is_finished = true; - LOG_NOTICE(HLE, "Audio Decoder thread ended"); - return; - } + { + adec.is_finished = true; + cellAdec->Notice("Audio Decoder thread ended"); + return; + } default: - LOG_ERROR(HLE, "Audio Decoder thread error: unknown task(%d)", task.type); + cellAdec->Error("Audio Decoder thread error: unknown task(%d)", task.type); } } adec.is_finished = true; - LOG_WARNING(HLE, "Audio Decoder thread aborted"); + cellAdec->Warning("Audio Decoder thread aborted"); }); t.detach(); @@ -512,8 +574,8 @@ bool adecCheckType(AudioCodecType type) { switch (type) { - case CELL_ADEC_TYPE_ATRACX: LOG_NOTICE(HLE, "adecCheckType: ATRAC3plus"); break; - case CELL_ADEC_TYPE_ATRACX_2CH: LOG_NOTICE(HLE, "adecCheckType: ATRAC3plus 2ch"); break; + case CELL_ADEC_TYPE_ATRACX: cellAdec->Notice("adecCheckType: ATRAC3plus"); break; + case CELL_ADEC_TYPE_ATRACX_2CH: cellAdec->Notice("adecCheckType: ATRAC3plus 2ch"); break; case CELL_ADEC_TYPE_ATRACX_6CH: case CELL_ADEC_TYPE_ATRACX_8CH: @@ -588,7 +650,7 @@ int cellAdecClose(u32 handle) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellAdecClose(%d) aborted", handle); + cellAdec->Warning("cellAdecClose(%d) aborted", handle); break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -752,15 +814,15 @@ int cellAdecGetPcmItem(u32 handle, mem32_t pcmItem_ptr) void cellAdec_init() { - cellAdec->AddFunc(0x7e4a4a49, cellAdecQueryAttr); - cellAdec->AddFunc(0xd00a6988, cellAdecOpen); - cellAdec->AddFunc(0x8b5551a4, cellAdecOpenEx); - cellAdec->AddFunc(0x847d2380, cellAdecClose); - cellAdec->AddFunc(0x487b613e, cellAdecStartSeq); - cellAdec->AddFunc(0xe2ea549b, cellAdecEndSeq); - cellAdec->AddFunc(0x1529e506, cellAdecDecodeAu); - cellAdec->AddFunc(0x97ff2af1, cellAdecGetPcm); - cellAdec->AddFunc(0xbd75f78b, cellAdecGetPcmItem); + REG_FUNC(cellAdec, cellAdecQueryAttr); + REG_FUNC(cellAdec, cellAdecOpen); + REG_FUNC(cellAdec, cellAdecOpenEx); + REG_FUNC(cellAdec, cellAdecClose); + REG_FUNC(cellAdec, cellAdecStartSeq); + REG_FUNC(cellAdec, cellAdecEndSeq); + REG_FUNC(cellAdec, cellAdecDecodeAu); + REG_FUNC(cellAdec, cellAdecGetPcm); + REG_FUNC(cellAdec, cellAdecGetPcmItem); av_register_all(); avcodec_register_all(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index 108844f22c..a72c126094 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1117,67 +1117,7 @@ public: CPUThread* adecCb; - AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg) - : type(type) - , memAddr(addr) - , memSize(size) - , memBias(0) - , cbFunc(func) - , cbArg(arg) - , adecCb(nullptr) - , is_running(false) - , is_finished(false) - , just_started(false) - , just_finished(false) - , ctx(nullptr) - , fmt(nullptr) - { - AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); - if (!codec) - { - LOG_ERROR(HLE, "AudioDecoder(): avcodec_find_decoder(ATRAC3P) failed"); - Emu.Pause(); - return; - } - fmt = avformat_alloc_context(); - if (!fmt) - { - LOG_ERROR(HLE, "AudioDecoder(): avformat_alloc_context failed"); - Emu.Pause(); - return; - } - io_buf = (u8*)av_malloc(4096); - fmt->pb = avio_alloc_context(io_buf, 4096, 0, this, adecRead, NULL, NULL); - if (!fmt->pb) - { - LOG_ERROR(HLE, "AudioDecoder(): avio_alloc_context failed"); - Emu.Pause(); - return; - } - } + AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg); - ~AudioDecoder() - { - // TODO: check finalization - if (ctx) - { - for (u32 i = frames.GetCount() - 1; ~i; i--) - { - AdecFrame& af = frames.Peek(i); - av_frame_unref(af.data); - av_frame_free(&af.data); - } - avcodec_close(ctx); - avformat_close_input(&fmt); - } - if (fmt) - { - if (io_buf) - { - av_free(io_buf); - } - if (fmt->pb) av_free(fmt->pb); - avformat_free_context(fmt); - } - } + ~AudioDecoder(); }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp index fea80fdb1c..7967075062 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp @@ -1,8 +1,6 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" Module *cellAtrac = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 57d9e7a47c..b370717eb3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -1,14 +1,15 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" + +#include "rpcs3/Ini.h" #include "Utilities/SQueue.h" #include "Emu/Event.h" -#include "Emu/Audio/cellAudio.h" -#include "Emu/Audio/AudioManager.h" +#include "Emu/SysCalls/lv2/sys_time.h" +//#include "Emu/Audio/AudioManager.h" #include "Emu/Audio/AudioDumper.h" +#include "Emu/Audio/cellAudio.h" //void cellAudio_init(); //Module cellAudio(0x0011, cellAudio_init); @@ -51,11 +52,11 @@ int cellAudioInit() if (do_dump && !m_dump.Init()) { - LOG_ERROR(HLE, "cellAudioInit(): AudioDumper::Init() failed"); + cellAudio->Error("cellAudioInit(): AudioDumper::Init() failed"); return; } - LOG_NOTICE(HLE, "Audio thread started"); + cellAudio->Notice("Audio thread started"); if (Ini.AudioDumpToFile.GetValue()) m_dump.WriteHeader(); @@ -136,7 +137,7 @@ int cellAudioInit() { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "Audio thread aborted"); + cellAudio->Warning("Audio thread aborted"); goto abort; } @@ -358,7 +359,7 @@ int cellAudioInit() } } - const u64 stamp1 = get_system_time(); + //const u64 stamp1 = get_system_time(); if (first_mix) { @@ -380,7 +381,7 @@ int cellAudioInit() oal_buffer_offset = 0; } - const u64 stamp2 = get_system_time(); + //const u64 stamp2 = get_system_time(); // send aftermix event (normal audio event) { @@ -408,7 +409,7 @@ int cellAudioInit() Emu.GetEventManager().SendEvent(keys[i], 0x10103000e010e07, 0, 0, 0); } - const u64 stamp3 = get_system_time(); + //const u64 stamp3 = get_system_time(); if (do_dump && !first_mix) { @@ -416,7 +417,7 @@ int cellAudioInit() { if (m_dump.WriteData(&buf8ch, sizeof(buf8ch)) != sizeof(buf8ch)) // write file data { - LOG_ERROR(HLE, "cellAudioInit(): AudioDumper::WriteData() failed"); + cellAudio->Error("cellAudioInit(): AudioDumper::WriteData() failed"); goto abort; } } @@ -424,13 +425,13 @@ int cellAudioInit() { if (m_dump.WriteData(&buf2ch, sizeof(buf2ch)) != sizeof(buf2ch)) // write file data { - LOG_ERROR(HLE, "cellAudioInit(): AudioDumper::WriteData() failed"); + cellAudio->Error("cellAudioInit(): AudioDumper::WriteData() failed"); goto abort; } } else { - LOG_ERROR(HLE, "cellAudioInit(): unknown AudioDumper::GetCh() value (%d)", m_dump.GetCh()); + cellAudio->Error("cellAudioInit(): unknown AudioDumper::GetCh() value (%d)", m_dump.GetCh()); goto abort; } } @@ -438,7 +439,7 @@ int cellAudioInit() //LOG_NOTICE(HLE, "Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)", //stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3); } - LOG_NOTICE(HLE, "Audio thread ended"); + cellAudio->Notice("Audio thread ended"); abort: queue.Push(nullptr); queue_float.Push(nullptr); @@ -470,7 +471,7 @@ abort: { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellAudioInit() aborted"); + cellAudio->Warning("cellAudioInit() aborted"); return CELL_OK; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -495,7 +496,7 @@ int cellAudioQuit() std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellAudioQuit(): aborted"); + cellAudio->Warning("cellAudioQuit(): aborted"); return CELL_OK; } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellBgdl.cpp b/rpcs3/Emu/SysCalls/Modules/cellBgdl.cpp index 72879e8d3b..15b7f773e0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellBgdl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellBgdl.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellBgdl_init(); Module cellBgdl(0x003f, cellBgdl_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp index ee00c683fa..c2237352bf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellCamera_init(); Module cellCamera(0x0023, cellCamera_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellCelp8Enc.cpp b/rpcs3/Emu/SysCalls/Modules/cellCelp8Enc.cpp index 70109e224a..83473a902c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCelp8Enc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCelp8Enc.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellCelp8Enc_init(); Module cellCelp8Enc(0x0048, cellCelp8Enc_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellCelpEnc.cpp b/rpcs3/Emu/SysCalls/Modules/cellCelpEnc.cpp index 6541f6ae76..03be6b4957 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCelpEnc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCelpEnc.cpp @@ -1,8 +1,5 @@ - #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellCelpEnc_init(); Module cellCelpEnc(0xf00a, cellCelpEnc_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 13f23a10a3..8b99c8098b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -1,10 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" + #include "cellPamf.h" #include "cellDmux.h" @@ -12,6 +10,300 @@ //Module cellDmux(0x0007, cellDmux_init); Module *cellDmux = nullptr; +PesHeader::PesHeader(DemuxerStream& stream) + : pts(0xffffffffffffffffull) + , dts(0xffffffffffffffffull) + , size(0) + , new_au(false) +{ + u16 header; + stream.get(header); + stream.get(size); + if (size) + { + u8 empty = 0; + u8 v; + while (true) + { + stream.get(v); + if (v != 0xFF) break; // skip padding bytes + empty++; + if (empty == size) return; + }; + + if ((v & 0xF0) == 0x20 && (size - empty) >= 5) // pts only + { + new_au = true; + pts = stream.get_ts(v); + stream.skip(size - empty - 5); + } + else + { + new_au = true; + if ((v & 0xF0) != 0x30 || (size - empty) < 10) + { + cellDmux->Error("PesHeader(): pts not found"); + Emu.Pause(); + } + pts = stream.get_ts(v); + stream.get(v); + if ((v & 0xF0) != 0x10) + { + cellDmux->Error("PesHeader(): dts not found"); + Emu.Pause(); + } + dts = stream.get_ts(v); + stream.skip(size - empty - 10); + } + } +} + +bool ElementaryStream::is_full() +{ + if (released < put_count) + { + u32 first = entries.Peek(); + if (first >= put) + { + return (first - put) < GetMaxAU(); + } + else + { + // probably, always false + return (put + GetMaxAU()) > (memAddr + memSize); + } + } + else + { + return false; + } +} + +const u32 ElementaryStream::GetMaxAU() const +{ + return (fidMajor == 0xbd) ? 4096 : 640 * 1024 + 128; // TODO +} + +u32 ElementaryStream::freespace() +{ + if (size > GetMaxAU()) + { + cellDmux->Error("es::freespace(): last_size too big (size=0x%x, max_au=0x%x)", size, GetMaxAU()); + Emu.Pause(); + return 0; + } + return GetMaxAU() - size; +} + +bool ElementaryStream::hasunseen() +{ + std::lock_guard lock(m_mutex); + return peek_count < put_count; +} + +bool ElementaryStream::hasdata() +{ + std::lock_guard lock(m_mutex); + return size != 0; +} + +bool ElementaryStream::isfull() +{ + std::lock_guard lock(m_mutex); + return is_full(); +} + +void ElementaryStream::finish(DemuxerStream& stream) // not multithread-safe +{ + u32 addr; + { + std::lock_guard lock(m_mutex); + //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); + + addr = put; + /*if (!first) + { + first = put; + } + if (!peek) + { + peek = put; + }*/ + + mem_ptr_t info(put); + //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::finish(): (%s) size = 0x%x, info_addr=0x%x, pts = 0x%x", + //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), + //(u32)info->auSize, put, (u32)info->ptsLower); + + u32 new_addr = a128(put + 128 + size); + put = ((new_addr + GetMaxAU()) > (memAddr + memSize)) + ? memAddr : new_addr; + + size = 0; + + put_count++; + //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); + } + if (!entries.Push(addr)) + { + cellDmux->Error("es::finish() aborted (no space)"); + } +} + +void ElementaryStream::push(DemuxerStream& stream, u32 sz, PesHeader& pes) +{ + std::lock_guard lock(m_mutex); + + if (is_full()) + { + cellDmux->Error("es::push(): buffer is full"); + Emu.Pause(); + return; + } + + u32 data_addr = put + 128 + size; + size += sz; + memcpy(Memory + data_addr, Memory + stream.addr, sz); + stream.skip(sz); + + mem_ptr_t info(put); + info->auAddr = put + 128; + info->auSize = size; + if (pes.new_au) + { + info->dts.lower = (u32)pes.dts; + info->dts.upper = (u32)(pes.dts >> 32); + info->pts.lower = (u32)pes.pts; + info->pts.upper = (u32)(pes.pts >> 32); + info->isRap = false; // TODO: set valid value + info->reserved = 0; + info->userData = stream.userdata; + } + + mem_ptr_t tail(put + sizeof(CellDmuxAuInfoEx)); + tail->reserved1 = 0; + + mem_ptr_t inf(put + 64); + inf->auAddr = put + 128; + inf->auSize = size; + if (pes.new_au) + { + inf->dtsLower = (u32)pes.dts; + inf->dtsUpper = (u32)(pes.dts >> 32); + inf->ptsLower = (u32)pes.pts; + inf->ptsUpper = (u32)(pes.pts >> 32); + inf->auMaxSize = 0; // ????? + inf->userData = stream.userdata; + } +} + +bool ElementaryStream::release() +{ + std::lock_guard lock(m_mutex); + //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::release(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); + if (released >= put_count) + { + cellDmux->Error("es::release(): buffer is empty"); + return false; + } + + u32 addr = entries.Peek(); + + mem_ptr_t info(addr); + //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::release(): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", + //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), (u32)info->auSize, first, (u32)info->ptsLower); + + if (released >= peek_count) + { + cellDmux->Error("es::release(): buffer has not been seen yet"); + return false; + } + + /*u32 new_addr = a128(info.GetAddr() + 128 + info->auSize); + + if (new_addr == put) + { + first = 0; + } + else if ((new_addr + GetMaxAU()) > (memAddr + memSize)) + { + first = memAddr; + } + else + { + first = new_addr; + }*/ + + released++; + if (!entries.Pop(addr)) + { + cellDmux->Error("es::release(): entries.Pop() aborted (no entries found)"); + return false; + } + //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::release(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); + return true; +} + +bool ElementaryStream::peek(u32& out_data, bool no_ex, u32& out_spec, bool update_index) +{ + std::lock_guard lock(m_mutex); + //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::peek(%sAu%s): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", wxString(update_index ? "Get" : "Peek").wx_str(), + //wxString(no_ex ? "" : "Ex").wx_str(), peek, first, put, size); + if (peek_count >= put_count) return false; + + if (peek_count < released) + { + cellDmux->Error("es::peek(): sequence error: peek_count < released (peek_count=%d, released=%d)", peek_count, released); + Emu.Pause(); + return false; + } + + u32 addr = entries.Peek(peek_count - released); + mem_ptr_t info(addr); + //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::peek(%sAu(Ex)): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", + //wxString(update_index ? "Get" : "Peek").wx_str(), + //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), (u32)info->auSize, peek, (u32)info->ptsLower); + + out_data = addr; + out_spec = out_data + sizeof(CellDmuxAuInfoEx); + if (no_ex) out_data += 64; + + if (update_index) + { + /*u32 new_addr = a128(peek + 128 + info->auSize); + if (new_addr == put) + { + peek = 0; + } + else if ((new_addr + GetMaxAU()) > (memAddr + memSize)) + { + peek = memAddr; + } + else + { + peek = new_addr; + }*/ + peek_count++; + } + + //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::peek(%sAu%s): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", wxString(update_index ? "Get" : "Peek").wx_str(), + //wxString(no_ex ? "" : "Ex").wx_str(), peek, first, put, size); + return true; +} + +void ElementaryStream::reset() +{ + std::lock_guard lock(m_mutex); + //first = 0; + //peek = 0; + put = memAddr; + size = 0; + entries.Clear(); + put_count = 0; + released = 0; + peek_count = 0; +} + void dmuxQueryAttr(u32 info_addr /* may be 0 */, mem_ptr_t attr) { attr->demuxerVerLower = 0x280000; // TODO: check values @@ -45,7 +337,7 @@ u32 dmuxOpen(Demuxer* data) thread t("Demuxer[" + std::to_string(dmux_id) + "] Thread", [&]() { - LOG_NOTICE(HLE, "Demuxer thread started (mem=0x%x, size=0x%x, cb=0x%x, arg=0x%x)", dmux.memAddr, dmux.memSize, dmux.cbFunc, dmux.cbArg); + cellDmux->Notice("Demuxer thread started (mem=0x%x, size=0x%x, cb=0x%x, arg=0x%x)", dmux.memAddr, dmux.memSize, dmux.cbFunc, dmux.cbArg); DemuxerTask task; DemuxerStream stream; @@ -132,7 +424,7 @@ u32 dmuxOpen(Demuxer* data) if (!pes.new_au) // temporarily { - LOG_ERROR(HLE, "No pts info found"); + cellDmux->Error("No pts info found"); } // read additional header: @@ -262,7 +554,7 @@ u32 dmuxOpen(Demuxer* data) case 0x1dc: case 0x1dd: case 0x1de: case 0x1df: { // unknown - LOG_WARNING(HLE, "Unknown MPEG stream found"); + cellDmux->Warning("Unknown MPEG stream found"); stream.skip(4); stream.get(len); stream.skip(len); @@ -271,7 +563,7 @@ u32 dmuxOpen(Demuxer* data) case USER_DATA_START_CODE: { - LOG_ERROR(HLE, "USER_DATA_START_CODE found"); + cellDmux->Error("USER_DATA_START_CODE found"); return; } @@ -298,7 +590,7 @@ u32 dmuxOpen(Demuxer* data) { if (task.stream.discontinuity) { - LOG_WARNING(HLE, "dmuxSetStream (beginning)"); + cellDmux->Warning("dmuxSetStream (beginning)"); for (u32 i = 0; i < 192; i++) { if (esALL[i]) @@ -312,7 +604,7 @@ u32 dmuxOpen(Demuxer* data) if (updates_count != updates_signaled) { - LOG_ERROR(HLE, "dmuxSetStream: stream update inconsistency (input=%d, signaled=%d)", updates_count, updates_signaled); + cellDmux->Error("dmuxSetStream: stream update inconsistency (input=%d, signaled=%d)", updates_count, updates_signaled); return; } @@ -351,7 +643,7 @@ u32 dmuxOpen(Demuxer* data) case dmuxClose: { dmux.is_finished = true; - LOG_NOTICE(HLE, "Demuxer thread ended"); + cellDmux->Notice("Demuxer thread ended"); return; } @@ -375,7 +667,7 @@ u32 dmuxOpen(Demuxer* data) } else { - LOG_WARNING(HLE, "dmuxEnableEs: (TODO) unsupported filter (0x%x, 0x%x, 0x%x, 0x%x)", es.fidMajor, es.fidMinor, es.sup1, es.sup2); + cellDmux->Warning("dmuxEnableEs: (TODO) unsupported filter (0x%x, 0x%x, 0x%x, 0x%x)", es.fidMajor, es.fidMinor, es.sup1, es.sup2); } es.dmux = &dmux; } @@ -386,7 +678,7 @@ u32 dmuxOpen(Demuxer* data) ElementaryStream& es = *task.es.es_ptr; if (es.dmux != &dmux) { - LOG_WARNING(HLE, "dmuxDisableEs: invalid elementary stream"); + cellDmux->Warning("dmuxDisableEs: invalid elementary stream"); break; } for (u32 i = 0; i < 192; i++) @@ -444,11 +736,11 @@ u32 dmuxOpen(Demuxer* data) break; default: - LOG_ERROR(HLE, "Demuxer thread error: unknown task(%d)", task.type); + cellDmux->Error("Demuxer thread error: unknown task(%d)", task.type); return; } } - LOG_WARNING(HLE, "Demuxer thread aborted"); + cellDmux->Warning("Demuxer thread aborted"); }); t.detach(); @@ -552,7 +844,7 @@ int cellDmuxClose(u32 demuxerHandle) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellDmuxClose(%d) aborted", demuxerHandle); + cellDmux->Warning("cellDmuxClose(%d) aborted", demuxerHandle); return CELL_OK; } @@ -579,7 +871,7 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle); + cellDmux->Warning("cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle); return CELL_OK; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -598,12 +890,12 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize u32 addr; if (!dmux->fbSetStream.Pop(addr)) { - LOG_WARNING(HLE, "cellDmuxSetStream(%d) aborted (fbSetStream.Pop())", demuxerHandle); + cellDmux->Warning("cellDmuxSetStream(%d) aborted (fbSetStream.Pop())", demuxerHandle); return CELL_OK; } if (addr != info.addr) { - LOG_ERROR(HLE, "cellDmuxSetStream(%d): wrong stream queued (right=0x%x, queued=0x%x)", demuxerHandle, info.addr, addr); + cellDmux->Error("cellDmuxSetStream(%d): wrong stream queued (right=0x%x, queued=0x%x)", demuxerHandle, info.addr, addr); Emu.Pause(); } return CELL_OK; @@ -639,12 +931,12 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) u32 addr; if (!dmux->fbSetStream.Pop(addr)) { - LOG_WARNING(HLE, "cellDmuxResetStreamAndWaitDone(%d) aborted (fbSetStream.Pop())", demuxerHandle); + cellDmux->Warning("cellDmuxResetStreamAndWaitDone(%d) aborted (fbSetStream.Pop())", demuxerHandle); return CELL_OK; } if (addr != 0) { - LOG_ERROR(HLE, "cellDmuxResetStreamAndWaitDone(%d): wrong stream queued (0x%x)", demuxerHandle, addr); + cellDmux->Error("cellDmuxResetStreamAndWaitDone(%d): wrong stream queued (0x%x)", demuxerHandle, addr); Emu.Pause(); } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index db6e39b5c8..cd0e5c6af7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -362,53 +362,7 @@ struct PesHeader u8 size; bool new_au; - PesHeader(DemuxerStream& stream) - : pts(0xffffffffffffffff) - , dts(0xffffffffffffffff) - , size(0) - , new_au(false) - { - u16 header; - stream.get(header); - stream.get(size); - if (size) - { - u8 empty = 0; - u8 v; - while (true) - { - stream.get(v); - if (v != 0xFF) break; // skip padding bytes - empty++; - if (empty == size) return; - }; - - if ((v & 0xF0) == 0x20 && (size - empty) >= 5) // pts only - { - new_au = true; - pts = stream.get_ts(v); - stream.skip(size - empty - 5); - } - else - { - new_au = true; - if ((v & 0xF0) != 0x30 || (size - empty) < 10) - { - LOG_ERROR(HLE, "PesHeader(): pts not found"); - Emu.Pause(); - } - pts = stream.get_ts(v); - stream.get(v); - if ((v & 0xF0) != 0x10) - { - LOG_ERROR(HLE, "PesHeader(): dts not found"); - Emu.Pause(); - } - dts = stream.get_ts(v); - stream.skip(size - empty - 10); - } - } - } + PesHeader(DemuxerStream& stream); }; class ElementaryStream; @@ -493,26 +447,7 @@ class ElementaryStream //u32 first; // AU that will be released //u32 peek; // AU that will be obtained by GetAu(Ex)/PeekAu(Ex) - bool is_full() - { - if (released < put_count) - { - u32 first = entries.Peek(); - if (first >= put) - { - return (first - put) < GetMaxAU(); - } - else - { - // probably, always false - return (put + GetMaxAU()) > (memAddr + memSize); - } - } - else - { - return false; - } - } + bool is_full(); public: Demuxer* dmux; @@ -548,228 +483,23 @@ public: { } - const u32 GetMaxAU() const - { - return (fidMajor == 0xbd) ? 4096 : 640 * 1024 + 128; // TODO - } + const u32 GetMaxAU() const; - u32 freespace() - { - if (size > GetMaxAU()) - { - LOG_ERROR(HLE, "es::freespace(): last_size too big (size=0x%x, max_au=0x%x)", size, GetMaxAU()); - Emu.Pause(); - return 0; - } - return GetMaxAU() - size; - } + u32 freespace(); - bool hasunseen() - { - std::lock_guard lock(m_mutex); - return peek_count < put_count; - } + bool hasunseen(); - bool hasdata() - { - std::lock_guard lock(m_mutex); - return size; - } + bool hasdata(); - bool isfull() - { - std::lock_guard lock(m_mutex); - return is_full(); - } + bool isfull(); - void finish(DemuxerStream& stream) // not multithread-safe - { - u32 addr; - { - std::lock_guard lock(m_mutex); - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); + void finish(DemuxerStream& stream); - addr = put; - /*if (!first) - { - first = put; - } - if (!peek) - { - peek = put; - }*/ + void push(DemuxerStream& stream, u32 sz, PesHeader& pes); - mem_ptr_t info(put); - //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::finish(): (%s) size = 0x%x, info_addr=0x%x, pts = 0x%x", - //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), - //(u32)info->auSize, put, (u32)info->ptsLower); + bool release(); - u32 new_addr = a128(put + 128 + size); - put = ((new_addr + GetMaxAU()) > (memAddr + memSize)) - ? memAddr : new_addr; + bool peek(u32& out_data, bool no_ex, u32& out_spec, bool update_index); - size = 0; - - put_count++; - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); - } - if (!entries.Push(addr)) - { - LOG_ERROR(HLE, "es::finish() aborted (no space)"); - } - } - - void push(DemuxerStream& stream, u32 sz, PesHeader& pes) - { - std::lock_guard lock(m_mutex); - - if (is_full()) - { - LOG_ERROR(HLE, "es::push(): buffer is full"); - Emu.Pause(); - return; - } - - u32 data_addr = put + 128 + size; - size += sz; - memcpy(Memory + data_addr, Memory + stream.addr, sz); - stream.skip(sz); - - mem_ptr_t info(put); - info->auAddr = put + 128; - info->auSize = size; - if (pes.new_au) - { - info->dts.lower = (u32)pes.dts; - info->dts.upper = (u32)(pes.dts >> 32); - info->pts.lower = (u32)pes.pts; - info->pts.upper = (u32)(pes.pts >> 32); - info->isRap = false; // TODO: set valid value - info->reserved = 0; - info->userData = stream.userdata; - } - - mem_ptr_t tail(put + sizeof(CellDmuxAuInfoEx)); - tail->reserved1 = 0; - - mem_ptr_t inf(put + 64); - inf->auAddr = put + 128; - inf->auSize = size; - if (pes.new_au) - { - inf->dtsLower = (u32)pes.dts; - inf->dtsUpper = (u32)(pes.dts >> 32); - inf->ptsLower = (u32)pes.pts; - inf->ptsUpper = (u32)(pes.pts >> 32); - inf->auMaxSize = 0; // ????? - inf->userData = stream.userdata; - } - } - - bool release() - { - std::lock_guard lock(m_mutex); - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::release(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); - if (released >= put_count) - { - LOG_ERROR(HLE, "es::release(): buffer is empty"); - return false; - } - - u32 addr = entries.Peek(); - - mem_ptr_t info(addr); - //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::release(): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", - //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), (u32)info->auSize, first, (u32)info->ptsLower); - - if (released >= peek_count) - { - LOG_ERROR(HLE, "es::release(): buffer has not been seen yet"); - return false; - } - - /*u32 new_addr = a128(info.GetAddr() + 128 + info->auSize); - - if (new_addr == put) - { - first = 0; - } - else if ((new_addr + GetMaxAU()) > (memAddr + memSize)) - { - first = memAddr; - } - else - { - first = new_addr; - }*/ - - released++; - if (!entries.Pop(addr)) - { - LOG_ERROR(HLE, "es::release(): entries.Pop() aborted (no entries found)"); - return false; - } - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::release(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size); - return true; - } - - bool peek(u32& out_data, bool no_ex, u32& out_spec, bool update_index) - { - std::lock_guard lock(m_mutex); - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::peek(%sAu%s): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", wxString(update_index ? "Get" : "Peek").wx_str(), - //wxString(no_ex ? "" : "Ex").wx_str(), peek, first, put, size); - if (peek_count >= put_count) return false; - - if (peek_count < released) - { - LOG_ERROR(HLE, "es::peek(): sequence error: peek_count < released (peek_count=%d, released=%d)", peek_count, released); - Emu.Pause(); - return false; - } - - u32 addr = entries.Peek(peek_count - released); - mem_ptr_t info(addr); - //if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::peek(%sAu(Ex)): (%s) size = 0x%x, info = 0x%x, pts = 0x%x", - //wxString(update_index ? "Get" : "Peek").wx_str(), - //wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(), (u32)info->auSize, peek, (u32)info->ptsLower); - - out_data = addr; - out_spec = out_data + sizeof(CellDmuxAuInfoEx); - if (no_ex) out_data += 64; - - if (update_index) - { - /*u32 new_addr = a128(peek + 128 + info->auSize); - if (new_addr == put) - { - peek = 0; - } - else if ((new_addr + GetMaxAU()) > (memAddr + memSize)) - { - peek = memAddr; - } - else - { - peek = new_addr; - }*/ - peek_count++; - } - - //if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::peek(%sAu%s): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", wxString(update_index ? "Get" : "Peek").wx_str(), - //wxString(no_ex ? "" : "Ex").wx_str(), peek, first, put, size); - return true; - } - - void reset() - { - std::lock_guard lock(m_mutex); - //first = 0; - //peek = 0; - put = memAddr; - size = 0; - entries.Clear(); - put_count = 0; - released = 0; - peek_count = 0; - } + void reset(); }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp index a64a9a914f..eadca3d19f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellFiber_init(); Module cellFiber(0x0043, cellFiber_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp index 8629065669..5987358ef3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp @@ -1,13 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" + +#include "stblib/stb_truetype.h" #include "Emu/FS/vfsFile.h" #include "cellFont.h" -#include "stblib/stb_truetype.h" //void cellFont_init(); //void cellFont_load(); @@ -15,224 +12,6 @@ //Module cellFont(0x0019, cellFont_init, cellFont_load, cellFont_unload); Module *cellFont = nullptr; -// Font Set Types -enum -{ - CELL_FONT_TYPE_RODIN_SANS_SERIF_LATIN = 0x00000000, - CELL_FONT_TYPE_RODIN_SANS_SERIF_LIGHT_LATIN = 0x00000001, - CELL_FONT_TYPE_RODIN_SANS_SERIF_BOLD_LATIN = 0x00000002, - CELL_FONT_TYPE_RODIN_SANS_SERIF_LATIN2 = 0x00000018, - CELL_FONT_TYPE_RODIN_SANS_SERIF_LIGHT_LATIN2 = 0x00000019, - CELL_FONT_TYPE_RODIN_SANS_SERIF_BOLD_LATIN2 = 0x0000001a, - CELL_FONT_TYPE_MATISSE_SERIF_LATIN = 0x00000020, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_JAPANESE = 0x00000008, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_LIGHT_JAPANESE = 0x00000009, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_BOLD_JAPANESE = 0x0000000a, - CELL_FONT_TYPE_YD_GOTHIC_KOREAN = 0x0000000c, - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_LATIN = 0x00000040, - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_LATIN2 = 0x00000041, - CELL_FONT_TYPE_VAGR_SANS_SERIF_ROUND = 0x00000043, - CELL_FONT_TYPE_VAGR_SANS_SERIF_ROUND_LATIN2 = 0x00000044, - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_JAPANESE = 0x00000048, - - CELL_FONT_TYPE_NEWRODIN_GOTHIC_JP_SET = 0x00000100, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_LATIN_SET = 0x00000101, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN_SET = 0x00000104, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN2_SET = 0x00000204, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN2_SET = 0x00000201, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_DFHEI5_SET = 0x00000108, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_DFHEI5_RODIN_SET = 0x00000109, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_DFHEI5_RODIN2_SET = 0x00000209, - CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_TCH_SET = 0x0000010a, - CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN_TCH_SET = 0x0000010b, - CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN2_TCH_SET = 0x0000020b, - CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_SCH_SET = 0x0000010c, - CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN_SCH_SET = 0x0000010d, - CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN2_SCH_SET = 0x0000020d, - - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_RSANS_SET = 0x00300104, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_RSANS_SET = 0x00300105, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_JP_SET = 0x00300107, - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_YG_DFHEI5_RSANS_SET = 0x00300109, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS_SET = 0x0030010F, - CELL_FONT_TYPE_VAGR_SEURAT_CAPIE_MARU_GOTHIC_RSANS_SET = 0x00300124, - CELL_FONT_TYPE_VAGR_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS_SET = 0x00300129, - - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_LIGHT_SET = 0x00040100, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN_LIGHT_SET = 0x00040101, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN2_LIGHT_SET = 0x00040201, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN_LIGHT_SET = 0x00040104, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN2_LIGHT_SET = 0x00040204, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_BOLD_SET = 0x00070100, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN_BOLD_SET = 0x00070101, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN2_BOLD_SET = 0x00070201, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN_BOLD_SET = 0x00070104, - CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN2_BOLD_SET = 0x00070204, - - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_RSANS2_SET = 0x00300204, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_RSANS2_SET = 0x00300205, - CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_YG_DFHEI5_RSANS2_SET = 0x00300209, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS2_SET = 0x0030020F, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_VAGR2_SET = 0x00300229, - CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_VAGR2_SET = 0x00300224, -}; - -enum -{ - CELL_FONT_MAP_FONT = 0, - CELL_FONT_MAP_UNICODE = 1, -}; - -struct CellFontConfig -{ - struct { - be_t buffer_addr; - be_t size; - } FileCache; - - be_t userFontEntryMax; - be_t userFontEntrys_addr; - be_t flags; -}; - -struct CellFontRenderer -{ - void *systemReserved[64]; -}; - -//Custom enum to determine the origin of a CellFont object -enum -{ - CELL_FONT_OPEN_FONTSET, - CELL_FONT_OPEN_FONT_FILE, - CELL_FONT_OPEN_FONT_INSTANCE, - CELL_FONT_OPEN_MEMORY, -}; - -struct CellFont -{ - //void* SystemReserved[64]; - be_t scale_x; - be_t scale_y; - be_t slant; - be_t renderer_addr; - - stbtt_fontinfo stbfont; - be_t fontdata_addr; - be_t origin; -}; - -struct CellFontType -{ - be_t type; - be_t map; -}; - -struct CellFontInitGraphicsConfigGcm -{ - be_t configType; - struct { - be_t address; - be_t size; - } GraphicsMemory; - struct { - be_t address; - be_t size; - } MappedMainMemory; - struct { - be_t slotNumber; - be_t slotCount; - } VertexShader; -}; - -struct CellFontGraphics -{ - u32 graphicsType; - u32 SystemClosed_addr; -}; - -struct CellFontHorizontalLayout -{ - be_t baseLineY; - be_t lineHeight; - be_t effectHeight; -}; - -struct CellFontVerticalLayout -{ - be_t baseLineX; - be_t lineWidth; - be_t effectWidth; -}; - -struct CellFontGlyphMetrics -{ - be_t width; - be_t height; - struct { - be_t bearingX; - be_t bearingY; - be_t advance; - } Horizontal; - struct { - be_t bearingX; - be_t bearingY; - be_t advance; - } Vertical; -}; - -struct CellFontImageTransInfo -{ - be_t Image_addr; - be_t imageWidthByte; - be_t imageWidth; - be_t imageHeight; - be_t Surface_addr; - be_t surfWidthByte; -}; - -struct CellFontRendererConfig -{ - struct BufferingPolicy - { - be_t buffer; - be_t initSize; - be_t maxSize; - be_t expandSize; - be_t resetSize; - }; -}; - -struct CellFontRenderSurface -{ - be_t buffer_addr; - be_t widthByte; - be_t pixelSizeByte; - be_t width, height; - struct { - be_t x0, y0; - be_t x1, y1; - } Scissor; -}; - -// Internal Datatypes -struct CCellFontInternal //Module cellFont -{ - u32 m_buffer_addr, m_buffer_size; - u32 m_userFontEntrys_addr, m_userFontEntryMax; - - bool m_bInitialized; - bool m_bFontGcmInitialized; - - CCellFontInternal() - : m_buffer_addr(0) - , m_buffer_size(0) - , m_bInitialized(false) - , m_bFontGcmInitialized(false) - { - } -}; - CCellFontInternal* s_fontInternalInstance = nullptr; // Functions @@ -296,7 +75,9 @@ int cellFontOpenFontMemory(mem_ptr_t library, u32 fontAddr, u32 if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; - if (!stbtt_InitFont(&(font->stbfont), (unsigned char*)Memory.VirtualToRealAddr(fontAddr), 0)) + font->stbfont = (stbtt_fontinfo*)((u8*)&(font->stbfont) + sizeof(void*)); // hack: use next bytes of the struct + + if (!stbtt_InitFont(font->stbfont, (unsigned char*)Memory.VirtualToRealAddr(fontAddr), 0)) return CELL_FONT_ERROR_FONT_OPEN_FAILED; font->renderer_addr = 0; @@ -484,8 +265,8 @@ int cellFontGetHorizontalLayout(mem_ptr_t font, mem_ptr_tstbfont), font->scale_y); - stbtt_GetFontVMetrics(&(font->stbfont), &ascent, &descent, &lineGap); + float scale = stbtt_ScaleForPixelHeight(font->stbfont, font->scale_y); + stbtt_GetFontVMetrics(font->stbfont, &ascent, &descent, &lineGap); layout->baseLineY = ascent * scale; layout->lineHeight = (ascent-descent+lineGap) * scale; @@ -559,14 +340,14 @@ int cellFontRenderCharGlyphImage(mem_ptr_t font, u32 code, mem_ptr_tstbfont), font->scale_y); - unsigned char* box = stbtt_GetCodepointBitmap(&(font->stbfont), scale, scale, code, &width, &height, &xoff, &yoff); + float scale = stbtt_ScaleForPixelHeight(font->stbfont, font->scale_y); + unsigned char* box = stbtt_GetCodepointBitmap(font->stbfont, scale, scale, code, &width, &height, &xoff, &yoff); if (!box) return CELL_OK; // Get the baseLineY value int baseLineY; int ascent, descent, lineGap; - stbtt_GetFontVMetrics(&(font->stbfont), &ascent, &descent, &lineGap); + stbtt_GetFontVMetrics(font->stbfont, &ascent, &descent, &lineGap); baseLineY = ascent * scale; // Move the rendered character to the surface @@ -641,9 +422,9 @@ int cellFontGetCharGlyphMetrics(mem_ptr_t font, u32 code, mem_ptr_tstbfont), font->scale_y); - stbtt_GetCodepointBox(&(font->stbfont), code, &x0, &y0, &x1, &y1); - stbtt_GetCodepointHMetrics(&(font->stbfont), code, &advanceWidth, &leftSideBearing); + float scale = stbtt_ScaleForPixelHeight(font->stbfont, font->scale_y); + stbtt_GetCodepointBox(font->stbfont, code, &x0, &y0, &x1, &y1); + stbtt_GetCodepointHMetrics(font->stbfont, code, &advanceWidth, &leftSideBearing); // TODO: Add the rest of the information metrics->width = (x1-x0) * scale; diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.h b/rpcs3/Emu/SysCalls/Modules/cellFont.h index f2cf9f1321..2f4dee8410 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.h +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.h @@ -44,4 +44,225 @@ struct CellFontMemoryInterface //CellFontFreeCallback Free; //CellFontReallocCallback Realloc; //CellFontCallocCallback Calloc; +}; + +// Font Set Types +enum +{ + CELL_FONT_TYPE_RODIN_SANS_SERIF_LATIN = 0x00000000, + CELL_FONT_TYPE_RODIN_SANS_SERIF_LIGHT_LATIN = 0x00000001, + CELL_FONT_TYPE_RODIN_SANS_SERIF_BOLD_LATIN = 0x00000002, + CELL_FONT_TYPE_RODIN_SANS_SERIF_LATIN2 = 0x00000018, + CELL_FONT_TYPE_RODIN_SANS_SERIF_LIGHT_LATIN2 = 0x00000019, + CELL_FONT_TYPE_RODIN_SANS_SERIF_BOLD_LATIN2 = 0x0000001a, + CELL_FONT_TYPE_MATISSE_SERIF_LATIN = 0x00000020, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_JAPANESE = 0x00000008, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_LIGHT_JAPANESE = 0x00000009, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_BOLD_JAPANESE = 0x0000000a, + CELL_FONT_TYPE_YD_GOTHIC_KOREAN = 0x0000000c, + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_LATIN = 0x00000040, + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_LATIN2 = 0x00000041, + CELL_FONT_TYPE_VAGR_SANS_SERIF_ROUND = 0x00000043, + CELL_FONT_TYPE_VAGR_SANS_SERIF_ROUND_LATIN2 = 0x00000044, + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_JAPANESE = 0x00000048, + + CELL_FONT_TYPE_NEWRODIN_GOTHIC_JP_SET = 0x00000100, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_LATIN_SET = 0x00000101, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN_SET = 0x00000104, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN2_SET = 0x00000204, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN2_SET = 0x00000201, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_DFHEI5_SET = 0x00000108, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_DFHEI5_RODIN_SET = 0x00000109, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_DFHEI5_RODIN2_SET = 0x00000209, + CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_TCH_SET = 0x0000010a, + CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN_TCH_SET = 0x0000010b, + CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN2_TCH_SET = 0x0000020b, + CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_SCH_SET = 0x0000010c, + CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN_SCH_SET = 0x0000010d, + CELL_FONT_TYPE_DFHEI5_GOTHIC_YG_NEWRODIN_RODIN2_SCH_SET = 0x0000020d, + + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_RSANS_SET = 0x00300104, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_RSANS_SET = 0x00300105, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_JP_SET = 0x00300107, + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_YG_DFHEI5_RSANS_SET = 0x00300109, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS_SET = 0x0030010F, + CELL_FONT_TYPE_VAGR_SEURAT_CAPIE_MARU_GOTHIC_RSANS_SET = 0x00300124, + CELL_FONT_TYPE_VAGR_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS_SET = 0x00300129, + + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_LIGHT_SET = 0x00040100, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN_LIGHT_SET = 0x00040101, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN2_LIGHT_SET = 0x00040201, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN_LIGHT_SET = 0x00040104, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN2_LIGHT_SET = 0x00040204, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_BOLD_SET = 0x00070100, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN_BOLD_SET = 0x00070101, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_YG_RODIN2_BOLD_SET = 0x00070201, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN_BOLD_SET = 0x00070104, + CELL_FONT_TYPE_NEWRODIN_GOTHIC_RODIN2_BOLD_SET = 0x00070204, + + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_RSANS2_SET = 0x00300204, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_RSANS2_SET = 0x00300205, + CELL_FONT_TYPE_SEURAT_MARU_GOTHIC_YG_DFHEI5_RSANS2_SET = 0x00300209, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS2_SET = 0x0030020F, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_VAGR2_SET = 0x00300229, + CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_VAGR2_SET = 0x00300224, +}; + +enum +{ + CELL_FONT_MAP_FONT = 0, + CELL_FONT_MAP_UNICODE = 1, +}; + +struct CellFontConfig +{ + struct { + be_t buffer_addr; + be_t size; + } FileCache; + + be_t userFontEntryMax; + be_t userFontEntrys_addr; + be_t flags; +}; + +struct CellFontRenderer +{ + void *systemReserved[64]; +}; + +//Custom enum to determine the origin of a CellFont object +enum +{ + CELL_FONT_OPEN_FONTSET, + CELL_FONT_OPEN_FONT_FILE, + CELL_FONT_OPEN_FONT_INSTANCE, + CELL_FONT_OPEN_MEMORY, +}; + +struct stbtt_fontinfo; + +struct CellFont +{ + //void* SystemReserved[64]; + be_t scale_x; + be_t scale_y; + be_t slant; + be_t renderer_addr; + + be_t fontdata_addr; + be_t origin; + stbtt_fontinfo* stbfont; + // hack: don't place anything after pointer +}; + +struct CellFontType +{ + be_t type; + be_t map; +}; + +struct CellFontInitGraphicsConfigGcm +{ + be_t configType; + struct { + be_t address; + be_t size; + } GraphicsMemory; + struct { + be_t address; + be_t size; + } MappedMainMemory; + struct { + be_t slotNumber; + be_t slotCount; + } VertexShader; +}; + +struct CellFontGraphics +{ + u32 graphicsType; + u32 SystemClosed_addr; +}; + +struct CellFontHorizontalLayout +{ + be_t baseLineY; + be_t lineHeight; + be_t effectHeight; +}; + +struct CellFontVerticalLayout +{ + be_t baseLineX; + be_t lineWidth; + be_t effectWidth; +}; + +struct CellFontGlyphMetrics +{ + be_t width; + be_t height; + struct { + be_t bearingX; + be_t bearingY; + be_t advance; + } Horizontal; + struct { + be_t bearingX; + be_t bearingY; + be_t advance; + } Vertical; +}; + +struct CellFontImageTransInfo +{ + be_t Image_addr; + be_t imageWidthByte; + be_t imageWidth; + be_t imageHeight; + be_t Surface_addr; + be_t surfWidthByte; +}; + +struct CellFontRendererConfig +{ + struct BufferingPolicy + { + be_t buffer; + be_t initSize; + be_t maxSize; + be_t expandSize; + be_t resetSize; + }; +}; + +struct CellFontRenderSurface +{ + be_t buffer_addr; + be_t widthByte; + be_t pixelSizeByte; + be_t width, height; + struct { + be_t x0, y0; + be_t x1, y1; + } Scissor; +}; + +// Internal Datatypes +struct CCellFontInternal //Module cellFont +{ + u32 m_buffer_addr, m_buffer_size; + u32 m_userFontEntrys_addr, m_userFontEntryMax; + + bool m_bInitialized; + bool m_bFontGcmInitialized; + + CCellFontInternal() + : m_buffer_addr(0) + , m_buffer_size(0) + , m_bInitialized(false) + , m_bFontGcmInitialized(false) + { + } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp b/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp index cf33200cb3..7b42bf90fd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp @@ -1,10 +1,9 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" + #include "cellFont.h" +#include "cellFontFT.h" //void cellFontFT_init(); //void cellFontFT_load(); @@ -12,33 +11,6 @@ //Module cellFontFT(0x001a, cellFontFT_init, cellFontFT_load, cellFontFT_unload); Module *cellFontFT = nullptr; -struct CellFontLibraryConfigFT -{ - u32 library_addr; //void* - CellFontMemoryInterface MemoryIF; -}; - -struct CellFontRendererConfigFT -{ - struct { - u32 buffer_addr; //void* - u32 initSize; - u32 maxSize; - u32 expandSize; - u32 resetSize; - } BufferingPolicy; -}; - -struct CCellFontFTInternal -{ - bool m_bInitialized; - - CCellFontFTInternal() - : m_bInitialized(false) - { - } -}; - CCellFontFTInternal* s_fontFtInternalInstance = nullptr; int cellFontInitLibraryFreeTypeWithRevision(u64 revisionFlags, mem_ptr_t config, u32 lib_addr_addr) diff --git a/rpcs3/Emu/SysCalls/Modules/cellFontFT.h b/rpcs3/Emu/SysCalls/Modules/cellFontFT.h new file mode 100644 index 0000000000..fb8a0c109f --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellFontFT.h @@ -0,0 +1,28 @@ +#pragma once + +struct CellFontLibraryConfigFT +{ + u32 library_addr; //void* + CellFontMemoryInterface MemoryIF; +}; + +struct CellFontRendererConfigFT +{ + struct { + u32 buffer_addr; //void* + u32 initSize; + u32 maxSize; + u32 expandSize; + u32 resetSize; + } BufferingPolicy; +}; + +struct CCellFontFTInternal +{ + bool m_bInitialized; + + CCellFontFTInternal() + : m_bInitialized(false) + { + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 86611c8edb..95d8bff3f2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -1,14 +1,11 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" + +#include "Utilities/rMsgBox.h" #include "Emu/FS/vfsFile.h" - #include "Loader/PSF.h" - #include "cellGame.h" //void cellGame_init(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 9abe15a9b0..5c994b3baf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -1,12 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/RSX/GCM.h" -#include "Emu/SysCalls/lv2/sys_process.h" -#include "sysPrxForUser.h" + +//#include "Emu/RSX/GCM.h" +//#include "Emu/SysCalls/lv2/sys_process.h" #include "cellGcmSys.h" //void cellGcmSys_init(); @@ -488,7 +486,7 @@ s32 cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) if(current + 8 >= end) { - LOG_WARNING(HLE, "bad flip!"); + cellGcmSys->Error("bad flip!"); //cellGcmCallback(ctxt.GetAddr(), current + 8 - end); //copied: @@ -496,7 +494,7 @@ s32 cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) const s32 res = ctxt->current - ctxt->begin - ctrl.put; - memmove(Memory + ctxt->begin, Memory + ctxt->current - res, res); + memmove(Memory + ctxt->begin, Memory + (ctxt->current - res), res); ctxt->current = ctxt->begin + res; @@ -1169,7 +1167,7 @@ int cellGcmCallback(u32 context_addr, u32 count) const s32 res = ctx.current - ctx.begin - ctrl.put; - memmove(Memory + ctx.begin, Memory + ctx.current - res, res); + memmove(Memory + ctx.begin, Memory + (ctx.current - res), res); ctx.current = ctx.begin + res; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp index 24b5897885..96ebff239e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" + #include "cellGem.h" void cellGem_init(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGem.h b/rpcs3/Emu/SysCalls/Modules/cellGem.h index f94ea35112..712e406998 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGem.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGem.h @@ -1,7 +1,5 @@ #pragma once -#include "cellSpurs.h" - // Had to use define, since enum doesn't allow floats #define CELL_GEM_SPHERE_RADIUS_MM = 22.5f; @@ -90,7 +88,7 @@ struct CellGemAttribute be_t version; be_t max_connect; be_t memory_ptr; - CellSpurs spurs; + be_t spurs_addr; u8 spu_priorities[8]; }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index bf904a2170..b684204a00 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -1,13 +1,11 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" -#include "cellGifDec.h" #include "stblib/stb_image.h" #include "stblib/stb_image.c" // (TODO: Should we put this elsewhere?) +#include "Emu/SysCalls/lv2/lv2Fs.h" +#include "cellGifDec.h" //void cellGifDec_init(); //Module cellGifDec(0xf010, cellGifDec_init); @@ -198,7 +196,7 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m { const int dstOffset = i * bytesPerLine; const int srcOffset = width * nComponents * i; - memcpy(Memory + data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize); + memcpy(Memory + (data.GetAddr() + dstOffset), &image.get()[srcOffset], linesize); } } else @@ -226,7 +224,7 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m output[j + 2] = image.get()[srcOffset + j + 1]; output[j + 3] = image.get()[srcOffset + j + 2]; } - memcpy(Memory + data.GetAddr() + dstOffset, output, linesize); + memcpy(Memory + (data.GetAddr() + dstOffset), output, linesize); } free(output); } @@ -269,7 +267,7 @@ int cellGifDecClose(u32 mainHandle, u32 subHandle) return CELL_GIFDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); - Emu.GetIdManager().RemoveID(subHandle); + cellGifDec->RemoveId(subHandle); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.h b/rpcs3/Emu/SysCalls/Modules/cellGifDec.h index 7ed3160b27..7783855306 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.h @@ -1,6 +1,5 @@ #pragma once - //Return Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellHttpUtil.cpp b/rpcs3/Emu/SysCalls/Modules/cellHttpUtil.cpp index 97f94de794..0548c9bf16 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellHttpUtil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellHttpUtil.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellHttpUtil_init(); Module cellHttpUtil(0x0002, cellHttpUtil_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellImejp.cpp b/rpcs3/Emu/SysCalls/Modules/cellImejp.cpp index b3dc1bd5da..3a8ba92062 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellImejp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellImejp.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellImejp_init(); Module cellImejp(0xf023, cellImejp_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 9c0ccd9377..43fd50ca63 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "cellJpgDec.h" + #include "stblib/stb_image.h" +#include "Emu/SysCalls/lv2/lv2Fs.h" +#include "cellJpgDec.h" //void cellJpgDec_init(); //Module cellJpgDec(0x000f, cellJpgDec_init); @@ -75,7 +75,7 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle) return CELL_JPGDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); - Emu.GetIdManager().RemoveID(subHandle); + cellJpgDec->RemoveId(subHandle); return CELL_OK; } @@ -206,7 +206,7 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m { const int dstOffset = i * bytesPerLine; const int srcOffset = width * nComponents * (flip ? height - i - 1 : i); - memcpy(Memory + data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize); + memcpy(Memory + (data.GetAddr() + dstOffset), &image.get()[srcOffset], linesize); } } else @@ -236,7 +236,7 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m output[j + 2] = image.get()[srcOffset + j + 1]; output[j + 3] = image.get()[srcOffset + j + 2]; } - memcpy(Memory + data.GetAddr() + dstOffset, output, linesize); + memcpy(Memory + (data.GetAddr() + dstOffset), output, linesize); } free(output); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgEnc.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgEnc.cpp index e8aa461f29..c138f37697 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgEnc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgEnc.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellJpgEnc_init(); Module cellJpgEnc(0x003d, cellJpgEnc_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellKey2char.cpp b/rpcs3/Emu/SysCalls/Modules/cellKey2char.cpp index eef9eb72f7..4b1e6d7a10 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellKey2char.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellKey2char.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellKey2char_init(); Module cellKey2char(0x0021, cellKey2char_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index b9eb3f6739..3f4db02ebd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -1,8 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "cellL10n.h" #include #include @@ -286,9 +285,9 @@ int _L10nConvertStr(int src_code, const void* src, size_t * src_len, int dst_cod //TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful. int L10nConvertStr(int src_code, mem8_ptr_t src, mem64_t src_len, int dst_code, mem8_ptr_t dst, mem64_t dst_len) { - LOG_ERROR(HLE, "L10nConvertStr(src_code=%d,src=0x%x,src_len=%ld,dst_code=%d,dst=0x%x,dst_len=%ld)", + cellL10n->Todo("L10nConvertStr(src_code=%d,src=0x%x,src_len=%ld,dst_code=%d,dst=0x%x,dst_len=%ld)", src_code, src.GetAddr(), src_len.GetValue(), dst_code, dst.GetAddr(), dst_len.GetValue()); - LOG_ERROR(HLE, "L10nConvertStr: 1st char at dst: %x(Hex)", *((char*)Memory.VirtualToRealAddr(src.GetAddr()))); + cellL10n->Todo("L10nConvertStr: 1st char at dst: %x(Hex)", *((char*)Memory.VirtualToRealAddr(src.GetAddr()))); #ifdef _MSC_VER unsigned int srcCode = 0, dstCode = 0; //OEM code pages bool src_page_converted = _L10nCodeParse(src_code, srcCode); //Check if code is in list. diff --git a/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp b/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp index 01dd518bba..06bd8d77fa 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellLv2dbg_init(); Module cellLv2dbg(0x002e, cellLv2dbg_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMic.cpp b/rpcs3/Emu/SysCalls/Modules/cellMic.cpp index 23b2a9f61a..a3a665f55e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMic.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMic.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellMic_init(); Module cellMic(0x0022, cellMic_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 21d1d4515a..76b43b0643 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -1,10 +1,11 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "rpcs3.h" +#include "rpcs3.h" +#include "Utilities/rMsgBox.h" +#include "Emu/SysCalls/lv2/sys_time.h" #include "cellSysutil.h" #include "cellMsgDialog.h" @@ -44,8 +45,8 @@ int cellMsgDialogOpen2(u32 type, mem_list_ptr_t msgString, mem_func_ptr_tWarning("Message: \n%s", msgString.GetString()); break; + case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: cellSysutil->Error("Message: \n%s", msgString.GetString()); break; } switch (type & CELL_MSGDIALOG_TYPE_SE_MUTE) // TODO @@ -359,7 +360,7 @@ int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, mem_list_ptr_t msgS return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2) + if (progressBarIndex >= (m_gauge1 ? 1u : 0u) + (m_gauge2 ? 1u : 0u)) { return CELL_MSGDIALOG_ERROR_PARAM; } @@ -388,7 +389,7 @@ int cellMsgDialogProgressBarReset(u32 progressBarIndex) return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2) + if (progressBarIndex >= (m_gauge1 ? 1u : 0u) + (m_gauge2 ? 1u : 0u)) { return CELL_MSGDIALOG_ERROR_PARAM; } @@ -413,7 +414,7 @@ int cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta) return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= (u32)(bool)m_gauge1 + (u32)(bool)m_gauge2) + if (progressBarIndex >= (m_gauge1 ? 1u : 0u) + (m_gauge2 ? 1u : 0u)) { return CELL_MSGDIALOG_ERROR_PARAM; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellMusicDecode.cpp b/rpcs3/Emu/SysCalls/Modules/cellMusicDecode.cpp index 14c64aefd0..82acd368b8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMusicDecode.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMusicDecode.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellMusicDecode_init(); Module cellMusicDecode(0x004f, cellMusicDecode_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMusicExport.cpp b/rpcs3/Emu/SysCalls/Modules/cellMusicExport.cpp index 7ded73fc72..d8699348c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMusicExport.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMusicExport.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellMusicExport_init(); Module cellMusicExport(0xf02c, cellMusicExport_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp index f7d4a2b81c..aa5b1460d3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "cellNetCtl.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp b/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp index 25907207e1..f580c41608 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellOvis_init(); Module cellOvis(0x000b, cellOvis_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index 7332696116..1ea9c785a0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -1,8 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "cellPamf.h" Module *cellPamf = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPhotoDecode.cpp b/rpcs3/Emu/SysCalls/Modules/cellPhotoDecode.cpp index 9281f3c17b..40c68a32b2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPhotoDecode.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPhotoDecode.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellPhotoDecode_init(); Module cellPhotoDecode(0xf02e, cellPhotoDecode_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPhotoExport.cpp b/rpcs3/Emu/SysCalls/Modules/cellPhotoExport.cpp index 71dd6f5bc9..4dd37501d0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPhotoExport.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPhotoExport.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellPhotoExport_init(); Module cellPhotoExport(0xf029, cellPhotoExport_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPhotoImport.cpp b/rpcs3/Emu/SysCalls/Modules/cellPhotoImport.cpp index c5815b9f5b..3427169d02 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPhotoImport.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPhotoImport.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellPhotoImport_init(); Module cellPhotoImport(0xf02b, cellPhotoImport_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 735054e89d..e94e3369c8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "cellPngDec.h" + #include "stblib/stb_image.h" +#include "Emu/SysCalls/lv2/lv2Fs.h" +#include "cellPngDec.h" #include //void cellPngDec_init(); @@ -113,7 +113,7 @@ int cellPngDecClose(u32 mainHandle, u32 subHandle) return CELL_PNGDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); - Emu.GetIdManager().RemoveID(subHandle); + cellPngDec->RemoveId(subHandle); return CELL_OK; } @@ -240,7 +240,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m { const int dstOffset = i * bytesPerLine; const int srcOffset = width * nComponents * (flip ? height - i - 1 : i); - memcpy(Memory + data.GetAddr() + dstOffset, &image.get()[srcOffset], linesize); + memcpy(Memory + (data.GetAddr() + dstOffset), &image.get()[srcOffset], linesize); } } else @@ -270,7 +270,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m output[j + 2] = image.get()[srcOffset + j + 1]; output[j + 3] = image.get()[srcOffset + j + 2]; } - memcpy(Memory + data.GetAddr() + dstOffset, output, linesize); + memcpy(Memory + (data.GetAddr() + dstOffset), output, linesize); } free(output); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngEnc.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngEnc.cpp index 4b59e80a26..e77f231ad1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngEnc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngEnc.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellPngEnc_init(); Module cellPngEnc(0x0052, cellPngEnc_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPrint.cpp b/rpcs3/Emu/SysCalls/Modules/cellPrint.cpp index 191c53c1d8..1848a277be 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPrint.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPrint.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellPrint_init(); Module cellPrint(0xf02a, cellPrint_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 3809643ad6..e27532d895 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -1,9 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "cellSysutil.h" +#include "Emu/RSX/sysutil_video.h" #include "cellResc.h" Module *cellResc = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp b/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp index f16dc3752f..fbb110e40b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" +#include "Utilities/rTime.h" #include "cellRtc.h" //void cellRtc_init(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp b/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp index 6cef6bbf08..c7b59517ed 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellRudp.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellRudp_init(); Module cellRudp(0x0057, cellRudp_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp index b354b86f5e..6859c20edf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp @@ -1,11 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/lv2/sys_cond.h" -#include "Emu/SysCalls/lv2/sys_mutex.h" -#include "cellSpurs.h" + #include "cellSail.h" Module *cellSail = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.h b/rpcs3/Emu/SysCalls/Modules/cellSail.h index 89a3155e7b..9361081976 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.h @@ -137,7 +137,7 @@ typedef void(*CellSailSourceCheckFuncError)(u32 pArg, s8 pMsg, s32 line); typedef int(*CellSailFsFuncOpen)(s8 pPath, s32 flag, s32 pFd, u32 pArg, u64 size); typedef int(*CellSailFsFuncOpenSecond)(s8 pPath, s32 flag, s32 fd, u32 pArg, u64 size); typedef int(*CellSailFsFuncClose)(s32 fd); -typedef int(*CellSailFsFuncFstat)(s32 fd, mem_ptr_t pStat); +typedef int(*CellSailFsFuncFstat)(s32 fd, u32 pStat_addr); typedef int(*CellSailFsFuncRead)(s32 fd, u32 pBuf, u64 numBytes, u64 pNumRead); typedef int(*CellSailFsFuncLseek)(s32 fd, s64 offset, s32 whence, u64 pPosition); typedef int(*CellSailFsFuncCancel)(s32 fd); @@ -569,7 +569,7 @@ struct CellSailPlayerAttribute struct CellSailPlayerResource { - CellSpurs pSpurs; + be_t pSpurs; be_t reserved0; // All three specify 0 be_t reserved1; be_t reserved2; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSailRec.cpp b/rpcs3/Emu/SysCalls/Modules/cellSailRec.cpp index dce0b36acb..ba88dd083c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSailRec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSailRec.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellSailRec_init(); Module cellSailRec(0xf034, cellSailRec_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellScreenshot.cpp b/rpcs3/Emu/SysCalls/Modules/cellScreenshot.cpp index bcc77d5466..14959e3d0b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellScreenshot.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellScreenshot.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellScreenshot_init(); Module cellScreenshot(0x004e, cellScreenshot_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSearch.cpp b/rpcs3/Emu/SysCalls/Modules/cellSearch.cpp index 8ba73eba86..d56f44ce2a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSearch.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSearch.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellSearch_init(); Module cellSearch(0xf02f, cellSearch_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSheap.cpp b/rpcs3/Emu/SysCalls/Modules/cellSheap.cpp index ea15f3819f..c29c7e6781 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSheap.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSheap.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellSheap_init(); Module cellSheap(0x000c, cellSheap_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 76a8f423ca..16860d49a4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -1,117 +1,106 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/SPURSManager.h" #include "cellSpurs.h" //void cellSpurs_init(); //Module cellSpurs(0x000a, cellSpurs_init); Module *cellSpurs = nullptr; -int cellSpursInitialize(mem_ptr_t spurs, int nSpus, int spuPriority, - int ppuPriority, bool exitIfNoWork) +#ifdef PRX_DEBUG +extern u32 libsre; +extern u32 libsre_rtoc; +#endif + +s32 cellSpursInitialize(mem_ptr_t spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { - cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%u, spuPriority=%u, ppuPriority=%u, exitIfNoWork=%u)", spurs.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursInitialize : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8480, libsre_rtoc); +#else SPURSManagerAttribute *attr = new SPURSManagerAttribute(nSpus, spuPriority, ppuPriority, exitIfNoWork); spurs->spurs = new SPURSManager(attr); return CELL_OK; +#endif } -int cellSpursFinalize(mem_ptr_t spurs) +s32 cellSpursFinalize(mem_ptr_t spurs) { cellSpurs->Warning("cellSpursFinalize(spurs_addr=0x%x)", spurs.GetAddr()); - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursFinalize : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8568, libsre_rtoc); +#else spurs->spurs->Finalize(); return CELL_OK; +#endif } -int cellSpursInitializeWithAttribute(mem_ptr_t spurs, const mem_ptr_t attr) +s32 cellSpursInitializeWithAttribute(mem_ptr_t spurs, const mem_ptr_t attr) { cellSpurs->Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.GetAddr(), attr.GetAddr()); - if ((spurs.GetAddr() % 128 != 0) || (attr.GetAddr() % 8 != 0)) - { - cellSpurs->Error("cellSpursInitializeWithAttribute : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x839C, libsre_rtoc); +#else spurs->spurs = new SPURSManager(attr->attr); return CELL_OK; +#endif } -int cellSpursInitializeWithAttribute2(mem_ptr_t spurs, const mem_ptr_t attr) +s32 cellSpursInitializeWithAttribute2(mem_ptr_t spurs, const mem_ptr_t attr) { cellSpurs->Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.GetAddr(), attr.GetAddr()); - if ((spurs.GetAddr() % 128 != 0) || (attr.GetAddr() % 8 != 0)) - { - cellSpurs->Error("cellSpursInitializeWithAttribute2 : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x82B4, libsre_rtoc); +#else spurs->spurs = new SPURSManager(attr->attr); return CELL_OK; +#endif } -int _cellSpursAttributeInitialize(mem_ptr_t attr, int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork) +s32 _cellSpursAttributeInitialize(mem_ptr_t attr, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { - cellSpurs->Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%u, spuPriority=%u, ppuPriority=%u, exitIfNoWork=%u)", attr.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork); - - if (attr.GetAddr() % 8 != 0) - { - cellSpurs->Error("_cellSpursAttributeInitialize : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", + attr.GetAddr(), nSpus, spuPriority, ppuPriority, exitIfNoWork); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x72CC, libsre_rtoc); +#else attr->attr = new SPURSManagerAttribute(nSpus, spuPriority, ppuPriority, exitIfNoWork); return CELL_OK; +#endif } -int cellSpursAttributeSetMemoryContainerForSpuThread(mem_ptr_t attr, u32 container) +s32 cellSpursAttributeSetMemoryContainerForSpuThread(mem_ptr_t attr, u32 container) { cellSpurs->Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", attr.GetAddr(), container); - if (attr.GetAddr() % 8 != 0) - { - cellSpurs->Error("cellSpursAttributeSetMemoryContainerForSpuThread : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x6FF8, libsre_rtoc); +#else attr->attr->_setMemoryContainerForSpuThread(container); return CELL_OK; +#endif } -int cellSpursAttributeSetNamePrefix(mem_ptr_t attr, const mem8_t prefix, u32 size) +s32 cellSpursAttributeSetNamePrefix(mem_ptr_t attr, const mem8_t prefix, u32 size) { cellSpurs->Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=0x%x)", attr.GetAddr(), prefix.GetAddr(), size); - if (attr.GetAddr() % 8 != 0) - { - cellSpurs->Error("cellSpursAttributeSetNamePrefix : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x7234, libsre_rtoc); +#else if (size > CELL_SPURS_NAME_MAX_LENGTH) { cellSpurs->Error("cellSpursAttributeSetNamePrefix : CELL_SPURS_CORE_ERROR_INVAL"); @@ -121,48 +110,42 @@ int cellSpursAttributeSetNamePrefix(mem_ptr_t attr, const me attr->attr->_setNamePrefix(Memory.ReadString(prefix.GetAddr(), size).c_str(), size); return CELL_OK; +#endif } -int cellSpursAttributeEnableSpuPrintfIfAvailable(mem_ptr_t attr) +s32 cellSpursAttributeEnableSpuPrintfIfAvailable(mem_ptr_t attr) { - cellSpurs->Todo("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.GetAddr()); - - if (attr.GetAddr() % 8 != 0) - { - cellSpurs->Error("cellSpursAttributeEnableSpuPrintfIfAvailable : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x7150, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursAttributeSetSpuThreadGroupType(mem_ptr_t attr, int type) +s32 cellSpursAttributeSetSpuThreadGroupType(mem_ptr_t attr, s32 type) { - cellSpurs->Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%u)", attr.GetAddr(), type); - - if (attr.GetAddr() % 8 != 0) - { - cellSpurs->Error("cellSpursAttributeSetNamePrefix : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.GetAddr(), type); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x70C8, libsre_rtoc); +#else attr->attr->_setSpuThreadGroupType(type); return CELL_OK; +#endif } -int cellSpursAttributeEnableSystemWorkload(mem_ptr_t attr, const u8 priority[CELL_SPURS_MAX_SPU], - u32 maxSpu, const bool isPreemptible[CELL_SPURS_MAX_SPU]) +s32 cellSpursAttributeEnableSystemWorkload(mem_ptr_t attr, mem8_ptr_t priority, u32 maxSpu, mem8_ptr_t isPreemptible) { - cellSpurs->Todo("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority[%u], maxSpu=%u, isPreemptible[%u])", attr.GetAddr(), priority, maxSpu, isPreemptible); + cellSpurs->Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)", + attr.GetAddr(), priority.GetAddr(), maxSpu, isPreemptible.GetAddr()); - if (attr.GetAddr() % 8 != 0) - { - cellSpurs->Error("cellSpursAttributeEnableSystemWorkload : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - for (int i = 0; i < CELL_SPURS_MAX_SPU; i++) +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xF410, libsre_rtoc); +#else + for (s32 i = 0; i < CELL_SPURS_MAX_SPU; i++) { if (priority[i] != 1 || maxSpu == 0) { @@ -171,560 +154,658 @@ int cellSpursAttributeEnableSystemWorkload(mem_ptr_t attr, c } } return CELL_OK; +#endif } -int cellSpursGetSpuThreadGroupId(mem_ptr_t spurs, mem32_t group) +s32 cellSpursGetSpuThreadGroupId(mem_ptr_t spurs, mem32_t group) { - cellSpurs->Todo("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.GetAddr(), group.GetAddr()); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursGetSpuThreadGroupId : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.GetAddr(), group.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8B30, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursGetNumSpuThread(mem_ptr_t spurs, mem32_t nThreads) +s32 cellSpursGetNumSpuThread(mem_ptr_t spurs, mem32_t nThreads) { - cellSpurs->Todo("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.GetAddr(), nThreads.GetAddr()); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursGetNumSpuThread : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.GetAddr(), nThreads.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8B78, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursGetSpuThreadId(mem_ptr_t spurs, mem32_t thread, mem32_t nThreads) +s32 cellSpursGetSpuThreadId(mem_ptr_t spurs, mem32_t thread, mem32_t nThreads) { - cellSpurs->Todo("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.GetAddr(), thread.GetAddr(), nThreads.GetAddr()); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursGetSpuThreadId : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.GetAddr(), thread.GetAddr(), nThreads.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8A98, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursSetMaxContention(mem_ptr_t spurs, u32 workloadId, u32 maxContention) +s32 cellSpursSetMaxContention(mem_ptr_t spurs, u32 workloadId, u32 maxContention) { - cellSpurs->Todo("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%u, maxContention=%u)", spurs.GetAddr(), workloadId, maxContention); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursSetMaxContention : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%d, maxContention=%d)", spurs.GetAddr(), workloadId, maxContention); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8E90, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursSetPriorities(mem_ptr_t spurs, u32 workloadId, const u8 priorities[CELL_SPURS_MAX_SPU]) +s32 cellSpursSetPriorities(mem_ptr_t spurs, u32 workloadId, const mem8_ptr_t priorities) { - cellSpurs->Todo("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%u, priorities[%u])", spurs.GetAddr(), workloadId, priorities); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursSetPriorities : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%d, priorities_addr=0x%x)", spurs.GetAddr(), workloadId, priorities.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x8BC0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursSetPriority(mem_ptr_t spurs, u32 workloadId, u32 spuId, u32 priority) +s32 cellSpursSetPreemptionVictimHints(mem_ptr_t spurs, mem8_ptr_t isPreemptible) { - cellSpurs->Todo("cellSpursSetPriority(spurs_addr=0x%x, workloadId=%u, spuId=%u, priority=%u)", spurs.GetAddr(), workloadId, spuId, priority); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursSetPriority : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible_addr=0x%x)", spurs.GetAddr(), isPreemptible.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xF5A4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursSetPreemptionVictimHints(mem_ptr_t spurs, const bool isPreemptible[CELL_SPURS_MAX_SPU]) +s32 cellSpursAttachLv2EventQueue(mem_ptr_t spurs, u32 queue, mem8_t port, s32 isDynamic) { - cellSpurs->Todo("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible[%u])", spurs.GetAddr(), isPreemptible); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursSetPreemptionVictimHints : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=%d, port_addr=0x%x, isDynamic=%d)", + spurs.GetAddr(), queue, port.GetAddr(), isDynamic); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xAFE0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursAttachLv2EventQueue(mem_ptr_t spurs, u32 queue, mem8_t port, int isDynamic) -{ - cellSpurs->Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%u)", spurs.GetAddr(), queue, port.GetAddr(), isDynamic); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursAttachLv2EventQueue : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - spurs->spurs->AttachLv2EventQueue(queue, port, isDynamic); - - return CELL_OK; -} - -int cellSpursDetachLv2EventQueue(mem_ptr_t spurs, u8 port) +s32 cellSpursDetachLv2EventQueue(mem_ptr_t spurs, u8 port) { cellSpurs->Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=0x%x)", spurs.GetAddr(), port); - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursDetachLv2EventQueue : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - spurs->spurs->DetachLv2EventQueue(port); - +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xB144, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEnableExceptionEventHandler(mem_ptr_t spurs, bool flag) +s32 cellSpursEnableExceptionEventHandler(mem_ptr_t spurs, bool flag) { - cellSpurs->Todo("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%u)", spurs.GetAddr(), flag); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEnableExceptionEventHandler : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%d)", spurs.GetAddr(), flag); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xDCC0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursSetGlobalExceptionEventHandler(mem_ptr_t spurs, mem_func_ptr_t eaHandler, mem_ptr_t arg) +s32 cellSpursSetGlobalExceptionEventHandler(mem_ptr_t spurs, u32 eaHandler_addr, u32 arg_addr) { - cellSpurs->Todo("cellSpursSetGlobalExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x,)", spurs.GetAddr(), eaHandler.GetAddr(), arg.GetAddr()); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursSetGlobalExceptionEventHandler : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursSetGlobalExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x)", + spurs.GetAddr(), eaHandler_addr, arg_addr); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xD6D0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursUnsetGlobalExceptionEventHandler(mem_ptr_t spurs) +s32 cellSpursUnsetGlobalExceptionEventHandler(mem_ptr_t spurs) { - cellSpurs->Todo("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.GetAddr()); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursUnsetGlobalExceptionEventHandler : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xD674, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursGetInfo(mem_ptr_t spurs, mem_ptr_t info) +s32 cellSpursGetInfo(mem_ptr_t spurs, mem_ptr_t info) { - cellSpurs->Todo("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.GetAddr(), info.GetAddr()); - - if (spurs.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursGetInfo : CELL_SPURS_CORE_ERROR_ALIGN"); - return CELL_SPURS_CORE_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.GetAddr(), info.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xE540, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursEventFlagInitialize(mem_ptr_t spurs, mem_ptr_t taskset, mem_ptr_t eventFlag, u32 flagClearMode, u32 flagDirection) +s32 _cellSpursEventFlagInitialize(mem_ptr_t spurs, mem_ptr_t taskset, mem_ptr_t eventFlag, u32 flagClearMode, u32 flagDirection) { - cellSpurs->Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%u, flagDirection=%u)", spurs.GetAddr(), taskset.GetAddr(), eventFlag.GetAddr(), flagClearMode, flagDirection); - - if ((taskset.GetAddr() % 128 != 0) || (eventFlag.GetAddr() % 128 != 0)) - { - cellSpurs->Error("_cellSpursEventFlagInitialize : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - eventFlag->eventFlag = new SPURSManagerEventFlag(flagClearMode, flagDirection); + cellSpurs->Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%d, flagDirection=%d)", + spurs.GetAddr(), taskset.GetAddr(), eventFlag.GetAddr(), flagClearMode, flagDirection); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1564C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagAttachLv2EventQueue(mem_ptr_t eventFlag) +s32 cellSpursEventFlagAttachLv2EventQueue(mem_ptr_t eventFlag) { - cellSpurs->Todo("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.GetAddr()); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagAttachLv2EventQueue : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x157B8, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagDetachLv2EventQueue(mem_ptr_t eventFlag) +s32 cellSpursEventFlagDetachLv2EventQueue(mem_ptr_t eventFlag) { - cellSpurs->Todo("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.GetAddr()); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagDetachLv2EventQueue : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x15998, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagWait(mem_ptr_t eventFlag, mem16_t mask, u32 mode) +s32 cellSpursEventFlagWait(mem_ptr_t eventFlag, mem16_t mask, u32 mode) { - cellSpurs->Todo("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask=0x%x, mode=%u)", eventFlag.GetAddr(), mask.GetAddr(), mode); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagWait : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%d)", eventFlag.GetAddr(), mask.GetAddr(), mode); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x15E68, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagClear(mem_ptr_t eventFlag, u16 bits) +s32 cellSpursEventFlagClear(mem_ptr_t eventFlag, u16 bits) { - cellSpurs->Todo("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=%u)", eventFlag.GetAddr(), bits); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagClear : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.GetAddr(), bits); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x15E9C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagSet(mem_ptr_t eventFlag, u16 bits) +s32 cellSpursEventFlagSet(mem_ptr_t eventFlag, u16 bits) { - cellSpurs->Todo("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=%u)", eventFlag.GetAddr(), bits); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagSet : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.GetAddr(), bits); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x15F04, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagTryWait(mem_ptr_t eventFlag, mem16_t mask, u32 mode) +s32 cellSpursEventFlagTryWait(mem_ptr_t eventFlag, mem16_t mask, u32 mode) { - cellSpurs->Todo("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%u)", eventFlag.GetAddr(), mask.GetAddr(), mode); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagTryWait : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=0x%x)", eventFlag.GetAddr(), mask.GetAddr(), mode); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x15E70, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagGetDirection(mem_ptr_t eventFlag, mem32_t direction) +s32 cellSpursEventFlagGetDirection(mem_ptr_t eventFlag, mem32_t direction) { - cellSpurs->Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=%u)", eventFlag.GetAddr(), direction.GetAddr()); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagGetDirection : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - direction = eventFlag->eventFlag->_getDirection(); + cellSpurs->Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.GetAddr(), direction.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x162C4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagGetClearMode(mem_ptr_t eventFlag, mem32_t clear_mode) +s32 cellSpursEventFlagGetClearMode(mem_ptr_t eventFlag, mem32_t clear_mode) { - cellSpurs->Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=%u)", eventFlag.GetAddr(), clear_mode.GetAddr()); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagGetClearMode : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - clear_mode = eventFlag->eventFlag->_getClearMode(); + cellSpurs->Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.GetAddr(), clear_mode.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x16310, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursEventFlagGetTasksetAddress(mem_ptr_t eventFlag, mem_ptr_t taskset) +s32 cellSpursEventFlagGetTasksetAddress(mem_ptr_t eventFlag, mem_ptr_t taskset) { - cellSpurs->Todo("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.GetAddr(), taskset.GetAddr()); - - if (eventFlag.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursEventFlagTryWait : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.GetAddr(), taskset.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1635C, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursLFQueueInitialize() +s32 _cellSpursLFQueueInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17028, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursLFQueuePushBody() +s32 _cellSpursLFQueuePushBody() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x170AC, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursLFQueueDetachLv2EventQueue() +s32 cellSpursLFQueueDetachLv2EventQueue() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x177CC, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursLFQueueAttachLv2EventQueue() +s32 cellSpursLFQueueAttachLv2EventQueue() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x173EC, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursLFQueuePopBody() +s32 _cellSpursLFQueuePopBody() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17238, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursLFQueueGetTasksetAddress() +s32 cellSpursLFQueueGetTasksetAddress() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17C34, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursQueueInitialize() +s32 _cellSpursQueueInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x163B4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueuePopBody() +s32 cellSpursQueuePopBody() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x16BF0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueuePushBody() +s32 cellSpursQueuePushBody() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x168C4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueAttachLv2EventQueue() +s32 cellSpursQueueAttachLv2EventQueue() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1666C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueDetachLv2EventQueue() +s32 cellSpursQueueDetachLv2EventQueue() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x16524, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueGetTasksetAddress() +s32 cellSpursQueueGetTasksetAddress() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x16F50, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueClear() +s32 cellSpursQueueClear() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1675C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueDepth() +s32 cellSpursQueueDepth() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1687C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueGetEntrySize() +s32 cellSpursQueueGetEntrySize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x16FE0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueSize() +s32 cellSpursQueueSize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x167F0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursQueueGetDirection() +s32 cellSpursQueueGetDirection() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x16F98, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateJobChainWithAttribute() +s32 cellSpursCreateJobChainWithAttribute() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1898C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateJobChain() +s32 cellSpursCreateJobChain() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18B84, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJoinJobChain() +s32 cellSpursJoinJobChain() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18DB0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursKickJobChain() +s32 cellSpursKickJobChain() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18E8C, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursJobChainAttributeInitialize() +s32 _cellSpursJobChainAttributeInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1845C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTasksetWithAttribute() +s32 cellSpursGetJobChainId() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x19064, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTaskset(mem_ptr_t spurs, mem_ptr_t taskset, u64 args, mem8_t priority, u32 maxContention) +s32 cellSpursJobChainSetExceptionEventHandler() { - cellSpurs->Todo("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%x, priority_addr=0x%x, maxContention=%u)", spurs.GetAddr(), taskset.GetAddr(), args, priority.GetAddr(), maxContention); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1A5A0, libsre_rtoc); +#else + return CELL_OK; +#endif +} - if ((spurs.GetAddr() % 128 != 0) || (taskset.GetAddr() % 128 != 0)) - { - cellSpurs->Error("cellSpursCreateTaskset : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } +s32 cellSpursJobChainUnsetExceptionEventHandler() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1A614, libsre_rtoc); +#else + return CELL_OK; +#endif +} +s32 cellSpursGetJobChainInfo() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1A7A0, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursJobChainGetSpursAddress() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1A900, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursCreateTasksetWithAttribute() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14BEC, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursCreateTaskset(mem_ptr_t spurs, mem_ptr_t taskset, u64 args, mem8_t priority, u32 maxContention) +{ + cellSpurs->Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)", + spurs.GetAddr(), taskset.GetAddr(), args, priority.GetAddr(), maxContention); + +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14CB8, libsre_rtoc); +#else SPURSManagerTasksetAttribute *tattr = new SPURSManagerTasksetAttribute(args, priority, maxContention); taskset->taskset = new SPURSManagerTaskset(taskset.GetAddr(), tattr); return CELL_OK; +#endif } -int cellSpursJoinTaskset(mem_ptr_t taskset) +s32 cellSpursJoinTaskset(mem_ptr_t taskset) { - cellSpurs->Todo("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.GetAddr()); - - if (taskset.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursJoinTaskset : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x152F8, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursGetTasksetId(mem_ptr_t taskset, mem32_t workloadId) +s32 cellSpursGetTasksetId(mem_ptr_t taskset, mem32_t workloadId) { - cellSpurs->Todo("cellSpursGetTasksetId(taskset_addr=0x%x, workloadId_addr=0x%x)", taskset.GetAddr(), workloadId.GetAddr()); - - if (taskset.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursGetTasksetId : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursGetTasksetId(taskset_addr=0x%x, workloadId_addr=0x%x)", taskset.GetAddr(), workloadId.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14EA0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursShutdownTaskset(mem_ptr_t taskset) +s32 cellSpursShutdownTaskset(mem_ptr_t taskset) { - cellSpurs->Todo("cellSpursShutdownTaskset(taskset_addr=0x%x)", taskset.GetAddr()); - - if (taskset.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursShutdownTaskset : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursShutdownTaskset(taskset_addr=0x%x)", taskset.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14868, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTask(mem_ptr_t taskset, mem32_t taskID, mem_ptr_t elf_addr, - mem_ptr_t context_addr, u32 context_size, mem_ptr_t lsPattern, +s32 cellSpursCreateTask(mem_ptr_t taskset, mem32_t taskID, u32 elf_addr, u32 context_addr, u32 context_size, mem_ptr_t lsPattern, mem_ptr_t argument) { - cellSpurs->Todo("cellSpursCreateTask(taskset_addr=0x%x, taskID_addr=0x%x, elf_addr_addr=0x%x, context_addr_addr=0x%x, context_size=%u, lsPattern_addr=0x%x, argument_addr=0x%x)", - taskset.GetAddr(), taskID.GetAddr(), elf_addr.GetAddr(), context_addr.GetAddr(), context_size, lsPattern.GetAddr(), argument.GetAddr()); - - if (taskset.GetAddr() % 128 != 0) - { - cellSpurs->Error("cellSpursCreateTask : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("cellSpursCreateTask(taskset_addr=0x%x, taskID_addr=0x%x, elf_addr_addr=0x%x, context_addr_addr=0x%x, context_size=%d, lsPattern_addr=0x%x, argument_addr=0x%x)", + taskset.GetAddr(), taskID.GetAddr(), elf_addr, context_addr, context_size, lsPattern.GetAddr(), argument.GetAddr()); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x12414, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursSendSignal(mem_ptr_t taskset, u32 taskID) +s32 _cellSpursSendSignal(mem_ptr_t taskset, u32 taskID) { - cellSpurs->Todo("_cellSpursSendSignal(taskset_addr=0x%x, taskID=%u)", taskset.GetAddr(), taskID); - - if (taskset.GetAddr() % 128 != 0) - { - cellSpurs->Error("_cellSpursSendSignal : CELL_SPURS_TASK_ERROR_ALIGN"); - return CELL_SPURS_TASK_ERROR_ALIGN; - } + cellSpurs->Warning("_cellSpursSendSignal(taskset_addr=0x%x, taskID=%d)", taskset.GetAddr(), taskID); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x124CC, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTaskWithAttribute() +s32 cellSpursCreateTaskWithAttribute() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x12204, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTasksetAttributeSetName() +s32 cellSpursTasksetAttributeSetName() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14210, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursTasksetAttribute2Initialize(mem_ptr_t attribute, u32 revision) +s32 cellSpursTasksetAttributeSetTasksetSize() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14254, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursTasksetAttributeEnableClearLS() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x142AC, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 _cellSpursTasksetAttribute2Initialize(mem_ptr_t attribute, u32 revision) { cellSpurs->Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.GetAddr(), revision); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1474C, libsre_rtoc); +#else attribute->revision = revision; attribute->name_addr = NULL; attribute->argTaskset = 0; - for (int i = 0; i < 8; i++) + for (s32 i = 0; i < 8; i++) { attribute->priority[i] = 1; } @@ -734,70 +815,106 @@ int _cellSpursTasksetAttribute2Initialize(mem_ptr_t attribute->CellSpursTaskNameBuffer_addr = 0; return CELL_OK; +#endif } -int cellSpursTaskExitCodeGet() +s32 cellSpursTaskExitCodeGet() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1397C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskExitCodeInitialize() +s32 cellSpursTaskExitCodeInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1352C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskExitCodeTryGet() +s32 cellSpursTaskExitCodeTryGet() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x13974, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskGetLoadableSegmentPattern() +s32 cellSpursTaskGetLoadableSegmentPattern() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x13ED4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskGetReadOnlyAreaPattern() +s32 cellSpursTaskGetReadOnlyAreaPattern() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x13CFC, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskGenerateLsPattern() +s32 cellSpursTaskGenerateLsPattern() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x13B78, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskAttributeInitialize() +s32 _cellSpursTaskAttributeInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x10C30, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTaskAttributeSetExitCodeContainer() +s32 cellSpursTaskAttributeSetExitCodeContainer() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x10A98, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursTaskAttribute2Initialize(mem_ptr_t attribute, u32 revision) +s32 _cellSpursTaskAttribute2Initialize(mem_ptr_t attribute, u32 revision) { cellSpurs->Warning("_cellSpursTaskAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.GetAddr(), revision); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x10B00, libsre_rtoc); +#else attribute->revision = revision; attribute->sizeContext = 0; attribute->eaContext = NULL; - for (int c = 0; c < 4; c++) + for (s32 c = 0; c < 4; c++) { attribute->lsPattern.u32[c] = 0; } - for (int i = 0; i < 2; i++) + for (s32 i = 0; i < 2; i++) { attribute->lsPattern.u64[i] = 0; } @@ -805,250 +922,703 @@ int _cellSpursTaskAttribute2Initialize(mem_ptr_t attrib attribute->name_addr = 0; return CELL_OK; +#endif } -int cellSpursTaskGetContextSaveAreaSize() +s32 cellSpursTaskGetContextSaveAreaSize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1409C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTaskset2() +s32 cellSpursCreateTaskset2() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x15108, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTask2() +s32 cellSpursCreateTask2() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x11E54, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJoinTask2() +s32 cellSpursJoinTask2() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x11378, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTryJoinTask2() +s32 cellSpursTryJoinTask2() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x11748, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursDestroyTaskset2() +s32 cellSpursDestroyTaskset2() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14EE8, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursCreateTask2WithBinInfo() +s32 cellSpursCreateTask2WithBinInfo() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x120E0, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursLookUpTasksetAddress() +s32 cellSpursTasksetSetExceptionEventHandler() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x13124, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursTasksetGetSpursAddress() +s32 cellSpursTasksetUnsetExceptionEventHandler() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x13194, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpurssetExceptionEventHandler() +s32 cellSpursLookUpTasksetAddress() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x133AC, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursUnsetExceptionEventHandler() +s32 cellSpursTasksetGetSpursAddress() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x14408, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursGetTasksetInfo() +s32 cellSpursSetExceptionEventHandler() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xDB54, libsre_rtoc); +#else return CELL_OK; +#endif } -int _cellSpursTasksetAttributeInitialize() +s32 cellSpursUnsetExceptionEventHandler() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xD77C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobGuardInitialize() +s32 cellSpursGetTasksetInfo() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1445C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobChainAttributeSetName() +s32 _cellSpursTasksetAttributeInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x142FC, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursShutdownJobChain() +s32 cellSpursJobGuardInitialize() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1807C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobChainAttributeSetHaltOnError() +s32 cellSpursJobChainAttributeSetName() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1861C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobChainAttributesetJobTypeMemoryCheck() +s32 cellSpursShutdownJobChain() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18D2C, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobGuardNotify() +s32 cellSpursJobChainAttributeSetHaltOnError() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18660, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobGuardReset() +s32 cellSpursJobChainAttributeSetJobTypeMemoryCheck() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x186A4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursRunJobChain() +s32 cellSpursJobGuardNotify() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17FA4, libsre_rtoc); +#else return CELL_OK; +#endif } -int cellSpursJobChainGetError() +s32 cellSpursJobGuardReset() { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17F60, libsre_rtoc); +#else return CELL_OK; +#endif +} + +s32 cellSpursRunJobChain() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18F94, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursJobChainGetError() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x190AC, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursWorkloadAttributeSetName() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x9664, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x96A4, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursAddWorkloadWithAttribute() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x9E14, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursRemoveWorkload() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA414, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursWaitForWorkloadShutdown() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA20C, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursAddWorkload() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x9ED0, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursWakeUp() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x84D8, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursShutdownWorkload() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA060, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 _cellSpursWorkloadFlagReceiver() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xF158, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursGetWorkloadFlag() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xEC00, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursReadyCountStore() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xAB2C, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 _cellSpursWorkloadAttributeInitialize() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x9F08, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursSendWorkloadSignal() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA658, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursGetWorkloadData() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA78C, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursReadyCountAdd() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA868, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursReadyCountCompareAndSwap() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xA9CC, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursReadyCountSwap() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xAC34, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursRequestIdleSpu() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xAD88, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursGetWorkloadInfo() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xE70C, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursGetSpuGuid() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xEFB0, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 _cellSpursWorkloadFlagReceiver2() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0xF298, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursGetJobPipelineInfo() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1A954, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursJobSetMaxGrab() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1AC88, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursJobHeaderSetJobbin2Param() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1AD58, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursAddUrgentCommand() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x18160, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursAddUrgentCall() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x1823C, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursBarrierInitialize() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17CD8, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursBarrierGetTasksetAddress() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17DB0, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 _cellSpursSemaphoreInitialize() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17DF8, libsre_rtoc); +#else + return CELL_OK; +#endif +} + +s32 cellSpursSemaphoreGetTasksetAddress() +{ + cellSpurs->Warning("%s()", __FUNCTION__); +#ifdef PRX_DEBUG + return GetCurrentPPUThread().FastCall2(libsre + 0x17F18, libsre_rtoc); +#else + return CELL_OK; +#endif } void cellSpurs_init() { // Core - cellSpurs->AddFunc(0xacfc8dbc, cellSpursInitialize); - cellSpurs->AddFunc(0xaa6269a8, cellSpursInitializeWithAttribute); - cellSpurs->AddFunc(0x30aa96c4, cellSpursInitializeWithAttribute2); - cellSpurs->AddFunc(0xca4c4600, cellSpursFinalize); - cellSpurs->AddFunc(0x95180230, _cellSpursAttributeInitialize); - cellSpurs->AddFunc(0x82275c1c, cellSpursAttributeSetMemoryContainerForSpuThread); - cellSpurs->AddFunc(0x07529113, cellSpursAttributeSetNamePrefix); - cellSpurs->AddFunc(0x1051d134, cellSpursAttributeEnableSpuPrintfIfAvailable); - cellSpurs->AddFunc(0xa839a4d9, cellSpursAttributeSetSpuThreadGroupType); - cellSpurs->AddFunc(0x9dcbcb5d, cellSpursAttributeEnableSystemWorkload); - cellSpurs->AddFunc(0x39c173fb, cellSpursGetSpuThreadGroupId); - cellSpurs->AddFunc(0xc56defb5, cellSpursGetNumSpuThread); - cellSpurs->AddFunc(0x6c960f6d, cellSpursGetSpuThreadId); - cellSpurs->AddFunc(0x1f402f8f, cellSpursGetInfo); - cellSpurs->AddFunc(0x84d2f6d5, cellSpursSetMaxContention); - cellSpurs->AddFunc(0x80a29e27, cellSpursSetPriorities); - // cellSpurs->AddFunc(, cellSpursSetPriority); - cellSpurs->AddFunc(0x4de203e2, cellSpursSetPreemptionVictimHints); - cellSpurs->AddFunc(0xb9bc6207, cellSpursAttachLv2EventQueue); - cellSpurs->AddFunc(0x4e66d483, cellSpursDetachLv2EventQueue); - cellSpurs->AddFunc(0x32b94add, cellSpursEnableExceptionEventHandler); - cellSpurs->AddFunc(0x7517724a, cellSpursSetGlobalExceptionEventHandler); - cellSpurs->AddFunc(0x861237f8, cellSpursUnsetGlobalExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursInitialize); + REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute); + REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute2); + REG_FUNC(cellSpurs, cellSpursFinalize); + REG_FUNC(cellSpurs, _cellSpursAttributeInitialize); + REG_FUNC(cellSpurs, cellSpursAttributeSetMemoryContainerForSpuThread); + REG_FUNC(cellSpurs, cellSpursAttributeSetNamePrefix); + REG_FUNC(cellSpurs, cellSpursAttributeEnableSpuPrintfIfAvailable); + REG_FUNC(cellSpurs, cellSpursAttributeSetSpuThreadGroupType); + REG_FUNC(cellSpurs, cellSpursAttributeEnableSystemWorkload); + REG_FUNC(cellSpurs, cellSpursGetSpuThreadGroupId); + REG_FUNC(cellSpurs, cellSpursGetNumSpuThread); + REG_FUNC(cellSpurs, cellSpursGetSpuThreadId); + REG_FUNC(cellSpurs, cellSpursGetInfo); + REG_FUNC(cellSpurs, cellSpursSetMaxContention); + REG_FUNC(cellSpurs, cellSpursSetPriorities); + REG_FUNC(cellSpurs, cellSpursSetPreemptionVictimHints); + REG_FUNC(cellSpurs, cellSpursAttachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursDetachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursEnableExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursSetGlobalExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursUnsetGlobalExceptionEventHandler); // Event flag - cellSpurs->AddFunc(0x5ef96465, _cellSpursEventFlagInitialize); - cellSpurs->AddFunc(0x87630976, cellSpursEventFlagAttachLv2EventQueue); - cellSpurs->AddFunc(0x22aab31d, cellSpursEventFlagDetachLv2EventQueue); - cellSpurs->AddFunc(0x373523d4, cellSpursEventFlagWait); - cellSpurs->AddFunc(0x4ac7bae4, cellSpursEventFlagClear); - cellSpurs->AddFunc(0xf5507729, cellSpursEventFlagSet); - cellSpurs->AddFunc(0x6d2d9339, cellSpursEventFlagTryWait); - cellSpurs->AddFunc(0x890f9e5a, cellSpursEventFlagGetDirection); - cellSpurs->AddFunc(0x4d1e9373, cellSpursEventFlagGetClearMode); - cellSpurs->AddFunc(0x947efb0b, cellSpursEventFlagGetTasksetAddress); + REG_FUNC(cellSpurs, _cellSpursEventFlagInitialize); + REG_FUNC(cellSpurs, cellSpursEventFlagAttachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursEventFlagDetachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursEventFlagWait); + REG_FUNC(cellSpurs, cellSpursEventFlagClear); + REG_FUNC(cellSpurs, cellSpursEventFlagSet); + REG_FUNC(cellSpurs, cellSpursEventFlagTryWait); + REG_FUNC(cellSpurs, cellSpursEventFlagGetDirection); + REG_FUNC(cellSpurs, cellSpursEventFlagGetClearMode); + REG_FUNC(cellSpurs, cellSpursEventFlagGetTasksetAddress); // Taskset - cellSpurs->AddFunc(0x52cc6c82, cellSpursCreateTaskset); - cellSpurs->AddFunc(0xc10931cb, cellSpursCreateTasksetWithAttribute); - cellSpurs->AddFunc(0x16394a4e, _cellSpursTasksetAttributeInitialize); - cellSpurs->AddFunc(0xc2acdf43, _cellSpursTasksetAttribute2Initialize); - cellSpurs->AddFunc(0x652b70e2, cellSpursTasksetAttributeSetName); - cellSpurs->AddFunc(0x9f72add3, cellSpursJoinTaskset); - cellSpurs->AddFunc(0xe7dd87e1, cellSpursGetTasksetId); - cellSpurs->AddFunc(0xa789e631, cellSpursShutdownTaskset); - cellSpurs->AddFunc(0xbeb600ac, cellSpursCreateTask); - cellSpurs->AddFunc(0x1d46fedf, cellSpursCreateTaskWithAttribute); - cellSpurs->AddFunc(0xb8474eff, cellSpursTaskAttributeInitialize); - cellSpurs->AddFunc(0x8adadf65, _cellSpursTaskAttribute2Initialize); - cellSpurs->AddFunc(0xa121a224, cellSpursTaskAttributeSetExitCodeContainer); - cellSpurs->AddFunc(0x13ae18f3, cellSpursTaskExitCodeGet); - cellSpurs->AddFunc(0x34552fa6, cellSpursTaskExitCodeInitialize); - cellSpurs->AddFunc(0xe717ac73, cellSpursTaskExitCodeTryGet); - cellSpurs->AddFunc(0x1d344406, cellSpursTaskGetLoadableSegmentPattern); - cellSpurs->AddFunc(0x7cb33c2e, cellSpursTaskGetReadOnlyAreaPattern); - cellSpurs->AddFunc(0x9197915f, cellSpursTaskGenerateLsPattern); - cellSpurs->AddFunc(0x9034e538, cellSpursTaskGetContextSaveAreaSize); - cellSpurs->AddFunc(0xe0a6dbe4, _cellSpursSendSignal); - cellSpurs->AddFunc(0x4a6465e3, cellSpursCreateTaskset2); - cellSpurs->AddFunc(0xe14ca62d, cellSpursCreateTask2); - cellSpurs->AddFunc(0xa7a94892, cellSpursJoinTask2); - cellSpurs->AddFunc(0x838fa4f0, cellSpursTryJoinTask2); - cellSpurs->AddFunc(0x1ebcf459, cellSpursDestroyTaskset2); - cellSpurs->AddFunc(0xe4944a1c, cellSpursCreateTask2WithBinInfo); - cellSpurs->AddFunc(0x4cce88a9, cellSpursLookUpTasksetAddress); - cellSpurs->AddFunc(0x58d58fcf, cellSpursTasksetGetSpursAddress); - cellSpurs->AddFunc(0xd2e23fa9, cellSpurssetExceptionEventHandler); - cellSpurs->AddFunc(0x4c75deb8, cellSpursUnsetExceptionEventHandler); - cellSpurs->AddFunc(0x9fcb567b, cellSpursGetTasksetInfo); + REG_FUNC(cellSpurs, cellSpursCreateTaskset); + REG_FUNC(cellSpurs, cellSpursCreateTasksetWithAttribute); + REG_FUNC(cellSpurs, _cellSpursTasksetAttributeInitialize); + REG_FUNC(cellSpurs, _cellSpursTasksetAttribute2Initialize); + REG_FUNC(cellSpurs, cellSpursTasksetAttributeSetName); + REG_FUNC(cellSpurs, cellSpursTasksetAttributeSetTasksetSize); + REG_FUNC(cellSpurs, cellSpursTasksetAttributeEnableClearLS); + REG_FUNC(cellSpurs, cellSpursJoinTaskset); + REG_FUNC(cellSpurs, cellSpursGetTasksetId); + REG_FUNC(cellSpurs, cellSpursShutdownTaskset); + REG_FUNC(cellSpurs, cellSpursCreateTask); + REG_FUNC(cellSpurs, cellSpursCreateTaskWithAttribute); + REG_FUNC(cellSpurs, _cellSpursTaskAttributeInitialize); + REG_FUNC(cellSpurs, _cellSpursTaskAttribute2Initialize); + REG_FUNC(cellSpurs, cellSpursTaskAttributeSetExitCodeContainer); + REG_FUNC(cellSpurs, cellSpursTaskExitCodeGet); + REG_FUNC(cellSpurs, cellSpursTaskExitCodeInitialize); + REG_FUNC(cellSpurs, cellSpursTaskExitCodeTryGet); + REG_FUNC(cellSpurs, cellSpursTaskGetLoadableSegmentPattern); + REG_FUNC(cellSpurs, cellSpursTaskGetReadOnlyAreaPattern); + REG_FUNC(cellSpurs, cellSpursTaskGenerateLsPattern); + REG_FUNC(cellSpurs, cellSpursTaskGetContextSaveAreaSize); + REG_FUNC(cellSpurs, _cellSpursSendSignal); + REG_FUNC(cellSpurs, cellSpursCreateTaskset2); + REG_FUNC(cellSpurs, cellSpursCreateTask2); + REG_FUNC(cellSpurs, cellSpursJoinTask2); + REG_FUNC(cellSpurs, cellSpursTryJoinTask2); + REG_FUNC(cellSpurs, cellSpursDestroyTaskset2); + REG_FUNC(cellSpurs, cellSpursCreateTask2WithBinInfo); + REG_FUNC(cellSpurs, cellSpursLookUpTasksetAddress); + REG_FUNC(cellSpurs, cellSpursTasksetGetSpursAddress); + REG_FUNC(cellSpurs, cellSpursSetExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursUnsetExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursGetTasksetInfo); + REG_FUNC(cellSpurs, cellSpursTasksetSetExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursTasksetUnsetExceptionEventHandler); // Job Chain - cellSpurs->AddFunc(0x60eb2dec, cellSpursCreateJobChain); - cellSpurs->AddFunc(0x303c19cd, cellSpursCreateJobChainWithAttribute); - cellSpurs->AddFunc(0x738e40e6, cellSpursShutdownJobChain); - cellSpurs->AddFunc(0xa7c066de, cellSpursJoinJobChain); - cellSpurs->AddFunc(0xbfea60fa, cellSpursKickJobChain); - cellSpurs->AddFunc(0xf31731bb, cellSpursRunJobChain); - cellSpurs->AddFunc(0x161da6a7, cellSpursJobChainGetError); - cellSpurs->AddFunc(0x3548f483, _cellSpursJobChainAttributeInitialize); - cellSpurs->AddFunc(0x9fef70c2, cellSpursJobChainAttributeSetName); - cellSpurs->AddFunc(0xbb68d76e, cellSpursJobChainAttributeSetHaltOnError); - cellSpurs->AddFunc(0x2cfccb99, cellSpursJobChainAttributesetJobTypeMemoryCheck); + REG_FUNC(cellSpurs, cellSpursCreateJobChain); + REG_FUNC(cellSpurs, cellSpursCreateJobChainWithAttribute); + REG_FUNC(cellSpurs, cellSpursShutdownJobChain); + REG_FUNC(cellSpurs, cellSpursJoinJobChain); + REG_FUNC(cellSpurs, cellSpursKickJobChain); + REG_FUNC(cellSpurs, cellSpursRunJobChain); + REG_FUNC(cellSpurs, cellSpursJobChainGetError); + REG_FUNC(cellSpurs, _cellSpursJobChainAttributeInitialize); + REG_FUNC(cellSpurs, cellSpursJobChainAttributeSetName); + REG_FUNC(cellSpurs, cellSpursJobChainAttributeSetHaltOnError); + REG_FUNC(cellSpurs, cellSpursJobChainAttributeSetJobTypeMemoryCheck); + REG_FUNC(cellSpurs, cellSpursGetJobChainId); + REG_FUNC(cellSpurs, cellSpursJobChainSetExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursJobChainUnsetExceptionEventHandler); + REG_FUNC(cellSpurs, cellSpursGetJobChainInfo); + REG_FUNC(cellSpurs, cellSpursJobChainGetSpursAddress); // Job Guard - cellSpurs->AddFunc(0x68aaeba9, cellSpursJobGuardInitialize); - cellSpurs->AddFunc(0xd5d0b256, cellSpursJobGuardNotify); - cellSpurs->AddFunc(0x00af2519, cellSpursJobGuardReset); + REG_FUNC(cellSpurs, cellSpursJobGuardInitialize); + REG_FUNC(cellSpurs, cellSpursJobGuardNotify); + REG_FUNC(cellSpurs, cellSpursJobGuardReset); // LFQueue - cellSpurs->AddFunc(0x011ee38b, _cellSpursLFQueueInitialize); - cellSpurs->AddFunc(0x8a85674d, _cellSpursLFQueuePushBody); - cellSpurs->AddFunc(0x1656d49f, cellSpursLFQueueAttachLv2EventQueue); - cellSpurs->AddFunc(0x73e06f91, cellSpursLFQueueDetachLv2EventQueue); - cellSpurs->AddFunc(0x35dae22b, _cellSpursLFQueuePopBody); - cellSpurs->AddFunc(0xb792ca1a, cellSpursLFQueueGetTasksetAddress); + REG_FUNC(cellSpurs, _cellSpursLFQueueInitialize); + REG_FUNC(cellSpurs, _cellSpursLFQueuePushBody); + REG_FUNC(cellSpurs, cellSpursLFQueueAttachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursLFQueueDetachLv2EventQueue); + REG_FUNC(cellSpurs, _cellSpursLFQueuePopBody); + REG_FUNC(cellSpurs, cellSpursLFQueueGetTasksetAddress); // Queue - cellSpurs->AddFunc(0x082bfb09, _cellSpursQueueInitialize); - cellSpurs->AddFunc(0x91066667, cellSpursQueuePopBody); - cellSpurs->AddFunc(0x92cff6ed, cellSpursQueuePushBody); - cellSpurs->AddFunc(0xe5443be7, cellSpursQueueAttachLv2EventQueue); - cellSpurs->AddFunc(0x039d70b7, cellSpursQueueDetachLv2EventQueue); - cellSpurs->AddFunc(0x2093252b, cellSpursQueueGetTasksetAddress); - cellSpurs->AddFunc(0x247414d0, cellSpursQueueClear); - cellSpurs->AddFunc(0x35f02287, cellSpursQueueDepth); - cellSpurs->AddFunc(0x369fe03d, cellSpursQueueGetEntrySize); - cellSpurs->AddFunc(0x54876603, cellSpursQueueSize); - cellSpurs->AddFunc(0xec68442c, cellSpursQueueGetDirection); + REG_FUNC(cellSpurs, _cellSpursQueueInitialize); + REG_FUNC(cellSpurs, cellSpursQueuePopBody); + REG_FUNC(cellSpurs, cellSpursQueuePushBody); + REG_FUNC(cellSpurs, cellSpursQueueAttachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursQueueDetachLv2EventQueue); + REG_FUNC(cellSpurs, cellSpursQueueGetTasksetAddress); + REG_FUNC(cellSpurs, cellSpursQueueClear); + REG_FUNC(cellSpurs, cellSpursQueueDepth); + REG_FUNC(cellSpurs, cellSpursQueueGetEntrySize); + REG_FUNC(cellSpurs, cellSpursQueueSize); + REG_FUNC(cellSpurs, cellSpursQueueGetDirection); + + // Workload + REG_FUNC(cellSpurs, cellSpursWorkloadAttributeSetName); + REG_FUNC(cellSpurs, cellSpursWorkloadAttributeSetShutdownCompletionEventHook); + REG_FUNC(cellSpurs, cellSpursAddWorkloadWithAttribute); + REG_FUNC(cellSpurs, cellSpursAddWorkload); + REG_FUNC(cellSpurs, cellSpursShutdownWorkload); + REG_FUNC(cellSpurs, cellSpursWaitForWorkloadShutdown); + REG_FUNC(cellSpurs, cellSpursRemoveWorkload); + REG_FUNC(cellSpurs, cellSpursReadyCountStore); + REG_FUNC(cellSpurs, cellSpursGetWorkloadFlag); + REG_FUNC(cellSpurs, _cellSpursWorkloadFlagReceiver); + REG_FUNC(cellSpurs, _cellSpursWorkloadAttributeInitialize); + REG_FUNC(cellSpurs, cellSpursSendWorkloadSignal); + REG_FUNC(cellSpurs, cellSpursGetWorkloadData); + REG_FUNC(cellSpurs, cellSpursReadyCountAdd); + REG_FUNC(cellSpurs, cellSpursReadyCountCompareAndSwap); + REG_FUNC(cellSpurs, cellSpursReadyCountSwap); + REG_FUNC(cellSpurs, cellSpursRequestIdleSpu); + REG_FUNC(cellSpurs, cellSpursGetWorkloadInfo); + REG_FUNC(cellSpurs, cellSpursGetSpuGuid); + REG_FUNC(cellSpurs, _cellSpursWorkloadFlagReceiver2); + REG_FUNC(cellSpurs, cellSpursGetJobPipelineInfo); + REG_FUNC(cellSpurs, cellSpursJobSetMaxGrab); + REG_FUNC(cellSpurs, cellSpursJobHeaderSetJobbin2Param); + + REG_FUNC(cellSpurs, cellSpursWakeUp); + REG_FUNC(cellSpurs, cellSpursAddUrgentCommand); + REG_FUNC(cellSpurs, cellSpursAddUrgentCall); + + REG_FUNC(cellSpurs, cellSpursBarrierInitialize); + REG_FUNC(cellSpurs, cellSpursBarrierGetTasksetAddress); + + REG_FUNC(cellSpurs, _cellSpursSemaphoreInitialize); + REG_FUNC(cellSpurs, cellSpursSemaphoreGetTasksetAddress); } +#undef PRX_DEBUG \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index 13d56dfaef..b23fea8496 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -1,5 +1,4 @@ #pragma once -#include "Emu/Cell/SPURSManager.h" // Core return codes. enum @@ -33,6 +32,55 @@ enum CELL_SPURS_TASK_ERROR_SHUTDOWN = 0x80410920, }; +// SPURS defines. +enum SPURSKernelInterfaces +{ + CELL_SPURS_MAX_SPU = 8, + CELL_SPURS_MAX_WORKLOAD = 16, + CELL_SPURS_MAX_WORKLOAD2 = 32, + CELL_SPURS_MAX_PRIORITY = 16, + CELL_SPURS_NAME_MAX_LENGTH = 15, + CELL_SPURS_SIZE = 4096, + CELL_SPURS_SIZE2 = 8192, + CELL_SPURS_ALIGN = 128, + CELL_SPURS_ATTRIBUTE_SIZE = 512, + CELL_SPURS_ATTRIBUTE_ALIGN = 8, + CELL_SPURS_INTERRUPT_VECTOR = 0x0, + CELL_SPURS_LOCK_LINE = 0x80, + CELL_SPURS_KERNEL_DMA_TAG_ID = 31, +}; + +enum RangeofEventQueuePortNumbers +{ + CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15, + CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16, + CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63, +}; + +enum SPURSTraceTypes +{ + CELL_SPURS_TRACE_TAG_LOAD = 0x2a, + CELL_SPURS_TRACE_TAG_MAP = 0x2b, + CELL_SPURS_TRACE_TAG_START = 0x2c, + CELL_SPURS_TRACE_TAG_STOP = 0x2d, + CELL_SPURS_TRACE_TAG_USER = 0x2e, + CELL_SPURS_TRACE_TAG_GUID = 0x2f, +}; + +// SPURS task defines. +enum TaskConstants +{ + CELL_SPURS_MAX_TASK = 128, + CELL_SPURS_TASK_TOP = 0x3000, + CELL_SPURS_TASK_BOTTOM = 0x40000, + CELL_SPURS_MAX_TASK_NAME_LENGTH = 32, +}; + +class SPURSManager; +class SPURSManagerAttribute; +class SPURSManagerEventFlag; +class SPURSManagerTaskset; + // Core CellSpurs structures. struct CellSpurs { @@ -146,11 +194,11 @@ struct CellSpursTracePacket }; // Exception handlers. -typedef void (*CellSpursGlobalExceptionEventHandler)(mem_ptr_t spurs, const mem_ptr_t info, - u32 id, mem_ptr_t arg); - -typedef void (*CellSpursTasksetExceptionEventHandler)(mem_ptr_t spurs, mem_ptr_t taskset, - u32 idTask, const mem_ptr_t info, mem_ptr_t arg); +//typedef void (*CellSpursGlobalExceptionEventHandler)(mem_ptr_t spurs, const mem_ptr_t info, +// u32 id, mem_ptr_t arg); +// +//typedef void (*CellSpursTasksetExceptionEventHandler)(mem_ptr_t spurs, mem_ptr_t taskset, +// u32 idTask, const mem_ptr_t info, mem_ptr_t arg); struct CellSpursTasksetInfo { @@ -159,7 +207,7 @@ struct CellSpursTasksetInfo be_t idWorkload; be_t idLastScheduledTask; //typedef unsigned CellSpursTaskId be_t name_addr; - CellSpursTasksetExceptionEventHandler exceptionEventHandler; + be_t exceptionEventHandler_addr; be_t exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument be_t sizeTaskset; //be_t reserved[]; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSsl.cpp b/rpcs3/Emu/SysCalls/Modules/cellSsl.cpp index c0a30dc9f7..cd6d3b7e45 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSsl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSsl.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellSsl_init(); Module cellSsl(0x0003, cellSsl_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp index 467f82d29d..ff0612316b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellSubdisplay_init(); Module cellSubdisplay(0x0034, cellSubdisplay_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index c19f1e27db..e8f2908d89 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1,19 +1,40 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/lv2/sys_process.h" +#include "Emu/Event.h" #include "cellSync.h" //void cellSync_init(); //Module cellSync("cellSync", cellSync_init); Module *cellSync = nullptr; -s32 cellSyncMutexInitialize(mem_ptr_t mutex) -{ - cellSync->Log("cellSyncMutexInitialize(mutex_addr=0x%x)", mutex.GetAddr()); +#ifdef PRX_DEBUG +#include "rpcs3.h" +#include "prx_libsre.h" +u32 libsre; +u32 libsre_rtoc; +void fix_import(Module* module, u32 func, u32 addr) +{ + Memory.Write32(addr + 0x0, 0x3d600000 | (func >> 16)); /* lis r11, (func_id >> 16) */ + Memory.Write32(addr + 0x4, 0x616b0000 | (func & 0xffff)); /* ori r11, (func_id & 0xffff) */ + Memory.Write32(addr + 0x8, 0x60000000); /* nop */ + // leave rtoc saving at 0xC + Memory.Write64(addr + 0x10, 0x440000024e800020ull); /* sc + blr */ + Memory.Write64(addr + 0x18, 0x6000000060000000ull); /* nop + nop */ + + module->Load(func); +} + +#define FIX_IMPORT(module, func, addr) fix_import(module, getFunctionId(#func), addr) + +#endif + +s32 syncMutexInitialize(mem_ptr_t mutex) +{ if (!mutex) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -29,6 +50,13 @@ s32 cellSyncMutexInitialize(mem_ptr_t mutex) return CELL_OK; } +s32 cellSyncMutexInitialize(mem_ptr_t mutex) +{ + cellSync->Log("cellSyncMutexInitialize(mutex_addr=0x%x)", mutex.GetAddr()); + + return syncMutexInitialize(mutex); +} + s32 cellSyncMutexLock(mem_ptr_t mutex) { cellSync->Log("cellSyncMutexLock(mutex_addr=0x%x)", mutex.GetAddr()); @@ -61,7 +89,7 @@ s32 cellSyncMutexLock(mem_ptr_t mutex) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellSyncMutexLock(mutex_addr=0x%x) aborted", mutex.GetAddr()); + cellSync->Warning("cellSyncMutexLock(mutex_addr=0x%x) aborted", mutex.GetAddr()); break; } } @@ -133,10 +161,8 @@ s32 cellSyncMutexUnlock(mem_ptr_t mutex) return CELL_OK; } -s32 cellSyncBarrierInitialize(mem_ptr_t barrier, u16 total_count) +s32 syncBarrierInitialize(mem_ptr_t barrier, u16 total_count) { - cellSync->Log("cellSyncBarrierInitialize(barrier_addr=0x%x, total_count=%d)", barrier.GetAddr(), total_count); - if (!barrier) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -157,6 +183,13 @@ s32 cellSyncBarrierInitialize(mem_ptr_t barrier, u16 total_coun return CELL_OK; } +s32 cellSyncBarrierInitialize(mem_ptr_t barrier, u16 total_count) +{ + cellSync->Log("cellSyncBarrierInitialize(barrier_addr=0x%x, total_count=%d)", barrier.GetAddr(), total_count); + + return syncBarrierInitialize(barrier, total_count); +} + s32 cellSyncBarrierNotify(mem_ptr_t barrier) { cellSync->Log("cellSyncBarrierNotify(barrier_addr=0x%x)", barrier.GetAddr()); @@ -185,7 +218,7 @@ s32 cellSyncBarrierNotify(mem_ptr_t barrier) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellSyncBarrierNotify(barrier_addr=0x%x) aborted", barrier.GetAddr()); + cellSync->Warning("cellSyncBarrierNotify(barrier_addr=0x%x) aborted", barrier.GetAddr()); return CELL_OK; } continue; @@ -272,7 +305,7 @@ s32 cellSyncBarrierWait(mem_ptr_t barrier) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellSyncBarrierWait(barrier_addr=0x%x) aborted", barrier.GetAddr()); + cellSync->Warning("cellSyncBarrierWait(barrier_addr=0x%x) aborted", barrier.GetAddr()); return CELL_OK; } continue; @@ -329,10 +362,8 @@ s32 cellSyncBarrierTryWait(mem_ptr_t barrier) return CELL_OK; } -s32 cellSyncRwmInitialize(mem_ptr_t rwm, u32 buffer_addr, u32 buffer_size) +s32 syncRwmInitialize(mem_ptr_t rwm, u32 buffer_addr, u32 buffer_size) { - cellSync->Log("cellSyncRwmInitialize(rwm_addr=0x%x, buffer_addr=0x%x, buffer_size=0x%x)", rwm.GetAddr(), buffer_addr, buffer_size); - if (!rwm || !buffer_addr) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -354,6 +385,13 @@ s32 cellSyncRwmInitialize(mem_ptr_t rwm, u32 buffer_addr, u32 buffe return CELL_OK; } +s32 cellSyncRwmInitialize(mem_ptr_t rwm, u32 buffer_addr, u32 buffer_size) +{ + cellSync->Log("cellSyncRwmInitialize(rwm_addr=0x%x, buffer_addr=0x%x, buffer_size=0x%x)", rwm.GetAddr(), buffer_addr, buffer_size); + + return syncRwmInitialize(rwm, buffer_addr, buffer_size); +} + s32 cellSyncRwmRead(mem_ptr_t rwm, u32 buffer_addr) { cellSync->Log("cellSyncRwmRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.GetAddr(), buffer_addr); @@ -539,10 +577,8 @@ s32 cellSyncRwmTryWrite(mem_ptr_t rwm, u32 buffer_addr) return CELL_OK; } -s32 cellSyncQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth) +s32 syncQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth) { - cellSync->Log("cellSyncQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x)", queue.GetAddr(), buffer_addr, size, depth); - if (!queue) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -569,6 +605,13 @@ s32 cellSyncQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 return CELL_OK; } +s32 cellSyncQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth) +{ + cellSync->Log("cellSyncQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x)", queue.GetAddr(), buffer_addr, size, depth); + + return syncQueueInitialize(queue, buffer_addr, size, depth); +} + s32 cellSyncQueuePush(mem_ptr_t queue, u32 buffer_addr) { cellSync->Log("cellSyncQueuePush(queue_addr=0x%x, buffer_addr=0x%x)", queue.GetAddr(), buffer_addr); @@ -584,11 +627,7 @@ s32 cellSyncQueuePush(mem_ptr_t queue, u32 buffer_addr) const u32 size = (u32)queue->m_size; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueuePush(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); u32 position; while (true) @@ -622,7 +661,7 @@ s32 cellSyncQueuePush(mem_ptr_t queue, u32 buffer_addr) } // prx: memcpy(position * m_size + m_addr, buffer_addr, m_size), sync - memcpy(Memory + (u64)queue->m_addr + position * size, Memory + buffer_addr, size); + memcpy(Memory + ((u64)queue->m_addr + position * size), Memory + buffer_addr, size); // prx: atomically insert 0 in 5th u8 while (true) @@ -652,11 +691,7 @@ s32 cellSyncQueueTryPush(mem_ptr_t queue, u32 buffer_addr) const u32 size = (u32)queue->m_size; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueueTryPush(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); u32 position; while (true) @@ -678,7 +713,7 @@ s32 cellSyncQueueTryPush(mem_ptr_t queue, u32 buffer_addr) if (InterlockedCompareExchange(&queue->m_data(), new_queue.m_data(), old_data) == old_data) break; } - memcpy(Memory + (u64)queue->m_addr + position * size, Memory + buffer_addr, size); + memcpy(Memory + ((u64)queue->m_addr + position * size), Memory + buffer_addr, size); while (true) { @@ -707,11 +742,7 @@ s32 cellSyncQueuePop(mem_ptr_t queue, u32 buffer_addr) const u32 size = (u32)queue->m_size; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueuePop(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); u32 position; while (true) @@ -745,7 +776,7 @@ s32 cellSyncQueuePop(mem_ptr_t queue, u32 buffer_addr) } // prx: (sync), memcpy(buffer_addr, position * m_size + m_addr, m_size) - memcpy(Memory + buffer_addr, Memory + (u64)queue->m_addr + position * size, size); + memcpy(Memory + buffer_addr, Memory + ((u64)queue->m_addr + position * size), size); // prx: atomically insert 0 in first u8 while (true) @@ -775,11 +806,7 @@ s32 cellSyncQueueTryPop(mem_ptr_t queue, u32 buffer_addr) const u32 size = (u32)queue->m_size; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueueTryPop(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); u32 position; while (true) @@ -801,7 +828,7 @@ s32 cellSyncQueueTryPop(mem_ptr_t queue, u32 buffer_addr) if (InterlockedCompareExchange(&queue->m_data(), new_queue.m_data(), old_data) == old_data) break; } - memcpy(Memory + buffer_addr, Memory + (u64)queue->m_addr + position * size, size); + memcpy(Memory + buffer_addr, Memory + ((u64)queue->m_addr + position * size), size); while (true) { @@ -830,11 +857,7 @@ s32 cellSyncQueuePeek(mem_ptr_t queue, u32 buffer_addr) const u32 size = (u32)queue->m_size; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueuePeek(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); u32 position; while (true) @@ -861,7 +884,7 @@ s32 cellSyncQueuePeek(mem_ptr_t queue, u32 buffer_addr) if (InterlockedCompareExchange(&queue->m_data(), new_queue.m_data(), old_data) == old_data) break; } - memcpy(Memory + buffer_addr, Memory + (u64)queue->m_addr + position * size, size); + memcpy(Memory + buffer_addr, Memory + ((u64)queue->m_addr + position * size), size); while (true) { @@ -890,11 +913,7 @@ s32 cellSyncQueueTryPeek(mem_ptr_t queue, u32 buffer_addr) const u32 size = (u32)queue->m_size; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueueTryPeek(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); u32 position; while (true) @@ -915,7 +934,7 @@ s32 cellSyncQueueTryPeek(mem_ptr_t queue, u32 buffer_addr) if (InterlockedCompareExchange(&queue->m_data(), new_queue.m_data(), old_data) == old_data) break; } - memcpy(Memory + buffer_addr, Memory + (u64)queue->m_addr + position * size, size); + memcpy(Memory + buffer_addr, Memory + ((u64)queue->m_addr + position * size), size); while (true) { @@ -944,11 +963,7 @@ s32 cellSyncQueueSize(mem_ptr_t queue) const u32 count = (u32)queue->m_v2 & 0xffffff; const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || count > depth) - { - cellSync->Error("cellSyncQueueSize(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && count <= depth); return count; } @@ -967,11 +982,7 @@ s32 cellSyncQueueClear(mem_ptr_t queue) } const u32 depth = (u32)queue->m_depth; - if (((u32)queue->m_v1 & 0xffffff) > depth || ((u32)queue->m_v2 & 0xffffff) > depth) - { - cellSync->Error("cellSyncQueueSize(queue_addr=0x%x): m_depth limit broken", queue.GetAddr()); - Emu.Pause(); - } + assert(((u32)queue->m_v1 & 0xffffff) <= depth && ((u32)queue->m_v2 & 0xffffff) <= depth); // TODO: optimize if possible while (true) @@ -1023,83 +1034,71 @@ s32 cellSyncQueueClear(mem_ptr_t queue) return CELL_OK; } -int cellSyncLFQueueGetEntrySize() +// LFQueue functions + +void syncLFQueueDump(mem_ptr_t queue) { - cellSync->Todo("cellSyncLFQueueGetEntrySize()"); - return CELL_OK; + cellSync->Notice("CellSyncLFQueue dump: addr = 0x%x", queue.GetAddr()); + for (u32 i = 0; i < sizeof(CellSyncLFQueue) / 16; i++) + { + cellSync->Notice("*** 0x%.16llx 0x%.16llx", Memory.Read64(queue.GetAddr() + i * 16), Memory.Read64(queue.GetAddr() + i * 16 + 8)); + } } -int cellSyncLFQueueSize() +void syncLFQueueInit(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr) { - cellSync->Todo("cellSyncLFQueueSize()"); - return CELL_OK; + queue->m_h1 = 0; + queue->m_h2 = 0; + queue->m_h4 = 0; + queue->m_h5 = 0; + queue->m_h6 = 0; + queue->m_h8 = 0; + queue->m_size = size; + queue->m_depth = depth; + queue->m_buffer = (u64)buffer_addr; + queue->m_direction = direction; + for (u32 i = 0; i < sizeof(queue->m_hs) / sizeof(queue->m_hs[0]); i++) + { + queue->m_hs[i] = 0; + } + queue->m_eaSignal = (u64)eaSignal_addr; + + if (direction == CELL_SYNC_QUEUE_ANY2ANY) + { + queue->m_h3 = 0; + queue->m_h7 = 0; + queue->m_buffer = (u64)buffer_addr | 1; + queue->m_bs[0] = -1; + queue->m_bs[1] = -1; + //m_bs[2] + //m_bs[3] + queue->m_v1 = -1; + queue->m_hs[0] = -1; + queue->m_hs[16] = -1; + queue->m_v2 = 0; + queue->m_v3 = 0; + } + else + { + //m_h3 + //m_h7 + queue->m_bs[0] = -1; // written as u32 + queue->m_bs[1] = -1; + queue->m_bs[2] = -1; + queue->m_bs[3] = -1; + queue->m_v1 = 0; + queue->m_v2 = 0; // written as u64 + queue->m_v3 = 0; + } } -int cellSyncLFQueueClear() +s32 syncLFQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr) { - cellSync->Todo("cellSyncLFQueueClear()"); - return CELL_OK; -} +#ifdef PRX_DEBUG_XXX + return GetCurrentPPUThread().FastCall(libsre + 0x205C, libsre_rtoc, queue.GetAddr(), buffer_addr, size, depth, direction, eaSignal_addr); +#else -int _cellSyncLFQueueCompletePushPointer2() -{ - cellSync->Todo("_cellSyncLFQueueCompletePushPointer2()"); - return CELL_OK; -} - -int _cellSyncLFQueueGetPopPointer2() -{ - cellSync->Todo("_cellSyncLFQueueGetPopPointer2()"); - return CELL_OK; -} - -int _cellSyncLFQueueCompletePushPointer() -{ - cellSync->Todo("_cellSyncLFQueueCompletePushPointer()"); - return CELL_OK; -} - -int _cellSyncLFQueueAttachLv2EventQueue() -{ - cellSync->Todo("_cellSyncLFQueueAttachLv2EventQueue()"); - return CELL_OK; -} - -int _cellSyncLFQueueGetPushPointer2() -{ - cellSync->Todo("_cellSyncLFQueueGetPushPointer2()"); - return CELL_OK; -} - -int _cellSyncLFQueueGetPopPointer() -{ - cellSync->Todo("_cellSyncLFQueueGetPopPointer()"); - return CELL_OK; -} - -int _cellSyncLFQueueCompletePopPointer2() -{ - cellSync->Todo("_cellSyncLFQueueCompletePopPointer2()"); - return CELL_OK; -} - -int _cellSyncLFQueueDetachLv2EventQueue() -{ - cellSync->Todo("_cellSyncLFQueueDetachLv2EventQueue()"); - return CELL_OK; -} - -void syncLFQueueInitialize(mem_ptr_t ea, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr) -{ - -} - -int cellSyncLFQueueInitialize(mem_ptr_t ea, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr) -{ - cellSync->Todo("cellSyncLFQueueInitialize(ea_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal_addr=0x%x)", - ea.GetAddr(), buffer_addr, size, depth, direction, eaSignal_addr); - - if (!ea) + if (!queue) { return CELL_SYNC_ERROR_NULL_POINTER; } @@ -1118,7 +1117,7 @@ int cellSyncLFQueueInitialize(mem_ptr_t ea, u32 buffer_addr, u3 { return CELL_SYNC_ERROR_INVAL; } - if (ea.GetAddr() % 128 || buffer_addr % 16) + if (queue.GetAddr() % 128 || buffer_addr % 16) { return CELL_SYNC_ERROR_ALIGN; } @@ -1139,9 +1138,9 @@ int cellSyncLFQueueInitialize(mem_ptr_t ea, u32 buffer_addr, u3 u32 old_value; while (true) { - const u32 old_data = ea->m_data1(); + const u32 old_data = queue->m_data(); CellSyncLFQueue new_data; - new_data.m_data1() = old_data; + new_data.m_data() = old_data; if (old_data) { @@ -1157,28 +1156,28 @@ int cellSyncLFQueueInitialize(mem_ptr_t ea, u32 buffer_addr, u3 { for (u32 i = 0; i < sizeof(CellSyncLFQueue) / sizeof(u64); i++) { - if ((u64&)Memory[ea.GetAddr() + i * sizeof(u64)]) + if ((u64&)Memory[queue.GetAddr() + i * sizeof(u64)]) { return CELL_SYNC_ERROR_STAT; } } } - new_data.m_data1() = se32(1); + new_data.m_data() = se32(1); old_value = se32(1); } - - if (InterlockedCompareExchange(&ea->m_data1(), new_data.m_data1(), old_data) == old_data) break; + + if (InterlockedCompareExchange(&queue->m_data(), new_data.m_data(), old_data) == old_data) break; } if (old_value == se32(2)) { - if ((u32)ea->m_size != size || (u32)ea->m_depth != depth || (u64)ea->m_buffer != (u64)buffer_addr) + if ((u32)queue->m_size != size || (u32)queue->m_depth != depth || (u64)queue->m_buffer != (u64)buffer_addr) { return CELL_SYNC_ERROR_INVAL; } if (sdk_ver > 0x17ffff) { - if ((u64)ea->m_eaSignal != (u64)eaSignal_addr || (u32)ea->m_direction != direction) + if ((u64)queue->m_eaSignal != (u64)eaSignal_addr || (u32)queue->m_direction != direction) { return CELL_SYNC_ERROR_INVAL; } @@ -1187,60 +1186,990 @@ int cellSyncLFQueueInitialize(mem_ptr_t ea, u32 buffer_addr, u3 else { // prx: call internal function with same arguments - + syncLFQueueInit(queue, buffer_addr, size, depth, direction, eaSignal_addr); // prx: sync, zeroize u32 at 0x2c offset - InterlockedCompareExchange(&ea->m_data1(), 0, 0); - ea->m_data1() = 0; + InterlockedCompareExchange(&queue->m_data(), 0, 0); + queue->m_data() = 0; } // prx: sync - InterlockedCompareExchange(&ea->m_data1(), 0, 0); + InterlockedCompareExchange(&queue->m_data(), 0, 0); + return CELL_OK; +#endif +} + +s32 cellSyncLFQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr) +{ + cellSync->Warning("cellSyncLFQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal_addr=0x%x)", + queue.GetAddr(), buffer_addr, size, depth, direction, eaSignal_addr); + + return syncLFQueueInitialize(queue, buffer_addr, size, depth, direction, eaSignal_addr); +} + +s32 syncLFQueueGetPushPointer(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32 useEventQueue) +{ + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_PPU2SPU)) + { + return CELL_SYNC_ERROR_PERM; + } + + u32 var1 = 0; + s32 depth = (u32)queue->m_depth; + while (true) + { + while (true) + { + if (Emu.IsStopped()) + { + return -1; + } + + const u64 old_data = InterlockedCompareExchange(&queue->m_push1(), 0, 0); + CellSyncLFQueue new_queue; + new_queue.m_push1() = old_data; + + if (var1) + { + new_queue.m_h7 = 0; + } + if (isBlocking && useEventQueue && *(u32*)queue->m_bs == -1) + { + return CELL_SYNC_ERROR_STAT; + } + + s32 var2 = (s32)(s16)new_queue.m_h8; + s32 res; + if (useEventQueue && ((s32)(u16)new_queue.m_h5 != var2 || new_queue.m_h7.ToBE() != 0)) + { + res = CELL_SYNC_ERROR_BUSY; + } + else + { + var2 -= (s32)(u16)queue->m_h1; + if (var2 < 0) + { + var2 += depth * 2; + } + + if (var2 < depth) + { + pointer = (s16)new_queue.m_h8; + if (pointer + 1 >= depth * 2) + { + new_queue.m_h8 = 0; + } + else + { + new_queue.m_h8++; + } + res = CELL_OK; + } + else if (!isBlocking) + { + res = CELL_SYNC_ERROR_AGAIN; + if (!new_queue.m_h7.ToBE() || res) + { + return res; + } + break; + } + else if (!useEventQueue) + { + continue; + } + else + { + res = CELL_OK; + new_queue.m_h7 = 3; + if (isBlocking != 3) + { + break; + } + } + } + + if (InterlockedCompareExchange(&queue->m_push1(), new_queue.m_push1(), old_data) == old_data) + { + if (!new_queue.m_h7.ToBE() || res) + { + return res; + } + break; + } + } + + u32 eq = (u32)queue->m_v3; // 0x7c + sys_event_data event; + assert(0); + // TODO: sys_event_queue_receive (event data is not used), assert if error returned + var1 = 1; + } + + assert(0); +} + +s32 _cellSyncLFQueueGetPushPointer(mem_ptr_t queue, mem32_t pointer, u32 isBlocking, u32 useEventQueue) +{ + cellSync->Todo("_cellSyncLFQueueGetPushPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", + queue.GetAddr(), pointer.GetAddr(), isBlocking, useEventQueue); + + s32 pointer_value; + s32 result = syncLFQueueGetPushPointer(queue, pointer_value, isBlocking, useEventQueue); + pointer = pointer_value; + return result; +} + +s32 syncLFQueueGetPushPointer2(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32 useEventQueue) +{ + // TODO + //pointer = 0; + assert(0); return CELL_OK; } -int _cellSyncLFQueueGetSignalAddress() +s32 _cellSyncLFQueueGetPushPointer2(mem_ptr_t queue, mem32_t pointer, u32 isBlocking, u32 useEventQueue) { - cellSync->Todo("_cellSyncLFQueueGetSignalAddress()"); + // arguments copied from _cellSyncLFQueueGetPushPointer + cellSync->Todo("_cellSyncLFQueueGetPushPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", + queue.GetAddr(), pointer.GetAddr(), isBlocking, useEventQueue); + + s32 pointer_value; + s32 result = syncLFQueueGetPushPointer2(queue, pointer_value, isBlocking, useEventQueue); + pointer = pointer_value; + return result; +} + +s32 syncLFQueueCompletePushPointer(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal) +{ + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_PPU2SPU)) + { + return CELL_SYNC_ERROR_PERM; + } + + s32 depth = (u32)queue->m_depth; + + while (true) + { + const u32 old_data = InterlockedCompareExchange(&queue->m_push2(), 0, 0); + CellSyncLFQueue new_queue; + new_queue.m_push2() = old_data; + + const u32 old_data2 = queue->m_push3(); + new_queue.m_push3() = old_data2; + + s32 var1 = pointer - (u16)new_queue.m_h5; + if (var1 < 0) + { + var1 += depth * 2; + } + + s32 var2 = (s32)(s16)queue->m_h4 - (s32)(u16)queue->m_h1; + if (var2 < 0) + { + var2 += depth * 2; + } + + s32 var9_ = 15 - var1; + // calculate (1 slw (15 - var1)) + if (var9_ & 0x30) + { + var9_ = 0; + } + else + { + var9_ = 1 << var9_; + } + s32 var9 = ~(var9_ | (u16)new_queue.m_h6); + // count leading zeros in u16 + { + u16 v = var9; + for (var9 = 0; var9 < 16; var9++) + { + if (v & (1 << (15 - var9))) + { + break; + } + } + } + + s32 var5 = (s32)(u16)new_queue.m_h6 | var9_; + if (var9 & 0x30) + { + var5 = 0; + } + else + { + var5 <<= var9; + } + + s32 var3 = (u16)new_queue.m_h5 + var9; + if (var3 >= depth * 2) + { + var3 -= depth * 2; + } + + u16 pack = new_queue.m_hs[0]; // three packed 5-bit fields + + s32 var4 = ((pack >> 10) & 0x1f) - ((pack >> 5) & 0x1f); + if (var4 < 0) + { + var4 += 0x1e; + } + + u32 var6; + if (var2 + var4 <= 15 && ((pack >> 10) & 0x1f) != (pack & 0x1f)) + { + s32 var8 = (pack & 0x1f) - ((pack >> 10) & 0x1f); + if (var8 < 0) + { + var8 += 0x1e; + } + + if (var9 > 1 && (u32)var8 > 1) + { + assert(16 - var2 <= 1); + } + + s32 var11 = (pack >> 10) & 0x1f; + if (var11 >= 15) + { + var11 -= 15; + } + + u16 var12 = (pack >> 10) & 0x1f; + if (var12 == 0x1d) + { + var12 = 0; + } + else + { + var12 = (var12 + 1) << 10; + } + + new_queue.m_hs[0] = (pack & 0x83ff) | var12; + var6 = (u16)queue->m_hs[1 + 2 * var11]; + } + else + { + var6 = -1; + } + + s32 var7 = (var3 << 16) | (var5 & 0xffff); + + if (InterlockedCompareExchange(&queue->m_push2(), new_queue.m_push2(), old_data) == old_data) + { + assert(var2 + var4 < 16); + if (var6 != -1) + { + bool exch = InterlockedCompareExchange(&queue->m_push3(), re32(var7), old_data2) == old_data2; + assert(exch); + if (exch) + { + assert(fpSendSignal); + return fpSendSignal((u64)queue->m_eaSignal, var6); + } + } + else + { + pack = queue->m_hs[0]; + if ((pack & 0x1f) == ((pack >> 10) & 0x1f)) + { + if (InterlockedCompareExchange(&queue->m_push3(), re32(var7), old_data2) == old_data2) + { + return CELL_OK; + } + } + } + } + } + + assert(0); +} + +s32 _cellSyncLFQueueCompletePushPointer(mem_ptr_t queue, s32 pointer, mem_func_ptr_t fpSendSignal) +{ + cellSync->Todo("_cellSyncLFQueueCompletePushPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", + queue.GetAddr(), pointer, fpSendSignal.GetAddr()); + + return syncLFQueueCompletePushPointer(queue, pointer, [fpSendSignal](u32 addr, u32 arg){ return fpSendSignal(addr, arg); }); +} + +s32 syncLFQueueCompletePushPointer2(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal) +{ + // TODO + //if (fpSendSignal) return fpSendSignal(0, 0); + assert(0); return CELL_OK; } -int _cellSyncLFQueuePushBody() +s32 _cellSyncLFQueueCompletePushPointer2(mem_ptr_t queue, s32 pointer, mem_func_ptr_t fpSendSignal) { - cellSync->Todo("_cellSyncLFQueuePushBody()"); + // arguments copied from _cellSyncLFQueueCompletePushPointer + cellSync->Todo("_cellSyncLFQueueCompletePushPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", + queue.GetAddr(), pointer, fpSendSignal.GetAddr()); + + return syncLFQueueCompletePushPointer2(queue, pointer, [fpSendSignal](u32 addr, u32 arg){ return fpSendSignal(addr, arg); }); +} + +s32 _cellSyncLFQueuePushBody(mem_ptr_t queue, u32 buffer_addr, u32 isBlocking) +{ + // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 + cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.GetAddr(), buffer_addr, isBlocking); + + if (!queue || !buffer_addr) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128 || buffer_addr % 16) + { + return CELL_SYNC_ERROR_ALIGN; + } + + s32 position; + //syncLFQueueDump(queue); + +#ifdef PRX_DEBUG + MemoryAllocator> position_v; +#endif + while (true) + { + s32 res; + + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY)) + { +#ifdef PRX_DEBUG_XXX + res = GetCurrentPPUThread().FastCall(libsre + 0x24B0, libsre_rtoc, queue.GetAddr(), position_v.GetAddr(), isBlocking, 0); + position = position_v->ToLE(); +#else + res = syncLFQueueGetPushPointer(queue, position, isBlocking, 0); +#endif + } + else + { +#ifdef PRX_DEBUG + res = GetCurrentPPUThread().FastCall(libsre + 0x3050, libsre_rtoc, queue.GetAddr(), position_v.GetAddr(), isBlocking, 0); + position = position_v->ToLE(); +#else + res = syncLFQueueGetPushPointer2(queue, position, isBlocking, 0); +#endif + } + + //LOG_NOTICE(HLE, "... position = %d", position); + //syncLFQueueDump(queue); + + if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) + { + if (res) + { + return res; + } + break; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + if (Emu.IsStopped()) + { + cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x) aborted", queue.GetAddr()); + return CELL_OK; + } + } + + s32 depth = (u32)queue->m_depth; + s32 size = (u32)queue->m_size; + memcpy(Memory + (((u64)queue->m_buffer & ~1ull) + size * (position >= depth ? position - depth : position)), Memory + buffer_addr, size); + + s32 res; + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY)) + { +#ifdef PRX_DEBUG_XXX + res = GetCurrentPPUThread().FastCall(libsre + 0x26C0, libsre_rtoc, queue.GetAddr(), position, 0); +#else + res = syncLFQueueCompletePushPointer(queue, position, nullptr); +#endif + } + else + { +#ifdef PRX_DEBUG + res = GetCurrentPPUThread().FastCall(libsre + 0x355C, libsre_rtoc, queue.GetAddr(), position, 0); +#else + res = syncLFQueueCompletePushPointer2(queue, position, nullptr); +#endif + } + + //syncLFQueueDump(queue); + return res; +} + +s32 syncLFQueueGetPopPointer(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue) +{ + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_SPU2PPU)) + { + return CELL_SYNC_ERROR_PERM; + } + + u32 var1 = 0; + s32 depth = (u32)queue->m_depth; + while (true) + { + while (true) + { + if (Emu.IsStopped()) + { + return -1; + } + + const u64 old_data = InterlockedCompareExchange(&queue->m_pop1(), 0, 0); + CellSyncLFQueue new_queue; + new_queue.m_pop1() = old_data; + + if (var1) + { + new_queue.m_h3 = 0; + } + if (isBlocking && useEventQueue && *(u32*)queue->m_bs == -1) + { + return CELL_SYNC_ERROR_STAT; + } + + s32 var2 = (s32)(s16)new_queue.m_h4; + s32 res; + if (useEventQueue && ((s32)(u16)new_queue.m_h1 != var2 || new_queue.m_h3.ToBE() != 0)) + { + res = CELL_SYNC_ERROR_BUSY; + } + else + { + var2 = (s32)(u16)queue->m_h5 - var2; + if (var2 < 0) + { + var2 += depth * 2; + } + + if (var2 > 0) + { + pointer = (s16)new_queue.m_h4; + if (pointer + 1 >= depth * 2) + { + new_queue.m_h4 = 0; + } + else + { + new_queue.m_h4++; + } + res = CELL_OK; + } + else if (!isBlocking) + { + res = CELL_SYNC_ERROR_AGAIN; + if (!new_queue.m_h3.ToBE() || res) + { + return res; + } + break; + } + else if (!useEventQueue) + { + continue; + } + else + { + res = CELL_OK; + new_queue.m_h3 = 3; + if (isBlocking != 3) + { + break; + } + } + } + + if (InterlockedCompareExchange(&queue->m_pop1(), new_queue.m_pop1(), old_data) == old_data) + { + if (!new_queue.m_h3.ToBE() || res) + { + return res; + } + break; + } + } + + u32 eq = (u32)queue->m_v3; // 0x7c + sys_event_data event; + assert(0); + // TODO: sys_event_queue_receive (event data is not used), assert if error returned + var1 = 1; + } + + assert(0); +} + +s32 _cellSyncLFQueueGetPopPointer(mem_ptr_t queue, mem32_t pointer, u32 isBlocking, u32 arg4, u32 useEventQueue) +{ + cellSync->Todo("_cellSyncLFQueueGetPopPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", + queue.GetAddr(), pointer.GetAddr(), isBlocking, arg4, useEventQueue); + + s32 pointer_value; + s32 result = syncLFQueueGetPopPointer(queue, pointer_value, isBlocking, arg4, useEventQueue); + pointer = pointer_value; + return result; +} + +s32 syncLFQueueGetPopPointer2(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32 useEventQueue) +{ + // TODO + //pointer = 0; + assert(0); return CELL_OK; } -int cellSyncLFQueueGetDirection() +s32 _cellSyncLFQueueGetPopPointer2(mem_ptr_t queue, mem32_t pointer, u32 isBlocking, u32 useEventQueue) { - cellSync->Todo("cellSyncLFQueueGetDirection()"); + // arguments copied from _cellSyncLFQueueGetPopPointer + cellSync->Todo("_cellSyncLFQueueGetPopPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", + queue.GetAddr(), pointer.GetAddr(), isBlocking, useEventQueue); + + s32 pointer_value; + s32 result = syncLFQueueGetPopPointer2(queue, pointer_value, isBlocking, useEventQueue); + pointer = pointer_value; + return result; +} + +s32 syncLFQueueCompletePopPointer(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) +{ + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_SPU2PPU)) + { + return CELL_SYNC_ERROR_PERM; + } + + s32 depth = (u32)queue->m_depth; + + while (true) + { + const u32 old_data = InterlockedCompareExchange(&queue->m_pop2(), 0, 0); + CellSyncLFQueue new_queue; + new_queue.m_pop2() = old_data; + + const u32 old_data2 = queue->m_pop3(); + new_queue.m_pop3() = old_data2; + + s32 var1 = pointer - (u16)new_queue.m_h1; + if (var1 < 0) + { + var1 += depth * 2; + } + + s32 var2 = (s32)(s16)queue->m_h8 - (s32)(u16)queue->m_h5; + if (var2 < 0) + { + var2 += depth * 2; + } + + s32 var9_ = 15 - var1; + // calculate (1 slw (15 - var1)) + if (var9_ & 0x30) + { + var9_ = 0; + } + else + { + var9_ = 1 << var9_; + } + s32 var9 = ~(var9_ | (u16)new_queue.m_h2); + // count leading zeros in u16 + { + u16 v = var9; + for (var9 = 0; var9 < 16; var9++) + { + if (v & (1 << (15 - var9))) + { + break; + } + } + } + + s32 var5 = (s32)(u16)new_queue.m_h2 | var9_; + if (var9 & 0x30) + { + var5 = 0; + } + else + { + var5 <<= var9; + } + + s32 var3 = (u16)new_queue.m_h1 + var9; + if (var3 >= depth * 2) + { + var3 -= depth * 2; + } + + u16 pack = new_queue.m_hs[16]; // three packed 5-bit fields + + s32 var4 = ((pack >> 10) & 0x1f) - ((pack >> 5) & 0x1f); + if (var4 < 0) + { + var4 += 0x1e; + } + + u32 var6; + if (noQueueFull || var2 + var4 > 15 || ((pack >> 10) & 0x1f) == (pack & 0x1f)) + { + var6 = -1; + } + else + { + s32 var8 = (pack & 0x1f) - ((pack >> 10) & 0x1f); + if (var8 < 0) + { + var8 += 0x1e; + } + + if (var9 > 1 && (u32)var8 > 1) + { + assert(16 - var2 <= 1); + } + + s32 var11 = (pack >> 10) & 0x1f; + if (var11 >= 15) + { + var11 -= 15; + } + + u16 var12 = (pack >> 10) & 0x1f; + if (var12 == 0x1d) + { + var12 = 0; + } + else + { + var12 = (var12 + 1) << 10; + } + + new_queue.m_hs[0] = (pack & 0x83ff) | var12; + var6 = (u16)queue->m_hs[17 + 2 * var11]; + } + + s32 var7 = (var3 << 16) | (var5 & 0xffff); + + if (InterlockedCompareExchange(&queue->m_pop2(), new_queue.m_pop2(), old_data) == old_data) + { + if (var6 != -1) + { + bool exch = InterlockedCompareExchange(&queue->m_pop3(), re32(var7), old_data2) == old_data2; + assert(exch); + if (exch) + { + assert(fpSendSignal); + return fpSendSignal((u64)queue->m_eaSignal, var6); + } + } + else + { + pack = queue->m_hs[16]; + if ((pack & 0x1f) == ((pack >> 10) & 0x1f)) + { + if (InterlockedCompareExchange(&queue->m_pop3(), re32(var7), old_data2) == old_data2) + { + return CELL_OK; + } + } + } + } + } + + assert(0); +} + +s32 _cellSyncLFQueueCompletePopPointer(mem_ptr_t queue, s32 pointer, mem_func_ptr_t fpSendSignal, u32 noQueueFull) +{ + // arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer) + cellSync->Todo("_cellSyncLFQueueCompletePopPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", + queue.GetAddr(), pointer, fpSendSignal.GetAddr(), noQueueFull); + + return syncLFQueueCompletePopPointer(queue, pointer, [fpSendSignal](u32 addr, u32 arg){ return fpSendSignal(addr, arg); }, noQueueFull); +} + +s32 syncLFQueueCompletePopPointer2(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) +{ + // TODO + //if (fpSendSignal) fpSendSignal(0, 0); + assert(0); return CELL_OK; } -int cellSyncLFQueueDepth() +s32 _cellSyncLFQueueCompletePopPointer2(mem_ptr_t queue, s32 pointer, mem_func_ptr_t fpSendSignal, u32 noQueueFull) { - cellSync->Todo("cellSyncLFQueueDepth()"); + // arguments copied from _cellSyncLFQueueCompletePopPointer + cellSync->Todo("_cellSyncLFQueueCompletePopPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", + queue.GetAddr(), pointer, fpSendSignal.GetAddr(), noQueueFull); + + return syncLFQueueCompletePopPointer2(queue, pointer, [fpSendSignal](u32 addr, u32 arg){ return fpSendSignal(addr, arg); }, noQueueFull); +} + +s32 _cellSyncLFQueuePopBody(mem_ptr_t queue, u32 buffer_addr, u32 isBlocking) +{ + // cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0 + cellSync->Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.GetAddr(), buffer_addr, isBlocking); + + if (!queue || !buffer_addr) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128 || buffer_addr % 16) + { + return CELL_SYNC_ERROR_ALIGN; + } + + s32 position; +#ifdef PRX_DEBUG + MemoryAllocator> position_v; +#endif + while (true) + { + s32 res; + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY)) + { +#ifdef PRX_DEBUG_XXX + res = GetCurrentPPUThread().FastCall(libsre + 0x2A90, libsre_rtoc, queue.GetAddr(), position_v.GetAddr(), isBlocking, 0, 0); + position = position_v->ToLE(); +#else + res = syncLFQueueGetPopPointer(queue, position, isBlocking, 0, 0); +#endif + } + else + { +#ifdef PRX_DEBUG + res = GetCurrentPPUThread().FastCall(libsre + 0x39AC, libsre_rtoc, queue.GetAddr(), position_v.GetAddr(), isBlocking, 0); + position = position_v->ToLE(); +#else + res = syncLFQueueGetPopPointer2(queue, position, isBlocking, 0); +#endif + } + + if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) + { + if (res) + { + return res; + } + break; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + if (Emu.IsStopped()) + { + cellSync->Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x) aborted", queue.GetAddr()); + return CELL_OK; + } + } + + s32 depth = (u32)queue->m_depth; + s32 size = (u32)queue->m_size; + memcpy(Memory + buffer_addr, Memory + (((u64)queue->m_buffer & ~1ull) + size * (position >= depth ? position - depth : position)), size); + + s32 res; + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY)) + { +#ifdef PRX_DEBUG_XXX + res = GetCurrentPPUThread().FastCall(libsre + 0x2CA8, libsre_rtoc, queue.GetAddr(), position, 0, 0); +#else + res = syncLFQueueCompletePopPointer(queue, position, nullptr, 0); +#endif + } + else + { +#ifdef PRX_DEBUG + res = GetCurrentPPUThread().FastCall(libsre + 0x3EB8, libsre_rtoc, queue.GetAddr(), position, 0, 0); +#else + res = syncLFQueueCompletePopPointer2(queue, position, nullptr, 0); +#endif + } + + return res; +} + +s32 cellSyncLFQueueClear(mem_ptr_t queue) +{ + cellSync->Warning("cellSyncLFQueueClear(queue_addr=0x%x)", queue.GetAddr()); + + if (!queue) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128) + { + return CELL_SYNC_ERROR_ALIGN; + } + + // TODO: optimize if possible + while (true) + { + const u64 old_data = InterlockedCompareExchange(&queue->m_pop1(), 0, 0); + CellSyncLFQueue new_queue; + new_queue.m_pop1() = old_data; + + const u64 new_data = queue->m_push1(); + new_queue.m_push1() = new_data; + + s32 var1, var2; + if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY)) + { + var1 = var2 = (u16)queue->m_hs[16]; + } + else + { + var1 = (u16)new_queue.m_h7; + var2 = (u16)new_queue.m_h3; + } + + if ((s32)(s16)new_queue.m_h4 != (s32)(u16)new_queue.m_h1 || + (s32)(s16)new_queue.m_h8 != (s32)(u16)new_queue.m_h5 || + ((var2 >> 10) & 0x1f) != (var2 & 0x1f) || + ((var1 >> 10) & 0x1f) != (var1 & 0x1f)) + { + return CELL_SYNC_ERROR_BUSY; + } + + if (InterlockedCompareExchange(&queue->m_pop1(), new_data, old_data) == old_data) break; + } + return CELL_OK; } -int _cellSyncLFQueuePopBody() +s32 cellSyncLFQueueSize(mem_ptr_t queue, mem32_t size) { - cellSync->Todo("_cellSyncLFQueuePopBody()"); + cellSync->Warning("cellSyncLFQueueSize(queue_addr=0x%x, size_addr=0x%x)", queue.GetAddr(), size.GetAddr()); + + if (!queue || !size.GetAddr()) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128) + { + return CELL_SYNC_ERROR_ALIGN; + } + + // TODO: optimize if possible + while (true) + { + const u32 old_data = InterlockedCompareExchange(&queue->m_pop3(), 0, 0); + + u32 var1 = (u16)queue->m_h1; + u32 var2 = (u16)queue->m_h5; + + if (InterlockedCompareExchange(&queue->m_pop3(), old_data, old_data) == old_data) + { + if (var1 <= var2) + { + size = var2 - var1; + } + else + { + size = var2 - var1 + (u32)queue->m_depth * 2; + } + return CELL_OK; + } + } + + assert(0); +} + +s32 cellSyncLFQueueDepth(mem_ptr_t queue, mem32_t depth) +{ + cellSync->Log("cellSyncLFQueueDepth(queue_addr=0x%x, depth_addr=0x%x)", queue.GetAddr(), depth.GetAddr()); + + if (!queue || !depth.GetAddr()) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128) + { + return CELL_SYNC_ERROR_ALIGN; + } + + depth = queue->m_depth; return CELL_OK; } -int _cellSyncLFQueueGetPushPointer() +s32 _cellSyncLFQueueGetSignalAddress(mem_ptr_t queue, mem32_t ppSignal) { - cellSync->Todo("_cellSyncLFQueueGetPushPointer()"); + cellSync->Log("_cellSyncLFQueueGetSignalAddress(queue_addr=0x%x, ppSignal_addr=0x%x)", queue.GetAddr(), ppSignal.GetAddr()); + + if (!queue || !ppSignal.GetAddr()) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128) + { + return CELL_SYNC_ERROR_ALIGN; + } + + ppSignal = queue->m_eaSignal; return CELL_OK; } -int _cellSyncLFQueueCompletePopPointer() +s32 cellSyncLFQueueGetDirection(mem_ptr_t queue, mem32_t direction) { - cellSync->Todo("_cellSyncLFQueueCompletePopPointer()"); + cellSync->Log("cellSyncLFQueueGetDirection(queue_addr=0x%x, direction_addr=0x%x)", queue.GetAddr(), direction.GetAddr()); + + if (!queue || !direction.GetAddr()) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128) + { + return CELL_SYNC_ERROR_ALIGN; + } + + direction = queue->m_direction; return CELL_OK; } +s32 cellSyncLFQueueGetEntrySize(mem_ptr_t queue, mem32_t entry_size) +{ + cellSync->Log("cellSyncLFQueueGetEntrySize(queue_addr=0x%x, entry_size_addr=0x%x)", queue.GetAddr(), entry_size.GetAddr()); + + if (!queue || !entry_size.GetAddr()) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (queue.GetAddr() % 128) + { + return CELL_SYNC_ERROR_ALIGN; + } + + entry_size = queue->m_size; + return CELL_OK; +} + +s32 syncLFQueueAttachLv2EventQueue(mem32_ptr_t spus, u32 num, mem_ptr_t queue) +{ + // TODO + assert(0); + return CELL_OK; +} + +s32 _cellSyncLFQueueAttachLv2EventQueue(mem32_ptr_t spus, u32 num, mem_ptr_t queue) +{ + cellSync->Todo("_cellSyncLFQueueAttachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.GetAddr(), num, queue.GetAddr()); + + return syncLFQueueAttachLv2EventQueue(spus, num, queue); +} + +s32 syncLFQueueDetachLv2EventQueue(mem32_ptr_t spus, u32 num, mem_ptr_t queue) +{ + // TODO + assert(0); + return CELL_OK; +} + +s32 _cellSyncLFQueueDetachLv2EventQueue(mem32_ptr_t spus, u32 num, mem_ptr_t queue) +{ + cellSync->Todo("_cellSyncLFQueueDetachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.GetAddr(), num, queue.GetAddr()); + + return syncLFQueueDetachLv2EventQueue(spus, num, queue); +} + void cellSync_init() { cellSync->AddFunc(0xa9072dee, cellSyncMutexInitialize); @@ -1289,4 +2218,102 @@ void cellSync_init() cellSync->AddFunc(0xe1bc7add, _cellSyncLFQueuePopBody); cellSync->AddFunc(0xe9bf2110, _cellSyncLFQueueGetPushPointer); cellSync->AddFunc(0xfe74e8e7, _cellSyncLFQueueCompletePopPointer); + +#ifdef PRX_DEBUG + wxGetApp().CallAfter([&]() + { + libsre = Memory.PRXMem.AllocAlign(sizeof(libsre_data), 4096); + memcpy(Memory + libsre, libsre_data, sizeof(libsre_data)); + libsre_rtoc = libsre + 0x399B0; + + extern Module* sysPrxForUser; + + FIX_IMPORT(sysPrxForUser, cellUserTraceRegister , libsre + 0x1D5BC); // ??? + FIX_IMPORT(sysPrxForUser, cellUserTraceUnregister , libsre + 0x1D5DC); // ??? + + FIX_IMPORT(sysPrxForUser, _sys_strncmp , libsre + 0x1D5FC); + FIX_IMPORT(sysPrxForUser, _sys_strcat , libsre + 0x1D61C); + FIX_IMPORT(sysPrxForUser, _sys_vsnprintf , libsre + 0x1D63C); + FIX_IMPORT(sysPrxForUser, _sys_snprintf , libsre + 0x1D65C); + FIX_IMPORT(sysPrxForUser, sys_lwmutex_lock , libsre + 0x1D67C); + FIX_IMPORT(sysPrxForUser, sys_lwmutex_unlock , libsre + 0x1D69C); + FIX_IMPORT(sysPrxForUser, sys_lwcond_destroy , libsre + 0x1D6BC); + FIX_IMPORT(sysPrxForUser, sys_ppu_thread_create , libsre + 0x1D6DC); + FIX_IMPORT(sysPrxForUser, sys_lwcond_wait , libsre + 0x1D6FC); + FIX_IMPORT(sysPrxForUser, _sys_strlen , libsre + 0x1D71C); + FIX_IMPORT(sysPrxForUser, sys_lwmutex_create , libsre + 0x1D73C); + FIX_IMPORT(sysPrxForUser, _sys_spu_printf_detach_group , libsre + 0x1D75C); + FIX_IMPORT(sysPrxForUser, _sys_memset , libsre + 0x1D77C); + FIX_IMPORT(sysPrxForUser, _sys_memcpy , libsre + 0x1D79C); + FIX_IMPORT(sysPrxForUser, _sys_strncat , libsre + 0x1D7BC); + FIX_IMPORT(sysPrxForUser, _sys_strcpy , libsre + 0x1D7DC); + FIX_IMPORT(sysPrxForUser, _sys_printf , libsre + 0x1D7FC); + fix_import(sysPrxForUser, 0x9FB6228E , libsre + 0x1D81C); + FIX_IMPORT(sysPrxForUser, sys_ppu_thread_exit , libsre + 0x1D83C); + FIX_IMPORT(sysPrxForUser, sys_lwmutex_destroy , libsre + 0x1D85C); + FIX_IMPORT(sysPrxForUser, _sys_strncpy , libsre + 0x1D87C); + FIX_IMPORT(sysPrxForUser, sys_lwcond_create , libsre + 0x1D89C); + FIX_IMPORT(sysPrxForUser, _sys_spu_printf_attach_group , libsre + 0x1D8BC); + FIX_IMPORT(sysPrxForUser, sys_prx_get_module_id_by_name , libsre + 0x1D8DC); + FIX_IMPORT(sysPrxForUser, sys_spu_image_close , libsre + 0x1D8FC); + fix_import(sysPrxForUser, 0xE75C40F2 , libsre + 0x1D91C); + FIX_IMPORT(sysPrxForUser, sys_spu_image_import , libsre + 0x1D93C); + FIX_IMPORT(sysPrxForUser, sys_lwcond_signal , libsre + 0x1D95C); + FIX_IMPORT(sysPrxForUser, _sys_vprintf , libsre + 0x1D97C); + FIX_IMPORT(sysPrxForUser, _sys_memcmp , libsre + 0x1D99C); + + const u32 seg2 = 0x2DF00; + // start of table: + // addr = (u64) addr - seg2, (u32) 1, (u32) 1, (u64) ptr + // addr = (u64) addr - seg2, (u32) 0x101, (u32) 1, (u64) ptr - seg2 (???) + // addr = (u64) addr, (u32) 0x100, (u32) 1, (u64) ptr - seg2 (???) + // addr = (u64) addr, (u32) 0, (u32) 1, (u64) ptr (???) + + for (u32 i = libsre + 0x31EE0; i < libsre + 0x3A4F0; i += 24) + { + u64 addr = Memory.Read64(i); + const u64 flag = Memory.Read64(i + 8); + + if (flag == 0x10100000001ull) + { + addr = addr + seg2 + libsre; + u32 value = Memory.Read32(addr); + assert(value == Memory.Read64(i + 16) + seg2); + Memory.Write32(addr, value + libsre); + } + else if (flag == 0x100000001ull) + { + addr = addr + seg2 + libsre; + u32 value = Memory.Read32(addr); + assert(value == Memory.Read64(i + 16)); + Memory.Write32(addr, value + libsre); + } + else if (flag == 0x10000000001ull) + { + addr = addr + libsre; + u32 value = Memory.Read32(addr); + assert(value == Memory.Read64(i + 16) + seg2); + Memory.Write32(addr, value + libsre); + } + else if (flag == 1) + { + addr = addr + libsre; + u32 value = Memory.Read32(addr); + assert(value == Memory.Read64(i + 16)); + Memory.Write32(addr, value + libsre); + } + else if (flag == 0x10000000004ull || flag == 0x10000000006ull) + { + // seems to be instruction modifiers for imports (done in other way in FIX_IMPORT) + } + else + { + cellSync->Notice("libsre: 0x%x : 0x%llx", i - libsre, flag); + } + } + }); +#endif } + +#undef PRX_DEBUG +#undef FIX_IMPORT \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.h b/rpcs3/Emu/SysCalls/Modules/cellSync.h index ff941b65d4..70d9c7823d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.h @@ -87,7 +87,7 @@ struct CellSyncQueue static_assert(sizeof(CellSyncQueue) == 32, "CellSyncQueue: wrong size"); -enum CellSyncQueueDirection : u32 +enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection { CELL_SYNC_QUEUE_SPU2SPU = 0, // SPU to SPU CELL_SYNC_QUEUE_SPU2PPU = 1, // SPU to PPU @@ -97,29 +97,80 @@ enum CellSyncQueueDirection : u32 struct CellSyncLFQueue { - be_t m_v1; - be_t m_v2; - be_t m_size; - be_t m_depth; - be_t m_buffer; - be_t m_v5; - be_t m_direction; - be_t m_v6; - be_t m_v7; - be_t m_v8; - be_t m_v9; - be_t m_v10; - be_t m_v11; - be_t m_v12; - be_t m_v13; - be_t m_v14; - be_t m_eaSignal; - be_t reserved; + be_t m_h1; // 0x0 + be_t m_h2; // 0x2 + be_t m_h3; // 0x4 + be_t m_h4; // 0x6 + be_t m_h5; // 0x8 + be_t m_h6; // 0xA + be_t m_h7; // 0xC + be_t m_h8; // 0xE + be_t m_size; // 0x10 + be_t m_depth; // 0x14 + be_t m_buffer; // 0x18 + u8 m_bs[4]; // 0x20 + be_t m_direction; // 0x24 + be_t m_v1; // 0x28 + be_t m_sync; // 0x2C + be_t m_hs[32]; // 0x30 + be_t m_eaSignal;// 0x70 + be_t m_v2; // 0x78 + be_t m_v3; // 0x7C - volatile u32& m_data1() + volatile u32& m_data() { return *reinterpret_cast((u8*)this + 0x2c); } + + volatile u64& m_push1() + { + return *reinterpret_cast((u8*)this + 0x8); + } + + volatile u32& m_push2() + { + return *reinterpret_cast((u8*)this + 0x30); + } + + volatile u32& m_push3() + { + return *reinterpret_cast((u8*)this + 0x8); + } + + volatile u64& m_pop1() + { + return *reinterpret_cast((u8*)this + 0x0); + } + + volatile u32& m_pop2() + { + return *reinterpret_cast((u8*)this + 0x50); + } + + volatile u32& m_pop3() + { + return *reinterpret_cast((u8*)this + 0x0); + } }; -static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size"); \ No newline at end of file +static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size"); + +s32 syncMutexInitialize(mem_ptr_t mutex); + +s32 syncBarrierInitialize(mem_ptr_t barrier, u16 total_count); + +s32 syncRwmInitialize(mem_ptr_t rwm, u32 buffer_addr, u32 buffer_size); + +s32 syncQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth); + +s32 syncLFQueueInitialize(mem_ptr_t queue, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr); +s32 syncLFQueueGetPushPointer(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32 useEventQueue); +s32 syncLFQueueGetPushPointer2(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32 useEventQueue); +s32 syncLFQueueCompletePushPointer(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal); +s32 syncLFQueueCompletePushPointer2(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal); +s32 syncLFQueueGetPopPointer(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue); +s32 syncLFQueueGetPopPointer2(mem_ptr_t queue, s32& pointer, u32 isBlocking, u32 useEventQueue); +s32 syncLFQueueCompletePopPointer(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull); +s32 syncLFQueueCompletePopPointer2(mem_ptr_t queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull); +s32 syncLFQueueAttachLv2EventQueue(mem32_ptr_t spus, u32 num, mem_ptr_t queue); +s32 syncLFQueueDetachLv2EventQueue(mem32_ptr_t spus, u32 num, mem_ptr_t queue); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp index 1817f3c1b6..1a7017de43 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellSync2_init(); Module cellSync2(0x0055, cellSync2_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp index c470d28e36..89b1b9333d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/ModuleManager.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 390a6939e2..1c4b688c24 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -1,18 +1,18 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/DbgCommand.h" -#include "Emu/FS/vfsFile.h" -#include "Emu/Audio/sysutil_audio.h" -#include "cellSysutil.h" -#include "cellSysutil_SaveData.h" +#include "rpcs3/Ini.h" +#include "Emu/FS/vfsFile.h" +#include "Loader/PSF.h" +#include "Emu/Audio/sysutil_audio.h" +#include "Emu/RSX/sysutil_video.h" #include "cellMsgDialog.h" #include "cellGame.h" - -#include "Loader/PSF.h" +#include "cellSysutil.h" +#include "cellSysutil_SaveData.h" typedef void (*CellHddGameStatCallback)(mem_ptr_t cbResult, mem_ptr_t get, mem_ptr_t set); @@ -327,7 +327,7 @@ int cellSysutilCheckCallback() std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellSysutilCheckCallback() aborted"); + cellSysutil->Warning("cellSysutilCheckCallback() aborted"); break; } } @@ -550,7 +550,7 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut) int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, mem_ptr_t info) { - cellSysutil->Todo("Unimplemented function: cellAudioOutGetDeviceInfo(audioOut=%u, deviceIndex=%u, info_addr=0x%x)", + cellSysutil->Todo("cellAudioOutGetDeviceInfo(audioOut=%u, deviceIndex=%u, info_addr=0x%x)", audioOut, deviceIndex, info.GetAddr()); if(deviceIndex) return CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp index 2c2ddb95b3..0eb532cfed 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" //void cellSysutilAp_init(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp index 341ed6c4ef..9a52f1b1ab 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp @@ -1,14 +1,13 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" + #include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsDir.h" -#include - -#include "cellSysutil_SaveData.h" #include "Loader/PSF.h" +#include "cellSysutil_SaveData.h" +#include extern Module *cellSysutil; @@ -228,7 +227,7 @@ s32 modifySaveDataFiles(mem_func_ptr_t& funcFile, mem_ { funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) { @@ -249,7 +248,7 @@ s32 modifySaveDataFiles(mem_func_ptr_t& funcFile, mem_ case CELL_SAVEDATA_FILETYPE_CONTENT_SND0: filepath += "SND0.AT3"; break; default: - LOG_ERROR(HLE, "modifySaveDataFiles: Unknown fileType! Aborting..."); + cellSysutil->Error("modifySaveDataFiles: Unknown fileType! Aborting..."); return CELL_SAVEDATA_ERROR_PARAM; } @@ -272,11 +271,11 @@ s32 modifySaveDataFiles(mem_func_ptr_t& funcFile, mem_ break; case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC: - LOG_WARNING(HLE, "modifySaveDataFiles: File operation CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC not yet implemented"); + cellSysutil->Warning("modifySaveDataFiles: File operation CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC not yet implemented"); break; default: - LOG_ERROR(HLE, "modifySaveDataFiles: Unknown fileOperation! Aborting..."); + cellSysutil->Error("modifySaveDataFiles: Unknown fileOperation! Aborting..."); return CELL_SAVEDATA_ERROR_PARAM; } @@ -337,7 +336,7 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m funcList(result.GetAddr(), listGet.GetAddr(), listSet.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -345,7 +344,7 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m if (listSet->newData.GetAddr()) addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); if (saveEntries.size() == 0) { - LOG_WARNING(HLE, "cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error + cellSysutil->Warning("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error return CELL_SAVEDATA_RET_OK; } @@ -358,7 +357,7 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); Memory.Free(statGet->fileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -422,7 +421,7 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m funcList(result.GetAddr(), listGet.GetAddr(), listSet.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -430,7 +429,7 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m if (listSet->newData.GetAddr()) addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); if (saveEntries.size() == 0) { - LOG_WARNING(HLE, "cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error + cellSysutil->Warning("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error return CELL_SAVEDATA_RET_OK; } @@ -443,7 +442,7 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); Memory.Free(statGet->fileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -502,7 +501,7 @@ int cellSaveDataFixedSave2(u32 version, mem_ptr_t setList, } funcFixed(result.GetAddr(), listGet.GetAddr(), fixedSet.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataFixedSave2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataFixedSave2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } setSaveDataFixed(saveEntries, fixedSet.GetAddr()); @@ -513,7 +512,7 @@ int cellSaveDataFixedSave2(u32 version, mem_ptr_t setList, funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); Memory.Free(statGet->fileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataFixedSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataFixedSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam.GetAddr()) @@ -571,7 +570,7 @@ int cellSaveDataFixedLoad2(u32 version, mem_ptr_t setList, } funcFixed(result.GetAddr(), listGet.GetAddr(), fixedSet.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataFixedLoad2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataFixedLoad2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } setSaveDataFixed(saveEntries, fixedSet.GetAddr()); @@ -582,7 +581,7 @@ int cellSaveDataFixedLoad2(u32 version, mem_ptr_t setList, funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); Memory.Free(statGet->fileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam.GetAddr()) @@ -635,7 +634,7 @@ int cellSaveDataAutoSave2(u32 version, u32 dirName_addr, u32 errDialog, mem_ptr_ Memory.Free(statGet->fileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataAutoSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataAutoSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam.GetAddr()) @@ -675,7 +674,7 @@ int cellSaveDataAutoLoad2(u32 version, u32 dirName_addr, u32 errDialog, mem_ptr_ // The target entry does not exist if (saveEntries.size() == 0) { - LOG_WARNING(HLE, "cellSaveDataAutoLoad2: Couldn't find save entry (%s)", dirName.c_str()); + cellSysutil->Warning("cellSaveDataAutoLoad2: Couldn't find save entry (%s)", dirName.c_str()); return CELL_OK; // TODO: Can anyone check the actual behaviour of a PS3 when saves are not found? } @@ -685,7 +684,7 @@ int cellSaveDataAutoLoad2(u32 version, u32 dirName_addr, u32 errDialog, mem_ptr_ Memory.Free(statGet->fileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataAutoLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataAutoLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam.GetAddr()) @@ -747,7 +746,7 @@ int cellSaveDataListAutoSave(u32 version, u32 errDialog, mem_ptr_tresult < 0) { - LOG_ERROR(HLE, "cellSaveDataListAutoSave: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListAutoSave: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -755,7 +754,7 @@ int cellSaveDataListAutoSave(u32 version, u32 errDialog, mem_ptr_tnewData.GetAddr()) addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); if (saveEntries.size() == 0) { - LOG_WARNING(HLE, "cellSaveDataListAutoSave: No save entries found!"); // TODO: Find a better way to handle this error + cellSysutil->Warning("cellSaveDataListAutoSave: No save entries found!"); // TODO: Find a better way to handle this error return CELL_SAVEDATA_RET_OK; } @@ -768,7 +767,7 @@ int cellSaveDataListAutoSave(u32 version, u32 errDialog, mem_ptr_tfileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataListAutoSave: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListAutoSave: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -831,7 +830,7 @@ int cellSaveDataListAutoLoad(u32 version, u32 errDialog, mem_ptr_tresult < 0) { - LOG_ERROR(HLE, "cellSaveDataListAutoLoad: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListAutoLoad: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -839,7 +838,7 @@ int cellSaveDataListAutoLoad(u32 version, u32 errDialog, mem_ptr_tnewData.GetAddr()) addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); if (saveEntries.size() == 0) { - LOG_WARNING(HLE, "cellSaveDataListAutoLoad: No save entries found!"); // TODO: Find a better way to handle this error + cellSysutil->Warning("cellSaveDataListAutoLoad: No save entries found!"); // TODO: Find a better way to handle this error return CELL_SAVEDATA_RET_OK; } @@ -853,7 +852,7 @@ int cellSaveDataListAutoLoad(u32 version, u32 errDialog, mem_ptr_tfileList.GetAddr()); if (result->result < 0) { - LOG_ERROR(HLE, "cellSaveDataListAutoLoad: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil->Error("cellSaveDataListAutoLoad: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellUsbd.cpp b/rpcs3/Emu/SysCalls/Modules/cellUsbd.cpp index fa4323a05e..07759a9cb4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUsbd.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellUsbd.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellUsbd_init(); Module cellUsbd(0x001c, cellUsbd_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellUsbpspcm.cpp b/rpcs3/Emu/SysCalls/Modules/cellUsbpspcm.cpp index 9ce3671f2d..e4bb35bcc1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUsbpspcm.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellUsbpspcm.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellUsbpspcm_init(); Module cellUsbpspcm(0x0030, cellUsbpspcm_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp index a8325f6082..c549d2fada 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index c2b5d0b99e..73da9bb124 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -1,9 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "cellPamf.h" std::mutex g_mutex_avcodec_open2; @@ -14,12 +12,77 @@ extern "C" #include "libavutil/imgutils.h" } +#include "cellPamf.h" #include "cellVdec.h" //void cellVdec_init(); //Module cellVdec(0x0005, cellVdec_init); Module *cellVdec = nullptr; +VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg) + : type(type) + , profile(profile) + , memAddr(addr) + , memSize(size) + , memBias(0) + , cbFunc(func) + , cbArg(arg) + , is_finished(false) + , is_running(false) + , just_started(false) + , just_finished(false) + , ctx(nullptr) + , vdecCb(nullptr) +{ + AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); + if (!codec) + { + cellVdec->Error("VideoDecoder(): avcodec_find_decoder(H264) failed"); + Emu.Pause(); + return; + } + fmt = avformat_alloc_context(); + if (!fmt) + { + cellVdec->Error("VideoDecoder(): avformat_alloc_context failed"); + Emu.Pause(); + return; + } + io_buf = (u8*)av_malloc(4096); + fmt->pb = avio_alloc_context(io_buf, 4096, 0, this, vdecRead, NULL, NULL); + if (!fmt->pb) + { + cellVdec->Error("VideoDecoder(): avio_alloc_context failed"); + Emu.Pause(); + return; + } +} + +VideoDecoder::~VideoDecoder() +{ + // TODO: check finalization + if (ctx) + { + for (u32 i = frames.GetCount() - 1; ~i; i--) + { + VdecFrame& vf = frames.Peek(i); + av_frame_unref(vf.data); + av_frame_free(&vf.data); + } + avcodec_close(ctx); + avformat_close_input(&fmt); + } + if (fmt) + { + if (io_buf) + { + av_free(io_buf); + } + if (fmt->pb) av_free(fmt->pb); + avformat_free_context(fmt); + } +} + int vdecRead(void* opaque, u8* buf, int buf_size) { VideoDecoder& vdec = *(VideoDecoder*)opaque; @@ -33,7 +96,7 @@ next: { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "vdecRead(): aborted"); + cellVdec->Warning("vdecRead(): aborted"); return 0; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -69,7 +132,7 @@ next: } break; default: - LOG_ERROR(HLE, "vdecRead(): sequence error (task %d)", vdec.job.Peek().type); + cellVdec->Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type); return 0; } @@ -126,7 +189,7 @@ u32 vdecOpen(VideoDecoder* data) thread t("Video Decoder[" + std::to_string(vdec_id) + "] Thread", [&]() { - LOG_NOTICE(HLE, "Video Decoder thread started"); + cellVdec->Notice("Video Decoder thread started"); VdecTask& task = vdec.task; @@ -157,257 +220,257 @@ u32 vdecOpen(VideoDecoder* data) switch (task.type) { case vdecStartSeq: - { - // TODO: reset data - LOG_WARNING(HLE, "vdecStartSeq:"); + { + // TODO: reset data + cellVdec->Warning("vdecStartSeq:"); - vdec.reader.addr = 0; - vdec.reader.size = 0; - vdec.is_running = true; - vdec.just_started = true; - } - break; + vdec.reader.addr = 0; + vdec.reader.size = 0; + vdec.is_running = true; + vdec.just_started = true; + } + break; case vdecEndSeq: - { - // TODO: finalize - LOG_WARNING(HLE, "vdecEndSeq:"); + { + // TODO: finalize + cellVdec->Warning("vdecEndSeq:"); - vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); - /*Callback cb; - cb.SetAddr(vdec.cbFunc); - cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); - cb.Branch(true); // ???*/ + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); + /*Callback cb; + cb.SetAddr(vdec.cbFunc); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); + cb.Branch(true); // ???*/ - vdec.is_running = false; - vdec.just_finished = true; - } - break; + vdec.is_running = false; + vdec.just_finished = true; + } + break; case vdecDecodeAu: - { - int err; + { + int err; - if (task.mode != CELL_VDEC_DEC_MODE_NORMAL) + if (task.mode != CELL_VDEC_DEC_MODE_NORMAL) + { + cellVdec->Error("vdecDecodeAu: unsupported decoding mode(%d)", task.mode); + break; + } + + vdec.reader.addr = task.addr; + vdec.reader.size = task.size; + //LOG_NOTICE(HLE, "Video AU: size = 0x%x, pts = 0x%llx, dts = 0x%llx", task.size, task.pts, task.dts); + + if (vdec.just_started) + { + vdec.first_pts = task.pts; + vdec.last_pts = task.pts; + vdec.first_dts = task.dts; + } + + struct AVPacketHolder : AVPacket + { + AVPacketHolder(u32 size) { - LOG_ERROR(HLE, "vdecDecodeAu: unsupported decoding mode(%d)", task.mode); + av_init_packet(this); + + if (size) + { + data = (u8*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; + } + else + { + data = NULL; + size = 0; + } + } + + ~AVPacketHolder() + { + av_free(data); + //av_free_packet(this); + } + + } au(0); + + if (vdec.just_started && vdec.just_finished) + { + avcodec_flush_buffers(vdec.ctx); + vdec.just_started = false; + vdec.just_finished = false; + } + else if (vdec.just_started) // deferred initialization + { + err = avformat_open_input(&vdec.fmt, NULL, av_find_input_format("mpeg"), NULL); + if (err) + { + cellVdec->Error("vdecDecodeAu: avformat_open_input() failed"); + Emu.Pause(); + break; + } + AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); // ??? + if (!codec) + { + cellVdec->Error("vdecDecodeAu: avcodec_find_decoder() failed"); + Emu.Pause(); + break; + } + /*err = avformat_find_stream_info(vdec.fmt, NULL); + if (err) + { + LOG_ERROR(HLE, "vdecDecodeAu: avformat_find_stream_info() failed"); + Emu.Pause(); + break; + } + if (!vdec.fmt->nb_streams) + { + LOG_ERROR(HLE, "vdecDecodeAu: no stream found"); + Emu.Pause(); + break; + }*/ + if (!avformat_new_stream(vdec.fmt, codec)) + { + cellVdec->Error("vdecDecodeAu: avformat_new_stream() failed"); + Emu.Pause(); + break; + } + vdec.ctx = vdec.fmt->streams[0]->codec; // TODO: check data + + AVDictionary* opts = nullptr; + av_dict_set(&opts, "refcounted_frames", "1", 0); + { + std::lock_guard lock(g_mutex_avcodec_open2); + // not multithread-safe (???) + err = avcodec_open2(vdec.ctx, codec, &opts); + } + if (err) + { + cellVdec->Error("vdecDecodeAu: avcodec_open2() failed"); + Emu.Pause(); + break; + } + vdec.just_started = false; + } + + bool last_frame = false; + + while (true) + { + if (Emu.IsStopped() || vdec.job.PeekIfExist().type == vdecClose) + { + vdec.is_finished = true; + cellVdec->Warning("vdecDecodeAu: aborted"); + return; + } + + last_frame = av_read_frame(vdec.fmt, &au) < 0; + if (last_frame) + { + //break; + av_free(au.data); + au.data = NULL; + au.size = 0; + } + + struct VdecFrameHolder : VdecFrame + { + VdecFrameHolder() + { + data = av_frame_alloc(); + } + + ~VdecFrameHolder() + { + if (data) + { + av_frame_unref(data); + av_frame_free(&data); + } + } + + } frame; + + if (!frame.data) + { + cellVdec->Error("vdecDecodeAu: av_frame_alloc() failed"); + Emu.Pause(); break; } - vdec.reader.addr = task.addr; - vdec.reader.size = task.size; - //LOG_NOTICE(HLE, "Video AU: size = 0x%x, pts = 0x%llx, dts = 0x%llx", task.size, task.pts, task.dts); + int got_picture = 0; - if (vdec.just_started) + int decode = avcodec_decode_video2(vdec.ctx, frame.data, &got_picture, &au); + + if (decode <= 0) { - vdec.first_pts = task.pts; - vdec.last_pts = task.pts; - vdec.first_dts = task.dts; + if (!last_frame && decode < 0) + { + cellVdec->Error("vdecDecodeAu: AU decoding error(0x%x)", decode); + } + if (!got_picture && vdec.reader.size == 0) break; // video end? } - struct AVPacketHolder : AVPacket + if (got_picture) { - AVPacketHolder(u32 size) + u64 ts = av_frame_get_best_effort_timestamp(frame.data); + if (ts != AV_NOPTS_VALUE) { - av_init_packet(this); - - if (size) - { - data = (u8*)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - this->size = size + FF_INPUT_BUFFER_PADDING_SIZE; - } - else - { - data = NULL; - size = 0; - } + frame.pts = ts/* - vdec.first_pts*/; // ??? + vdec.last_pts = frame.pts; } - - ~AVPacketHolder() + else { - av_free(data); - //av_free_packet(this); + vdec.last_pts += vdec.ctx->time_base.num * 90000 / (vdec.ctx->time_base.den / vdec.ctx->ticks_per_frame); + frame.pts = vdec.last_pts; } + //frame.pts = vdec.last_pts; + //vdec.last_pts += 3754; + frame.dts = (frame.pts - vdec.first_pts) + vdec.first_dts; + frame.userdata = task.userData; - } au(0); + //LOG_NOTICE(HLE, "got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts); - if (vdec.just_started && vdec.just_finished) - { - avcodec_flush_buffers(vdec.ctx); - vdec.just_started = false; - vdec.just_finished = false; + vdec.frames.Push(frame); // !!!!!!!! + frame.data = nullptr; // to prevent destruction + + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); + /*Callback cb; + cb.SetAddr(vdec.cbFunc); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); + cb.Branch(false);*/ } - else if (vdec.just_started) // deferred initialization - { - err = avformat_open_input(&vdec.fmt, NULL, av_find_input_format("mpeg"), NULL); - if (err) - { - LOG_ERROR(HLE, "vdecDecodeAu: avformat_open_input() failed"); - Emu.Pause(); - break; - } - AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); // ??? - if (!codec) - { - LOG_ERROR(HLE, "vdecDecodeAu: avcodec_find_decoder() failed"); - Emu.Pause(); - break; - } - /*err = avformat_find_stream_info(vdec.fmt, NULL); - if (err) - { - LOG_ERROR(HLE, "vdecDecodeAu: avformat_find_stream_info() failed"); - Emu.Pause(); - break; - } - if (!vdec.fmt->nb_streams) - { - LOG_ERROR(HLE, "vdecDecodeAu: no stream found"); - Emu.Pause(); - break; - }*/ - if (!avformat_new_stream(vdec.fmt, codec)) - { - LOG_ERROR(HLE, "vdecDecodeAu: avformat_new_stream() failed"); - Emu.Pause(); - break; - } - vdec.ctx = vdec.fmt->streams[0]->codec; // TODO: check data - - AVDictionary* opts = nullptr; - av_dict_set(&opts, "refcounted_frames", "1", 0); - { - std::lock_guard lock(g_mutex_avcodec_open2); - // not multithread-safe (???) - err = avcodec_open2(vdec.ctx, codec, &opts); - } - if (err) - { - LOG_ERROR(HLE, "vdecDecodeAu: avcodec_open2() failed"); - Emu.Pause(); - break; - } - vdec.just_started = false; - } - - bool last_frame = false; - - while (true) - { - if (Emu.IsStopped() || vdec.job.PeekIfExist().type == vdecClose) - { - vdec.is_finished = true; - LOG_WARNING(HLE, "vdecDecodeAu: aborted"); - return; - } - - last_frame = av_read_frame(vdec.fmt, &au) < 0; - if (last_frame) - { - //break; - av_free(au.data); - au.data = NULL; - au.size = 0; - } - - struct VdecFrameHolder : VdecFrame - { - VdecFrameHolder() - { - data = av_frame_alloc(); - } - - ~VdecFrameHolder() - { - if (data) - { - av_frame_unref(data); - av_frame_free(&data); - } - } - - } frame; - - if (!frame.data) - { - LOG_ERROR(HLE, "vdecDecodeAu: av_frame_alloc() failed"); - Emu.Pause(); - break; - } - - int got_picture = 0; - - int decode = avcodec_decode_video2(vdec.ctx, frame.data, &got_picture, &au); - - if (decode <= 0) - { - if (!last_frame && decode < 0) - { - LOG_ERROR(HLE, "vdecDecodeAu: AU decoding error(0x%x)", decode); - } - if (!got_picture && vdec.reader.size == 0) break; // video end? - } - - if (got_picture) - { - u64 ts = av_frame_get_best_effort_timestamp(frame.data); - if (ts != AV_NOPTS_VALUE) - { - frame.pts = ts/* - vdec.first_pts*/; // ??? - vdec.last_pts = frame.pts; - } - else - { - vdec.last_pts += vdec.ctx->time_base.num * 90000 / (vdec.ctx->time_base.den / vdec.ctx->ticks_per_frame); - frame.pts = vdec.last_pts; - } - //frame.pts = vdec.last_pts; - //vdec.last_pts += 3754; - frame.dts = (frame.pts - vdec.first_pts) + vdec.first_dts; - frame.userdata = task.userData; - - //LOG_NOTICE(HLE, "got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts); - - vdec.frames.Push(frame); // !!!!!!!! - frame.data = nullptr; // to prevent destruction - - vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); - /*Callback cb; - cb.SetAddr(vdec.cbFunc); - cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg); - cb.Branch(false);*/ - } - } - - vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); - /*Callback cb; - cb.SetAddr(vdec.cbFunc); - cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); - cb.Branch(false);*/ } - break; + + vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); + /*Callback cb; + cb.SetAddr(vdec.cbFunc); + cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg); + cb.Branch(false);*/ + } + break; case vdecClose: - { - vdec.is_finished = true; - LOG_NOTICE(HLE, "Video Decoder thread ended"); - return; - } + { + vdec.is_finished = true; + cellVdec->Notice("Video Decoder thread ended"); + return; + } case vdecSetFrameRate: - { - LOG_ERROR(HLE, "TODO: vdecSetFrameRate(%d)", task.frc); - } - break; + { + cellVdec->Error("TODO: vdecSetFrameRate(%d)", task.frc); + } + break; default: - LOG_ERROR(HLE, "Video Decoder thread error: unknown task(%d)", task.type); + cellVdec->Error("Video Decoder thread error: unknown task(%d)", task.type); } } vdec.is_finished = true; - LOG_WARNING(HLE, "Video Decoder thread aborted"); + cellVdec->Warning("Video Decoder thread aborted"); }); t.detach(); @@ -465,7 +528,7 @@ int cellVdecClose(u32 handle) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellVdecClose(%d) aborted", handle); + cellVdec->Warning("cellVdecClose(%d) aborted", handle); break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -516,7 +579,7 @@ int cellVdecEndSeq(u32 handle) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "cellVdecEndSeq(%d) aborted", handle); + cellVdec->Warning("cellVdecEndSeq(%d) aborted", handle); return CELL_OK; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -589,7 +652,7 @@ int cellVdecGetPicture(u32 handle, const mem_ptr_t format, u3 // TODO: zero padding bytes - int err = av_image_copy_to_buffer(Memory + out_addr, buf_size, frame.data, frame.linesize, vdec->ctx->pix_fmt, frame.width, frame.height, 1); + int err = av_image_copy_to_buffer(Memory.GetMemFromAddr(out_addr), buf_size, frame.data, frame.linesize, vdec->ctx->pix_fmt, frame.width, frame.height, 1); if (err < 0) { cellVdec->Error("cellVdecGetPicture: av_image_copy_to_buffer failed(%d)", err); @@ -690,13 +753,13 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr) } else { - LOG_ERROR(HLE, "cellVdecGetPicItem: unsupported time_base.den (%d)", vdec->ctx->time_base.den); + cellVdec->Error("cellVdecGetPicItem: unsupported time_base.den (%d)", vdec->ctx->time_base.den); Emu.Pause(); } } else { - LOG_ERROR(HLE, "cellVdecGetPicItem: unsupported time_base.num (%d)", vdec->ctx->time_base.num); + cellVdec->Error("cellVdecGetPicItem: unsupported time_base.num (%d)", vdec->ctx->time_base.num); Emu.Pause(); } avc->fixed_frame_rate_flag = true; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 5b6a5633d2..10fb65a16e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -727,67 +727,7 @@ public: CPUThread* vdecCb; - VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg) - : type(type) - , profile(profile) - , memAddr(addr) - , memSize(size) - , memBias(0) - , cbFunc(func) - , cbArg(arg) - , is_finished(false) - , is_running(false) - , just_started(false) - , just_finished(false) - , ctx(nullptr) - , vdecCb(nullptr) - { - AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); - if (!codec) - { - LOG_ERROR(HLE, "VideoDecoder(): avcodec_find_decoder(H264) failed"); - Emu.Pause(); - return; - } - fmt = avformat_alloc_context(); - if (!fmt) - { - LOG_ERROR(HLE, "VideoDecoder(): avformat_alloc_context failed"); - Emu.Pause(); - return; - } - io_buf = (u8*)av_malloc(4096); - fmt->pb = avio_alloc_context(io_buf, 4096, 0, this, vdecRead, NULL, NULL); - if (!fmt->pb) - { - LOG_ERROR(HLE, "VideoDecoder(): avio_alloc_context failed"); - Emu.Pause(); - return; - } - } + VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg); - ~VideoDecoder() - { - // TODO: check finalization - if (ctx) - { - for (u32 i = frames.GetCount() - 1; ~i; i--) - { - VdecFrame& vf = frames.Peek(i); - av_frame_unref(vf.data); - av_frame_free(&vf.data); - } - avcodec_close(ctx); - avformat_close_input(&fmt); - } - if (fmt) - { - if (io_buf) - { - av_free(io_buf); - } - if (fmt->pb) av_free(fmt->pb); - avformat_free_context(fmt); - } - } + ~VideoDecoder(); }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp b/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp index 63dc1763d3..1b568231fd 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void cellVoice_init(); Module cellVoice(0x0046, cellVoice_init); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp index ad594ad883..038fb4b891 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" @@ -33,7 +32,7 @@ u32 vpostOpen(VpostInstance* data) { u32 id = cellVpost->GetNewId(data); - LOG_NOTICE(HLE, "*** Vpost instance created (to_rgba=%d): id = %d", data->to_rgba, id); + cellVpost->Notice("*** Vpost instance created (to_rgba=%d): id = %d", data->to_rgba, id); return id; } @@ -90,15 +89,15 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_toutHeight; ctrlParam->inWindow; // ignored - if (ctrlParam->inWindow.x) LOG_WARNING(HLE, "*** inWindow.x = %d", (u32)ctrlParam->inWindow.x); - if (ctrlParam->inWindow.y) LOG_WARNING(HLE, "*** inWindow.y = %d", (u32)ctrlParam->inWindow.y); - if (ctrlParam->inWindow.width != w) LOG_WARNING(HLE, "*** inWindow.width = %d", (u32)ctrlParam->inWindow.width); - if (ctrlParam->inWindow.height != h) LOG_WARNING(HLE, "*** inWindow.height = %d", (u32)ctrlParam->inWindow.height); + if (ctrlParam->inWindow.x) cellVpost->Notice("*** inWindow.x = %d", (u32)ctrlParam->inWindow.x); + if (ctrlParam->inWindow.y) cellVpost->Notice("*** inWindow.y = %d", (u32)ctrlParam->inWindow.y); + if (ctrlParam->inWindow.width != w) cellVpost->Notice("*** inWindow.width = %d", (u32)ctrlParam->inWindow.width); + if (ctrlParam->inWindow.height != h) cellVpost->Notice("*** inWindow.height = %d", (u32)ctrlParam->inWindow.height); ctrlParam->outWindow; // ignored - if (ctrlParam->outWindow.x) LOG_WARNING(HLE, "*** outWindow.x = %d", (u32)ctrlParam->outWindow.x); - if (ctrlParam->outWindow.y) LOG_WARNING(HLE, "*** outWindow.y = %d", (u32)ctrlParam->outWindow.y); - if (ctrlParam->outWindow.width != ow) LOG_WARNING(HLE, "*** outWindow.width = %d", (u32)ctrlParam->outWindow.width); - if (ctrlParam->outWindow.height != oh) LOG_WARNING(HLE, "*** outWindow.height = %d", (u32)ctrlParam->outWindow.height); + if (ctrlParam->outWindow.x) cellVpost->Notice("*** outWindow.x = %d", (u32)ctrlParam->outWindow.x); + if (ctrlParam->outWindow.y) cellVpost->Notice("*** outWindow.y = %d", (u32)ctrlParam->outWindow.y); + if (ctrlParam->outWindow.width != ow) cellVpost->Notice("*** outWindow.width = %d", (u32)ctrlParam->outWindow.width); + if (ctrlParam->outWindow.height != oh) cellVpost->Notice("*** outWindow.height = %d", (u32)ctrlParam->outWindow.height); ctrlParam->execType; // ignored ctrlParam->scalerType; // ignored ctrlParam->ipcType; // ignored @@ -127,16 +126,16 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_treserved1 = 0; picInfo->reserved2 = 0; - u64 stamp0 = get_system_time(); + //u64 stamp0 = get_system_time(); std::unique_ptr pA(new u8[w*h]); memset(pA.get(), (const u8)ctrlParam->outAlpha, w*h); - u64 stamp1 = get_system_time(); + //u64 stamp1 = get_system_time(); SwsContext* sws = sws_getContext(w, h, AV_PIX_FMT_YUVA420P, ow, oh, AV_PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL); - u64 stamp2 = get_system_time(); + //u64 stamp2 = get_system_time(); u8* in_data[4] = { Memory.GetMemFromAddr(inPicBuff_addr), Memory.GetMemFromAddr(inPicBuff_addr + w*h), Memory.GetMemFromAddr(inPicBuff_addr + w*h + w*h / 4), pA.get() }; int in_line[4] = { w, w/2, w/2, w }; @@ -145,7 +144,7 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_t config) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "Surmixer aborted"); + libmixer->Warning("Surmixer aborted"); break; } @@ -349,12 +348,12 @@ int cellSurMixerCreate(const mem_ptr_t config) if (port.m_is_audio_port_started) { - u64 stamp0 = get_system_time(); + //u64 stamp0 = get_system_time(); memset(mixdata, 0, sizeof(mixdata)); if (surMixerCb) mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256); - u64 stamp1 = get_system_time(); + //u64 stamp1 = get_system_time(); { std::lock_guard lock(mixer_mutex); @@ -435,7 +434,7 @@ int cellSurMixerCreate(const mem_ptr_t config) } } - u64 stamp2 = get_system_time(); + //u64 stamp2 = get_system_time(); auto buf = (be_t*)&Memory[m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % port.block) * port.channel * 256 * sizeof(float)]; @@ -445,7 +444,7 @@ int cellSurMixerCreate(const mem_ptr_t config) buf[i] = mixdata[i]; } - u64 stamp3 = get_system_time(); + //u64 stamp3 = get_system_time(); //ConLog.Write("Libmixer perf: start=%lld (cb=%lld, ssp=%lld, finalize=%lld)", stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2); } diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp b/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp index 4e1c84d384..d386b5e709 100644 --- a/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void libsnd3_init(); Module libsnd3("libsnd3", libsnd3_init); diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp b/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp index 340d586e24..5f335b1e58 100644 --- a/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void libsynth2_init(); Module libsynth2("libsynth2", libsynth2_init); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index 253001353c..4135045b0b 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -1,10 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" + #include "Emu/FS/vfsDir.h" #include "Crypto/unedat.h" #include "sceNp.h" diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.h b/rpcs3/Emu/SysCalls/Modules/sceNp.h index f8526e476d..0ac739cab0 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.h @@ -1,5 +1,4 @@ #pragma once - #include "cellRtc.h" // Error Codes diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp index 5a6b204fbf..d0528c0334 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp @@ -1,7 +1,8 @@ #include "stdafx.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "cellRtc.h" +#include "Emu/SysCalls/Modules.h" + #include "sceNp.h" #include "sceNpClans.h" diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp index 2e0777cdfd..c6e29023b0 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" +#include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" -#include "cellRtc.h" + #include "sceNpCommerce2.h" //void sceNpCommerce2_unload(); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h index 3dd26730ef..90e30569d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h @@ -1,4 +1,5 @@ #pragma once +#include "cellRtc.h" // Return codes enum diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index a4f5b9b295..24a5360065 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -1,21 +1,16 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Utilities/rXml.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/FS/vfsDir.h" - -#include "cellRtc.h" -#include "sceNp.h" -#include "sceNpTrophy.h" +#include "rpcs3/Ini.h" +#include "Utilities/rXml.h" #include "Loader/TRP.h" #include "Loader/TROPUSR.h" +#include "Emu/FS/vfsDir.h" #include "Emu/SysCalls/lv2/sys_time.h" - +#include "sceNp.h" +#include "sceNpTrophy.h" #include #include @@ -350,7 +345,7 @@ int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, mem_ptr_tGetTrophiesCount(); if (count.GetValue() > 128) - LOG_WARNING(HLE, "sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!"); + sceNpTrophy->Warning("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!"); // Pack up to 128 bools in u32 flag_bits[4] for (u32 id=0; idWarning("sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); + sysPrxForUser->Warning("_sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); u32 heap_id = sysPrxForUser->GetNewId(new HeapInfo(heap_addr, align, size)); sysPrxForUser->Warning("*** sys_heap created: id = %d", heap_id); return heap_id; } -int sys_heap_malloc(const u32 heap_id, const u32 size) +int _sys_heap_malloc(const u32 heap_id, const u32 size) { - sysPrxForUser->Warning("sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size); + sysPrxForUser->Warning("_sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size); HeapInfo* heap; if(!sysPrxForUser->CheckId(heap_id, heap)) return CELL_ESRCH; @@ -50,15 +57,15 @@ void sys_initialize_tls() sysPrxForUser->Log("sys_initialize_tls()"); } -s64 sys_process_atexitspawn() +s64 _sys_process_atexitspawn() { - sysPrxForUser->Log("sys_process_atexitspawn()"); + sysPrxForUser->Log("_sys_process_atexitspawn()"); return CELL_OK; } -s64 sys_process_at_Exitspawn() +s64 _sys_process_at_Exitspawn() { - sysPrxForUser->Log("sys_process_at_Exitspawn"); + sysPrxForUser->Log("_sys_process_at_Exitspawn"); return CELL_OK; } @@ -70,25 +77,12 @@ int sys_process_is_stack(u32 p) return (int)(bool)(p >= Memory.StackMem.GetStartAddr() && p <= Memory.StackMem.GetEndAddr()); } -int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5) -{ - sysPrxForUser->Warning("sys_spu_printf_initialize(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", a1, a2, a3, a4, a5); - return CELL_OK; -} - s64 sys_prx_exitspawn_with_level() { sysPrxForUser->Log("sys_prx_exitspawn_with_level()"); return CELL_OK; } -s64 sys_strlen(u32 addr) -{ - const std::string& str = Memory.ReadString(addr); - sysPrxForUser->Log("sys_strlen(0x%x - \"%s\")", addr, str.c_str()); - return str.length(); -} - int sys_spu_elf_get_information(u32 elf_img, mem32_t entry, mem32_t nseg) { sysPrxForUser->Warning("sys_spu_elf_get_information(elf_img=0x%x, entry_addr=0x%x, nseg_addr=0x%x", elf_img, entry.GetAddr(), nseg.GetAddr()); @@ -149,35 +143,195 @@ int sys_raw_spu_image_load(int id, mem_ptr_t img) { sysPrxForUser->Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.GetAddr()); - memcpy(Memory + RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, Memory + (u32)img->segs_addr, 256 * 1024); + memcpy(Memory + (RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), Memory + (u32)img->segs_addr, 256 * 1024); Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, (u32)img->entry_point); return CELL_OK; } -s32 _sys_memset(u32 addr, s32 value, u32 size) +u32 _sys_memset(u32 addr, s32 value, u32 size) { sysPrxForUser->Log("_sys_memset(addr=0x%x, value=%d, size=%d)", addr, value, size); memset(Memory + addr, value, size); + return addr; +} + +u32 _sys_memcpy(u32 dest, u32 source, u32 size) +{ + sysPrxForUser->Log("_sys_memcpy(dest=0x%x, source=0x%x, size=%d)", dest, source, size); + + memcpy(Memory + dest, Memory + source, size); + return dest; +} + +s32 _sys_memcmp(u32 addr1, u32 addr2, u32 size) +{ + sysPrxForUser->Log("_sys_memcmp(addr1=0x%x, addr2=0x%x, size=%d)", addr1, addr2, size); + + return memcmp(Memory + addr1, Memory + addr2, size); +} + +s32 _sys_strlen(u32 addr) +{ + sysPrxForUser->Log("_sys_strlen(addr=0x%x)", addr); + + return strlen((char*)(Memory + addr)); +} + +s32 _sys_strncmp(u32 str1, u32 str2, s32 max) +{ + sysPrxForUser->Log("_sys_strncmp(str1=0x%x, str2=0x%x, max=%d)", str1, str2, max); + + return strncmp((char*)(Memory + str1), (char*)(Memory + str2), max); +} + +u32 _sys_strcat(u32 dest, u32 source) +{ + sysPrxForUser->Log("_sys_strcat(dest=0x%x, source=0x%x)", dest, source); + + assert(Memory.RealToVirtualAddr(strcat((char*)(Memory + dest), (char*)(Memory + source))) == dest); + return dest; +} + +u32 _sys_strncat(u32 dest, u32 source, u32 len) +{ + sysPrxForUser->Log("_sys_strncat(dest=0x%x, source=0x%x, len=%d)", dest, source, len); + + assert(Memory.RealToVirtualAddr(strncat((char*)(Memory + dest), (char*)(Memory + source), len)) == dest); + return dest; +} + +u32 _sys_strcpy(u32 dest, u32 source) +{ + sysPrxForUser->Log("_sys_strcpy(dest=0x%x, source=0x%x)", dest, source); + + assert(Memory.RealToVirtualAddr(strcpy((char*)(Memory + dest), (char*)(Memory + source))) == dest); + return dest; +} + +u32 _sys_strncpy(u32 dest, u32 source, u32 len) +{ + sysPrxForUser->Log("_sys_strncpy(dest=0x%x, source=0x%x, len=%d)", dest, source, len); + + if (!dest || !source) + { + return 0; + } + + assert(Memory.RealToVirtualAddr(strncpy((char*)(Memory + dest), (char*)(Memory + source), len)) == dest); + return dest; +} + +u32 spu_printf_agcb; +u32 spu_printf_dgcb; +u32 spu_printf_atcb; +u32 spu_printf_dtcb; + +s32 _sys_spu_printf_initialize(u32 agcb, u32 dgcb, u32 atcb, u32 dtcb) +{ + sysPrxForUser->Warning("_sys_spu_printf_initialize(agcb=0x%x, dgcb=0x%x, atcb=0x%x, dtcb=0x%x)", agcb, dgcb, atcb, dtcb); + + // prx: register some callbacks + spu_printf_agcb = agcb; + spu_printf_dgcb = dgcb; + spu_printf_atcb = atcb; + spu_printf_dtcb = dtcb; return CELL_OK; } +s32 _sys_spu_printf_finalize() +{ + sysPrxForUser->Warning("_sys_spu_printf_finalize()"); + + spu_printf_agcb = 0; + spu_printf_dgcb = 0; + spu_printf_atcb = 0; + spu_printf_dtcb = 0; + return CELL_OK; +} + +s32 _sys_spu_printf_attach_group(u32 arg) +{ + sysPrxForUser->Warning("_sys_spu_printf_attach_group(arg=0x%x)", arg); + + if (!spu_printf_agcb) + { + return CELL_ESTAT; + } + + return GetCurrentPPUThread().FastCall(Memory.Read32(spu_printf_agcb), Memory.Read32(spu_printf_agcb + 4), arg); +} + +s32 _sys_spu_printf_detach_group(u32 arg) +{ + sysPrxForUser->Warning("_sys_spu_printf_detach_group(arg=0x%x)", arg); + + if (!spu_printf_dgcb) + { + return CELL_ESTAT; + } + + return GetCurrentPPUThread().FastCall(Memory.Read32(spu_printf_dgcb), Memory.Read32(spu_printf_dgcb + 4), arg); +} + +s32 _sys_spu_printf_attach_thread(u32 arg) +{ + sysPrxForUser->Warning("_sys_spu_printf_attach_thread(arg=0x%x)", arg); + + if (!spu_printf_atcb) + { + return CELL_ESTAT; + } + + return GetCurrentPPUThread().FastCall(Memory.Read32(spu_printf_atcb), Memory.Read32(spu_printf_atcb + 4), arg); +} + +s32 _sys_spu_printf_detach_thread(u32 arg) +{ + sysPrxForUser->Warning("_sys_spu_printf_detach_thread(arg=0x%x)", arg); + + if (!spu_printf_dtcb) + { + return CELL_ESTAT; + } + + return GetCurrentPPUThread().FastCall(Memory.Read32(spu_printf_dtcb), Memory.Read32(spu_printf_dtcb + 4), arg); +} + +s32 _sys_printf(u32 arg1) +{ + sysPrxForUser->Todo("_sys_printf(arg1=0x%x)", arg1); + + // probably, assertion failed + sysPrxForUser->Warning("_sys_printf: \n%s", (char*)(Memory + arg1)); + return CELL_OK; +} + +s32 _unnamed_E75C40F2(u32 dest) +{ + sysPrxForUser->Todo("Unnamed function 0xE75C40F2 (dest=0x%x) -> CELL_ENOENT", dest); + + // prx: load some data (0x40 bytes) previously set by sys_process_get_paramsfo + //memset(Memory + dest, 0, 0x40); + return CELL_ENOENT; +} + void sysPrxForUser_init() { - sysPrxForUser->AddFunc(0x744680a2, sys_initialize_tls); + REG_FUNC(sysPrxForUser, sys_initialize_tls); - sysPrxForUser->AddFunc(0x2f85c0ef, sys_lwmutex_create); - sysPrxForUser->AddFunc(0xc3476d0c, sys_lwmutex_destroy); - sysPrxForUser->AddFunc(0x1573dc3f, sys_lwmutex_lock); - sysPrxForUser->AddFunc(0xaeb78725, sys_lwmutex_trylock); - sysPrxForUser->AddFunc(0x1bc200f4, sys_lwmutex_unlock); + REG_FUNC(sysPrxForUser, sys_lwmutex_create); + REG_FUNC(sysPrxForUser, sys_lwmutex_destroy); + REG_FUNC(sysPrxForUser, sys_lwmutex_lock); + REG_FUNC(sysPrxForUser, sys_lwmutex_trylock); + REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); sysPrxForUser->AddFunc(0x8461e528, sys_time_get_system_time); sysPrxForUser->AddFunc(0xe6f2c1e7, sys_process_exit); - sysPrxForUser->AddFunc(0x2c847572, sys_process_atexitspawn); - sysPrxForUser->AddFunc(0x96328741, sys_process_at_Exitspawn); + sysPrxForUser->AddFunc(0x2c847572, _sys_process_atexitspawn); + sysPrxForUser->AddFunc(0x96328741, _sys_process_at_Exitspawn); sysPrxForUser->AddFunc(0x4f7172c9, sys_process_is_stack); sysPrxForUser->AddFunc(0x24a1ea07, sys_ppu_thread_create); @@ -185,8 +339,6 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0xaff080a4, sys_ppu_thread_exit); sysPrxForUser->AddFunc(0xa3e3be68, sys_ppu_thread_once); - sysPrxForUser->AddFunc(0x45fe2fce, sys_spu_printf_initialize); - sysPrxForUser->AddFunc(0x26090058, sys_prx_load_module); sysPrxForUser->AddFunc(0x9f18429d, sys_prx_start_module); sysPrxForUser->AddFunc(0x80fb0c19, sys_prx_stop_module); @@ -199,12 +351,10 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0xaa6d9bff, sys_prx_load_module_on_memcontainer); sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); - sysPrxForUser->AddFunc(0x2d36462b, sys_strlen); - - sysPrxForUser->AddFunc(0x35168520, sys_heap_malloc); - //sysPrxForUser->AddFunc(0xaede4b03, sys_heap_free); - //sysPrxForUser->AddFunc(0x8a561d92, sys_heap_delete_heap); - sysPrxForUser->AddFunc(0xb2fcf2c8, sys_heap_create_heap); + sysPrxForUser->AddFunc(0x35168520, _sys_heap_malloc); + //sysPrxForUser->AddFunc(0xaede4b03, _sys_heap_free); + //sysPrxForUser->AddFunc(0x8a561d92, _sys_heap_delete_heap); + sysPrxForUser->AddFunc(0xb2fcf2c8, _sys_heap_create_heap); sysPrxForUser->AddFunc(0x44265c08, _sys_heap_memalign); sysPrxForUser->AddFunc(0xb257540b, sys_mmapper_allocate_memory); @@ -236,5 +386,28 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0x67f9fedb, sys_game_process_exitspawn2); sysPrxForUser->AddFunc(0xfc52a7a9, sys_game_process_exitspawn); - sysPrxForUser->AddFunc(0x68b9b011, _sys_memset); + REG_FUNC(sysPrxForUser, _sys_memset); + REG_FUNC(sysPrxForUser, _sys_memcpy); + REG_FUNC(sysPrxForUser, _sys_memcmp); + REG_FUNC(sysPrxForUser, _sys_strlen); + REG_FUNC(sysPrxForUser, _sys_strncmp); + REG_FUNC(sysPrxForUser, _sys_strcat); + REG_FUNC(sysPrxForUser, _sys_strncat); + REG_FUNC(sysPrxForUser, _sys_strcpy); + REG_FUNC(sysPrxForUser, _sys_strncpy); + sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown + + spu_printf_agcb = 0; + spu_printf_dgcb = 0; + spu_printf_atcb = 0; + spu_printf_dtcb = 0; + + REG_FUNC(sysPrxForUser, _sys_spu_printf_initialize); + REG_FUNC(sysPrxForUser, _sys_spu_printf_finalize); + REG_FUNC(sysPrxForUser, _sys_spu_printf_attach_group); + REG_FUNC(sysPrxForUser, _sys_spu_printf_detach_group); + REG_FUNC(sysPrxForUser, _sys_spu_printf_attach_thread); + REG_FUNC(sysPrxForUser, _sys_spu_printf_detach_thread); + + REG_FUNC(sysPrxForUser, _sys_printf); } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h index d32efb69c5..3dc3697ce9 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h @@ -13,6 +13,3 @@ struct HeapInfo { } }; - -// SysCalls -s32 _sys_memset(u32 addr, s32 value, u32 num); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 032da5f98f..b99a75b804 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -1,11 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/lv2/lv2Fs.h" + Module *sys_fs = nullptr; bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) @@ -155,7 +154,7 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_tWarning("fsAioRead() aborted"); return; } } @@ -186,9 +185,8 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_toffset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str()); + sys_fs->Log("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])", + fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str()); if (func) // start callback thread { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_http.cpp b/rpcs3/Emu/SysCalls/Modules/sys_http.cpp index e28671989a..b96bbebafa 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_http.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_http.cpp @@ -1,7 +1,5 @@ #include "stdafx.h" #if 0 -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" void sys_http_init(); Module sys_http(0x0001, sys_http_init); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index 60cd11c39b..1eca9381a1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -1,9 +1,5 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" //void sys_io_init(); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 7885312aae..40332c7240 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -1,13 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" -#include "sys_net.h" - #ifdef _WIN32 #include #else @@ -20,6 +14,8 @@ extern "C" } #endif +#include "sys_net.h" + //void sys_net_init(); //Module sys_net((u16)0x0000, sys_net_init); Module *sys_net = nullptr; diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 6b9fde794a..7e3ecc41ad 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -1,10 +1,7 @@ #pragma once - -#include "Emu/Memory/Memory.h" #include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SysCalls.h" -#define RESULT(x) SC_ARGS_1 = (x) +#define RESULT(x) CPU.GPR[3] = (x) class func_caller { @@ -25,7 +22,8 @@ struct get_arg // not fp, not ptr, 1..8 template struct get_arg // ptr, 1..8 { - static __forceinline T func(PPUThread& CPU) { return CPU.GPR[i + 2] ? (T)&Memory[CPU.GPR[i + 2]] : nullptr; } + static_assert(i == 0, "Invalid function argument type: pointer"); + static __forceinline T func(PPUThread& CPU) { return nullptr; } }; template @@ -37,13 +35,14 @@ struct get_arg // fp, 1..12 template struct get_arg // not fp, not ptr, 9..12 { - static __forceinline T func(PPUThread& CPU) { u64 res = Memory.Read64(CPU.GPR[1] + 0x70 + 0x8 * (i - 9)); return (T&)res; } + static __forceinline T func(PPUThread& CPU) { u64 res = CPU.GetStackArg(i); return (T&)res; } }; template struct get_arg // ptr, 9..12 { - static __forceinline T func(PPUThread& CPU) { u64 addr = Memory.Read64(CPU.GPR[1] + 0x70 + 0x8 * (i - 9)); return addr ? (T)&Memory[addr] : nullptr; } + static_assert(i == 0, "Invalid function argument type: pointer"); + static __forceinline T func(PPUThread& CPU) { return nullptr; } }; #define ARG(n) get_arg<((n) > 8), std::is_floating_point::value, std::is_pointer::value, T##n, n>::func(CPU) diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index 7a0bf9f784..866f50fe6e 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -1,9 +1,6 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" #include "Emu/SysCalls/Modules.h" #include "Static.h" diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 839c5cc3ec..54ce826b74 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -1,12 +1,36 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Utilities/AutoPause.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/Modules.h" #include "ModuleManager.h" +#include "lv2/lv2Fs.h" +#include "lv2/sys_cond.h" +#include "lv2/sys_event.h" +#include "lv2/sys_event_flag.h" +#include "lv2/sys_interrupt.h" +#include "lv2/sys_lwcond.h" +#include "lv2/sys_lwmutex.h" +#include "lv2/sys_memory.h" +#include "lv2/sys_mmapper.h" +#include "lv2/sys_ppu_thread.h" +#include "lv2/sys_process.h" +#include "lv2/sys_prx.h" +#include "lv2/sys_rsx.h" +#include "lv2/sys_rwlock.h" +#include "lv2/sys_semaphore.h" +#include "lv2/sys_spinlock.h" +#include "lv2/sys_spu.h" +#include "lv2/sys_time.h" +#include "lv2/sys_timer.h" +#include "lv2/sys_trace.h" +#include "lv2/sys_tty.h" +#include "lv2/sys_vm.h" + +#include "SysCalls.h" + namespace detail{ template<> bool CheckId(u32 id, ID*& _id,const std::string &name) { @@ -19,6 +43,8 @@ static func_caller *null_func = bind_func(default_syscall); static const int kSyscallTableLength = 1024; +extern int cellGcmCallback(u32 context_addr, u32 count); + // UNS = Unused // ROOT = Root // DBG = Debug @@ -45,7 +71,7 @@ static func_caller* sc_table[kSyscallTableLength] = bind_func(sys_process_kill), //19 (0x013) null_func, //20 (0x014) UNS null_func,//bind_func(_sys_process_spawn), //21 (0x015) DBG - bind_func(sys_process_exit), //22 (0x016) + null_func,//bind_func(sys_process_exit), //22 (0x016) bind_func(sys_process_wait_for_child2), //23 (0x017) DBG null_func,//bind_func(), //24 (0x018) DBG bind_func(sys_process_get_sdk_version), //25 (0x019) @@ -939,3 +965,13 @@ void SysCalls::DoSyscall(u32 code) declCPU(); RESULT(0); } + +IdManager& SysCallBase::GetIdManager() const +{ + return Emu.GetIdManager(); +} + +bool SysCallBase::RemoveId(u32 id) +{ + return Emu.GetIdManager().RemoveID(id); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index e7b20635b4..c96cbfcfb7 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -1,40 +1,9 @@ #pragma once #include "ErrorCodes.h" -#include "Static.h" - -#include "Emu/Memory/Memory.h" - -// Most of the headers below rely on Memory.h -#include "lv2/lv2Fs.h" -#include "lv2/sys_cond.h" -#include "lv2/sys_event.h" -#include "lv2/sys_event_flag.h" -#include "lv2/sys_interrupt.h" -#include "lv2/sys_lwcond.h" -#include "lv2/sys_lwmutex.h" -#include "lv2/sys_memory.h" -#include "lv2/sys_mmapper.h" -#include "lv2/sys_ppu_thread.h" -#include "lv2/sys_process.h" -#include "lv2/sys_prx.h" -#include "lv2/sys_rsx.h" -#include "lv2/sys_rwlock.h" -#include "lv2/sys_semaphore.h" -#include "lv2/sys_spinlock.h" -#include "lv2/sys_spu.h" -#include "lv2/sys_time.h" -#include "lv2/sys_timer.h" -#include "lv2/sys_trace.h" -#include "lv2/sys_tty.h" -#include "lv2/sys_vm.h" - -#include "rpcs3/Ini.h" #include "LogBase.h" //#define SYSCALLS_DEBUG -#define declCPU PPUThread& CPU = GetCurrentPPUThread - class SysCallBase; namespace detail{ @@ -54,6 +23,7 @@ class SysCallBase : public LogBase private: std::string m_module_name; //u32 m_id; + IdManager& GetIdManager() const; public: SysCallBase(const std::string& name/*, u32 id*/) @@ -69,7 +39,7 @@ public: bool CheckId(u32 id) const { - return Emu.GetIdManager().CheckID(id) && Emu.GetIdManager().GetID(id).m_name == GetName(); + return GetIdManager().CheckID(id) && GetIdManager().GetID(id).m_name == GetName(); } template bool CheckId(u32 id, T*& data) @@ -80,46 +50,12 @@ public: template u32 GetNewId(T* data, IDType type = TYPE_OTHER) { - return Emu.GetIdManager().GetNewID(GetName(), data, type); + return GetIdManager().GetNewID(GetName(), data, type); } + + bool RemoveId(u32 id); }; -//cellGcm (used as lv2 syscall #1023) -extern int cellGcmCallback(u32 context_addr, u32 count); - - -#define UNIMPLEMENTED_FUNC(module) module->Todo("%s", __FUNCTION__) - -#define SC_ARG_0 CPU.GPR[3] -#define SC_ARG_1 CPU.GPR[4] -#define SC_ARG_2 CPU.GPR[5] -#define SC_ARG_3 CPU.GPR[6] -#define SC_ARG_4 CPU.GPR[7] -#define SC_ARG_5 CPU.GPR[8] -#define SC_ARG_6 CPU.GPR[9] -#define SC_ARG_7 CPU.GPR[10] -/* // these definitions are wrong: -#define SC_ARG_8 CPU.GPR[11] -#define SC_ARG_9 CPU.GPR[12] -#define SC_ARG_10 CPU.GPR[13] -#define SC_ARG_11 CPU.GPR[14] -*/ - -#define SC_ARGS_1 SC_ARG_0 -#define SC_ARGS_2 SC_ARGS_1,SC_ARG_1 -#define SC_ARGS_3 SC_ARGS_2,SC_ARG_2 -#define SC_ARGS_4 SC_ARGS_3,SC_ARG_3 -#define SC_ARGS_5 SC_ARGS_4,SC_ARG_4 -#define SC_ARGS_6 SC_ARGS_5,SC_ARG_5 -#define SC_ARGS_7 SC_ARGS_6,SC_ARG_6 -#define SC_ARGS_8 SC_ARGS_7,SC_ARG_7 -/* -#define SC_ARGS_9 SC_ARGS_8,SC_ARG_8 -#define SC_ARGS_10 SC_ARGS_9,SC_ARG_9 -#define SC_ARGS_11 SC_ARGS_10,SC_ARG_10 -#define SC_ARGS_12 SC_ARGS_11,SC_ARG_11 -*/ - extern bool dump_enable; class SysCalls @@ -128,7 +64,3 @@ public: static void DoSyscall(u32 code); static std::string GetHLEFuncName(const u32 fid); }; - -#define REG_SUB(module, group, name, ...) \ - static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \ - module->AddFuncSub(group, name ## _table, #name, name) diff --git a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp b/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp index 76ab51955f..15f1ee826d 100644 --- a/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/lv2Fs.cpp @@ -1,15 +1,12 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" +//#include "Emu/SysCalls/SysCalls.h" + #include "Emu/SysCalls/Modules.h" #include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsDir.h" - #include "lv2Fs.h" -#include "Emu/SysCalls/SysCalls.h" extern Module *sys_fs; @@ -112,7 +109,7 @@ s32 cellFsOpen(u32 path_addr, s32 flags, mem32_t fd, mem32_t arg, u64 size) } fd = sys_fs->GetNewId(stream, TYPE_FS_FILE); - LOG_NOTICE(HLE, "\"%s\" opened: fd = %d", path.c_str(), fd.GetValue()); + sys_fs->Notice("\"%s\" opened: fd = %d", path.c_str(), fd.GetValue()); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index e169fcc740..8a99ac7f25 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -1,10 +1,9 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" - #include "Emu/SysCalls/SysCalls.h" + +#include "Emu/Cell/PPUThread.h" #include "sys_cond.h" SysCallBase sys_cond("sys_cond"); @@ -74,13 +73,13 @@ s32 sys_cond_signal(u32 cond_id) if (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { - cond->signal_stamp = get_system_time(); + //cond->signal_stamp = get_system_time(); cond->signal.lock(target); Emu.GetCPU().NotifyThread(target); if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_cond_signal(id=%d) aborted", cond_id); + sys_cond.Warning("sys_cond_signal(id=%d) aborted", cond_id); } } @@ -102,13 +101,13 @@ s32 sys_cond_signal_all(u32 cond_id) while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { cond->signaler = GetCurrentCPUThread()->GetId(); - cond->signal_stamp = get_system_time(); + //cond->signal_stamp = get_system_time(); cond->signal.lock(target); Emu.GetCPU().NotifyThread(target); if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_cond_signal_all(id=%d) aborted", cond_id); + sys_cond.Warning("sys_cond_signal_all(id=%d) aborted", cond_id); break; } } @@ -141,14 +140,14 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) u32 target = thread_id; { - cond->signal_stamp = get_system_time(); + //cond->signal_stamp = get_system_time(); cond->signal.lock(target); Emu.GetCPU().NotifyThread(target); } if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_cond_signal_to(id=%d, to=%d) aborted", cond_id, thread_id); + sys_cond.Warning("sys_cond_signal_to(id=%d, to=%d) aborted", cond_id, thread_id); } return CELL_OK; @@ -189,7 +188,7 @@ s32 sys_cond_wait(u32 cond_id, u64 timeout) { if (cond->signal.unlock(tid, tid) == SMR_OK) { - const u64 stamp2 = get_system_time(); + //const u64 stamp2 = get_system_time(); if (SMutexResult res = mutex->m_mutex.trylock(tid)) { if (res != SMR_FAILED) @@ -231,6 +230,6 @@ s32 sys_cond_wait(u32 cond_id, u64 timeout) } abort: - LOG_WARNING(HLE, "sys_cond_wait(id=%d) aborted", cond_id); + sys_cond.Warning("sys_cond_wait(id=%d) aborted", cond_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index bf4b722388..953538decd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" - #include "Emu/SysCalls/SysCalls.h" -#include "Emu/Cell/SPUThread.h" +#include "Emu/Cell/PPUThread.h" +#include "Emu/Event.h" +#include "sys_process.h" #include "sys_event.h" SysCallBase sys_event("sys_event"); @@ -90,7 +89,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, int mode) std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_event_queue_destroy(equeue=%d) aborted", equeue_id); + sys_event.Warning("sys_event_queue_destroy(equeue=%d) aborted", equeue_id); break; } } @@ -203,7 +202,7 @@ s32 sys_event_queue_receive(u32 equeue_id, mem_ptr_t event, u64 std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (counter++ > timeout || Emu.IsStopped()) { - if (Emu.IsStopped()) LOG_WARNING(HLE, "sys_event_queue_receive(equeue=%d) aborted", equeue_id); + if (Emu.IsStopped()) sys_event.Warning("sys_event_queue_receive(equeue=%d) aborted", equeue_id); eq->sq.invalidate(tid); return CELL_ETIMEDOUT; } @@ -238,7 +237,7 @@ s32 sys_event_port_create(mem32_t eport_id, int port_type, u64 name) EventPort* eport = new EventPort(); u32 id = sys_event.GetNewId(eport, TYPE_EVENT_PORT); - eport->name = name ? name : ((u64)sys_process_getpid() << 32) | (u64)id; + eport->name = name ? name : ((u64)process_getpid() << 32) | (u64)id; eport_id = id; sys_event.Warning("*** sys_event_port created: id = %d", id); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index 8a2b1374e5..2e5a0e479f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -1,15 +1,42 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" - #include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/PPUThread.h" +#include "sys_lwmutex.h" #include "sys_event_flag.h" SysCallBase sys_event_flag("sys_event_flag"); +u32 EventFlag::check() +{ + SleepQueue sq; // TODO: implement without SleepQueue + + u32 target = 0; + + for (u32 i = 0; i < waiters.size(); i++) + { + if (((waiters[i].mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & waiters[i].bitptn) == waiters[i].bitptn) || + ((waiters[i].mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & waiters[i].bitptn))) + { + if (m_protocol == SYS_SYNC_FIFO) + { + target = waiters[i].tid; + break; + } + sq.list.push_back(waiters[i].tid); + } + } + + if (m_protocol == SYS_SYNC_PRIORITY) + { + target = sq.pop_prio(); + } + + return target; +} + s32 sys_event_flag_create(mem32_t eflag_id, mem_ptr_t attr, u64 init) { sys_event_flag.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)", @@ -36,7 +63,7 @@ s32 sys_event_flag_create(mem32_t eflag_id, mem_ptr_t attr, default: return CELL_EINVAL; } - eflag_id = sys_event_flag.GetNewId(new EventFlag(init, (u32)attr->protocol, (int)attr->type)); + eflag_id = sys_event_flag.GetNewId(new EventFlag(init, (u32)attr->protocol, (int)attr->type), TYPE_EVENT_FLAG); sys_event_flag.Warning("*** event_flag created [%s] (protocol=0x%x, type=0x%x): id = %d", std::string(attr->name, 8).c_str(), (u32)attr->protocol, (int)attr->type, eflag_id.GetValue()); @@ -187,7 +214,7 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 } if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_event_flag_wait(id=%d) aborted", eflag_id); + sys_event_flag.Warning("sys_event_flag_wait(id=%d) aborted", eflag_id); return CELL_OK; } } @@ -306,7 +333,7 @@ s32 sys_event_flag_cancel(u32 eflag_id, mem32_t num) if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_event_flag_cancel(id=%d) aborted", eflag_id); + sys_event_flag.Warning("sys_event_flag_cancel(id=%d) aborted", eflag_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h index 48901ba572..f31b04a57f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h @@ -1,5 +1,7 @@ #pragma once +#include "Utilities/SMutex.h" + enum { SYS_SYNC_WAITER_SINGLE = 0x10000, @@ -45,33 +47,7 @@ struct EventFlag { } - u32 check() - { - SleepQueue sq; // TODO: implement without SleepQueue - - u32 target = 0; - - for (u32 i = 0; i < waiters.size(); i++) - { - if (((waiters[i].mode & SYS_EVENT_FLAG_WAIT_AND) && (flags & waiters[i].bitptn) == waiters[i].bitptn) || - ((waiters[i].mode & SYS_EVENT_FLAG_WAIT_OR) && (flags & waiters[i].bitptn))) - { - if (m_protocol == SYS_SYNC_FIFO) - { - target = waiters[i].tid; - break; - } - sq.list.push_back(waiters[i].tid); - } - } - - if (m_protocol == SYS_SYNC_PRIORITY) - { - target = sq.pop_prio(); - } - - return target; - } + u32 check(); }; s32 sys_event_flag_create(mem32_t eflag_id, mem_ptr_t attr, u64 init); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index 36f5839975..5ab4e2caac 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -1,18 +1,17 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/SysCalls/SysCalls.h" + #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/RawSPUThread.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" #include "sys_interrupt.h" -static SysCallBase sc_int("sys_interrupt"); +static SysCallBase sys_interrupt("sys_interrupt"); s32 sys_interrupt_tag_destroy(u32 intrtag) { - sc_int.Warning("sys_interrupt_tag_destroy(intrtag=%d)", intrtag); + sys_interrupt.Warning("sys_interrupt_tag_destroy(intrtag=%d)", intrtag); u32 id = intrtag & 0xff; u32 class_id = intrtag >> 8; @@ -39,7 +38,7 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) s32 sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 arg) { - sc_int.Warning("sys_interrupt_thread_establish(ih_addr=0x%x, intrtag=%d, intrthread=%lld, arg=0x%llx)", ih.GetAddr(), intrtag, intrthread, arg); + sys_interrupt.Warning("sys_interrupt_thread_establish(ih_addr=0x%x, intrtag=%d, intrthread=%lld, arg=0x%llx)", ih.GetAddr(), intrtag, intrthread, arg); u32 id = intrtag & 0xff; u32 class_id = intrtag >> 8; @@ -78,7 +77,7 @@ s32 sys_interrupt_thread_establish(mem32_t ih, u32 intrtag, u64 intrthread, u64 s32 sys_interrupt_thread_disestablish(u32 ih) { - sc_int.Todo("sys_interrupt_thread_disestablish(ih=%d)", ih); + sys_interrupt.Todo("sys_interrupt_thread_disestablish(ih=%d)", ih); CPUThread* it = Emu.GetCPU().GetThread(ih); if (!it) @@ -98,8 +97,8 @@ s32 sys_interrupt_thread_disestablish(u32 ih) void sys_interrupt_thread_eoi() { - sc_int.Log("sys_interrupt_thread_eoi()"); + sys_interrupt.Log("sys_interrupt_thread_eoi()"); - GetCurrentPPUThread().Stop(); + GetCurrentPPUThread().FastStop(); return; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index 57943453bb..4e368f9ed7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -1,9 +1,9 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/SysCalls.h" + +#include "Emu/Cell/PPUThread.h" #include "sys_lwmutex.h" #include "sys_lwcond.h" @@ -63,7 +63,7 @@ s32 sys_lwcond_signal(mem_ptr_t lwcond) if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_lwcond_signal(id=%d) aborted", (u32)lwcond->lwcond_queue); + sys_lwcond.Warning("sys_lwcond_signal(id=%d) aborted", (u32)lwcond->lwcond_queue); return CELL_OK; } } @@ -89,7 +89,7 @@ s32 sys_lwcond_signal_all(mem_ptr_t lwcond) if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_lwcond_signal_all(id=%d) aborted", (u32)lwcond->lwcond_queue); + sys_lwcond.Warning("sys_lwcond_signal_all(id=%d) aborted", (u32)lwcond->lwcond_queue); return CELL_OK; } } @@ -123,7 +123,7 @@ s32 sys_lwcond_signal_to(mem_ptr_t lwcond, u32 ppu_thread_id) if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_lwcond_signal_to(id=%d, to=%d) aborted", (u32)lwcond->lwcond_queue, ppu_thread_id); + sys_lwcond.Warning("sys_lwcond_signal_to(id=%d, to=%d) aborted", (u32)lwcond->lwcond_queue, ppu_thread_id); return CELL_OK; } } @@ -213,6 +213,6 @@ s32 sys_lwcond_wait(mem_ptr_t lwcond, u64 timeout) } abort: - LOG_WARNING(HLE, "sys_lwcond_wait(id=%d) aborted", (u32)lwcond->lwcond_queue); + sys_lwcond.Warning("sys_lwcond_wait(id=%d) aborted", (u32)lwcond->lwcond_queue); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp index 267b68a0d0..61fb1141c5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp @@ -1,32 +1,34 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/SysCalls.h" + +#include "Emu/Cell/PPUThread.h" #include "sys_lwmutex.h" -SysCallBase sc_lwmutex("sys_lwmutex"); +SysCallBase sys_lwmutex("sys_lwmutex"); + +// TODO: move SleepQueue somewhere s32 sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_t attr) { - sc_lwmutex.Log("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", + sys_lwmutex.Log("sys_lwmutex_create(lwmutex_addr=0x%x, lwmutex_attr_addr=0x%x)", lwmutex.GetAddr(), attr.GetAddr()); switch (attr->attr_recursive.ToBE()) { case se32(SYS_SYNC_RECURSIVE): break; case se32(SYS_SYNC_NOT_RECURSIVE): break; - default: sc_lwmutex.Error("Unknown recursive attribute(0x%x)", (u32)attr->attr_recursive); return CELL_EINVAL; + default: sys_lwmutex.Error("Unknown recursive attribute(0x%x)", (u32)attr->attr_recursive); return CELL_EINVAL; } switch (attr->attr_protocol.ToBE()) { case se32(SYS_SYNC_PRIORITY): break; case se32(SYS_SYNC_RETRY): break; - case se32(SYS_SYNC_PRIORITY_INHERIT): sc_lwmutex.Error("Invalid SYS_SYNC_PRIORITY_INHERIT protocol attr"); return CELL_EINVAL; + case se32(SYS_SYNC_PRIORITY_INHERIT): sys_lwmutex.Error("Invalid SYS_SYNC_PRIORITY_INHERIT protocol attr"); return CELL_EINVAL; case se32(SYS_SYNC_FIFO): break; - default: sc_lwmutex.Error("Unknown protocol attribute(0x%x)", (u32)attr->attr_protocol); return CELL_EINVAL; + default: sys_lwmutex.Error("Unknown protocol attribute(0x%x)", (u32)attr->attr_protocol); return CELL_EINVAL; } lwmutex->attribute = attr->attr_protocol | attr->attr_recursive; @@ -36,10 +38,10 @@ s32 sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_tpad = 0; lwmutex->recursive_count = 0; - u32 sq_id = sc_lwmutex.GetNewId(new SleepQueue(attr->name_u64), TYPE_LWMUTEX); + u32 sq_id = sys_lwmutex.GetNewId(new SleepQueue(attr->name_u64), TYPE_LWMUTEX); lwmutex->sleep_queue = sq_id; - sc_lwmutex.Warning("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", + sys_lwmutex.Warning("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", std::string(attr->name, 8).c_str(), (u32) lwmutex->attribute, sq_id); return CELL_OK; @@ -47,7 +49,7 @@ s32 sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_t lwmutex) { - sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr()); + sys_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr=0x%x)", lwmutex.GetAddr()); u32 sq_id = lwmutex->sleep_queue; if (!Emu.GetIdManager().CheckID(sq_id)) return CELL_ESRCH; @@ -66,7 +68,7 @@ s32 sys_lwmutex_destroy(mem_ptr_t lwmutex) s32 sys_lwmutex_lock(mem_ptr_t lwmutex, u64 timeout) { - sc_lwmutex.Log("sys_lwmutex_lock(lwmutex_addr=0x%x, timeout=%lld)", lwmutex.GetAddr(), timeout); + sys_lwmutex.Log("sys_lwmutex_lock(lwmutex_addr=0x%x, timeout=%lld)", lwmutex.GetAddr(), timeout); //ConLog.Write("*** lock mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)", //lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, lwmutex->vars.parts.owner.GetOwner(), (u32)lwmutex->waiter); @@ -76,14 +78,14 @@ s32 sys_lwmutex_lock(mem_ptr_t lwmutex, u64 timeout) s32 sys_lwmutex_trylock(mem_ptr_t lwmutex) { - sc_lwmutex.Log("sys_lwmutex_trylock(lwmutex_addr=0x%x)", lwmutex.GetAddr()); + sys_lwmutex.Log("sys_lwmutex_trylock(lwmutex_addr=0x%x)", lwmutex.GetAddr()); return lwmutex->trylock(be_t::MakeFromLE(GetCurrentPPUThread().GetId())); } s32 sys_lwmutex_unlock(mem_ptr_t lwmutex) { - sc_lwmutex.Log("sys_lwmutex_unlock(lwmutex_addr=0x%x)", lwmutex.GetAddr()); + sys_lwmutex.Log("sys_lwmutex_unlock(lwmutex_addr=0x%x)", lwmutex.GetAddr()); //ConLog.Write("*** unlocking mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)", //lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, (u32)lwmutex->vars.parts.owner.GetOwner(), (u32)lwmutex->waiter); @@ -158,7 +160,7 @@ u32 SleepQueue::pop_prio() // SYS_SYNC_PRIORITY u32 SleepQueue::pop_prio_inherit() // (TODO) { - LOG_ERROR(HLE, "TODO: SleepQueue::pop_prio_inherit()"); + sys_lwmutex.Error("TODO: SleepQueue::pop_prio_inherit()"); Emu.Pause(); return 0; } @@ -278,7 +280,7 @@ int sys_lwmutex_t::unlock(be_t tid) { if (!recursive_count || (recursive_count.ToBE() != se32(1) && (attribute.ToBE() & se32(SYS_SYNC_NOT_RECURSIVE)))) { - sc_lwmutex.Error("sys_lwmutex_t::unlock(%d): wrong recursive value fixed (%d)", (u32)sleep_queue, (u32)recursive_count); + sys_lwmutex.Error("sys_lwmutex_t::unlock(%d): wrong recursive value fixed (%d)", (u32)sleep_queue, (u32)recursive_count); recursive_count = 1; } recursive_count -= 1; @@ -329,7 +331,7 @@ int sys_lwmutex_t::lock(be_t tid, u64 timeout) case SMR_TIMEOUT: sq->invalidate(tid); return CELL_ETIMEDOUT; case SMR_ABORT: - if (Emu.IsStopped()) LOG_WARNING(HLE, "sys_lwmutex_t::lock(sq=%d) aborted", (u32)sleep_queue); + if (Emu.IsStopped()) sys_lwmutex.Warning("sys_lwmutex_t::lock(sq=%d) aborted", (u32)sleep_queue); default: sq->invalidate(tid); return CELL_EINVAL; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp index 936b5ff0ac..082f933bdc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp @@ -1,16 +1,15 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_memory.h" #include -SysCallBase sc_mem("memory"); +SysCallBase sys_memory("sys_memory"); s32 sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr) { - sc_mem.Log("sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags); + sys_memory.Log("sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags); // Check page size. u32 addr; @@ -33,7 +32,7 @@ s32 sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr) return CELL_ENOMEM; // Write back the start address of the allocated area. - sc_mem.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", addr, size); + sys_memory.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", addr, size); Memory.Write32(alloc_addr_addr, addr); return CELL_OK; @@ -41,11 +40,11 @@ s32 sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr) s32 sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_addr_addr) { - sc_mem.Log("sys_memory_allocate_from_container(size=0x%x, cid=0x%x, flags=0x%x)", size, cid, flags); + sys_memory.Log("sys_memory_allocate_from_container(size=0x%x, cid=0x%x, flags=0x%x)", size, cid, flags); // Check if this container ID is valid. MemoryContainerInfo* ct; - if(!sc_mem.CheckId(cid, ct)) + if (!sys_memory.CheckId(cid, ct)) return CELL_ESRCH; // Check page size. @@ -70,7 +69,7 @@ s32 sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_a ct->size = size; // Write back the start address of the allocated area. - sc_mem.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", ct->addr, ct->size); + sys_memory.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", ct->addr, ct->size); Memory.Write32(alloc_addr_addr, ct->addr); return CELL_OK; @@ -78,7 +77,7 @@ s32 sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_a s32 sys_memory_free(u32 start_addr) { - sc_mem.Log("sys_memory_free(start_addr=0x%x)", start_addr); + sys_memory.Log("sys_memory_free(start_addr=0x%x)", start_addr); // Release the allocated memory. if(!Memory.Free(start_addr)) @@ -89,7 +88,7 @@ s32 sys_memory_free(u32 start_addr) s32 sys_memory_get_page_attribute(u32 addr, mem_ptr_t attr) { - sc_mem.Warning("sys_memory_get_page_attribute(addr=0x%x, attr_addr=0x%x)", addr, attr.GetAddr()); + sys_memory.Warning("sys_memory_get_page_attribute(addr=0x%x, attr_addr=0x%x)", addr, attr.GetAddr()); // TODO: Implement per thread page attribute setting. attr->attribute = 0; @@ -102,7 +101,7 @@ s32 sys_memory_get_page_attribute(u32 addr, mem_ptr_t attr) s32 sys_memory_get_user_memory_size(mem_ptr_t mem_info) { - sc_mem.Warning("sys_memory_get_user_memory_size(mem_info_addr=0x%x)", mem_info.GetAddr()); + sys_memory.Warning("sys_memory_get_user_memory_size(mem_info_addr=0x%x)", mem_info.GetAddr()); // Fetch the user memory available. mem_info->total_user_memory = Memory.GetUserMemTotalSize(); @@ -112,7 +111,7 @@ s32 sys_memory_get_user_memory_size(mem_ptr_t mem_info) s32 sys_memory_container_create(mem32_t cid, u32 yield_size) { - sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.GetAddr(), yield_size); + sys_memory.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.GetAddr(), yield_size); yield_size &= ~0xfffff; //round down to 1 MB granularity u64 addr = Memory.Alloc(yield_size, 0x100000); //1 MB alignment @@ -122,36 +121,36 @@ s32 sys_memory_container_create(mem32_t cid, u32 yield_size) // Wrap the allocated memory in a memory container. MemoryContainerInfo *ct = new MemoryContainerInfo(addr, yield_size); - cid = sc_mem.GetNewId(ct, TYPE_MEM); + cid = sys_memory.GetNewId(ct, TYPE_MEM); - sc_mem.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue()); + sys_memory.Warning("*** memory_container created(addr=0x%llx): id = %d", addr, cid.GetValue()); return CELL_OK; } s32 sys_memory_container_destroy(u32 cid) { - sc_mem.Warning("sys_memory_container_destroy(cid=%d)", cid); + sys_memory.Warning("sys_memory_container_destroy(cid=%d)", cid); // Check if this container ID is valid. MemoryContainerInfo* ct; - if(!sc_mem.CheckId(cid, ct)) + if (!sys_memory.CheckId(cid, ct)) return CELL_ESRCH; // Release the allocated memory and remove the ID. Memory.Free(ct->addr); - Emu.GetIdManager().RemoveID(cid); + sys_memory.RemoveId(cid); return CELL_OK; } s32 sys_memory_container_get_size(mem_ptr_t mem_info, u32 cid) { - sc_mem.Warning("sys_memory_container_get_size(mem_info_addr=0x%x, cid=%d)", mem_info.GetAddr(), cid); + sys_memory.Warning("sys_memory_container_get_size(mem_info_addr=0x%x, cid=%d)", mem_info.GetAddr(), cid); // Check if this container ID is valid. MemoryContainerInfo* ct; - if(!sc_mem.CheckId(cid, ct)) + if (!sys_memory.CheckId(cid, ct)) return CELL_ESRCH; // HACK: Return all memory. diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp index 7555a5da0e..3c580f1721 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp @@ -1,8 +1,7 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" -#include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_memory.h" #include "sys_mmapper.h" #include @@ -25,13 +24,13 @@ s32 sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_a { default: case SYS_MEMORY_PAGE_SIZE_1M: - if(Memory.AlignAddr(size, alignment) & 0xfffff) + if(AlignAddr(size, alignment) & 0xfffff) return CELL_EALIGN; addr = Memory.Alloc(size, 0x100000); break; case SYS_MEMORY_PAGE_SIZE_64K: - if(Memory.AlignAddr(size, alignment) & 0xffff) + if(AlignAddr(size, alignment) & 0xffff) return CELL_EALIGN; addr = Memory.Alloc(size, 0x10000); break; @@ -155,7 +154,7 @@ s32 sys_mmapper_free_memory(u32 mem_id) // Release the allocated memory and remove the ID. Memory.Free(info->addr); - Emu.GetIdManager().RemoveID(mem_id); + sys_mmapper.RemoveId(mem_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index e9817bd0dd..b9e4e57371 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -1,25 +1,41 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/SysCalls.h" -#include "Utilities/SMutex.h" + +#include "Emu/Cell/PPUThread.h" #include "sys_mutex.h" -SysCallBase sys_mtx("sys_mutex"); +SysCallBase sys_mutex("sys_mutex"); + +Mutex::~Mutex() +{ + if (u32 owner = m_mutex.GetOwner()) + { + sys_mutex.Notice("Mutex(%d) was owned by thread %d (recursive=%d)", id, owner, recursive); + } + + if (!m_queue.m_mutex.try_lock()) return; + + for (u32 i = 0; i < m_queue.list.size(); i++) + { + if (u32 owner = m_queue.list[i]) sys_mutex.Notice("Mutex(%d) was waited by thread %d", id, owner); + } + + m_queue.m_mutex.unlock(); +} s32 sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) { - sys_mtx.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr()); + sys_mutex.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)", mutex_id.GetAddr(), attr.GetAddr()); switch (attr->protocol.ToBE()) { case se32(SYS_SYNC_FIFO): break; case se32(SYS_SYNC_PRIORITY): break; - case se32(SYS_SYNC_PRIORITY_INHERIT): sys_mtx.Todo("sys_mutex_create(): SYS_SYNC_PRIORITY_INHERIT"); break; - case se32(SYS_SYNC_RETRY): sys_mtx.Error("sys_mutex_create(): SYS_SYNC_RETRY"); return CELL_EINVAL; - default: sys_mtx.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL; + case se32(SYS_SYNC_PRIORITY_INHERIT): sys_mutex.Todo("sys_mutex_create(): SYS_SYNC_PRIORITY_INHERIT"); break; + case se32(SYS_SYNC_RETRY): sys_mutex.Error("sys_mutex_create(): SYS_SYNC_RETRY"); return CELL_EINVAL; + default: sys_mutex.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL; } bool is_recursive; @@ -27,23 +43,23 @@ s32 sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) { case se32(SYS_SYNC_RECURSIVE): is_recursive = true; break; case se32(SYS_SYNC_NOT_RECURSIVE): is_recursive = false; break; - default: sys_mtx.Error("Unknown recursive attribute(0x%x)", (u32)attr->recursive); return CELL_EINVAL; + default: sys_mutex.Error("Unknown recursive attribute(0x%x)", (u32)attr->recursive); return CELL_EINVAL; } if (attr->pshared.ToBE() != se32(0x200)) { - sys_mtx.Error("Unknown pshared attribute(0x%x)", (u32)attr->pshared); + sys_mutex.Error("Unknown pshared attribute(0x%x)", (u32)attr->pshared); return CELL_EINVAL; } u32 tid = GetCurrentPPUThread().GetId(); Mutex* mutex = new Mutex((u32)attr->protocol, is_recursive, attr->name_u64); - u32 id = sys_mtx.GetNewId(mutex, TYPE_MUTEX); + u32 id = sys_mutex.GetNewId(mutex, TYPE_MUTEX); mutex->m_mutex.lock(tid); mutex->id = id; mutex_id = id; mutex->m_mutex.unlock(tid); - sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d", + sys_mutex.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d", std::string(attr->name, 8).c_str(), (u32) attr->protocol, (is_recursive ? "true" : "false"), mutex_id.GetValue()); @@ -54,7 +70,7 @@ s32 sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) s32 sys_mutex_destroy(u32 mutex_id) { - sys_mtx.Warning("sys_mutex_destroy(mutex_id=%d)", mutex_id); + sys_mutex.Warning("sys_mutex_destroy(mutex_id=%d)", mutex_id); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -87,7 +103,7 @@ s32 sys_mutex_destroy(u32 mutex_id) s32 sys_mutex_lock(u32 mutex_id, u64 timeout) { - sys_mtx.Log("sys_mutex_lock(mutex_id=%d, timeout=%lld)", mutex_id, timeout); + sys_mutex.Log("sys_mutex_lock(mutex_id=%d, timeout=%lld)", mutex_id, timeout); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -120,7 +136,7 @@ s32 sys_mutex_lock(u32 mutex_id, u64 timeout) } else { - sys_mtx.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner); + sys_mutex.Error("sys_mutex_lock(%d): deadlock on invalid thread(%d)", mutex_id, owner); } } @@ -148,7 +164,7 @@ s32 sys_mutex_lock(u32 mutex_id, u64 timeout) abort: if (Emu.IsStopped()) { - sys_mtx.Warning("sys_mutex_lock(id=%d) aborted", mutex_id); + sys_mutex.Warning("sys_mutex_lock(id=%d) aborted", mutex_id); return CELL_OK; } return CELL_ESRCH; @@ -156,7 +172,7 @@ abort: s32 sys_mutex_trylock(u32 mutex_id) { - sys_mtx.Log("sys_mutex_trylock(mutex_id=%d)", mutex_id); + sys_mutex.Log("sys_mutex_trylock(mutex_id=%d)", mutex_id); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -189,7 +205,7 @@ s32 sys_mutex_trylock(u32 mutex_id) } else { - sys_mtx.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner); + sys_mutex.Error("sys_mutex_trylock(%d): deadlock on invalid thread(%d)", mutex_id, owner); } } @@ -203,7 +219,7 @@ s32 sys_mutex_trylock(u32 mutex_id) s32 sys_mutex_unlock(u32 mutex_id) { - sys_mtx.Log("sys_mutex_unlock(mutex_id=%d)", mutex_id); + sys_mutex.Log("sys_mutex_unlock(mutex_id=%d)", mutex_id); Mutex* mutex; if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) @@ -218,7 +234,7 @@ s32 sys_mutex_unlock(u32 mutex_id) { if (!mutex->recursive || (mutex->recursive != 1 && !mutex->is_recursive)) { - sys_mtx.Error("sys_mutex_unlock(%d): wrong recursive value fixed (%d)", mutex_id, mutex->recursive); + sys_mutex.Error("sys_mutex_unlock(%d): wrong recursive value fixed (%d)", mutex_id, mutex->recursive); mutex->recursive = 1; } mutex->recursive--; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h index fb91773145..b2813e41d2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h @@ -36,22 +36,7 @@ struct Mutex { } - ~Mutex() - { - if (u32 owner = m_mutex.GetOwner()) - { - LOG_NOTICE(HLE, "Mutex(%d) was owned by thread %d (recursive=%d)", id, owner, recursive); - } - - if (!m_queue.m_mutex.try_lock()) return; - - for (u32 i = 0; i < m_queue.list.size(); i++) - { - if (u32 owner = m_queue.list[i]) LOG_NOTICE(HLE, "Mutex(%d) was waited by thread %d", id, owner); - } - - m_queue.m_mutex.unlock(); - } + ~Mutex(); }; // SysCalls diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index 9a69b5b4b5..7dfba3b29c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -1,14 +1,12 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" -#include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/SysCalls.h" + +#include "Emu/Cell/PPUThread.h" #include "sys_ppu_thread.h" -extern Module *sysPrxForUser; +static SysCallBase sys_ppu_thread("sys_ppu_thread"); static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU/*UUUUUUUUUUuuuuuuuuuu~~~~~~~~*/; @@ -19,7 +17,7 @@ void ppu_thread_exit(u64 errorcode) if (thr.owned_mutexes) { - LOG_ERROR(PPU, "Owned mutexes found (%d)", thr.owned_mutexes); + sys_ppu_thread.Error("Owned mutexes found (%d)", thr.owned_mutexes); thr.owned_mutexes = 0; } @@ -29,21 +27,21 @@ void ppu_thread_exit(u64 errorcode) void sys_ppu_thread_exit(u64 errorcode) { - sysPrxForUser->Log("sys_ppu_thread_exit(0x%llx)", errorcode); + sys_ppu_thread.Log("sys_ppu_thread_exit(0x%llx)", errorcode); ppu_thread_exit(errorcode); } void sys_internal_ppu_thread_exit(u64 errorcode) { - sysPrxForUser->Log("sys_internal_ppu_thread_exit(0x%llx)", errorcode); + sys_ppu_thread.Log("sys_internal_ppu_thread_exit(0x%llx)", errorcode); ppu_thread_exit(errorcode); } s32 sys_ppu_thread_yield() { - sysPrxForUser->Log("sys_ppu_thread_yield()"); + sys_ppu_thread.Log("sys_ppu_thread_yield()"); // Note: Or do we actually want to yield? std::this_thread::sleep_for(std::chrono::milliseconds(1)); return CELL_OK; @@ -51,7 +49,7 @@ s32 sys_ppu_thread_yield() s32 sys_ppu_thread_join(u64 thread_id, mem64_t vptr) { - sysPrxForUser->Warning("sys_ppu_thread_join(thread_id=%lld, vptr_addr=0x%x)", thread_id, vptr.GetAddr()); + sys_ppu_thread.Warning("sys_ppu_thread_join(thread_id=%lld, vptr_addr=0x%x)", thread_id, vptr.GetAddr()); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; @@ -60,7 +58,7 @@ s32 sys_ppu_thread_join(u64 thread_id, mem64_t vptr) { if (Emu.IsStopped()) { - LOG_WARNING(PPU, "sys_ppu_thread_join(%d) aborted", thread_id); + sys_ppu_thread.Warning("sys_ppu_thread_join(%d) aborted", thread_id); return CELL_OK; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -72,7 +70,7 @@ s32 sys_ppu_thread_join(u64 thread_id, mem64_t vptr) s32 sys_ppu_thread_detach(u64 thread_id) { - sysPrxForUser->Todo("sys_ppu_thread_detach(thread_id=%lld)", thread_id); + sys_ppu_thread.Todo("sys_ppu_thread_detach(thread_id=%lld)", thread_id); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; @@ -86,13 +84,13 @@ s32 sys_ppu_thread_detach(u64 thread_id) void sys_ppu_thread_get_join_state(u32 isjoinable_addr) { - sysPrxForUser->Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable_addr); + sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable_addr); Memory.Write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable()); } s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio) { - sysPrxForUser->Log("sys_ppu_thread_set_priority(thread_id=%lld, prio=%d)", thread_id, prio); + sys_ppu_thread.Log("sys_ppu_thread_set_priority(thread_id=%lld, prio=%d)", thread_id, prio); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; @@ -104,7 +102,7 @@ s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio) s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr) { - sysPrxForUser->Log("sys_ppu_thread_get_priority(thread_id=%lld, prio_addr=0x%x)", thread_id, prio_addr); + sys_ppu_thread.Log("sys_ppu_thread_get_priority(thread_id=%lld, prio_addr=0x%x)", thread_id, prio_addr); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; @@ -116,7 +114,7 @@ s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr) s32 sys_ppu_thread_get_stack_information(u32 info_addr) { - sysPrxForUser->Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr); + sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr); declCPU(); @@ -128,7 +126,7 @@ s32 sys_ppu_thread_get_stack_information(u32 info_addr) s32 sys_ppu_thread_stop(u64 thread_id) { - sysPrxForUser->Warning("sys_ppu_thread_stop(thread_id=%lld)", thread_id); + sys_ppu_thread.Warning("sys_ppu_thread_stop(thread_id=%lld)", thread_id); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; @@ -140,7 +138,7 @@ s32 sys_ppu_thread_stop(u64 thread_id) s32 sys_ppu_thread_restart(u64 thread_id) { - sysPrxForUser->Warning("sys_ppu_thread_restart(thread_id=%lld)", thread_id); + sys_ppu_thread.Warning("sys_ppu_thread_restart(thread_id=%lld)", thread_id); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; @@ -156,7 +154,7 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s std::string threadname = ""; if (threadname_addr) threadname = Memory.ReadString(threadname_addr); - sysPrxForUser->Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))", + sys_ppu_thread.Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))", thread_id.GetAddr(), entry, arg, prio, stacksize, flags, threadname_addr, threadname.c_str()); bool is_joinable = false; @@ -175,7 +173,7 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s is_interrupt = true; break; } - default: sysPrxForUser->Error("sys_ppu_thread_create(): unknown flags value (0x%llx)", flags); return CELL_EPERM; + default: sys_ppu_thread.Error("sys_ppu_thread_create(): unknown flags value (0x%llx)", flags); return CELL_EPERM; } CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); @@ -190,7 +188,7 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s new_thread.m_is_interrupt = is_interrupt; new_thread.SetName(threadname); - LOG_NOTICE(PPU, "*** New PPU Thread [%s] (flags=0x%llx, entry=0x%x): id = %d", new_thread.GetName().c_str(), flags, entry, new_thread.GetId()); + sys_ppu_thread.Notice("*** New PPU Thread [%s] (flags=0x%llx, entry=0x%x): id = %d", new_thread.GetName().c_str(), flags, entry, new_thread.GetId()); if (!is_interrupt) { @@ -203,23 +201,18 @@ s32 sys_ppu_thread_create(mem64_t thread_id, u32 entry, u64 arg, s32 prio, u32 s void sys_ppu_thread_once(mem_ptr_t>> once_ctrl, u32 entry) { - sysPrxForUser->Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl.GetAddr(), entry); + sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl.GetAddr(), entry); be_t old = be_t::MakeFromBE(se32(SYS_PPU_THREAD_ONCE_INIT)); if (once_ctrl->compare_exchange_weak(old, be_t::MakeFromBE(se32(SYS_PPU_THREAD_DONE_INIT)))) { - CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - new_thread.SetEntry(entry); - new_thread.Run(); - new_thread.Exec(); - - while (new_thread.IsAlive()) SM_Sleep(); + GetCurrentPPUThread().FastCall2(Memory.Read32(entry), Memory.Read32(entry + 4)); } } s32 sys_ppu_thread_get_id(const u32 id_addr) { - sysPrxForUser->Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr); + sys_ppu_thread.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr); Memory.Write64(id_addr, GetCurrentPPUThread().GetId()); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index 02ff2174b6..0f0c4d0d54 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -1,12 +1,12 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_process.h" #include "rpcs3.h" -SysCallBase sc_p("Process"); +SysCallBase sys_process("sys_process"); s32 process_getpid() { @@ -16,21 +16,21 @@ s32 process_getpid() s32 sys_process_getpid() { - sc_p.Log("sys_process_getpid() -> 1"); + sys_process.Log("sys_process_getpid() -> 1"); return process_getpid(); } s32 sys_process_getppid() { - sc_p.Todo("sys_process_getppid() -> 0"); + sys_process.Todo("sys_process_getppid() -> 0"); return 0; } s32 sys_process_exit(s32 errorcode) { - sc_p.Warning("sys_process_exit(%d)", errorcode); + sys_process.Warning("sys_process_exit(%d)", errorcode); Emu.Pause(); - LOG_SUCCESS(HLE, "Process finished"); + sys_process.Success("Process finished"); wxGetApp().CallAfter([]() { Emu.Stop(); @@ -51,14 +51,14 @@ void sys_game_process_exitspawn( u32 prio, u64 flags ) { - sc_p.Todo("sys_game_process_exitspawn()"); - sc_p.Warning("path: %s", Memory.ReadString(path_addr).c_str()); - sc_p.Warning("argv: 0x%x", argv_addr); - sc_p.Warning("envp: 0x%x", envp_addr); - sc_p.Warning("data: 0x%x", data_addr); - sc_p.Warning("data_size: 0x%x", data_size); - sc_p.Warning("prio: %d", prio); - sc_p.Warning("flags: %d", flags); + sys_process.Todo("sys_game_process_exitspawn()"); + sys_process.Warning("path: %s", Memory.ReadString(path_addr).c_str()); + sys_process.Warning("argv: 0x%x", argv_addr); + sys_process.Warning("envp: 0x%x", envp_addr); + sys_process.Warning("data: 0x%x", data_addr); + sys_process.Warning("data_size: 0x%x", data_size); + sys_process.Warning("prio: %d", prio); + sys_process.Warning("flags: %d", flags); std::string path = Memory.ReadString(path_addr); std::vector argv; @@ -78,10 +78,10 @@ void sys_game_process_exitspawn( } for (auto &arg : argv){ - sc_p.Log("argument: %s", arg.c_str()); + sys_process.Log("argument: %s", arg.c_str()); } for (auto &en : env){ - sc_p.Log("env_argument: %s", en.c_str()); + sys_process.Log("env_argument: %s", en.c_str()); } //TODO: execute the file in with the args in argv //and the environment parameters in envp and copy the data @@ -99,14 +99,14 @@ void sys_game_process_exitspawn2( u32 prio, u64 flags) { - sc_p.Todo("sys_game_process_exitspawn2"); - sc_p.Warning("path: %s", Memory.ReadString(path_addr).c_str()); - sc_p.Warning("argv: 0x%x", argv_addr); - sc_p.Warning("envp: 0x%x", envp_addr); - sc_p.Warning("data: 0x%x", data_addr); - sc_p.Warning("data_size: 0x%x", data_size); - sc_p.Warning("prio: %d", prio); - sc_p.Warning("flags: %d", flags); + sys_process.Todo("sys_game_process_exitspawn2"); + sys_process.Warning("path: %s", Memory.ReadString(path_addr).c_str()); + sys_process.Warning("argv: 0x%x", argv_addr); + sys_process.Warning("envp: 0x%x", envp_addr); + sys_process.Warning("data: 0x%x", data_addr); + sys_process.Warning("data_size: 0x%x", data_size); + sys_process.Warning("prio: %d", prio); + sys_process.Warning("flags: %d", flags); std::string path = Memory.ReadString(path_addr); std::vector argv; @@ -126,10 +126,10 @@ void sys_game_process_exitspawn2( } for (auto &arg : argv){ - sc_p.Log("argument: %s", arg.c_str()); + sys_process.Log("argument: %s", arg.c_str()); } for (auto &en : env){ - sc_p.Log("env_argument: %s", en.c_str()); + sys_process.Log("env_argument: %s", en.c_str()); } //TODO: execute the file in with the args in argv //and the environment parameters in envp and copy the data @@ -140,7 +140,7 @@ void sys_game_process_exitspawn2( s32 sys_process_get_number_of_object(u32 object, mem32_t nump) { - sc_p.Warning("sys_process_get_number_of_object(object=%d, nump_addr=0x%x)", + sys_process.Warning("sys_process_get_number_of_object(object=%d, nump_addr=0x%x)", object, nump.GetAddr()); switch(object) @@ -175,7 +175,7 @@ s32 sys_process_get_number_of_object(u32 object, mem32_t nump) s32 sys_process_get_id(u32 object, mem32_ptr_t buffer, u32 size, mem32_t set_size) { - sc_p.Todo("sys_process_get_id(object=%d, buffer_addr=0x%x, size=%d, set_size_addr=0x%x)", + sys_process.Todo("sys_process_get_id(object=%d, buffer_addr=0x%x, size=%d, set_size_addr=0x%x)", object, buffer.GetAddr(), size, set_size.GetAddr()); switch(object) @@ -219,7 +219,7 @@ s32 sys_process_get_id(u32 object, mem32_ptr_t buffer, u32 size, mem32_t set_siz s32 sys_process_get_paramsfo(mem8_ptr_t buffer) { - sc_p.Todo("sys_process_get_paramsfo(buffer_addr=0x%x) -> CELL_ENOENT", buffer.GetAddr()); + sys_process.Todo("sys_process_get_paramsfo(buffer_addr=0x%x) -> CELL_ENOENT", buffer.GetAddr()); return CELL_ENOENT; /*//Before uncommenting this code, we should check if it is actually working. @@ -246,7 +246,7 @@ s32 process_get_sdk_version(u32 pid, s32& ver) s32 sys_process_get_sdk_version(u32 pid, mem32_t version) { - sc_p.Warning("sys_process_get_sdk_version(pid=%d, version_addr=0x%x)", pid, version.GetAddr()); + sys_process.Warning("sys_process_get_sdk_version(pid=%d, version_addr=0x%x)", pid, version.GetAddr()); s32 sdk_ver; s32 ret = process_get_sdk_version(pid, sdk_ver); @@ -263,33 +263,33 @@ s32 sys_process_get_sdk_version(u32 pid, mem32_t version) s32 sys_process_kill(u32 pid) { - sc_p.Todo("sys_process_kill(pid=%d)", pid); + sys_process.Todo("sys_process_kill(pid=%d)", pid); return CELL_OK; } s32 sys_process_wait_for_child(u32 pid, mem32_t status, u64 unk) { - sc_p.Todo("sys_process_wait_for_child(pid=%d, status_addr=0x%x, unk=0x%llx", + sys_process.Todo("sys_process_wait_for_child(pid=%d, status_addr=0x%x, unk=0x%llx", pid, status.GetAddr(), unk); return CELL_OK; } s32 sys_process_wait_for_child2(u64 unk1, u64 unk2, u64 unk3, u64 unk4, u64 unk5, u64 unk6) { - sc_p.Todo("sys_process_wait_for_child2(unk1=0x%llx, unk2=0x%llx, unk3=0x%llx, unk4=0x%llx, unk5=0x%llx, unk6=0x%llx)", + sys_process.Todo("sys_process_wait_for_child2(unk1=0x%llx, unk2=0x%llx, unk3=0x%llx, unk4=0x%llx, unk5=0x%llx, unk6=0x%llx)", unk1, unk2, unk3, unk4, unk5, unk6); return CELL_OK; } s32 sys_process_get_status(u64 unk) { - sc_p.Todo("sys_process_get_status(unk=0x%llx)", unk); + sys_process.Todo("sys_process_get_status(unk=0x%llx)", unk); //Memory.Write32(CPU.GPR[4], GetPPUThreadStatus(CPU)); return CELL_OK; } s32 sys_process_detach_child(u64 unk) { - sc_p.Todo("sys_process_detach_child(unk=0x%llx)", unk); + sys_process.Todo("sys_process_detach_child(unk=0x%llx)", unk); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp index 5e8370b730..1da8a4cf0b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "Emu/FS/vfsFile.h" #include "Crypto/unself.h" #include "sys_prx.h" diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp index 1b65fdd5ea..7ffba5fd2c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_rsx.h" SysCallBase sys_rsx("sys_rsx"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index 28a7d61d21..187349b5a2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -1,7 +1,10 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Cell/PPUThread.h" +#include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + +#include "Emu/Cell/PPUThread.h" +#include "sys_lwmutex.h" #include "sys_rwlock.h" SysCallBase sys_rwlock("sys_rwlock"); @@ -68,7 +71,7 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_rwlock_rlock(rw_lock_id=%d, ...) aborted", rw_lock_id); + sys_rwlock.Warning("sys_rwlock_rlock(rw_lock_id=%d, ...) aborted", rw_lock_id); return CELL_ETIMEDOUT; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -131,7 +134,7 @@ s32 sys_rwlock_wlock(u32 rw_lock_id, u64 timeout) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_rwlock_wlock(rw_lock_id=%d, ...) aborted", rw_lock_id); + sys_rwlock.Warning("sys_rwlock_wlock(rw_lock_id=%d, ...) aborted", rw_lock_id); return CELL_ETIMEDOUT; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index d402105eee..aebb57dff7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -1,28 +1,29 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "Emu/Cell/PPUThread.h" #include "sys_semaphore.h" #include "sys_time.h" +//#include "Utilities/SMutex.h" -SysCallBase sys_sem("sys_semaphore"); +SysCallBase sys_semaphore("sys_semaphore"); s32 sys_semaphore_create(mem32_t sem, mem_ptr_t attr, int initial_count, int max_count) { - sys_sem.Warning("sys_semaphore_create(sem_addr=0x%x, attr_addr=0x%x, initial_count=%d, max_count=%d)", + sys_semaphore.Warning("sys_semaphore_create(sem_addr=0x%x, attr_addr=0x%x, initial_count=%d, max_count=%d)", sem.GetAddr(), attr.GetAddr(), initial_count, max_count); if (max_count <= 0 || initial_count > max_count || initial_count < 0) { - sys_sem.Error("sys_semaphore_create(): invalid parameters (initial_count=%d, max_count=%d)", initial_count, max_count); + sys_semaphore.Error("sys_semaphore_create(): invalid parameters (initial_count=%d, max_count=%d)", initial_count, max_count); return CELL_EINVAL; } if (attr->pshared.ToBE() != se32(0x200)) { - sys_sem.Error("sys_semaphore_create(): invalid pshared value(0x%x)", (u32)attr->pshared); + sys_semaphore.Error("sys_semaphore_create(): invalid pshared value(0x%x)", (u32)attr->pshared); return CELL_EINVAL; } @@ -30,13 +31,13 @@ s32 sys_semaphore_create(mem32_t sem, mem_ptr_t attr, i { case se32(SYS_SYNC_FIFO): break; case se32(SYS_SYNC_PRIORITY): break; - case se32(SYS_SYNC_PRIORITY_INHERIT): sys_sem.Todo("SYS_SYNC_PRIORITY_INHERIT"); break; - case se32(SYS_SYNC_RETRY): sys_sem.Error("SYS_SYNC_RETRY"); return CELL_EINVAL; - default: sys_sem.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL; + case se32(SYS_SYNC_PRIORITY_INHERIT): sys_semaphore.Todo("SYS_SYNC_PRIORITY_INHERIT"); break; + case se32(SYS_SYNC_RETRY): sys_semaphore.Error("SYS_SYNC_RETRY"); return CELL_EINVAL; + default: sys_semaphore.Error("Unknown protocol attribute(0x%x)", (u32)attr->protocol); return CELL_EINVAL; } - sem = sys_sem.GetNewId(new Semaphore(initial_count, max_count, attr->protocol, attr->name_u64), TYPE_SEMAPHORE); - LOG_NOTICE(HLE, "*** semaphore created [%s] (protocol=0x%x): id = %d", + sem = sys_semaphore.GetNewId(new Semaphore(initial_count, max_count, attr->protocol, attr->name_u64), TYPE_SEMAPHORE); + sys_semaphore.Notice("*** semaphore created [%s] (protocol=0x%x): id = %d", std::string(attr->name, 8).c_str(), (u32)attr->protocol, sem.GetValue()); return CELL_OK; @@ -44,7 +45,7 @@ s32 sys_semaphore_create(mem32_t sem, mem_ptr_t attr, i s32 sys_semaphore_destroy(u32 sem_id) { - sys_sem.Warning("sys_semaphore_destroy(sem_id=%d)", sem_id); + sys_semaphore.Warning("sys_semaphore_destroy(sem_id=%d)", sem_id); Semaphore* sem; if (!Emu.GetIdManager().GetIDData(sem_id, sem)) @@ -63,7 +64,7 @@ s32 sys_semaphore_destroy(u32 sem_id) s32 sys_semaphore_wait(u32 sem_id, u64 timeout) { - sys_sem.Log("sys_semaphore_wait(sem_id=%d, timeout=%lld)", sem_id, timeout); + sys_semaphore.Log("sys_semaphore_wait(sem_id=%d, timeout=%lld)", sem_id, timeout); Semaphore* sem; if (!Emu.GetIdManager().GetIDData(sem_id, sem)) @@ -88,7 +89,7 @@ s32 sys_semaphore_wait(u32 sem_id, u64 timeout) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_semaphore_wait(%d) aborted", sem_id); + sys_semaphore.Warning("sys_semaphore_wait(%d) aborted", sem_id); return CELL_OK; } @@ -117,7 +118,7 @@ s32 sys_semaphore_wait(u32 sem_id, u64 timeout) s32 sys_semaphore_trywait(u32 sem_id) { - sys_sem.Log("sys_semaphore_trywait(sem_id=%d)", sem_id); + sys_semaphore.Log("sys_semaphore_trywait(sem_id=%d)", sem_id); Semaphore* sem; if (!Emu.GetIdManager().GetIDData(sem_id, sem)) @@ -140,7 +141,7 @@ s32 sys_semaphore_trywait(u32 sem_id) s32 sys_semaphore_post(u32 sem_id, int count) { - sys_sem.Log("sys_semaphore_post(sem_id=%d, count=%d)", sem_id, count); + sys_semaphore.Log("sys_semaphore_post(sem_id=%d, count=%d)", sem_id, count); Semaphore* sem; if (!Emu.GetIdManager().GetIDData(sem_id, sem)) @@ -162,7 +163,7 @@ s32 sys_semaphore_post(u32 sem_id, int count) { if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_semaphore_post(%d) aborted", sem_id); + sys_semaphore.Warning("sys_semaphore_post(%d) aborted", sem_id); return CELL_OK; } @@ -192,7 +193,7 @@ s32 sys_semaphore_post(u32 sem_id, int count) s32 sys_semaphore_get_value(u32 sem_id, mem32_t count) { - sys_sem.Log("sys_semaphore_get_value(sem_id=%d, count_addr=0x%x)", sem_id, count.GetAddr()); + sys_semaphore.Log("sys_semaphore_get_value(sem_id=%d, count_addr=0x%x)", sem_id, count.GetAddr()); Semaphore* sem; if (!Emu.GetIdManager().GetIDData(sem_id, sem)) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h index 653f46502a..e78165d989 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h @@ -1,5 +1,7 @@ #pragma once +#include "sys_lwmutex.h" + struct sys_semaphore_attribute { be_t protocol; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spinlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spinlock.cpp index 26462efd71..454b23572b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spinlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spinlock.cpp @@ -1,8 +1,6 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/SysCalls.h" #include "sys_spinlock.h" @@ -35,7 +33,7 @@ void sys_spinlock_lock(mem_ptr_t>> lock) if (Emu.IsStopped()) { - LOG_WARNING(HLE, "sys_spinlock_lock(0x%x) aborted", lock.GetAddr()); + sys_spinlock.Warning("sys_spinlock_lock(0x%x) aborted", lock.GetAddr()); break; } } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 7298643bc2..ddc53e80e7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -1,18 +1,15 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/FS/vfsFile.h" -#include "sys_spu.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/SC_FUNC.h" -#include "Loader/ELF.h" + #include "Emu/Cell/RawSPUThread.h" +#include "Emu/FS/vfsFile.h" +#include "Loader/ELF.h" +#include "sys_spu.h" #include -static SysCallBase sc_spu("sys_spu"); -extern SysCallBase sys_event; +static SysCallBase sys_spu("sys_spu"); u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) { @@ -29,12 +26,12 @@ u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) s32 sys_spu_image_open(mem_ptr_t img, u32 path_addr) { const std::string path = Memory.ReadString(path_addr); - sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path.c_str()); + sys_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.GetAddr(), path_addr, path.c_str()); vfsFile f(path); if(!f.IsOpened()) { - sc_spu.Error("sys_spu_image_open error: '%s' not found!", path.c_str()); + sys_spu.Error("sys_spu_image_open error: '%s' not found!", path.c_str()); return CELL_ENOENT; } @@ -52,7 +49,7 @@ s32 sys_spu_image_open(mem_ptr_t img, u32 path_addr) //172 s32 sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t img, mem_ptr_t attr, mem_ptr_t arg) { - sc_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)", + sys_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)", thread.GetAddr(), group, spu_num, img.GetAddr(), attr.GetAddr(), arg.GetAddr()); SpuGroupInfo* group_info; @@ -102,7 +99,7 @@ s32 sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< thread = group_info->list[spu_num] = new_thread.GetId(); (*(SPUThread*)&new_thread).group = group_info; - sc_spu.Warning("*** New SPU Thread [%s] (img_offset=0x%x, ls_offset=0x%x, ep=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d", + sys_spu.Warning("*** New SPU Thread [%s] (img_offset=0x%x, ls_offset=0x%x, ep=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d", (attr->name_addr ? name.c_str() : ""), (u32) img->segs_addr, ((SPUThread&) new_thread).dmac.ls_offset, spu_ep, a1, a2, a3, a4, thread.GetValue()); return CELL_OK; @@ -111,7 +108,7 @@ s32 sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< //166 s32 sys_spu_thread_set_argument(u32 id, mem_ptr_t arg) { - sc_spu.Warning("sys_spu_thread_set_argument(id=%d, arg_addr=0x%x)", id, arg.GetAddr()); + sys_spu.Warning("sys_spu_thread_set_argument(id=%d, arg_addr=0x%x)", id, arg.GetAddr()); CPUThread* thr = Emu.GetCPU().GetThread(id); if(!thr || thr->GetType() != CPU_THREAD_SPU) @@ -130,7 +127,7 @@ s32 sys_spu_thread_set_argument(u32 id, mem_ptr_t arg) //165 s32 sys_spu_thread_get_exit_status(u32 id, mem32_t status) { - sc_spu.Warning("sys_spu_thread_get_exit_status(id=%d, status_addr=0x%x)", id, status.GetAddr()); + sys_spu.Warning("sys_spu_thread_get_exit_status(id=%d, status_addr=0x%x)", id, status.GetAddr()); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -152,7 +149,7 @@ s32 sys_spu_thread_get_exit_status(u32 id, mem32_t status) //171 s32 sys_spu_thread_group_destroy(u32 id) { - sc_spu.Warning("sys_spu_thread_group_destroy(id=%d)", id); + sys_spu.Warning("sys_spu_thread_group_destroy(id=%d)", id); SpuGroupInfo* group_info; if(!Emu.GetIdManager().GetIDData(id, group_info)) @@ -168,7 +165,7 @@ s32 sys_spu_thread_group_destroy(u32 id) if ((group_info->m_state != SPU_THREAD_GROUP_STATUS_INITIALIZED) && (group_info->m_state != SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED)) { - sc_spu.Error("sys_spu_thread_group_destroy(id=%d) is not in NOT_INITIALIZED / INITIALIZED, state=%d", id, group_info->m_state); + sys_spu.Error("sys_spu_thread_group_destroy(id=%d) is not in NOT_INITIALIZED / INITIALIZED, state=%d", id, group_info->m_state); return CELL_ESTAT; //Indeed this should not be encountered. If program itself all right. } //SET BUSY @@ -191,7 +188,7 @@ s32 sys_spu_thread_group_destroy(u32 id) //173 s32 sys_spu_thread_group_start(u32 id) { - sc_spu.Warning("sys_spu_thread_group_start(id=%d)", id); + sys_spu.Warning("sys_spu_thread_group_start(id=%d)", id); SpuGroupInfo* group_info; if(!Emu.GetIdManager().GetIDData(id, group_info)) @@ -227,7 +224,7 @@ s32 sys_spu_thread_group_start(u32 id) //174 s32 sys_spu_thread_group_suspend(u32 id) { - sc_spu.Log("sys_spu_thread_group_suspend(id=%d)", id); + sys_spu.Log("sys_spu_thread_group_suspend(id=%d)", id); SpuGroupInfo* group_info; if(!Emu.GetIdManager().GetIDData(id, group_info)) @@ -274,7 +271,7 @@ s32 sys_spu_thread_group_suspend(u32 id) //175 s32 sys_spu_thread_group_resume(u32 id) { - sc_spu.Log("sys_spu_thread_group_resume(id=%d)", id); + sys_spu.Log("sys_spu_thread_group_resume(id=%d)", id); SpuGroupInfo* group_info; if(!Emu.GetIdManager().GetIDData(id, group_info)) @@ -322,7 +319,7 @@ s32 sys_spu_thread_group_resume(u32 id) //176: Left doing nothing, indeed s32 sys_spu_thread_group_yield(u32 id) { - sc_spu.Error("sys_spu_thread_group_yield(id=%d)", id); + sys_spu.Error("sys_spu_thread_group_yield(id=%d)", id); SpuGroupInfo* group_info; if (!Emu.GetIdManager().GetIDData(id, group_info)) @@ -365,7 +362,7 @@ s32 sys_spu_thread_group_yield(u32 id) //177: Left omit the EPERM check. s32 sys_spu_thread_group_terminate(u32 id, int value) { - sc_spu.Error("sys_spu_thread_group_terminate(id=%d, value=%d)", id, value); + sys_spu.Error("sys_spu_thread_group_terminate(id=%d, value=%d)", id, value); SpuGroupInfo* group_info; if (!Emu.GetIdManager().GetIDData(id, group_info)) @@ -404,7 +401,7 @@ s32 sys_spu_thread_group_terminate(u32 id, int value) //170 s32 sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t attr) { - sc_spu.Warning("sys_spu_thread_group_create(id_addr=0x%x, num=%d, prio=%d, attr_addr=0x%x)", + sys_spu.Warning("sys_spu_thread_group_create(id_addr=0x%x, num=%d, prio=%d, attr_addr=0x%x)", id.GetAddr(), num, prio, attr.GetAddr()); if (num > 256) return CELL_EINVAL; @@ -413,9 +410,9 @@ s32 sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_tname_addr, attr->name_len); - id = sc_spu.GetNewId(new SpuGroupInfo(name, num, prio, attr->type, attr->ct)); + id = sys_spu.GetNewId(new SpuGroupInfo(name, num, prio, attr->type, attr->ct)); - sc_spu.Warning("*** SPU Thread Group created [%s] (type=0x%x, option.ct=0x%x): id=%d", + sys_spu.Warning("*** SPU Thread Group created [%s] (type=0x%x, option.ct=0x%x): id=%d", name.c_str(), (int)attr->type, (u32)attr->ct, id.GetValue()); return CELL_OK; @@ -424,7 +421,7 @@ s32 sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_tm_state = SPU_THREAD_GROUP_STATUS_INITIALIZED; group_info->lock = 0; // release lock TODO: this LOCK may be replaced. return CELL_OK; } s32 sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr) { - sc_spu.Todo("sys_spu_thread_create(thread_id_addr=0x%x, entry_addr=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x", + sys_spu.Todo("sys_spu_thread_create(thread_id_addr=0x%x, entry_addr=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x", thread_id.GetAddr(), entry.GetAddr(), arg, prio, stacksize, flags, threadname_addr); return CELL_OK; } @@ -471,7 +469,7 @@ s32 sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u //169 s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) { - sc_spu.Warning("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu); + sys_spu.Warning("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu); if(max_raw_spu > 5) { @@ -484,7 +482,7 @@ s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) //181 s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) { - sc_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=0x%x)", + sys_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=0x%x)", id, address, value, type); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -517,7 +515,7 @@ s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) //182 s32 sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type) { - sc_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value_addr=0x%x, type=0x%x)", + sys_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value_addr=0x%x, type=0x%x)", id, address, value.GetAddr(), type); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -550,7 +548,7 @@ s32 sys_spu_thread_read_ls(u32 id, u32 address, mem64_t value, u32 type) //190 s32 sys_spu_thread_write_spu_mb(u32 id, u32 value) { - sc_spu.Log("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value); + sys_spu.Log("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -567,7 +565,7 @@ s32 sys_spu_thread_write_spu_mb(u32 id, u32 value) //187 s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) { - sc_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value); + sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -589,7 +587,7 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) //188 s32 sys_spu_thread_get_spu_cfg(u32 id, mem64_t value) { - sc_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value_addr=0x%x)", id, value.GetAddr()); + sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value_addr=0x%x)", id, value.GetAddr()); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -606,7 +604,7 @@ s32 sys_spu_thread_get_spu_cfg(u32 id, mem64_t value) //184 s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) { - sc_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value); + sys_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value); CPUThread* thr = Emu.GetCPU().GetThread(id); if(!thr || thr->GetType() != CPU_THREAD_SPU) @@ -626,14 +624,14 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et) { - sc_spu.Todo("sys_spu_thread_group_connect_event(id=%d, eq=%d, et=0x%x)", id, eq, et); + sys_spu.Todo("sys_spu_thread_group_connect_event(id=%d, eq=%d, et=0x%x)", id, eq, et); return CELL_OK; } s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et) { - sc_spu.Todo("sys_spu_thread_group_disconnect_event(id=%d, et=0x%x)", id, et); + sys_spu.Todo("sys_spu_thread_group_disconnect_event(id=%d, et=0x%x)", id, et); return CELL_OK; } @@ -648,7 +646,7 @@ s32 sys_spu_thread_tryreceive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_ s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup) { - sc_spu.Warning("sys_spu_thread_connect_event(id=%d, eq_id=%d, event_type=0x%x, spup=%d)", id, eq_id, et, spup); + sys_spu.Warning("sys_spu_thread_connect_event(id=%d, eq_id=%d, event_type=0x%x, spup=%d)", id, eq_id, et, spup); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -665,13 +663,13 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup) if (spup > 63) { - sc_spu.Error("sys_spu_thread_connect_event: invalid spup (%d)", spup); + sys_spu.Error("sys_spu_thread_connect_event: invalid spup (%d)", spup); return CELL_EINVAL; } if (et != SYS_SPU_THREAD_EVENT_USER) { - sc_spu.Error("sys_spu_thread_connect_event: unsupported event type (0x%x)", et); + sys_spu.Error("sys_spu_thread_connect_event: unsupported event type (0x%x)", et); return CELL_EINVAL; } @@ -697,7 +695,7 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq_id, u32 et, u8 spup) // s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) { - sc_spu.Warning("sys_spu_thread_disconnect_event(id=%d, event_type=0x%x, spup=%d)", id, et, spup); + sys_spu.Warning("sys_spu_thread_disconnect_event(id=%d, event_type=0x%x, spup=%d)", id, et, spup); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -708,13 +706,13 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) if (spup > 63) { - sc_spu.Error("sys_spu_thread_connect_event: invalid spup (%d)", spup); + sys_spu.Error("sys_spu_thread_connect_event: invalid spup (%d)", spup); return CELL_EINVAL; } if (et != SYS_SPU_THREAD_EVENT_USER) { - sc_spu.Error("sys_spu_thread_connect_event: unsupported event type (0x%x)", et); + sys_spu.Error("sys_spu_thread_connect_event: unsupported event type (0x%x)", et); return CELL_EINVAL; } @@ -737,7 +735,7 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) s32 sys_spu_thread_bind_queue(u32 id, u32 eq_id, u32 spuq_num) { - sc_spu.Warning("sys_spu_thread_bind_queue(id=%d, equeue_id=%d, spuq_num=0x%x)", id, eq_id, spuq_num); + sys_spu.Warning("sys_spu_thread_bind_queue(id=%d, equeue_id=%d, spuq_num=0x%x)", id, eq_id, spuq_num); EventQueue* eq; if (!Emu.GetIdManager().GetIDData(eq_id, eq)) @@ -767,7 +765,7 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 eq_id, u32 spuq_num) s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) { - sc_spu.Warning("sys_spu_thread_unbind_queue(id=0x%x, spuq_num=0x%x)", id, spuq_num); + sys_spu.Warning("sys_spu_thread_unbind_queue(id=0x%x, spuq_num=0x%x)", id, spuq_num); CPUThread* thr = Emu.GetCPU().GetThread(id); @@ -786,7 +784,7 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, mem8_t spup) { - sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=%d, eq_id=%d, req=0x%llx, spup_addr=0x%x)", + sys_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=%d, eq_id=%d, req=0x%llx, spup_addr=0x%x)", id, eq_id, req, spup.GetAddr()); EventQueue* eq; @@ -813,7 +811,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, m CPUThread* thr = Emu.GetCPU().GetThread(v); if (thr->GetType() != CPU_THREAD_SPU) { - sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (wrong thread type)"); + sys_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (wrong thread type)"); return CELL_ESTAT; } threads.push_back((SPUThread*)thr); @@ -821,7 +819,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, m if (threads.size() != group->m_count) { - sc_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (%d from %d)", (u32)threads.size(), group->m_count); + sys_spu.Error("sys_spu_thread_group_connect_event_all_threads(): CELL_ESTAT (%d from %d)", (u32)threads.size(), group->m_count); return CELL_ESTAT; } @@ -841,6 +839,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, m eq->ports.add(&(t->SPUPs[i])); t->SPUPs[i].eq = eq; } + sys_spu.Warning("*** spup -> %d", i); spup = (u8)i; } @@ -859,7 +858,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, m s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) { - sc_spu.Todo("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup); + sys_spu.Todo("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup); return CELL_OK; } @@ -867,7 +866,7 @@ s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) //160 s32 sys_raw_spu_create(mem32_t id, u32 attr_addr) { - sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id.GetAddr(), attr_addr); + sys_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id.GetAddr(), attr_addr); CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); if (((RawSPUThread&)new_thread).GetIndex() >= 5) @@ -883,7 +882,7 @@ s32 sys_raw_spu_create(mem32_t id, u32 attr_addr) s32 sys_raw_spu_destroy(u32 id) { - sc_spu.Warning("sys_raw_spu_destroy(id=%d)", id); + sys_spu.Warning("sys_raw_spu_destroy(id=%d)", id); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); @@ -900,7 +899,7 @@ s32 sys_raw_spu_destroy(u32 id) s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, mem32_t intrtag) { - sc_spu.Warning("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag_addr=0x%x)", id, class_id, hwthread, intrtag.GetAddr()); + sys_spu.Warning("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag_addr=0x%x)", id, class_id, hwthread, intrtag.GetAddr()); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); @@ -927,7 +926,7 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, mem32_t s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) { - sc_spu.Warning("sys_raw_spu_set_int_mask(id=%d, class_id=%d, mask=0x%llx)", id, class_id, mask); + sys_spu.Warning("sys_raw_spu_set_int_mask(id=%d, class_id=%d, mask=0x%llx)", id, class_id, mask); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) @@ -946,7 +945,7 @@ s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, mem64_t mask) { - sc_spu.Log("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask_addr=0x%x)", id, class_id, mask.GetAddr()); + sys_spu.Log("sys_raw_spu_get_int_mask(id=%d, class_id=%d, mask_addr=0x%x)", id, class_id, mask.GetAddr()); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) @@ -965,7 +964,7 @@ s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, mem64_t mask) s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) { - sc_spu.Log("sys_raw_spu_set_int_stat(id=%d, class_id=%d, stat=0x%llx)", id, class_id, stat); + sys_spu.Log("sys_raw_spu_set_int_stat(id=%d, class_id=%d, stat=0x%llx)", id, class_id, stat); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) @@ -984,7 +983,7 @@ s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, mem64_t stat) { - sc_spu.Log("sys_raw_spu_get_int_stat(id=%d, class_id=%d, stat_addr=0xx)", id, class_id, stat.GetAddr()); + sys_spu.Log("sys_raw_spu_get_int_stat(id=%d, class_id=%d, stat_addr=0xx)", id, class_id, stat.GetAddr()); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) @@ -1003,7 +1002,7 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, mem64_t stat) s32 sys_raw_spu_read_puint_mb(u32 id, mem32_t value) { - sc_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value_addr=0x%x)", id, value.GetAddr()); + sys_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value_addr=0x%x)", id, value.GetAddr()); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) @@ -1019,7 +1018,7 @@ s32 sys_raw_spu_read_puint_mb(u32 id, mem32_t value) s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value) { - sc_spu.Log("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value); + sys_spu.Log("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) @@ -1033,7 +1032,7 @@ s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value) s32 sys_raw_spu_get_spu_cfg(u32 id, mem32_t value) { - sc_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value_addr=0x%x)", id, value.GetAddr()); + sys_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value_addr=0x%x)", id, value.GetAddr()); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); if (!t) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index 7f6399aa7b..e050703dd4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -1,7 +1,5 @@ #pragma once -u32 LoadSpuImage(vfsStream& stream, u32& spu_ep); - enum { SYS_SPU_THREAD_GROUP_TYPE_NORMAL = 0x00, diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp index 69292b5fed..90be5d2122 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp @@ -6,10 +6,10 @@ * GNU LGPL 2.1 license * */ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_time.h" SysCallBase sys_time("sys_time"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index 01f8ec7526..7250394698 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -1,8 +1,9 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + +#include "Emu/Event.h" #include "sys_timer.h" SysCallBase sys_timer("sys_timer"); @@ -11,10 +12,6 @@ s32 sys_timer_create(mem32_t timer_id) { sys_timer.Warning("sys_timer_create(timer_id_addr=0x%x)", timer_id.GetAddr()); - if (!timer_id.IsGood()) { - return CELL_EFAULT; - } - timer_id = sys_timer.GetNewId(new timer, TYPE_TIMER); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_trace.cpp b/rpcs3/Emu/SysCalls/lv2/sys_trace.cpp index 725cb49338..7e6b76e7d1 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_trace.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_trace.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_trace.h" SysCallBase sys_trace("sys_trace"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp b/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp index a570630de0..86548b31e4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp @@ -3,12 +3,16 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" + #include "sys_tty.h" +SysCallBase sys_tty("sys_tty"); + s32 sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr) { + sys_tty.Error("sys_tty_read(ch=%d, buf_addr=%llx, len=%d, preadlen_addr=0x%llx)", ch, buf_addr, len, preadlen_addr); + // We currently do not support reading from the Console - LOG_WARNING(HLE, "sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len); Memory.Write32(preadlen_addr, len); Emu.Pause(); @@ -17,6 +21,8 @@ s32 sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr) s32 sys_tty_write(u32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr) { + sys_tty.Log("sys_tty_write(ch=%d, buf_addr=%llx, len=%d, preadlen_addr=0x%llx)", ch, buf_addr, len, pwritelen_addr); + if(ch > 15 || (s32)len <= 0) return CELL_EINVAL; if (ch == SYS_TTYP_PPU_STDOUT || ch == SYS_TTYP_SPU_STDOUT || (ch >= SYS_TTYP_USER1 && ch <= SYS_TTYP_USER13)) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp index 3c1de7c437..9fd3e39b2d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp @@ -1,16 +1,17 @@ #include "stdafx.h" -#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" -#include "sys_memory.h" -SysCallBase sc_vm("vm"); +#include "sys_memory.h" +#include "sys_vm.h" + +SysCallBase sys_vm("vm"); MemoryContainerInfo* current_ct; s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr) { - sc_vm.Warning("sys_vm_memory_map(vsize=0x%x,psize=0x%x,cidr=0x%x,flags=0x%llx,policy=0x%llx,addr=0x%x)", + sys_vm.Warning("sys_vm_memory_map(vsize=0x%x,psize=0x%x,cidr=0x%x,flags=0x%llx,policy=0x%llx,addr=0x%x)", vsize, psize, cid, flag, policy, addr); // Check virtual size. @@ -51,7 +52,7 @@ s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 a { // Check memory container. MemoryContainerInfo* ct; - if(!sc_vm.CheckId(cid, ct)) return CELL_ESRCH; + if(!sys_vm.CheckId(cid, ct)) return CELL_ESRCH; current_ct = ct; } @@ -64,7 +65,7 @@ s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 a s32 sys_vm_unmap(u32 addr) { - sc_vm.Warning("sys_vm_unmap(addr=0x%x)", addr); + sys_vm.Warning("sys_vm_unmap(addr=0x%x)", addr); // Simply free the memory to unmap. if(!Memory.Free(addr)) return CELL_EINVAL; @@ -74,7 +75,7 @@ s32 sys_vm_unmap(u32 addr) s32 sys_vm_append_memory(u32 addr, u32 size) { - sc_vm.Warning("sys_vm_append_memory(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Warning("sys_vm_append_memory(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (size <= 0)) @@ -96,7 +97,7 @@ s32 sys_vm_append_memory(u32 addr, u32 size) s32 sys_vm_return_memory(u32 addr, u32 size) { - sc_vm.Warning("sys_vm_return_memory(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Warning("sys_vm_return_memory(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (size <= 0)) @@ -118,7 +119,7 @@ s32 sys_vm_return_memory(u32 addr, u32 size) s32 sys_vm_lock(u32 addr, u32 size) { - sc_vm.Warning("sys_vm_lock(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Warning("sys_vm_lock(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -140,7 +141,7 @@ s32 sys_vm_lock(u32 addr, u32 size) s32 sys_vm_unlock(u32 addr, u32 size) { - sc_vm.Warning("sys_vm_unlock(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Warning("sys_vm_unlock(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -155,7 +156,7 @@ s32 sys_vm_unlock(u32 addr, u32 size) s32 sys_vm_touch(u32 addr, u32 size) { - sc_vm.Todo("sys_vm_touch(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("sys_vm_touch(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -172,7 +173,7 @@ s32 sys_vm_touch(u32 addr, u32 size) s32 sys_vm_flush(u32 addr, u32 size) { - sc_vm.Todo("sys_vm_flush(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("sys_vm_flush(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -189,7 +190,7 @@ s32 sys_vm_flush(u32 addr, u32 size) s32 sys_vm_invalidate(u32 addr, u32 size) { - sc_vm.Todo("sys_vm_invalidate(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("sys_vm_invalidate(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -206,7 +207,7 @@ s32 sys_vm_invalidate(u32 addr, u32 size) s32 sys_vm_store(u32 addr, u32 size) { - sc_vm.Todo("sys_vm_store(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("sys_vm_store(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -223,7 +224,7 @@ s32 sys_vm_store(u32 addr, u32 size) s32 sys_vm_sync(u32 addr, u32 size) { - sc_vm.Todo("sys_vm_sync(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("sys_vm_sync(addr=0x%x,size=0x%x)", addr, size); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -239,7 +240,7 @@ s32 sys_vm_sync(u32 addr, u32 size) s32 sys_vm_test(u32 addr, u32 size, u32 result_addr) { - sc_vm.Todo("sys_vm_test(addr=0x%x,size=0x%x,result_addr=0x%x)", addr, size, result_addr); + sys_vm.Todo("sys_vm_test(addr=0x%x,size=0x%x,result_addr=0x%x)", addr, size, result_addr); // Check address and size. if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) @@ -258,7 +259,7 @@ s32 sys_vm_test(u32 addr, u32 size, u32 result_addr) s32 sys_vm_get_statistics(u32 addr, u32 stat_addr) { - sc_vm.Todo("sys_vm_get_statistics(addr=0x%x,stat_addr=0x%x)", addr, stat_addr); + sys_vm.Todo("sys_vm_get_statistics(addr=0x%x,stat_addr=0x%x)", addr, stat_addr); // Check address. if(current_ct->addr != addr) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 0745e1c49c..4f48d787df 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -2,7 +2,6 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -//#include "Ini.h" #include "Emu/GameInfo.h" #include "Emu/SysCalls/Static.h" @@ -324,11 +323,17 @@ void Emulator::Load() m_ppu_thr_exit = Memory.MainMem.AllocAlign(4 * 4); mem32_ptr_t ppu_thr_exit_data(m_ppu_thr_exit); - ppu_thr_exit_data += ADDI(3, 0, 0); + //ppu_thr_exit_data += ADDI(3, 0, 0); // why it kills return value (GPR[3]) ? ppu_thr_exit_data += ADDI(11, 0, 41); ppu_thr_exit_data += SC(2); ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0); + m_ppu_thr_stop = Memory.MainMem.AllocAlign(2 * 4); + + mem32_ptr_t ppu_thr_stop_data(m_ppu_thr_stop); + ppu_thr_stop_data += SC(4); + ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0); + Memory.Write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE); } break; @@ -422,11 +427,6 @@ void Emulator::Stop() break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); - if (counter++ > 3000) - { - LOG_ERROR(HLE, "%d threads not stopped (timeout)", (u32)(g_thread_count - uncounted)); - break; - } } m_rsx_callback = 0; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index f2500878ac..66a087589e 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -106,6 +106,7 @@ public: std::string m_path; std::string m_elf_path; std::string m_title_id; + u32 m_ppu_thr_stop; s32 m_sdk_version; Emulator(); diff --git a/rpcs3/Gui/AutoPauseManager.cpp b/rpcs3/Gui/AutoPauseManager.cpp index 98235314fa..67a43f2817 100644 --- a/rpcs3/Gui/AutoPauseManager.cpp +++ b/rpcs3/Gui/AutoPauseManager.cpp @@ -1,6 +1,11 @@ #include "stdafx.h" #include "Emu/System.h" #include "AutoPauseManager.h" +#include "stdafx.h" +#include +#include +#include "Utilities/Log.h" +#include "Utilities/rFile.h" enum { diff --git a/rpcs3/Gui/AutoPauseManager.h b/rpcs3/Gui/AutoPauseManager.h index a1b8f00450..c3b207b237 100644 --- a/rpcs3/Gui/AutoPauseManager.h +++ b/rpcs3/Gui/AutoPauseManager.h @@ -1,9 +1,4 @@ #pragma once -#include "stdafx.h" -#include -#include -#include "Utilities/Log.h" -#include "Utilities/rFile.h" class AutoPauseManagerDialog : public wxDialog { diff --git a/rpcs3/Gui/CompilerELF.cpp b/rpcs3/Gui/CompilerELF.cpp index c67dfe0703..c4b388283b 100644 --- a/rpcs3/Gui/CompilerELF.cpp +++ b/rpcs3/Gui/CompilerELF.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" +#include "Utilities/rMsgBox.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "CompilerELF.h" diff --git a/rpcs3/Gui/ConLogFrame.cpp b/rpcs3/Gui/ConLogFrame.cpp index 0e2ee848e5..e2c354e0e5 100644 --- a/rpcs3/Gui/ConLogFrame.cpp +++ b/rpcs3/Gui/ConLogFrame.cpp @@ -7,14 +7,9 @@ #include #include "Ini.h" -#include "Utilities/Thread.h" -#include "Utilities/StrFmt.h" -#include "Utilities/Log.h" #include "Utilities/Log.h" #include "Gui/ConLogFrame.h" -#include "Utilities/BEType.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" wxDEFINE_EVENT(EVT_LOG_COMMAND, wxCommandEvent); diff --git a/rpcs3/Gui/ConLogFrame.h b/rpcs3/Gui/ConLogFrame.h index da7749b619..911d4f313e 100644 --- a/rpcs3/Gui/ConLogFrame.h +++ b/rpcs3/Gui/ConLogFrame.h @@ -1,7 +1,11 @@ #pragma once #include -#include "Utilities/Log.h" +#include +namespace Log +{ + struct LogListener; +} class LogFrame : public wxPanel diff --git a/rpcs3/Gui/DisAsmFrame.cpp b/rpcs3/Gui/DisAsmFrame.cpp index 66852a2f83..1d87901943 100644 --- a/rpcs3/Gui/DisAsmFrame.cpp +++ b/rpcs3/Gui/DisAsmFrame.cpp @@ -2,8 +2,6 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/lv2/sys_lwmutex.h" -#include "Emu/SysCalls/lv2/sys_event.h" #include "DisAsmFrame.h" #include "Emu/FS/vfsLocalFile.h" #include "Emu/Cell/PPCThread.h" diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index d5205f029e..50c7c8a2db 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "GLGSFrame.h" +#include "Utilities/Timer.h" GLGSFrame::GLGSFrame() : GSFrame(nullptr, "GSFrame[OpenGL]") diff --git a/rpcs3/Gui/GSFrame.cpp b/rpcs3/Gui/GSFrame.cpp index d1361c9832..fde662b2db 100644 --- a/rpcs3/Gui/GSFrame.cpp +++ b/rpcs3/Gui/GSFrame.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "GSFrame.h" #include "Emu/System.h" +#include "Emu/RSX/sysutil_video.h" #include "rpcs3.h" BEGIN_EVENT_TABLE(GSFrame, wxFrame) diff --git a/rpcs3/Gui/GameViewer.h b/rpcs3/Gui/GameViewer.h index 463f7ee4b0..80c007fff0 100644 --- a/rpcs3/Gui/GameViewer.h +++ b/rpcs3/Gui/GameViewer.h @@ -1,5 +1,6 @@ #pragma once #include +#include "rpcs3/Ini.h" #include "Emu/GameInfo.h" struct Column diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index ee1ffdb535..b0eff5c67f 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -3,8 +3,6 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "rpcs3.h" -#include "Emu/SysCalls/lv2/sys_lwmutex.h" -#include "Emu/SysCalls/lv2/sys_event.h" #include "InterpreterDisAsm.h" #include "Emu/Cell/PPUDecoder.h" #include "Emu/Cell/PPUDisAsm.h" @@ -249,7 +247,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr) } else { - disasm->offset = CPU->GetOffset(); + disasm->offset = Memory.GetMemFromAddr(CPU->GetOffset()); for(uint i=0, count = 4; iGetOffset() + PC, 4)) diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 0a437560be..0d28888914 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "rpcs3/Ini.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" diff --git a/rpcs3/Gui/SaveDataUtility.cpp b/rpcs3/Gui/SaveDataUtility.cpp index 46ca644106..2bebd478ad 100644 --- a/rpcs3/Gui/SaveDataUtility.cpp +++ b/rpcs3/Gui/SaveDataUtility.cpp @@ -1,5 +1,10 @@ #include "stdafx.h" #include "SaveDataUtility.h" +#include "stdafx.h" +#include +#include +#include "Utilities/Log.h" +#include "Utilities/rFile.h" //Cause i can not decide what struct to be used to fill those. Just use no real data now. //Currently variable info isn't used. it supposed to be a container for the information passed by other. diff --git a/rpcs3/Gui/SaveDataUtility.h b/rpcs3/Gui/SaveDataUtility.h index 88037add29..38a9bbbd1b 100644 --- a/rpcs3/Gui/SaveDataUtility.h +++ b/rpcs3/Gui/SaveDataUtility.h @@ -1,9 +1,4 @@ #pragma once -#include "stdafx.h" -#include -#include -#include "Utilities/Log.h" -#include "Utilities/rFile.h" //TODO: Implement function calls related to Save Data List. //Those function calls may be needed to use this GUI. diff --git a/rpcs3/Loader/ELF.cpp b/rpcs3/Loader/ELF.cpp index d967e4583e..aaa7af4c65 100644 --- a/rpcs3/Loader/ELF.cpp +++ b/rpcs3/Loader/ELF.cpp @@ -1,7 +1,16 @@ #include "stdafx.h" -#include "Loader.h" #include "ELF.h" +void Elf_Ehdr::Show() +{ +} + +void Elf_Ehdr::Load(vfsStream& f) +{ + e_magic = Read32(f); + e_class = Read8(f); +} + ELFLoader::ELFLoader(vfsStream& f) : elf_f(f) , LoaderBase() diff --git a/rpcs3/Loader/ELF.h b/rpcs3/Loader/ELF.h index cbb9d88473..3ff9e34224 100644 --- a/rpcs3/Loader/ELF.h +++ b/rpcs3/Loader/ELF.h @@ -1,7 +1,6 @@ #pragma once #include "ELF64.h" #include "ELF32.h" -#include "Emu/FS/vfsStream.h" enum ElfClass { @@ -15,15 +14,9 @@ struct Elf_Ehdr u32 e_magic; u8 e_class; - virtual void Show() - { - } + virtual void Show(); - virtual void Load(vfsStream& f) - { - e_magic = Read32(f); - e_class = Read8(f); - } + virtual void Load(vfsStream& f); bool CheckMagic() const { return e_magic == 0x7F454C46; } diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 2c3c4f4fac..6c327e0494 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -3,6 +3,207 @@ #include "Emu/Memory/Memory.h" #include "ELF32.h" +void Elf32_Ehdr::Show() +{ +#ifdef LOADER_DEBUG + LOG_NOTICE(LOADER, "Magic: %08x", e_magic); + LOG_NOTICE(LOADER, "Class: %s", "ELF32"); + LOG_NOTICE(LOADER, "Data: %s", Ehdr_DataToString(e_data).c_str()); + LOG_NOTICE(LOADER, "Current Version: %d", e_curver); + LOG_NOTICE(LOADER, "OS/ABI: %s", Ehdr_OS_ABIToString(e_os_abi).c_str()); + LOG_NOTICE(LOADER, "ABI version: %lld", e_abi_ver); + LOG_NOTICE(LOADER, "Type: %s", Ehdr_TypeToString(e_type).c_str()); + LOG_NOTICE(LOADER, "Machine: %s", Ehdr_MachineToString(e_machine).c_str()); + LOG_NOTICE(LOADER, "Version: %d", e_version); + LOG_NOTICE(LOADER, "Entry point address: 0x%x", e_entry); + LOG_NOTICE(LOADER, "Program headers offset: 0x%08x", e_phoff); + LOG_NOTICE(LOADER, "Section headers offset: 0x%08x", e_shoff); + LOG_NOTICE(LOADER, "Flags: 0x%x", e_flags); + LOG_NOTICE(LOADER, "Size of this header: %d", e_ehsize); + LOG_NOTICE(LOADER, "Size of program headers: %d", e_phentsize); + LOG_NOTICE(LOADER, "Number of program headers: %d", e_phnum); + LOG_NOTICE(LOADER, "Size of section headers: %d", e_shentsize); + LOG_NOTICE(LOADER, "Number of section headers: %d", e_shnum); + LOG_NOTICE(LOADER, "Section header string table index: %d", e_shstrndx); +#endif +} + +void Elf32_Ehdr::Load(vfsStream& f) +{ + e_magic = Read32(f); + e_class = Read8(f); + e_data = Read8(f); + e_curver = Read8(f); + e_os_abi = Read8(f); + + if(IsLittleEndian()) + { + e_abi_ver = Read64LE(f); + e_type = Read16LE(f); + e_machine = Read16LE(f); + e_version = Read32LE(f); + e_entry = Read32LE(f); + e_phoff = Read32LE(f); + e_shoff = Read32LE(f); + e_flags = Read32LE(f); + e_ehsize = Read16LE(f); + e_phentsize = Read16LE(f); + e_phnum = Read16LE(f); + e_shentsize = Read16LE(f); + e_shnum = Read16LE(f); + e_shstrndx = Read16LE(f); + } + else + { + e_abi_ver = Read64(f); + e_type = Read16(f); + e_machine = Read16(f); + e_version = Read32(f); + e_entry = Read32(f); + e_phoff = Read32(f); + e_shoff = Read32(f); + e_flags = Read32(f); + e_ehsize = Read16(f); + e_phentsize = Read16(f); + e_phnum = Read16(f); + e_shentsize = Read16(f); + e_shnum = Read16(f); + e_shstrndx = Read16(f); + } +} + +void Elf32_Desc::Load(vfsStream& f) +{ + revision = Read32(f); + ls_size = Read32(f); + stack_size = Read32(f); + flags = Read32(f); +} + +void Elf32_Desc::LoadLE(vfsStream& f) +{ + revision = Read32LE(f); + ls_size = Read32LE(f); + stack_size = Read32LE(f); + flags = Read32LE(f); +} + +void Elf32_Note::Load(vfsStream& f) +{ + namesz = Read32(f); + descsz = Read32(f); + type = Read32(f); + f.Read(name, 8); + + if (descsz == 32) + { + f.Read(desc_text, descsz); + } + else + { + desc.Load(f); + } +} + +void Elf32_Note::LoadLE(vfsStream& f) +{ + namesz = Read32LE(f); + descsz = Read32LE(f); + type = Read32LE(f); + f.Read(name, 8); + + if (descsz == 32) + { + f.Read(desc_text, descsz); + } + else + { + desc.Load(f); + } +} + +void Elf32_Shdr::Load(vfsStream& f) +{ + sh_name = Read32(f); + sh_type = Read32(f); + sh_flags = Read32(f); + sh_addr = Read32(f); + sh_offset = Read32(f); + sh_size = Read32(f); + sh_link = Read32(f); + sh_info = Read32(f); + sh_addralign = Read32(f); + sh_entsize = Read32(f); +} + +void Elf32_Shdr::LoadLE(vfsStream& f) +{ + sh_name = Read32LE(f); + sh_type = Read32LE(f); + sh_flags = Read32LE(f); + sh_addr = Read32LE(f); + sh_offset = Read32LE(f); + sh_size = Read32LE(f); + sh_link = Read32LE(f); + sh_info = Read32LE(f); + sh_addralign = Read32LE(f); + sh_entsize = Read32LE(f); +} + +void Elf32_Shdr::Show() +{ +#ifdef LOADER_DEBUG + LOG_NOTICE(LOADER, "Name offset: %x", sh_name); + LOG_NOTICE(LOADER, "Type: %d", sh_type); + LOG_NOTICE(LOADER, "Addr: %x", sh_addr); + LOG_NOTICE(LOADER, "Offset: %x", sh_offset); + LOG_NOTICE(LOADER, "Size: %x", sh_size); + LOG_NOTICE(LOADER, "EntSize: %d", sh_entsize); + LOG_NOTICE(LOADER, "Flags: %x", sh_flags); + LOG_NOTICE(LOADER, "Link: %x", sh_link); + LOG_NOTICE(LOADER, "Info: %d", sh_info); + LOG_NOTICE(LOADER, "Address align: %x", sh_addralign); +#endif +} + +void Elf32_Phdr::Load(vfsStream& f) +{ + p_type = Read32(f); + p_offset = Read32(f); + p_vaddr = Read32(f); + p_paddr = Read32(f); + p_filesz = Read32(f); + p_memsz = Read32(f); + p_flags = Read32(f); + p_align = Read32(f); +} + +void Elf32_Phdr::LoadLE(vfsStream& f) +{ + p_type = Read32LE(f); + p_offset = Read32LE(f); + p_vaddr = Read32LE(f); + p_paddr = Read32LE(f); + p_filesz = Read32LE(f); + p_memsz = Read32LE(f); + p_flags = Read32LE(f); + p_align = Read32LE(f); +} + +void Elf32_Phdr::Show() +{ +#ifdef LOADER_DEBUG + LOG_NOTICE(LOADER, "Type: %s", Phdr_TypeToString(p_type).c_str()); + LOG_NOTICE(LOADER, "Offset: 0x%08x", p_offset); + LOG_NOTICE(LOADER, "Virtual address: 0x%08x", p_vaddr); + LOG_NOTICE(LOADER, "Physical address: 0x%08x", p_paddr); + LOG_NOTICE(LOADER, "File size: 0x%08x", p_filesz); + LOG_NOTICE(LOADER, "Memory size: 0x%08x", p_memsz); + LOG_NOTICE(LOADER, "Flags: %s", Phdr_FlagsToString(p_flags).c_str()); + LOG_NOTICE(LOADER, "Align: 0x%x", p_align); +#endif +} + void WriteEhdr(rFile& f, Elf32_Ehdr& ehdr) { Write32(f, ehdr.e_magic); diff --git a/rpcs3/Loader/ELF32.h b/rpcs3/Loader/ELF32.h index 50b5c6bd66..6d600fd82c 100644 --- a/rpcs3/Loader/ELF32.h +++ b/rpcs3/Loader/ELF32.h @@ -23,79 +23,14 @@ struct Elf32_Ehdr u16 e_shnum; u16 e_shstrndx; - void Show() - { -#ifdef LOADER_DEBUG - LOG_NOTICE(LOADER, "Magic: %08x", e_magic); - LOG_NOTICE(LOADER, "Class: %s", "ELF32"); - LOG_NOTICE(LOADER, "Data: %s", Ehdr_DataToString(e_data).c_str()); - LOG_NOTICE(LOADER, "Current Version: %d", e_curver); - LOG_NOTICE(LOADER, "OS/ABI: %s", Ehdr_OS_ABIToString(e_os_abi).c_str()); - LOG_NOTICE(LOADER, "ABI version: %lld", e_abi_ver); - LOG_NOTICE(LOADER, "Type: %s", Ehdr_TypeToString(e_type).c_str()); - LOG_NOTICE(LOADER, "Machine: %s", Ehdr_MachineToString(e_machine).c_str()); - LOG_NOTICE(LOADER, "Version: %d", e_version); - LOG_NOTICE(LOADER, "Entry point address: 0x%x", e_entry); - LOG_NOTICE(LOADER, "Program headers offset: 0x%08x", e_phoff); - LOG_NOTICE(LOADER, "Section headers offset: 0x%08x", e_shoff); - LOG_NOTICE(LOADER, "Flags: 0x%x", e_flags); - LOG_NOTICE(LOADER, "Size of this header: %d", e_ehsize); - LOG_NOTICE(LOADER, "Size of program headers: %d", e_phentsize); - LOG_NOTICE(LOADER, "Number of program headers: %d", e_phnum); - LOG_NOTICE(LOADER, "Size of section headers: %d", e_shentsize); - LOG_NOTICE(LOADER, "Number of section headers: %d", e_shnum); - LOG_NOTICE(LOADER, "Section header string table index: %d", e_shstrndx); -#endif - } + void Show(); bool IsLittleEndian() const { return e_data == 1; } - void Load(vfsStream& f) - { - e_magic = Read32(f); - e_class = Read8(f); - e_data = Read8(f); - e_curver = Read8(f); - e_os_abi = Read8(f); - - if(IsLittleEndian()) - { - e_abi_ver = Read64LE(f); - e_type = Read16LE(f); - e_machine = Read16LE(f); - e_version = Read32LE(f); - e_entry = Read32LE(f); - e_phoff = Read32LE(f); - e_shoff = Read32LE(f); - e_flags = Read32LE(f); - e_ehsize = Read16LE(f); - e_phentsize = Read16LE(f); - e_phnum = Read16LE(f); - e_shentsize = Read16LE(f); - e_shnum = Read16LE(f); - e_shstrndx = Read16LE(f); - } - else - { - e_abi_ver = Read64(f); - e_type = Read16(f); - e_machine = Read16(f); - e_version = Read32(f); - e_entry = Read32(f); - e_phoff = Read32(f); - e_shoff = Read32(f); - e_flags = Read32(f); - e_ehsize = Read16(f); - e_phentsize = Read16(f); - e_phnum = Read16(f); - e_shentsize = Read16(f); - e_shnum = Read16(f); - e_shstrndx = Read16(f); - } - } + void Load(vfsStream& f); bool CheckMagic() const { return e_magic == 0x7F454C46; } u32 GetEntry() const { return e_entry; } @@ -108,21 +43,9 @@ struct Elf32_Desc u32 stack_size; u32 flags; - void Load(vfsStream& f) - { - revision = Read32(f); - ls_size = Read32(f); - stack_size = Read32(f); - flags = Read32(f); - } + void Load(vfsStream& f); - void LoadLE(vfsStream& f) - { - revision = Read32LE(f); - ls_size = Read32LE(f); - stack_size = Read32LE(f); - flags = Read32LE(f); - } + void LoadLE(vfsStream& f); }; struct Elf32_Note @@ -137,39 +60,9 @@ struct Elf32_Note char desc_text[32]; }; - void Load(vfsStream& f) - { - namesz = Read32(f); - descsz = Read32(f); - type = Read32(f); - f.Read(name, 8); + void Load(vfsStream& f); - if(descsz == 32) - { - f.Read(desc_text, descsz); - } - else - { - desc.Load(f); - } - } - - void LoadLE(vfsStream& f) - { - namesz = Read32LE(f); - descsz = Read32LE(f); - type = Read32LE(f); - f.Read(name, 8); - - if(descsz == 32) - { - f.Read(desc_text, descsz); - } - else - { - desc.Load(f); - } - } + void LoadLE(vfsStream& f); }; struct Elf32_Shdr @@ -185,49 +78,11 @@ struct Elf32_Shdr u32 sh_addralign; u32 sh_entsize; - void Load(vfsStream& f) - { - sh_name = Read32(f); - sh_type = Read32(f); - sh_flags = Read32(f); - sh_addr = Read32(f); - sh_offset = Read32(f); - sh_size = Read32(f); - sh_link = Read32(f); - sh_info = Read32(f); - sh_addralign = Read32(f); - sh_entsize = Read32(f); - } + void Load(vfsStream& f); - void LoadLE(vfsStream& f) - { - sh_name = Read32LE(f); - sh_type = Read32LE(f); - sh_flags = Read32LE(f); - sh_addr = Read32LE(f); - sh_offset = Read32LE(f); - sh_size = Read32LE(f); - sh_link = Read32LE(f); - sh_info = Read32LE(f); - sh_addralign = Read32LE(f); - sh_entsize = Read32LE(f); - } + void LoadLE(vfsStream& f); - void Show() - { -#ifdef LOADER_DEBUG - LOG_NOTICE(LOADER, "Name offset: %x", sh_name); - LOG_NOTICE(LOADER, "Type: %d", sh_type); - LOG_NOTICE(LOADER, "Addr: %x", sh_addr); - LOG_NOTICE(LOADER, "Offset: %x", sh_offset); - LOG_NOTICE(LOADER, "Size: %x", sh_size); - LOG_NOTICE(LOADER, "EntSize: %d", sh_entsize); - LOG_NOTICE(LOADER, "Flags: %x", sh_flags); - LOG_NOTICE(LOADER, "Link: %x", sh_link); - LOG_NOTICE(LOADER, "Info: %d", sh_info); - LOG_NOTICE(LOADER, "Address align: %x", sh_addralign); -#endif - } + void Show(); }; struct Elf32_Phdr @@ -241,43 +96,11 @@ struct Elf32_Phdr u32 p_flags; u32 p_align; - void Load(vfsStream& f) - { - p_type = Read32(f); - p_offset = Read32(f); - p_vaddr = Read32(f); - p_paddr = Read32(f); - p_filesz = Read32(f); - p_memsz = Read32(f); - p_flags = Read32(f); - p_align = Read32(f); - } + void Load(vfsStream& f); - void LoadLE(vfsStream& f) - { - p_type = Read32LE(f); - p_offset = Read32LE(f); - p_vaddr = Read32LE(f); - p_paddr = Read32LE(f); - p_filesz = Read32LE(f); - p_memsz = Read32LE(f); - p_flags = Read32LE(f); - p_align = Read32LE(f); - } + void LoadLE(vfsStream& f); - void Show() - { -#ifdef LOADER_DEBUG - LOG_NOTICE(LOADER, "Type: %s", Phdr_TypeToString(p_type).c_str()); - LOG_NOTICE(LOADER, "Offset: 0x%08x", p_offset); - LOG_NOTICE(LOADER, "Virtual address: 0x%08x", p_vaddr); - LOG_NOTICE(LOADER, "Physical address: 0x%08x", p_paddr); - LOG_NOTICE(LOADER, "File size: 0x%08x", p_filesz); - LOG_NOTICE(LOADER, "Memory size: 0x%08x", p_memsz); - LOG_NOTICE(LOADER, "Flags: %s", Phdr_FlagsToString(p_flags).c_str()); - LOG_NOTICE(LOADER, "Align: 0x%x", p_align); -#endif - } + void Show(); }; class ELF32Loader : public LoaderBase diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index f32697a716..42c7a12042 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -2,15 +2,118 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/Cell/PPUThread.h" -#include "Emu/SysCalls/SC_FUNC.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/Static.h" #include "Emu/Cell/PPUInstrTable.h" #include "Emu/SysCalls/ModuleManager.h" #include "ELF64.h" using namespace PPU_instr; +void Elf64_Ehdr::Load(vfsStream& f) +{ + e_magic = Read32(f); + e_class = Read8(f); + e_data = Read8(f); + e_curver = Read8(f); + e_os_abi = Read8(f); + e_abi_ver = Read64(f); + e_type = Read16(f); + e_machine = Read16(f); + e_version = Read32(f); + e_entry = Read64(f); + e_phoff = Read64(f); + e_shoff = Read64(f); + e_flags = Read32(f); + e_ehsize = Read16(f); + e_phentsize = Read16(f); + e_phnum = Read16(f); + e_shentsize = Read16(f); + e_shnum = Read16(f); + e_shstrndx = Read16(f); +} + +void Elf64_Ehdr::Show() +{ +#ifdef LOADER_DEBUG + LOG_NOTICE(LOADER, "Magic: %08x", e_magic); + LOG_NOTICE(LOADER, "Class: %s", "ELF64"); + LOG_NOTICE(LOADER, "Data: %s", Ehdr_DataToString(e_data).c_str()); + LOG_NOTICE(LOADER, "Current Version: %d", e_curver); + LOG_NOTICE(LOADER, "OS/ABI: %s", Ehdr_OS_ABIToString(e_os_abi).c_str()); + LOG_NOTICE(LOADER, "ABI version: %lld", e_abi_ver); + LOG_NOTICE(LOADER, "Type: %s", Ehdr_TypeToString(e_type).c_str()); + LOG_NOTICE(LOADER, "Machine: %s", Ehdr_MachineToString(e_machine).c_str()); + LOG_NOTICE(LOADER, "Version: %d", e_version); + LOG_NOTICE(LOADER, "Entry point address: 0x%08llx", e_entry); + LOG_NOTICE(LOADER, "Program headers offset: 0x%08llx", e_phoff); + LOG_NOTICE(LOADER, "Section headers offset: 0x%08llx", e_shoff); + LOG_NOTICE(LOADER, "Flags: 0x%x", e_flags); + LOG_NOTICE(LOADER, "Size of this header: %d", e_ehsize); + LOG_NOTICE(LOADER, "Size of program headers: %d", e_phentsize); + LOG_NOTICE(LOADER, "Number of program headers: %d", e_phnum); + LOG_NOTICE(LOADER, "Size of section headers: %d", e_shentsize); + LOG_NOTICE(LOADER, "Number of section headers: %d", e_shnum); + LOG_NOTICE(LOADER, "Section header string table index: %d", e_shstrndx); +#endif +} + +void Elf64_Shdr::Load(vfsStream& f) +{ + sh_name = Read32(f); + sh_type = Read32(f); + sh_flags = Read64(f); + sh_addr = Read64(f); + sh_offset = Read64(f); + sh_size = Read64(f); + sh_link = Read32(f); + sh_info = Read32(f); + sh_addralign = Read64(f); + sh_entsize = Read64(f); +} + +void Elf64_Shdr::Show() +{ +#ifdef LOADER_DEBUG + LOG_NOTICE(LOADER, "Name offset: %x", sh_name); + LOG_NOTICE(LOADER, "Type: %d", sh_type); + LOG_NOTICE(LOADER, "Addr: %llx", sh_addr); + LOG_NOTICE(LOADER, "Offset: %llx", sh_offset); + LOG_NOTICE(LOADER, "Size: %llx", sh_size); + LOG_NOTICE(LOADER, "EntSize: %lld", sh_entsize); + LOG_NOTICE(LOADER, "Flags: %llx", sh_flags); + LOG_NOTICE(LOADER, "Link: %x", sh_link); + LOG_NOTICE(LOADER, "Info: %x", sh_info); + LOG_NOTICE(LOADER, "Address align: %llx", sh_addralign); +#endif +} + +void Elf64_Phdr::Load(vfsStream& f) +{ + p_type = Read32(f); + p_flags = Read32(f); + p_offset = Read64(f); + p_vaddr = Read64(f); + p_paddr = Read64(f); + p_filesz = Read64(f); + p_memsz = Read64(f); + p_align = Read64(f); +} + +void Elf64_Phdr::Show() +{ +#ifdef LOADER_DEBUG + LOG_NOTICE(LOADER, "Type: %s", Phdr_TypeToString(p_type).c_str()); + LOG_NOTICE(LOADER, "Offset: 0x%08llx", p_offset); + LOG_NOTICE(LOADER, "Virtual address: 0x%08llx", p_vaddr); + LOG_NOTICE(LOADER, "Physical address: 0x%08llx", p_paddr); + LOG_NOTICE(LOADER, "File size: 0x%08llx", p_filesz); + LOG_NOTICE(LOADER, "Memory size: 0x%08llx", p_memsz); + LOG_NOTICE(LOADER, "Flags: %s", Phdr_FlagsToString(p_flags).c_str()); + LOG_NOTICE(LOADER, "Align: 0x%llx", p_align); +#endif +} + void WriteEhdr(rFile& f, Elf64_Ehdr& ehdr) { Write32(f, ehdr.e_magic); diff --git a/rpcs3/Loader/ELF64.h b/rpcs3/Loader/ELF64.h index f6f6792922..162d153fb7 100644 --- a/rpcs3/Loader/ELF64.h +++ b/rpcs3/Loader/ELF64.h @@ -23,53 +23,9 @@ struct Elf64_Ehdr u16 e_shnum; u16 e_shstrndx; - void Load(vfsStream& f) - { - e_magic = Read32(f); - e_class = Read8(f); - e_data = Read8(f); - e_curver = Read8(f); - e_os_abi = Read8(f); - e_abi_ver = Read64(f); - e_type = Read16(f); - e_machine = Read16(f); - e_version = Read32(f); - e_entry = Read64(f); - e_phoff = Read64(f); - e_shoff = Read64(f); - e_flags = Read32(f); - e_ehsize = Read16(f); - e_phentsize = Read16(f); - e_phnum = Read16(f); - e_shentsize = Read16(f); - e_shnum = Read16(f); - e_shstrndx = Read16(f); - } + void Load(vfsStream& f); - void Show() - { -#ifdef LOADER_DEBUG - LOG_NOTICE(LOADER, "Magic: %08x", e_magic); - LOG_NOTICE(LOADER, "Class: %s", "ELF64"); - LOG_NOTICE(LOADER, "Data: %s", Ehdr_DataToString(e_data).c_str()); - LOG_NOTICE(LOADER, "Current Version: %d", e_curver); - LOG_NOTICE(LOADER, "OS/ABI: %s", Ehdr_OS_ABIToString(e_os_abi).c_str()); - LOG_NOTICE(LOADER, "ABI version: %lld", e_abi_ver); - LOG_NOTICE(LOADER, "Type: %s", Ehdr_TypeToString(e_type).c_str()); - LOG_NOTICE(LOADER, "Machine: %s", Ehdr_MachineToString(e_machine).c_str()); - LOG_NOTICE(LOADER, "Version: %d", e_version); - LOG_NOTICE(LOADER, "Entry point address: 0x%08llx", e_entry); - LOG_NOTICE(LOADER, "Program headers offset: 0x%08llx", e_phoff); - LOG_NOTICE(LOADER, "Section headers offset: 0x%08llx", e_shoff); - LOG_NOTICE(LOADER, "Flags: 0x%x", e_flags); - LOG_NOTICE(LOADER, "Size of this header: %d", e_ehsize); - LOG_NOTICE(LOADER, "Size of program headers: %d", e_phentsize); - LOG_NOTICE(LOADER, "Number of program headers: %d", e_phnum); - LOG_NOTICE(LOADER, "Size of section headers: %d", e_shentsize); - LOG_NOTICE(LOADER, "Number of section headers: %d", e_shnum); - LOG_NOTICE(LOADER, "Section header string table index: %d", e_shstrndx); -#endif - } + void Show(); bool CheckMagic() const { return e_magic == 0x7F454C46; } u32 GetEntry() const { return e_entry; } @@ -88,35 +44,9 @@ struct Elf64_Shdr u64 sh_addralign; u64 sh_entsize; - void Load(vfsStream& f) - { - sh_name = Read32(f); - sh_type = Read32(f); - sh_flags = Read64(f); - sh_addr = Read64(f); - sh_offset = Read64(f); - sh_size = Read64(f); - sh_link = Read32(f); - sh_info = Read32(f); - sh_addralign = Read64(f); - sh_entsize = Read64(f); - } + void Load(vfsStream& f); - void Show() - { -#ifdef LOADER_DEBUG - LOG_NOTICE(LOADER, "Name offset: %x", sh_name); - LOG_NOTICE(LOADER, "Type: %d", sh_type); - LOG_NOTICE(LOADER, "Addr: %llx", sh_addr); - LOG_NOTICE(LOADER, "Offset: %llx", sh_offset); - LOG_NOTICE(LOADER, "Size: %llx", sh_size); - LOG_NOTICE(LOADER, "EntSize: %lld", sh_entsize); - LOG_NOTICE(LOADER, "Flags: %llx", sh_flags); - LOG_NOTICE(LOADER, "Link: %x", sh_link); - LOG_NOTICE(LOADER, "Info: %x", sh_info); - LOG_NOTICE(LOADER, "Address align: %llx", sh_addralign); -#endif - } + void Show(); }; struct Elf64_Phdr @@ -130,31 +60,9 @@ struct Elf64_Phdr u64 p_memsz; u64 p_align; - void Load(vfsStream& f) - { - p_type = Read32(f); - p_flags = Read32(f); - p_offset = Read64(f); - p_vaddr = Read64(f); - p_paddr = Read64(f); - p_filesz = Read64(f); - p_memsz = Read64(f); - p_align = Read64(f); - } + void Load(vfsStream& f); - void Show() - { -#ifdef LOADER_DEBUG - LOG_NOTICE(LOADER, "Type: %s", Phdr_TypeToString(p_type).c_str()); - LOG_NOTICE(LOADER, "Offset: 0x%08llx", p_offset); - LOG_NOTICE(LOADER, "Virtual address: 0x%08llx", p_vaddr); - LOG_NOTICE(LOADER, "Physical address: 0x%08llx", p_paddr); - LOG_NOTICE(LOADER, "File size: 0x%08llx", p_filesz); - LOG_NOTICE(LOADER, "Memory size: 0x%08llx", p_memsz); - LOG_NOTICE(LOADER, "Flags: %s", Phdr_FlagsToString(p_flags).c_str()); - LOG_NOTICE(LOADER, "Align: 0x%llx", p_align); -#endif - } + void Show(); }; class ELF64Loader : public LoaderBase diff --git a/rpcs3/Loader/PKG.cpp b/rpcs3/Loader/PKG.cpp index 2282c7541b..33b31725b3 100644 --- a/rpcs3/Loader/PKG.cpp +++ b/rpcs3/Loader/PKG.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" +#include "Utilities/rMsgBox.h" #include "PKG.h" #include "../Crypto/unpkg.h" diff --git a/rpcs3/Loader/SELF.cpp b/rpcs3/Loader/SELF.cpp index b614267bb2..2357d6e2d7 100644 --- a/rpcs3/Loader/SELF.cpp +++ b/rpcs3/Loader/SELF.cpp @@ -3,6 +3,56 @@ #include "SELF.h" #include "ELF64.h" +void SceHeader::Load(vfsStream& f) +{ + se_magic = Read32(f); + se_hver = Read32(f); + se_flags = Read16(f); + se_type = Read16(f); + se_meta = Read32(f); + se_hsize = Read64(f); + se_esize = Read64(f); +} + +void SceHeader::Show() +{ + LOG_NOTICE(LOADER, "Magic: %08x", se_magic); + LOG_NOTICE(LOADER, "Class: %s", "SELF"); + LOG_NOTICE(LOADER, "hver: 0x%08x", se_hver); + LOG_NOTICE(LOADER, "flags: 0x%04x", se_flags); + LOG_NOTICE(LOADER, "type: 0x%04x", se_type); + LOG_NOTICE(LOADER, "meta: 0x%08x", se_meta); + LOG_NOTICE(LOADER, "hsize: 0x%llx", se_hsize); + LOG_NOTICE(LOADER, "esize: 0x%llx", se_esize); +} + +void SelfHeader::Load(vfsStream& f) +{ + se_htype = Read64(f); + se_appinfooff = Read64(f); + se_elfoff = Read64(f); + se_phdroff = Read64(f); + se_shdroff = Read64(f); + se_secinfoff = Read64(f); + se_sceveroff = Read64(f); + se_controloff = Read64(f); + se_controlsize = Read64(f); + pad = Read64(f); +} + +void SelfHeader::Show() +{ + LOG_NOTICE(LOADER, "header type: 0x%llx", se_htype); + LOG_NOTICE(LOADER, "app info offset: 0x%llx", se_appinfooff); + LOG_NOTICE(LOADER, "elf offset: 0x%llx", se_elfoff); + LOG_NOTICE(LOADER, "program header offset: 0x%llx", se_phdroff); + LOG_NOTICE(LOADER, "section header offset: 0x%llx", se_shdroff); + LOG_NOTICE(LOADER, "section info offset: 0x%llx", se_secinfoff); + LOG_NOTICE(LOADER, "sce version offset: 0x%llx", se_sceveroff); + LOG_NOTICE(LOADER, "control info offset: 0x%llx", se_controloff); + LOG_NOTICE(LOADER, "control info size: 0x%llx", se_controlsize); +} + SELFLoader::SELFLoader(vfsStream& f) : self_f(f) , LoaderBase() diff --git a/rpcs3/Loader/SELF.h b/rpcs3/Loader/SELF.h index 6058456026..8c3cb70d51 100644 --- a/rpcs3/Loader/SELF.h +++ b/rpcs3/Loader/SELF.h @@ -11,28 +11,9 @@ struct SceHeader u64 se_hsize; u64 se_esize; - void Load(vfsStream& f) - { - se_magic = Read32(f); - se_hver = Read32(f); - se_flags = Read16(f); - se_type = Read16(f); - se_meta = Read32(f); - se_hsize = Read64(f); - se_esize = Read64(f); - } + void Load(vfsStream& f); - void Show() - { - LOG_NOTICE(LOADER, "Magic: %08x", se_magic); - LOG_NOTICE(LOADER, "Class: %s", "SELF"); - LOG_NOTICE(LOADER, "hver: 0x%08x", se_hver); - LOG_NOTICE(LOADER, "flags: 0x%04x", se_flags); - LOG_NOTICE(LOADER, "type: 0x%04x", se_type); - LOG_NOTICE(LOADER, "meta: 0x%08x", se_meta); - LOG_NOTICE(LOADER, "hsize: 0x%llx", se_hsize); - LOG_NOTICE(LOADER, "esize: 0x%llx", se_esize); - } + void Show(); bool CheckMagic() const { return se_magic == 0x53434500; } }; @@ -50,32 +31,9 @@ struct SelfHeader u64 se_controlsize; u64 pad; - void Load(vfsStream& f) - { - se_htype = Read64(f); - se_appinfooff = Read64(f); - se_elfoff = Read64(f); - se_phdroff = Read64(f); - se_shdroff = Read64(f); - se_secinfoff = Read64(f); - se_sceveroff = Read64(f); - se_controloff = Read64(f); - se_controlsize = Read64(f); - pad = Read64(f); - } + void Load(vfsStream& f); - void Show() - { - LOG_NOTICE(LOADER, "header type: 0x%llx", se_htype); - LOG_NOTICE(LOADER, "app info offset: 0x%llx", se_appinfooff); - LOG_NOTICE(LOADER, "elf offset: 0x%llx", se_elfoff); - LOG_NOTICE(LOADER, "program header offset: 0x%llx", se_phdroff); - LOG_NOTICE(LOADER, "section header offset: 0x%llx", se_shdroff); - LOG_NOTICE(LOADER, "section info offset: 0x%llx", se_secinfoff); - LOG_NOTICE(LOADER, "sce version offset: 0x%llx", se_sceveroff); - LOG_NOTICE(LOADER, "control info offset: 0x%llx", se_controloff); - LOG_NOTICE(LOADER, "control info size: 0x%llx", se_controlsize); - } + void Show(); }; class SELFLoader : public LoaderBase diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp index b19f0016d7..35e3b7bda0 100644 --- a/rpcs3/Loader/TROPUSR.cpp +++ b/rpcs3/Loader/TROPUSR.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" #include "Utilities/rXml.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "TROPUSR.h" @@ -212,7 +211,8 @@ bool TROPUSRLoader::Close() { if (m_file && m_file->Close()) { - safe_delete(m_file); + delete m_file; + m_file = nullptr; return true; } return false; diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index 87427a4326..2127e4acf6 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/FS/vfsFile.h" #include "TRP.h" diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 7ce030b02a..3ed057f908 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -93,6 +93,7 @@ + @@ -354,6 +355,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 271fa80725..b4afa1ee91 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -605,6 +605,9 @@ Utilities + + Emu\SysCalls + @@ -1155,9 +1158,12 @@ Emu\SysCalls\Modules - + Emu + + Emu\SysCalls\Modules + \ No newline at end of file diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 4ea8af5587..f6190d5a82 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -1,6 +1,4 @@ #include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "rpcs3.h" #include "Ini.h" diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index ff93662fa2..35cd772d9c 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -43,6 +43,8 @@ #include #include +#include "Utilities/GNU.h" + typedef unsigned int uint; typedef uint8_t u8; @@ -55,14 +57,203 @@ typedef int16_t s16; typedef int32_t s32; typedef int64_t s64; +union u128 +{ + struct + { + u64 hi; + u64 lo; + }; + + u64 _u64[2]; + u32 _u32[4]; + u16 _u16[8]; + u8 _u8[16]; + + operator u64() const { return _u64[0]; } + operator u32() const { return _u32[0]; } + operator u16() const { return _u16[0]; } + operator u8() const { return _u8[0]; } + + operator bool() const { return _u64[0] != 0 || _u64[1] != 0; } + + static u128 From128(u64 hi, u64 lo) + { + u128 ret = { hi, lo }; + return ret; + } + + static u128 From64(u64 src) + { + u128 ret = { 0, src }; + return ret; + } + + static u128 From32(u32 src) + { + u128 ret; + ret._u32[0] = src; + ret._u32[1] = 0; + ret._u32[2] = 0; + ret._u32[3] = 0; + return ret; + } + + static u128 FromBit(u32 bit) + { + u128 ret; + if (bit < 64) + { + ret.hi = 0; + ret.lo = (u64)1 << bit; + } + else if (bit < 128) + { + ret.hi = (u64)1 << (bit - 64); + ret.lo = 0; + } + else + { + ret.hi = 0; + ret.lo = 0; + } + return ret; + } + + bool operator == (const u128& right) const + { + return (lo == right.lo) && (hi == right.hi); + } + + bool operator != (const u128& right) const + { + return (lo != right.lo) || (hi != right.hi); + } + + u128 operator | (const u128& right) const + { + return From128(hi | right.hi, lo | right.lo); + } + + u128 operator & (const u128& right) const + { + return From128(hi & right.hi, lo & right.lo); + } + + u128 operator ^ (const u128& right) const + { + return From128(hi ^ right.hi, lo ^ right.lo); + } + + u128 operator ~ () const + { + return From128(~hi, ~lo); + } + + static __forceinline u128 byteswap(const u128 val) + { + u128 ret; + ret.lo = _byteswap_uint64(val.hi); + ret.hi = _byteswap_uint64(val.lo); + return ret; + } +}; + +union s128 +{ + struct + { + s64 hi; + s64 lo; + }; + + u64 _i64[2]; + u32 _i32[4]; + u16 _i16[8]; + u8 _i8[16]; + + operator s64() const { return _i64[0]; } + operator s32() const { return _i32[0]; } + operator s16() const { return _i16[0]; } + operator s8() const { return _i8[0]; } + + operator bool() const { return _i64[0] != 0 || _i64[1] != 0; } + + static s128 From64(s64 src) + { + s128 ret = { src, 0 }; + return ret; + } + + static s128 From32(s32 src) + { + s128 ret; + ret._i32[0] = src; + ret._i32[1] = 0; + ret.hi = 0; + return ret; + } + + bool operator == (const s128& right) const + { + return (lo == right.lo) && (hi == right.hi); + } + + bool operator != (const s128& right) const + { + return (lo != right.lo) || (hi != right.hi); + } +}; + +//TODO: SSE style +/* +struct u128 +{ + __m128 m_val; + + u128 GetValue128() + { + u128 ret; + _mm_store_ps( (float*)&ret, m_val ); + return ret; + } + + u64 GetValue64() + { + u64 ret; + _mm_store_ps( (float*)&ret, m_val ); + return ret; + } + + u32 GetValue32() + { + u32 ret; + _mm_store_ps( (float*)&ret, m_val ); + return ret; + } + + u16 GetValue16() + { + u16 ret; + _mm_store_ps( (float*)&ret, m_val ); + return ret; + } + + u8 GetValue8() + { + u8 ret; + _mm_store_ps( (float*)&ret, m_val ); + return ret; + } +}; +*/ + +#define AlignAddr(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1)) + #include "Utilities/StrFmt.h" -#include "Utilities/Log.h" #include "Utilities/BEType.h" #include "Utilities/rFile.h" -#include "Utilities/rTime.h" -#include "Utilities/rMsgBox.h" #include "Utilities/Thread.h" -#include "Utilities/Timer.h" #include "Emu/IdManager.h" #define _PRGNAME_ "RPCS3"