diff --git a/.gitignore b/.gitignore index 00fb6fe69b..559dedada0 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,6 @@ rpcs3/x64/* .DS_Store rpcs3/Emu/SysCalls/Modules/prx_*.h + +/CMakeFiles/ +CMakeCache.txt diff --git a/Utilities/BEType.h b/Utilities/BEType.h index d478e04d92..14fc479a04 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -1,6 +1,6 @@ #pragma once -#define IS_LE_MACHINE +#define IS_LE_MACHINE // only draft union u128 { @@ -165,13 +165,6 @@ union u128 } _bit; - //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 from64(u64 _0, u64 _1 = 0) { u128 ret; @@ -334,26 +327,6 @@ union u128 return (_u64[0] != right._u64[0]) || (_u64[1] != right._u64[1]); } - force_inline u128 operator | (const u128& right) const - { - return fromV(_mm_or_si128(vi, right.vi)); - } - - force_inline u128 operator & (const u128& right) const - { - return fromV(_mm_and_si128(vi, right.vi)); - } - - force_inline u128 operator ^ (const u128& right) const - { - return fromV(_mm_xor_si128(vi, right.vi)); - } - - u128 operator ~ () const - { - return from64(~_u64[0], ~_u64[1]); - } - force_inline bool is_any_1() const // check if any bit is 1 { return _u64[0] || _u64[1]; @@ -381,14 +354,31 @@ union u128 static force_inline u128 byteswap(const u128 val) { - u128 ret; - ret._u64[0] = _byteswap_uint64(val._u64[1]); - ret._u64[1] = _byteswap_uint64(val._u64[0]); - return ret; + return fromV(_mm_shuffle_epi8(val.vi, _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))); } }; -static_assert(__alignof(u128) == 16 && sizeof(u128) == 16, "Wrong u128 size or alignment"); +CHECK_SIZE_ALIGN(u128, 16, 16); + +inline u128 operator |(const u128& left, const u128& right) +{ + return u128::fromV(_mm_or_si128(left.vi, right.vi)); +} + +inline u128 operator &(const u128& left, const u128& right) +{ + return u128::fromV(_mm_and_si128(left.vi, right.vi)); +} + +inline u128 operator ^(const u128& left, const u128& right) +{ + return u128::fromV(_mm_xor_si128(left.vi, right.vi)); +} + +inline u128 operator ~(const u128& other) +{ + return u128::from64(~other._u64[0], ~other._u64[1]); +} static force_inline u128 sync_val_compare_and_swap(volatile u128* dest, u128 comp, u128 exch) { @@ -446,34 +436,16 @@ static force_inline u128 sync_fetch_and_xor(volatile u128* dest, u128 value) } } -#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 force_inline u8 to_be(const T& src) - { - return (u8&)src; - } - - static force_inline T from_be(const u8 src) - { - return (T&)src; - } -}; +template struct se_t; template struct se_t { - static force_inline u16 to_be(const T& src) + static force_inline u16 to(const T& src) { return _byteswap_ushort((u16&)src); } - static force_inline T from_be(const u16 src) + static force_inline T from(const u16 src) { const u16 res = _byteswap_ushort(src); return (T&)res; @@ -482,12 +454,12 @@ template struct se_t template struct se_t { - static force_inline u32 to_be(const T& src) + static force_inline u32 to(const T& src) { return _byteswap_ulong((u32&)src); } - static force_inline T from_be(const u32 src) + static force_inline T from(const u32 src) { const u32 res = _byteswap_ulong(src); return (T&)res; @@ -496,12 +468,12 @@ template struct se_t template struct se_t { - static force_inline u64 to_be(const T& src) + static force_inline u64 to(const T& src) { return _byteswap_uint64((u64&)src); } - static force_inline T from_be(const u64 src) + static force_inline T from(const u64 src) { const u64 res = _byteswap_uint64(src); return (T&)res; @@ -510,28 +482,25 @@ template struct se_t template struct se_t { - static force_inline u128 to_be(const T& src) + static force_inline u128 to(const T& src) { return u128::byteswap((u128&)src); } - static force_inline T from_be(const u128& src) + static force_inline T from(const u128& src) { const u128 res = u128::byteswap(src); return (T&)res; } }; -template struct const_se_t; - -template struct const_se_t -{ - static const u8 value = _value; -}; +template struct const_se_t; template struct const_se_t { - static const u16 value = ((_value >> 8) & 0xff) | ((_value << 8) & 0xff00); + static const u16 value = + ((_value >> 8) & 0x00ff) | + ((_value << 8) & 0xff00); }; template struct const_se_t @@ -583,22 +552,9 @@ template struct be_storage template using be_storage_t = typename be_storage::type; -template -struct be_t +template class be_t { - using type = std::remove_cv_t; - using stype = be_storage_t>; - - stype m_data; - - static_assert(!std::is_class::value, "be_t<> error: invalid type (class or structure)"); - static_assert(!std::is_union::value || std::is_same::value, "be_t<> error: invalid type (union)"); - static_assert(!std::is_pointer::value, "be_t<> error: invalid type (pointer)"); - static_assert(!std::is_reference::value, "be_t<> error: invalid type (reference)"); - static_assert(!std::is_array::value, "be_t<> error: invalid type (array)"); - static_assert(__alignof(type) == __alignof(stype), "be_t<> error: unexpected alignment"); - -private: + // TODO (complicated cases like int-float conversions are not handled correctly) template struct _convert { @@ -624,78 +580,76 @@ private: { static force_inline be_t& func(Tfrom& be_value) { - Tto res = be_value >> ((sizeof(Tfrom)-sizeof(Tto)) * 8); + Tto res = be_value >> ((sizeof(Tfrom) - sizeof(Tto)) * 8); return (be_t&)res; } }; - const stype& ToBE() const - { - return m_data; - } - - type ToLE() const - { - return se_t::from_be(m_data); - } - - void FromBE(const stype& value) - { - m_data = value; - } - - void FromLE(const type& value) - { - m_data = se_t::to_be(value); - } - - static be_t MakeFromLE(const type& value) - { - stype data = se_t::to_be(value); - return (be_t&)data; - } - - static be_t MakeFromBE(const stype& value) - { - return (be_t&)value; - } - public: - //make be_t from current machine byte ordering - static be_t make(const type& value) - { + using type = std::remove_cv_t; + using stype = be_storage_t>; + #ifdef IS_LE_MACHINE - return MakeFromLE(value); + stype m_data; // don't access directly #else - return MakeFromBE(value); + type m_data; // don't access directly #endif + + static_assert(!std::is_class::value, "be_t<> error: invalid type (class or structure)"); + static_assert(!std::is_union::value || std::is_same::value, "be_t<> error: invalid type (union)"); + static_assert(!std::is_pointer::value, "be_t<> error: invalid type (pointer)"); + static_assert(!std::is_reference::value, "be_t<> error: invalid type (reference)"); + static_assert(!std::is_array::value, "be_t<> error: invalid type (array)"); + static_assert(!std::is_enum::value, "be_t<> error: invalid type (enumeration), use integral type instead"); + static_assert(__alignof(type) == __alignof(stype), "be_t<> error: unexpected alignment"); + + be_t() = default; + + be_t(const be_t&) = default; + + template::value>> be_t(const type& value) +#ifdef IS_LE_MACHINE + : m_data(se_t::to(value)) +#else + : m_data(value) +#endif + { } - //get value in current machine byte ordering + // get value in current machine byte ordering force_inline type value() const { #ifdef IS_LE_MACHINE - return ToLE(); + return se_t::from(m_data); #else - return ToBE(); + return m_data; #endif } + // get underlying data without any byte order manipulation const stype& data() const { - return ToBE(); +#ifdef IS_LE_MACHINE + return m_data; +#else + return reinterpret_cast(m_data); +#endif } - be_t& operator =(const be_t& value) = default; + be_t& operator =(const be_t&) = default; template std::enable_if_t::value, be_t&> operator =(const CT& value) { - m_data = se_t::to_be(value); +#ifdef IS_LE_MACHINE + m_data = se_t::to(value); +#else + m_data = value; +#endif return *this; } - //template::value>> operator CT() const + //template::value>> operator CT() const //{ // return value(); //} @@ -706,58 +660,69 @@ public: } // conversion to another be_t type - template operator be_t() const - { - return be_t::make(value()); + //template operator be_t() const + //{ + // return value(); + // //return _convert sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data); + //} - // TODO (complicated cases like int-float conversions are not handled correctly) - //return _convert sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data); - } + template be_t& operator +=(const T1& right) { return *this = value() + right; } + template be_t& operator -=(const T1& right) { return *this = value() - right; } + template be_t& operator *=(const T1& right) { return *this = value() * right; } + template be_t& operator /=(const T1& right) { return *this = value() / right; } + template be_t& operator %=(const T1& right) { return *this = value() % right; } - template be_t& operator += (T1 right) { return *this = value() + right; } - template be_t& operator -= (T1 right) { return *this = value() - right; } - template be_t& operator *= (T1 right) { return *this = value() * right; } - template be_t& operator /= (T1 right) { return *this = value() / right; } - template be_t& operator %= (T1 right) { return *this = value() % right; } - template be_t& operator &= (T1 right) { return *this = value() & right; } - template be_t& operator |= (T1 right) { return *this = value() | right; } - template be_t& operator ^= (T1 right) { return *this = value() ^ right; } - template be_t& operator <<= (T1 right) { return *this = value() << right; } - template be_t& operator >>= (T1 right) { return *this = value() >> right; } + template be_t& operator <<=(const T1& right) { return *this = value() << right; } + template be_t& operator >>=(const T1& right) { return *this = value() >> right; } - template be_t& operator += (const be_t& right) { return *this = ToLE() + right.ToLE(); } - template be_t& operator -= (const be_t& right) { return *this = ToLE() - right.ToLE(); } - template be_t& operator *= (const be_t& right) { return *this = ToLE() * right.ToLE(); } - template be_t& operator /= (const be_t& right) { return *this = ToLE() / right.ToLE(); } - template be_t& operator %= (const be_t& right) { return *this = ToLE() % right.ToLE(); } - template be_t& operator &= (const be_t& right) { return *this = ToBE() & right.ToBE(); } - template be_t& operator |= (const be_t& right) { return *this = ToBE() | right.ToBE(); } - template be_t& operator ^= (const be_t& right) { return *this = ToBE() ^ right.ToBE(); } + template be_t& operator &=(const T1& right) { return m_data &= be_t(right).data(), *this; } + template be_t& operator |=(const T1& right) { return m_data |= be_t(right).data(), *this; } + template be_t& operator ^=(const T1& right) { return m_data ^= be_t(right).data(), *this; } - template be_t operator & (const be_t& right) const { be_t res; res.FromBE(ToBE() & right.ToBE()); return res; } - template be_t operator | (const be_t& right) const { be_t res; res.FromBE(ToBE() | right.ToBE()); return res; } - template be_t operator ^ (const be_t& right) const { be_t res; res.FromBE(ToBE() ^ right.ToBE()); return res; } - - template bool operator == (T1 right) const { return (T1)ToLE() == right; } - template bool operator != (T1 right) const { return !(*this == right); } - template bool operator > (T1 right) const { return (T1)ToLE() > right; } - template bool operator < (T1 right) const { return (T1)ToLE() < right; } - template bool operator >= (T1 right) const { return (T1)ToLE() >= right; } - template bool operator <= (T1 right) const { return (T1)ToLE() <= right; } - - template bool operator == (const be_t& right) const { return ToBE() == right.ToBE(); } - template bool operator != (const be_t& right) const { return !(*this == right); } - template bool operator > (const be_t& right) const { return (T1)ToLE() > right.ToLE(); } - template bool operator < (const be_t& right) const { return (T1)ToLE() < right.ToLE(); } - template bool operator >= (const be_t& right) const { return (T1)ToLE() >= right.ToLE(); } - template bool operator <= (const be_t& right) const { return (T1)ToLE() <= right.ToLE(); } - - be_t operator++ (int) { be_t res = *this; *this += 1; return res; } - be_t operator-- (int) { be_t res = *this; *this -= 1; return res; } - be_t& operator++ () { *this += 1; return *this; } - be_t& operator-- () { *this -= 1; return *this; } + be_t operator ++(int) { be_t res = *this; *this += 1; return res; } + be_t operator --(int) { be_t res = *this; *this -= 1; return res; } + be_t& operator ++() { *this += 1; return *this; } + be_t& operator --() { *this -= 1; return *this; } }; +template inline std::enable_if_t::value && std::is_integral::value, bool> operator ==(const be_t& left, const be_t& right) +{ + return left.data() == right.data(); +} + +template inline std::enable_if_t::value && std::is_integral::value, bool> operator !=(const be_t& left, const be_t& right) +{ + return left.data() != right.data(); +} + +template inline std::enable_if_t::value && std::is_integral::value, be_t> operator &(const be_t& left, const be_t& right) +{ + be_t result; + result.m_data = left.data() & right.data(); + return result; +} + +template inline std::enable_if_t::value && std::is_integral::value, be_t> operator |(const be_t& left, const be_t& right) +{ + be_t result; + result.m_data = left.data() | right.data(); + return result; +} + +template inline std::enable_if_t::value && std::is_integral::value, be_t> operator ^(const be_t& left, const be_t& right) +{ + be_t result; + result.m_data = left.data() ^ right.data(); + return result; +} + +template inline std::enable_if_t::value, be_t> operator ~(const be_t& arg) +{ + be_t result; + result.m_data = ~arg.data(); + return result; +} + template struct is_be_t : public std::integral_constant { }; @@ -801,98 +766,77 @@ template<> struct to_be { using type = char; }; template<> struct to_be { using type = u8; }; template<> struct to_be { using type = s8; }; -template struct _se : public const_se_t {}; -template struct _se, T1, value> : public const_se_t {}; - -//#define se(t, x) _se::value -#define se16(x) _se::value -#define se32(x) _se::value -#define se64(x) _se::value - -template -struct convert_le_be_t -{ - static Tto func(Tfrom value) - { - return (Tto)value; - } -}; - -template -struct convert_le_be_t, Tfrom> -{ - static be_t func(Tfrom value) - { - return be_t::make(value); - } -}; - -template -struct convert_le_be_t, be_t> -{ - static be_t func(be_t value) - { - return value; - } -}; - -template -struct convert_le_be_t> -{ - static Tto func(be_t value) - { - return value.value(); - } -}; - -template -force_inline Tto convert_le_be(Tfrom value) -{ - return convert_le_be_t::func(value); -} - -template -force_inline void convert_le_be(Tto& dst, Tfrom src) -{ - dst = convert_le_be_t::func(src); -} - -template struct le_t +template class le_t { +public: using type = std::remove_cv_t; using stype = be_storage_t>; - stype m_data; + type m_data; // don't access directly + + static_assert(!std::is_class::value, "le_t<> error: invalid type (class or structure)"); + static_assert(!std::is_union::value || std::is_same::value, "le_t<> error: invalid type (union)"); + static_assert(!std::is_pointer::value, "le_t<> error: invalid type (pointer)"); + static_assert(!std::is_reference::value, "le_t<> error: invalid type (reference)"); + static_assert(!std::is_array::value, "le_t<> error: invalid type (array)"); + static_assert(!std::is_enum::value, "le_t<> error: invalid type (enumeration), use integral type instead"); + static_assert(__alignof(type) == __alignof(stype), "le_t<> error: unexpected alignment"); + + le_t() = default; + + le_t(const le_t&) = default; + + template::value>> le_t(const type& value) + : m_data(value) + { + } type value() const { - return reinterpret_cast(m_data); + return m_data; + } + + const stype& data() const + { + return reinterpret_cast(m_data); } le_t& operator =(const le_t& value) = default; template std::enable_if_t::value, le_t&> operator =(const CT& value) { - m_data = reinterpret_cast(value); - + m_data = value; return *this; } - //template operator std::enable_if_t::value, CT>() const - //{ - // return value(); - //} - operator type() const { return value(); } // conversion to another le_t type - //template operator const le_t() const + //template operator le_t() const //{ - // return le_t::make(value()); + // return value(); //} + + template le_t& operator +=(const T1& right) { return *this = value() + right; } + template le_t& operator -=(const T1& right) { return *this = value() - right; } + template le_t& operator *=(const T1& right) { return *this = value() * right; } + template le_t& operator /=(const T1& right) { return *this = value() / right; } + template le_t& operator %=(const T1& right) { return *this = value() % right; } + + template le_t& operator <<=(const T1& right) { return *this = value() << right; } + template le_t& operator >>=(const T1& right) { return *this = value() >> right; } + + template le_t& operator &=(const T1& right) { return m_data &= le_t(right).data(), *this; } + template le_t& operator |=(const T1& right) { return m_data |= le_t(right).data(), *this; } + template le_t& operator ^=(const T1& right) { return m_data ^= le_t(right).data(), *this; } + + le_t operator ++(int) { le_t res = *this; *this += 1; return res; } + le_t operator --(int) { le_t res = *this; *this -= 1; return res; } + le_t& operator ++() { *this += 1; return *this; } + le_t& operator --() { *this -= 1; return *this; } }; template struct is_le_t : public std::integral_constant diff --git a/Utilities/File.cpp b/Utilities/File.cpp index d79cdb2718..4f0dcacd89 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -9,50 +9,44 @@ static_assert(fs::file::null == intptr_t(INVALID_HANDLE_VALUE) && fs::dir::null == fs::file::null, "Check fs::file::null definition"); -std::unique_ptr ConvertUTF8ToWChar(const std::string& source) +std::unique_ptr to_wchar(const std::string& source) { - const size_t length = source.size() + 1; // size + null terminator + const auto length = source.size() + 1; // size + null terminator - const int size = source.size() < INT_MAX ? static_cast(length) : throw std::length_error(__FUNCTION__); + const int size = source.size() < INT_MAX ? static_cast(length) : throw EXCEPTION("Invalid source length (0x%llx)", source.size()); std::unique_ptr buffer(new wchar_t[length]); // allocate buffer assuming that length is the max possible size if (!MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get(), size)) { - LOG_ERROR(GENERAL, "ConvertUTF8ToWChar(source='%s') failed: 0x%llx", source, GET_API_ERROR); - throw __FUNCTION__; + throw EXCEPTION("System error 0x%x", GetLastError()); } return buffer; } -std::string ConvertWCharToUTF8(const wchar_t* source) +void to_utf8(std::string& result, const wchar_t* source) { const int length = lstrlenW(source); // source length - std::string result; - if (length == 0) { - return result; + return result.clear(); } const int size = WideCharToMultiByte(CP_UTF8, 0, source, length, NULL, 0, NULL, NULL); // output size if (size <= 0) { - LOG_ERROR(GENERAL, "ConvertWCharToUTF8(length=%d) failed: 0x%llx", length, GET_API_ERROR); - throw __FUNCTION__; + throw EXCEPTION("System error 0x%x", GetLastError()); } result.resize(size); if (!WideCharToMultiByte(CP_UTF8, 0, source, length, &result.front(), size, NULL, NULL)) { - throw __FUNCTION__; + throw EXCEPTION("System error 0x%x", GetLastError()); } - - return result; } time_t to_time_t(const ULARGE_INTEGER& ft) @@ -81,7 +75,7 @@ time_t to_time_t(const FILETIME& ft) bool truncate_file(const std::string& file, u64 length) { // open the file - const auto handle = CreateFileW(ConvertUTF8ToWChar(file).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + const auto handle = CreateFileW(to_wchar(file).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { @@ -124,7 +118,7 @@ bool fs::stat(const std::string& path, stat_t& info) { #ifdef _WIN32 WIN32_FILE_ATTRIBUTE_DATA attrs; - if (!GetFileAttributesExW(ConvertUTF8ToWChar(path).get(), GetFileExInfoStandard, &attrs)) + if (!GetFileAttributesExW(to_wchar(path).get(), GetFileExInfoStandard, &attrs)) { return false; } @@ -156,7 +150,7 @@ bool fs::stat(const std::string& path, stat_t& info) bool fs::exists(const std::string& path) { #ifdef _WIN32 - return GetFileAttributesW(ConvertUTF8ToWChar(path).get()) != 0xFFFFFFFF; + return GetFileAttributesW(to_wchar(path).get()) != 0xFFFFFFFF; #else struct stat buffer; return stat(path.c_str(), &buffer) == 0; @@ -167,7 +161,7 @@ bool fs::is_file(const std::string& file) { #ifdef _WIN32 DWORD attrs; - if ((attrs = GetFileAttributesW(ConvertUTF8ToWChar(file).get())) == INVALID_FILE_ATTRIBUTES) + if ((attrs = GetFileAttributesW(to_wchar(file).get())) == INVALID_FILE_ATTRIBUTES) { return false; } @@ -188,7 +182,7 @@ bool fs::is_dir(const std::string& dir) { #ifdef _WIN32 DWORD attrs; - if ((attrs = GetFileAttributesW(ConvertUTF8ToWChar(dir).get())) == INVALID_FILE_ATTRIBUTES) + if ((attrs = GetFileAttributesW(to_wchar(dir).get())) == INVALID_FILE_ATTRIBUTES) { return false; } @@ -208,7 +202,7 @@ bool fs::is_dir(const std::string& dir) bool fs::create_dir(const std::string& dir) { #ifdef _WIN32 - if (!CreateDirectoryW(ConvertUTF8ToWChar(dir).get(), NULL)) + if (!CreateDirectoryW(to_wchar(dir).get(), NULL)) #else if (mkdir(dir.c_str(), 0777)) #endif @@ -265,7 +259,7 @@ bool fs::create_path(const std::string& path) bool fs::remove_dir(const std::string& dir) { #ifdef _WIN32 - if (!RemoveDirectoryW(ConvertUTF8ToWChar(dir).get())) + if (!RemoveDirectoryW(to_wchar(dir).get())) #else if (rmdir(dir.c_str())) #endif @@ -279,9 +273,8 @@ bool fs::remove_dir(const std::string& dir) bool fs::rename(const std::string& from, const std::string& to) { - // TODO: Deal with case-sensitivity #ifdef _WIN32 - if (!MoveFileW(ConvertUTF8ToWChar(from).get(), ConvertUTF8ToWChar(to).get())) + if (!MoveFileW(to_wchar(from).get(), to_wchar(to).get())) #else if (rename(from.c_str(), to.c_str())) #endif @@ -332,7 +325,7 @@ int OSCopyFile(const char* source, const char* destination, bool overwrite) bool fs::copy_file(const std::string& from, const std::string& to, bool overwrite) { #ifdef _WIN32 - if (!CopyFileW(ConvertUTF8ToWChar(from).get(), ConvertUTF8ToWChar(to).get(), !overwrite)) + if (!CopyFileW(to_wchar(from).get(), to_wchar(to).get(), !overwrite)) #else if (OSCopyFile(from.c_str(), to.c_str(), overwrite)) #endif @@ -347,7 +340,7 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit bool fs::remove_file(const std::string& file) { #ifdef _WIN32 - if (!DeleteFileW(ConvertUTF8ToWChar(file).get())) + if (!DeleteFileW(to_wchar(file).get())) #else if (unlink(file.c_str())) #endif @@ -388,7 +381,7 @@ fs::file::~file() bool fs::file::open(const std::string& filename, u32 mode) { - this->~file(); + this->close(); #ifdef _WIN32 DWORD access = 0; @@ -424,7 +417,7 @@ bool fs::file::open(const std::string& filename, u32 mode) return false; } - m_fd = (intptr_t)CreateFileW(ConvertUTF8ToWChar(filename).get(), access, FILE_SHARE_READ, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); + m_fd = (intptr_t)CreateFileW(to_wchar(filename).get(), access, FILE_SHARE_READ, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); #else int flags = 0; @@ -537,31 +530,35 @@ bool fs::file::close() u64 fs::file::read(void* buffer, u64 count) const { + const int size = count <= INT_MAX ? static_cast(count) : throw EXCEPTION("Invalid count (0x%llx)", count); + #ifdef _WIN32 DWORD nread; - if (!ReadFile((HANDLE)m_fd, buffer, count, &nread, NULL)) + if (!ReadFile((HANDLE)m_fd, buffer, size, &nread, NULL)) { return -1; } return nread; #else - return ::read(m_fd, buffer, count); + return ::read(m_fd, buffer, size); #endif } u64 fs::file::write(const void* buffer, u64 count) const { + const int size = count <= INT_MAX ? static_cast(count) : throw EXCEPTION("Invalid count (0x%llx)", count); + #ifdef _WIN32 DWORD nwritten; - if (!WriteFile((HANDLE)m_fd, buffer, count, &nwritten, NULL)) + if (!WriteFile((HANDLE)m_fd, buffer, size, &nwritten, NULL)) { return -1; } return nwritten; #else - return ::write(m_fd, buffer, count); + return ::write(m_fd, buffer, size); #endif } @@ -631,7 +628,7 @@ void fs::dir::import(handle_type dd, const std::string& path) m_dd = dd; #ifdef _WIN32 - m_path = ConvertUTF8ToWChar(path); + m_path = to_wchar(path); #else m_path.reset(new char[path.size() + 1]); memcpy(m_path.get(), path.c_str(), path.size() + 1); @@ -659,7 +656,7 @@ bool fs::dir::open(const std::string& dirname) } #ifdef _WIN32 - m_path = ConvertUTF8ToWChar(dirname + "/*"); + m_path = to_wchar(dirname + "/*"); #else m_path.reset(new char[dirname.size() + 1]); memcpy(m_path.get(), dirname.c_str(), dirname.size() + 1); @@ -723,7 +720,7 @@ bool fs::dir::get_first(std::string& name, stat_t& info) return false; } - name = ConvertWCharToUTF8(found.cFileName); + to_utf8(name, found.cFileName); info.is_directory = (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; @@ -755,7 +752,7 @@ bool fs::dir::get_next(std::string& name, stat_t& info) return false; } - name = ConvertWCharToUTF8(found.cFileName); + to_utf8(name, found.cFileName); info.is_directory = (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; diff --git a/Utilities/GNU.h b/Utilities/GNU.h index 64a45acb63..00a80a57fb 100644 --- a/Utilities/GNU.h +++ b/Utilities/GNU.h @@ -2,6 +2,11 @@ #include +// temporarily (until noexcept is available); use `noexcept(true)` instead of `noexcept` if necessary +#if defined(_MSC_VER) && _MSC_VER <= 1800 +#define noexcept _NOEXCEPT_OP +#endif + #if defined(_MSC_VER) #define thread_local __declspec(thread) #elif __APPLE__ @@ -26,21 +31,11 @@ #define force_inline __attribute__((always_inline)) #endif -template -void strcpy_trunc(char(&dst)[size], const std::string& src) -{ - const size_t count = (src.size() >= size) ? size - 1 /* truncation */ : src.size(); - memcpy(dst, src.c_str(), count); - dst[count] = 0; -} - -template -void strcpy_trunc(char(&dst)[size], const char(&src)[rsize]) -{ - const size_t count = (rsize >= size) ? size - 1 /* truncation */ : rsize; - memcpy(dst, src, count); - dst[count] = 0; -} +#if defined(_MSC_VER) +#define set_alignment(x) _CRT_ALIGN(x) +#else +#define set_alignment(x) __attribute__((aligned(x))) +#endif #if defined(__GNUG__) @@ -82,42 +77,42 @@ int clock_gettime(int foo, struct timespec *ts); #endif /* __APPLE__ */ -template static inline std::enable_if_t::value, T> sync_val_compare_and_swap(volatile T* dest, T2 comp, T2 exch) +template inline std::enable_if_t::value, T> sync_val_compare_and_swap(volatile T* dest, T2 comp, T2 exch) { return __sync_val_compare_and_swap(dest, comp, exch); } -template static inline std::enable_if_t::value, bool> sync_bool_compare_and_swap(volatile T* dest, T2 comp, T2 exch) +template inline std::enable_if_t::value, bool> sync_bool_compare_and_swap(volatile T* dest, T2 comp, T2 exch) { return __sync_bool_compare_and_swap(dest, comp, exch); } -template static inline std::enable_if_t::value, T> sync_lock_test_and_set(volatile T* dest, T2 value) +template inline std::enable_if_t::value, T> sync_lock_test_and_set(volatile T* dest, T2 value) { return __sync_lock_test_and_set(dest, value); } -template static inline std::enable_if_t::value, T> sync_fetch_and_add(volatile T* dest, T2 value) +template inline std::enable_if_t::value, T> sync_fetch_and_add(volatile T* dest, T2 value) { return __sync_fetch_and_add(dest, value); } -template static inline std::enable_if_t::value, T> sync_fetch_and_sub(volatile T* dest, T2 value) +template inline std::enable_if_t::value, T> sync_fetch_and_sub(volatile T* dest, T2 value) { return __sync_fetch_and_sub(dest, value); } -template static inline std::enable_if_t::value, T> sync_fetch_and_or(volatile T* dest, T2 value) +template inline std::enable_if_t::value, T> sync_fetch_and_or(volatile T* dest, T2 value) { return __sync_fetch_and_or(dest, value); } -template static inline std::enable_if_t::value, T> sync_fetch_and_and(volatile T* dest, T2 value) +template inline std::enable_if_t::value, T> sync_fetch_and_and(volatile T* dest, T2 value) { return __sync_fetch_and_and(dest, value); } -template static inline std::enable_if_t::value, T> sync_fetch_and_xor(volatile T* dest, T2 value) +template inline std::enable_if_t::value, T> sync_fetch_and_xor(volatile T* dest, T2 value) { return __sync_fetch_and_xor(dest, value); } @@ -128,181 +123,181 @@ template static inline std::enable_if_t g_log_manager; u32 LogMessage::size() const { //1 byte for NULL terminator - return (u32)(sizeof(LogMessage::size_type) + sizeof(LogType) + sizeof(LogSeverity) + sizeof(std::string::value_type) * mText.size() + 1); + return (u32)(sizeof(LogMessage::size_type) + sizeof(LogType) + sizeof(Severity) + sizeof(std::string::value_type) * mText.size() + 1); } void LogMessage::serialize(char *output) const @@ -24,8 +24,8 @@ void LogMessage::serialize(char *output) const output += sizeof(LogMessage::size_type); memcpy(output, &mType, sizeof(LogType)); output += sizeof(LogType); - memcpy(output, &mServerity, sizeof(LogSeverity)); - output += sizeof(LogSeverity); + memcpy(output, &mServerity, sizeof(Severity)); + output += sizeof(Severity); memcpy(output, mText.c_str(), mText.size() ); output += sizeof(std::string::value_type)*mText.size(); *output = '\0'; @@ -38,13 +38,13 @@ LogMessage LogMessage::deserialize(char *input, u32* size_out) input += sizeof(LogMessage::size_type); msg.mType = *(reinterpret_cast(input)); input += sizeof(LogType); - msg.mServerity = *(reinterpret_cast(input)); - input += sizeof(LogSeverity); + msg.mServerity = *(reinterpret_cast(input)); + input += sizeof(Severity); if (msgSize > 9000) { int wtf = 6; } - msg.mText.append(input, msgSize - 1 - sizeof(LogSeverity) - sizeof(LogType)); + msg.mText.append(input, msgSize - 1 - sizeof(Severity) - sizeof(LogType)); if (size_out){(*size_out) = msgSize;} return msg; } @@ -57,7 +57,7 @@ LogChannel::LogChannel() : LogChannel("unknown") LogChannel::LogChannel(const std::string& name) : name(name) , mEnabled(true) - , mLogLevel(LogSeverityWarning) + , mLogLevel(Severity::Warning) {} void LogChannel::log(const LogMessage &msg) @@ -186,22 +186,22 @@ void LogManager::log(LogMessage msg) std::string prefix; switch (msg.mServerity) { - case LogSeveritySuccess: + case Severity::Success: prefix = "S "; break; - case LogSeverityNotice: + case Severity::Notice: prefix = "! "; break; - case LogSeverityWarning: + case Severity::Warning: prefix = "W "; break; - case LogSeverityError: + case Severity::Error: prefix = "E "; break; } - if (NamedThreadBase* thr = GetCurrentNamedThread()) + if (auto thr = get_current_thread_ctrl()) { - prefix += "{" + thr->GetThreadName() + "} "; + prefix += "{" + thr->get_name() + "} "; } msg.mText.insert(0, prefix); msg.mText.append(1,'\n'); @@ -248,12 +248,12 @@ LogChannel &LogManager::getChannel(LogType type) return mChannels[static_cast(type)]; } -void log_message(Log::LogType type, Log::LogSeverity sev, const char* text) +void log_message(Log::LogType type, Log::Severity sev, const char* text) { log_message(type, sev, std::string(text)); } -void log_message(Log::LogType type, Log::LogSeverity sev, std::string text) +void log_message(Log::LogType type, Log::Severity sev, std::string text) { if (g_log_manager) { @@ -265,12 +265,12 @@ void log_message(Log::LogType type, Log::LogSeverity sev, std::string text) else { rMessageBox(text, - sev == LogSeverityNotice ? "Notice" : - sev == LogSeverityWarning ? "Warning" : - sev == LogSeveritySuccess ? "Success" : - sev == LogSeverityError ? "Error" : "Unknown", - sev == LogSeverityNotice ? rICON_INFORMATION : - sev == LogSeverityWarning ? rICON_EXCLAMATION : - sev == LogSeverityError ? rICON_ERROR : rICON_INFORMATION); + sev == Severity::Notice ? "Notice" : + sev == Severity::Warning ? "Warning" : + sev == Severity::Success ? "Success" : + sev == Severity::Error ? "Error" : "Unknown", + sev == Severity::Notice ? rICON_INFORMATION : + sev == Severity::Warning ? rICON_EXCLAMATION : + sev == Severity::Error ? rICON_ERROR : rICON_INFORMATION); } } diff --git a/Utilities/Log.h b/Utilities/Log.h index c5df9a7217..c0811f35d3 100644 --- a/Utilities/Log.h +++ b/Utilities/Log.h @@ -5,10 +5,10 @@ //first parameter is of type Log::LogType and text is of type std::string -#define LOG_SUCCESS(logType, text, ...) log_message(logType, Log::LogSeveritySuccess, text, ##__VA_ARGS__) -#define LOG_NOTICE(logType, text, ...) log_message(logType, Log::LogSeverityNotice, text, ##__VA_ARGS__) -#define LOG_WARNING(logType, text, ...) log_message(logType, Log::LogSeverityWarning, text, ##__VA_ARGS__) -#define LOG_ERROR(logType, text, ...) log_message(logType, Log::LogSeverityError, text, ##__VA_ARGS__) +#define LOG_SUCCESS(logType, text, ...) log_message(logType, Log::Severity::Success, text, ##__VA_ARGS__) +#define LOG_NOTICE(logType, text, ...) log_message(logType, Log::Severity::Notice, text, ##__VA_ARGS__) +#define LOG_WARNING(logType, text, ...) log_message(logType, Log::Severity::Warning, text, ##__VA_ARGS__) +#define LOG_ERROR(logType, text, ...) log_message(logType, Log::Severity::Error, text, ##__VA_ARGS__) namespace Log { @@ -48,19 +48,19 @@ namespace Log { TTY, "TTY: " } } }; - enum LogSeverity : u32 + enum class Severity : u32 { - LogSeverityNotice = 0, - LogSeverityWarning, - LogSeveritySuccess, - LogSeverityError, + Notice = 0, + Warning, + Success, + Error, }; struct LogMessage { using size_type = u32; LogType mType; - LogSeverity mServerity; + Severity mServerity; std::string mText; u32 size() const; @@ -86,7 +86,7 @@ namespace Log std::string name; private: bool mEnabled; - LogSeverity mLogLevel; + Severity mLogLevel; std::mutex mListenerLock; std::set> mListeners; }; @@ -126,10 +126,10 @@ static struct { inline operator Log::LogType() { return Log::LogType::SPU; } } S static struct { inline operator Log::LogType() { return Log::LogType::ARMv7; } } ARMv7; static struct { inline operator Log::LogType() { return Log::LogType::TTY; } } TTY; -void log_message(Log::LogType type, Log::LogSeverity sev, const char* text); -void log_message(Log::LogType type, Log::LogSeverity sev, std::string text); +void log_message(Log::LogType type, Log::Severity sev, const char* text); +void log_message(Log::LogType type, Log::Severity sev, std::string text); -template never_inline void log_message(Log::LogType type, Log::LogSeverity sev, const char* fmt, Args... args) +template never_inline void log_message(Log::LogType type, Log::Severity sev, const char* fmt, Args... args) { log_message(type, sev, fmt::Format(fmt, fmt::do_unveil(args)...)); } diff --git a/Utilities/SSemaphore.cpp b/Utilities/SSemaphore.cpp index 37c3cc6faa..fd1aad9fbb 100644 --- a/Utilities/SSemaphore.cpp +++ b/Utilities/SSemaphore.cpp @@ -19,10 +19,7 @@ void SSemaphore::wait() while (true) { - if (Emu.IsStopped()) - { - return; - } + CHECK_EMU_STATUS; m_cond.wait_for(cv_lock, std::chrono::milliseconds(1)); diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index 4011878360..3ee3e408f0 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -242,6 +242,17 @@ namespace fmt } }; + template + struct unveil, false> + { + using result_type = typename unveil::result_type; + + force_inline static result_type get_value(const le_t& arg) + { + return unveil::get_value(arg.value()); + } + }; + template force_inline typename unveil::result_type do_unveil(const T& arg) { @@ -257,12 +268,8 @@ namespace fmt be_t<> forced to .value() (fmt::unveil reverts byte order automatically) External specializations for fmt::unveil (can be found in another headers): - vm::ps3::ptr (fmt::unveil) (vm_ptr.h) (with appropriate address type, using .addr() can be avoided) - vm::ps3::bptr (fmt::unveil) (vm_ptr.h) - vm::psv::ptr (fmt::unveil) (vm_ptr.h) - vm::ps3::ref (fmt::unveil) (vm_ref.h) - vm::ps3::bref (fmt::unveil) (vm_ref.h) - vm::psv::ref (fmt::unveil) (vm_ref.h) + vm::ptr, vm::bptr, ... (fmt::unveil) (vm_ptr.h) (with appropriate address type, using .addr() can be avoided) + vm::ref, vm::bref, ... (fmt::unveil) (vm_ref.h) */ template force_inline safe_buffers std::string format(const char* fmt, Args... args) @@ -270,6 +277,39 @@ namespace fmt return Format(fmt, do_unveil(args)...); } + struct exception + { + std::unique_ptr message; + + template never_inline safe_buffers exception(const char* file, int line, const char* func, const char* text, Args... args) + { + const std::string data = format(text, args...) + format("\n(in file %s:%d, in function %s)", file, line, func); + + message = std::make_unique(data.size() + 1); + + std::memcpy(message.get(), data.c_str(), data.size() + 1); + } + + exception(const exception& other) + { + const std::size_t size = std::strlen(other); + + message = std::make_unique(size + 1); + + std::memcpy(message.get(), other, size + 1); + } + + exception(exception&& other) + { + message = std::move(other.message); + } + + operator const char*() const + { + return message.get(); + } + }; + //convert a wxString to a std::string encoded in utf8 //CAUTION, only use this to interface with wxWidgets classes std::string ToUTF8(const wxString& right); diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 9f7eb958bf..b344bac68b 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -109,6 +109,7 @@ enum x64_op_t : u32 X64OP_NONE, X64OP_LOAD, // obtain and put the value into x64 register X64OP_STORE, // take the value from x64 register or an immediate and use it + // example: add eax,[rax] -> X64OP_LOAD_ADD (add the value to x64 register) // example: add [rax],eax -> X64OP_LOAD_ADD_STORE (this will probably never happen for MMIO registers) @@ -116,7 +117,7 @@ enum x64_op_t : u32 X64OP_STOS, X64OP_XCHG, X64OP_CMPXCHG, - X64OP_LOAD_AND_STORE, + X64OP_LOAD_AND_STORE, // lock and [mem],reg }; void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, size_t& out_size, size_t& out_length) @@ -748,7 +749,7 @@ size_t get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, siz if (op == X64OP_CMPXCHG) { // detect whether this instruction can't actually modify memory to avoid breaking reservation; - // this may theoretically cause endless loop, but it shouldn't be a problem if only read_sync() generates such instruction + // this may theoretically cause endless loop, but it shouldn't be a problem if only load_sync() generates such instruction u64 cmp, exch; if (!get_x64_reg_value(context, reg, d_size, i_size, cmp) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, exch)) { @@ -806,9 +807,9 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) // check if address is RawSPU MMIO register if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) { - auto t = Emu.GetCPU().GetRawSPUThread((addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET); + auto thread = Emu.GetCPU().GetRawSPUThread((addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET); - if (!t) + if (!thread) { return false; } @@ -819,14 +820,12 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) return false; } - auto& spu = static_cast(*t); - switch (op) { case X64OP_LOAD: { u32 value; - if (is_writing || !spu.ReadReg(addr, value) || !put_x64_reg_value(context, reg, d_size, re32(value))) + if (is_writing || !thread->ReadReg(addr, value) || !put_x64_reg_value(context, reg, d_size, _byteswap_ulong(value))) { return false; } @@ -836,7 +835,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) case X64OP_STORE: { u64 reg_value; - if (!is_writing || !get_x64_reg_value(context, reg, d_size, i_size, reg_value) || !spu.WriteReg(addr, re32((u32)reg_value))) + if (!is_writing || !get_x64_reg_value(context, reg, d_size, i_size, reg_value) || !thread->WriteReg(addr, _byteswap_ulong((u32)reg_value))) { return false; } @@ -1013,10 +1012,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: reg_value = vm::priv_ref>(addr).exchange((u8)reg_value); break; - case 2: reg_value = vm::priv_ref>(addr).exchange((u16)reg_value); break; - case 4: reg_value = vm::priv_ref>(addr).exchange((u32)reg_value); break; - case 8: reg_value = vm::priv_ref>(addr).exchange((u64)reg_value); break; + case 1: reg_value = vm::priv_ref>(addr).exchange((u8)reg_value); break; + case 2: reg_value = vm::priv_ref>(addr).exchange((u16)reg_value); break; + case 4: reg_value = vm::priv_ref>(addr).exchange((u32)reg_value); break; + case 8: reg_value = vm::priv_ref>(addr).exchange((u64)reg_value); break; default: return false; } @@ -1036,10 +1035,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: old_value = vm::priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; - case 2: old_value = vm::priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; - case 4: old_value = vm::priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; - case 8: old_value = vm::priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; + case 1: old_value = vm::priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; + case 2: old_value = vm::priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; + case 4: old_value = vm::priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; + case 8: old_value = vm::priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; default: return false; } @@ -1059,10 +1058,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: value = vm::priv_ref>(addr) &= value; break; - case 2: value = vm::priv_ref>(addr) &= value; break; - case 4: value = vm::priv_ref>(addr) &= value; break; - case 8: value = vm::priv_ref>(addr) &= value; break; + case 1: value = vm::priv_ref>(addr) &= (u8)value; break; + case 2: value = vm::priv_ref>(addr) &= (u16)value; break; + case 4: value = vm::priv_ref>(addr) &= (u32)value; break; + case 8: value = vm::priv_ref>(addr) &= value; break; default: return false; } @@ -1096,7 +1095,7 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp) if (u == EXCEPTION_ACCESS_VIOLATION && (u32)addr64 == addr64) { - throw fmt::format("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64); + throw EXCEPTION("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64); } } @@ -1107,7 +1106,7 @@ const PVOID exception_handler = (atexit([]{ RemoveVectoredExceptionHandler(excep if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && (u32)addr64 == addr64 && - GetCurrentNamedThread() && + get_current_thread_ctrl() && handle_access_violation((u32)addr64, is_writing, pExp->ContextRecord)) { return EXCEPTION_CONTINUE_EXECUTION; @@ -1118,6 +1117,13 @@ const PVOID exception_handler = (atexit([]{ RemoveVectoredExceptionHandler(excep } })); +const auto exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS pExp) -> LONG +{ + _se_translator(pExp->ExceptionRecord->ExceptionCode, pExp); + + return EXCEPTION_CONTINUE_SEARCH; +}); + #else void signal_handler(int sig, siginfo_t* info, void* uct) @@ -1130,7 +1136,7 @@ void signal_handler(int sig, siginfo_t* info, void* uct) const bool is_writing = ((ucontext_t*)uct)->uc_mcontext.gregs[REG_ERR] & 0x2; #endif - if ((u32)addr64 == addr64 && GetCurrentNamedThread()) + if ((u32)addr64 == addr64 && get_current_thread_ctrl()) { if (handle_access_violation((u32)addr64, is_writing, (ucontext_t*)uct)) { @@ -1138,7 +1144,7 @@ void signal_handler(int sig, siginfo_t* info, void* uct) } // TODO: this may be wrong - throw fmt::format("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64); + throw EXCEPTION("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64); } // else some fatal error @@ -1157,19 +1163,23 @@ const int sigaction_result = []() -> int #endif -thread_local NamedThreadBase* g_tls_this_thread = nullptr; -std::atomic g_thread_count(0); +thread_local thread_ctrl_t* g_tls_this_thread = nullptr; -NamedThreadBase* GetCurrentNamedThread() +const thread_ctrl_t* get_current_thread_ctrl() { return g_tls_this_thread; } -void SetCurrentNamedThread(NamedThreadBase* value) +std::string thread_ctrl_t::get_name() const +{ + return name(); +} + +void thread_ctrl_t::set_current() { const auto old_value = g_tls_this_thread; - if (old_value == value) + if (old_value == this) { return; } @@ -1179,76 +1189,75 @@ void SetCurrentNamedThread(NamedThreadBase* value) vm::reservation_free(); } - if (value && value->m_tls_assigned.exchange(true)) + if (true && assigned.exchange(true)) { - LOG_ERROR(GENERAL, "Thread '%s' was already assigned to g_tls_this_thread of another thread", value->GetThreadName()); + LOG_ERROR(GENERAL, "Thread '%s' was already assigned to g_tls_this_thread of another thread", get_name()); g_tls_this_thread = nullptr; } else { - g_tls_this_thread = value; + g_tls_this_thread = this; } if (old_value) { - old_value->m_tls_assigned = false; + old_value->assigned = false; } } -std::string NamedThreadBase::GetThreadName() const +thread_t::thread_t(std::function name, std::function func) { - return m_name; + start(std::move(name), func); } -void NamedThreadBase::SetThreadName(const std::string& name) +thread_t::~thread_t() noexcept(false) { - m_name = name; -} - -void NamedThreadBase::WaitForAnySignal(u64 time) // wait for Notify() signal or sleep -{ - std::unique_lock lock(m_signal_mtx); - m_signal_cv.wait_for(lock, std::chrono::milliseconds(time)); -} - -void NamedThreadBase::Notify() // wake up waiting thread or nothing -{ - m_signal_cv.notify_one(); -} - -ThreadBase::ThreadBase(const std::string& name) - : NamedThreadBase(name) - , m_executor(nullptr) - , m_destroy(false) - , m_alive(false) -{ -} - -ThreadBase::~ThreadBase() -{ - if(IsAlive()) - Stop(false); - - delete m_executor; - m_executor = nullptr; -} - -void ThreadBase::Start() -{ - if(m_executor) Stop(); - - std::lock_guard lock(m_main_mutex); - - m_destroy = false; - m_alive = true; - - m_executor = new std::thread([this]() + if (m_thread) { - SetCurrentThreadDebugName(GetThreadName().c_str()); + throw EXCEPTION("Neither joined nor detached"); + } +} + +std::string thread_t::get_name() const +{ + if (!m_thread) + { + throw EXCEPTION("Invalid thread"); + } + + if (!m_thread->name) + { + throw EXCEPTION("Invalid name getter"); + } + + return m_thread->name(); +} + +std::atomic g_thread_count{ 0 }; + +void thread_t::start(std::function name, std::function func) +{ + if (m_thread) + { + throw EXCEPTION("Thread already exists"); + } + + // create new thread control variable + m_thread = std::make_shared(std::move(name)); + + // start thread + m_thread->m_thread = std::thread([](std::shared_ptr ctrl, std::function func) + { + g_thread_count++; + + SetCurrentThreadDebugName(ctrl->get_name().c_str()); + +#if defined(_MSC_VER) + auto old_se_translator = _set_se_translator(_se_translator); +#endif #ifdef _WIN32 - auto old_se_translator = _set_se_translator(_se_translator); - if (!exception_handler) + if (!exception_handler || !exception_filter) { LOG_ERROR(GENERAL, "exception_handler not set"); return; @@ -1261,232 +1270,125 @@ void ThreadBase::Start() } #endif - SetCurrentNamedThread(this); - g_thread_count++; + // error handler + const auto error = [&](const char* text) + { + log_message(GENERAL, Emu.IsStopped() ? Log::Severity::Warning : Log::Severity::Error, "Exception: %s", text); + Emu.Pause(); + }; try { - Task(); + ctrl->set_current(); + + if (Ini.HLELogging.GetValue()) + { + LOG_NOTICE(GENERAL, "Thread started"); + } + + func(); } - catch (const char* e) + catch (const char* e) // obsolete { - LOG_ERROR(GENERAL, "Exception: %s", e); - DumpInformation(); - Emu.Pause(); + LOG_ERROR(GENERAL, "Deprecated exception type (const char*)"); + error(e); } - catch (const std::string& e) + catch (const std::string& e) // obsolete { - LOG_ERROR(GENERAL, "Exception: %s", e); - DumpInformation(); - Emu.Pause(); + LOG_ERROR(GENERAL, "Deprecated exception type (std::string)"); + error(e.c_str()); } - - m_alive = false; - SetCurrentNamedThread(nullptr); - g_thread_count--; - -#ifdef _WIN32 - _set_se_translator(old_se_translator); -#endif - }); -} - -void ThreadBase::Stop(bool wait, bool send_destroy) -{ - std::lock_guard lock(m_main_mutex); - - if (send_destroy) - m_destroy = true; - - if(!m_executor) - return; - - if(wait && m_executor->joinable() && m_alive) - { - m_executor->join(); - } - else - { - m_executor->detach(); - } - - delete m_executor; - m_executor = nullptr; -} - -bool ThreadBase::Join() const -{ - std::lock_guard lock(m_main_mutex); - if(m_executor->joinable() && m_alive && m_executor != nullptr) - { - m_executor->join(); - return true; - } - - return false; -} - -bool ThreadBase::IsAlive() const -{ - std::lock_guard lock(m_main_mutex); - return m_alive; -} - -bool ThreadBase::TestDestroy() const -{ - return m_destroy; -} - -thread_t::thread_t(const std::string& name, bool autojoin, std::function func) - : m_name(name) - , m_state(TS_NON_EXISTENT) - , m_autojoin(autojoin) -{ - start(func); -} - -thread_t::thread_t(const std::string& name, std::function func) - : m_name(name) - , m_state(TS_NON_EXISTENT) - , m_autojoin(false) -{ - start(func); -} - -thread_t::thread_t(const std::string& name) - : m_name(name) - , m_state(TS_NON_EXISTENT) - , m_autojoin(false) -{ -} - -thread_t::thread_t() - : m_state(TS_NON_EXISTENT) - , m_autojoin(false) -{ -} - -void thread_t::set_name(const std::string& name) -{ - m_name = name; -} - -thread_t::~thread_t() -{ - if (m_state == TS_JOINABLE) - { - if (m_autojoin) + catch (const fmt::exception& e) { - m_thr.join(); + error(e); } - else - { - m_thr.detach(); - } - } -} - -void thread_t::start(std::function func) -{ - if (m_state.exchange(TS_NON_EXISTENT) == TS_JOINABLE) - { - m_thr.join(); // forcefully join previously created thread - } - - std::string name = m_name; - m_thr = std::thread([func, name]() - { - SetCurrentThreadDebugName(name.c_str()); - -#ifdef _WIN32 - auto old_se_translator = _set_se_translator(_se_translator); -#endif - - NamedThreadBase info(name); - SetCurrentNamedThread(&info); - g_thread_count++; if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, name + " started"); + LOG_NOTICE(GENERAL, "Thread ended"); } - try - { - func(); - } - catch (const char* e) - { - LOG_ERROR(GENERAL, "Exception: %s", e); - Emu.Pause(); - } - catch (const std::string& e) - { - LOG_ERROR(GENERAL, "Exception: %s", e.c_str()); - Emu.Pause(); - } + //ctrl->set_current(false); - if (Emu.IsStopped()) - { - LOG_NOTICE(HLE, name + " aborted"); - } - else if (Ini.HLELogging.GetValue()) - { - LOG_NOTICE(HLE, name + " ended"); - } + vm::reservation_free(); - SetCurrentNamedThread(nullptr); g_thread_count--; -#ifdef _WIN32 +#if defined(_MSC_VER) _set_se_translator(old_se_translator); #endif - }); - - if (m_state.exchange(TS_JOINABLE) == TS_JOINABLE) - { - assert(!"thread_t::start() failed"); // probably started from another thread - } + }, m_thread, std::move(func)); } void thread_t::detach() { - if (m_state.exchange(TS_NON_EXISTENT) == TS_JOINABLE) + if (!m_thread) { - m_thr.detach(); + throw EXCEPTION("Invalid thread"); } - else + + // +clear m_thread + const auto ctrl = std::move(m_thread); + + // notify if detached by another thread + if (g_tls_this_thread != m_thread.get()) { - assert(!"thread_t::detach() failed"); // probably joined or detached + // lock for reliable notification + std::lock_guard lock(mutex); + + cv.notify_one(); } + + ctrl->m_thread.detach(); } void thread_t::join() { - if (m_state.exchange(TS_NON_EXISTENT) == TS_JOINABLE) + if (!m_thread) { - m_thr.join(); + throw EXCEPTION("Invalid thread"); } - else + + if (g_tls_this_thread == m_thread.get()) { - assert(!"thread_t::join() failed"); // probably joined or detached + throw EXCEPTION("Deadlock"); } + + // +clear m_thread + const auto ctrl = std::move(m_thread); + + { + // lock for reliable notification + std::lock_guard lock(mutex); + + cv.notify_one(); + } + + ctrl->m_thread.join(); } -bool thread_t::joinable() const +bool thread_t::is_current() const { - //return m_thr.joinable(); - return m_state == TS_JOINABLE; + if (!m_thread) + { + throw EXCEPTION("Invalid thread"); + } + + return g_tls_this_thread == m_thread.get(); } -bool waiter_map_t::is_stopped(u64 signal_id) +void waiter_map_t::check_emu_status(u32 addr) { if (Emu.IsStopped()) { - LOG_WARNING(Log::HLE, "%s: waiter_op() aborted (signal_id=0x%llx)", name.c_str(), signal_id); - return true; + throw EXCEPTION("Aborted (emulation stopped) (%s, addr=0x%x)", name, addr); } - return false; +} + +void waiter_map_t::notify(u32 addr) +{ + // signal an appropriate condition variable + cvs[get_hash(addr)].notify_all(); } const std::function SQUEUE_ALWAYS_EXIT = [](){ return true; }; diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 783f66176c..23676853c9 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -1,112 +1,108 @@ #pragma once -class NamedThreadBase +const class thread_ctrl_t* get_current_thread_ctrl(); + +// named thread control class +class thread_ctrl_t final { - std::string m_name; - std::condition_variable m_signal_cv; - std::mutex m_signal_mtx; + friend class thread_t; + + // thread handler + std::thread m_thread; + + // name getter + const std::function name; + + // true if assigned somewhere in TLS + std::atomic assigned{ false }; + + // assign TLS (must be assigned only once) + void set_current(); public: - std::atomic m_tls_assigned; - - NamedThreadBase(const std::string& name) : m_name(name), m_tls_assigned(false) + thread_ctrl_t(std::function name) + : name(std::move(name)) { } - NamedThreadBase() : m_tls_assigned(false) - { - } - - virtual std::string GetThreadName() const; - virtual void SetThreadName(const std::string& name); - - void WaitForAnySignal(u64 time = 1); - void Notify(); - - virtual void DumpInformation() {} -}; - -NamedThreadBase* GetCurrentNamedThread(); -void SetCurrentNamedThread(NamedThreadBase* value); - -class ThreadBase : public NamedThreadBase -{ -protected: - std::atomic m_destroy; - std::atomic m_alive; - std::thread* m_executor; - - mutable std::mutex m_main_mutex; - - ThreadBase(const std::string& name); - ~ThreadBase(); - -public: - void Start(); - void Stop(bool wait = true, bool send_destroy = true); - - bool Join() const; - bool IsAlive() const; - bool TestDestroy() const; - - virtual void Task() = 0; + // get thread name + std::string get_name() const; }; class thread_t { - enum thread_state_t - { - TS_NON_EXISTENT, - TS_JOINABLE, - }; - - std::atomic m_state; - std::string m_name; - std::thread m_thr; - bool m_autojoin; + // pointer to managed resource (shared with actual thread) + std::shared_ptr m_thread; public: - thread_t(const std::string& name, bool autojoin, std::function func); - thread_t(const std::string& name, std::function func); - thread_t(const std::string& name); - thread_t(); - ~thread_t(); + // thread mutex for external use + std::mutex mutex; - thread_t(const thread_t& right) = delete; - thread_t(thread_t&& right) = delete; - - thread_t& operator =(const thread_t& right) = delete; - thread_t& operator =(thread_t&& right) = delete; + // thread condition variable for external use + std::condition_variable cv; public: - void set_name(const std::string& name); - void start(std::function func); + // initialize in empty state + thread_t() = default; + + // create named thread + thread_t(std::function name, std::function func); + + // destructor, joins automatically (questionable, don't rely on this functionality in derived destructors) + virtual ~thread_t() noexcept(false); + + thread_t(const thread_t&) = delete; + + thread_t& operator =(const thread_t&) = delete; + +public: + // get thread name + std::string get_name() const; + + // create named thread (current state must be empty) + void start(std::function name, std::function func); + + // detach thread -> empty state void detach(); + + // join thread -> empty state void join(); - bool joinable() const; + + // check if not empty + bool joinable() const { return m_thread.operator bool(); } + + // check whether it is the current running thread + bool is_current() const; }; -class slw_mutex_t +class autojoin_thread_t final : private thread_t { +public: + using thread_t::mutex; + using thread_t::cv; -}; +public: + autojoin_thread_t() = delete; -class slw_recursive_mutex_t -{ + autojoin_thread_t(std::function name, std::function func) + { + start(std::move(name), std::move(func)); + } -}; - -class slw_shared_mutex_t -{ + virtual ~autojoin_thread_t() override + { + join(); + } + using thread_t::is_current; }; struct waiter_map_t { - static const size_t size = 32; + static const size_t size = 16; - std::array mutex; - std::array cv; + std::array mutexes; + std::array cvs; const std::string name; @@ -115,40 +111,45 @@ struct waiter_map_t { } - bool is_stopped(u64 signal_id); - - // wait until waiter_func() returns true, signal_id is an arbitrary number - template force_inline safe_buffers void wait_op(const S& signal_id, const WT waiter_func) + // generate simple "hash" for mutex/cv distribution + u32 get_hash(u32 addr) { - // generate hash - const auto hash = std::hash()(signal_id) % size; + addr ^= addr >> 16; + addr ^= addr >> 24; + addr ^= addr >> 28; + return addr % size; + } + + void check_emu_status(u32 addr); + + // wait until pred() returns true, `addr` is an arbitrary number + template safe_buffers auto wait_op(u32 addr, F pred, Args&&... args) -> decltype(static_cast(pred(args...))) + { + const u32 hash = get_hash(addr); // set mutex locker - std::unique_lock locker(mutex[hash], std::defer_lock); + std::unique_lock lock(mutexes[hash], std::defer_lock); - // check the condition or if the emulator is stopped - while (!waiter_func() && !is_stopped(signal_id)) + while (true) { - // lock the mutex and initialize waiter (only once) - if (!locker.owns_lock()) + // check the condition + if (pred(args...)) return; + + check_emu_status(addr); + + if (!lock) { - locker.lock(); + lock.lock(); + continue; } - // wait on appropriate condition variable for 1 ms or until signal arrived - cv[hash].wait_for(locker, std::chrono::milliseconds(1)); + // wait on an appropriate cond var for 1 ms or until a signal arrived + cvs[hash].wait_for(lock, std::chrono::milliseconds(1)); } } - // signal all threads waiting on waiter_op() with the same signal_id (signaling only hints those threads that corresponding conditions are *probably* met) - template force_inline void notify(const S& signal_id) - { - // generate hash - const auto hash = std::hash()(signal_id) % size; - - // signal appropriate condition variable - cv[hash].notify_all(); - } + // signal all threads waiting on wait_op() with the same `addr` (signaling only hints those threads that corresponding conditions are *probably* met) + void notify(u32 addr); }; extern const std::function SQUEUE_ALWAYS_EXIT; @@ -173,7 +174,7 @@ class squeue_t }; }; - atomic m_sync; + atomic_t m_sync; mutable std::mutex m_rcv_mutex; mutable std::mutex m_wcv_mutex; @@ -209,7 +210,7 @@ public: { u32 pos = 0; - while (u32 res = m_sync.atomic_op_sync(SQSVR_OK, [&pos](squeue_sync_var_t& sync) -> u32 + while (u32 res = m_sync.atomic_op([&pos](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); @@ -272,7 +273,7 @@ public: { u32 pos = 0; - while (u32 res = m_sync.atomic_op_sync(SQSVR_OK, [&pos](squeue_sync_var_t& sync) -> u32 + while (u32 res = m_sync.atomic_op([&pos](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); @@ -341,7 +342,7 @@ public: assert(start_pos < sq_size); u32 pos = 0; - while (u32 res = m_sync.atomic_op_sync(SQSVR_OK, [&pos, start_pos](squeue_sync_var_t& sync) -> u32 + while (u32 res = m_sync.atomic_op([&pos, start_pos](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); @@ -425,7 +426,7 @@ public: { u32 pos, count; - while (m_sync.atomic_op_sync(SQSVR_OK, [&pos, &count](squeue_sync_var_t& sync) -> u32 + while (m_sync.atomic_op([&pos, &count](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); @@ -463,7 +464,7 @@ public: void clear() { - while (m_sync.atomic_op_sync(SQSVR_OK, [](squeue_sync_var_t& sync) -> u32 + while (m_sync.atomic_op([](squeue_sync_var_t& sync) -> u32 { assert(sync.count <= sq_size); assert(sync.position < sq_size); diff --git a/Utilities/rPlatform.cpp b/Utilities/rPlatform.cpp index 63eae5d141..ba1bee9455 100644 --- a/Utilities/rPlatform.cpp +++ b/Utilities/rPlatform.cpp @@ -35,7 +35,7 @@ void rImage::SaveFile(const std::string& name, rImageType type) } else { - throw std::string("unsupported type"); + throw EXCEPTION("unsupported type"); } } diff --git a/Utilities/rTime.cpp b/Utilities/rTime.cpp index 58f607d1e3..9687141302 100644 --- a/Utilities/rTime.cpp +++ b/Utilities/rTime.cpp @@ -133,7 +133,7 @@ wxDateTime::TimeZone convertTZ(rDateTime::rTimeZone tz) case rDateTime::UTC: return wxDateTime::UTC; default: - throw std::string("WRONG DATETIME"); + throw EXCEPTION("WRONG DATETIME"); } } diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index fdc99b2e99..b76f75fecf 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -179,7 +179,7 @@ bool UnpackEntry(const fs::file& dec_pkg_f, const PKGEntry& entry, std::string d dec_pkg_f.read(buf, entry.name_size); buf[entry.name_size] = 0; - switch (entry.type.data() >> 24) + switch (entry.type & 0xff) { case PKG_FILE_ENTRY_NPDRM: case PKG_FILE_ENTRY_NPDRMEDAT: diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index 495eac45dc..56cd59e994 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -102,34 +102,34 @@ force_inline void Write64LE(const fs::file& f, const u64 data) f.write(&data, sizeof(data)); } -force_inline void Write16(vfsStream& f, const u16 data) +force_inline void Write16(vfsStream& f, const be_t data) { - Write16LE(f, re16(data)); + f.Write(&data, sizeof(data)); } -force_inline void Write16(const fs::file& f, const u16 data) +force_inline void Write16(const fs::file& f, const be_t data) { - Write16LE(f, re16(data)); + f.write(&data, sizeof(data)); } -force_inline void Write32(vfsStream& f, const u32 data) +force_inline void Write32(vfsStream& f, const be_t data) { - Write32LE(f, re32(data)); + f.Write(&data, sizeof(data)); } -force_inline void Write32(const fs::file& f, const u32 data) +force_inline void Write32(const fs::file& f, const be_t data) { - Write32LE(f, re32(data)); + f.write(&data, sizeof(data)); } -force_inline void Write64(vfsStream& f, const u64 data) +force_inline void Write64(vfsStream& f, const be_t data) { - Write64LE(f, re64(data)); + f.Write(&data, sizeof(data)); } -force_inline void Write64(const fs::file& f, const u64 data) +force_inline void Write64(const fs::file& f, const be_t data) { - Write64LE(f, re64(data)); + f.write(&data, sizeof(data)); } void WriteEhdr(const fs::file& f, Elf64_Ehdr& ehdr) @@ -935,9 +935,9 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size) bool SELFDecrypter::LoadMetadata() { aes_context aes; - u32 metadata_info_size = sizeof(meta_info); + u32 metadata_info_size = sizeof32(meta_info); u8 *metadata_info = (u8 *)malloc(metadata_info_size); - u32 metadata_headers_size = sce_hdr.se_hsize - (sizeof(sce_hdr) + sce_hdr.se_meta + sizeof(meta_info)); + u32 metadata_headers_size = sce_hdr.se_hsize - (sizeof32(sce_hdr) + sce_hdr.se_meta + sizeof32(meta_info)); u8 *metadata_headers = (u8 *)malloc(metadata_headers_size); // Locate and read the encrypted metadata info. diff --git a/rpcs3/Emu/ARMv7/ARMv7Callback.h b/rpcs3/Emu/ARMv7/ARMv7Callback.h index b8d7daa452..d9e42f3d36 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Callback.h +++ b/rpcs3/Emu/ARMv7/ARMv7Callback.h @@ -7,12 +7,11 @@ namespace vm template force_inline RT _ptr_base::operator()(ARMv7Context& context, T... args) const { - return psv_func_detail::func_caller::call(context, vm::cast(this->addr()), args...); + return psv_func_detail::func_caller::call(context, VM_CAST(this->addr()), args...); } } -template -force_inline RT cb_call(ARMv7Context& context, u32 addr, T... args) +template inline RT cb_call(ARMv7Context& context, u32 addr, T... args) { return psv_func_detail::func_caller::call(context, addr, args...); } diff --git a/rpcs3/Emu/ARMv7/ARMv7Context.h b/rpcs3/Emu/ARMv7/ARMv7Context.h index 876e55fb36..592109ae60 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Context.h +++ b/rpcs3/Emu/ARMv7/ARMv7Context.h @@ -1,6 +1,6 @@ #pragma once -class ARMv7Thread; +#include "Emu/Memory/Memory.h" enum ARMv7InstructionSet { @@ -107,7 +107,7 @@ struct ARMv7Context operator bool() const { - return check_state; + return check_state != 0; } } ITSTATE; @@ -122,19 +122,34 @@ struct ARMv7Context std::array counters; - ARMv7Thread& thread; + u32 PC; + s32 prio; + u32 stack_addr; + u32 stack_size; + u32 hle_func; // current function ID - u32 debug; // debug flags + u32 debug; std::string debug_str; - ARMv7Context(ARMv7Thread& thread) : thread(thread), debug(/*DF_DISASM | DF_PRINT*/ 0) {} + void write_pc(u32 value, u32 size) + { + ISET = value & 1 ? Thumb : ARM; + PC = (value & ~1) - size; + } + + u32 read_pc() + { + return ISET == ARM ? PC + 8 : PC + 4; + } + + u32 get_stack_arg(u32 pos) + { + return vm::psv::read32(SP + sizeof(u32) * (pos - 5)); + } - void write_pc(u32 value); - u32 read_pc(); - u32 get_stack_arg(u32 pos); void fast_call(u32 addr); - void write_gpr(u32 n, u32 value) + void write_gpr(u32 n, u32 value, u32 size) { assert(n < 16); @@ -144,7 +159,7 @@ struct ARMv7Context } else { - write_pc(value); + write_pc(value, size); } } @@ -307,4 +322,3 @@ force_inline T cast_from_armv7_gpr(const u32 reg) { return cast_armv7_gpr::from_gpr(reg); } - diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp index f5c61bcd46..bf73953e2e 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp @@ -1183,7 +1183,7 @@ struct ARMv7_op4t_table_t } } - throw "HACK instruction not found"; + throw EXCEPTION("HACK instruction not found"); } } g_op4t; @@ -1221,6 +1221,8 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump) //g_opct.clear(); //g_opct.reserve(end_addr - addr); + const auto hack = g_op4t.HACK(); + while (addr < end_addr) { ARMv7Code code = {}; @@ -1280,7 +1282,7 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump) const u32 i2 = (code.data >> 11) & 0x1 ^ s ^ 1; const u32 target = (addr + 4 & ~3) + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); - const u32 instr = vm::check_addr(target, 4) ? vm::psv::read32(target) : 0; + const u32 instr = vm::check_addr(target, 4) ? vm::psv::read32(target).value() : 0; // possibly a call to imported function: if (target >= end_addr && ((target - end_addr) % 16) == 0 && (instr & 0xfff000f0) == 0xe0700090) @@ -1288,7 +1290,7 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump) // replace BLX with "HACK" instruction directly (in Thumb form), it can help to see where it was called from const u32 index = (instr & 0xfff00) >> 4 | (instr & 0xf); vm::psv::write32(addr, 0xf870 | index << 16); - g_opct[0xf8700000 | index] = g_op4t.HACK(); + g_opct[0xf8700000 | index] = hack; } else { @@ -1355,7 +1357,7 @@ u32 ARMv7Decoder::DecodeMemory(const u32 address) } else { - throw "ARMv7Decoder::DecodeMemory() failed (invalid instruction set set)"; + throw EXCEPTION("Invalid instruction set"); } ARMv7_instrs::UNK(m_ctx, code); diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index cf0b482c35..48612562ec 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include #include "Utilities/Log.h" #include "Emu/System.h" #include "Emu/Memory/Memory.h" @@ -9,7 +8,7 @@ #include "PSVFuncList.h" #include "ARMv7Interpreter.h" -#define reject(cond, info) { if (cond) Error(__FUNCTION__, code, type, #cond, info); } +#define reject(cond, info) { if (cond) throw EXCEPTION("%s ('%s', type=%s)", info, #cond, fmt_encoding(type)); } std::map g_armv7_dump; @@ -84,7 +83,7 @@ namespace ARMv7_instrs } break; - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } return shift_t; @@ -100,7 +99,7 @@ namespace ARMv7_instrs // case 1: shift_t = SRType_LSR; break; // case 2: shift_t = SRType_ASR; break; // case 3: shift_t = SRType_ROR; break; - // default: throw __FUNCTION__; + // default: throw EXCEPTION(""); // } // return shift_t; @@ -109,7 +108,7 @@ namespace ARMv7_instrs u32 LSL_C(u32 x, s32 shift, bool& carry_out) { assert(shift > 0); - carry_out = shift <= 32 ? x & (1 << (32 - shift)) : false; + carry_out = shift <= 32 ? (x & (1 << (32 - shift))) != 0 : false; return shift < 32 ? x << shift : 0; } @@ -122,7 +121,7 @@ namespace ARMv7_instrs u32 LSR_C(u32 x, s32 shift, bool& carry_out) { assert(shift > 0); - carry_out = shift <= 32 ? x & (1 << (shift - 1)) : false; + carry_out = shift <= 32 ? (x & (1 << (shift - 1))) != 0 : false; return shift < 32 ? x >> shift : 0; } @@ -135,7 +134,7 @@ namespace ARMv7_instrs s32 ASR_C(s32 x, s32 shift, bool& carry_out) { assert(shift > 0); - carry_out = shift <= 32 ? x & (1 << (shift - 1)) : x < 0; + carry_out = shift <= 32 ? (x & (1 << (shift - 1))) != 0 : x < 0; return shift < 32 ? x >> shift : x >> 31; } @@ -149,7 +148,7 @@ namespace ARMv7_instrs { assert(shift); const u32 result = x >> shift | x << (32 - shift); - carry_out = result >> 31; + carry_out = (result >> 31) != 0; return result; } @@ -182,7 +181,7 @@ namespace ARMv7_instrs case SRType_ASR: return ASR_C(value, amount, carry_out); case SRType_ROR: return ROR_C(value, amount, carry_out); case SRType_RRX: return RRX_C(value, carry_in, carry_out); - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } } @@ -201,8 +200,8 @@ namespace ARMv7_instrs const T sign_mask = (T)1 << (sizeof(T) * 8 - 1); T result = x + y; - carry_out = ((x & y) | ((x ^ y) & ~result)) & sign_mask; - overflow = (x ^ result) & (y ^ result) & sign_mask; + carry_out = (((x & y) | ((x ^ y) & ~result)) & sign_mask) != 0; + overflow = ((x ^ result) & (y ^ result) & sign_mask) != 0; if (carry_in) { result += 1; @@ -265,25 +264,6 @@ namespace ARMv7_instrs return result; } - void Error(const char* func, const ARMv7Code code, const ARMv7_encoding type, const char* cond, const char* info) - { - auto format_encoding = [](const ARMv7_encoding type) -> const char* - { - switch (type) - { - case T1: return "T1"; - case T2: return "T2"; - case T3: return "T3"; - case T4: return "T4"; - case A1: return "A1"; - case A2: return "A2"; - default: return "???"; - } - }; - - throw fmt::format("%s(%s) error: %s (%s)", func, format_encoding(type), info, cond); - } - bool process_debug(ARMv7Context& context) { if (context.debug & DF_PRINT) @@ -294,21 +274,21 @@ namespace ARMv7_instrs context.debug_str.insert(pos, 8 - pos, ' '); } - context.fmt_debug_str("0x%08x: %s", context.thread.PC, context.debug_str); + context.fmt_debug_str("0x%08x: %s", context.PC, context.debug_str); LV2_LOCK; - auto found = g_armv7_dump.find(context.thread.PC); + auto found = g_armv7_dump.find(context.PC); if (found != g_armv7_dump.end()) { if (found->second != context.debug_str) { - throw context.debug_str; + throw EXCEPTION("Disasm inconsistency: '%s' != '%s'", found->second.c_str(), context.debug_str.c_str()); } } else { - g_armv7_dump[context.thread.PC] = context.debug_str; + g_armv7_dump[context.PC] = context.debug_str; } } @@ -320,6 +300,20 @@ namespace ARMv7_instrs return false; } + const char* fmt_encoding(const ARMv7_encoding type) + { + switch (type) + { + case T1: return "T1"; + case T2: return "T2"; + case T3: return "T3"; + case T4: return "T4"; + case A1: return "A1"; + case A2: return "A2"; + default: return "???"; + } + }; + const char* fmt_cond(u32 cond) { switch (cond) @@ -493,11 +487,11 @@ void ARMv7_instrs::UNK(ARMv7Context& context, const ARMv7Code code) { if (context.ISET == Thumb) { - throw fmt::format("Unknown/illegal opcode: 0x%04X 0x%04X", code.code1, code.code0); + throw EXCEPTION("Unknown/illegal opcode: 0x%04X 0x%04X", code.code1, code.code0); } else { - throw fmt::format("Unknown/illegal opcode: 0x%08X", code.data); + throw EXCEPTION("Unknown/illegal opcode: 0x%08X", code.data); } } @@ -519,7 +513,7 @@ void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7 index = (code.data & 0xfff00) >> 4 | (code.data & 0xf); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -572,7 +566,7 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7 reject(t == 13 && (type == T1 || type == T2), "UNPREDICTABLE"); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } auto disasm = [&]() @@ -596,14 +590,14 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (!context.TLS) { - throw "TLS not initialized"; + throw EXCEPTION("TLS not initialized"); } context.GPR[t] = context.TLS; return; } - Error(__FUNCTION__, code, type, (disasm(), context.debug_str.c_str()), "Bad instruction"); + throw EXCEPTION("Bad instruction: '%s' (code=0x%x, type=%d)", (disasm(), context.debug_str.c_str()), code.data, type); } } @@ -619,14 +613,14 @@ void ARMv7_instrs::ADC_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -639,7 +633,7 @@ void ARMv7_instrs::ADC_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry, overflow; const u32 result = AddWithCarry(context.read_gpr(n), imm32, context.APSR.C, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -673,14 +667,14 @@ void ARMv7_instrs::ADC_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -694,7 +688,7 @@ void ARMv7_instrs::ADC_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry, overflow; const u32 shifted = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 result = AddWithCarry(context.read_gpr(n), shifted, context.APSR.C, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -710,8 +704,8 @@ void ARMv7_instrs::ADC_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -743,7 +737,7 @@ void ARMv7_instrs::ADD_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMN (immediate)"); @@ -764,8 +758,8 @@ void ARMv7_instrs::ADD_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 13 || d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -778,7 +772,7 @@ void ARMv7_instrs::ADD_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry, overflow; const u32 result = AddWithCarry(context.read_gpr(n), imm32, false, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type < T3 ? 2 : 4); if (set_flags) { @@ -827,7 +821,7 @@ void ARMv7_instrs::ADD_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 15 && set_flags, "CMN (register)"); @@ -835,8 +829,8 @@ void ARMv7_instrs::ADD_REG(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -850,7 +844,7 @@ void ARMv7_instrs::ADD_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry, overflow; const u32 shifted = Shift(context.read_gpr(m), shift_t, shift_n, true); const u32 result = AddWithCarry(context.read_gpr(n), shifted, false, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type < T3 ? 2 : 4); if (set_flags) { @@ -866,8 +860,8 @@ void ARMv7_instrs::ADD_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -898,7 +892,7 @@ void ARMv7_instrs::ADD_SPI(ARMv7Context& context, const ARMv7Code code, const AR { cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMN (immediate)"); @@ -915,8 +909,8 @@ void ARMv7_instrs::ADD_SPI(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -929,7 +923,7 @@ void ARMv7_instrs::ADD_SPI(ARMv7Context& context, const ARMv7Code code, const AR { bool carry, overflow; const u32 result = AddWithCarry(context.SP, imm32, false, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type < T3 ? 2 : 4); if (set_flags) { @@ -974,15 +968,15 @@ void ARMv7_instrs::ADD_SPR(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 13 && (shift_t != SRType_LSL || shift_n > 3), "UNPREDICTABLE"); reject(d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -996,7 +990,7 @@ void ARMv7_instrs::ADD_SPR(ARMv7Context& context, const ARMv7Code code, const AR bool carry, overflow; const u32 shifted = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 result = AddWithCarry(context.SP, shifted, false, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type < T3 ? 2 : 4); if (set_flags) { @@ -1044,8 +1038,8 @@ void ARMv7_instrs::ADR(ARMv7Context& context, const ARMv7Code code, const ARMv7_ reject(d == 13 || d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } const u32 base = context.read_pc() & ~3; @@ -1059,7 +1053,7 @@ void ARMv7_instrs::ADR(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); } } @@ -1076,15 +1070,15 @@ void ARMv7_instrs::AND_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); reject(d == 15 && set_flags, "TST (immediate)"); reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1096,7 +1090,7 @@ void ARMv7_instrs::AND_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = context.read_gpr(n) & imm32; - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -1129,15 +1123,15 @@ void ARMv7_instrs::AND_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 15 && set_flags, "TST (register)"); reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1151,7 +1145,7 @@ void ARMv7_instrs::AND_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry; const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); const u32 result = context.read_gpr(n) & shifted; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -1166,8 +1160,8 @@ void ARMv7_instrs::AND_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1176,8 +1170,8 @@ void ARMv7_instrs::ASR_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1185,8 +1179,8 @@ void ARMv7_instrs::ASR_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1248,7 +1242,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en imm32 = sign<26, u32>((code.data & 0xffffff) << 2); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -1259,7 +1253,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en if (ConditionPassed(context, cond)) { - context.thread.SetBranch(context.read_pc() + imm32); + context.PC = context.read_pc() + imm32 - (type < T3 ? 2 : 4); } } @@ -1268,8 +1262,8 @@ void ARMv7_instrs::BFC(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1277,8 +1271,8 @@ void ARMv7_instrs::BFI(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1295,14 +1289,14 @@ void ARMv7_instrs::BIC_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1314,7 +1308,7 @@ void ARMv7_instrs::BIC_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = context.read_gpr(n) & ~imm32; - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -1347,14 +1341,14 @@ void ARMv7_instrs::BIC_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1368,7 +1362,7 @@ void ARMv7_instrs::BIC_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry; const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); const u32 result = context.read_gpr(n) & ~shifted; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -1383,8 +1377,8 @@ void ARMv7_instrs::BIC_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1393,8 +1387,8 @@ void ARMv7_instrs::BKPT(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1424,7 +1418,7 @@ void ARMv7_instrs::BL(ARMv7Context& context, const ARMv7Code code, const ARMv7_e imm32 = sign<26, u32>((code.data & 0xffffff) << 2); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } const u32 lr = context.ISET == ARM ? context.read_pc() - 4 : context.read_pc() | 1; @@ -1439,7 +1433,7 @@ void ARMv7_instrs::BL(ARMv7Context& context, const ARMv7Code code, const ARMv7_e if (ConditionPassed(context, cond)) { context.LR = lr; - context.thread.SetBranch(pc); + context.PC = pc - 4; } } @@ -1452,7 +1446,7 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ case T1: { cond = context.ITSTATE.advance(); - newLR = (context.thread.PC + 2) | 1; + newLR = (context.PC + 2) | 1; { const u32 m = (code.data >> 3) & 0xf; reject(m == 15, "UNPREDICTABLE"); @@ -1465,12 +1459,12 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ case T2: { cond = context.ITSTATE.advance(); - newLR = (context.thread.PC + 4) | 1; + newLR = (context.PC + 4) | 1; { const u32 s = (code.data >> 26) & 0x1; const u32 i1 = (code.data >> 13) & 0x1 ^ s ^ 1; const u32 i2 = (code.data >> 11) & 0x1 ^ s ^ 1; - target = ~3 & context.thread.PC + 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); + target = ~3 & context.PC + 4 + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); } reject(context.ITSTATE, "UNPREDICTABLE"); @@ -1479,18 +1473,18 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ case A1: { cond = code.data >> 28; - newLR = context.thread.PC + 4; + newLR = context.PC + 4; target = context.read_gpr(code.data & 0xf); break; } case A2: { cond = 0xe; // always true - newLR = context.thread.PC + 4; - target = 1 | context.thread.PC + 8 + sign<25, u32>((code.data & 0xffffff) << 2 | (code.data & 0x1000000) >> 23); + newLR = context.PC + 4; + target = 1 | context.PC + 8 + sign<25, u32>((code.data & 0xffffff) << 2 | (code.data & 0x1000000) >> 23); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -1511,7 +1505,7 @@ void ARMv7_instrs::BLX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { context.LR = newLR; - context.write_pc(target); + context.write_pc(target, type == T1 ? 2 : 4); } } @@ -1535,7 +1529,7 @@ void ARMv7_instrs::BX(ARMv7Context& context, const ARMv7Code code, const ARMv7_e m = (code.data & 0xf); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -1546,7 +1540,7 @@ void ARMv7_instrs::BX(ARMv7Context& context, const ARMv7Code code, const ARMv7_e if (ConditionPassed(context, cond)) { - context.write_pc(context.read_gpr(m)); + context.write_pc(context.read_gpr(m), type == T1 ? 2 : 4); } } @@ -1562,12 +1556,12 @@ void ARMv7_instrs::CB_Z(ARMv7Context& context, const ARMv7Code code, const ARMv7 { n = code.data & 0x7; imm32 = (code.data & 0xf8) >> 2 | (code.data & 0x200) >> 3; - nonzero = (code.data & 0x800); + nonzero = (code.data & 0x800) != 0; reject(context.ITSTATE, "UNPREDICTABLE"); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -1578,7 +1572,7 @@ void ARMv7_instrs::CB_Z(ARMv7Context& context, const ARMv7Code code, const ARMv7 if ((context.read_gpr(n) == 0) ^ nonzero) { - context.thread.SetBranch(context.read_pc() + imm32); + context.PC = context.read_pc() + imm32 - 2; } } @@ -1599,8 +1593,8 @@ void ARMv7_instrs::CLZ(ARMv7Context& context, const ARMv7Code code, const ARMv7_ reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1611,7 +1605,7 @@ void ARMv7_instrs::CLZ(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { - context.write_gpr(d, cntlz32(context.read_gpr(m))); + context.write_gpr(d, cntlz32(context.read_gpr(m)), 4); } } @@ -1620,8 +1614,8 @@ void ARMv7_instrs::CMN_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1629,8 +1623,8 @@ void ARMv7_instrs::CMN_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1638,8 +1632,8 @@ void ARMv7_instrs::CMN_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1666,8 +1660,8 @@ void ARMv7_instrs::CMP_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject(n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1727,8 +1721,8 @@ void ARMv7_instrs::CMP_REG(ARMv7Context& context, const ARMv7Code code, const AR reject(n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1757,8 +1751,8 @@ void ARMv7_instrs::CMP_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1767,8 +1761,8 @@ void ARMv7_instrs::DBG(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1776,8 +1770,8 @@ void ARMv7_instrs::DMB(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1785,8 +1779,8 @@ void ARMv7_instrs::DSB(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1803,15 +1797,15 @@ void ARMv7_instrs::EOR_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); reject(d == 15 && set_flags, "TEQ (immediate)"); reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1823,7 +1817,7 @@ void ARMv7_instrs::EOR_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = context.read_gpr(n) ^ imm32; - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -1856,15 +1850,15 @@ void ARMv7_instrs::EOR_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 15 && set_flags, "TEQ (register)"); reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1878,7 +1872,7 @@ void ARMv7_instrs::EOR_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry; const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); const u32 result = context.read_gpr(n) ^ shifted; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -1893,8 +1887,8 @@ void ARMv7_instrs::EOR_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1916,7 +1910,7 @@ void ARMv7_instrs::IT(ARMv7Context& context, const ARMv7Code code, const ARMv7_e context.ITSTATE.IT = code.data & 0xff; break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -1949,7 +1943,7 @@ void ARMv7_instrs::LDM(ARMv7Context& context, const ARMv7Code code, const ARMv7_ cond = context.ITSTATE.advance(); n = (code.data & 0xf0000) >> 16; reg_list = (code.data & 0xdfff); - wback = (code.data & 0x200000); + wback = (code.data & 0x200000) != 0; reject(wback && n == 13, "POP"); reject(n == 15 || BitCount(reg_list, 16) < 2 || reg_list >= 0xc000, "UNPREDICTABLE"); @@ -1957,8 +1951,8 @@ void ARMv7_instrs::LDM(ARMv7Context& context, const ARMv7Code code, const ARMv7_ reject(wback && reg_list & (1 << n), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -1969,19 +1963,19 @@ void ARMv7_instrs::LDM(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { - auto memory = vm::psv::ptr::make(context.read_gpr(n)); + auto memory = vm::ptr::make(context.read_gpr(n)); for (u32 i = 0; i < 16; i++) { if (reg_list & (1 << i)) { - context.write_gpr(i, *memory++); + context.write_gpr(i, *memory++, type == T1 ? 2 : 4); } } if (wback) { - context.write_gpr(n, memory.addr()); + context.write_gpr(n, memory.addr(), type == T1 ? 2 : 4); } } } @@ -1990,8 +1984,8 @@ void ARMv7_instrs::LDMDA(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -1999,8 +1993,8 @@ void ARMv7_instrs::LDMDB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2008,8 +2002,8 @@ void ARMv7_instrs::LDMIB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2063,9 +2057,9 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(n == 15, "LDR (literal)"); reject(index && add && !wback, "LDRT"); @@ -2074,8 +2068,8 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject((wback && n == t) || (t == 15 && context.ITSTATE), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2088,11 +2082,11 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - context.write_gpr(t, vm::psv::read32(addr)); + context.write_gpr(t, vm::read32(addr), type < T3 ? 2 : 4); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type < T3 ? 2 : 4); } } } @@ -2117,13 +2111,13 @@ void ARMv7_instrs::LDR_LIT(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); t = (code.data & 0xf000) >> 12; imm32 = (code.data & 0xfff); - add = (code.data & 0x800000); + add = (code.data & 0x800000) != 0; reject(t == 15 && context.ITSTATE, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } const u32 base = context.read_pc() & ~3; @@ -2137,8 +2131,8 @@ void ARMv7_instrs::LDR_LIT(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { - const u32 data = vm::psv::read32(addr); - context.write_gpr(t, data); + const u32 data = vm::read32(addr); + context.write_gpr(t, data, type == T1 ? 2 : 4); } } @@ -2179,8 +2173,8 @@ void ARMv7_instrs::LDR_REG(ARMv7Context& context, const ARMv7Code code, const AR reject(t == 15 && context.ITSTATE, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2194,11 +2188,11 @@ void ARMv7_instrs::LDR_REG(ARMv7Context& context, const ARMv7Code code, const AR const u32 offset = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 offset_addr = add ? context.read_gpr(n) + offset : context.read_gpr(n) - offset; const u32 addr = index ? offset_addr : context.read_gpr(n); - context.write_gpr(t, vm::psv::read32(addr)); + context.write_gpr(t, vm::read32(addr), type == T1 ? 2 : 4); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -2243,9 +2237,9 @@ void ARMv7_instrs::LDRB_IMM(ARMv7Context& context, const ARMv7Code code, const A t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(t == 15 && index && !add && !wback, "PLD"); reject(n == 15, "LDRB (literal)"); @@ -2254,8 +2248,8 @@ void ARMv7_instrs::LDRB_IMM(ARMv7Context& context, const ARMv7Code code, const A reject(t == 13 || t == 15 || (wback && n == t), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2268,11 +2262,11 @@ void ARMv7_instrs::LDRB_IMM(ARMv7Context& context, const ARMv7Code code, const A { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - context.write_gpr(t, vm::psv::read8(addr)); + context.write_gpr(t, vm::read8(addr), type == T1 ? 2 : 4); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -2281,8 +2275,8 @@ void ARMv7_instrs::LDRB_LIT(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2323,8 +2317,8 @@ void ARMv7_instrs::LDRB_REG(ARMv7Context& context, const ARMv7Code code, const A reject(t == 13 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2338,11 +2332,11 @@ void ARMv7_instrs::LDRB_REG(ARMv7Context& context, const ARMv7Code code, const A const u32 offset = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 offset_addr = add ? context.read_gpr(n) + offset : context.read_gpr(n) - offset; const u32 addr = index ? offset_addr : context.read_gpr(n); - context.write_gpr(t, vm::psv::read8(addr)); + context.write_gpr(t, vm::read8(addr), type == T1 ? 2 : 4); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -2362,9 +2356,9 @@ void ARMv7_instrs::LDRD_IMM(ARMv7Context& context, const ARMv7Code code, const A t2 = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff) << 2; - index = (code.data & 0x1000000); - add = (code.data & 0x800000); - wback = (code.data & 0x200000); + index = (code.data & 0x1000000) != 0; + add = (code.data & 0x800000) != 0; + wback = (code.data & 0x200000) != 0; reject(!index && !wback, "Related encodings"); reject(n == 15, "LDRD (literal)"); @@ -2372,8 +2366,8 @@ void ARMv7_instrs::LDRD_IMM(ARMv7Context& context, const ARMv7Code code, const A reject(t == 13 || t == 15 || t2 == 13 || t2 == 15 || t == t2, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2386,13 +2380,13 @@ void ARMv7_instrs::LDRD_IMM(ARMv7Context& context, const ARMv7Code code, const A { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - const u64 value = vm::psv::read64(addr); - context.write_gpr(t, (u32)(value)); - context.write_gpr(t2, (u32)(value >> 32)); + const u64 value = vm::read64(addr); + context.write_gpr(t, (u32)(value), 4); + context.write_gpr(t2, (u32)(value >> 32), 4); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, 4); } } } @@ -2410,14 +2404,14 @@ void ARMv7_instrs::LDRD_LIT(ARMv7Context& context, const ARMv7Code code, const A t = (code.data & 0xf000) >> 12; t2 = (code.data & 0xf00) >> 8; imm32 = (code.data & 0xff) << 2; - add = (code.data & 0x800000); + add = (code.data & 0x800000) != 0; reject(!(code.data & 0x1000000), "Related encodings"); // ??? reject(t == 13 || t == 15 || t2 == 13 || t2 == 15 || t == t2, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } const u32 base = context.read_pc() & ~3; @@ -2431,9 +2425,9 @@ void ARMv7_instrs::LDRD_LIT(ARMv7Context& context, const ARMv7Code code, const A if (ConditionPassed(context, cond)) { - const u64 value = vm::psv::read64(addr); - context.write_gpr(t, (u32)(value)); - context.write_gpr(t2, (u32)(value >> 32)); + const u64 value = vm::read64(addr); + context.write_gpr(t, (u32)(value), 4); + context.write_gpr(t2, (u32)(value >> 32), 4); } } @@ -2441,8 +2435,8 @@ void ARMv7_instrs::LDRD_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2486,9 +2480,9 @@ void ARMv7_instrs::LDRH_IMM(ARMv7Context& context, const ARMv7Code code, const A t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(n == 15, "LDRH (literal)"); reject(t == 15 && index && !add && !wback, "Unallocated memory hints"); @@ -2497,8 +2491,8 @@ void ARMv7_instrs::LDRH_IMM(ARMv7Context& context, const ARMv7Code code, const A reject(t == 13 || t == 15 || (wback && n == t), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2511,11 +2505,11 @@ void ARMv7_instrs::LDRH_IMM(ARMv7Context& context, const ARMv7Code code, const A { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - context.write_gpr(t, vm::psv::read16(addr)); + context.write_gpr(t, vm::read16(addr), type == T1 ? 2 : 4); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -2524,8 +2518,8 @@ void ARMv7_instrs::LDRH_LIT(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2533,8 +2527,8 @@ void ARMv7_instrs::LDRH_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2567,9 +2561,9 @@ void ARMv7_instrs::LDRSB_IMM(ARMv7Context& context, const ARMv7Code code, const t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(t == 15 && index && !add && !wback, "PLI"); reject(n == 15, "LDRSB (literal)"); @@ -2578,8 +2572,8 @@ void ARMv7_instrs::LDRSB_IMM(ARMv7Context& context, const ARMv7Code code, const reject(t == 13 || t == 15 || (wback && n == t), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2592,12 +2586,12 @@ void ARMv7_instrs::LDRSB_IMM(ARMv7Context& context, const ARMv7Code code, const { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - const s8 value = vm::psv::read8(addr); - context.write_gpr(t, value); // sign-extend + const s8 value = vm::read8(addr); + context.write_gpr(t, value, 4); // sign-extend if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, 4); } } } @@ -2606,8 +2600,8 @@ void ARMv7_instrs::LDRSB_LIT(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2615,8 +2609,8 @@ void ARMv7_instrs::LDRSB_REG(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2625,8 +2619,8 @@ void ARMv7_instrs::LDRSH_IMM(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2634,8 +2628,8 @@ void ARMv7_instrs::LDRSH_LIT(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2643,8 +2637,8 @@ void ARMv7_instrs::LDRSH_REG(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2665,8 +2659,8 @@ void ARMv7_instrs::LDREX(ARMv7Context& context, const ARMv7Code code, const ARMv reject(t == 13 || t == 15 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2682,7 +2676,7 @@ void ARMv7_instrs::LDREX(ARMv7Context& context, const ARMv7Code code, const ARMv u32 value; vm::reservation_acquire(&value, addr, sizeof(value)); - context.write_gpr(t, value); + context.write_gpr(t, value, 4); } } @@ -2690,8 +2684,8 @@ void ARMv7_instrs::LDREXB(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2699,8 +2693,8 @@ void ARMv7_instrs::LDREXD(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2708,8 +2702,8 @@ void ARMv7_instrs::LDREXH(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2736,15 +2730,15 @@ void ARMv7_instrs::LSL_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; DecodeImmShift(0, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(!shift_n, "MOV (register)"); reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2757,7 +2751,7 @@ void ARMv7_instrs::LSL_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry; const u32 result = Shift_C(context.read_gpr(m), SRType_LSL, shift_n, context.APSR.C, carry); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -2788,13 +2782,13 @@ void ARMv7_instrs::LSL_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2807,7 +2801,7 @@ void ARMv7_instrs::LSL_REG(ARMv7Context& context, const ARMv7Code code, const AR { bool carry; const u32 result = Shift_C(context.read_gpr(n), SRType_LSL, (context.read_gpr(m) & 0xff), context.APSR.C, carry); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -2839,14 +2833,14 @@ void ARMv7_instrs::LSR_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; DecodeImmShift(1, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -2859,7 +2853,7 @@ void ARMv7_instrs::LSR_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry; const u32 result = Shift_C(context.read_gpr(m), SRType_LSR, shift_n, context.APSR.C, carry); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -2874,8 +2868,8 @@ void ARMv7_instrs::LSR_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2884,8 +2878,8 @@ void ARMv7_instrs::MLA(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2893,8 +2887,8 @@ void ARMv7_instrs::MLS(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -2917,7 +2911,7 @@ void ARMv7_instrs::MOV_IMM(ARMv7Context& context, const ARMv7Code code, const AR case T2: { cond = context.ITSTATE.advance(); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; d = (code.data >> 8) & 0xf; imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); @@ -2934,7 +2928,7 @@ void ARMv7_instrs::MOV_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 13 || d == 15, "UNPREDICTABLE"); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -2953,7 +2947,7 @@ void ARMv7_instrs::MOV_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = imm32; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -2996,14 +2990,14 @@ void ARMv7_instrs::MOV_REG(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; reject((d == 13 || m == 13 || m == 15) && set_flags, "UNPREDICTABLE"); reject((d == 13 && (m == 13 || m == 15)) || d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3015,7 +3009,7 @@ void ARMv7_instrs::MOV_REG(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = context.read_gpr(m); - context.write_gpr(d, result); + context.write_gpr(d, result, type < T3 ? 2 : 4); if (set_flags) { @@ -3041,8 +3035,8 @@ void ARMv7_instrs::MOVT(ARMv7Context& context, const ARMv7Code code, const ARMv7 reject(d == 13 || d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3053,7 +3047,7 @@ void ARMv7_instrs::MOVT(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (ConditionPassed(context, cond)) { - context.write_gpr(d, (context.read_gpr(d) & 0xffff) | (imm16 << 16)); + context.write_gpr(d, (context.read_gpr(d) & 0xffff) | (imm16 << 16), 4); } } @@ -3062,8 +3056,8 @@ void ARMv7_instrs::MRS(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3071,8 +3065,8 @@ void ARMv7_instrs::MSR_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3080,8 +3074,8 @@ void ARMv7_instrs::MSR_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3113,8 +3107,8 @@ void ARMv7_instrs::MUL(ARMv7Context& context, const ARMv7Code code, const ARMv7_ reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3128,7 +3122,7 @@ void ARMv7_instrs::MUL(ARMv7Context& context, const ARMv7Code code, const ARMv7_ const u32 op1 = context.read_gpr(n); const u32 op2 = context.read_gpr(m); const u32 result = op1 * op2; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -3150,14 +3144,14 @@ void ARMv7_instrs::MVN_IMM(ARMv7Context& context, const ARMv7Code code, const AR { cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), context.APSR.C, carry); reject(d == 13 || d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3169,7 +3163,7 @@ void ARMv7_instrs::MVN_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = ~imm32; - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -3201,14 +3195,14 @@ void ARMv7_instrs::MVN_REG(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3222,7 +3216,7 @@ void ARMv7_instrs::MVN_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry; const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); const u32 result = ~shifted; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -3237,8 +3231,8 @@ void ARMv7_instrs::MVN_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3264,7 +3258,7 @@ void ARMv7_instrs::NOP(ARMv7Context& context, const ARMv7Code code, const ARMv7_ cond = code.data >> 28; break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -3283,8 +3277,8 @@ void ARMv7_instrs::ORN_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3292,8 +3286,8 @@ void ARMv7_instrs::ORN_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3310,15 +3304,15 @@ void ARMv7_instrs::ORR_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm_C((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff), carry, carry); reject(n == 15, "MOV (immediate)"); reject(d == 13 || d == 15 || n == 13, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3330,7 +3324,7 @@ void ARMv7_instrs::ORR_IMM(ARMv7Context& context, const ARMv7Code code, const AR if (ConditionPassed(context, cond)) { const u32 result = context.read_gpr(n) | imm32; - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -3363,15 +3357,15 @@ void ARMv7_instrs::ORR_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(n == 15, "ROR (immediate)"); reject(d == 13 || d == 15 || n == 13 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3385,7 +3379,7 @@ void ARMv7_instrs::ORR_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry; const u32 shifted = Shift_C(context.read_gpr(m), shift_t, shift_n, context.APSR.C, carry); const u32 result = context.read_gpr(n) | shifted; - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -3400,8 +3394,8 @@ void ARMv7_instrs::ORR_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3410,8 +3404,8 @@ void ARMv7_instrs::PKH(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3464,7 +3458,7 @@ void ARMv7_instrs::POP(ARMv7Context& context, const ARMv7Code code, const ARMv7_ reject(reg_list & 0x2000, "UNPREDICTABLE"); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -3475,13 +3469,13 @@ void ARMv7_instrs::POP(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { - auto stack = vm::psv::ptr::make(context.SP); + auto stack = vm::ptr::make(context.SP); for (u32 i = 0; i < 16; i++) { if (reg_list & (1 << i)) { - context.write_gpr(i, *stack++); + context.write_gpr(i, *stack++, type == T1 ? 2 : 4); } } @@ -3535,7 +3529,7 @@ void ARMv7_instrs::PUSH(ARMv7Context& context, const ARMv7Code code, const ARMv7 reject(reg_list & 0x2000, "UNPREDICTABLE"); break; } - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } if (context.debug) @@ -3546,7 +3540,7 @@ void ARMv7_instrs::PUSH(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (ConditionPassed(context, cond)) { - auto memory = vm::psv::ptr::make(context.SP); + auto memory = vm::ptr::make(context.SP); for (u32 i = 15; ~i; i--) { @@ -3565,8 +3559,8 @@ void ARMv7_instrs::QADD(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3574,8 +3568,8 @@ void ARMv7_instrs::QADD16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3583,8 +3577,8 @@ void ARMv7_instrs::QADD8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3592,8 +3586,8 @@ void ARMv7_instrs::QASX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3601,8 +3595,8 @@ void ARMv7_instrs::QDADD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3610,8 +3604,8 @@ void ARMv7_instrs::QDSUB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3619,8 +3613,8 @@ void ARMv7_instrs::QSAX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3628,8 +3622,8 @@ void ARMv7_instrs::QSUB(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3637,8 +3631,8 @@ void ARMv7_instrs::QSUB16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3646,8 +3640,8 @@ void ARMv7_instrs::QSUB8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3656,8 +3650,8 @@ void ARMv7_instrs::RBIT(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3684,8 +3678,8 @@ void ARMv7_instrs::REV(ARMv7Context& context, const ARMv7Code code, const ARMv7_ reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3696,7 +3690,7 @@ void ARMv7_instrs::REV(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { - context.write_gpr(d, re32(context.read_gpr(m))); + context.write_gpr(d, _byteswap_ulong(context.read_gpr(m)), type == T1 ? 2 : 4); } } @@ -3704,8 +3698,8 @@ void ARMv7_instrs::REV16(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3713,8 +3707,8 @@ void ARMv7_instrs::REVSH(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3731,15 +3725,15 @@ void ARMv7_instrs::ROR_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; const u32 shift_t = DecodeImmShift(3, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(shift_t == SRType_RRX, "RRX"); reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3752,7 +3746,7 @@ void ARMv7_instrs::ROR_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry; const u32 result = Shift_C(context.read_gpr(m), SRType_ROR, shift_n, context.APSR.C, carry); - context.write_gpr(d, result); + context.write_gpr(d, result, 4); if (set_flags) { @@ -3783,13 +3777,13 @@ void ARMv7_instrs::ROR_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; reject(d == 13 || d == 15 || n == 13 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3803,7 +3797,7 @@ void ARMv7_instrs::ROR_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry; const u32 shift_n = context.read_gpr(m) & 0xff; const u32 result = Shift_C(context.read_gpr(n), SRType_ROR, shift_n, context.APSR.C, carry); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -3819,8 +3813,8 @@ void ARMv7_instrs::RRX(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3845,14 +3839,14 @@ void ARMv7_instrs::RSB_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 13 || d == 15 || n == 13 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -3865,7 +3859,7 @@ void ARMv7_instrs::RSB_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry, overflow; const u32 result = AddWithCarry(~context.read_gpr(n), imm32, true, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -3881,8 +3875,8 @@ void ARMv7_instrs::RSB_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3890,8 +3884,8 @@ void ARMv7_instrs::RSB_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3900,8 +3894,8 @@ void ARMv7_instrs::RSC_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3909,8 +3903,8 @@ void ARMv7_instrs::RSC_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3918,8 +3912,8 @@ void ARMv7_instrs::RSC_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3928,8 +3922,8 @@ void ARMv7_instrs::SADD16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3937,8 +3931,8 @@ void ARMv7_instrs::SADD8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3946,8 +3940,8 @@ void ARMv7_instrs::SASX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3956,8 +3950,8 @@ void ARMv7_instrs::SBC_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3965,8 +3959,8 @@ void ARMv7_instrs::SBC_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3974,8 +3968,8 @@ void ARMv7_instrs::SBC_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3984,8 +3978,8 @@ void ARMv7_instrs::SBFX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -3994,8 +3988,8 @@ void ARMv7_instrs::SDIV(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4004,8 +3998,8 @@ void ARMv7_instrs::SEL(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4014,8 +4008,8 @@ void ARMv7_instrs::SHADD16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4023,8 +4017,8 @@ void ARMv7_instrs::SHADD8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4032,8 +4026,8 @@ void ARMv7_instrs::SHASX(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4041,8 +4035,8 @@ void ARMv7_instrs::SHSAX(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4050,8 +4044,8 @@ void ARMv7_instrs::SHSUB16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4059,8 +4053,8 @@ void ARMv7_instrs::SHSUB8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4069,8 +4063,8 @@ void ARMv7_instrs::SMLA__(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4078,8 +4072,8 @@ void ARMv7_instrs::SMLAD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4087,8 +4081,8 @@ void ARMv7_instrs::SMLAL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4096,8 +4090,8 @@ void ARMv7_instrs::SMLAL__(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4105,8 +4099,8 @@ void ARMv7_instrs::SMLALD(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4114,8 +4108,8 @@ void ARMv7_instrs::SMLAW_(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4123,8 +4117,8 @@ void ARMv7_instrs::SMLSD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4132,8 +4126,8 @@ void ARMv7_instrs::SMLSLD(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4141,8 +4135,8 @@ void ARMv7_instrs::SMMLA(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4150,8 +4144,8 @@ void ARMv7_instrs::SMMLS(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4159,8 +4153,8 @@ void ARMv7_instrs::SMMUL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4168,8 +4162,8 @@ void ARMv7_instrs::SMUAD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4177,8 +4171,8 @@ void ARMv7_instrs::SMUL__(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4186,8 +4180,8 @@ void ARMv7_instrs::SMULL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4195,8 +4189,8 @@ void ARMv7_instrs::SMULW_(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4204,8 +4198,8 @@ void ARMv7_instrs::SMUSD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4214,8 +4208,8 @@ void ARMv7_instrs::SSAT(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4223,8 +4217,8 @@ void ARMv7_instrs::SSAT16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4232,8 +4226,8 @@ void ARMv7_instrs::SSAX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4241,8 +4235,8 @@ void ARMv7_instrs::SSUB16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4250,8 +4244,8 @@ void ARMv7_instrs::SSUB8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4278,14 +4272,14 @@ void ARMv7_instrs::STM(ARMv7Context& context, const ARMv7Code code, const ARMv7_ cond = context.ITSTATE.advance(); n = (code.data & 0xf0000) >> 16; reg_list = (code.data & 0x5fff); - wback = (code.data & 0x200000); + wback = (code.data & 0x200000) != 0; reject(n == 15 || BitCount(reg_list, 16) < 2, "UNPREDICTABLE"); reject(wback && reg_list & (1 << n), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4296,7 +4290,7 @@ void ARMv7_instrs::STM(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (ConditionPassed(context, cond)) { - auto memory = vm::psv::ptr::make(context.read_gpr(n)); + auto memory = vm::ptr::make(context.read_gpr(n)); for (u32 i = 0; i < 16; i++) { @@ -4308,7 +4302,7 @@ void ARMv7_instrs::STM(ARMv7Context& context, const ARMv7Code code, const ARMv7_ if (wback) { - context.write_gpr(n, memory.addr()); + context.write_gpr(n, memory.addr(), type == T1 ? 2 : 4); } } } @@ -4317,8 +4311,8 @@ void ARMv7_instrs::STMDA(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4326,8 +4320,8 @@ void ARMv7_instrs::STMDB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4335,8 +4329,8 @@ void ARMv7_instrs::STMIB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4390,9 +4384,9 @@ void ARMv7_instrs::STR_IMM(ARMv7Context& context, const ARMv7Code code, const AR t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(index && add && !wback, "STRT"); reject(n == 13 && index && !add && wback && imm32 == 4, "PUSH"); @@ -4400,8 +4394,8 @@ void ARMv7_instrs::STR_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject(t == 15 || (wback && n == t), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4414,11 +4408,11 @@ void ARMv7_instrs::STR_IMM(ARMv7Context& context, const ARMv7Code code, const AR { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - vm::psv::write32(addr, context.read_gpr(t)); + vm::write32(addr, context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type < T3 ? 2 : 4); } } } @@ -4459,8 +4453,8 @@ void ARMv7_instrs::STR_REG(ARMv7Context& context, const ARMv7Code code, const AR reject(t == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4474,11 +4468,11 @@ void ARMv7_instrs::STR_REG(ARMv7Context& context, const ARMv7Code code, const AR const u32 offset = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 offset_addr = add ? context.read_gpr(n) + offset : context.read_gpr(n) - offset; const u32 addr = index ? offset_addr : context.read_gpr(n); - vm::psv::write32(addr, context.read_gpr(t)); + vm::write32(addr, context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -4522,17 +4516,17 @@ void ARMv7_instrs::STRB_IMM(ARMv7Context& context, const ARMv7Code code, const A t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(index && add && !wback, "STRBT"); reject(n == 15 || (!index && !wback), "UNDEFINED"); reject(t == 13 || t == 15 || (wback && n == t), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4545,11 +4539,11 @@ void ARMv7_instrs::STRB_IMM(ARMv7Context& context, const ARMv7Code code, const A { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - vm::psv::write8(addr, (u8)context.read_gpr(t)); + vm::write8(addr, (u8)context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -4590,8 +4584,8 @@ void ARMv7_instrs::STRB_REG(ARMv7Context& context, const ARMv7Code code, const A reject(t == 13 || t == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4605,11 +4599,11 @@ void ARMv7_instrs::STRB_REG(ARMv7Context& context, const ARMv7Code code, const A const u32 offset = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 offset_addr = add ? context.read_gpr(n) + offset : context.read_gpr(n) - offset; const u32 addr = index ? offset_addr : context.read_gpr(n); - vm::psv::write8(addr, (u8)context.read_gpr(t)); + vm::write8(addr, (u8)context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -4629,17 +4623,17 @@ void ARMv7_instrs::STRD_IMM(ARMv7Context& context, const ARMv7Code code, const A t2 = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff) << 2; - index = (code.data & 0x1000000); - add = (code.data & 0x800000); - wback = (code.data & 0x200000); + index = (code.data & 0x1000000) != 0; + add = (code.data & 0x800000) != 0; + wback = (code.data & 0x200000) != 0; reject(!index && !wback, "Related encodings"); reject(wback && (n == t || n == t2), "UNPREDICTABLE"); reject(n == 15 || t == 13 || t == 15 || t2 == 13 || t2 == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4653,11 +4647,11 @@ void ARMv7_instrs::STRD_IMM(ARMv7Context& context, const ARMv7Code code, const A const u32 n_value = context.read_gpr(n); const u32 offset = add ? n_value + imm32 : n_value - imm32; const u32 addr = index ? offset : n_value; - vm::psv::write64(addr, (u64)context.read_gpr(t2) << 32 | (u64)context.read_gpr(t)); + vm::write64(addr, (u64)context.read_gpr(t2) << 32 | (u64)context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset); + context.write_gpr(n, offset, 4); } } } @@ -4666,8 +4660,8 @@ void ARMv7_instrs::STRD_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4710,17 +4704,17 @@ void ARMv7_instrs::STRH_IMM(ARMv7Context& context, const ARMv7Code code, const A t = (code.data & 0xf000) >> 12; n = (code.data & 0xf0000) >> 16; imm32 = (code.data & 0xff); - index = (code.data & 0x400); - add = (code.data & 0x200); - wback = (code.data & 0x100); + index = (code.data & 0x400) != 0; + add = (code.data & 0x200) != 0; + wback = (code.data & 0x100) != 0; reject(index && add && !wback, "STRHT"); reject(n == 15 || (!index && !wback), "UNDEFINED"); reject(t == 13 || t == 15 || (wback && n == t), "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4733,11 +4727,11 @@ void ARMv7_instrs::STRH_IMM(ARMv7Context& context, const ARMv7Code code, const A { const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32; const u32 addr = index ? offset_addr : context.read_gpr(n); - vm::psv::write16(addr, (u16)context.read_gpr(t)); + vm::write16(addr, (u16)context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -4778,8 +4772,8 @@ void ARMv7_instrs::STRH_REG(ARMv7Context& context, const ARMv7Code code, const A reject(t == 13 || t == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4793,11 +4787,11 @@ void ARMv7_instrs::STRH_REG(ARMv7Context& context, const ARMv7Code code, const A const u32 offset = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 offset_addr = add ? context.read_gpr(n) + offset : context.read_gpr(n) - offset; const u32 addr = index ? offset_addr : context.read_gpr(n); - vm::psv::write16(addr, (u16)context.read_gpr(t)); + vm::write16(addr, (u16)context.read_gpr(t)); if (wback) { - context.write_gpr(n, offset_addr); + context.write_gpr(n, offset_addr, type == T1 ? 2 : 4); } } } @@ -4821,8 +4815,8 @@ void ARMv7_instrs::STREX(ARMv7Context& context, const ARMv7Code code, const ARMv reject(d == n || d == t, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4835,7 +4829,7 @@ void ARMv7_instrs::STREX(ARMv7Context& context, const ARMv7Code code, const ARMv { const u32 addr = context.read_gpr(n) + imm32; const u32 value = context.read_gpr(t); - context.write_gpr(d, !vm::reservation_update(addr, &value, sizeof(value))); + context.write_gpr(d, !vm::reservation_update(addr, &value, sizeof(value)), 4); } } @@ -4843,8 +4837,8 @@ void ARMv7_instrs::STREXB(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4852,8 +4846,8 @@ void ARMv7_instrs::STREXD(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4861,8 +4855,8 @@ void ARMv7_instrs::STREXH(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -4894,7 +4888,7 @@ void ARMv7_instrs::SUB_IMM(ARMv7Context& context, const ARMv7Code code, const AR cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMP (immediate)"); @@ -4915,8 +4909,8 @@ void ARMv7_instrs::SUB_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 13 || d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4929,7 +4923,7 @@ void ARMv7_instrs::SUB_IMM(ARMv7Context& context, const ARMv7Code code, const AR { bool carry, overflow; const u32 result = AddWithCarry(context.read_gpr(n), ~imm32, true, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type < T3 ? 2 : 4); if (set_flags) { @@ -4964,7 +4958,7 @@ void ARMv7_instrs::SUB_REG(ARMv7Context& context, const ARMv7Code code, const AR d = (code.data & 0xf00) >> 8; n = (code.data & 0xf0000) >> 16; m = (code.data & 0xf); - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n); reject(d == 15 && set_flags, "CMP (register)"); @@ -4972,8 +4966,8 @@ void ARMv7_instrs::SUB_REG(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 13 || d == 15 || n == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -4987,7 +4981,7 @@ void ARMv7_instrs::SUB_REG(ARMv7Context& context, const ARMv7Code code, const AR bool carry, overflow; const u32 shifted = Shift(context.read_gpr(m), shift_t, shift_n, context.APSR.C); const u32 result = AddWithCarry(context.read_gpr(n), ~shifted, true, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -5003,8 +4997,8 @@ void ARMv7_instrs::SUB_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5027,7 +5021,7 @@ void ARMv7_instrs::SUB_SPI(ARMv7Context& context, const ARMv7Code code, const AR { cond = context.ITSTATE.advance(); d = (code.data & 0xf00) >> 8; - set_flags = (code.data & 0x100000); + set_flags = (code.data & 0x100000) != 0; imm32 = ThumbExpandImm((code.data & 0x4000000) >> 15 | (code.data & 0x7000) >> 4 | (code.data & 0xff)); reject(d == 15 && set_flags, "CMP (immediate)"); @@ -5044,8 +5038,8 @@ void ARMv7_instrs::SUB_SPI(ARMv7Context& context, const ARMv7Code code, const AR reject(d == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -5058,7 +5052,7 @@ void ARMv7_instrs::SUB_SPI(ARMv7Context& context, const ARMv7Code code, const AR { bool carry, overflow; const u32 result = AddWithCarry(context.SP, ~imm32, true, carry, overflow); - context.write_gpr(d, result); + context.write_gpr(d, result, type == T1 ? 2 : 4); if (set_flags) { @@ -5074,8 +5068,8 @@ void ARMv7_instrs::SUB_SPR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5084,8 +5078,8 @@ void ARMv7_instrs::SVC(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5094,8 +5088,8 @@ void ARMv7_instrs::SXTAB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5103,8 +5097,8 @@ void ARMv7_instrs::SXTAB16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5112,8 +5106,8 @@ void ARMv7_instrs::SXTAH(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5121,8 +5115,8 @@ void ARMv7_instrs::SXTB(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5130,8 +5124,8 @@ void ARMv7_instrs::SXTB16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5139,8 +5133,8 @@ void ARMv7_instrs::SXTH(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5149,8 +5143,8 @@ void ARMv7_instrs::TB_(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5159,8 +5153,8 @@ void ARMv7_instrs::TEQ_IMM(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5168,8 +5162,8 @@ void ARMv7_instrs::TEQ_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5177,8 +5171,8 @@ void ARMv7_instrs::TEQ_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5199,8 +5193,8 @@ void ARMv7_instrs::TST_IMM(ARMv7Context& context, const ARMv7Code code, const AR reject(n == 13 || n == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -5222,8 +5216,8 @@ void ARMv7_instrs::TST_REG(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5231,8 +5225,8 @@ void ARMv7_instrs::TST_RSR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5241,8 +5235,8 @@ void ARMv7_instrs::UADD16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5250,8 +5244,8 @@ void ARMv7_instrs::UADD8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5259,8 +5253,8 @@ void ARMv7_instrs::UASX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5268,8 +5262,8 @@ void ARMv7_instrs::UBFX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5277,8 +5271,8 @@ void ARMv7_instrs::UDIV(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5286,8 +5280,8 @@ void ARMv7_instrs::UHADD16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5295,8 +5289,8 @@ void ARMv7_instrs::UHADD8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5304,8 +5298,8 @@ void ARMv7_instrs::UHASX(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5313,8 +5307,8 @@ void ARMv7_instrs::UHSAX(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5322,8 +5316,8 @@ void ARMv7_instrs::UHSUB16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5331,8 +5325,8 @@ void ARMv7_instrs::UHSUB8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5340,8 +5334,8 @@ void ARMv7_instrs::UMAAL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5349,8 +5343,8 @@ void ARMv7_instrs::UMLAL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5374,8 +5368,8 @@ void ARMv7_instrs::UMULL(ARMv7Context& context, const ARMv7Code code, const ARMv reject(d0 == d1, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -5387,8 +5381,8 @@ void ARMv7_instrs::UMULL(ARMv7Context& context, const ARMv7Code code, const ARMv if (ConditionPassed(context, cond)) { const u64 result = (u64)context.read_gpr(n) * (u64)context.read_gpr(m); - context.write_gpr(d1, (u32)(result >> 32)); - context.write_gpr(d0, (u32)(result)); + context.write_gpr(d1, (u32)(result >> 32), 4); + context.write_gpr(d0, (u32)(result), 4); if (set_flags) { @@ -5402,8 +5396,8 @@ void ARMv7_instrs::UQADD16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5411,8 +5405,8 @@ void ARMv7_instrs::UQADD8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5420,8 +5414,8 @@ void ARMv7_instrs::UQASX(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5429,8 +5423,8 @@ void ARMv7_instrs::UQSAX(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5438,8 +5432,8 @@ void ARMv7_instrs::UQSUB16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5447,8 +5441,8 @@ void ARMv7_instrs::UQSUB8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5456,8 +5450,8 @@ void ARMv7_instrs::USAD8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5465,8 +5459,8 @@ void ARMv7_instrs::USADA8(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5474,8 +5468,8 @@ void ARMv7_instrs::USAT(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5483,8 +5477,8 @@ void ARMv7_instrs::USAT16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5492,8 +5486,8 @@ void ARMv7_instrs::USAX(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5501,8 +5495,8 @@ void ARMv7_instrs::USUB16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5510,8 +5504,8 @@ void ARMv7_instrs::USUB8(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5519,8 +5513,8 @@ void ARMv7_instrs::UXTAB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5528,8 +5522,8 @@ void ARMv7_instrs::UXTAB16(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5537,8 +5531,8 @@ void ARMv7_instrs::UXTAH(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5566,8 +5560,8 @@ void ARMv7_instrs::UXTB(ARMv7Context& context, const ARMv7Code code, const ARMv7 reject(d == 13 || d == 15 || m == 13 || m == 15, "UNPREDICTABLE"); break; } - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } if (context.debug) @@ -5578,7 +5572,7 @@ void ARMv7_instrs::UXTB(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (ConditionPassed(context, cond)) { - context.write_gpr(d, (context.read_gpr(m) >> rot) & 0xff); + context.write_gpr(d, (context.read_gpr(m) >> rot) & 0xff, type == T1 ? 2 : 4); } } @@ -5586,8 +5580,8 @@ void ARMv7_instrs::UXTB16(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5595,8 +5589,8 @@ void ARMv7_instrs::UXTH(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5605,8 +5599,8 @@ void ARMv7_instrs::VABA_(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5614,8 +5608,8 @@ void ARMv7_instrs::VABD_(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5623,8 +5617,8 @@ void ARMv7_instrs::VABD_FP(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5632,8 +5626,8 @@ void ARMv7_instrs::VABS(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5641,8 +5635,8 @@ void ARMv7_instrs::VAC__(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5650,8 +5644,8 @@ void ARMv7_instrs::VADD(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5659,8 +5653,8 @@ void ARMv7_instrs::VADD_FP(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5668,8 +5662,8 @@ void ARMv7_instrs::VADDHN(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5677,8 +5671,8 @@ void ARMv7_instrs::VADD_(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5686,8 +5680,8 @@ void ARMv7_instrs::VAND(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5695,8 +5689,8 @@ void ARMv7_instrs::VBIC_IMM(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5704,8 +5698,8 @@ void ARMv7_instrs::VBIC_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5713,8 +5707,8 @@ void ARMv7_instrs::VB__(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5722,8 +5716,8 @@ void ARMv7_instrs::VCEQ_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5731,8 +5725,8 @@ void ARMv7_instrs::VCEQ_ZERO(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5740,8 +5734,8 @@ void ARMv7_instrs::VCGE_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5749,8 +5743,8 @@ void ARMv7_instrs::VCGE_ZERO(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5758,8 +5752,8 @@ void ARMv7_instrs::VCGT_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5767,8 +5761,8 @@ void ARMv7_instrs::VCGT_ZERO(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5776,8 +5770,8 @@ void ARMv7_instrs::VCLE_ZERO(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5785,8 +5779,8 @@ void ARMv7_instrs::VCLS(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5794,8 +5788,8 @@ void ARMv7_instrs::VCLT_ZERO(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5803,8 +5797,8 @@ void ARMv7_instrs::VCLZ(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5812,8 +5806,8 @@ void ARMv7_instrs::VCMP_(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5821,8 +5815,8 @@ void ARMv7_instrs::VCNT(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5830,8 +5824,8 @@ void ARMv7_instrs::VCVT_FIA(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5839,8 +5833,8 @@ void ARMv7_instrs::VCVT_FIF(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5848,8 +5842,8 @@ void ARMv7_instrs::VCVT_FFA(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5857,8 +5851,8 @@ void ARMv7_instrs::VCVT_FFF(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5866,8 +5860,8 @@ void ARMv7_instrs::VCVT_DF(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5875,8 +5869,8 @@ void ARMv7_instrs::VCVT_HFA(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5884,8 +5878,8 @@ void ARMv7_instrs::VCVT_HFF(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5893,8 +5887,8 @@ void ARMv7_instrs::VDIV(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5902,8 +5896,8 @@ void ARMv7_instrs::VDUP_S(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5911,8 +5905,8 @@ void ARMv7_instrs::VDUP_R(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5920,8 +5914,8 @@ void ARMv7_instrs::VEOR(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5929,8 +5923,8 @@ void ARMv7_instrs::VEXT(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5938,8 +5932,8 @@ void ARMv7_instrs::VHADDSUB(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5947,8 +5941,8 @@ void ARMv7_instrs::VLD__MS(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5956,8 +5950,8 @@ void ARMv7_instrs::VLD1_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5965,8 +5959,8 @@ void ARMv7_instrs::VLD1_SAL(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5974,8 +5968,8 @@ void ARMv7_instrs::VLD2_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5983,8 +5977,8 @@ void ARMv7_instrs::VLD2_SAL(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -5992,8 +5986,8 @@ void ARMv7_instrs::VLD3_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6001,8 +5995,8 @@ void ARMv7_instrs::VLD3_SAL(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6010,8 +6004,8 @@ void ARMv7_instrs::VLD4_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6019,8 +6013,8 @@ void ARMv7_instrs::VLD4_SAL(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6028,8 +6022,8 @@ void ARMv7_instrs::VLDM(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6037,8 +6031,8 @@ void ARMv7_instrs::VLDR(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6046,8 +6040,8 @@ void ARMv7_instrs::VMAXMIN(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6055,8 +6049,8 @@ void ARMv7_instrs::VMAXMIN_FP(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6064,8 +6058,8 @@ void ARMv7_instrs::VML__(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6073,8 +6067,8 @@ void ARMv7_instrs::VML__FP(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6082,8 +6076,8 @@ void ARMv7_instrs::VML__S(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6091,8 +6085,8 @@ void ARMv7_instrs::VMOV_IMM(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6100,8 +6094,8 @@ void ARMv7_instrs::VMOV_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6109,8 +6103,8 @@ void ARMv7_instrs::VMOV_RS(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6118,8 +6112,8 @@ void ARMv7_instrs::VMOV_SR(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6127,8 +6121,8 @@ void ARMv7_instrs::VMOV_RF(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6136,8 +6130,8 @@ void ARMv7_instrs::VMOV_2RF(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6145,8 +6139,8 @@ void ARMv7_instrs::VMOV_2RD(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6154,8 +6148,8 @@ void ARMv7_instrs::VMOVL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6163,8 +6157,8 @@ void ARMv7_instrs::VMOVN(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6172,8 +6166,8 @@ void ARMv7_instrs::VMRS(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6181,8 +6175,8 @@ void ARMv7_instrs::VMSR(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6190,8 +6184,8 @@ void ARMv7_instrs::VMUL_(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6199,8 +6193,8 @@ void ARMv7_instrs::VMUL_FP(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6208,8 +6202,8 @@ void ARMv7_instrs::VMUL_S(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6217,8 +6211,8 @@ void ARMv7_instrs::VMVN_IMM(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6226,8 +6220,8 @@ void ARMv7_instrs::VMVN_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6235,8 +6229,8 @@ void ARMv7_instrs::VNEG(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6244,8 +6238,8 @@ void ARMv7_instrs::VNM__(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6253,8 +6247,8 @@ void ARMv7_instrs::VORN_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6262,8 +6256,8 @@ void ARMv7_instrs::VORR_IMM(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6271,8 +6265,8 @@ void ARMv7_instrs::VORR_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6280,8 +6274,8 @@ void ARMv7_instrs::VPADAL(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6289,8 +6283,8 @@ void ARMv7_instrs::VPADD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6298,8 +6292,8 @@ void ARMv7_instrs::VPADD_FP(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6307,8 +6301,8 @@ void ARMv7_instrs::VPADDL(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6316,8 +6310,8 @@ void ARMv7_instrs::VPMAXMIN(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6325,8 +6319,8 @@ void ARMv7_instrs::VPMAXMIN_FP(ARMv7Context& context, const ARMv7Code code, cons { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6334,8 +6328,8 @@ void ARMv7_instrs::VPOP(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6343,8 +6337,8 @@ void ARMv7_instrs::VPUSH(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6352,8 +6346,8 @@ void ARMv7_instrs::VQABS(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6361,8 +6355,8 @@ void ARMv7_instrs::VQADD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6370,8 +6364,8 @@ void ARMv7_instrs::VQDML_L(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6379,8 +6373,8 @@ void ARMv7_instrs::VQDMULH(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6388,8 +6382,8 @@ void ARMv7_instrs::VQDMULL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6397,8 +6391,8 @@ void ARMv7_instrs::VQMOV_N(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6406,8 +6400,8 @@ void ARMv7_instrs::VQNEG(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6415,8 +6409,8 @@ void ARMv7_instrs::VQRDMULH(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6424,8 +6418,8 @@ void ARMv7_instrs::VQRSHL(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6433,8 +6427,8 @@ void ARMv7_instrs::VQRSHR_N(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6442,8 +6436,8 @@ void ARMv7_instrs::VQSHL_REG(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6451,8 +6445,8 @@ void ARMv7_instrs::VQSHL_IMM(ARMv7Context& context, const ARMv7Code code, const { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6460,8 +6454,8 @@ void ARMv7_instrs::VQSHR_N(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6469,8 +6463,8 @@ void ARMv7_instrs::VQSUB(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6478,8 +6472,8 @@ void ARMv7_instrs::VRADDHN(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6487,8 +6481,8 @@ void ARMv7_instrs::VRECPE(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6496,8 +6490,8 @@ void ARMv7_instrs::VRECPS(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6505,8 +6499,8 @@ void ARMv7_instrs::VREV__(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6514,8 +6508,8 @@ void ARMv7_instrs::VRHADD(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6523,8 +6517,8 @@ void ARMv7_instrs::VRSHL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6532,8 +6526,8 @@ void ARMv7_instrs::VRSHR(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6541,8 +6535,8 @@ void ARMv7_instrs::VRSHRN(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6550,8 +6544,8 @@ void ARMv7_instrs::VRSQRTE(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6559,8 +6553,8 @@ void ARMv7_instrs::VRSQRTS(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6568,8 +6562,8 @@ void ARMv7_instrs::VRSRA(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6577,8 +6571,8 @@ void ARMv7_instrs::VRSUBHN(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6586,8 +6580,8 @@ void ARMv7_instrs::VSHL_IMM(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6595,8 +6589,8 @@ void ARMv7_instrs::VSHL_REG(ARMv7Context& context, const ARMv7Code code, const A { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6604,8 +6598,8 @@ void ARMv7_instrs::VSHLL(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6613,8 +6607,8 @@ void ARMv7_instrs::VSHR(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6622,8 +6616,8 @@ void ARMv7_instrs::VSHRN(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6631,8 +6625,8 @@ void ARMv7_instrs::VSLI(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6640,8 +6634,8 @@ void ARMv7_instrs::VSQRT(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6649,8 +6643,8 @@ void ARMv7_instrs::VSRA(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6658,8 +6652,8 @@ void ARMv7_instrs::VSRI(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6667,8 +6661,8 @@ void ARMv7_instrs::VST__MS(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6676,8 +6670,8 @@ void ARMv7_instrs::VST1_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6685,8 +6679,8 @@ void ARMv7_instrs::VST2_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6694,8 +6688,8 @@ void ARMv7_instrs::VST3_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6703,8 +6697,8 @@ void ARMv7_instrs::VST4_SL(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6712,8 +6706,8 @@ void ARMv7_instrs::VSTM(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6721,8 +6715,8 @@ void ARMv7_instrs::VSTR(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6730,8 +6724,8 @@ void ARMv7_instrs::VSUB(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6739,8 +6733,8 @@ void ARMv7_instrs::VSUB_FP(ARMv7Context& context, const ARMv7Code code, const AR { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6748,8 +6742,8 @@ void ARMv7_instrs::VSUBHN(ARMv7Context& context, const ARMv7Code code, const ARM { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6757,8 +6751,8 @@ void ARMv7_instrs::VSUB_(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6766,8 +6760,8 @@ void ARMv7_instrs::VSWP(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6775,8 +6769,8 @@ void ARMv7_instrs::VTB_(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6784,8 +6778,8 @@ void ARMv7_instrs::VTRN(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6793,8 +6787,8 @@ void ARMv7_instrs::VTST(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6802,8 +6796,8 @@ void ARMv7_instrs::VUZP(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6811,8 +6805,8 @@ void ARMv7_instrs::VZIP(ARMv7Context& context, const ARMv7Code code, const ARMv7 { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6821,8 +6815,8 @@ void ARMv7_instrs::WFE(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6830,8 +6824,8 @@ void ARMv7_instrs::WFI(ARMv7Context& context, const ARMv7Code code, const ARMv7_ { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } @@ -6839,7 +6833,7 @@ void ARMv7_instrs::YIELD(ARMv7Context& context, const ARMv7Code code, const ARMv { switch (type) { - case A1: throw __FUNCTION__; - default: throw __FUNCTION__; + case A1: throw EXCEPTION(""); + default: throw EXCEPTION(""); } } diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index 90a56e2187..e77563ecdd 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -3,32 +3,17 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/CPU/CPUThreadManager.h" +#include "Emu/IdManager.h" +#include "Emu/ARMv7/PSVFuncList.h" #include "ARMv7Thread.h" #include "ARMv7Decoder.h" #include "ARMv7DisAsm.h" #include "ARMv7Interpreter.h" -void ARMv7Context::write_pc(u32 value) -{ - ISET = value & 1 ? Thumb : ARM; - thread.SetBranch(value & ~1); -} - -u32 ARMv7Context::read_pc() -{ - return ISET == ARM ? thread.PC + 8 : thread.PC + 4; -} - -u32 ARMv7Context::get_stack_arg(u32 pos) -{ - return vm::psv::read32(SP + sizeof(u32) * (pos - 5)); -} - void ARMv7Context::fast_call(u32 addr) { - return thread.FastCall(addr); + return static_cast(this)->FastCall(addr); } #define TLS_MAX 128 @@ -74,7 +59,7 @@ u32 armv7_get_tls(u32 thread) } } - throw "Out of TLS memory"; + throw EXCEPTION("Out of TLS memory"); } void armv7_free_tls(u32 thread) @@ -94,71 +79,93 @@ void armv7_free_tls(u32 thread) } } -ARMv7Thread::ARMv7Thread() - : CPUThread(CPU_THREAD_ARMv7) - , context(*this) - //, m_arg(0) - //, m_last_instr_size(0) - //, m_last_instr_name("UNK") +ARMv7Thread::ARMv7Thread(const std::string& name) + : CPUThread(CPU_THREAD_ARMv7, name, WRAP_EXPR(fmt::format("ARMv7[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC))) + , ARMv7Context({}) { } ARMv7Thread::~ARMv7Thread() { + cv.notify_one(); + join(); + + CloseStack(); armv7_free_tls(GetId()); } +void ARMv7Thread::DumpInformation() const +{ + if (hle_func) + { + const auto func = get_psv_func_by_nid(hle_func); + + LOG_SUCCESS(HLE, "Information: function 0x%x (%s)", hle_func, func ? func->name : "?????????"); + } + + CPUThread::DumpInformation(); +} + void ARMv7Thread::InitRegs() { - memset(context.GPR, 0, sizeof(context.GPR)); - context.APSR.APSR = 0; - context.IPSR.IPSR = 0; - context.ISET = PC & 1 ? Thumb : ARM; // select instruction set - context.thread.SetPc(PC & ~1); // and fix PC - context.ITSTATE.IT = 0; - context.SP = m_stack_addr + m_stack_size; - context.TLS = armv7_get_tls(GetId()); - context.debug |= DF_DISASM | DF_PRINT; + memset(GPR, 0, sizeof(GPR)); + APSR.APSR = 0; + IPSR.IPSR = 0; + ISET = PC & 1 ? Thumb : ARM; // select instruction set + PC = PC & ~1; // and fix PC + ITSTATE.IT = 0; + SP = stack_addr + stack_size; + TLS = armv7_get_tls(GetId()); + debug = DF_DISASM | DF_PRINT; } void ARMv7Thread::InitStack() { - if (!m_stack_addr) + if (!stack_addr) { - assert(m_stack_size); - m_stack_addr = Memory.Alloc(m_stack_size, 4096); + if (!stack_size) + { + throw EXCEPTION("Invalid stack size"); + } + + stack_addr = Memory.Alloc(stack_size, 4096); + + if (!stack_addr) + { + throw EXCEPTION("Out of stack memory"); + } } } void ARMv7Thread::CloseStack() { - if (m_stack_addr) + if (stack_addr) { - Memory.Free(m_stack_addr); - m_stack_addr = 0; + Memory.Free(stack_addr); + stack_addr = 0; } } -std::string ARMv7Thread::RegsToString() +std::string ARMv7Thread::RegsToString() const { std::string result = "Registers:\n=========\n"; for(int i=0; i<15; ++i) { - result += fmt::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], context.GPR[i]); + result += fmt::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], GPR[i]); } result += fmt::Format("APSR\t= 0x%08x [N: %d, Z: %d, C: %d, V: %d, Q: %d]\n", - context.APSR.APSR, - fmt::by_value(context.APSR.N), - fmt::by_value(context.APSR.Z), - fmt::by_value(context.APSR.C), - fmt::by_value(context.APSR.V), - fmt::by_value(context.APSR.Q)); + APSR.APSR, + fmt::by_value(APSR.N), + fmt::by_value(APSR.Z), + fmt::by_value(APSR.C), + fmt::by_value(APSR.V), + fmt::by_value(APSR.Q)); return result; } -std::string ARMv7Thread::ReadRegString(const std::string& reg) +std::string ARMv7Thread::ReadRegString(const std::string& reg) const { return ""; } @@ -168,19 +175,15 @@ bool ARMv7Thread::WriteRegString(const std::string& reg, std::string value) return true; } -void ARMv7Thread::DoReset() -{ -} - void ARMv7Thread::DoRun() { - m_dec = nullptr; + m_dec.reset(); switch(Ini.CPUDecoderMode.GetValue()) { case 0: case 1: - m_dec = new ARMv7Decoder(context); + m_dec.reset(new ARMv7Decoder(*this)); break; default: LOG_ERROR(PPU, "Invalid CPU decoder mode: %d", Ini.CPUDecoderMode.GetValue()); @@ -188,58 +191,75 @@ void ARMv7Thread::DoRun() } } -void ARMv7Thread::DoPause() +void ARMv7Thread::Task() { -} + if (custom_task) + { + if (m_state.load() && CheckStatus()) return; -void ARMv7Thread::DoResume() -{ -} + return custom_task(*this); + } -void ARMv7Thread::DoStop() -{ -} + while (true) + { + if (m_state.load() && CheckStatus()) break; -void ARMv7Thread::DoCode() -{ + // decode instruction using specified decoder + PC += m_dec->DecodeMemory(PC); + } } void ARMv7Thread::FastCall(u32 addr) { - auto old_status = m_status; + if (!is_current()) + { + throw EXCEPTION("Called from the wrong thread"); + } + auto old_PC = PC; - auto old_stack = context.SP; - auto old_LR = context.LR; - auto old_thread = GetCurrentNamedThread(); + auto old_stack = SP; + auto old_LR = LR; + auto old_task = decltype(custom_task)(); - m_status = Running; PC = addr; - context.LR = Emu.GetCPUThreadStop(); - SetCurrentNamedThread(this); + LR = Emu.GetCPUThreadStop(); + custom_task.swap(old_task); - CPUThread::Task(); + try + { + Task(); + } + catch (CPUThreadReturn) + { + } + + m_state &= ~CPU_STATE_RETURN; - m_status = old_status; PC = old_PC; - context.SP = old_stack; - context.LR = old_LR; - SetCurrentNamedThread(old_thread); + + if (SP != old_stack) // SP shouldn't change + { + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=0x%x, old=0x%x)", addr, SP, old_stack); + } + + LR = old_LR; + custom_task.swap(old_task); } void ARMv7Thread::FastStop() { - m_status = Stopped; - m_events |= CPU_EVENT_STOP; + m_state |= CPU_STATE_RETURN; } armv7_thread::armv7_thread(u32 entry, const std::string& name, u32 stack_size, s32 prio) { - thread = Emu.GetCPU().AddThread(CPU_THREAD_ARMv7); + std::shared_ptr armv7 = Emu.GetIdManager().make_ptr(name); - thread->SetName(name); - thread->SetEntry(entry); - thread->SetStackSize(stack_size); - thread->SetPrio(prio); + armv7->PC = entry; + armv7->stack_size = stack_size; + armv7->prio = prio; + + thread = std::move(armv7); argc = 0; } @@ -284,8 +304,8 @@ cpu_thread& armv7_thread::run() armv7.Run(); // set arguments - armv7.context.GPR[0] = argc; - armv7.context.GPR[1] = argv; + armv7.GPR[0] = argc; + armv7.GPR[1] = argv; return *this; } diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.h b/rpcs3/Emu/ARMv7/ARMv7Thread.h index 5bbc4a564c..dca801d622 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.h +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.h @@ -2,35 +2,31 @@ #include "Emu/CPU/CPUThread.h" #include "ARMv7Context.h" -class ARMv7Thread : public CPUThread +class ARMv7Thread final : public CPUThread, public ARMv7Context { public: - ARMv7Context context; - - ARMv7Thread(); - ~ARMv7Thread(); + std::function custom_task; public: - virtual void InitRegs(); - virtual void InitStack(); - virtual void CloseStack(); + ARMv7Thread(const std::string& name); + virtual ~ARMv7Thread() override; + + virtual void DumpInformation() const override; + virtual u32 GetPC() const override { return PC; } + virtual u32 GetOffset() const override { return 0; } + virtual void DoRun() override; + virtual void Task() override; + + virtual void InitRegs() override; + virtual void InitStack() override; + virtual void CloseStack() override; u32 GetStackArg(u32 pos); void FastCall(u32 addr); void FastStop(); - virtual void DoRun(); -public: - virtual std::string RegsToString(); - virtual std::string ReadRegString(const std::string& reg); - virtual bool WriteRegString(const std::string& reg, std::string value); - -protected: - virtual void DoReset(); - virtual void DoPause(); - virtual void DoResume(); - virtual void DoStop(); - - virtual void DoCode(); + virtual std::string RegsToString() const override; + virtual std::string ReadRegString(const std::string& reg) const override; + virtual bool WriteRegString(const std::string& reg, std::string value) override; }; class armv7_thread : cpu_thread diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp b/rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp index 5b39017a62..bc0d63c2b0 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceAppMgr.cpp @@ -2,33 +2,26 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceAppMgr; +#include "sceAppMgr.h" -struct SceAppMgrEvent +s32 sceAppMgrReceiveEventNum(vm::ptr eventNum) { - s32 event; - s32 appId; - char param[56]; -}; - -s32 sceAppMgrReceiveEventNum(vm::psv::ptr eventNum) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppMgrReceiveEvent(vm::psv::ptr appEvent) +s32 sceAppMgrReceiveEvent(vm::ptr appEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAppMgrAcquireBgmPort() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAppMgrReleaseBgmPort() { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -39,6 +32,7 @@ psv_log_base sceAppMgr("SceAppMgr", []() sceAppMgr.on_load = nullptr; sceAppMgr.on_unload = nullptr; sceAppMgr.on_stop = nullptr; + sceAppMgr.on_error = nullptr; REG_FUNC(0x47E5DD7D, sceAppMgrReceiveEventNum); REG_FUNC(0xCFAD5A3A, sceAppMgrReceiveEvent); diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppMgr.h b/rpcs3/Emu/ARMv7/Modules/sceAppMgr.h new file mode 100644 index 0000000000..8329b62e14 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceAppMgr.h @@ -0,0 +1,10 @@ +#pragma once + +struct SceAppMgrEvent +{ + le_t event; + le_t appId; + char param[56]; +}; + +extern psv_log_base sceAppMgr; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp b/rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp index 815efa0461..f05c91b0ec 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceAppUtil.cpp @@ -4,69 +4,69 @@ #include "sceAppUtil.h" -s32 sceAppUtilInit(vm::psv::ptr initParam, vm::psv::ptr bootParam) +s32 sceAppUtilInit(vm::cptr initParam, vm::ptr bootParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAppUtilShutdown() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSaveDataSlotCreate(u32 slotId, vm::psv::ptr param, vm::psv::ptr mountPoint) +s32 sceAppUtilSaveDataSlotCreate(u32 slotId, vm::cptr param, vm::cptr mountPoint) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSaveDataSlotDelete(u32 slotId, vm::psv::ptr mountPoint) +s32 sceAppUtilSaveDataSlotDelete(u32 slotId, vm::cptr mountPoint) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSaveDataSlotSetParam(u32 slotId, vm::psv::ptr param, vm::psv::ptr mountPoint) +s32 sceAppUtilSaveDataSlotSetParam(u32 slotId, vm::cptr param, vm::cptr mountPoint) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSaveDataSlotGetParam(u32 slotId, vm::psv::ptr param, vm::psv::ptr mountPoint) +s32 sceAppUtilSaveDataSlotGetParam(u32 slotId, vm::ptr param, vm::cptr mountPoint) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSaveDataFileSave(vm::psv::ptr slot, vm::psv::ptr files, u32 fileNum, vm::psv::ptr mountPoint, vm::psv::ptr requiredSizeKB) +s32 sceAppUtilSaveDataFileSave(vm::cptr slot, vm::cptr files, u32 fileNum, vm::cptr mountPoint, vm::ptr requiredSizeKB) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAppUtilPhotoMount() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAppUtilPhotoUmount() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSystemParamGetInt(u32 paramId, vm::psv::ptr value) +s32 sceAppUtilSystemParamGetInt(u32 paramId, vm::ptr value) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSystemParamGetString(u32 paramId, vm::psv::ptr buf, u32 bufSize) +s32 sceAppUtilSystemParamGetString(u32 paramId, vm::ptr buf, u32 bufSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilSaveSafeMemory(vm::psv::ptr buf, u32 bufSize, s64 offset) +s32 sceAppUtilSaveSafeMemory(vm::cptr buf, u32 bufSize, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAppUtilLoadSafeMemory(vm::psv::ptr buf, u32 bufSize, s64 offset) +s32 sceAppUtilLoadSafeMemory(vm::ptr buf, u32 bufSize, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -77,6 +77,7 @@ psv_log_base sceAppUtil("SceAppUtil", []() sceAppUtil.on_load = nullptr; sceAppUtil.on_unload = nullptr; sceAppUtil.on_stop = nullptr; + sceAppUtil.on_error = nullptr; REG_FUNC(0xDAFFE671, sceAppUtilInit); REG_FUNC(0xB220B00B, sceAppUtilShutdown); diff --git a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.h b/rpcs3/Emu/ARMv7/Modules/sceAppUtil.h index 2e489cab22..b3e9fc4448 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAppUtil.h +++ b/rpcs3/Emu/ARMv7/Modules/sceAppUtil.h @@ -2,14 +2,14 @@ struct SceAppUtilInitParam { - u32 workBufSize; + le_t workBufSize; char reserved[60]; }; struct SceAppUtilBootParam { - u32 attr; - u32 appVersion; + le_t attr; + le_t appVersion; char reserved[32]; }; @@ -20,49 +20,49 @@ struct SceAppUtilSaveDataMountPoint struct SceAppUtilSaveDataSlotParam { - u32 status; + le_t status; char title[64]; char subTitle[128]; char detail[512]; char iconPath[64]; - s32 userParam; - u32 sizeKB; + le_t userParam; + le_t sizeKB; SceDateTime modifiedTime; char reserved[48]; }; struct SceAppUtilSaveDataSlotEmptyParam { - vm::psv::ptr title; - vm::psv::ptr iconPath; - vm::psv::ptr iconBuf; - u32 iconBufSize; + vm::lptr title; + vm::lptr iconPath; + vm::lptr iconBuf; + le_t iconBufSize; char reserved[32]; }; struct SceAppUtilSaveDataSlot { - u32 id; - u32 status; - s32 userParam; - vm::psv::ptr emptyParam; + le_t id; + le_t status; + le_t userParam; + vm::lptr emptyParam; }; struct SceAppUtilSaveDataFile { - vm::psv::ptr filePath; - vm::psv::ptr buf; - u32 bufSize; - s64 offset; - u32 mode; - u32 progDelta; + vm::lcptr filePath; + vm::lptr buf; + le_t bufSize; + le_t offset; + le_t mode; + le_t progDelta; char reserved[32]; }; struct SceAppUtilSaveDataFileSlot { - u32 id; - vm::psv::ptr slotParam; + le_t id; + vm::lptr slotParam; char reserved[32]; }; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudio.cpp b/rpcs3/Emu/ARMv7/Modules/sceAudio.cpp index ad0ab8d9af..c4107eef55 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudio.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceAudio.cpp @@ -2,46 +2,46 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceAudio; +#include "sceAudio.h" s32 sceAudioOutOpenPort(s32 portType, s32 len, s32 freq, s32 param) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioOutReleasePort(s32 port) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioOutOutput(s32 port, vm::psv::ptr ptr) +s32 sceAudioOutOutput(s32 port, vm::ptr ptr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioOutSetVolume(s32 port, s32 flag, vm::psv::ptr vol) +s32 sceAudioOutSetVolume(s32 port, s32 flag, vm::ptr vol) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioOutSetConfig(s32 port, s32 len, s32 freq, s32 param) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioOutGetConfig(s32 port, s32 configType) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioOutGetRestSample(s32 port) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioOutGetAdopt(s32 portType) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -52,6 +52,7 @@ psv_log_base sceAudio("SceAudio", []() sceAudio.on_load = nullptr; sceAudio.on_unload = nullptr; sceAudio.on_stop = nullptr; + sceAudio.on_error = nullptr; REG_FUNC(0x5BC341E4, sceAudioOutOpenPort); REG_FUNC(0x69E2E6B5, sceAudioOutReleasePort); diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudio.h b/rpcs3/Emu/ARMv7/Modules/sceAudio.h new file mode 100644 index 0000000000..f6c654b5d0 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceAudio.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceAudio; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp b/rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp index 29c7378b33..03523adbd2 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceAudioIn.cpp @@ -2,21 +2,21 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceAudioIn; +#include "sceAudioIn.h" s32 sceAudioInOpenPort(s32 portType, s32 grain, s32 freq, s32 param) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioInReleasePort(s32 port) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioInInput(s32 port, vm::psv::ptr destPtr) +s32 sceAudioInInput(s32 port, vm::ptr destPtr) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -27,6 +27,7 @@ psv_log_base sceAudioIn("SceAudioIn", []() sceAudioIn.on_load = nullptr; sceAudioIn.on_unload = nullptr; sceAudioIn.on_stop = nullptr; + sceAudioIn.on_error = nullptr; REG_FUNC(0x638ADD2D, sceAudioInInput); REG_FUNC(0x39B50DC1, sceAudioInOpenPort); diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioIn.h b/rpcs3/Emu/ARMv7/Modules/sceAudioIn.h new file mode 100644 index 0000000000..ff85239855 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceAudioIn.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceAudioIn; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp b/rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp index bf0d1a6bf9..abb147a619 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceAudiodec.cpp @@ -2,121 +2,41 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceAudiodec; +#include "sceAudiodec.h" -struct SceAudiodecInitStreamParam +s32 sceAudiodecInitLibrary(u32 codecType, vm::ptr pInitParam) { - u32 size; - u32 totalStreams; -}; - -struct SceAudiodecInitChParam -{ - u32 size; - u32 totalCh; -}; - -union SceAudiodecInitParam -{ - u32 size; - SceAudiodecInitChParam at9; - SceAudiodecInitStreamParam mp3; - SceAudiodecInitStreamParam aac; - SceAudiodecInitStreamParam celp; -}; - -struct SceAudiodecInfoAt9 -{ - u32 size; - u8 configData[4]; - u32 ch; - u32 bitRate; - u32 samplingRate; - u32 superFrameSize; - u32 framesInSuperFrame; -}; - -struct SceAudiodecInfoMp3 -{ - u32 size; - u32 ch; - u32 version; -}; - -struct SceAudiodecInfoAac -{ - u32 size; - u32 isAdts; - u32 ch; - u32 samplingRate; - u32 isSbr; -}; - -struct SceAudiodecInfoCelp -{ - u32 size; - u32 excitationMode; - u32 samplingRate; - u32 bitRate; - u32 lostCount; -}; - -union SceAudiodecInfo -{ - u32 size; - SceAudiodecInfoAt9 at9; - SceAudiodecInfoMp3 mp3; - SceAudiodecInfoAac aac; - SceAudiodecInfoCelp celp; -}; - -struct SceAudiodecCtrl -{ - u32 size; - s32 handle; - vm::psv::ptr pEs; - u32 inputEsSize; - u32 maxEsSize; - vm::psv::ptr pPcm; - u32 outputPcmSize; - u32 maxPcmSize; - u32 wordLength; - vm::psv::ptr pInfo; -}; - -s32 sceAudiodecInitLibrary(u32 codecType, vm::psv::ptr pInitParam) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudiodecTermLibrary(u32 codecType) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudiodecCreateDecoder(vm::psv::ptr pCtrl, u32 codecType) +s32 sceAudiodecCreateDecoder(vm::ptr pCtrl, u32 codecType) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudiodecDeleteDecoder(vm::psv::ptr pCtrl) +s32 sceAudiodecDeleteDecoder(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudiodecDecode(vm::psv::ptr pCtrl) +s32 sceAudiodecDecode(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudiodecClearContext(vm::psv::ptr pCtrl) +s32 sceAudiodecClearContext(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudiodecGetInternalError(vm::psv::ptr pCtrl, vm::psv::ptr pInternalError) +s32 sceAudiodecGetInternalError(vm::ptr pCtrl, vm::ptr pInternalError) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -127,6 +47,7 @@ psv_log_base sceAudiodec("SceAudiodec", []() sceAudiodec.on_load = nullptr; sceAudiodec.on_unload = nullptr; sceAudiodec.on_stop = nullptr; + sceAudiodec.on_error = nullptr; REG_FUNC(0x445C2CEF, sceAudiodecInitLibrary); REG_FUNC(0x45719B9D, sceAudiodecTermLibrary); diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudiodec.h b/rpcs3/Emu/ARMv7/Modules/sceAudiodec.h new file mode 100644 index 0000000000..cfa6c12b80 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceAudiodec.h @@ -0,0 +1,83 @@ +#pragma once + +struct SceAudiodecInitStreamParam +{ + le_t size; + le_t totalStreams; +}; + +struct SceAudiodecInitChParam +{ + le_t size; + le_t totalCh; +}; + +union SceAudiodecInitParam +{ + le_t size; + SceAudiodecInitChParam at9; + SceAudiodecInitStreamParam mp3; + SceAudiodecInitStreamParam aac; + SceAudiodecInitStreamParam celp; +}; + +struct SceAudiodecInfoAt9 +{ + le_t size; + u8 configData[4]; + le_t ch; + le_t bitRate; + le_t samplingRate; + le_t superFrameSize; + le_t framesInSuperFrame; +}; + +struct SceAudiodecInfoMp3 +{ + le_t size; + le_t ch; + le_t version; +}; + +struct SceAudiodecInfoAac +{ + le_t size; + le_t isAdts; + le_t ch; + le_t samplingRate; + le_t isSbr; +}; + +struct SceAudiodecInfoCelp +{ + le_t size; + le_t excitationMode; + le_t samplingRate; + le_t bitRate; + le_t lostCount; +}; + +union SceAudiodecInfo +{ + le_t size; + SceAudiodecInfoAt9 at9; + SceAudiodecInfoMp3 mp3; + SceAudiodecInfoAac aac; + SceAudiodecInfoCelp celp; +}; + +struct SceAudiodecCtrl +{ + le_t size; + le_t handle; + vm::lptr pEs; + le_t inputEsSize; + le_t maxEsSize; + vm::lptr pPcm; + le_t outputPcmSize; + le_t maxPcmSize; + le_t wordLength; + vm::lptr pInfo; +}; + +extern psv_log_base sceAudiodec; diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp b/rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp index d507170248..73cdfe8b5a 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceAudioenc.cpp @@ -2,103 +2,46 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceAudioenc; +#include "sceAudioenc.h" -struct SceAudioencInitStreamParam +s32 sceAudioencInitLibrary(u32 codecType, vm::ptr pInitParam) { - u32 size; - u32 totalStreams; -}; - -struct SceAudioencInfoCelp -{ - u32 size; - u32 excitationMode; - u32 samplingRate; - u32 bitRate; -}; - -struct SceAudioencOptInfoCelp -{ - u32 size; - u8 header[32]; - u32 headerSize; - u32 encoderVersion; -}; - - -union SceAudioencInitParam -{ - u32 size; - SceAudioencInitStreamParam celp; -}; - -union SceAudioencInfo -{ - u32 size; - SceAudioencInfoCelp celp; -}; - -union SceAudioencOptInfo -{ - u32 size; - SceAudioencOptInfoCelp celp; -}; - -struct SceAudioencCtrl -{ - u32 size; - s32 handle; - vm::psv::ptr pInputPcm; - u32 inputPcmSize; - u32 maxPcmSize; - vm::psv::ptr pOutputEs; - u32 outputEsSize; - u32 maxEsSize; - u32 wordLength; - vm::psv::ptr pInfo; - vm::psv::ptr pOptInfo; -}; - - -s32 sceAudioencInitLibrary(u32 codecType, vm::psv::ptr pInitParam) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceAudioencTermLibrary(u32 codecType) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioencCreateEncoder(vm::psv::ptr pCtrl, u32 codecType) +s32 sceAudioencCreateEncoder(vm::ptr pCtrl, u32 codecType) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioencDeleteEncoder(vm::psv::ptr pCtrl) +s32 sceAudioencDeleteEncoder(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioencEncode(vm::psv::ptr pCtrl) +s32 sceAudioencEncode(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioencClearContext(vm::psv::ptr pCtrl) +s32 sceAudioencClearContext(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioencGetOptInfo(vm::psv::ptr pCtrl) +s32 sceAudioencGetOptInfo(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAudioencGetInternalError(vm::psv::ptr pCtrl, vm::psv::ptr pInternalError) +s32 sceAudioencGetInternalError(vm::ptr pCtrl, vm::ptr pInternalError) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -109,6 +52,7 @@ psv_log_base sceAudioenc("SceAudioenc", []() sceAudioenc.on_load = nullptr; sceAudioenc.on_unload = nullptr; sceAudioenc.on_stop = nullptr; + sceAudioenc.on_error = nullptr; REG_FUNC(0x76EE4DC6, sceAudioencInitLibrary); REG_FUNC(0xAB32D022, sceAudioencTermLibrary); diff --git a/rpcs3/Emu/ARMv7/Modules/sceAudioenc.h b/rpcs3/Emu/ARMv7/Modules/sceAudioenc.h new file mode 100644 index 0000000000..9b361005e0 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceAudioenc.h @@ -0,0 +1,59 @@ +#pragma once + +struct SceAudioencInitStreamParam +{ + le_t size; + le_t totalStreams; +}; + +struct SceAudioencInfoCelp +{ + le_t size; + le_t excitationMode; + le_t samplingRate; + le_t bitRate; +}; + +struct SceAudioencOptInfoCelp +{ + le_t size; + u8 header[32]; + le_t headerSize; + le_t encoderVersion; +}; + + +union SceAudioencInitParam +{ + le_t size; + SceAudioencInitStreamParam celp; +}; + +union SceAudioencInfo +{ + le_t size; + SceAudioencInfoCelp celp; +}; + +union SceAudioencOptInfo +{ + le_t size; + SceAudioencOptInfoCelp celp; +}; + +struct SceAudioencCtrl +{ + le_t size; + le_t handle; + vm::lptr pInputPcm; + le_t inputPcmSize; + le_t maxPcmSize; + vm::lptr pOutputEs; + le_t outputEsSize; + le_t maxEsSize; + le_t wordLength; + vm::lptr pInfo; + vm::lptr pOptInfo; +}; + +extern psv_log_base sceAudioenc; diff --git a/rpcs3/Emu/ARMv7/Modules/sceCamera.cpp b/rpcs3/Emu/ARMv7/Modules/sceCamera.cpp index e341d6d75f..d5ff9d996d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCamera.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceCamera.cpp @@ -2,248 +2,211 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceCamera; +#include "sceCamera.h" -struct SceCameraInfo +s32 sceCameraOpen(s32 devnum, vm::ptr pInfo) { - u32 sizeThis; - u32 wPriority; - u32 wFormat; - u32 wResolution; - u32 wFramerate; - u32 wWidth; - u32 wHeight; - u32 wRange; - u32 _padding_0; - u32 sizeIBase; - u32 sizeUBase; - u32 sizeVBase; - vm::psv::ptr pvIBase; - vm::psv::ptr pvUBase; - vm::psv::ptr pvVBase; - u32 wPitch; - u32 wBuffer; -}; - -struct SceCameraRead -{ - u32 sizeThis; - s32 dwMode; - s32 _padding_0; - s32 dwStatus; - u32 qwFrame; - u32 qwTimestamp; - u32 sizeIBase; - u32 sizeUBase; - u32 sizeVBase; - vm::psv::ptr pvIBase; - vm::psv::ptr pvUBase; - vm::psv::ptr pvVBase; -}; - -s32 sceCameraOpen(s32 devnum, vm::psv::ptr pInfo) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraClose(s32 devnum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraStart(s32 devnum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraStop(s32 devnum) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraRead(s32 devnum, vm::psv::ptr pRead) +s32 sceCameraRead(s32 devnum, vm::ptr pRead) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraIsActive(s32 devnum) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetSaturation(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetSaturation(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetSaturation(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetBrightness(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetBrightness(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetBrightness(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetContrast(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetContrast(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetContrast(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetSharpness(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetSharpness(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetSharpness(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetReverse(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetReverse(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetReverse(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetEffect(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetEffect(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetEffect(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetEV(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetEV(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetEV(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetZoom(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetZoom(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetZoom(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetAntiFlicker(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetAntiFlicker(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetAntiFlicker(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetISO(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetISO(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetISO(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetGain(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetGain(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetGain(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetWhiteBalance(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetWhiteBalance(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetWhiteBalance(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetBacklight(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetBacklight(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetBacklight(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetNightmode(s32 devnum, vm::psv::ptr pMode) +s32 sceCameraGetNightmode(s32 devnum, vm::ptr pMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetNightmode(s32 devnum, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraLedSwitch(s32 devnum, s32 iSwitch) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraLedBlink(s32 devnum, s32 iOnCount, s32 iOffCount, s32 iBlinkCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetNoiseReductionForDebug(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetNoiseReductionForDebug(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetNoiseReductionForDebug(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCameraGetSharpnessOffForDebug(s32 devnum, vm::psv::ptr pLevel) +s32 sceCameraGetSharpnessOffForDebug(s32 devnum, vm::ptr pLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCameraSetSharpnessOffForDebug(s32 devnum, s32 level) { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceCameraUseCacheMemoryForTrial(s32 isCache) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -254,6 +217,7 @@ psv_log_base sceCamera("SceCamera", []() sceCamera.on_load = nullptr; sceCamera.on_unload = nullptr; sceCamera.on_stop = nullptr; + sceCamera.on_error = nullptr; REG_FUNC(0xA462F801, sceCameraOpen); REG_FUNC(0xCD6E1CFC, sceCameraClose); diff --git a/rpcs3/Emu/ARMv7/Modules/sceCamera.h b/rpcs3/Emu/ARMv7/Modules/sceCamera.h new file mode 100644 index 0000000000..b0edcf3b77 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceCamera.h @@ -0,0 +1,40 @@ +#pragma once + +struct SceCameraInfo +{ + le_t sizeThis; + le_t wPriority; + le_t wFormat; + le_t wResolution; + le_t wFramerate; + le_t wWidth; + le_t wHeight; + le_t wRange; + le_t _padding_0; + le_t sizeIBase; + le_t sizeUBase; + le_t sizeVBase; + vm::lptr pvIBase; + vm::lptr pvUBase; + vm::lptr pvVBase; + le_t wPitch; + le_t wBuffer; +}; + +struct SceCameraRead +{ + le_t sizeThis; + le_t dwMode; + le_t _padding_0; + le_t dwStatus; + le_t qwFrame; + le_t qwTimestamp; + le_t sizeIBase; + le_t sizeUBase; + le_t sizeVBase; + vm::lptr pvIBase; + vm::lptr pvUBase; + vm::lptr pvVBase; +}; + +extern psv_log_base sceCamera; diff --git a/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp b/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp index cda018a995..cfb84e9cfe 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.cpp @@ -2,32 +2,26 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceCodecEngine; - -struct SceCodecEnginePmonProcessorLoad -{ - u32 size; - u32 average; -}; +#include "sceCodecEngine.h" s32 sceCodecEnginePmonStart() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCodecEnginePmonStop() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCodecEnginePmonGetProcessorLoad(vm::psv::ptr pProcessorLoad) +s32 sceCodecEnginePmonGetProcessorLoad(vm::ptr pProcessorLoad) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCodecEnginePmonReset() { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -38,6 +32,7 @@ psv_log_base sceCodecEngine("SceCodecEngine", []() sceCodecEngine.on_load = nullptr; sceCodecEngine.on_unload = nullptr; sceCodecEngine.on_stop = nullptr; + sceCodecEngine.on_error = nullptr; REG_FUNC(0x3E718890, sceCodecEnginePmonStart); REG_FUNC(0x268B1EF5, sceCodecEnginePmonStop); diff --git a/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.h b/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.h new file mode 100644 index 0000000000..9cd72d5598 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceCodecEngine.h @@ -0,0 +1,9 @@ +#pragma once + +struct SceCodecEnginePmonProcessorLoad +{ + le_t size; + le_t average; +}; + +extern psv_log_base sceCodecEngine; diff --git a/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp b/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp index 3e7b998f63..b63dd9d202 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.cpp @@ -2,506 +2,206 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceGxm.h" -#include "sceAppUtil.h" -#include "sceIme.h" +#include "sceCommonDialog.h" -extern psv_log_base sceCommonDialog; - -enum SceCommonDialogStatus : s32 +s32 sceCommonDialogUpdate(vm::cptr updateParam) { - SCE_COMMON_DIALOG_STATUS_NONE = 0, - SCE_COMMON_DIALOG_STATUS_RUNNING = 1, - SCE_COMMON_DIALOG_STATUS_FINISHED = 2 -}; - -enum SceCommonDialogResult : s32 -{ - SCE_COMMON_DIALOG_RESULT_OK, - SCE_COMMON_DIALOG_RESULT_USER_CANCELED, - SCE_COMMON_DIALOG_RESULT_ABORTED -}; - -struct SceCommonDialogRenderTargetInfo -{ - vm::psv::ptr depthSurfaceData; - vm::psv::ptr colorSurfaceData; - SceGxmColorSurfaceType surfaceType; - SceGxmColorFormat colorFormat; - u32 width; - u32 height; - u32 strideInPixels; - u8 reserved[32]; -}; - -struct SceCommonDialogUpdateParam -{ - SceCommonDialogRenderTargetInfo renderTarget; - vm::psv::ptr displaySyncObject; - u8 reserved[32]; -}; - -struct SceMsgDialogUserMessageParam -{ - s32 buttonType; - vm::psv::ptr msg; - char reserved[32]; -}; - -struct SceMsgDialogSystemMessageParam -{ - s32 sysMsgType; - s32 value; - char reserved[32]; -}; - -struct SceMsgDialogErrorCodeParam -{ - s32 errorCode; - char reserved[32]; -}; - -struct SceMsgDialogProgressBarParam -{ - s32 barType; - SceMsgDialogSystemMessageParam sysMsgParam; - vm::psv::ptr msg; - char reserved[32]; -}; - -struct SceMsgDialogParam -{ - u32 sdkVersion; - s32 mode; - vm::psv::ptr userMsgParam; - vm::psv::ptr sysMsgParam; - vm::psv::ptr errorCodeParam; - vm::psv::ptr progBarParam; - u32 flag; - char reserved[32]; -}; - -struct SceMsgDialogResult -{ - s32 mode; - s32 result; - s32 buttonId; - u8 reserved[32]; -}; - - -struct SceNetCheckDialogParam -{ - u32 sdkVersion; - s32 mode; - u8 reserved[128]; -}; - -struct SceNetCheckDialogResult -{ - s32 result; - u8 reserved[128]; -}; - -struct SceSaveDataDialogFixedParam -{ - u32 targetSlot; - char reserved[32]; -}; - -struct SceSaveDataDialogListParam -{ - vm::psv::ptr slotList; - u32 slotListSize; - s32 focusPos; - u32 focusId; - vm::psv::ptr listTitle; - char reserved[32]; -}; - -struct SceSaveDataDialogUserMessageParam -{ - s32 buttonType; - vm::psv::ptr msg; - u32 targetSlot; - char reserved[32]; -}; - -struct SceSaveDataDialogSystemMessageParam -{ - s32 sysMsgType; - s32 value; - u32 targetSlot; - char reserved[32]; -}; - -struct SceSaveDataDialogErrorCodeParam -{ - s32 errorCode; - u32 targetSlot; - char reserved[32]; -}; - -struct SceSaveDataDialogProgressBarParam -{ - s32 barType; - SceSaveDataDialogSystemMessageParam sysMsgParam; - vm::psv::ptr msg; - u32 targetSlot; - char reserved[32]; -}; - -struct SceSaveDataDialogSlotConfigParam -{ - vm::psv::ptr mountPoint; - vm::psv::ptr appSubDir; - char reserved[32]; -}; - -struct SceSaveDataDialogParam -{ - u32 sdkVersion; - s32 mode; - s32 dispType; - vm::psv::ptr fixedParam; - vm::psv::ptr listParam; - vm::psv::ptr userMsgParam; - vm::psv::ptr sysMsgParam; - vm::psv::ptr errorCodeParam; - vm::psv::ptr progBarParam; - vm::psv::ptr slotConfParam; - u32 flag; - vm::psv::ptr userdata; - char reserved[32]; -}; - -struct SceSaveDataDialogFinishParam -{ - u32 flag; - char reserved[32]; -}; - -struct SceSaveDataDialogSlotInfo -{ - u32 isExist; - vm::psv::ptr slotParam; - u8 reserved[32]; -}; - -struct SceSaveDataDialogResult -{ - s32 mode; - s32 result; - s32 buttonId; - u32 slotId; - vm::psv::ptr slotInfo; - vm::psv::ptr userdata; - char reserved[32]; -}; - - -struct SceImeDialogParam -{ - u32 sdkVersion; - u32 inputMethod; - u64 supportedLanguages; - s32 languagesForced; - u32 type; - u32 option; - vm::psv::ptr filter; - u32 dialogMode; - u32 textBoxMode; - vm::psv::ptr title; - u32 maxTextLength; - vm::psv::ptr initialText; - vm::psv::ptr inputTextBuffer; - char reserved[32]; -}; - -struct SceImeDialogResult -{ - s32 result; - char reserved[32]; -}; - -enum ScePhotoImportDialogFormatType : s32 -{ - SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_UNKNOWN = 0, - SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_JPEG, - SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_PNG, - SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_GIF, - SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_BMP, - SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_TIFF -}; - -enum ScePhotoImportDialogOrientation : s32 -{ - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_UNKNOWN = 0, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_TOP_LEFT, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_TOP_RIGHT, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_BOTTOM_RIGHT, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_BOTTOM_LEFT, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_LEFT_TOP, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_RIGHT_TOP, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_RIGHT_BOTTOM, - SCE_PHOTOIMPORT_DIALOG_ORIENTATION_LEFT_BOTTOM -}; - -struct ScePhotoImportDialogFileDataSub -{ - u32 width; - u32 height; - ScePhotoImportDialogFormatType format; - ScePhotoImportDialogOrientation orientation; - char reserved[32]; -}; - -struct ScePhotoImportDialogFileData -{ - char fileName[1024]; - char photoTitle[256]; - char reserved[32]; -}; - -struct ScePhotoImportDialogItemData -{ - ScePhotoImportDialogFileData fileData; - ScePhotoImportDialogFileDataSub dataSub; - char reserved[32]; -}; - -struct ScePhotoImportDialogResult -{ - s32 result; - u32 importedItemNum; - char reserved[32]; -}; - -struct ScePhotoImportDialogParam -{ - u32 sdkVersion; - s32 mode; - u32 visibleCategory; - u32 itemCount; - vm::psv::ptr itemData; - char reserved[32]; -}; - -struct ScePhotoReviewDialogParam -{ - u32 sdkVersion; - s32 mode; - char fileName[1024]; - vm::psv::ptr workMemory; - u32 workMemorySize; - char reserved[32]; -}; - -struct ScePhotoReviewDialogResult -{ - s32 result; - char reserved[32]; -}; - - -s32 sceCommonDialogUpdate(vm::psv::ptr updateParam) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMsgDialogInit(vm::psv::ptr param) +s32 sceMsgDialogInit(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus sceMsgDialogGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMsgDialogAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMsgDialogGetResult(vm::psv::ptr result) +s32 sceMsgDialogGetResult(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMsgDialogTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMsgDialogClose() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMsgDialogProgressBarInc(s32 target, u32 delta) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMsgDialogProgressBarSetValue(s32 target, u32 rate) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCheckDialogInit(vm::psv::ptr param) +s32 sceNetCheckDialogInit(vm::ptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus sceNetCheckDialogGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetCheckDialogAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCheckDialogGetResult(vm::psv::ptr result) +s32 sceNetCheckDialogGetResult(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetCheckDialogTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSaveDataDialogInit(vm::psv::ptr param) +s32 sceSaveDataDialogInit(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus sceSaveDataDialogGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSaveDataDialogAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSaveDataDialogGetResult(vm::psv::ptr result) +s32 sceSaveDataDialogGetResult(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSaveDataDialogTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus sceSaveDataDialogGetSubStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSaveDataDialogSubClose() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSaveDataDialogContinue(vm::psv::ptr param) +s32 sceSaveDataDialogContinue(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSaveDataDialogFinish(vm::psv::ptr param) +s32 sceSaveDataDialogFinish(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSaveDataDialogProgressBarInc(s32 target, u32 delta) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSaveDataDialogProgressBarSetValue(s32 target, u32 rate) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceImeDialogInit(vm::psv::ptr param) +s32 sceImeDialogInit(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus sceImeDialogGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceImeDialogAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceImeDialogGetResult(vm::psv::ptr result) +s32 sceImeDialogGetResult(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceImeDialogTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 scePhotoImportDialogInit(vm::psv::ptr param) +s32 scePhotoImportDialogInit(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus scePhotoImportDialogGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 scePhotoImportDialogGetResult(vm::psv::ptr result) +s32 scePhotoImportDialogGetResult(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 scePhotoImportDialogTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 scePhotoImportDialogAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 scePhotoReviewDialogInit(vm::psv::ptr param) +s32 scePhotoReviewDialogInit(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } SceCommonDialogStatus scePhotoReviewDialogGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 scePhotoReviewDialogGetResult(vm::psv::ptr result) +s32 scePhotoReviewDialogGetResult(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 scePhotoReviewDialogTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 scePhotoReviewDialogAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -512,6 +212,7 @@ psv_log_base sceCommonDialog("SceCommonDialog", []() sceCommonDialog.on_load = nullptr; sceCommonDialog.on_unload = nullptr; sceCommonDialog.on_stop = nullptr; + sceCommonDialog.on_error = nullptr; REG_FUNC(0x90530F2F, sceCommonDialogUpdate); REG_FUNC(0x755FF270, sceMsgDialogInit); diff --git a/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.h b/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.h new file mode 100644 index 0000000000..564c9eabea --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceCommonDialog.h @@ -0,0 +1,302 @@ +#pragma once + +#include "sceGxm.h" +#include "sceAppUtil.h" +#include "sceIme.h" + +enum SceCommonDialogStatus : s32 +{ + SCE_COMMON_DIALOG_STATUS_NONE = 0, + SCE_COMMON_DIALOG_STATUS_RUNNING = 1, + SCE_COMMON_DIALOG_STATUS_FINISHED = 2, +}; + +enum SceCommonDialogResult : s32 +{ + SCE_COMMON_DIALOG_RESULT_OK, + SCE_COMMON_DIALOG_RESULT_USER_CANCELED, + SCE_COMMON_DIALOG_RESULT_ABORTED, +}; + +struct SceCommonDialogRenderTargetInfo +{ + vm::lptr depthSurfaceData; + vm::lptr colorSurfaceData; + le_t surfaceType; // SceGxmColorSurfaceType + le_t colorFormat; // SceGxmColorFormat + le_t width; + le_t height; + le_t strideInPixels; + u8 reserved[32]; +}; + +struct SceCommonDialogUpdateParam +{ + SceCommonDialogRenderTargetInfo renderTarget; + vm::lptr displaySyncObject; + u8 reserved[32]; +}; + +struct SceMsgDialogUserMessageParam +{ + le_t buttonType; + vm::lcptr msg; + char reserved[32]; +}; + +struct SceMsgDialogSystemMessageParam +{ + le_t sysMsgType; + le_t value; + char reserved[32]; +}; + +struct SceMsgDialogErrorCodeParam +{ + le_t errorCode; + char reserved[32]; +}; + +struct SceMsgDialogProgressBarParam +{ + le_t barType; + SceMsgDialogSystemMessageParam sysMsgParam; + vm::lcptr msg; + char reserved[32]; +}; + +struct SceMsgDialogParam +{ + le_t sdkVersion; + le_t mode; + vm::lptr userMsgParam; + vm::lptr sysMsgParam; + vm::lptr errorCodeParam; + vm::lptr progBarParam; + le_t flag; + char reserved[32]; +}; + +struct SceMsgDialogResult +{ + le_t mode; + le_t result; + le_t buttonId; + u8 reserved[32]; +}; + + +struct SceNetCheckDialogParam +{ + le_t sdkVersion; + le_t mode; + u8 reserved[128]; +}; + +struct SceNetCheckDialogResult +{ + le_t result; + u8 reserved[128]; +}; + +struct SceSaveDataDialogFixedParam +{ + le_t targetSlot; + char reserved[32]; +}; + +struct SceSaveDataDialogListParam +{ + vm::lcptr slotList; + le_t slotListSize; + le_t focusPos; + le_t focusId; + vm::lcptr listTitle; + char reserved[32]; +}; + +struct SceSaveDataDialogUserMessageParam +{ + le_t buttonType; + vm::lcptr msg; + le_t targetSlot; + char reserved[32]; +}; + +struct SceSaveDataDialogSystemMessageParam +{ + le_t sysMsgType; + le_t value; + le_t targetSlot; + char reserved[32]; +}; + +struct SceSaveDataDialogErrorCodeParam +{ + le_t errorCode; + le_t targetSlot; + char reserved[32]; +}; + +struct SceSaveDataDialogProgressBarParam +{ + le_t barType; + SceSaveDataDialogSystemMessageParam sysMsgParam; + vm::lcptr msg; + le_t targetSlot; + char reserved[32]; +}; + +struct SceSaveDataDialogSlotConfigParam +{ + vm::lcptr mountPoint; + vm::lcptr appSubDir; + char reserved[32]; +}; + +struct SceSaveDataDialogParam +{ + le_t sdkVersion; + le_t mode; + le_t dispType; + vm::lptr fixedParam; + vm::lptr listParam; + vm::lptr userMsgParam; + vm::lptr sysMsgParam; + vm::lptr errorCodeParam; + vm::lptr progBarParam; + vm::lptr slotConfParam; + le_t flag; + vm::lptr userdata; + char reserved[32]; +}; + +struct SceSaveDataDialogFinishParam +{ + le_t flag; + char reserved[32]; +}; + +struct SceSaveDataDialogSlotInfo +{ + le_t isExist; + vm::lptr slotParam; + u8 reserved[32]; +}; + +struct SceSaveDataDialogResult +{ + le_t mode; + le_t result; + le_t buttonId; + le_t slotId; + vm::lptr slotInfo; + vm::lptr userdata; + char reserved[32]; +}; + + +struct SceImeDialogParam +{ + le_t sdkVersion; + le_t inputMethod; + le_t supportedLanguages; + le_t languagesForced; + le_t type; + le_t option; + vm::lptr filter; + le_t dialogMode; + le_t textBoxMode; + vm::lcptr title; + le_t maxTextLength; + vm::lptr initialText; + vm::lptr inputTextBuffer; + char reserved[32]; +}; + +struct SceImeDialogResult +{ + le_t result; + char reserved[32]; +}; + +enum ScePhotoImportDialogFormatType : s32 +{ + SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_UNKNOWN = 0, + SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_JPEG, + SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_PNG, + SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_GIF, + SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_BMP, + SCE_PHOTOIMPORT_DIALOG_FORMAT_TYPE_TIFF +}; + +enum ScePhotoImportDialogOrientation : s32 +{ + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_UNKNOWN = 0, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_TOP_LEFT, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_TOP_RIGHT, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_BOTTOM_RIGHT, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_BOTTOM_LEFT, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_LEFT_TOP, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_RIGHT_TOP, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_RIGHT_BOTTOM, + SCE_PHOTOIMPORT_DIALOG_ORIENTATION_LEFT_BOTTOM, +}; + +struct ScePhotoImportDialogFileDataSub +{ + le_t width; + le_t height; + ScePhotoImportDialogFormatType format; + ScePhotoImportDialogOrientation orientation; + char reserved[32]; +}; + +struct ScePhotoImportDialogFileData +{ + char fileName[1024]; + char photoTitle[256]; + char reserved[32]; +}; + +struct ScePhotoImportDialogItemData +{ + ScePhotoImportDialogFileData fileData; + ScePhotoImportDialogFileDataSub dataSub; + char reserved[32]; +}; + +struct ScePhotoImportDialogResult +{ + le_t result; + le_t importedItemNum; + char reserved[32]; +}; + +struct ScePhotoImportDialogParam +{ + le_t sdkVersion; + le_t mode; + le_t visibleCategory; + le_t itemCount; + vm::lptr itemData; + char reserved[32]; +}; + +struct ScePhotoReviewDialogParam +{ + le_t sdkVersion; + le_t mode; + char fileName[1024]; + vm::lptr workMemory; + le_t workMemorySize; + char reserved[32]; +}; + +struct ScePhotoReviewDialogResult +{ + le_t result; + char reserved[32]; +}; + +extern psv_log_base sceCommonDialog; diff --git a/rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp b/rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp index b858e40972..3dc74100c4 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceCtrl.cpp @@ -2,67 +2,46 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceCtrl; - -struct SceCtrlData -{ - u64 timeStamp; - u32 buttons; - u8 lx; - u8 ly; - u8 rx; - u8 ry; - u8 rsrv[16]; -}; - -struct SceCtrlRapidFireRule -{ - u32 uiMask; - u32 uiTrigger; - u32 uiTarget; - u32 uiDelay; - u32 uiMake; - u32 uiBreak; -}; +#include "sceCtrl.h" s32 sceCtrlSetSamplingMode(u32 uiMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCtrlGetSamplingMode(vm::psv::ptr puiMode) +s32 sceCtrlGetSamplingMode(vm::ptr puiMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCtrlPeekBufferPositive(s32 port, vm::psv::ptr pData, s32 nBufs) +s32 sceCtrlPeekBufferPositive(s32 port, vm::ptr pData, s32 nBufs) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCtrlPeekBufferNegative(s32 port, vm::psv::ptr pData, s32 nBufs) +s32 sceCtrlPeekBufferNegative(s32 port, vm::ptr pData, s32 nBufs) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCtrlReadBufferPositive(s32 port, vm::psv::ptr pData, s32 nBufs) +s32 sceCtrlReadBufferPositive(s32 port, vm::ptr pData, s32 nBufs) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCtrlReadBufferNegative(s32 port, vm::psv::ptr pData, s32 nBufs) +s32 sceCtrlReadBufferNegative(s32 port, vm::ptr pData, s32 nBufs) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceCtrlSetRapidFire(s32 port, s32 idx, vm::psv::ptr pRule) +s32 sceCtrlSetRapidFire(s32 port, s32 idx, vm::cptr pRule) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceCtrlClearRapidFire(s32 port, s32 idx) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -73,6 +52,7 @@ psv_log_base sceCtrl("SceCtrl", []() sceCtrl.on_load = nullptr; sceCtrl.on_unload = nullptr; sceCtrl.on_stop = nullptr; + sceCtrl.on_error = nullptr; REG_FUNC(0xA497B150, sceCtrlSetSamplingMode); REG_FUNC(0xEC752AAF, sceCtrlGetSamplingMode); diff --git a/rpcs3/Emu/ARMv7/Modules/sceCtrl.h b/rpcs3/Emu/ARMv7/Modules/sceCtrl.h new file mode 100644 index 0000000000..278e478b78 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceCtrl.h @@ -0,0 +1,24 @@ +#pragma once + +struct SceCtrlData +{ + le_t timeStamp; + le_t buttons; + u8 lx; + u8 ly; + u8 rx; + u8 ry; + u8 reserved[16]; +}; + +struct SceCtrlRapidFireRule +{ + le_t uiMask; + le_t uiTrigger; + le_t uiTarget; + le_t uiDelay; + le_t uiMake; + le_t uiBreak; +}; + +extern psv_log_base sceCtrl; diff --git a/rpcs3/Emu/ARMv7/Modules/sceDbg.cpp b/rpcs3/Emu/ARMv7/Modules/sceDbg.cpp index 6a2cc4c9a2..33d3ce6a31 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDbg.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceDbg.cpp @@ -2,32 +2,26 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceDbg; - -enum SceDbgBreakOnErrorState : s32 -{ - SCE_DBG_DISABLE_BREAK_ON_ERROR = 0, - SCE_DBG_ENABLE_BREAK_ON_ERROR -}; +#include "sceDbg.h" s32 sceDbgSetMinimumLogLevel(s32 minimumLogLevel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDbgSetBreakOnErrorState(SceDbgBreakOnErrorState state) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceDbgAssertionHandler(vm::psv::ptr pFile, s32 line, bool stop, vm::psv::ptr pComponent, vm::psv::ptr pMessage) // va_args... +s32 sceDbgAssertionHandler(vm::cptr pFile, s32 line, bool stop, vm::cptr pComponent, vm::cptr pMessage, armv7_va_args_t va_args) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceDbgLoggingHandler(vm::psv::ptr pFile, s32 line, s32 severity, vm::psv::ptr pComponent, vm::psv::ptr pMessage) // va_args... +s32 sceDbgLoggingHandler(vm::cptr pFile, s32 line, s32 severity, vm::cptr pComponent, vm::cptr pMessage, armv7_va_args_t va_args) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -38,6 +32,7 @@ psv_log_base sceDbg("SceDbg", []() sceDbg.on_load = nullptr; sceDbg.on_unload = nullptr; sceDbg.on_stop = nullptr; + sceDbg.on_error = nullptr; REG_FUNC(0x941622FA, sceDbgSetMinimumLogLevel); REG_FUNC(0x1AF3678B, sceDbgAssertionHandler); diff --git a/rpcs3/Emu/ARMv7/Modules/sceDbg.h b/rpcs3/Emu/ARMv7/Modules/sceDbg.h new file mode 100644 index 0000000000..c9136a4c0f --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceDbg.h @@ -0,0 +1,9 @@ +#pragma once + +enum SceDbgBreakOnErrorState : s32 +{ + SCE_DBG_DISABLE_BREAK_ON_ERROR = 0, + SCE_DBG_ENABLE_BREAK_ON_ERROR +}; + +extern psv_log_base sceDbg; diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp b/rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp index f0cf7e3c8e..1553aa4bf3 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceDeci4p.cpp @@ -2,33 +2,31 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceDeci4p; +#include "sceDeci4p.h" -typedef vm::psv::ptr pCommon)> SceKernelDeci4pCallback; - -s32 sceKernelDeci4pOpen(vm::psv::ptr protoname, u32 protonum, u32 bufsize) +s32 sceKernelDeci4pOpen(vm::cptr protoname, u32 protonum, u32 bufsize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDeci4pClose(s32 socketid) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelDeci4pRead(s32 socketid, vm::psv::ptr buffer, u32 size, u32 reserved) +s32 sceKernelDeci4pRead(s32 socketid, vm::ptr buffer, u32 size, u32 reserved) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelDeci4pWrite(s32 socketid, vm::psv::ptr buffer, u32 size, u32 reserved) +s32 sceKernelDeci4pWrite(s32 socketid, vm::cptr buffer, u32 size, u32 reserved) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDeci4pRegisterCallback(s32 socketid, s32 cbid) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -39,6 +37,7 @@ psv_log_base sceDeci4p("SceDeci4pUserp", []() sceDeci4p.on_load = nullptr; sceDeci4p.on_unload = nullptr; sceDeci4p.on_stop = nullptr; + sceDeci4p.on_error = nullptr; REG_FUNC(0x28578FE8, sceKernelDeci4pOpen); REG_FUNC(0x63B0C50F, sceKernelDeci4pClose); diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeci4p.h b/rpcs3/Emu/ARMv7/Modules/sceDeci4p.h new file mode 100644 index 0000000000..8f5e20acfe --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceDeci4p.h @@ -0,0 +1,5 @@ +#pragma once + +using SceKernelDeci4pCallback = func_def pCommon)>; + +extern psv_log_base sceDeci4p; diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp b/rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp index f1ce171d65..2aa496213c 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceDeflt.cpp @@ -2,71 +2,71 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceDeflt; +#include "sceDeflt.h" -s32 sceGzipIsValid(vm::psv::ptr pSrcGzip) +s32 sceGzipIsValid(vm::cptr pSrcGzip) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGzipGetInfo(vm::psv::ptr pSrcGzip, vm::psv::pptr ppvExtra, vm::psv::pptr ppszName, vm::psv::pptr ppszComment, vm::psv::ptr pusCrc, vm::psv::pptr ppvData) +s32 sceGzipGetInfo(vm::cptr pSrcGzip, vm::cpptr ppvExtra, vm::cpptr ppszName, vm::cpptr ppszComment, vm::ptr pusCrc, vm::cpptr ppvData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGzipGetName(vm::psv::ptr pSrcGzip) +vm::cptr sceGzipGetName(vm::cptr pSrcGzip) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGzipGetComment(vm::psv::ptr pSrcGzip) +vm::cptr sceGzipGetComment(vm::cptr pSrcGzip) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGzipGetCompressedData(vm::psv::ptr pSrcGzip) +vm::cptr sceGzipGetCompressedData(vm::cptr pSrcGzip) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGzipDecompress(vm::psv::ptr pDst, u32 uiBufSize, vm::psv::ptr pSrcGzip, vm::psv::ptr puiCrc32) +s32 sceGzipDecompress(vm::ptr pDst, u32 uiBufSize, vm::cptr pSrcGzip, vm::ptr puiCrc32) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceZlibIsValid(vm::psv::ptr pSrcZlib) +s32 sceZlibIsValid(vm::cptr pSrcZlib) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceZlibGetInfo(vm::psv::ptr pSrcZlib, vm::psv::ptr pbCmf, vm::psv::ptr pbFlg, vm::psv::ptr puiDictId, vm::psv::pptr ppvData) +s32 sceZlibGetInfo(vm::cptr pSrcZlib, vm::ptr pbCmf, vm::ptr pbFlg, vm::ptr puiDictId, vm::cpptr ppvData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceZlibGetCompressedData(vm::psv::ptr pSrcZlib) +vm::cptr sceZlibGetCompressedData(vm::cptr pSrcZlib) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceZlibDecompress(vm::psv::ptr pDst, u32 uiBufSize, vm::psv::ptr pSrcZlib, vm::psv::ptr puiAdler32) +s32 sceZlibDecompress(vm::ptr pDst, u32 uiBufSize, vm::cptr pSrcZlib, vm::ptr puiAdler32) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceZlibAdler32(u32 uiAdler, vm::psv::ptr pSrc, u32 uiSize) +u32 sceZlibAdler32(u32 uiAdler, vm::cptr pSrc, u32 uiSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceDeflateDecompress(vm::psv::ptr pDst, u32 uiBufSize, vm::psv::ptr pSrcDeflate, vm::psv::pptr ppNext) +s32 sceDeflateDecompress(vm::ptr pDst, u32 uiBufSize, vm::cptr pSrcDeflate, vm::cpptr ppNext) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceZipGetInfo(vm::psv::ptr pSrc, vm::psv::pptr ppvExtra, vm::psv::ptr puiCrc, vm::psv::pptr ppvData) +s32 sceZipGetInfo(vm::cptr pSrc, vm::cpptr ppvExtra, vm::ptr puiCrc, vm::cpptr ppvData) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -77,6 +77,7 @@ psv_log_base sceDeflt("SceDeflt", []() sceDeflt.on_load = nullptr; sceDeflt.on_unload = nullptr; sceDeflt.on_stop = nullptr; + sceDeflt.on_error = nullptr; REG_FUNC(0xCD83A464, sceZlibAdler32); REG_FUNC(0x110D5050, sceDeflateDecompress); diff --git a/rpcs3/Emu/ARMv7/Modules/sceDeflt.h b/rpcs3/Emu/ARMv7/Modules/sceDeflt.h new file mode 100644 index 0000000000..1d61e9f7b1 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceDeflt.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceDeflt; diff --git a/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp b/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp index c03c7622e5..48e1eed48a 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceDisplay.cpp @@ -2,86 +2,76 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceDisplay; +#include "sceDisplay.h" -struct SceDisplayFrameBuf +s32 sceDisplayGetRefreshRate(vm::ptr pFps) { - u32 size; - vm::psv::ptr base; - u32 pitch; - u32 pixelformat; - u32 width; - u32 height; -}; - -s32 sceDisplayGetRefreshRate(vm::psv::ptr pFps) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceDisplaySetFrameBuf(vm::psv::ptr pFrameBuf, s32 iUpdateTimingMode) +s32 sceDisplaySetFrameBuf(vm::cptr pFrameBuf, s32 iUpdateTimingMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceDisplayGetFrameBuf(vm::psv::ptr pFrameBuf, s32 iUpdateTimingMode) +s32 sceDisplayGetFrameBuf(vm::ptr pFrameBuf, s32 iUpdateTimingMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayGetVcount() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitVblankStart() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitVblankStartCB() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitVblankStartMulti(u32 vcount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitVblankStartMultiCB(u32 vcount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitSetFrameBuf() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitSetFrameBufCB() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitSetFrameBufMulti(u32 vcount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayWaitSetFrameBufMultiCB(u32 vcount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayRegisterVblankStartCallback(s32 uid) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceDisplayUnregisterVblankStartCallback(s32 uid) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -92,6 +82,7 @@ psv_log_base sceDisplay("SceDisplay", []() sceDisplay.on_load = nullptr; sceDisplay.on_unload = nullptr; sceDisplay.on_stop = nullptr; + sceDisplay.on_error = nullptr; // SceDisplayUser REG_FUNC(0x7A410B64, sceDisplaySetFrameBuf); diff --git a/rpcs3/Emu/ARMv7/Modules/sceDisplay.h b/rpcs3/Emu/ARMv7/Modules/sceDisplay.h new file mode 100644 index 0000000000..cce29c9e38 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceDisplay.h @@ -0,0 +1,13 @@ +#pragma once + +struct SceDisplayFrameBuf +{ + le_t size; + vm::lptr base; + le_t pitch; + le_t pixelformat; + le_t width; + le_t height; +}; + +extern psv_log_base sceDisplay; diff --git a/rpcs3/Emu/ARMv7/Modules/sceFiber.cpp b/rpcs3/Emu/ARMv7/Modules/sceFiber.cpp index cd2155cd1d..44fab30de3 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFiber.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceFiber.cpp @@ -2,82 +2,46 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceFiber; +#include "sceFiber.h" -typedef vm::psv::ptr SceFiberEntry; - -struct SceFiber +s32 _sceFiberInitializeImpl(vm::ptr fiber, vm::cptr name, vm::ptr entry, u32 argOnInitialize, vm::ptr addrContext, u32 sizeContext, vm::cptr optParam, u32 buildVersion) { - static const uint size = 128; - static const uint align = 8; - u64 padding[size / sizeof(u64)]; -}; - -struct SceFiberOptParam -{ - static const uint size = 128; - static const uint align = 8; - u64 padding[size / sizeof(u64)]; -}; - -struct SceFiberInfo -{ - static const uint size = 128; - static const uint align = 8; - - union - { - u64 padding[size / sizeof(u64)]; - - struct - { - SceFiberEntry entry; - u32 argOnInitialize; - vm::psv::ptr addrContext; - s32 sizeContext; - char name[32]; - }; - }; -}; - -s32 _sceFiberInitializeImpl(vm::psv::ptr fiber, vm::psv::ptr name, SceFiberEntry entry, u32 argOnInitialize, vm::psv::ptr addrContext, u32 sizeContext, vm::psv::ptr optParam, u32 buildVersion) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberOptParamInitialize(vm::psv::ptr optParam) +s32 sceFiberOptParamInitialize(vm::ptr optParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberFinalize(vm::psv::ptr fiber) +s32 sceFiberFinalize(vm::ptr fiber) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberRun(vm::psv::ptr fiber, u32 argOnRunTo, vm::psv::ptr argOnReturn) +s32 sceFiberRun(vm::ptr fiber, u32 argOnRunTo, vm::ptr argOnReturn) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberSwitch(vm::psv::ptr fiber, u32 argOnRunTo, vm::psv::ptr argOnRun) +s32 sceFiberSwitch(vm::ptr fiber, u32 argOnRunTo, vm::ptr argOnRun) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberGetSelf(vm::psv::pptr fiber) +s32 sceFiberGetSelf(vm::pptr fiber) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberReturnToThread(u32 argOnReturn, vm::psv::ptr argOnRun) +s32 sceFiberReturnToThread(u32 argOnReturn, vm::ptr argOnRun) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiberGetInfo(vm::psv::ptr fiber, vm::psv::ptr fiberInfo) +s32 sceFiberGetInfo(vm::ptr fiber, vm::ptr fiberInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -88,6 +52,7 @@ psv_log_base sceFiber("SceFiber", []() sceFiber.on_load = nullptr; sceFiber.on_unload = nullptr; sceFiber.on_stop = nullptr; + sceFiber.on_error = nullptr; REG_FUNC(0xF24A298C, _sceFiberInitializeImpl); //REG_FUNC(0xC6A3F9BB, _sceFiberInitializeWithInternalOptionImpl); diff --git a/rpcs3/Emu/ARMv7/Modules/sceFiber.h b/rpcs3/Emu/ARMv7/Modules/sceFiber.h new file mode 100644 index 0000000000..521d0eeb13 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceFiber.h @@ -0,0 +1,31 @@ +#pragma once + +using SceFiberEntry = func_def; + +struct set_alignment(8) SceFiber +{ + le_t padding[16]; +}; + +CHECK_SIZE_ALIGN(SceFiber, 128, 8); + +struct set_alignment(8) SceFiberOptParam +{ + le_t padding[16]; +}; + +CHECK_SIZE_ALIGN(SceFiberOptParam, 128, 8); + +struct set_alignment(8) SceFiberInfo +{ + vm::lptr entry; + le_t argOnInitialize; + vm::lptr addrContext; + le_t sizeContext; + char name[32]; + u8 padding[80]; +}; + +CHECK_SIZE_ALIGN(SceFiberInfo, 128, 8); + +extern psv_log_base sceFiber; diff --git a/rpcs3/Emu/ARMv7/Modules/sceFios.cpp b/rpcs3/Emu/ARMv7/Modules/sceFios.cpp index 49831265e5..58ca7c3fa1 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFios.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceFios.cpp @@ -2,804 +2,686 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceFios; +#include "sceFios.h" -typedef s64 SceFiosOffset; -typedef s64 SceFiosSize; -typedef u8 SceFiosOpEvent; -typedef s32 SceFiosHandle; -typedef SceFiosHandle SceFiosOp; -typedef SceFiosHandle SceFiosFH; -typedef SceFiosHandle SceFiosDH; -typedef s64 SceFiosTime; -typedef s8 SceFiosPriority; -typedef SceFiosTime SceFiosTimeInterval; -typedef u64 SceFiosDate; -typedef s32 SceFiosOverlayID; - -typedef vm::psv::ptr pContext, SceFiosOp op, SceFiosOpEvent event, s32 err)> SceFiosOpCallback; -typedef vm::psv::ptr fmt, va_list ap)> SceFiosVprintfCallback; -typedef vm::psv::ptr(vm::psv::ptr dst, vm::psv::ptr src, u32 len)> SceFiosMemcpyCallback; - -enum SceFiosWhence : s32 +s32 sceFiosInitialize(vm::cptr pParameters) { - SCE_FIOS_SEEK_SET = 0, - SCE_FIOS_SEEK_CUR = 1, - SCE_FIOS_SEEK_END = 2 -}; - -struct SceFiosBuffer -{ - vm::psv::ptr pPtr; - u32 length; -}; - -struct SceFiosOpAttr -{ - SceFiosTime deadline; - SceFiosOpCallback pCallback; - vm::psv::ptr pCallbackContext; - s32 priority : 8; - u32 opflags : 24; - u32 userTag; - vm::psv::ptr userPtr; - vm::psv::ptr pReserved; -}; - -struct SceFiosDirEntry -{ - SceFiosOffset fileSize; - u32 statFlags; - u16 nameLength; - u16 fullPathLength; - u16 offsetToName; - u16 reserved[3]; - char fullPath[1024]; -}; - -struct SceFiosStat -{ - SceFiosOffset fileSize; - SceFiosDate accessDate; - SceFiosDate modificationDate; - SceFiosDate creationDate; - u32 statFlags; - u32 reserved; - s64 uid; - s64 gid; - s64 dev; - s64 ino; - s64 mode; -}; - -struct SceFiosOpenParams -{ - u32 openFlags; - u32 reserved; - SceFiosBuffer buffer; -}; - -struct SceFiosTuple -{ - SceFiosOffset offset; - SceFiosSize size; - char path[1024]; -}; - -struct SceFiosParams -{ - u32 initialized : 1; - u32 paramsSize : 14; - u32 pathMax : 16; - u32 profiling; - SceFiosBuffer opStorage; - SceFiosBuffer fhStorage; - SceFiosBuffer dhStorage; - SceFiosBuffer chunkStorage; - SceFiosVprintfCallback pVprintf; - SceFiosMemcpyCallback pMemcpy; - s32 threadPriority[2]; - s32 threadAffinity[2]; -}; - -struct SceFiosOverlay -{ - u8 type; - u8 order; - u8 reserved[10]; - SceFiosOverlayID id; - char dst[292]; - char src[292]; -}; - -typedef vm::psv::ptr SceFiosIOFilterCallback; - -struct SceFiosPsarcDearchiverContext -{ - u32 sizeOfContext; - u32 workBufferSize; - vm::psv::ptr pWorkBuffer; - s32 reserved[4]; -}; - -s32 sceFiosInitialize(vm::psv::ptr pParameters) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosTerminate() { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosIsInitialized(vm::psv::ptr pOutParameters) +bool sceFiosIsInitialized(vm::ptr pOutParameters) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosUpdateParameters(vm::psv::ptr pParameters) +void sceFiosUpdateParameters(vm::cptr pParameters) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosSetGlobalDefaultOpAttr(vm::psv::ptr pAttr) +void sceFiosSetGlobalDefaultOpAttr(vm::cptr pAttr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosGetGlobalDefaultOpAttr(vm::psv::ptr pOutAttr) +bool sceFiosGetGlobalDefaultOpAttr(vm::ptr pOutAttr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosSetThreadDefaultOpAttr(vm::psv::ptr pAttr) +void sceFiosSetThreadDefaultOpAttr(vm::cptr pAttr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosGetThreadDefaultOpAttr(vm::psv::ptr pOutAttr) +bool sceFiosGetThreadDefaultOpAttr(vm::ptr pOutAttr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosGetDefaultOpAttr(vm::psv::ptr pOutAttr) +void sceFiosGetDefaultOpAttr(vm::ptr pOutAttr) { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosSuspend() { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceFiosGetSuspendCount() { - throw __FUNCTION__; + throw EXCEPTION(""); } bool sceFiosIsSuspended() { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosResume() { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosShutdownAndCancelOps() { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosCancelAllOps() { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosCloseAllFiles() { - throw __FUNCTION__; + throw EXCEPTION(""); } bool sceFiosIsIdle() { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceFiosGetAllFHs(vm::psv::ptr pOutArray, u32 arraySize) +u32 sceFiosGetAllFHs(vm::ptr pOutArray, u32 arraySize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceFiosGetAllDHs(vm::psv::ptr pOutArray, u32 arraySize) +u32 sceFiosGetAllDHs(vm::ptr pOutArray, u32 arraySize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceFiosGetAllOps(vm::psv::ptr pOutArray, u32 arraySize) +u32 sceFiosGetAllOps(vm::ptr pOutArray, u32 arraySize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosIsValidHandle(SceFiosHandle h) +bool sceFiosIsValidHandle(s32 h) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosPathcmp(vm::psv::ptr pA, vm::psv::ptr pB) +s32 sceFiosPathcmp(vm::cptr pA, vm::cptr pB) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosPathncmp(vm::psv::ptr pA, vm::psv::ptr pB, u32 n) +s32 sceFiosPathncmp(vm::cptr pA, vm::cptr pB, u32 n) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosPrintf(vm::psv::ptr pFormat) // va_args... +s32 sceFiosPrintf(vm::cptr pFormat, armv7_va_args_t va_args) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosVprintf(vm::psv::ptr pFormat) // va_list +s32 sceFiosVprintf(vm::cptr pFormat) // va_list { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFileExists(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pOutExists) +s32 sceFiosFileExists(vm::cptr pAttr, vm::cptr pPath, vm::ptr pOutExists) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosFileExistsSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +bool sceFiosFileExistsSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFileGetSize(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pOutSize) +s32 sceFiosFileGetSize(vm::cptr pAttr, vm::cptr pPath, vm::ptr pOutSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFileGetSizeSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s64 sceFiosFileGetSizeSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFileDelete(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosFileDelete(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFileDeleteSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosFileDeleteSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosDirectoryExists(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pOutExists) +s32 sceFiosDirectoryExists(vm::cptr pAttr, vm::cptr pPath, vm::ptr pOutExists) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosDirectoryExistsSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +bool sceFiosDirectoryExistsSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosDirectoryCreate(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosDirectoryCreate(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosDirectoryCreateSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosDirectoryCreateSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosDirectoryDelete(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosDirectoryDelete(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosDirectoryDeleteSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosDirectoryDeleteSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosExists(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pOutExists) +s32 sceFiosExists(vm::cptr pAttr, vm::cptr pPath, vm::ptr pOutExists) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosExistsSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +bool sceFiosExistsSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosStat(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pOutStatus) +s32 sceFiosStat(vm::cptr pAttr, vm::cptr pPath, vm::ptr pOutStatus) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosStatSync(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pOutStatus) +s32 sceFiosStatSync(vm::cptr pAttr, vm::cptr pPath, vm::ptr pOutStatus) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosDelete(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosDelete(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosDeleteSync(vm::psv::ptr pAttr, vm::psv::ptr pPath) +s32 sceFiosDeleteSync(vm::cptr pAttr, vm::cptr pPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosResolve(vm::psv::ptr pAttr, vm::psv::ptr pInTuple, vm::psv::ptr pOutTuple) +s32 sceFiosResolve(vm::cptr pAttr, vm::cptr pInTuple, vm::ptr pOutTuple) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosResolveSync(vm::psv::ptr pAttr, vm::psv::ptr pInTuple, vm::psv::ptr pOutTuple) +s32 sceFiosResolveSync(vm::cptr pAttr, vm::cptr pInTuple, vm::ptr pOutTuple) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosRename(vm::psv::ptr pAttr, vm::psv::ptr pOldPath, vm::psv::ptr pNewPath) +s32 sceFiosRename(vm::cptr pAttr, vm::cptr pOldPath, vm::cptr pNewPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosRenameSync(vm::psv::ptr pAttr, vm::psv::ptr pOldPath, vm::psv::ptr pNewPath) +s32 sceFiosRenameSync(vm::cptr pAttr, vm::cptr pOldPath, vm::cptr pNewPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFileRead(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s32 sceFiosFileRead(vm::cptr pAttr, vm::cptr pPath, vm::ptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFileReadSync(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s64 sceFiosFileReadSync(vm::cptr pAttr, vm::cptr pPath, vm::ptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFileWrite(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s32 sceFiosFileWrite(vm::cptr pAttr, vm::cptr pPath, vm::cptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFileWriteSync(vm::psv::ptr pAttr, vm::psv::ptr pPath, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s64 sceFiosFileWriteSync(vm::cptr pAttr, vm::cptr pPath, vm::cptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFileTruncate(vm::psv::ptr pAttr, vm::psv::ptr pPath, SceFiosSize length) +s32 sceFiosFileTruncate(vm::cptr pAttr, vm::cptr pPath, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFileTruncateSync(vm::psv::ptr pAttr, vm::psv::ptr pPath, SceFiosSize length) +s32 sceFiosFileTruncateSync(vm::cptr pAttr, vm::cptr pPath, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHOpen(vm::psv::ptr pAttr, vm::psv::ptr pOutFH, vm::psv::ptr pPath, vm::psv::ptr pOpenParams) +s32 sceFiosFHOpen(vm::cptr pAttr, vm::ptr pOutFH, vm::cptr pPath, vm::cptr pOpenParams) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFHOpenSync(vm::psv::ptr pAttr, vm::psv::ptr pOutFH, vm::psv::ptr pPath, vm::psv::ptr pOpenParams) +s32 sceFiosFHOpenSync(vm::cptr pAttr, vm::ptr pOutFH, vm::cptr pPath, vm::cptr pOpenParams) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHStat(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pOutStatus) +s32 sceFiosFHStat(vm::cptr pAttr, s32 fh, vm::ptr pOutStatus) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFHStatSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pOutStatus) +s32 sceFiosFHStatSync(vm::cptr pAttr, s32 fh, vm::ptr pOutStatus) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHTruncate(vm::psv::ptr pAttr, SceFiosFH fh, SceFiosSize length) +s32 sceFiosFHTruncate(vm::cptr pAttr, s32 fh, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFHTruncateSync(vm::psv::ptr pAttr, SceFiosFH fh, SceFiosSize length) +s32 sceFiosFHTruncateSync(vm::cptr pAttr, s32 fh, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHSync(vm::psv::ptr pAttr, SceFiosFH fh) +s32 sceFiosFHSync(vm::cptr pAttr, s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFHSyncSync(vm::psv::ptr pAttr, SceFiosFH fh) +s32 sceFiosFHSyncSync(vm::cptr pAttr, s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHRead(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length) +s32 sceFiosFHRead(vm::cptr pAttr, s32 fh, vm::ptr pBuf, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHReadSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length) +s64 sceFiosFHReadSync(vm::cptr pAttr, s32 fh, vm::ptr pBuf, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHWrite(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length) +s32 sceFiosFHWrite(vm::cptr pAttr, s32 fh, vm::cptr pBuf, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHWriteSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length) +s64 sceFiosFHWriteSync(vm::cptr pAttr, s32 fh, vm::cptr pBuf, s64 length) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHReadv(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt) +s32 sceFiosFHReadv(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHReadvSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt) +s64 sceFiosFHReadvSync(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHWritev(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt) +s32 sceFiosFHWritev(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHWritevSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt) +s64 sceFiosFHWritevSync(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHPread(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s32 sceFiosFHPread(vm::cptr pAttr, s32 fh, vm::ptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHPreadSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s64 sceFiosFHPreadSync(vm::cptr pAttr, s32 fh, vm::ptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHPwrite(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s32 sceFiosFHPwrite(vm::cptr pAttr, s32 fh, vm::cptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHPwriteSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr pBuf, SceFiosSize length, SceFiosOffset offset) +s64 sceFiosFHPwriteSync(vm::cptr pAttr, s32 fh, vm::cptr pBuf, s64 length, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHPreadv(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt, SceFiosOffset offset) +s32 sceFiosFHPreadv(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHPreadvSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt, SceFiosOffset offset) +s64 sceFiosFHPreadvSync(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHPwritev(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt, SceFiosOffset offset) +s32 sceFiosFHPwritev(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHPwritevSync(vm::psv::ptr pAttr, SceFiosFH fh, vm::psv::ptr iov, s32 iovcnt, SceFiosOffset offset) +s64 sceFiosFHPwritevSync(vm::cptr pAttr, s32 fh, vm::cptr iov, s32 iovcnt, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosFHClose(vm::psv::ptr pAttr, SceFiosFH fh) +s32 sceFiosFHClose(vm::cptr pAttr, s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosFHCloseSync(vm::psv::ptr pAttr, SceFiosFH fh) +s32 sceFiosFHCloseSync(vm::cptr pAttr, s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOffset sceFiosFHSeek(SceFiosFH fh, SceFiosOffset offset, SceFiosWhence whence) +s64 sceFiosFHSeek(s32 fh, s64 offset, SceFiosWhence whence) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOffset sceFiosFHTell(SceFiosFH fh) +s64 sceFiosFHTell(s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosFHGetPath(SceFiosFH fh) +vm::cptr sceFiosFHGetPath(s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosFHGetSize(SceFiosFH fh) +s64 sceFiosFHGetSize(s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosFHGetOpenParams(SceFiosFH fh) +vm::ptr sceFiosFHGetOpenParams(s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//SceFiosOp sceFiosDHOpen(vm::psv::ptr pAttr, vm::psv::ptr pOutDH, vm::psv::ptr pPath, SceFiosBuffer buf) -//{ -// throw __FUNCTION__; -//} -// -//s32 sceFiosDHOpenSync(vm::psv::ptr pAttr, vm::psv::ptr pOutDH, vm::psv::ptr pPath, SceFiosBuffer buf) -//{ -// throw __FUNCTION__; -//} +s32 sceFiosDHOpen(vm::cptr pAttr, vm::ptr pOutDH, vm::cptr pPath, SceFiosBuffer buf) +{ + throw EXCEPTION(""); +} + +s32 sceFiosDHOpenSync(vm::cptr pAttr, vm::ptr pOutDH, vm::cptr pPath, SceFiosBuffer buf) +{ + throw EXCEPTION(""); +} -SceFiosOp sceFiosDHRead(vm::psv::ptr pAttr, SceFiosDH dh, vm::psv::ptr pOutEntry) +s32 sceFiosDHRead(vm::cptr pAttr, s32 dh, vm::ptr pOutEntry) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosDHReadSync(vm::psv::ptr pAttr, SceFiosDH dh, vm::psv::ptr pOutEntry) +s32 sceFiosDHReadSync(vm::cptr pAttr, s32 dh, vm::ptr pOutEntry) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosDHClose(vm::psv::ptr pAttr, SceFiosDH dh) +s32 sceFiosDHClose(vm::cptr pAttr, s32 dh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosDHCloseSync(vm::psv::ptr pAttr, SceFiosDH dh) +s32 sceFiosDHCloseSync(vm::cptr pAttr, s32 dh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDHGetPath(SceFiosDH dh) +vm::cptr sceFiosDHGetPath(s32 dh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosOpIsDone(SceFiosOp op) +bool sceFiosOpIsDone(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOpWait(SceFiosOp op) +s32 sceFiosOpWait(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOpWaitUntil(SceFiosOp op, SceFiosTime deadline) +s32 sceFiosOpWaitUntil(s32 op, s64 deadline) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosOpDelete(SceFiosOp op) +void sceFiosOpDelete(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOpSyncWait(SceFiosOp op) +s32 sceFiosOpSyncWait(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosOpSyncWaitForIO(SceFiosOp op) +s64 sceFiosOpSyncWaitForIO(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOpGetError(SceFiosOp op) +s32 sceFiosOpGetError(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosOpCancel(SceFiosOp op) +void sceFiosOpCancel(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceFiosOpIsCancelled(SceFiosOp op) +bool sceFiosOpIsCancelled(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosOpGetAttr(SceFiosOp op) +vm::cptr sceFiosOpGetAttr(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosOpGetPath(SceFiosOp op) +vm::cptr sceFiosOpGetPath(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosOpGetBuffer(SceFiosOp op) +vm::ptr sceFiosOpGetBuffer(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOffset sceFiosOpGetOffset(SceFiosOp op) +s64 sceFiosOpGetOffset(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosOpGetRequestCount(SceFiosOp op) +s64 sceFiosOpGetRequestCount(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosOpGetActualCount(SceFiosOp op) +s64 sceFiosOpGetActualCount(s32 op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceFiosOpReschedule(SceFiosOp op, SceFiosTime newDeadline) +void sceFiosOpReschedule(s32 op, s64 newDeadline) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosTime sceFiosTimeGetCurrent() +s64 sceFiosTimeGetCurrent() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s64 sceFiosTimeIntervalToNanoseconds(SceFiosTimeInterval interval) +s64 sceFiosTimeIntervalToNanoseconds(s64 interval) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosTimeInterval sceFiosTimeIntervalFromNanoseconds(s64 ns) +s64 sceFiosTimeIntervalFromNanoseconds(s64 ns) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosDate sceFiosDateGetCurrent() +u64 sceFiosDateGetCurrent() { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosDate sceFiosDateFromComponents(vm::psv::ptr pComponents) +u64 sceFiosDateFromComponents(vm::cptr pComponents) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDateToComponents(SceFiosDate date, vm::psv::ptr pOutComponents) +vm::ptr sceFiosDateToComponents(u64 date, vm::ptr pOutComponents) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosDate sceFiosDateFromSceDateTime(vm::psv::ptr pSceDateTime) +u64 sceFiosDateFromSceDateTime(vm::cptr pSceDateTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDateToSceDateTime(SceFiosDate date, vm::psv::ptr pSceDateTime) +vm::ptr sceFiosDateToSceDateTime(u64 date, vm::ptr pSceDateTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOverlayAdd(vm::psv::ptr pOverlay, vm::psv::ptr pOutID) +s32 sceFiosOverlayAdd(vm::cptr pOverlay, vm::ptr pOutID) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOverlayRemove(SceFiosOverlayID id) +s32 sceFiosOverlayRemove(s32 id) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOverlayGetInfo(SceFiosOverlayID id, vm::psv::ptr pOutOverlay) +s32 sceFiosOverlayGetInfo(s32 id, vm::ptr pOutOverlay) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOverlayModify(SceFiosOverlayID id, vm::psv::ptr pNewValue) +s32 sceFiosOverlayModify(s32 id, vm::cptr pNewValue) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOverlayGetList(vm::psv::ptr pOutIDs, u32 maxIDs, vm::psv::ptr pActualIDs) +s32 sceFiosOverlayGetList(vm::ptr pOutIDs, u32 maxIDs, vm::ptr pActualIDs) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosOverlayResolveSync(s32 resolveFlag, vm::psv::ptr pInPath, vm::psv::ptr pOutPath, u32 maxPath) +s32 sceFiosOverlayResolveSync(s32 resolveFlag, vm::cptr pInPath, vm::ptr pOutPath, u32 maxPath) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosOp sceFiosArchiveGetMountBufferSize(vm::psv::ptr pAttr, vm::psv::ptr pArchivePath, vm::psv::ptr pOpenParams) +s32 sceFiosArchiveGetMountBufferSize(vm::cptr pAttr, vm::cptr pArchivePath, vm::cptr pOpenParams) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceFiosSize sceFiosArchiveGetMountBufferSizeSync(vm::psv::ptr pAttr, vm::psv::ptr pArchivePath, vm::psv::ptr pOpenParams) +s64 sceFiosArchiveGetMountBufferSizeSync(vm::cptr pAttr, vm::cptr pArchivePath, vm::cptr pOpenParams) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//SceFiosOp sceFiosArchiveMount(vm::psv::ptr pAttr, vm::psv::ptr pOutFH, vm::psv::ptr pArchivePath, vm::psv::ptr pMountPoint, SceFiosBuffer mountBuffer, vm::psv::ptr pOpenParams) -//{ -// throw __FUNCTION__; -//} -// -//s32 sceFiosArchiveMountSync(vm::psv::ptr pAttr, vm::psv::ptr pOutFH, vm::psv::ptr pArchivePath, vm::psv::ptr pMountPoint, SceFiosBuffer mountBuffer, vm::psv::ptr pOpenParams) -//{ -// throw __FUNCTION__; -//} +s32 sceFiosArchiveMount(vm::cptr pAttr, vm::ptr pOutFH, vm::cptr pArchivePath, vm::cptr pMountPoint, SceFiosBuffer mountBuffer, vm::cptr pOpenParams) +{ + throw EXCEPTION(""); +} + +s32 sceFiosArchiveMountSync(vm::cptr pAttr, vm::ptr pOutFH, vm::cptr pArchivePath, vm::cptr pMountPoint, SceFiosBuffer mountBuffer, vm::cptr pOpenParams) +{ + throw EXCEPTION(""); +} -SceFiosOp sceFiosArchiveUnmount(vm::psv::ptr pAttr, SceFiosFH fh) +s32 sceFiosArchiveUnmount(vm::cptr pAttr, s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosArchiveUnmountSync(vm::psv::ptr pAttr, SceFiosFH fh) +s32 sceFiosArchiveUnmountSync(vm::cptr pAttr, s32 fh) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDebugDumpError(s32 err, vm::psv::ptr pBuffer, u32 bufferSize) +vm::ptr sceFiosDebugDumpError(s32 err, vm::ptr pBuffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDebugDumpOp(SceFiosOp op, vm::psv::ptr pBuffer, u32 bufferSize) +vm::ptr sceFiosDebugDumpOp(s32 op, vm::ptr pBuffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDebugDumpFH(SceFiosFH fh, vm::psv::ptr pBuffer, u32 bufferSize) +vm::ptr sceFiosDebugDumpFH(s32 fh, vm::ptr pBuffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDebugDumpDH(SceFiosDH dh, vm::psv::ptr pBuffer, u32 bufferSize) +vm::ptr sceFiosDebugDumpDH(s32 dh, vm::ptr pBuffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceFiosDebugDumpDate(SceFiosDate date, vm::psv::ptr pBuffer, u32 bufferSize) +vm::ptr sceFiosDebugDumpDate(u64 date, vm::ptr pBuffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosIOFilterAdd(s32 index, SceFiosIOFilterCallback pFilterCallback, vm::psv::ptr pFilterContext) +s32 sceFiosIOFilterAdd(s32 index, vm::ptr pFilterCallback, vm::ptr pFilterContext) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceFiosIOFilterGetInfo(s32 index, vm::psv::ptr pOutFilterCallback, vm::psv::pptr pOutFilterContext) +s32 sceFiosIOFilterGetInfo(s32 index, vm::pptr pOutFilterCallback, vm::pptr pOutFilterContext) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceFiosIOFilterRemove(s32 index) { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceFiosIOFilterPsarcDearchiver() { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceFios, #name, name) @@ -809,6 +691,7 @@ psv_log_base sceFios("SceFios2", []() sceFios.on_load = nullptr; sceFios.on_unload = nullptr; sceFios.on_stop = nullptr; + sceFios.on_error = nullptr; REG_FUNC(0x15857180, sceFiosArchiveGetMountBufferSize); REG_FUNC(0xDF3352FC, sceFiosArchiveGetMountBufferSizeSync); diff --git a/rpcs3/Emu/ARMv7/Modules/sceFios.h b/rpcs3/Emu/ARMv7/Modules/sceFios.h new file mode 100644 index 0000000000..68c14608fa --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceFios.h @@ -0,0 +1,113 @@ +#pragma once + +using SceFiosOpCallback = func_def pContext, s32 op, u8 event, s32 err)>; +using SceFiosVprintfCallback = func_def fmt, va_list ap)>; +using SceFiosMemcpyCallback = func_def(vm::ptr dst, vm::cptr src, u32 len)>; + +enum SceFiosWhence : s32 +{ + SCE_FIOS_SEEK_SET = 0, + SCE_FIOS_SEEK_CUR = 1, + SCE_FIOS_SEEK_END = 2, +}; + +struct SceFiosBuffer +{ + vm::lptr pPtr; + le_t length; +}; + +struct SceFiosOpAttr +{ + le_t deadline; + vm::lptr pCallback; + vm::lptr pCallbackContext; + + //le_t priority : 8; + //le_t opflags : 24; + le_t params; // priority, opflags + + le_t userTag; + vm::lptr userPtr; + vm::lptr pReserved; +}; + +struct SceFiosDirEntry +{ + le_t fileSize; + le_t statFlags; + le_t nameLength; + le_t fullPathLength; + le_t offsetToName; + le_t reserved[3]; + char fullPath[1024]; +}; + +struct SceFiosStat +{ + le_t fileSize; + le_t accessDate; + le_t modificationDate; + le_t creationDate; + le_t statFlags; + le_t reserved; + le_t uid; + le_t gid; + le_t dev; + le_t ino; + le_t mode; +}; + +struct SceFiosOpenParams +{ + le_t openFlags; + le_t reserved; + SceFiosBuffer buffer; +}; + +struct SceFiosTuple +{ + le_t offset; + le_t size; + char path[1024]; +}; + +struct SceFiosParams +{ + //le_t initialized : 1; + //le_t paramsSize : 14; + //le_t pathMax : 16; + le_t params; // initialized, paramsSize, pathMax + + le_t profiling; + SceFiosBuffer opStorage; + SceFiosBuffer fhStorage; + SceFiosBuffer dhStorage; + SceFiosBuffer chunkStorage; + vm::lptr pVprintf; + vm::lptr pMemcpy; + le_t threadPriority[2]; + le_t threadAffinity[2]; +}; + +struct SceFiosOverlay +{ + u8 type; + u8 order; + u8 reserved[10]; + le_t id; + char dst[292]; + char src[292]; +}; + +using SceFiosIOFilterCallback = func_def; + +struct SceFiosPsarcDearchiverContext +{ + le_t sizeOfContext; + le_t workBufferSize; + vm::lptr pWorkBuffer; + le_t reserved[4]; +}; + +extern psv_log_base sceFios; diff --git a/rpcs3/Emu/ARMv7/Modules/sceFpu.cpp b/rpcs3/Emu/ARMv7/Modules/sceFpu.cpp index 2992c6fc58..27b7c6e5c7 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceFpu.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceFpu.cpp @@ -2,7 +2,79 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceFpu; +#include "sceFpu.h" + +float sceFpuSinf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuCosf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuTanf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuAtanf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuAtan2f(float y, float x) +{ + throw EXCEPTION(""); +} + +float sceFpuAsinf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuAcosf(float x) +{ + throw EXCEPTION(""); +} + + +float sceFpuLogf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuLog2f(float fs) +{ + throw EXCEPTION(""); +} + +float sceFpuLog10f(float fs) +{ + throw EXCEPTION(""); +} + +float sceFpuExpf(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuExp2f(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuExp10f(float x) +{ + throw EXCEPTION(""); +} + +float sceFpuPowf(float x, float y) +{ + throw EXCEPTION(""); +} + #define REG_FUNC(nid, name) reg_psv_func(nid, &sceFpu, #name, name) @@ -11,6 +83,7 @@ psv_log_base sceFpu("SceFpu", []() sceFpu.on_load = nullptr; sceFpu.on_unload = nullptr; sceFpu.on_stop = nullptr; + sceFpu.on_error = nullptr; //REG_FUNC(0x33E1AC14, sceFpuSinf); //REG_FUNC(0xDB66BA89, sceFpuCosf); diff --git a/rpcs3/Emu/ARMv7/Modules/sceFpu.h b/rpcs3/Emu/ARMv7/Modules/sceFpu.h new file mode 100644 index 0000000000..2df62880d4 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceFpu.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceFpu; diff --git a/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp b/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp index 2ef54331e5..0a176282a9 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceGxm.cpp @@ -4,1066 +4,1066 @@ #include "sceGxm.h" -s32 sceGxmInitialize(vm::psv::ptr params) +s32 sceGxmInitialize(vm::cptr params) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceGxmTerminate() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmGetNotificationRegion() +vm::ptr sceGxmGetNotificationRegion() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmNotificationWait(vm::psv::ptr notification) +s32 sceGxmNotificationWait(vm::cptr notification) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmMapMemory(vm::psv::ptr base, u32 size, SceGxmMemoryAttribFlags attr) +s32 sceGxmMapMemory(vm::ptr base, u32 size, SceGxmMemoryAttribFlags attr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmUnmapMemory(vm::psv::ptr base) +s32 sceGxmUnmapMemory(vm::ptr base) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmMapVertexUsseMemory(vm::psv::ptr base, u32 size, vm::psv::ptr offset) +s32 sceGxmMapVertexUsseMemory(vm::ptr base, u32 size, vm::ptr offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmUnmapVertexUsseMemory(vm::psv::ptr base) +s32 sceGxmUnmapVertexUsseMemory(vm::ptr base) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmMapFragmentUsseMemory(vm::psv::ptr base, u32 size, vm::psv::ptr offset) +s32 sceGxmMapFragmentUsseMemory(vm::ptr base, u32 size, vm::ptr offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmUnmapFragmentUsseMemory(vm::psv::ptr base) +s32 sceGxmUnmapFragmentUsseMemory(vm::ptr base) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDisplayQueueAddEntry(vm::psv::ptr oldBuffer, vm::psv::ptr newBuffer, vm::psv::ptr callbackData) +s32 sceGxmDisplayQueueAddEntry(vm::ptr oldBuffer, vm::ptr newBuffer, vm::cptr callbackData) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceGxmDisplayQueueFinish() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSyncObjectCreate(vm::psv::pptr syncObject) +s32 sceGxmSyncObjectCreate(vm::pptr syncObject) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSyncObjectDestroy(vm::psv::ptr syncObject) +s32 sceGxmSyncObjectDestroy(vm::ptr syncObject) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmCreateContext(vm::psv::ptr params, vm::psv::pptr context) +s32 sceGxmCreateContext(vm::cptr params, vm::pptr context) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDestroyContext(vm::psv::ptr context) +s32 sceGxmDestroyContext(vm::ptr context) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetValidationEnable(vm::psv::ptr context, bool enable) +void sceGxmSetValidationEnable(vm::ptr context, bool enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetVertexProgram(vm::psv::ptr context, vm::psv::ptr vertexProgram) +void sceGxmSetVertexProgram(vm::ptr context, vm::cptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFragmentProgram(vm::psv::ptr context, vm::psv::ptr fragmentProgram) +void sceGxmSetFragmentProgram(vm::ptr context, vm::cptr fragmentProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmReserveVertexDefaultUniformBuffer(vm::psv::ptr context, vm::psv::pptr uniformBuffer) +s32 sceGxmReserveVertexDefaultUniformBuffer(vm::ptr context, vm::pptr uniformBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmReserveFragmentDefaultUniformBuffer(vm::psv::ptr context, vm::psv::pptr uniformBuffer) +s32 sceGxmReserveFragmentDefaultUniformBuffer(vm::ptr context, vm::pptr uniformBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetVertexStream(vm::psv::ptr context, u32 streamIndex, vm::psv::ptr streamData) +s32 sceGxmSetVertexStream(vm::ptr context, u32 streamIndex, vm::cptr streamData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetVertexTexture(vm::psv::ptr context, u32 textureIndex, vm::psv::ptr texture) +s32 sceGxmSetVertexTexture(vm::ptr context, u32 textureIndex, vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetFragmentTexture(vm::psv::ptr context, u32 textureIndex, vm::psv::ptr texture) +s32 sceGxmSetFragmentTexture(vm::ptr context, u32 textureIndex, vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetVertexUniformBuffer(vm::psv::ptr context, u32 bufferIndex, vm::psv::ptr bufferData) +s32 sceGxmSetVertexUniformBuffer(vm::ptr context, u32 bufferIndex, vm::cptr bufferData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetFragmentUniformBuffer(vm::psv::ptr context, u32 bufferIndex, vm::psv::ptr bufferData) +s32 sceGxmSetFragmentUniformBuffer(vm::ptr context, u32 bufferIndex, vm::cptr bufferData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetAuxiliarySurface(vm::psv::ptr context, u32 surfaceIndex, vm::psv::ptr surface) +s32 sceGxmSetAuxiliarySurface(vm::ptr context, u32 surfaceIndex, vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetPrecomputedFragmentState(vm::psv::ptr context, vm::psv::ptr precomputedState) +void sceGxmSetPrecomputedFragmentState(vm::ptr context, vm::cptr precomputedState) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetPrecomputedVertexState(vm::psv::ptr context, vm::psv::ptr precomputedState) +void sceGxmSetPrecomputedVertexState(vm::ptr context, vm::cptr precomputedState) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDrawPrecomputed(vm::psv::ptr context, vm::psv::ptr precomputedDraw) +s32 sceGxmDrawPrecomputed(vm::ptr context, vm::cptr precomputedDraw) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDraw(vm::psv::ptr context, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::psv::ptr indexData, u32 indexCount) +s32 sceGxmDraw(vm::ptr context, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::cptr indexData, u32 indexCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDrawInstanced(vm::psv::ptr context, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::psv::ptr indexData, u32 indexCount, u32 indexWrap) +s32 sceGxmDrawInstanced(vm::ptr context, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::cptr indexData, u32 indexCount, u32 indexWrap) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetVisibilityBuffer(vm::psv::ptr context, vm::psv::ptr bufferBase, u32 stridePerCore) +s32 sceGxmSetVisibilityBuffer(vm::ptr context, vm::ptr bufferBase, u32 stridePerCore) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmBeginScene(vm::psv::ptr context, u32 flags, vm::psv::ptr renderTarget, vm::psv::ptr validRegion, vm::psv::ptr vertexSyncObject, vm::psv::ptr fragmentSyncObject, vm::psv::ptr colorSurface, vm::psv::ptr depthStencil) +s32 sceGxmBeginScene(vm::ptr context, u32 flags, vm::cptr renderTarget, vm::cptr validRegion, vm::ptr vertexSyncObject, vm::ptr fragmentSyncObject, vm::cptr colorSurface, vm::cptr depthStencil) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmMidSceneFlush(vm::psv::ptr context, u32 flags, vm::psv::ptr vertexSyncObject, vm::psv::ptr vertexNotification) +s32 sceGxmMidSceneFlush(vm::ptr context, u32 flags, vm::ptr vertexSyncObject, vm::cptr vertexNotification) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmEndScene(vm::psv::ptr context, vm::psv::ptr vertexNotification, vm::psv::ptr fragmentNotification) +s32 sceGxmEndScene(vm::ptr context, vm::cptr vertexNotification, vm::cptr fragmentNotification) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontDepthFunc(vm::psv::ptr context, SceGxmDepthFunc depthFunc) +void sceGxmSetFrontDepthFunc(vm::ptr context, SceGxmDepthFunc depthFunc) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackDepthFunc(vm::psv::ptr context, SceGxmDepthFunc depthFunc) +void sceGxmSetBackDepthFunc(vm::ptr context, SceGxmDepthFunc depthFunc) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontFragmentProgramEnable(vm::psv::ptr context, SceGxmFragmentProgramMode enable) +void sceGxmSetFrontFragmentProgramEnable(vm::ptr context, SceGxmFragmentProgramMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackFragmentProgramEnable(vm::psv::ptr context, SceGxmFragmentProgramMode enable) +void sceGxmSetBackFragmentProgramEnable(vm::ptr context, SceGxmFragmentProgramMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontDepthWriteEnable(vm::psv::ptr context, SceGxmDepthWriteMode enable) +void sceGxmSetFrontDepthWriteEnable(vm::ptr context, SceGxmDepthWriteMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackDepthWriteEnable(vm::psv::ptr context, SceGxmDepthWriteMode enable) +void sceGxmSetBackDepthWriteEnable(vm::ptr context, SceGxmDepthWriteMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontLineFillLastPixelEnable(vm::psv::ptr context, SceGxmLineFillLastPixelMode enable) +void sceGxmSetFrontLineFillLastPixelEnable(vm::ptr context, SceGxmLineFillLastPixelMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackLineFillLastPixelEnable(vm::psv::ptr context, SceGxmLineFillLastPixelMode enable) +void sceGxmSetBackLineFillLastPixelEnable(vm::ptr context, SceGxmLineFillLastPixelMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontStencilRef(vm::psv::ptr context, u32 sref) +void sceGxmSetFrontStencilRef(vm::ptr context, u32 sref) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackStencilRef(vm::psv::ptr context, u32 sref) +void sceGxmSetBackStencilRef(vm::ptr context, u32 sref) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontPointLineWidth(vm::psv::ptr context, u32 width) +void sceGxmSetFrontPointLineWidth(vm::ptr context, u32 width) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackPointLineWidth(vm::psv::ptr context, u32 width) +void sceGxmSetBackPointLineWidth(vm::ptr context, u32 width) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontPolygonMode(vm::psv::ptr context, SceGxmPolygonMode mode) +void sceGxmSetFrontPolygonMode(vm::ptr context, SceGxmPolygonMode mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackPolygonMode(vm::psv::ptr context, SceGxmPolygonMode mode) +void sceGxmSetBackPolygonMode(vm::ptr context, SceGxmPolygonMode mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontStencilFunc(vm::psv::ptr context, SceGxmStencilFunc func, SceGxmStencilOp stencilFail, SceGxmStencilOp depthFail, SceGxmStencilOp depthPass, u8 compareMask, u8 writeMask) +void sceGxmSetFrontStencilFunc(vm::ptr context, SceGxmStencilFunc func, SceGxmStencilOp stencilFail, SceGxmStencilOp depthFail, SceGxmStencilOp depthPass, u8 compareMask, u8 writeMask) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackStencilFunc(vm::psv::ptr context, SceGxmStencilFunc func, SceGxmStencilOp stencilFail, SceGxmStencilOp depthFail, SceGxmStencilOp depthPass, u8 compareMask, u8 writeMask) +void sceGxmSetBackStencilFunc(vm::ptr context, SceGxmStencilFunc func, SceGxmStencilOp stencilFail, SceGxmStencilOp depthFail, SceGxmStencilOp depthPass, u8 compareMask, u8 writeMask) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontDepthBias(vm::psv::ptr context, s32 factor, s32 units) +void sceGxmSetFrontDepthBias(vm::ptr context, s32 factor, s32 units) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackDepthBias(vm::psv::ptr context, s32 factor, s32 units) +void sceGxmSetBackDepthBias(vm::ptr context, s32 factor, s32 units) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetTwoSidedEnable(vm::psv::ptr context, SceGxmTwoSidedMode enable) +void sceGxmSetTwoSidedEnable(vm::ptr context, SceGxmTwoSidedMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//void sceGxmSetViewport(vm::psv::ptr context, float xOffset, float xScale, float yOffset, float yScale, float zOffset, float zScale) -//{ -// throw __FUNCTION__; -//} -// -//void sceGxmSetWClampValue(vm::psv::ptr context, float clampValue) -//{ -// throw __FUNCTION__; -//} - -void sceGxmSetWClampEnable(vm::psv::ptr context, SceGxmWClampMode enable) +void sceGxmSetViewport(vm::ptr context, float xOffset, float xScale, float yOffset, float yScale, float zOffset, float zScale) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetRegionClip(vm::psv::ptr context, SceGxmRegionClipMode mode, u32 xMin, u32 yMin, u32 xMax, u32 yMax) +void sceGxmSetWClampValue(vm::ptr context, float clampValue) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetCullMode(vm::psv::ptr context, SceGxmCullMode mode) +void sceGxmSetWClampEnable(vm::ptr context, SceGxmWClampMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetViewportEnable(vm::psv::ptr context, SceGxmViewportMode enable) +void sceGxmSetRegionClip(vm::ptr context, SceGxmRegionClipMode mode, u32 xMin, u32 yMin, u32 xMax, u32 yMax) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetWBufferEnable(vm::psv::ptr context, SceGxmWBufferMode enable) +void sceGxmSetCullMode(vm::ptr context, SceGxmCullMode mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontVisibilityTestIndex(vm::psv::ptr context, u32 index) +void sceGxmSetViewportEnable(vm::ptr context, SceGxmViewportMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackVisibilityTestIndex(vm::psv::ptr context, u32 index) +void sceGxmSetWBufferEnable(vm::ptr context, SceGxmWBufferMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontVisibilityTestOp(vm::psv::ptr context, SceGxmVisibilityTestOp op) +void sceGxmSetFrontVisibilityTestIndex(vm::ptr context, u32 index) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackVisibilityTestOp(vm::psv::ptr context, SceGxmVisibilityTestOp op) +void sceGxmSetBackVisibilityTestIndex(vm::ptr context, u32 index) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetFrontVisibilityTestEnable(vm::psv::ptr context, SceGxmVisibilityTestMode enable) +void sceGxmSetFrontVisibilityTestOp(vm::ptr context, SceGxmVisibilityTestOp op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmSetBackVisibilityTestEnable(vm::psv::ptr context, SceGxmVisibilityTestMode enable) +void sceGxmSetBackVisibilityTestOp(vm::ptr context, SceGxmVisibilityTestOp op) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmFinish(vm::psv::ptr context) +void sceGxmSetFrontVisibilityTestEnable(vm::ptr context, SceGxmVisibilityTestMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPushUserMarker(vm::psv::ptr context, vm::psv::ptr tag) +void sceGxmSetBackVisibilityTestEnable(vm::ptr context, SceGxmVisibilityTestMode enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPopUserMarker(vm::psv::ptr context) +void sceGxmFinish(vm::ptr context) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetUserMarker(vm::psv::ptr context, vm::psv::ptr tag) +s32 sceGxmPushUserMarker(vm::ptr context, vm::cptr tag) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPadHeartbeat(vm::psv::ptr displaySurface, vm::psv::ptr displaySyncObject) +s32 sceGxmPopUserMarker(vm::ptr context) { - throw __FUNCTION__; + throw EXCEPTION(""); +} + +s32 sceGxmSetUserMarker(vm::ptr context, vm::cptr tag) +{ + throw EXCEPTION(""); +} + +s32 sceGxmPadHeartbeat(vm::cptr displaySurface, vm::ptr displaySyncObject) +{ + throw EXCEPTION(""); } s32 sceGxmPadTriggerGpuPaTrace() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmColorSurfaceInit(vm::psv::ptr surface, SceGxmColorFormat colorFormat, SceGxmColorSurfaceType surfaceType, SceGxmColorSurfaceScaleMode scaleMode, SceGxmOutputRegisterSize outputRegisterSize, u32 width, u32 height, u32 strideInPixels, vm::psv::ptr data) +s32 sceGxmColorSurfaceInit(vm::ptr surface, SceGxmColorFormat colorFormat, SceGxmColorSurfaceType surfaceType, SceGxmColorSurfaceScaleMode scaleMode, SceGxmOutputRegisterSize outputRegisterSize, u32 width, u32 height, u32 strideInPixels, vm::ptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmColorSurfaceInitDisabled(vm::psv::ptr surface) +s32 sceGxmColorSurfaceInitDisabled(vm::ptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceGxmColorSurfaceIsEnabled(vm::psv::ptr surface) +bool sceGxmColorSurfaceIsEnabled(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmColorSurfaceGetClip(vm::psv::ptr surface, vm::psv::ptr xMin, vm::psv::ptr yMin, vm::psv::ptr xMax, vm::psv::ptr yMax) +void sceGxmColorSurfaceGetClip(vm::cptr surface, vm::ptr xMin, vm::ptr yMin, vm::ptr xMax, vm::ptr yMax) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmColorSurfaceSetClip(vm::psv::ptr surface, u32 xMin, u32 yMin, u32 xMax, u32 yMax) +void sceGxmColorSurfaceSetClip(vm::ptr surface, u32 xMin, u32 yMin, u32 xMax, u32 yMax) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmColorSurfaceScaleMode sceGxmColorSurfaceGetScaleMode(vm::psv::ptr surface) +SceGxmColorSurfaceScaleMode sceGxmColorSurfaceGetScaleMode(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmColorSurfaceSetScaleMode(vm::psv::ptr surface, SceGxmColorSurfaceScaleMode scaleMode) +void sceGxmColorSurfaceSetScaleMode(vm::ptr surface, SceGxmColorSurfaceScaleMode scaleMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmColorSurfaceGetData(vm::psv::ptr surface) +vm::ptr sceGxmColorSurfaceGetData(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmColorSurfaceSetData(vm::psv::ptr surface, vm::psv::ptr data) +s32 sceGxmColorSurfaceSetData(vm::ptr surface, vm::ptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmColorFormat sceGxmColorSurfaceGetFormat(vm::psv::ptr surface) +SceGxmColorFormat sceGxmColorSurfaceGetFormat(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmColorSurfaceSetFormat(vm::psv::ptr surface, SceGxmColorFormat format) +s32 sceGxmColorSurfaceSetFormat(vm::ptr surface, SceGxmColorFormat format) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmColorSurfaceType sceGxmColorSurfaceGetType(vm::psv::ptr surface) +SceGxmColorSurfaceType sceGxmColorSurfaceGetType(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmColorSurfaceGetStrideInPixels(vm::psv::ptr surface) +u32 sceGxmColorSurfaceGetStrideInPixels(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDepthStencilSurfaceInit(vm::psv::ptr surface, SceGxmDepthStencilFormat depthStencilFormat, SceGxmDepthStencilSurfaceType surfaceType, u32 strideInSamples, vm::psv::ptr depthData, vm::psv::ptr stencilData) +s32 sceGxmDepthStencilSurfaceInit(vm::ptr surface, SceGxmDepthStencilFormat depthStencilFormat, SceGxmDepthStencilSurfaceType surfaceType, u32 strideInSamples, vm::ptr depthData, vm::ptr stencilData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDepthStencilSurfaceInitDisabled(vm::psv::ptr surface) +s32 sceGxmDepthStencilSurfaceInitDisabled(vm::ptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//float sceGxmDepthStencilSurfaceGetBackgroundDepth(vm::psv::ptr surface) -//{ -// throw __FUNCTION__; -//} +float sceGxmDepthStencilSurfaceGetBackgroundDepth(vm::cptr surface) +{ + throw EXCEPTION(""); +} -//void sceGxmDepthStencilSurfaceSetBackgroundDepth(vm::psv::ptr surface, float backgroundDepth) -//{ -// throw __FUNCTION__; -//} +void sceGxmDepthStencilSurfaceSetBackgroundDepth(vm::ptr surface, float backgroundDepth) +{ + throw EXCEPTION(""); +} -u8 sceGxmDepthStencilSurfaceGetBackgroundStencil(vm::psv::ptr surface) +u8 sceGxmDepthStencilSurfaceGetBackgroundStencil(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmDepthStencilSurfaceSetBackgroundStencil(vm::psv::ptr surface, u8 backgroundStencil) +void sceGxmDepthStencilSurfaceSetBackgroundStencil(vm::ptr surface, u8 backgroundStencil) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceGxmDepthStencilSurfaceIsEnabled(vm::psv::ptr surface) +bool sceGxmDepthStencilSurfaceIsEnabled(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmDepthStencilSurfaceSetForceLoadMode(vm::psv::ptr surface, SceGxmDepthStencilForceLoadMode forceLoad) +void sceGxmDepthStencilSurfaceSetForceLoadMode(vm::ptr surface, SceGxmDepthStencilForceLoadMode forceLoad) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmDepthStencilForceLoadMode sceGxmDepthStencilSurfaceGetForceLoadMode(vm::psv::ptr surface) +SceGxmDepthStencilForceLoadMode sceGxmDepthStencilSurfaceGetForceLoadMode(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmDepthStencilSurfaceSetForceStoreMode(vm::psv::ptr surface, SceGxmDepthStencilForceStoreMode forceStore) +void sceGxmDepthStencilSurfaceSetForceStoreMode(vm::ptr surface, SceGxmDepthStencilForceStoreMode forceStore) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmDepthStencilForceStoreMode sceGxmDepthStencilSurfaceGetForceStoreMode(vm::psv::ptr surface) +SceGxmDepthStencilForceStoreMode sceGxmDepthStencilSurfaceGetForceStoreMode(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmColorSurfaceGammaMode sceGxmColorSurfaceGetGammaMode(vm::psv::ptr surface) +SceGxmColorSurfaceGammaMode sceGxmColorSurfaceGetGammaMode(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmColorSurfaceSetGammaMode(vm::psv::ptr surface, SceGxmColorSurfaceGammaMode gammaMode) +s32 sceGxmColorSurfaceSetGammaMode(vm::ptr surface, SceGxmColorSurfaceGammaMode gammaMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmColorSurfaceDitherMode sceGxmColorSurfaceGetDitherMode(vm::psv::ptr surface) +SceGxmColorSurfaceDitherMode sceGxmColorSurfaceGetDitherMode(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmColorSurfaceSetDitherMode(vm::psv::ptr surface, SceGxmColorSurfaceDitherMode ditherMode) +s32 sceGxmColorSurfaceSetDitherMode(vm::ptr surface, SceGxmColorSurfaceDitherMode ditherMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmDepthStencilFormat sceGxmDepthStencilSurfaceGetFormat(vm::psv::ptr surface) +SceGxmDepthStencilFormat sceGxmDepthStencilSurfaceGetFormat(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmDepthStencilSurfaceGetStrideInSamples(vm::psv::ptr surface) +u32 sceGxmDepthStencilSurfaceGetStrideInSamples(vm::cptr surface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmProgramCheck(vm::psv::ptr program) +s32 sceGxmProgramCheck(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramGetSize(vm::psv::ptr program) +u32 sceGxmProgramGetSize(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmProgramType sceGxmProgramGetType(vm::psv::ptr program) +SceGxmProgramType sceGxmProgramGetType(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceGxmProgramIsDiscardUsed(vm::psv::ptr program) +bool sceGxmProgramIsDiscardUsed(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceGxmProgramIsDepthReplaceUsed(vm::psv::ptr program) +bool sceGxmProgramIsDepthReplaceUsed(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceGxmProgramIsSpriteCoordUsed(vm::psv::ptr program) +bool sceGxmProgramIsSpriteCoordUsed(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramGetDefaultUniformBufferSize(vm::psv::ptr program) +u32 sceGxmProgramGetDefaultUniformBufferSize(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramGetParameterCount(vm::psv::ptr program) +u32 sceGxmProgramGetParameterCount(vm::cptr program) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmProgramGetParameter(vm::psv::ptr program, u32 index) +vm::cptr sceGxmProgramGetParameter(vm::cptr program, u32 index) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmProgramFindParameterByName(vm::psv::ptr program, vm::psv::ptr name) +vm::cptr sceGxmProgramFindParameterByName(vm::cptr program, vm::cptr name) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmProgramFindParameterBySemantic(vm::psv::ptr program, SceGxmParameterSemantic semantic, u32 index) +vm::cptr sceGxmProgramFindParameterBySemantic(vm::cptr program, SceGxmParameterSemantic semantic, u32 index) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramParameterGetIndex(vm::psv::ptr program, vm::psv::ptr parameter) +u32 sceGxmProgramParameterGetIndex(vm::cptr program, vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmParameterCategory sceGxmProgramParameterGetCategory(vm::psv::ptr parameter) +SceGxmParameterCategory sceGxmProgramParameterGetCategory(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmProgramParameterGetName(vm::psv::ptr parameter) +vm::cptr sceGxmProgramParameterGetName(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmParameterSemantic sceGxmProgramParameterGetSemantic(vm::psv::ptr parameter) +SceGxmParameterSemantic sceGxmProgramParameterGetSemantic(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramParameterGetSemanticIndex(vm::psv::ptr parameter) +u32 sceGxmProgramParameterGetSemanticIndex(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmParameterType sceGxmProgramParameterGetType(vm::psv::ptr parameter) +SceGxmParameterType sceGxmProgramParameterGetType(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramParameterGetComponentCount(vm::psv::ptr parameter) +u32 sceGxmProgramParameterGetComponentCount(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramParameterGetArraySize(vm::psv::ptr parameter) +u32 sceGxmProgramParameterGetArraySize(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramParameterGetResourceIndex(vm::psv::ptr parameter) +u32 sceGxmProgramParameterGetResourceIndex(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmProgramParameterGetContainerIndex(vm::psv::ptr parameter) +u32 sceGxmProgramParameterGetContainerIndex(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -bool sceGxmProgramParameterIsSamplerCube(vm::psv::ptr parameter) +bool sceGxmProgramParameterIsSamplerCube(vm::cptr parameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmFragmentProgramGetProgram(vm::psv::ptr fragmentProgram) +vm::cptr sceGxmFragmentProgramGetProgram(vm::cptr fragmentProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmVertexProgramGetProgram(vm::psv::ptr vertexProgram) +vm::cptr sceGxmVertexProgramGetProgram(vm::cptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherCreate(vm::psv::ptr params, vm::psv::pptr shaderPatcher) +s32 sceGxmShaderPatcherCreate(vm::cptr params, vm::pptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherSetUserData(vm::psv::ptr shaderPatcher, vm::psv::ptr userData) +s32 sceGxmShaderPatcherSetUserData(vm::ptr shaderPatcher, vm::ptr userData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmShaderPatcherGetUserData(vm::psv::ptr shaderPatcher) +vm::ptr sceGxmShaderPatcherGetUserData(vm::ptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherDestroy(vm::psv::ptr shaderPatcher) +s32 sceGxmShaderPatcherDestroy(vm::ptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherRegisterProgram(vm::psv::ptr shaderPatcher, vm::psv::ptr programHeader, vm::psv::ptr programId) +s32 sceGxmShaderPatcherRegisterProgram(vm::ptr shaderPatcher, vm::cptr programHeader, vm::pptr programId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherUnregisterProgram(vm::psv::ptr shaderPatcher, SceGxmShaderPatcherId programId) +s32 sceGxmShaderPatcherUnregisterProgram(vm::ptr shaderPatcher, vm::ptr programId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmShaderPatcherGetProgramFromId(SceGxmShaderPatcherId programId) +vm::cptr sceGxmShaderPatcherGetProgramFromId(vm::ptr programId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherSetAuxiliarySurface(vm::psv::ptr shaderPatcher, u32 auxSurfaceIndex, vm::psv::ptr auxSurface) +s32 sceGxmShaderPatcherSetAuxiliarySurface(vm::ptr shaderPatcher, u32 auxSurfaceIndex, vm::cptr auxSurface) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherCreateVertexProgram(vm::psv::ptr shaderPatcher, SceGxmShaderPatcherId programId, vm::psv::ptr attributes, u32 attributeCount, vm::psv::ptr streams, u32 streamCount, vm::psv::pptr vertexProgram) +s32 sceGxmShaderPatcherCreateVertexProgram(vm::ptr shaderPatcher, vm::ptr programId, vm::cptr attributes, u32 attributeCount, vm::cptr streams, u32 streamCount, vm::pptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherCreateFragmentProgram(vm::psv::ptr shaderPatcher, SceGxmShaderPatcherId programId, SceGxmOutputRegisterFormat outputFormat, SceGxmMultisampleMode multisampleMode, vm::psv::ptr blendInfo, vm::psv::ptr vertexProgram, vm::psv::pptr fragmentProgram) +s32 sceGxmShaderPatcherCreateFragmentProgram(vm::ptr shaderPatcher, vm::ptr programId, SceGxmOutputRegisterFormat outputFormat, SceGxmMultisampleMode multisampleMode, vm::cptr blendInfo, vm::cptr vertexProgram, vm::pptr fragmentProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherAddRefVertexProgram(vm::psv::ptr shaderPatcher, vm::psv::ptr vertexProgram) +s32 sceGxmShaderPatcherAddRefVertexProgram(vm::ptr shaderPatcher, vm::ptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherAddRefFragmentProgram(vm::psv::ptr shaderPatcher, vm::psv::ptr fragmentProgram) +s32 sceGxmShaderPatcherAddRefFragmentProgram(vm::ptr shaderPatcher, vm::ptr fragmentProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherReleaseVertexProgram(vm::psv::ptr shaderPatcher, vm::psv::ptr vertexProgram) +s32 sceGxmShaderPatcherReleaseVertexProgram(vm::ptr shaderPatcher, vm::ptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmShaderPatcherReleaseFragmentProgram(vm::psv::ptr shaderPatcher, vm::psv::ptr fragmentProgram) +s32 sceGxmShaderPatcherReleaseFragmentProgram(vm::ptr shaderPatcher, vm::ptr fragmentProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmShaderPatcherGetHostMemAllocated(vm::psv::ptr shaderPatcher) +u32 sceGxmShaderPatcherGetHostMemAllocated(vm::cptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmShaderPatcherGetBufferMemAllocated(vm::psv::ptr shaderPatcher) +u32 sceGxmShaderPatcherGetBufferMemAllocated(vm::cptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmShaderPatcherGetVertexUsseMemAllocated(vm::psv::ptr shaderPatcher) +u32 sceGxmShaderPatcherGetVertexUsseMemAllocated(vm::cptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmShaderPatcherGetFragmentUsseMemAllocated(vm::psv::ptr shaderPatcher) +u32 sceGxmShaderPatcherGetFragmentUsseMemAllocated(vm::cptr shaderPatcher) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureInitSwizzled(vm::psv::ptr texture, vm::psv::ptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) +s32 sceGxmTextureInitSwizzled(vm::ptr texture, vm::cptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureInitLinear(vm::psv::ptr texture, vm::psv::ptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) +s32 sceGxmTextureInitLinear(vm::ptr texture, vm::cptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureInitLinearStrided(vm::psv::ptr texture, vm::psv::ptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 byteStride) +s32 sceGxmTextureInitLinearStrided(vm::ptr texture, vm::cptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 byteStride) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureInitTiled(vm::psv::ptr texture, vm::psv::ptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) +s32 sceGxmTextureInitTiled(vm::ptr texture, vm::cptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureInitCube(vm::psv::ptr texture, vm::psv::ptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) +s32 sceGxmTextureInitCube(vm::ptr texture, vm::cptr data, SceGxmTextureFormat texFormat, u32 width, u32 height, u32 mipCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureType sceGxmTextureGetType(vm::psv::ptr texture) +SceGxmTextureType sceGxmTextureGetType(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetMinFilter(vm::psv::ptr texture, SceGxmTextureFilter minFilter) +s32 sceGxmTextureSetMinFilter(vm::ptr texture, SceGxmTextureFilter minFilter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureFilter sceGxmTextureGetMinFilter(vm::psv::ptr texture) +SceGxmTextureFilter sceGxmTextureGetMinFilter(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetMagFilter(vm::psv::ptr texture, SceGxmTextureFilter magFilter) +s32 sceGxmTextureSetMagFilter(vm::ptr texture, SceGxmTextureFilter magFilter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureFilter sceGxmTextureGetMagFilter(vm::psv::ptr texture) +SceGxmTextureFilter sceGxmTextureGetMagFilter(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetMipFilter(vm::psv::ptr texture, SceGxmTextureMipFilter mipFilter) +s32 sceGxmTextureSetMipFilter(vm::ptr texture, SceGxmTextureMipFilter mipFilter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureMipFilter sceGxmTextureGetMipFilter(vm::psv::ptr texture) +SceGxmTextureMipFilter sceGxmTextureGetMipFilter(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetAnisoMode(vm::psv::ptr texture, SceGxmTextureAnisoMode anisoMode) +s32 sceGxmTextureSetAnisoMode(vm::ptr texture, SceGxmTextureAnisoMode anisoMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureAnisoMode sceGxmTextureGetAnisoMode(vm::psv::ptr texture) +SceGxmTextureAnisoMode sceGxmTextureGetAnisoMode(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetUAddrMode(vm::psv::ptr texture, SceGxmTextureAddrMode addrMode) +s32 sceGxmTextureSetUAddrMode(vm::ptr texture, SceGxmTextureAddrMode addrMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureAddrMode sceGxmTextureGetUAddrMode(vm::psv::ptr texture) +SceGxmTextureAddrMode sceGxmTextureGetUAddrMode(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetVAddrMode(vm::psv::ptr texture, SceGxmTextureAddrMode addrMode) +s32 sceGxmTextureSetVAddrMode(vm::ptr texture, SceGxmTextureAddrMode addrMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureAddrMode sceGxmTextureGetVAddrMode(vm::psv::ptr texture) +SceGxmTextureAddrMode sceGxmTextureGetVAddrMode(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetFormat(vm::psv::ptr texture, SceGxmTextureFormat texFormat) +s32 sceGxmTextureSetFormat(vm::ptr texture, SceGxmTextureFormat texFormat) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureFormat sceGxmTextureGetFormat(vm::psv::ptr texture) +SceGxmTextureFormat sceGxmTextureGetFormat(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetLodBias(vm::psv::ptr texture, u32 bias) +s32 sceGxmTextureSetLodBias(vm::ptr texture, u32 bias) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmTextureGetLodBias(vm::psv::ptr texture) +u32 sceGxmTextureGetLodBias(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetStride(vm::psv::ptr texture, u32 byteStride) +s32 sceGxmTextureSetStride(vm::ptr texture, u32 byteStride) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmTextureGetStride(vm::psv::ptr texture) +u32 sceGxmTextureGetStride(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetWidth(vm::psv::ptr texture, u32 width) +s32 sceGxmTextureSetWidth(vm::ptr texture, u32 width) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmTextureGetWidth(vm::psv::ptr texture) +u32 sceGxmTextureGetWidth(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetHeight(vm::psv::ptr texture, u32 height) +s32 sceGxmTextureSetHeight(vm::ptr texture, u32 height) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmTextureGetHeight(vm::psv::ptr texture) +u32 sceGxmTextureGetHeight(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetData(vm::psv::ptr texture, vm::psv::ptr data) +s32 sceGxmTextureSetData(vm::ptr texture, vm::cptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmTextureGetData(vm::psv::ptr texture) +vm::ptr sceGxmTextureGetData(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetMipmapCount(vm::psv::ptr texture, u32 mipCount) +s32 sceGxmTextureSetMipmapCount(vm::ptr texture, u32 mipCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmTextureGetMipmapCount(vm::psv::ptr texture) +u32 sceGxmTextureGetMipmapCount(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetPalette(vm::psv::ptr texture, vm::psv::ptr paletteData) +s32 sceGxmTextureSetPalette(vm::ptr texture, vm::cptr paletteData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmTextureGetPalette(vm::psv::ptr texture) +vm::ptr sceGxmTextureGetPalette(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -SceGxmTextureGammaMode sceGxmTextureGetGammaMode(vm::psv::ptr texture) +SceGxmTextureGammaMode sceGxmTextureGetGammaMode(vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmTextureSetGammaMode(vm::psv::ptr texture, SceGxmTextureGammaMode gammaMode) +s32 sceGxmTextureSetGammaMode(vm::ptr texture, SceGxmTextureGammaMode gammaMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmGetPrecomputedVertexStateSize(vm::psv::ptr vertexProgram) +u32 sceGxmGetPrecomputedVertexStateSize(vm::cptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedVertexStateInit(vm::psv::ptr precomputedState, vm::psv::ptr vertexProgram, vm::psv::ptr memBlock) +s32 sceGxmPrecomputedVertexStateInit(vm::ptr precomputedState, vm::cptr vertexProgram, vm::ptr memBlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmPrecomputedVertexStateSetDefaultUniformBuffer(vm::psv::ptr precomputedState, vm::psv::ptr defaultBuffer) +void sceGxmPrecomputedVertexStateSetDefaultUniformBuffer(vm::ptr precomputedState, vm::ptr defaultBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmPrecomputedVertexStateGetDefaultUniformBuffer(vm::psv::ptr precomputedState) +vm::ptr sceGxmPrecomputedVertexStateGetDefaultUniformBuffer(vm::cptr precomputedState) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedVertexStateSetAllTextures(vm::psv::ptr precomputedState, vm::psv::ptr textures) +s32 sceGxmPrecomputedVertexStateSetAllTextures(vm::ptr precomputedState, vm::cptr textures) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedVertexStateSetTexture(vm::psv::ptr precomputedState, u32 textureIndex, vm::psv::ptr texture) +s32 sceGxmPrecomputedVertexStateSetTexture(vm::ptr precomputedState, u32 textureIndex, vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedVertexStateSetAllUniformBuffers(vm::psv::ptr precomputedState, vm::psv::ptr> bufferDataArray) +s32 sceGxmPrecomputedVertexStateSetAllUniformBuffers(vm::ptr precomputedState, vm::cptr> bufferDataArray) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedVertexStateSetUniformBuffer(vm::psv::ptr precomputedState, u32 bufferIndex, vm::psv::ptr bufferData) +s32 sceGxmPrecomputedVertexStateSetUniformBuffer(vm::ptr precomputedState, u32 bufferIndex, vm::cptr bufferData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmGetPrecomputedFragmentStateSize(vm::psv::ptr fragmentProgram) +u32 sceGxmGetPrecomputedFragmentStateSize(vm::cptr fragmentProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedFragmentStateInit(vm::psv::ptr precomputedState, vm::psv::ptr fragmentProgram, vm::psv::ptr memBlock) +s32 sceGxmPrecomputedFragmentStateInit(vm::ptr precomputedState, vm::cptr fragmentProgram, vm::ptr memBlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmPrecomputedFragmentStateSetDefaultUniformBuffer(vm::psv::ptr precomputedState, vm::psv::ptr defaultBuffer) +void sceGxmPrecomputedFragmentStateSetDefaultUniformBuffer(vm::ptr precomputedState, vm::ptr defaultBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceGxmPrecomputedFragmentStateGetDefaultUniformBuffer(vm::psv::ptr precomputedState) +vm::ptr sceGxmPrecomputedFragmentStateGetDefaultUniformBuffer(vm::cptr precomputedState) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedFragmentStateSetAllTextures(vm::psv::ptr precomputedState, vm::psv::ptr textureArray) +s32 sceGxmPrecomputedFragmentStateSetAllTextures(vm::ptr precomputedState, vm::cptr textureArray) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedFragmentStateSetTexture(vm::psv::ptr precomputedState, u32 textureIndex, vm::psv::ptr texture) +s32 sceGxmPrecomputedFragmentStateSetTexture(vm::ptr precomputedState, u32 textureIndex, vm::cptr texture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedFragmentStateSetAllUniformBuffers(vm::psv::ptr precomputedState, vm::psv::ptr> bufferDataArray) +s32 sceGxmPrecomputedFragmentStateSetAllUniformBuffers(vm::ptr precomputedState, vm::cptr> bufferDataArray) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedFragmentStateSetUniformBuffer(vm::psv::ptr precomputedState, u32 bufferIndex, vm::psv::ptr bufferData) +s32 sceGxmPrecomputedFragmentStateSetUniformBuffer(vm::ptr precomputedState, u32 bufferIndex, vm::cptr bufferData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedFragmentStateSetAllAuxiliarySurfaces(vm::psv::ptr precomputedState, vm::psv::ptr auxSurfaceArray) +s32 sceGxmPrecomputedFragmentStateSetAllAuxiliarySurfaces(vm::ptr precomputedState, vm::cptr auxSurfaceArray) { - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceGxmGetPrecomputedDrawSize(vm::psv::ptr vertexProgram) +u32 sceGxmGetPrecomputedDrawSize(vm::cptr vertexProgram) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedDrawInit(vm::psv::ptr precomputedDraw, vm::psv::ptr vertexProgram, vm::psv::ptr memBlock) +s32 sceGxmPrecomputedDrawInit(vm::ptr precomputedDraw, vm::cptr vertexProgram, vm::ptr memBlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedDrawSetAllVertexStreams(vm::psv::ptr precomputedDraw, vm::psv::ptr> streamDataArray) +s32 sceGxmPrecomputedDrawSetAllVertexStreams(vm::ptr precomputedDraw, vm::cptr> streamDataArray) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmPrecomputedDrawSetVertexStream(vm::psv::ptr precomputedDraw, u32 streamIndex, vm::psv::ptr streamData) +s32 sceGxmPrecomputedDrawSetVertexStream(vm::ptr precomputedDraw, u32 streamIndex, vm::cptr streamData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmPrecomputedDrawSetParams(vm::psv::ptr precomputedDraw, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::psv::ptr indexData, u32 indexCount) +void sceGxmPrecomputedDrawSetParams(vm::ptr precomputedDraw, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::cptr indexData, u32 indexCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceGxmPrecomputedDrawSetParamsInstanced(vm::psv::ptr precomputedDraw, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::psv::ptr indexData, u32 indexCount, u32 indexWrap) +void sceGxmPrecomputedDrawSetParamsInstanced(vm::ptr precomputedDraw, SceGxmPrimitiveType primType, SceGxmIndexFormat indexType, vm::cptr indexData, u32 indexCount, u32 indexWrap) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmGetRenderTargetMemSizes(vm::psv::ptr params, vm::psv::ptr hostMemSize, vm::psv::ptr driverMemSize) +s32 sceGxmGetRenderTargetMemSizes(vm::cptr params, vm::ptr hostMemSize, vm::ptr driverMemSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmCreateRenderTarget(vm::psv::ptr params, vm::psv::pptr renderTarget) +s32 sceGxmCreateRenderTarget(vm::cptr params, vm::pptr renderTarget) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmRenderTargetGetHostMem(vm::psv::ptr renderTarget, vm::psv::pptr hostMem) +s32 sceGxmRenderTargetGetHostMem(vm::cptr renderTarget, vm::pptr hostMem) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmRenderTargetGetDriverMemBlock(vm::psv::ptr renderTarget, vm::psv::ptr driverMemBlock) +s32 sceGxmRenderTargetGetDriverMemBlock(vm::cptr renderTarget, vm::ptr driverMemBlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmDestroyRenderTarget(vm::psv::ptr renderTarget) +s32 sceGxmDestroyRenderTarget(vm::ptr renderTarget) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceGxmSetUniformDataF(vm::psv::ptr uniformBuffer, vm::psv::ptr parameter, u32 componentOffset, u32 componentCount, vm::psv::ptr sourceData) +s32 sceGxmSetUniformDataF(vm::ptr uniformBuffer, vm::cptr parameter, u32 componentOffset, u32 componentCount, vm::cptr sourceData) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -1074,6 +1074,7 @@ psv_log_base sceGxm("SceGxm", []() sceGxm.on_load = nullptr; sceGxm.on_unload = nullptr; sceGxm.on_stop = nullptr; + sceGxm.on_error = nullptr; REG_FUNC(0xB0F1E4EC, sceGxmInitialize); REG_FUNC(0xB627DE66, sceGxmTerminate); diff --git a/rpcs3/Emu/ARMv7/Modules/sceGxm.h b/rpcs3/Emu/ARMv7/Modules/sceGxm.h index 390c7ed1e7..c6a37730d8 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceGxm.h +++ b/rpcs3/Emu/ARMv7/Modules/sceGxm.h @@ -29,15 +29,15 @@ enum SCE_GXM_ERROR_DRIVER = 0x805B0017, }; -typedef void(SceGxmDisplayQueueCallback)(vm::psv::ptr callbackData); +using SceGxmDisplayQueueCallback = func_def callbackData)>; struct SceGxmInitializeParams { - u32 flags; - u32 displayQueueMaxPendingCount; - vm::psv::ptr displayQueueCallback; - u32 displayQueueCallbackDataSize; - s32 parameterBufferSize; + le_t flags; + le_t displayQueueMaxPendingCount; + vm::lptr displayQueueCallback; + le_t displayQueueCallbackDataSize; + le_t parameterBufferSize; }; enum SceGxmMemoryAttribFlags : u32 @@ -1002,13 +1002,13 @@ enum SceGxmColorMask : u8 struct SceGxmBlendInfo { - SceGxmColorMask colorMask; - SceGxmBlendFunc colorFunc : 4; - SceGxmBlendFunc alphaFunc : 4; - SceGxmBlendFactor colorSrc : 4; - SceGxmBlendFactor colorDst : 4; - SceGxmBlendFactor alphaSrc : 4; - SceGxmBlendFactor alphaDst : 4; + u8 colorMask; // SceGxmColorMask + u8 colorFunc : 4; // SceGxmBlendFunc + u8 alphaFunc : 4; // SceGxmBlendFunc + u8 colorSrc : 4; // SceGxmBlendFactor + u8 colorDst : 4; // SceGxmBlendFactor + u8 alphaSrc : 4; // SceGxmBlendFactor + u8 alphaDst : 4; // SceGxmBlendFactor }; struct SceGxmRenderTarget; @@ -1017,63 +1017,63 @@ struct SceGxmSyncObject; struct SceGxmVertexAttribute { - u16 streamIndex; - u16 offset; - SceGxmAttributeFormat format; + le_t streamIndex; + le_t offset; + u8 format; // SceGxmAttributeFormat u8 componentCount; - u16 regIndex; + le_t regIndex; }; struct SceGxmVertexStream { - u16 stride; - u16 indexSource; + le_t stride; + le_t indexSource; }; struct SceGxmTexture { - u32 controlWords[4]; + le_t controlWords[4]; }; struct SceGxmColorSurface { - u32 pbeSidebandWord; - u32 pbeEmitWords[6]; - u32 outputRegisterSize; + le_t pbeSidebandWord; + le_t pbeEmitWords[6]; + le_t outputRegisterSize; SceGxmTexture backgroundTex; }; struct SceGxmDepthStencilSurface { - u32 zlsControl; - vm::psv::ptr depthData; - vm::psv::ptr stencilData; - float backgroundDepth; - u32 backgroundControl; + le_t zlsControl; + vm::lptr depthData; + vm::lptr stencilData; + le_t backgroundDepth; + le_t backgroundControl; }; struct SceGxmAuxiliarySurface { - SceGxmColorFormat colorFormat; - SceGxmColorSurfaceType type; - u32 width; - u32 height; - u32 stride; - vm::psv::ptr data; + le_t colorFormat; // SceGxmColorFormat + le_t type; // SceGxmColorSurfaceType + le_t width; + le_t height; + le_t stride; + vm::lptr data; }; struct SceGxmNotification { - vm::psv::ptr address; - u32 value; + vm::lptr address; + le_t value; }; struct SceGxmValidRegion { - u32 xMin; - u32 yMin; - u32 xMax; - u32 yMax; + le_t xMin; + le_t yMin; + le_t xMax; + le_t yMax; }; struct SceGxmContext; @@ -1089,17 +1089,17 @@ enum struct SceGxmContextParams { - vm::psv::ptr hostMem; - u32 hostMemSize; - vm::psv::ptr vdmRingBufferMem; - u32 vdmRingBufferMemSize; - vm::psv::ptr vertexRingBufferMem; - u32 vertexRingBufferMemSize; - vm::psv::ptr fragmentRingBufferMem; - u32 fragmentRingBufferMemSize; - vm::psv::ptr fragmentUsseRingBufferMem; - u32 fragmentUsseRingBufferMemSize; - u32 fragmentUsseRingBufferOffset; + vm::lptr hostMem; + le_t hostMemSize; + vm::lptr vdmRingBufferMem; + le_t vdmRingBufferMemSize; + vm::lptr vertexRingBufferMem; + le_t vertexRingBufferMemSize; + vm::lptr fragmentRingBufferMem; + le_t fragmentRingBufferMemSize; + vm::lptr fragmentUsseRingBufferMem; + le_t fragmentUsseRingBufferMemSize; + le_t fragmentUsseRingBufferOffset; }; struct SceGxmVertexProgram; @@ -1115,17 +1115,17 @@ enum struct SceGxmPrecomputedVertexState { - u32 data[SCE_GXM_PRECOMPUTED_VERTEX_STATE_WORD_COUNT]; + le_t data[SCE_GXM_PRECOMPUTED_VERTEX_STATE_WORD_COUNT]; }; struct SceGxmPrecomputedFragmentState { - u32 data[SCE_GXM_PRECOMPUTED_FRAGMENT_STATE_WORD_COUNT]; + le_t data[SCE_GXM_PRECOMPUTED_FRAGMENT_STATE_WORD_COUNT]; }; struct SceGxmPrecomputedDraw { - u32 data[SCE_GXM_PRECOMPUTED_DRAW_WORD_COUNT]; + le_t data[SCE_GXM_PRECOMPUTED_DRAW_WORD_COUNT]; }; enum : u32 @@ -1193,34 +1193,32 @@ struct SceGxmShaderPatcher; struct SceGxmRegisteredProgram; -typedef vm::psv::ptr SceGxmShaderPatcherId; - -typedef vm::psv::ptr(SceGxmShaderPatcherHostAllocCallback)(vm::psv::ptr userData, u32 size); -typedef void(SceGxmShaderPatcherHostFreeCallback)(vm::psv::ptr userData, vm::psv::ptr mem); -typedef vm::psv::ptr(SceGxmShaderPatcherBufferAllocCallback)(vm::psv::ptr userData, u32 size); -typedef void(SceGxmShaderPatcherBufferFreeCallback)(vm::psv::ptr userData, vm::psv::ptr mem); -typedef vm::psv::ptr(SceGxmShaderPatcherUsseAllocCallback)(vm::psv::ptr userData, u32 size, vm::psv::ptr usseOffset); -typedef void(SceGxmShaderPatcherUsseFreeCallback)(vm::psv::ptr userData, vm::psv::ptr mem); +using SceGxmShaderPatcherHostAllocCallback = func_def(vm::ptr userData, u32 size)>; +using SceGxmShaderPatcherHostFreeCallback = func_def userData, vm::ptr mem)>; +using SceGxmShaderPatcherBufferAllocCallback = func_def(vm::ptr userData, u32 size)>; +using SceGxmShaderPatcherBufferFreeCallback = func_def userData, vm::ptr mem)>; +using SceGxmShaderPatcherUsseAllocCallback = func_def(vm::ptr userData, u32 size, vm::ptr usseOffset)>; +using SceGxmShaderPatcherUsseFreeCallback = func_def userData, vm::ptr mem)>; struct SceGxmShaderPatcherParams { - vm::psv::ptr userData; - vm::psv::ptr hostAllocCallback; - vm::psv::ptr hostFreeCallback; - vm::psv::ptr bufferAllocCallback; - vm::psv::ptr bufferFreeCallback; - vm::psv::ptr bufferMem; - u32 bufferMemSize; - vm::psv::ptr vertexUsseAllocCallback; - vm::psv::ptr vertexUsseFreeCallback; - vm::psv::ptr vertexUsseMem; - u32 vertexUsseMemSize; - u32 vertexUsseOffset; - vm::psv::ptr fragmentUsseAllocCallback; - vm::psv::ptr fragmentUsseFreeCallback; - vm::psv::ptr fragmentUsseMem; - u32 fragmentUsseMemSize; - u32 fragmentUsseOffset; + vm::lptr userData; + vm::lptr hostAllocCallback; + vm::lptr hostFreeCallback; + vm::lptr bufferAllocCallback; + vm::lptr bufferFreeCallback; + vm::lptr bufferMem; + le_t bufferMemSize; + vm::lptr vertexUsseAllocCallback; + vm::lptr vertexUsseFreeCallback; + vm::lptr vertexUsseMem; + le_t vertexUsseMemSize; + le_t vertexUsseOffset; + vm::lptr fragmentUsseAllocCallback; + vm::lptr fragmentUsseFreeCallback; + vm::lptr fragmentUsseMem; + le_t fragmentUsseMemSize; + le_t fragmentUsseOffset; }; enum SceGxmRenderTargetFlags : u32 @@ -1230,15 +1228,15 @@ enum SceGxmRenderTargetFlags : u32 struct SceGxmRenderTargetParams { - SceGxmRenderTargetFlags flags; - u16 width; - u16 height; - u16 scenesPerFrame; - SceGxmMultisampleMode multisampleMode; - u32 multisampleLocations; - vm::psv::ptr hostMem; - u32 hostMemSize; - s32 driverMemBlock; + le_t flags; // SceGxmRenderTargetFlags + le_t width; + le_t height; + le_t scenesPerFrame; + le_t multisampleMode; // SceGxmMultisampleMode + le_t multisampleLocations; + vm::lptr hostMem; + le_t hostMemSize; + le_t driverMemBlock; }; extern psv_log_base sceGxm; diff --git a/rpcs3/Emu/ARMv7/Modules/sceHttp.cpp b/rpcs3/Emu/ARMv7/Modules/sceHttp.cpp index c261e0335d..6d7417ffea 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceHttp.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceHttp.cpp @@ -2,354 +2,281 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceSsl.h" - -extern psv_log_base sceHttp; - -enum SceHttpHttpVersion : s32 -{ - SCE_HTTP_VERSION_1_0 = 1, - SCE_HTTP_VERSION_1_1 -}; - -enum SceHttpProxyMode : s32 -{ - SCE_HTTP_PROXY_AUTO, - SCE_HTTP_PROXY_MANUAL -}; - -enum SceHttpAddHeaderMode : s32 -{ - SCE_HTTP_HEADER_OVERWRITE, - SCE_HTTP_HEADER_ADD -}; - -enum SceHttpAuthType : s32 -{ - SCE_HTTP_AUTH_BASIC, - SCE_HTTP_AUTH_DIGEST, - SCE_HTTP_AUTH_RESERVED0, - SCE_HTTP_AUTH_RESERVED1, - SCE_HTTP_AUTH_RESERVED2 -}; - -typedef vm::psv::ptr realm, vm::psv::ptr username, vm::psv::ptr password, s32 needEntity, vm::psv::pptr entityBody, vm::psv::ptr entitySize, vm::psv::ptr save, vm::psv::ptr userArg)> SceHttpAuthInfoCallback; - -typedef vm::psv::ptr method, vm::psv::ptr location, vm::psv::ptr userArg)> SceHttpRedirectCallback; - -struct SceHttpMemoryPoolStats -{ - u32 poolSize; - u32 maxInuseSize; - u32 currentInuseSize; - s32 reserved; -}; - -struct SceHttpUriElement -{ - s32 opaque; - vm::psv::ptr scheme; - vm::psv::ptr username; - vm::psv::ptr password; - vm::psv::ptr hostname; - vm::psv::ptr path; - vm::psv::ptr query; - vm::psv::ptr fragment; - u16 port; - u8 reserved[10]; -}; - -typedef vm::psv::ptr url, vm::psv::ptr cookieHeader, u32 headerLen, vm::psv::ptr userArg)> SceHttpCookieRecvCallback; - -typedef vm::psv::ptr url, vm::psv::ptr cookieHeader, vm::psv::ptr userArg)> SceHttpCookieSendCallback; - -struct SceHttpsData -{ - vm::psv::ptr ptr; - u32 size; -}; - -struct SceHttpsCaList -{ - vm::psv::lpptr caCerts; - s32 caNum; -}; - -typedef vm::psv::ptr> sslCert, s32 certNum, vm::psv::ptr userArg)> SceHttpsCallback; +#include "sceHttp.h" s32 sceHttpInit(u32 poolSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetMemoryPoolStats(vm::psv::ptr currentStat) +s32 sceHttpGetMemoryPoolStats(vm::ptr currentStat) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpCreateTemplate(vm::psv::ptr userAgent, s32 httpVer, s32 autoProxyConf) +s32 sceHttpCreateTemplate(vm::cptr userAgent, s32 httpVer, s32 autoProxyConf) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpDeleteTemplate(s32 tmplId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpCreateConnection(s32 tmplId, vm::psv::ptr serverName, vm::psv::ptr scheme, u16 port, s32 enableKeepalive) +s32 sceHttpCreateConnection(s32 tmplId, vm::cptr serverName, vm::cptr scheme, u16 port, s32 enableKeepalive) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpCreateConnectionWithURL(s32 tmplId, vm::psv::ptr url, s32 enableKeepalive) +s32 sceHttpCreateConnectionWithURL(s32 tmplId, vm::cptr url, s32 enableKeepalive) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpDeleteConnection(s32 connId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpCreateRequest(s32 connId, s32 method, vm::psv::ptr path, u64 contentLength) +s32 sceHttpCreateRequest(s32 connId, s32 method, vm::cptr path, u64 contentLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpCreateRequestWithURL(s32 connId, s32 method, vm::psv::ptr url, u64 contentLength) +s32 sceHttpCreateRequestWithURL(s32 connId, s32 method, vm::cptr url, u64 contentLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpDeleteRequest(s32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetResponseHeaderMaxSize(s32 id, u32 headerSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetRecvBlockSize(s32 id, u32 blockSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetRequestContentLength(s32 id, u64 contentLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpSendRequest(s32 reqId, vm::psv::ptr postData, u32 size) +s32 sceHttpSendRequest(s32 reqId, vm::cptr postData, u32 size) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpAbortRequest(s32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetResponseContentLength(s32 reqId, vm::psv::ptr contentLength) +s32 sceHttpGetResponseContentLength(s32 reqId, vm::ptr contentLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetStatusCode(s32 reqId, vm::psv::ptr statusCode) +s32 sceHttpGetStatusCode(s32 reqId, vm::ptr statusCode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetAllResponseHeaders(s32 reqId, vm::psv::pptr header, vm::psv::ptr headerSize) +s32 sceHttpGetAllResponseHeaders(s32 reqId, vm::pptr header, vm::ptr headerSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpReadData(s32 reqId, vm::psv::ptr data, u32 size) +s32 sceHttpReadData(s32 reqId, vm::ptr data, u32 size) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpAddRequestHeader(s32 id, vm::psv::ptr name, vm::psv::ptr value, u32 mode) +s32 sceHttpAddRequestHeader(s32 id, vm::cptr name, vm::cptr value, u32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpRemoveRequestHeader(s32 id, vm::psv::ptr name) +s32 sceHttpRemoveRequestHeader(s32 id, vm::cptr name) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpParseResponseHeader(vm::psv::ptr header, u32 headerLen, vm::psv::ptr fieldStr, vm::psv::pptr fieldValue, vm::psv::ptr valueLen) +s32 sceHttpParseResponseHeader(vm::cptr header, u32 headerLen, vm::cptr fieldStr, vm::cpptr fieldValue, vm::ptr valueLen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpParseStatusLine(vm::psv::ptr statusLine, u32 lineLen, vm::psv::ptr httpMajorVer, vm::psv::ptr httpMinorVer, vm::psv::ptr responseCode, vm::psv::pptr reasonPhrase, vm::psv::ptr phraseLen) +s32 sceHttpParseStatusLine(vm::cptr statusLine, u32 lineLen, vm::ptr httpMajorVer, vm::ptr httpMinorVer, vm::ptr responseCode, vm::cpptr reasonPhrase, vm::ptr phraseLen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpSetAuthInfoCallback(s32 id, SceHttpAuthInfoCallback cbfunc, vm::psv::ptr userArg) +s32 sceHttpSetAuthInfoCallback(s32 id, vm::ptr cbfunc, vm::ptr userArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetAuthEnabled(s32 id, s32 enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetAuthEnabled(s32 id, vm::psv::ptr enable) +s32 sceHttpGetAuthEnabled(s32 id, vm::ptr enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpSetRedirectCallback(s32 id, SceHttpRedirectCallback cbfunc, vm::psv::ptr userArg) +s32 sceHttpSetRedirectCallback(s32 id, vm::ptr cbfunc, vm::ptr userArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetAutoRedirect(s32 id, s32 enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetAutoRedirect(s32 id, vm::psv::ptr enable) +s32 sceHttpGetAutoRedirect(s32 id, vm::ptr enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetResolveTimeOut(s32 id, u32 usec) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetResolveRetry(s32 id, s32 retry) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetConnectTimeOut(s32 id, u32 usec) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetSendTimeOut(s32 id, u32 usec) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetRecvTimeOut(s32 id, u32 usec) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpUriEscape(vm::psv::ptr out, vm::psv::ptr require, u32 prepare, vm::psv::ptr in) +s32 sceHttpUriEscape(vm::ptr out, vm::ptr require, u32 prepare, vm::cptr in) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpUriUnescape(vm::psv::ptr out, vm::psv::ptr require, u32 prepare, vm::psv::ptr in) +s32 sceHttpUriUnescape(vm::ptr out, vm::ptr require, u32 prepare, vm::cptr in) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpUriParse(vm::psv::ptr out, vm::psv::ptr srcUrl, vm::psv::ptr pool, vm::psv::ptr require, u32 prepare) +s32 sceHttpUriParse(vm::ptr out, vm::cptr srcUrl, vm::ptr pool, vm::ptr require, u32 prepare) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpUriBuild(vm::psv::ptr out, vm::psv::ptr require, u32 prepare, vm::psv::ptr srcElement, u32 option) +s32 sceHttpUriBuild(vm::ptr out, vm::ptr require, u32 prepare, vm::cptr srcElement, u32 option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpUriMerge(vm::psv::ptr mergedUrl, vm::psv::ptr url, vm::psv::ptr relativeUrl, vm::psv::ptr require, u32 prepare, u32 option) +s32 sceHttpUriMerge(vm::ptr mergedUrl, vm::cptr url, vm::cptr relativeUrl, vm::ptr require, u32 prepare, u32 option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpUriSweepPath(vm::psv::ptr dst, vm::psv::ptr src, u32 srcSize) +s32 sceHttpUriSweepPath(vm::ptr dst, vm::cptr src, u32 srcSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpSetCookieEnabled(s32 id, s32 enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetCookieEnabled(s32 id, vm::psv::ptr enable) +s32 sceHttpGetCookieEnabled(s32 id, vm::ptr enable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpGetCookie(vm::psv::ptr url, vm::psv::ptr cookie, vm::psv::ptr cookieLength, u32 prepare, s32 secure) +s32 sceHttpGetCookie(vm::cptr url, vm::ptr cookie, vm::ptr cookieLength, u32 prepare, s32 secure) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpAddCookie(vm::psv::ptr url, vm::psv::ptr cookie, u32 cookieLength) +s32 sceHttpAddCookie(vm::cptr url, vm::cptr cookie, u32 cookieLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpSetCookieRecvCallback(s32 id, SceHttpCookieRecvCallback cbfunc, vm::psv::ptr userArg) +s32 sceHttpSetCookieRecvCallback(s32 id, vm::ptr cbfunc, vm::ptr userArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpSetCookieSendCallback(s32 id, SceHttpCookieSendCallback cbfunc, vm::psv::ptr userArg) +s32 sceHttpSetCookieSendCallback(s32 id, vm::ptr cbfunc, vm::ptr userArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpsLoadCert(s32 caCertNum, vm::psv::pptr caList, vm::psv::ptr cert, vm::psv::ptr privKey) +s32 sceHttpsLoadCert(s32 caCertNum, vm::cpptr caList, vm::cptr cert, vm::cptr privKey) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpsUnloadCert() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpsEnableOption(u32 sslFlags) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceHttpsDisableOption(u32 sslFlags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpsGetSslError(s32 id, vm::psv::ptr errNum, vm::psv::ptr detail) +s32 sceHttpsGetSslError(s32 id, vm::ptr errNum, vm::ptr detail) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpsSetSslCallback(s32 id, SceHttpsCallback cbfunc, vm::psv::ptr userArg) +s32 sceHttpsSetSslCallback(s32 id, vm::ptr cbfunc, vm::ptr userArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpsGetCaList(vm::psv::ptr caList) +s32 sceHttpsGetCaList(vm::ptr caList) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceHttpsFreeCaList(vm::psv::ptr caList) +s32 sceHttpsFreeCaList(vm::ptr caList) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -360,6 +287,7 @@ psv_log_base sceHttp("SceHttp", []() sceHttp.on_load = nullptr; sceHttp.on_unload = nullptr; sceHttp.on_stop = nullptr; + sceHttp.on_error = nullptr; REG_FUNC(0x214926D9, sceHttpInit); REG_FUNC(0xC9076666, sceHttpTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceHttp.h b/rpcs3/Emu/ARMv7/Modules/sceHttp.h new file mode 100644 index 0000000000..6b957307ef --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceHttp.h @@ -0,0 +1,74 @@ +#pragma once + +#include "sceSsl.h" + +enum SceHttpHttpVersion : s32 +{ + SCE_HTTP_VERSION_1_0 = 1, + SCE_HTTP_VERSION_1_1 +}; + +enum SceHttpProxyMode : s32 +{ + SCE_HTTP_PROXY_AUTO, + SCE_HTTP_PROXY_MANUAL +}; + +enum SceHttpAddHeaderMode : s32 +{ + SCE_HTTP_HEADER_OVERWRITE, + SCE_HTTP_HEADER_ADD +}; + +enum SceHttpAuthType : s32 +{ + SCE_HTTP_AUTH_BASIC, + SCE_HTTP_AUTH_DIGEST, + SCE_HTTP_AUTH_RESERVED0, + SCE_HTTP_AUTH_RESERVED1, + SCE_HTTP_AUTH_RESERVED2 +}; + +using SceHttpAuthInfoCallback = func_def realm, vm::ptr username, vm::ptr password, s32 needEntity, vm::pptr entityBody, vm::ptr entitySize, vm::ptr save, vm::ptr userArg)>; +using SceHttpRedirectCallback = func_def method, vm::cptr location, vm::ptr userArg)>; + +struct SceHttpMemoryPoolStats +{ + le_t poolSize; + le_t maxInuseSize; + le_t currentInuseSize; + le_t reserved; +}; + +struct SceHttpUriElement +{ + le_t opaque; + vm::lptr scheme; + vm::lptr username; + vm::lptr password; + vm::lptr hostname; + vm::lptr path; + vm::lptr query; + vm::lptr fragment; + le_t port; + u8 reserved[10]; +}; + +using SceHttpCookieRecvCallback = func_def url, vm::cptr cookieHeader, u32 headerLen, vm::ptr userArg)>; +using SceHttpCookieSendCallback = func_def url, vm::cptr cookieHeader, vm::ptr userArg)>; + +struct SceHttpsData +{ + vm::lptr ptr; + le_t size; +}; + +struct SceHttpsCaList +{ + vm::lpptr caCerts; + le_t caNum; +}; + +using SceHttpsCallback = func_def> sslCert, s32 certNum, vm::ptr userArg)>; + +extern psv_log_base sceHttp; diff --git a/rpcs3/Emu/ARMv7/Modules/sceIme.cpp b/rpcs3/Emu/ARMv7/Modules/sceIme.cpp index 797e282ace..c903c58309 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceIme.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceIme.cpp @@ -4,29 +4,29 @@ #include "sceIme.h" -s32 sceImeOpen(vm::psv::ptr param) +s32 sceImeOpen(vm::ptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceImeUpdate() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceImeSetCaret(vm::psv::ptr caret) +s32 sceImeSetCaret(vm::cptr caret) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceImeSetPreeditGeometry(vm::psv::ptr preedit) +s32 sceImeSetPreeditGeometry(vm::cptr preedit) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceImeClose() { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -37,6 +37,7 @@ psv_log_base sceIme("SceIme", []() sceIme.on_load = nullptr; sceIme.on_unload = nullptr; sceIme.on_stop = nullptr; + sceIme.on_error = nullptr; REG_FUNC(0x0E050613, sceImeOpen); REG_FUNC(0x71D6898A, sceImeUpdate); diff --git a/rpcs3/Emu/ARMv7/Modules/sceIme.h b/rpcs3/Emu/ARMv7/Modules/sceIme.h index 7e7fffb429..4e1fda1849 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceIme.h +++ b/rpcs3/Emu/ARMv7/Modules/sceIme.h @@ -1,70 +1,70 @@ #pragma once -typedef s32(SceImeCharFilter)(u16 ch); +using SceImeCharFilter = func_def; struct SceImeRect { - u32 x; - u32 y; - u32 width; - u32 height; + le_t x; + le_t y; + le_t width; + le_t height; }; struct SceImeEditText { - u32 preeditIndex; - u32 preeditLength; - u32 caretIndex; - vm::psv::ptr str; + le_t preeditIndex; + le_t preeditLength; + le_t caretIndex; + vm::lptr str; }; union SceImeEventParam { SceImeRect rect; SceImeEditText text; - u32 caretIndex; + le_t caretIndex; }; struct SceImeEvent { - u32 id; + le_t id; SceImeEventParam param; }; struct SceImeCaret { - u32 x; - u32 y; - u32 height; - u32 index; + le_t x; + le_t y; + le_t height; + le_t index; }; struct SceImePreeditGeometry { - u32 x; - u32 y; - u32 height; + le_t x; + le_t y; + le_t height; }; -typedef void(SceImeEventHandler)(vm::psv::ptr arg, vm::psv::ptr e); +using SceImeEventHandler = func_def arg, vm::cptr e)>; struct SceImeParam { - u32 size; - u32 inputMethod; - u64 supportedLanguages; - s32 languagesForced; - u32 type; - u32 option; - vm::psv::ptr work; - vm::psv::ptr arg; - vm::psv::ptr handler; - vm::psv::ptr filter; - vm::psv::ptr initialText; - u32 maxTextLength; - vm::psv::ptr inputTextBuffer; - u32 reserved0; - u32 reserved1; + le_t size; + le_t inputMethod; + le_t supportedLanguages; + le_t languagesForced; + le_t type; + le_t option; + vm::lptr work; + vm::lptr arg; + vm::lptr handler; + vm::lptr filter; + vm::lptr initialText; + le_t maxTextLength; + vm::lptr inputTextBuffer; + le_t reserved0; + le_t reserved1; }; extern psv_log_base sceIme; diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp b/rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp index 06e8e0ec00..c09b1a15ad 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceJpeg.cpp @@ -2,107 +2,78 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceJpeg; - -struct SceJpegOutputInfo -{ - s32 colorSpace; - u16 imageWidth; - u16 imageHeight; - u32 outputBufferSize; - u32 tempBufferSize; - u32 coefBufferSize; - - struct { u32 x, y; } pitch[4]; -}; - -struct SceJpegSplitDecodeCtrl -{ - vm::psv::ptr pStreamBuffer; - u32 streamBufferSize; - vm::psv::ptr pWriteBuffer; - u32 writeBufferSize; - s32 isEndOfStream; - s32 decodeMode; - - SceJpegOutputInfo outputInfo; - - vm::psv::ptr pOutputBuffer; - vm::psv::ptr pCoefBuffer; - - u32 internalData[3]; -}; +#include "sceJpeg.h" s32 sceJpegInitMJpeg(s32 maxSplitDecoder) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegFinishMJpeg() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegDecodeMJpeg( - vm::psv::ptr pJpeg, + vm::cptr pJpeg, u32 isize, - vm::psv::ptr pRGBA, + vm::ptr pRGBA, u32 osize, s32 decodeMode, - vm::psv::ptr pTempBuffer, + vm::ptr pTempBuffer, u32 tempBufferSize, - vm::psv::ptr pCoefBuffer, + vm::ptr pCoefBuffer, u32 coefBufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegDecodeMJpegYCbCr( - vm::psv::ptr pJpeg, + vm::cptr pJpeg, u32 isize, - vm::psv::ptr pYCbCr, + vm::ptr pYCbCr, u32 osize, s32 decodeMode, - vm::psv::ptr pCoefBuffer, + vm::ptr pCoefBuffer, u32 coefBufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegMJpegCsc( - vm::psv::ptr pRGBA, - vm::psv::ptr pYCbCr, + vm::ptr pRGBA, + vm::cptr pYCbCr, s32 xysize, s32 iFrameWidth, s32 colorOption, s32 sampling) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegGetOutputInfo( - vm::psv::ptr pJpeg, + vm::cptr pJpeg, u32 isize, s32 outputFormat, s32 decodeMode, - vm::psv::ptr pOutputInfo) + vm::ptr pOutputInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceJpegCreateSplitDecoder(vm::psv::ptr pCtrl) +s32 sceJpegCreateSplitDecoder(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceJpegDeleteSplitDecoder(vm::psv::ptr pCtrl) +s32 sceJpegDeleteSplitDecoder(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceJpegSplitDecodeMJpeg(vm::psv::ptr pCtrl) +s32 sceJpegSplitDecodeMJpeg(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -113,6 +84,7 @@ psv_log_base sceJpeg("SceJpeg", []() sceJpeg.on_load = nullptr; sceJpeg.on_unload = nullptr; sceJpeg.on_stop = nullptr; + sceJpeg.on_error = nullptr; REG_FUNC(0xB030773B, sceJpegInitMJpeg); REG_FUNC(0x62842598, sceJpegFinishMJpeg); diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpeg.h b/rpcs3/Emu/ARMv7/Modules/sceJpeg.h new file mode 100644 index 0000000000..9b24acff5b --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceJpeg.h @@ -0,0 +1,38 @@ +#pragma once + +struct SceJpegOutputInfo +{ + le_t colorSpace; + le_t imageWidth; + le_t imageHeight; + le_t outputBufferSize; + le_t tempBufferSize; + le_t coefBufferSize; + + struct _pitch_t + { + le_t x; + le_t y; + }; + + _pitch_t pitch[4]; +}; + +struct SceJpegSplitDecodeCtrl +{ + vm::lptr pStreamBuffer; + le_t streamBufferSize; + vm::lptr pWriteBuffer; + le_t writeBufferSize; + le_t isEndOfStream; + le_t decodeMode; + + SceJpegOutputInfo outputInfo; + + vm::lptr pOutputBuffer; + vm::lptr pCoefBuffer; + + le_t internalData[3]; +}; + +extern psv_log_base sceJpeg; diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp b/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp index 690afd9e04..ef6bd1bccc 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.cpp @@ -2,13 +2,11 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceJpegEnc; - -typedef vm::psv::ptr SceJpegEncoderContext; +#include "sceJpegEnc.h" s32 sceJpegEncoderGetContextSize() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderInit( @@ -16,22 +14,22 @@ s32 sceJpegEncoderInit( s32 iFrameWidth, s32 iFrameHeight, s32 pixelFormat, - vm::psv::ptr pJpeg, + vm::ptr pJpeg, u32 oJpegbufSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderEncode( SceJpegEncoderContext context, - vm::psv::ptr pYCbCr) + vm::cptr pYCbCr) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderEnd(SceJpegEncoderContext context) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderSetValidRegion( @@ -39,39 +37,39 @@ s32 sceJpegEncoderSetValidRegion( s32 iFrameWidth, s32 iFrameHeight) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderSetCompressionRatio( SceJpegEncoderContext context, s32 compratio) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderSetHeaderMode( SceJpegEncoderContext context, s32 headerMode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderSetOutputAddr( SceJpegEncoderContext context, - vm::psv::ptr pJpeg, + vm::ptr pJpeg, u32 oJpegbufSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceJpegEncoderCsc( SceJpegEncoderContext context, - vm::psv::ptr pYCbCr, - vm::psv::ptr pRGBA, + vm::ptr pYCbCr, + vm::cptr pRGBA, s32 iFrameWidth, s32 inputPixelFormat) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -82,6 +80,7 @@ psv_log_base sceJpegEnc("SceJpegEnc", []() sceJpegEnc.on_load = nullptr; sceJpegEnc.on_unload = nullptr; sceJpegEnc.on_stop = nullptr; + sceJpegEnc.on_error = nullptr; REG_FUNC(0x2B55844D, sceJpegEncoderGetContextSize); REG_FUNC(0x88DA92B4, sceJpegEncoderInit); diff --git a/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.h b/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.h new file mode 100644 index 0000000000..4a046f6f52 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceJpegEnc.h @@ -0,0 +1,5 @@ +#pragma once + +using SceJpegEncoderContext = vm::ptr; + +extern psv_log_base sceJpegEnc; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp index 0d1c9baf29..c5a22f6624 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp @@ -1,9 +1,9 @@ #include "stdafx.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/ARMv7/PSVFuncList.h" #include "Emu/ARMv7/PSVObjectList.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/SysCalls/Callback.h" #include "Emu/ARMv7/ARMv7Thread.h" @@ -13,82 +13,75 @@ #include "psv_mutex.h" #include "psv_cond.h" -#define RETURN_ERROR(code) { Emu.Pause(); sceLibKernel.Error("%s() failed: %s", __FUNCTION__, #code); return code; } - -s32 sceKernelAllocMemBlock(vm::psv::ptr name, s32 type, u32 vsize, vm::psv::ptr pOpt) +s32 sceKernelAllocMemBlock(vm::cptr name, s32 type, u32 vsize, vm::ptr pOpt) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelFreeMemBlock(s32 uid) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetMemBlockBase(s32 uid, vm::psv::pptr ppBase) +s32 sceKernelGetMemBlockBase(s32 uid, vm::pptr ppBase) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetMemBlockInfoByAddr(vm::psv::ptr vbase, vm::psv::ptr pInfo) +s32 sceKernelGetMemBlockInfoByAddr(vm::ptr vbase, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCreateThread( - vm::psv::ptr pName, - vm::psv::ptr entry, + vm::cptr pName, + vm::ptr entry, s32 initPriority, u32 stackSize, u32 attr, s32 cpuAffinityMask, - vm::psv::ptr pOptParam) + vm::cptr pOptParam) { sceLibKernel.Warning("sceKernelCreateThread(pName=*0x%x, entry=*0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=*0x%x)", pName, entry, initPriority, stackSize, attr, cpuAffinityMask, pOptParam); - auto t = Emu.GetCPU().AddThread(CPU_THREAD_ARMv7); + auto armv7 = Emu.GetIdManager().make_ptr(pName.get_ptr()); - auto& armv7 = static_cast(*t); + armv7->PC = entry.addr(); + armv7->prio = initPriority; + armv7->stack_size = stackSize; + armv7->Run(); - armv7.SetEntry(entry.addr()); - armv7.SetPrio(initPriority); - armv7.SetStackSize(stackSize); - armv7.SetName(pName.get_ptr()); - armv7.Run(); - - return armv7.GetId(); + return armv7->GetId(); } -s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr pArgBlock) +s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::cptr pArgBlock) { sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock); - const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto thread = Emu.GetIdManager().get(threadId); - if (!t) + if (!thread) { - RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + return SCE_KERNEL_ERROR_INVALID_UID; } // thread should be in DORMANT state, but it's not possible to check it correctly atm - if (t->IsAlive()) - { - RETURN_ERROR(SCE_KERNEL_ERROR_NOT_DORMANT); - } - - ARMv7Thread& thread = static_cast(*t); + //if (thread->IsAlive()) + //{ + // return SCE_KERNEL_ERROR_NOT_DORMANT; + //} // push arg block onto the stack - const u32 pos = (thread.context.SP -= argSize); + const u32 pos = (thread->SP -= argSize); memcpy(vm::get_ptr(pos), pArgBlock.get_ptr(), argSize); // set SceKernelThreadEntry function arguments - thread.context.GPR[0] = argSize; - thread.context.GPR[1] = pos; + thread->GPR[0] = argSize; + thread->GPR[1] = pos; - thread.Exec(); + thread->Exec(); return SCE_OK; } @@ -97,7 +90,7 @@ s32 sceKernelExitThread(ARMv7Context& context, s32 exitStatus) sceLibKernel.Warning("sceKernelExitThread(exitStatus=0x%x)", exitStatus); // exit status is stored in r0 - context.thread.Stop(); + static_cast(context).Exit(); return SCE_OK; } @@ -106,21 +99,21 @@ s32 sceKernelDeleteThread(s32 threadId) { sceLibKernel.Warning("sceKernelDeleteThread(threadId=0x%x)", threadId); - const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto thread = Emu.GetIdManager().get(threadId); - if (!t) + if (!thread) { - RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + return SCE_KERNEL_ERROR_INVALID_UID; } // thread should be in DORMANT state, but it's not possible to check it correctly atm - if (t->IsAlive()) - { - RETURN_ERROR(SCE_KERNEL_ERROR_NOT_DORMANT); - } + //if (thread->IsAlive()) + //{ + // return SCE_KERNEL_ERROR_NOT_DORMANT; + //} - Emu.GetCPU().RemoveThread(threadId); + Emu.GetIdManager().remove(threadId); return SCE_OK; } @@ -129,13 +122,14 @@ s32 sceKernelExitDeleteThread(ARMv7Context& context, s32 exitStatus) sceLibKernel.Warning("sceKernelExitDeleteThread(exitStatus=0x%x)", exitStatus); // exit status is stored in r0 - context.thread.Stop(); + static_cast(context).Stop(); // current thread should be deleted - const u32 id = context.thread.GetId(); + const u32 id = static_cast(context).GetId(); + CallAfter([id]() { - Emu.GetCPU().RemoveThread(id); + Emu.GetIdManager().remove(id); }); return SCE_OK; @@ -145,255 +139,250 @@ s32 sceKernelChangeThreadCpuAffinityMask(s32 threadId, s32 cpuAffinityMask) { sceLibKernel.Todo("sceKernelChangeThreadCpuAffinityMask(threadId=0x%x, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelGetThreadCpuAffinityMask(s32 threadId) { sceLibKernel.Todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelChangeThreadPriority(s32 threadId, s32 priority) { sceLibKernel.Todo("sceKernelChangeThreadPriority(threadId=0x%x, priority=%d)", threadId, priority); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelGetThreadCurrentPriority() { sceLibKernel.Todo("sceKernelGetThreadCurrentPriority()"); - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceKernelGetThreadId(ARMv7Context& context) { sceLibKernel.Log("sceKernelGetThreadId()"); - return context.thread.GetId(); + return static_cast(context).GetId(); } s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr) { sceLibKernel.Todo("sceKernelChangeCurrentThreadAttr()"); - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetThreadExitStatus(s32 threadId, vm::psv::ptr pExitStatus) +s32 sceKernelGetThreadExitStatus(s32 threadId, vm::ptr pExitStatus) { sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=*0x%x)", threadId, pExitStatus); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelGetProcessId() { sceLibKernel.Todo("sceKernelGetProcessId()"); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCheckWaitableStatus() { sceLibKernel.Todo("sceKernelCheckWaitableStatus()"); - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetThreadInfo(s32 threadId, vm::psv::ptr pInfo) +s32 sceKernelGetThreadInfo(s32 threadId, vm::ptr pInfo) { sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=*0x%x)", threadId, pInfo); - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetThreadRunStatus(vm::psv::ptr pStatus) +s32 sceKernelGetThreadRunStatus(vm::ptr pStatus) { sceLibKernel.Todo("sceKernelGetThreadRunStatus(pStatus=*0x%x)", pStatus); - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetSystemInfo(vm::psv::ptr pInfo) +s32 sceKernelGetSystemInfo(vm::ptr pInfo) { sceLibKernel.Todo("sceKernelGetSystemInfo(pInfo=*0x%x)", pInfo); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelGetThreadmgrUIDClass(s32 uid) { sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelChangeThreadVfpException(s32 clearMask, s32 setMask) { sceLibKernel.Todo("sceKernelChangeThreadVfpException(clearMask=0x%x, setMask=0x%x)", clearMask, setMask); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelGetCurrentThreadVfpException() { sceLibKernel.Todo("sceKernelGetCurrentThreadVfpException()"); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDelayThread(u32 usec) { sceLibKernel.Todo("sceKernelDelayThread()"); - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDelayThreadCB(u32 usec) { sceLibKernel.Todo("sceKernelDelayThreadCB()"); - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr pExitStatus, vm::psv::ptr pTimeout) +s32 sceKernelWaitThreadEnd(s32 threadId, vm::ptr pExitStatus, vm::ptr pTimeout) { sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout); - const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto thread = Emu.GetIdManager().get(threadId); - if (!t) + if (!thread) { - RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + return SCE_KERNEL_ERROR_INVALID_UID; } - ARMv7Thread& thread = static_cast(*t); - if (pTimeout) { } - while (thread.IsAlive()) + while (thread->IsActive()) { - if (Emu.IsStopped()) - { - sceLibKernel.Warning("sceKernelWaitThreadEnd(0x%x) aborted", threadId); - return SCE_OK; - } + CHECK_EMU_STATUS; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } if (pExitStatus) { - *pExitStatus = thread.context.GPR[0]; + *pExitStatus = thread->GPR[0]; } return SCE_OK; } -s32 sceKernelWaitThreadEndCB(s32 threadId, vm::psv::ptr pExitStatus, vm::psv::ptr pTimeout) +s32 sceKernelWaitThreadEndCB(s32 threadId, vm::ptr pExitStatus, vm::ptr pTimeout) { sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout); - throw __FUNCTION__; + throw EXCEPTION(""); } // Callback functions -s32 sceKernelCreateCallback(vm::psv::ptr pName, u32 attr, vm::psv::ptr callbackFunc, vm::psv::ptr pCommon) +s32 sceKernelCreateCallback(vm::cptr pName, u32 attr, vm::ptr callbackFunc, vm::ptr pCommon) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDeleteCallback(s32 callbackId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelNotifyCallback(s32 callbackId, s32 notifyArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCancelCallback(s32 callbackId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelGetCallbackCount(s32 callbackId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCheckCallback() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetCallbackInfo(s32 callbackId, vm::psv::ptr pInfo) +s32 sceKernelGetCallbackInfo(s32 callbackId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelRegisterCallbackToEvent(s32 eventId, s32 callbackId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelUnregisterCallbackFromEvent(s32 eventId, s32 callbackId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelUnregisterCallbackFromEventAll(s32 eventId) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Event functions -s32 sceKernelWaitEvent(s32 eventId, u32 waitPattern, vm::psv::ptr pResultPattern, vm::psv::ptr pUserData, vm::psv::ptr pTimeout) +s32 sceKernelWaitEvent(s32 eventId, u32 waitPattern, vm::ptr pResultPattern, vm::ptr pUserData, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitEventCB(s32 eventId, u32 waitPattern, vm::psv::ptr pResultPattern, vm::psv::ptr pUserData, vm::psv::ptr pTimeout) +s32 sceKernelWaitEventCB(s32 eventId, u32 waitPattern, vm::ptr pResultPattern, vm::ptr pUserData, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelPollEvent(s32 eventId, u32 bitPattern, vm::psv::ptr pResultPattern, vm::psv::ptr pUserData) +s32 sceKernelPollEvent(s32 eventId, u32 bitPattern, vm::ptr pResultPattern, vm::ptr pUserData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelCancelEvent(s32 eventId, vm::psv::ptr pNumWaitThreads) +s32 sceKernelCancelEvent(s32 eventId, vm::ptr pNumWaitThreads) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetEventInfo(s32 eventId, vm::psv::ptr pInfo) +s32 sceKernelGetEventInfo(s32 eventId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitMultipleEvents(vm::psv::ptr pWaitEventList, s32 numEvents, u32 waitMode, vm::psv::ptr pResultEventList, vm::psv::ptr pTimeout) +s32 sceKernelWaitMultipleEvents(vm::ptr pWaitEventList, s32 numEvents, u32 waitMode, vm::ptr pResultEventList, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitMultipleEventsCB(vm::psv::ptr pWaitEventList, s32 numEvents, u32 waitMode, vm::psv::ptr pResultEventList, vm::psv::ptr pTimeout) +s32 sceKernelWaitMultipleEventsCB(vm::ptr pWaitEventList, s32 numEvents, u32 waitMode, vm::ptr pResultEventList, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Event flag functions -s32 sceKernelCreateEventFlag(vm::psv::ptr pName, u32 attr, u32 initPattern, vm::psv::ptr pOptParam) +s32 sceKernelCreateEventFlag(vm::cptr pName, u32 attr, u32 initPattern, vm::cptr pOptParam) { sceLibKernel.Error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam); @@ -402,62 +391,62 @@ s32 sceKernelCreateEventFlag(vm::psv::ptr pName, u32 attr, u32 initP return id; } - RETURN_ERROR(SCE_KERNEL_ERROR_ERROR); + return SCE_KERNEL_ERROR_ERROR; } s32 sceKernelDeleteEventFlag(s32 evfId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelOpenEventFlag(vm::psv::ptr pName) +s32 sceKernelOpenEventFlag(vm::cptr pName) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCloseEventFlag(s32 evfId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::psv::ptr pResultPat, vm::psv::ptr pTimeout) +s32 sceKernelWaitEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitEventFlagCB(s32 evfId, u32 bitPattern, u32 waitMode, vm::psv::ptr pResultPat, vm::psv::ptr pTimeout) +s32 sceKernelWaitEventFlagCB(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::psv::ptr pResultPat) +s32 sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr pResultPat) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelSetEventFlag(s32 evfId, u32 bitPattern) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelClearEventFlag(s32 evfId, u32 bitPattern) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::psv::ptr pNumWaitThreads) +s32 sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::ptr pNumWaitThreads) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetEventFlagInfo(s32 evfId, vm::psv::ptr pInfo) +s32 sceKernelGetEventFlagInfo(s32 evfId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Semaphore functions -s32 sceKernelCreateSema(vm::psv::ptr pName, u32 attr, s32 initCount, s32 maxCount, vm::psv::ptr pOptParam) +s32 sceKernelCreateSema(vm::cptr pName, u32 attr, s32 initCount, s32 maxCount, vm::cptr pOptParam) { sceLibKernel.Error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam); @@ -466,7 +455,7 @@ s32 sceKernelCreateSema(vm::psv::ptr pName, u32 attr, s32 initCount, return id; } - RETURN_ERROR(SCE_KERNEL_ERROR_ERROR); + return SCE_KERNEL_ERROR_ERROR; } s32 sceKernelDeleteSema(s32 semaId) @@ -477,28 +466,28 @@ s32 sceKernelDeleteSema(s32 semaId) if (!sema) { - RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + return SCE_KERNEL_ERROR_INVALID_UID; } if (!g_psv_sema_list.remove(semaId)) { - RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + return SCE_KERNEL_ERROR_INVALID_UID; } return SCE_OK; } -s32 sceKernelOpenSema(vm::psv::ptr pName) +s32 sceKernelOpenSema(vm::cptr pName) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCloseSema(s32 semaId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::psv::ptr pTimeout) +s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::ptr pTimeout) { sceLibKernel.Error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout); @@ -506,7 +495,7 @@ s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::psv::ptr pTimeout) if (!sema) { - RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID); + return SCE_KERNEL_ERROR_INVALID_UID; } sceLibKernel.Error("*** name = %s", sema->name); @@ -514,34 +503,34 @@ s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::psv::ptr pTimeout) return SCE_OK; } -s32 sceKernelWaitSemaCB(s32 semaId, s32 needCount, vm::psv::ptr pTimeout) +s32 sceKernelWaitSemaCB(s32 semaId, s32 needCount, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelPollSema(s32 semaId, s32 needCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelSignalSema(s32 semaId, s32 signalCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelCancelSema(s32 semaId, s32 setCount, vm::psv::ptr pNumWaitThreads) +s32 sceKernelCancelSema(s32 semaId, s32 setCount, vm::ptr pNumWaitThreads) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetSemaInfo(s32 semaId, vm::psv::ptr pInfo) +s32 sceKernelGetSemaInfo(s32 semaId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Mutex functions -s32 sceKernelCreateMutex(vm::psv::ptr pName, u32 attr, s32 initCount, vm::psv::ptr pOptParam) +s32 sceKernelCreateMutex(vm::cptr pName, u32 attr, s32 initCount, vm::cptr pOptParam) { sceLibKernel.Error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam); @@ -550,99 +539,99 @@ s32 sceKernelCreateMutex(vm::psv::ptr pName, u32 attr, s32 initCount return id; } - RETURN_ERROR(SCE_KERNEL_ERROR_ERROR); + return SCE_KERNEL_ERROR_ERROR; } s32 sceKernelDeleteMutex(s32 mutexId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelOpenMutex(vm::psv::ptr pName) +s32 sceKernelOpenMutex(vm::cptr pName) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCloseMutex(s32 mutexId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockMutex(s32 mutexId, s32 lockCount, vm::psv::ptr pTimeout) +s32 sceKernelLockMutex(s32 mutexId, s32 lockCount, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockMutexCB(s32 mutexId, s32 lockCount, vm::psv::ptr pTimeout) +s32 sceKernelLockMutexCB(s32 mutexId, s32 lockCount, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelTryLockMutex(s32 mutexId, s32 lockCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelUnlockMutex(s32 mutexId, s32 unlockCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelCancelMutex(s32 mutexId, s32 newCount, vm::psv::ptr pNumWaitThreads) +s32 sceKernelCancelMutex(s32 mutexId, s32 newCount, vm::ptr pNumWaitThreads) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetMutexInfo(s32 mutexId, vm::psv::ptr pInfo) +s32 sceKernelGetMutexInfo(s32 mutexId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Lightweight mutex functions -s32 sceKernelCreateLwMutex(vm::psv::ptr pWork, vm::psv::ptr pName, u32 attr, s32 initCount, vm::psv::ptr pOptParam) +s32 sceKernelCreateLwMutex(vm::ptr pWork, vm::cptr pName, u32 attr, s32 initCount, vm::cptr pOptParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelDeleteLwMutex(vm::psv::ptr pWork) +s32 sceKernelDeleteLwMutex(vm::ptr pWork) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockLwMutex(vm::psv::ptr pWork, s32 lockCount, vm::psv::ptr pTimeout) +s32 sceKernelLockLwMutex(vm::ptr pWork, s32 lockCount, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockLwMutexCB(vm::psv::ptr pWork, s32 lockCount, vm::psv::ptr pTimeout) +s32 sceKernelLockLwMutexCB(vm::ptr pWork, s32 lockCount, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelTryLockLwMutex(vm::psv::ptr pWork, s32 lockCount) +s32 sceKernelTryLockLwMutex(vm::ptr pWork, s32 lockCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelUnlockLwMutex(vm::psv::ptr pWork, s32 unlockCount) +s32 sceKernelUnlockLwMutex(vm::ptr pWork, s32 unlockCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetLwMutexInfo(vm::psv::ptr pWork, vm::psv::ptr pInfo) +s32 sceKernelGetLwMutexInfo(vm::ptr pWork, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetLwMutexInfoById(s32 lwMutexId, vm::psv::ptr pInfo) +s32 sceKernelGetLwMutexInfoById(s32 lwMutexId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Condition variable functions -s32 sceKernelCreateCond(vm::psv::ptr pName, u32 attr, s32 mutexId, vm::psv::ptr pOptParam) +s32 sceKernelCreateCond(vm::cptr pName, u32 attr, s32 mutexId, vm::cptr pOptParam) { sceLibKernel.Error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam); @@ -651,367 +640,367 @@ s32 sceKernelCreateCond(vm::psv::ptr pName, u32 attr, s32 mutexId, v return id; } - RETURN_ERROR(SCE_KERNEL_ERROR_ERROR); + return SCE_KERNEL_ERROR_ERROR; } s32 sceKernelDeleteCond(s32 condId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelOpenCond(vm::psv::ptr pName) +s32 sceKernelOpenCond(vm::cptr pName) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCloseCond(s32 condId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitCond(s32 condId, vm::psv::ptr pTimeout) +s32 sceKernelWaitCond(s32 condId, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitCondCB(s32 condId, vm::psv::ptr pTimeout) +s32 sceKernelWaitCondCB(s32 condId, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelSignalCond(s32 condId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelSignalCondAll(s32 condId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelSignalCondTo(s32 condId, s32 threadId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetCondInfo(s32 condId, vm::psv::ptr pInfo) +s32 sceKernelGetCondInfo(s32 condId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Lightweight condition variable functions -s32 sceKernelCreateLwCond(vm::psv::ptr pWork, vm::psv::ptr pName, u32 attr, vm::psv::ptr pLwMutex, vm::psv::ptr pOptParam) +s32 sceKernelCreateLwCond(vm::ptr pWork, vm::cptr pName, u32 attr, vm::ptr pLwMutex, vm::cptr pOptParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelDeleteLwCond(vm::psv::ptr pWork) +s32 sceKernelDeleteLwCond(vm::ptr pWork) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitLwCond(vm::psv::ptr pWork, vm::psv::ptr pTimeout) +s32 sceKernelWaitLwCond(vm::ptr pWork, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelWaitLwCondCB(vm::psv::ptr pWork, vm::psv::ptr pTimeout) +s32 sceKernelWaitLwCondCB(vm::ptr pWork, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelSignalLwCond(vm::psv::ptr pWork) +s32 sceKernelSignalLwCond(vm::ptr pWork) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelSignalLwCondAll(vm::psv::ptr pWork) +s32 sceKernelSignalLwCondAll(vm::ptr pWork) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelSignalLwCondTo(vm::psv::ptr pWork, s32 threadId) +s32 sceKernelSignalLwCondTo(vm::ptr pWork, s32 threadId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetLwCondInfo(vm::psv::ptr pWork, vm::psv::ptr pInfo) +s32 sceKernelGetLwCondInfo(vm::ptr pWork, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetLwCondInfoById(s32 lwCondId, vm::psv::ptr pInfo) +s32 sceKernelGetLwCondInfoById(s32 lwCondId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Time functions -s32 sceKernelGetSystemTime(vm::psv::ptr pClock) +s32 sceKernelGetSystemTime(vm::ptr pClock) { - throw __FUNCTION__; + throw EXCEPTION(""); } u64 sceKernelGetSystemTimeWide() { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceKernelGetSystemTimeLow() { - throw __FUNCTION__; + throw EXCEPTION(""); } // Timer functions -s32 sceKernelCreateTimer(vm::psv::ptr pName, u32 attr, vm::psv::ptr pOptParam) +s32 sceKernelCreateTimer(vm::cptr pName, u32 attr, vm::cptr pOptParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDeleteTimer(s32 timerId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelOpenTimer(vm::psv::ptr pName) +s32 sceKernelOpenTimer(vm::cptr pName) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCloseTimer(s32 timerId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelStartTimer(s32 timerId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelStopTimer(s32 timerId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetTimerBase(s32 timerId, vm::psv::ptr pBase) +s32 sceKernelGetTimerBase(s32 timerId, vm::ptr pBase) { - throw __FUNCTION__; + throw EXCEPTION(""); } u64 sceKernelGetTimerBaseWide(s32 timerId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetTimerTime(s32 timerId, vm::psv::ptr pClock) +s32 sceKernelGetTimerTime(s32 timerId, vm::ptr pClock) { - throw __FUNCTION__; + throw EXCEPTION(""); } u64 sceKernelGetTimerTimeWide(s32 timerId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelSetTimerTime(s32 timerId, vm::psv::ptr pClock) +s32 sceKernelSetTimerTime(s32 timerId, vm::ptr pClock) { - throw __FUNCTION__; + throw EXCEPTION(""); } u64 sceKernelSetTimerTimeWide(s32 timerId, u64 clock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelSetTimerEvent(s32 timerId, s32 type, vm::psv::ptr pInterval, s32 fRepeat) +s32 sceKernelSetTimerEvent(s32 timerId, s32 type, vm::ptr pInterval, s32 fRepeat) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelCancelTimer(s32 timerId, vm::psv::ptr pNumWaitThreads) +s32 sceKernelCancelTimer(s32 timerId, vm::ptr pNumWaitThreads) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetTimerInfo(s32 timerId, vm::psv::ptr pInfo) +s32 sceKernelGetTimerInfo(s32 timerId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // Reader/writer lock functions -s32 sceKernelCreateRWLock(vm::psv::ptr pName, u32 attr, vm::psv::ptr pOptParam) +s32 sceKernelCreateRWLock(vm::cptr pName, u32 attr, vm::cptr pOptParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelDeleteRWLock(s32 rwLockId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelOpenRWLock(vm::psv::ptr pName) +s32 sceKernelOpenRWLock(vm::cptr pName) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelCloseRWLock(s32 rwLockId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockReadRWLock(s32 rwLockId, vm::psv::ptr pTimeout) +s32 sceKernelLockReadRWLock(s32 rwLockId, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockReadRWLockCB(s32 rwLockId, vm::psv::ptr pTimeout) +s32 sceKernelLockReadRWLockCB(s32 rwLockId, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelTryLockReadRWLock(s32 rwLockId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelUnlockReadRWLock(s32 rwLockId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockWriteRWLock(s32 rwLockId, vm::psv::ptr pTimeout) +s32 sceKernelLockWriteRWLock(s32 rwLockId, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelLockWriteRWLockCB(s32 rwLockId, vm::psv::ptr pTimeout) +s32 sceKernelLockWriteRWLockCB(s32 rwLockId, vm::ptr pTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelTryLockWriteRWLock(s32 rwLockId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceKernelUnlockWriteRWLock(s32 rwLockId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelCancelRWLock(s32 rwLockId, vm::psv::ptr pNumReadWaitThreads, vm::psv::ptr pNumWriteWaitThreads, s32 flag) +s32 sceKernelCancelRWLock(s32 rwLockId, vm::ptr pNumReadWaitThreads, vm::ptr pNumWriteWaitThreads, s32 flag) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceKernelGetRWLockInfo(s32 rwLockId, vm::psv::ptr pInfo) +s32 sceKernelGetRWLockInfo(s32 rwLockId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } // IO/File functions -s32 sceIoRemove(vm::psv::ptr filename) +s32 sceIoRemove(vm::cptr filename) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoMkdir(vm::psv::ptr dirname, s32 mode) +s32 sceIoMkdir(vm::cptr dirname, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoRmdir(vm::psv::ptr dirname) +s32 sceIoRmdir(vm::cptr dirname) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoRename(vm::psv::ptr oldname, vm::psv::ptr newname) +s32 sceIoRename(vm::cptr oldname, vm::cptr newname) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoDevctl(vm::psv::ptr devname, s32 cmd, vm::psv::ptr arg, u32 arglen, vm::psv::ptr bufp, u32 buflen) +s32 sceIoDevctl(vm::cptr devname, s32 cmd, vm::cptr arg, u32 arglen, vm::ptr bufp, u32 buflen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoSync(vm::psv::ptr devname, s32 flag) +s32 sceIoSync(vm::cptr devname, s32 flag) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoOpen(vm::psv::ptr filename, s32 flag, s32 mode) +s32 sceIoOpen(vm::cptr filename, s32 flag, s32 mode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceIoClose(s32 fd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoIoctl(s32 fd, s32 cmd, vm::psv::ptr argp, u32 arglen, vm::psv::ptr bufp, u32 buflen) +s32 sceIoIoctl(s32 fd, s32 cmd, vm::cptr argp, u32 arglen, vm::ptr bufp, u32 buflen) { - throw __FUNCTION__; + throw EXCEPTION(""); } s64 sceIoLseek(s32 fd, s64 offset, s32 whence) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceIoLseek32(s32 fd, s32 offset, s32 whence) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoRead(s32 fd, vm::psv::ptr buf, u32 nbyte) +s32 sceIoRead(s32 fd, vm::ptr buf, u32 nbyte) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoWrite(s32 fd, vm::psv::ptr buf, u32 nbyte) +s32 sceIoWrite(s32 fd, vm::cptr buf, u32 nbyte) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoPread(s32 fd, vm::psv::ptr buf, u32 nbyte, s64 offset) +s32 sceIoPread(s32 fd, vm::ptr buf, u32 nbyte, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoPwrite(s32 fd, vm::psv::ptr buf, u32 nbyte, s64 offset) +s32 sceIoPwrite(s32 fd, vm::cptr buf, u32 nbyte, s64 offset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoDopen(vm::psv::ptr dirname) +s32 sceIoDopen(vm::cptr dirname) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceIoDclose(s32 fd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoDread(s32 fd, vm::psv::ptr buf) +s32 sceIoDread(s32 fd, vm::ptr buf) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoChstat(vm::psv::ptr name, vm::psv::ptr buf, u32 cbit) +s32 sceIoChstat(vm::cptr name, vm::cptr buf, u32 cbit) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceIoGetstat(vm::psv::ptr name, vm::psv::ptr buf) +s32 sceIoGetstat(vm::cptr name, vm::ptr buf) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -1022,6 +1011,7 @@ psv_log_base sceLibKernel("sceLibKernel", []() sceLibKernel.on_load = nullptr; sceLibKernel.on_unload = nullptr; sceLibKernel.on_stop = nullptr; + //sceLibKernel.on_error = nullptr; // keep default error handler // REG_FUNC(???, sceKernelGetEventInfo); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h index df2bbd3d3d..3fd02fa5e5 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.h @@ -269,339 +269,338 @@ union SceKernelSysClock { struct { - u32 low; - u32 hi; - }; + le_t low; + le_t hi; + } + u; - u64 quad; + le_t quad; }; struct SceKernelCallFrame { - u32 sp; - u32 pc; + le_t sp; + le_t pc; }; // Memory Manager definitions -typedef s32 SceKernelMemoryType; - struct SceKernelMemBlockInfo { - u32 size; - vm::psv::ptr mappedBase; - u32 mappedSize; - SceKernelMemoryType memoryType; - u32 access; + le_t size; + vm::lptr mappedBase; + le_t mappedSize; + le_t memoryType; // SceKernelMemoryType + le_t access; }; struct SceKernelAllocMemBlockOpt { - u32 size; - u32 attr; - u32 alignment; - s32 uidBaseBlock; - vm::psv::ptr strBaseBlockName; + le_t size; + le_t attr; + le_t alignment; + le_t uidBaseBlock; + vm::lcptr strBaseBlockName; }; // Thread Manager definitions (threads) -typedef s32(SceKernelThreadEntry)(u32 argSize, vm::psv::ptr pArgBlock); +using SceKernelThreadEntry = func_def pArgBlock)>; struct SceKernelThreadOptParam { - u32 size; - u32 attr; + le_t size; + le_t attr; }; struct SceKernelThreadInfo { - u32 size; - s32 processId; + le_t size; + le_t processId; char name[32]; - u32 attr; - u32 status; - vm::psv::ptr entry; - vm::psv::ptr pStack; - u32 stackSize; - s32 initPriority; - s32 currentPriority; - s32 initCpuAffinityMask; - s32 currentCpuAffinityMask; - s32 currentCpuId; - s32 lastExecutedCpuId; - u32 waitType; - s32 waitId; - s32 exitStatus; + le_t attr; + le_t status; + vm::lptr entry; + vm::lptr pStack; + le_t stackSize; + le_t initPriority; + le_t currentPriority; + le_t initCpuAffinityMask; + le_t currentCpuAffinityMask; + le_t currentCpuId; + le_t lastExecutedCpuId; + le_t waitType; + le_t waitId; + le_t exitStatus; SceKernelSysClock runClocks; - u32 intrPreemptCount; - u32 threadPreemptCount; - u32 threadReleaseCount; - s32 changeCpuCount; - s32 fNotifyCallback; - s32 reserved; + le_t intrPreemptCount; + le_t threadPreemptCount; + le_t threadReleaseCount; + le_t changeCpuCount; + le_t fNotifyCallback; + le_t reserved; }; struct SceKernelThreadRunStatus { - u32 size; + le_t size; struct { - s32 processId; - s32 threadId; - s32 priority; + le_t processId; + le_t threadId; + le_t priority; } cpuInfo[4]; }; struct SceKernelSystemInfo { - u32 size; - u32 activeCpuMask; + le_t size; + le_t activeCpuMask; struct { SceKernelSysClock idleClock; - u32 comesOutOfIdleCount; - u32 threadSwitchCount; + le_t comesOutOfIdleCount; + le_t threadSwitchCount; } cpuInfo[4]; }; // Thread Manager definitions (callbacks) -typedef s32(SceKernelCallbackFunction)(s32 notifyId, s32 notifyCount, s32 notifyArg, vm::psv::ptr pCommon); +using SceKernelCallbackFunction = func_def pCommon)>; struct SceKernelCallbackInfo { - u32 size; - s32 callbackId; + le_t size; + le_t callbackId; char name[32]; - u32 attr; - s32 threadId; - vm::psv::ptr callbackFunc; - s32 notifyId; - s32 notifyCount; - s32 notifyArg; - vm::psv::ptr pCommon; + le_t attr; + le_t threadId; + vm::lptr callbackFunc; + le_t notifyId; + le_t notifyCount; + le_t notifyArg; + vm::lptr pCommon; }; // Thread Manager definitions (events) -typedef s32(SceKernelThreadEventHandler)(s32 type, s32 threadId, s32 arg, vm::psv::ptr pCommon); +using SceKernelThreadEventHandler = func_def pCommon)>; struct SceKernelEventInfo { - u32 size; - s32 eventId; + le_t size; + le_t eventId; char name[32]; - u32 attr; - u32 eventPattern; - u64 userData; - u32 numWaitThreads; - s32 reserved[1]; + le_t attr; + le_t eventPattern; + le_t userData; + le_t numWaitThreads; + le_t reserved[1]; }; struct SceKernelWaitEvent { - s32 eventId; - u32 eventPattern; + le_t eventId; + le_t eventPattern; }; struct SceKernelResultEvent { - s32 eventId; - s32 result; - u32 resultPattern; - s32 reserved[1]; - u64 userData; + le_t eventId; + le_t result; + le_t resultPattern; + le_t reserved[1]; + le_t userData; }; // Thread Manager definitions (event flags) struct SceKernelEventFlagOptParam { - u32 size; + le_t size; }; struct SceKernelEventFlagInfo { - u32 size; - s32 evfId; + le_t size; + le_t evfId; char name[32]; - u32 attr; - u32 initPattern; - u32 currentPattern; - s32 numWaitThreads; + le_t attr; + le_t initPattern; + le_t currentPattern; + le_t numWaitThreads; }; // Thread Manager definitions (semaphores) struct SceKernelSemaOptParam { - u32 size; + le_t size; }; struct SceKernelSemaInfo { - u32 size; - s32 semaId; + le_t size; + le_t semaId; char name[32]; - u32 attr; - s32 initCount; - s32 currentCount; - s32 maxCount; - s32 numWaitThreads; + le_t attr; + le_t initCount; + le_t currentCount; + le_t maxCount; + le_t numWaitThreads; }; // Thread Manager definitions (mutexes) struct SceKernelMutexOptParam { - u32 size; - s32 ceilingPriority; + le_t size; + le_t ceilingPriority; }; struct SceKernelMutexInfo { - u32 size; - s32 mutexId; + le_t size; + le_t mutexId; char name[32]; - u32 attr; - s32 initCount; - s32 currentCount; - s32 currentOwnerId; - s32 numWaitThreads; + le_t attr; + le_t initCount; + le_t currentCount; + le_t currentOwnerId; + le_t numWaitThreads; }; // Thread Manager definitions (lightweight mutexes) struct SceKernelLwMutexWork { - s32 data[4]; + le_t data[4]; }; struct SceKernelLwMutexOptParam { - u32 size; + le_t size; }; struct SceKernelLwMutexInfo { - u32 size; - s32 uid; + le_t size; + le_t uid; char name[32]; - u32 attr; - vm::psv::ptr pWork; - s32 initCount; - s32 currentCount; - s32 currentOwnerId; - s32 numWaitThreads; + le_t attr; + vm::lptr pWork; + le_t initCount; + le_t currentCount; + le_t currentOwnerId; + le_t numWaitThreads; }; // Thread Manager definitions (condition variables) struct SceKernelCondOptParam { - u32 size; + le_t size; }; struct SceKernelCondInfo { - u32 size; - s32 condId; + le_t size; + le_t condId; char name[32]; - u32 attr; - s32 mutexId; - u32 numWaitThreads; + le_t attr; + le_t mutexId; + le_t numWaitThreads; }; // Thread Manager definitions (lightweight condition variables) struct SceKernelLwCondWork { - s32 data[4]; + le_t data[4]; }; struct SceKernelLwCondOptParam { - u32 size; + le_t size; }; struct SceKernelLwCondInfo { - u32 size; - s32 uid; + le_t size; + le_t uid; char name[32]; - u32 attr; - vm::psv::ptr pWork; - vm::psv::ptr pLwMutex; - u32 numWaitThreads; + le_t attr; + vm::lptr pWork; + vm::lptr pLwMutex; + le_t numWaitThreads; }; // Thread Manager definitions (timers) struct SceKernelTimerOptParam { - u32 size; + le_t size; }; struct SceKernelTimerInfo { - u32 size; - s32 timerId; + le_t size; + le_t timerId; char name[32]; - u32 attr; - s32 fActive; + le_t attr; + le_t fActive; SceKernelSysClock baseTime; SceKernelSysClock currentTime; SceKernelSysClock schedule; SceKernelSysClock interval; - s32 type; - s32 fRepeat; - s32 numWaitThreads; - s32 reserved[1]; + le_t type; + le_t fRepeat; + le_t numWaitThreads; + le_t reserved[1]; }; // Thread Manager definitions (reader/writer locks) struct SceKernelRWLockOptParam { - u32 size; + le_t size; }; struct SceKernelRWLockInfo { - u32 size; - s32 rwLockId; + le_t size; + le_t rwLockId; char name[32]; - u32 attr; - s32 lockCount; - s32 writeOwnerId; - s32 numReadWaitThreads; - s32 numWriteWaitThreads; + le_t attr; + le_t lockCount; + le_t writeOwnerId; + le_t numReadWaitThreads; + le_t numWriteWaitThreads; }; // IO/File Manager definitions struct SceIoStat { - s32 mode; - u32 attr; - s64 size; + le_t mode; + le_t attr; + le_t size; SceDateTime ctime; SceDateTime atime; SceDateTime mtime; - u64 _private[6]; + le_t _private[6]; }; struct SceIoDirent { SceIoStat d_stat; char d_name[256]; - vm::psv::ptr d_private; - s32 dummy; + vm::lptr d_private; + le_t dummy; }; // Module diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index d93e74af5f..5bc3ddfabf 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -5,17 +5,15 @@ #include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/ARMv7/ARMv7Callback.h" -extern psv_log_base sceLibc; +#include "sceLibc.h" -vm::psv::ptr g_dso; - -typedef void(atexit_func_t)(vm::psv::ptr); +vm::ptr g_dso; std::vector> g_atexit; std::mutex g_atexit_mutex; -std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g_count, u32 f_count, u32 v_count) +std::string armv7_fmt(ARMv7Context& context, vm::cptr fmt, u32 g_count, u32 f_count, u32 v_count) { std::string result; @@ -130,7 +128,7 @@ std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g case 's': { // string - auto string = vm::psv::ptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); + auto string = vm::cptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; @@ -139,7 +137,7 @@ std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g } } - throw fmt::format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr()); + throw EXCEPTION("Unknown formatting '%s'", start.get_ptr()); } } @@ -151,7 +149,7 @@ std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr fmt, u32 g namespace sce_libc_func { - void __cxa_atexit(vm::psv::ptr func, vm::psv::ptr arg, vm::psv::ptr dso) + void __cxa_atexit(vm::ptr func, vm::ptr arg, vm::ptr dso) { sceLibc.Warning("__cxa_atexit(func=*0x%x, arg=*0x%x, dso=*0x%x)", func, arg, dso); @@ -163,7 +161,7 @@ namespace sce_libc_func }); } - void __aeabi_atexit(vm::psv::ptr arg, vm::psv::ptr func, vm::psv::ptr dso) + void __aeabi_atexit(vm::ptr arg, vm::ptr func, vm::ptr dso) { sceLibc.Warning("__aeabi_atexit(arg=*0x%x, func=*0x%x, dso=*0x%x)", arg, func, dso); @@ -181,76 +179,76 @@ namespace sce_libc_func std::lock_guard lock(g_atexit_mutex); - if (!Emu.IsStopped()) + CHECK_EMU_STATUS; + + for (auto& func : decltype(g_atexit)(std::move(g_atexit))) { - for (auto func : decltype(g_atexit)(std::move(g_atexit))) - { - func(context); - } + func(context); + } - sceLibc.Success("Process finished"); + sceLibc.Success("Process finished"); - CallAfter([]() - { - Emu.Stop(); - }); + CallAfter([]() + { + Emu.Stop(); + }); - while (!Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } + while (true) + { + CHECK_EMU_STATUS; + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } - void printf(ARMv7Context& context, vm::psv::ptr fmt) // va_args... + void printf(ARMv7Context& context, vm::cptr fmt, armv7_va_args_t va_args) { sceLibc.Warning("printf(fmt=*0x%x)", fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); - const std::string& result = armv7_fmt(context, fmt, 1, 0, 0); + const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count); sceLibc.Log("*** -> '%s'", result); LOG_NOTICE(TTY, result); } - void sprintf(ARMv7Context& context, vm::psv::ptr str, vm::psv::ptr fmt) // va_args... + void sprintf(ARMv7Context& context, vm::ptr str, vm::cptr fmt, armv7_va_args_t va_args) { sceLibc.Warning("sprintf(str=*0x%x, fmt=*0x%x)", str, fmt); sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr()); - const std::string& result = armv7_fmt(context, fmt, 2, 0, 0); + const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count); sceLibc.Log("*** -> '%s'", result); ::memcpy(str.get_ptr(), result.c_str(), result.size() + 1); } - void __cxa_set_dso_handle_main(vm::psv::ptr dso) + void __cxa_set_dso_handle_main(vm::ptr dso) { sceLibc.Warning("__cxa_set_dso_handle_main(dso=*0x%x)", dso); g_dso = dso; } - void memcpy(vm::psv::ptr dst, vm::psv::ptr src, u32 size) + void memcpy(vm::ptr dst, vm::cptr src, u32 size) { sceLibc.Warning("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); ::memcpy(dst.get_ptr(), src.get_ptr(), size); } - void memset(vm::psv::ptr dst, s32 value, u32 size) + void memset(vm::ptr dst, s32 value, u32 size) { sceLibc.Warning("memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size); ::memset(dst.get_ptr(), value, size); } - void _Assert(ARMv7Context& context, vm::psv::ptr text, vm::psv::ptr func) + void _Assert(vm::cptr text, vm::cptr func) { sceLibc.Error("_Assert(text=*0x%x, func=*0x%x)", text, func); LOG_ERROR(TTY, "%s : %s\n", func.get_ptr(), text.get_ptr()); - LOG_NOTICE(ARMv7, context.thread.RegsToString()); Emu.Pause(); } } @@ -265,6 +263,7 @@ psv_log_base sceLibc("SceLibc", []() sceLibc.on_load = nullptr; sceLibc.on_unload = nullptr; sceLibc.on_stop = nullptr; + sceLibc.on_error = nullptr; REG_FUNC(0xE4531F85, _Assert); //REG_FUNC(0xE71C5CDE, _Stoul); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.h b/rpcs3/Emu/ARMv7/Modules/sceLibc.h new file mode 100644 index 0000000000..b09d575cf7 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.h @@ -0,0 +1,5 @@ +#pragma once + +using atexit_func_t = func_def)>; + +extern psv_log_base sceLibc; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibm.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibm.cpp index 0fc905e819..6bf914f617 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibm.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibm.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceLibm; +#include "sceLibm.h" namespace sce_libm_func { @@ -16,6 +16,7 @@ psv_log_base sceLibm("SceLibm", []() sceLibm.on_load = nullptr; sceLibm.on_unload = nullptr; sceLibm.on_stop = nullptr; + sceLibm.on_error = nullptr; //REG_FUNC(0xC73FE76D, _Exp); //REG_FUNC(0xFF4EAE04, _FExp); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibm.h b/rpcs3/Emu/ARMv7/Modules/sceLibm.h new file mode 100644 index 0000000000..1b0a58e4f6 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceLibm.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceLibm; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp index 263c0b3303..82dd811e25 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.cpp @@ -2,23 +2,23 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceLibstdcxx; +#include "sceLibstdcxx.h" namespace sce_libstdcxx_func { void __aeabi_unwind_cpp_pr0() { - throw __FUNCTION__; + throw EXCEPTION(""); } void __aeabi_unwind_cpp_pr1() { - throw __FUNCTION__; + throw EXCEPTION(""); } void __aeabi_unwind_cpp_pr2() { - throw __FUNCTION__; + throw EXCEPTION(""); } } @@ -30,6 +30,7 @@ psv_log_base sceLibstdcxx("SceLibstdcxx", []() sceLibstdcxx.on_load = nullptr; sceLibstdcxx.on_unload = nullptr; sceLibstdcxx.on_stop = nullptr; + sceLibstdcxx.on_error = nullptr; //REG_FUNC(0x52B0C625, std::bad_typeid::what() const); //REG_FUNC(0x64D7D074, std::bad_typeid::_Doraise() const); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.h b/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.h new file mode 100644 index 0000000000..5ddc0e48f4 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceLibstdcxx.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceLibstdcxx; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp b/rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp index 62eea18429..05ef8948e6 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLiveArea.cpp @@ -2,16 +2,16 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceLiveArea; +#include "sceLiveArea.h" -s32 sceLiveAreaResourceReplaceAll(vm::psv::ptr dirpath) +s32 sceLiveAreaResourceReplaceAll(vm::cptr dirpath) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceLiveAreaResourceGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceLiveArea, #name, name) @@ -21,6 +21,7 @@ psv_log_base sceLiveArea("SceLiveArea", []() sceLiveArea.on_load = nullptr; sceLiveArea.on_unload = nullptr; sceLiveArea.on_stop = nullptr; + sceLiveArea.on_error = nullptr; REG_FUNC(0xA4B506F9, sceLiveAreaResourceReplaceAll); REG_FUNC(0x54A395FB, sceLiveAreaResourceGetStatus); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLiveArea.h b/rpcs3/Emu/ARMv7/Modules/sceLiveArea.h new file mode 100644 index 0000000000..fab4f795c2 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceLiveArea.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceLiveArea; diff --git a/rpcs3/Emu/ARMv7/Modules/sceLocation.cpp b/rpcs3/Emu/ARMv7/Modules/sceLocation.cpp index 8b61bca224..007a4e742e 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLocation.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLocation.cpp @@ -2,173 +2,91 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceLocation; +#include "sceLocation.h" -typedef u8 SceLocationHandle; - -enum SceLocationLocationMethod : s32 +s32 sceLocationOpen(vm::ptr handle, SceLocationLocationMethod lmethod, SceLocationHeadingMethod hmethod) { - SCE_LOCATION_LMETHOD_NONE = 0, - SCE_LOCATION_LMETHOD_AGPS_AND_3G_AND_WIFI = 1, - SCE_LOCATION_LMETHOD_GPS_AND_WIFI = 2, - SCE_LOCATION_LMETHOD_WIFI = 3, - SCE_LOCATION_LMETHOD_3G = 4, - SCE_LOCATION_LMETHOD_GPS = 5 -}; - -enum SceLocationHeadingMethod : s32 -{ - SCE_LOCATION_HMETHOD_NONE = 0, - SCE_LOCATION_HMETHOD_AUTO = 1, - SCE_LOCATION_HMETHOD_VERTICAL = 2, - SCE_LOCATION_HMETHOD_HORIZONTAL = 3, - SCE_LOCATION_HMETHOD_CAMERA = 4 -}; - -enum SceLocationDialogStatus : s32 -{ - SCE_LOCATION_DIALOG_STATUS_IDLE = 0, - SCE_LOCATION_DIALOG_STATUS_RUNNING = 1, - SCE_LOCATION_DIALOG_STATUS_FINISHED = 2 -}; - -enum SceLocationDialogResult : s32 -{ - SCE_LOCATION_DIALOG_RESULT_NONE = 0, - SCE_LOCATION_DIALOG_RESULT_DISABLE = 1, - SCE_LOCATION_DIALOG_RESULT_ENABLE = 2 -}; - -enum SceLocationPermissionApplicationStatus : s32 -{ - SCE_LOCATION_PERMISSION_APPLICATION_NONE = 0, - SCE_LOCATION_PERMISSION_APPLICATION_INIT = 1, - SCE_LOCATION_PERMISSION_APPLICATION_DENY = 2, - SCE_LOCATION_PERMISSION_APPLICATION_ALLOW = 3 -}; - -enum SceLocationPermissionStatus : s32 -{ - SCE_LOCATION_PERMISSION_DENY = 0, - SCE_LOCATION_PERMISSION_ALLOW = 1 -}; - -struct SceLocationLocationInfo -{ - double latitude; - double longitude; - double altitude; - float accuracy; - float reserve; - float direction; - float speed; - u64 timestamp; -}; - -struct SceLocationHeadingInfo -{ - float trueHeading; - float headingVectorX; - float headingVectorY; - float headingVectorZ; - float reserve; - float reserve2; - u64 timestamp; -}; - -typedef vm::psv::ptr location, vm::psv::ptr userdata)> SceLocationLocationInfoCallback; -typedef vm::psv::ptr heading, vm::psv::ptr userdata)> SceLocationHeadingInfoCallback; - -struct SceLocationPermissionInfo -{ - SceLocationPermissionStatus parentalstatus; - SceLocationPermissionStatus mainstatus; - SceLocationPermissionApplicationStatus applicationstatus; -}; - -s32 sceLocationOpen(vm::psv::ptr handle, SceLocationLocationMethod lmethod, SceLocationHeadingMethod hmethod) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationClose(SceLocationHandle handle) +s32 sceLocationClose(u8 handle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationReopen(SceLocationHandle handle, SceLocationLocationMethod lmethod, SceLocationHeadingMethod hmethod) +s32 sceLocationReopen(u8 handle, SceLocationLocationMethod lmethod, SceLocationHeadingMethod hmethod) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationGetMethod(SceLocationHandle handle, vm::psv::ptr lmethod, vm::psv::ptr hmethod) +s32 sceLocationGetMethod(u8 handle, vm::ptr lmethod, vm::ptr hmethod) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationGetLocation(SceLocationHandle handle, vm::psv::ptr linfo) +s32 sceLocationGetLocation(u8 handle, vm::ptr linfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationCancelGetLocation(SceLocationHandle handle) +s32 sceLocationCancelGetLocation(u8 handle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationStartLocationCallback(SceLocationHandle handle, u32 distance, SceLocationLocationInfoCallback callback, vm::psv::ptr userdata) +s32 sceLocationStartLocationCallback(u8 handle, u32 distance, vm::ptr callback, vm::ptr userdata) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationStopLocationCallback(SceLocationHandle handle) +s32 sceLocationStopLocationCallback(u8 handle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationGetHeading(SceLocationHandle handle, vm::psv::ptr hinfo) +s32 sceLocationGetHeading(u8 handle, vm::ptr hinfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationStartHeadingCallback(SceLocationHandle handle, u32 difference, SceLocationHeadingInfoCallback callback, vm::psv::ptr userdata) +s32 sceLocationStartHeadingCallback(u8 handle, u32 difference, vm::ptr callback, vm::ptr userdata) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationStopHeadingCallback(SceLocationHandle handle) +s32 sceLocationStopHeadingCallback(u8 handle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationConfirm(SceLocationHandle handle) +s32 sceLocationConfirm(u8 handle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationConfirmGetStatus(SceLocationHandle handle, vm::psv::ptr status) +s32 sceLocationConfirmGetStatus(u8 handle, vm::ptr status) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationConfirmGetResult(SceLocationHandle handle, vm::psv::ptr result) +s32 sceLocationConfirmGetResult(u8 handle, vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationConfirmAbort(SceLocationHandle handle) +s32 sceLocationConfirmAbort(u8 handle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationGetPermission(SceLocationHandle handle, vm::psv::ptr info) +s32 sceLocationGetPermission(u8 handle, vm::ptr info) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceLocationSetGpsEmulationFile(vm::psv::ptr filename) +s32 sceLocationSetGpsEmulationFile(vm::ptr filename) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -179,6 +97,7 @@ psv_log_base sceLocation("SceLibLocation", []() sceLocation.on_load = nullptr; sceLocation.on_unload = nullptr; sceLocation.on_stop = nullptr; + sceLocation.on_error = nullptr; REG_FUNC(0xDD271661, sceLocationOpen); REG_FUNC(0x14FE76E8, sceLocationClose); diff --git a/rpcs3/Emu/ARMv7/Modules/sceLocation.h b/rpcs3/Emu/ARMv7/Modules/sceLocation.h new file mode 100644 index 0000000000..08253563bd --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceLocation.h @@ -0,0 +1,83 @@ +#pragma once + +enum SceLocationLocationMethod : s32 +{ + SCE_LOCATION_LMETHOD_NONE = 0, + SCE_LOCATION_LMETHOD_AGPS_AND_3G_AND_WIFI = 1, + SCE_LOCATION_LMETHOD_GPS_AND_WIFI = 2, + SCE_LOCATION_LMETHOD_WIFI = 3, + SCE_LOCATION_LMETHOD_3G = 4, + SCE_LOCATION_LMETHOD_GPS = 5 +}; + +enum SceLocationHeadingMethod : s32 +{ + SCE_LOCATION_HMETHOD_NONE = 0, + SCE_LOCATION_HMETHOD_AUTO = 1, + SCE_LOCATION_HMETHOD_VERTICAL = 2, + SCE_LOCATION_HMETHOD_HORIZONTAL = 3, + SCE_LOCATION_HMETHOD_CAMERA = 4 +}; + +enum SceLocationDialogStatus : s32 +{ + SCE_LOCATION_DIALOG_STATUS_IDLE = 0, + SCE_LOCATION_DIALOG_STATUS_RUNNING = 1, + SCE_LOCATION_DIALOG_STATUS_FINISHED = 2 +}; + +enum SceLocationDialogResult : s32 +{ + SCE_LOCATION_DIALOG_RESULT_NONE = 0, + SCE_LOCATION_DIALOG_RESULT_DISABLE = 1, + SCE_LOCATION_DIALOG_RESULT_ENABLE = 2 +}; + +enum SceLocationPermissionApplicationStatus : s32 +{ + SCE_LOCATION_PERMISSION_APPLICATION_NONE = 0, + SCE_LOCATION_PERMISSION_APPLICATION_INIT = 1, + SCE_LOCATION_PERMISSION_APPLICATION_DENY = 2, + SCE_LOCATION_PERMISSION_APPLICATION_ALLOW = 3 +}; + +enum SceLocationPermissionStatus : s32 +{ + SCE_LOCATION_PERMISSION_DENY = 0, + SCE_LOCATION_PERMISSION_ALLOW = 1 +}; + +struct SceLocationLocationInfo +{ + le_t latitude; + le_t longitude; + le_t altitude; + le_t accuracy; + le_t reserve; + le_t direction; + le_t speed; + le_t timestamp; +}; + +struct SceLocationHeadingInfo +{ + le_t trueHeading; + le_t headingVectorX; + le_t headingVectorY; + le_t headingVectorZ; + le_t reserve; + le_t reserve2; + le_t timestamp; +}; + +using SceLocationLocationInfoCallback = func_def location, vm::ptr userdata)>; +using SceLocationHeadingInfoCallback = func_def heading, vm::ptr userdata)>; + +struct SceLocationPermissionInfo +{ + SceLocationPermissionStatus parentalstatus; + SceLocationPermissionStatus mainstatus; + SceLocationPermissionApplicationStatus applicationstatus; +}; + +extern psv_log_base sceLocation; diff --git a/rpcs3/Emu/ARMv7/Modules/sceMd5.cpp b/rpcs3/Emu/ARMv7/Modules/sceMd5.cpp index d31e193e81..8b8172ebf8 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMd5.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceMd5.cpp @@ -2,37 +2,26 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceMd5; +#include "sceMd5.h" -struct SceMd5Context +s32 sceMd5Digest(vm::cptr plain, u32 len, vm::ptr digest) { - u32 h[4]; - u32 pad; - u16 usRemains; - u16 usComputed; - u64 ullTotalLen; - u8 buf[64]; - u8 result[64]; -}; - -s32 sceMd5Digest(vm::psv::ptr plain, u32 len, vm::psv::ptr digest) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMd5BlockInit(vm::psv::ptr pContext) +s32 sceMd5BlockInit(vm::ptr pContext) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMd5BlockUpdate(vm::psv::ptr pContext, vm::psv::ptr plain, u32 len) +s32 sceMd5BlockUpdate(vm::ptr pContext, vm::cptr plain, u32 len) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMd5BlockResult(vm::psv::ptr pContext, vm::psv::ptr digest) +s32 sceMd5BlockResult(vm::ptr pContext, vm::ptr digest) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceMd5, #name, name) @@ -42,6 +31,7 @@ psv_log_base sceMd5("SceMd5", []() sceMd5.on_load = nullptr; sceMd5.on_unload = nullptr; sceMd5.on_stop = nullptr; + sceMd5.on_error = nullptr; REG_FUNC(0xB845BCCB, sceMd5Digest); REG_FUNC(0x4D6436F9, sceMd5BlockInit); diff --git a/rpcs3/Emu/ARMv7/Modules/sceMd5.h b/rpcs3/Emu/ARMv7/Modules/sceMd5.h new file mode 100644 index 0000000000..27b1ba9879 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceMd5.h @@ -0,0 +1,14 @@ +#pragma once + +struct SceMd5Context +{ + le_t h[4]; + le_t pad; + le_t usRemains; + le_t usComputed; + le_t ullTotalLen; + u8 buf[64]; + u8 result[64]; +}; + +extern psv_log_base sceMd5; diff --git a/rpcs3/Emu/ARMv7/Modules/sceMotion.cpp b/rpcs3/Emu/ARMv7/Modules/sceMotion.cpp index 4128c78a65..2b11a2c932 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMotion.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceMotion.cpp @@ -2,113 +2,86 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceMotion; +#include "sceMotion.h" -struct SceMotionState +s32 sceMotionGetState(vm::ptr motionState) { - u32 timestamp; - SceFVector3 acceleration; - SceFVector3 angularVelocity; - u8 reserve1[12]; - SceFQuaternion deviceQuat; - SceUMatrix4 rotationMatrix; - SceUMatrix4 nedMatrix; - u8 reserve2[4]; - SceFVector3 basicOrientation; - u64 hostTimestamp; - u8 reserve3[40]; -}; - -struct SceMotionSensorState -{ - SceFVector3 accelerometer; - SceFVector3 gyro; - u8 reserve1[12]; - u32 timestamp; - u32 counter; - u8 reserve2[4]; - u64 hostTimestamp; - u8 reserve3[8]; -}; - -s32 sceMotionGetState(vm::psv::ptr motionState) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMotionGetSensorState(vm::psv::ptr sensorState, s32 numRecords) +s32 sceMotionGetSensorState(vm::ptr sensorState, s32 numRecords) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceMotionGetBasicOrientation(vm::psv::ptr basicOrientation) +s32 sceMotionGetBasicOrientation(vm::ptr basicOrientation) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//s32 sceMotionRotateYaw(const float radians) -//{ -// throw __FUNCTION__; -//} +s32 sceMotionRotateYaw(const float radians) +{ + throw EXCEPTION(""); +} s32 sceMotionGetTiltCorrection() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionSetTiltCorrection(s32 setValue) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionGetDeadband() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionSetDeadband(s32 setValue) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//s32 sceMotionSetAngleThreshold(const float angle) -//{ -// throw __FUNCTION__; -//} +s32 sceMotionSetAngleThreshold(const float angle) +{ + throw EXCEPTION(""); +} -//float sceMotionGetAngleThreshold() -//{ -// throw __FUNCTION__; -//} +float sceMotionGetAngleThreshold() +{ + throw EXCEPTION(""); +} s32 sceMotionReset() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionMagnetometerOn() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionMagnetometerOff() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionGetMagnetometerState() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionStartSampling() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceMotionStopSampling() { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceMotion, #name, name) @@ -118,6 +91,7 @@ psv_log_base sceMotion("SceMotion", []() sceMotion.on_load = nullptr; sceMotion.on_unload = nullptr; sceMotion.on_stop = nullptr; + sceMotion.on_error = nullptr; REG_FUNC(0xBDB32767, sceMotionGetState); REG_FUNC(0x47D679EA, sceMotionGetSensorState); diff --git a/rpcs3/Emu/ARMv7/Modules/sceMotion.h b/rpcs3/Emu/ARMv7/Modules/sceMotion.h new file mode 100644 index 0000000000..7f1b986758 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceMotion.h @@ -0,0 +1,30 @@ +#pragma once + +struct SceMotionState +{ + le_t timestamp; + SceFVector3 acceleration; + SceFVector3 angularVelocity; + u8 reserve1[12]; + SceFQuaternion deviceQuat; + SceUMatrix4 rotationMatrix; + SceUMatrix4 nedMatrix; + u8 reserve2[4]; + SceFVector3 basicOrientation; + le_t hostTimestamp; + u8 reserve3[40]; +}; + +struct SceMotionSensorState +{ + SceFVector3 accelerometer; + SceFVector3 gyro; + u8 reserve1[12]; + le_t timestamp; + le_t counter; + u8 reserve2[4]; + le_t hostTimestamp; + u8 reserve3[8]; +}; + +extern psv_log_base sceMotion; diff --git a/rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp b/rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp index 6a125206ec..885b9c9088 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceMt19937.cpp @@ -2,22 +2,16 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceMt19937; +#include "sceMt19937.h" -struct SceMt19937Context +s32 sceMt19937Init(vm::ptr pCtx, u32 seed) { - u32 count; - u32 state[624]; -}; - -s32 sceMt19937Init(vm::psv::ptr pCtx, u32 seed) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -u32 sceMt19937UInt(vm::psv::ptr pCtx) +u32 sceMt19937UInt(vm::ptr pCtx) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -28,6 +22,7 @@ psv_log_base sceMt19937("SceMt19937", []() sceMt19937.on_load = nullptr; sceMt19937.on_unload = nullptr; sceMt19937.on_stop = nullptr; + sceMt19937.on_error = nullptr; REG_FUNC(0xEE5BA27C, sceMt19937Init); REG_FUNC(0x29E43BB5, sceMt19937UInt); diff --git a/rpcs3/Emu/ARMv7/Modules/sceMt19937.h b/rpcs3/Emu/ARMv7/Modules/sceMt19937.h new file mode 100644 index 0000000000..b647a670a8 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceMt19937.h @@ -0,0 +1,9 @@ +#pragma once + +struct SceMt19937Context +{ + le_t count; + le_t state[624]; +}; + +extern psv_log_base sceMt19937; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNet.cpp b/rpcs3/Emu/ARMv7/Modules/sceNet.cpp index 347ba76df5..e873854dae 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNet.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNet.cpp @@ -4,294 +4,294 @@ #include "sceNet.h" -s32 sceNetSetDnsInfo(vm::psv::ptr info, s32 flags) +s32 sceNetSetDnsInfo(vm::ptr info, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetClearDnsCache(s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetDumpCreate(vm::psv::ptr name, s32 len, s32 flags) +s32 sceNetDumpCreate(vm::cptr name, s32 len, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetDumpRead(s32 id, vm::psv::ptr buf, s32 len, vm::psv::ptr pflags) +s32 sceNetDumpRead(s32 id, vm::ptr buf, s32 len, vm::ptr pflags) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetDumpDestroy(s32 id) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetDumpAbort(s32 id, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEpollCreate(vm::psv::ptr name, s32 flags) +s32 sceNetEpollCreate(vm::cptr name, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEpollControl(s32 eid, s32 op, s32 id, vm::psv::ptr event) +s32 sceNetEpollControl(s32 eid, s32 op, s32 id, vm::ptr event) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEpollWait(s32 eid, vm::psv::ptr events, s32 maxevents, s32 timeout) +s32 sceNetEpollWait(s32 eid, vm::ptr events, s32 maxevents, s32 timeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEpollWaitCB(s32 eid, vm::psv::ptr events, s32 maxevents, s32 timeout) +s32 sceNetEpollWaitCB(s32 eid, vm::ptr events, s32 maxevents, s32 timeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetEpollDestroy(s32 eid) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetEpollAbort(s32 eid, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNetErrnoLoc() +vm::ptr sceNetErrnoLoc() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEtherStrton(vm::psv::ptr str, vm::psv::ptr n) +s32 sceNetEtherStrton(vm::cptr str, vm::ptr n) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEtherNtostr(vm::psv::ptr n, vm::psv::ptr str, u32 len) +s32 sceNetEtherNtostr(vm::cptr n, vm::ptr str, u32 len) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetMacAddress(vm::psv::ptr addr, s32 flags) +s32 sceNetGetMacAddress(vm::ptr addr, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNetInetNtop(s32 af, vm::psv::ptr src, vm::psv::ptr dst, SceNetSocklen_t size) +vm::cptr sceNetInetNtop(s32 af, vm::cptr src, vm::ptr dst, SceNetSocklen_t size) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetInetPton(s32 af, vm::psv::ptr src, vm::psv::ptr dst) +s32 sceNetInetPton(s32 af, vm::cptr src, vm::ptr dst) { - throw __FUNCTION__; + throw EXCEPTION(""); } u64 sceNetHtonll(u64 host64) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceNetHtonl(u32 host32) { - throw __FUNCTION__; + throw EXCEPTION(""); } u16 sceNetHtons(u16 host16) { - throw __FUNCTION__; + throw EXCEPTION(""); } u64 sceNetNtohll(u64 net64) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceNetNtohl(u32 net32) { - throw __FUNCTION__; + throw EXCEPTION(""); } u16 sceNetNtohs(u16 net16) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetInit(vm::psv::ptr param) +s32 sceNetInit(vm::ptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetShowIfconfig() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetShowRoute() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetShowNetstat() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEmulationSet(vm::psv::ptr param, s32 flags) +s32 sceNetEmulationSet(vm::ptr param, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetEmulationGet(vm::psv::ptr param, s32 flags) +s32 sceNetEmulationGet(vm::ptr param, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetResolverCreate(vm::psv::ptr name, vm::psv::ptr param, s32 flags) +s32 sceNetResolverCreate(vm::cptr name, vm::ptr param, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetResolverStartNtoa(s32 rid, vm::psv::ptr hostname, vm::psv::ptr addr, s32 timeout, s32 retry, s32 flags) +s32 sceNetResolverStartNtoa(s32 rid, vm::cptr hostname, vm::ptr addr, s32 timeout, s32 retry, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetResolverStartAton(s32 rid, vm::psv::ptr addr, vm::psv::ptr hostname, s32 len, s32 timeout, s32 retry, s32 flags) +s32 sceNetResolverStartAton(s32 rid, vm::cptr addr, vm::ptr hostname, s32 len, s32 timeout, s32 retry, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetResolverGetError(s32 rid, vm::psv::ptr result) +s32 sceNetResolverGetError(s32 rid, vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetResolverDestroy(s32 rid) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetResolverAbort(s32 rid, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetSocket(vm::psv::ptr name, s32 domain, s32 type, s32 protocol) +s32 sceNetSocket(vm::cptr name, s32 domain, s32 type, s32 protocol) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetAccept(s32 s, vm::psv::ptr addr, vm::psv::ptr addrlen) +s32 sceNetAccept(s32 s, vm::ptr addr, vm::ptr addrlen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetBind(s32 s, vm::psv::ptr addr, SceNetSocklen_t addrlen) +s32 sceNetBind(s32 s, vm::cptr addr, SceNetSocklen_t addrlen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetConnect(s32 s, vm::psv::ptr name, SceNetSocklen_t namelen) +s32 sceNetConnect(s32 s, vm::cptr name, SceNetSocklen_t namelen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetpeername(s32 s, vm::psv::ptr name, vm::psv::ptr namelen) +s32 sceNetGetpeername(s32 s, vm::ptr name, vm::ptr namelen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetsockname(s32 s, vm::psv::ptr name, vm::psv::ptr namelen) +s32 sceNetGetsockname(s32 s, vm::ptr name, vm::ptr namelen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetsockopt(s32 s, s32 level, s32 optname, vm::psv::ptr optval, vm::psv::ptr optlen) +s32 sceNetGetsockopt(s32 s, s32 level, s32 optname, vm::ptr optval, vm::ptr optlen) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetListen(s32 s, s32 backlog) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetRecv(s32 s, vm::psv::ptr buf, u32 len, s32 flags) +s32 sceNetRecv(s32 s, vm::ptr buf, u32 len, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetRecvfrom(s32 s, vm::psv::ptr buf, u32 len, s32 flags, vm::psv::ptr from, vm::psv::ptr fromlen) +s32 sceNetRecvfrom(s32 s, vm::ptr buf, u32 len, s32 flags, vm::ptr from, vm::ptr fromlen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetRecvmsg(s32 s, vm::psv::ptr msg, s32 flags) +s32 sceNetRecvmsg(s32 s, vm::ptr msg, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetSend(s32 s, vm::psv::ptr msg, u32 len, s32 flags) +s32 sceNetSend(s32 s, vm::cptr msg, u32 len, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetSendto(s32 s, vm::psv::ptr msg, u32 len, s32 flags, vm::psv::ptr to, SceNetSocklen_t tolen) +s32 sceNetSendto(s32 s, vm::cptr msg, u32 len, s32 flags, vm::cptr to, SceNetSocklen_t tolen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetSendmsg(s32 s, vm::psv::ptr msg, s32 flags) +s32 sceNetSendmsg(s32 s, vm::cptr msg, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetSetsockopt(s32 s, s32 level, s32 optname, vm::psv::ptr optval, SceNetSocklen_t optlen) +s32 sceNetSetsockopt(s32 s, s32 level, s32 optname, vm::cptr optval, SceNetSocklen_t optlen) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetShutdown(s32 s, s32 how) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetSocketClose(s32 s) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetSocketAbort(s32 s, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetSockInfo(s32 s, vm::psv::ptr info, s32 n, s32 flags) +s32 sceNetGetSockInfo(s32 s, vm::ptr info, s32 n, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetSockIdInfo(vm::psv::ptr fds, s32 sockinfoflags, s32 flags) +s32 sceNetGetSockIdInfo(vm::ptr fds, s32 sockinfoflags, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetGetStatisticsInfo(vm::psv::ptr info, s32 flags) +s32 sceNetGetStatisticsInfo(vm::ptr info, s32 flags) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -302,6 +302,7 @@ psv_log_base sceNet("SceNet", []() sceNet.on_load = nullptr; sceNet.on_unload = nullptr; sceNet.on_stop = nullptr; + sceNet.on_error = nullptr; REG_FUNC(0xD62EF218, sceNetSetDnsInfo); REG_FUNC(0xFEC1166D, sceNetClearDnsCache); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNet.h b/rpcs3/Emu/ARMv7/Modules/sceNet.h index 6dc25e1ea9..37548dc287 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNet.h +++ b/rpcs3/Emu/ARMv7/Modules/sceNet.h @@ -1,22 +1,19 @@ #pragma once -typedef u32 SceNetInAddr_t; -typedef u16 SceNetInPort_t; -typedef u8 SceNetSaFamily_t; typedef u32 SceNetSocklen_t; struct SceNetInAddr { - SceNetInAddr_t s_addr; + le_t s_addr; }; struct SceNetSockaddrIn { u8 sin_len; - SceNetSaFamily_t sin_family; - SceNetInPort_t sin_port; + u8 sin_family; + le_t sin_port; SceNetInAddr sin_addr; - SceNetInPort_t sin_vport; + le_t sin_vport; char sin_zero[6]; }; @@ -28,34 +25,34 @@ struct SceNetDnsInfo struct SceNetSockaddr { u8 sa_len; - SceNetSaFamily_t sa_family; + u8 sa_family; char sa_data[14]; }; struct SceNetEpollDataExt { - s32 id; - u32 data; + le_t id; + le_t data; }; union SceNetEpollData { - vm::psv::ptr ptr; - s32 fd; - u32 _u32; - u64 _u64; + vm::lptr ptr; + le_t fd; + le_t _u32; + le_t _u64; SceNetEpollDataExt ext; }; struct SceNetEpollSystemData { - u32 system[4]; + le_t system[4]; }; struct SceNetEpollEvent { - u32 events; - u32 reserved; + le_t events; + le_t reserved; SceNetEpollSystemData system; SceNetEpollData data; }; @@ -80,108 +77,106 @@ struct SceNetIpMreq struct SceNetInitParam { - vm::psv::ptr memory; - s32 size; - s32 flags; + vm::lptr memory; + le_t size; + le_t flags; }; struct SceNetEmulationData { - u16 drop_rate; - u16 drop_duration; - u16 pass_duration; - u16 delay_time; - u16 delay_jitter; - u16 order_rate; - u16 order_delay_time; - u16 duplication_rate; - u32 bps_limit; - u16 lower_size_limit; - u16 upper_size_limit; - u32 system_policy_pattern; - u32 game_policy_pattern; - u16 policy_flags[64]; + le_t drop_rate; + le_t drop_duration; + le_t pass_duration; + le_t delay_time; + le_t delay_jitter; + le_t order_rate; + le_t order_delay_time; + le_t duplication_rate; + le_t bps_limit; + le_t lower_size_limit; + le_t upper_size_limit; + le_t system_policy_pattern; + le_t game_policy_pattern; + le_t policy_flags[64]; u8 reserved[64]; }; struct SceNetEmulationParam { - u16 version; - u16 option_number; - u16 current_version; - u16 result; - u32 flags; - u32 reserved1; + le_t version; + le_t option_number; + le_t current_version; + le_t result; + le_t flags; + le_t reserved1; SceNetEmulationData send; SceNetEmulationData recv; - u32 seed; + le_t seed; u8 reserved[44]; }; -typedef vm::psv::ptr(u32 size, s32 rid, vm::psv::ptr name, vm::psv::ptr user)> SceNetResolverFunctionAllocate; - -typedef vm::psv::ptr ptr, s32 rid, vm::psv::ptr name, vm::psv::ptr user)> SceNetResolverFunctionFree; +using SceNetResolverFunctionAllocate = func_def(u32 size, s32 rid, vm::cptr name, vm::ptr user)>; +using SceNetResolverFunctionFree = func_def ptr, s32 rid, vm::cptr name, vm::ptr user)>; struct SceNetResolverParam { - SceNetResolverFunctionAllocate allocate; - SceNetResolverFunctionFree free; - vm::psv::ptr user; + vm::lptr allocate; + vm::lptr free; + vm::lptr user; }; struct SceNetLinger { - s32 l_onoff; - s32 l_linger; + le_t l_onoff; + le_t l_linger; }; struct SceNetIovec { - vm::psv::ptr iov_base; - u32 iov_len; + vm::lptr iov_base; + le_t iov_len; }; struct SceNetMsghdr { - vm::psv::ptr msg_name; - SceNetSocklen_t msg_namelen; - vm::psv::ptr msg_iov; - s32 msg_iovlen; - vm::psv::ptr msg_control; - SceNetSocklen_t msg_controllen; - s32 msg_flags; + vm::lptr msg_name; + le_t msg_namelen; + vm::lptr msg_iov; + le_t msg_iovlen; + vm::lptr msg_control; + le_t msg_controllen; + le_t msg_flags; }; struct SceNetSockInfo { char name[32]; - s32 pid; - s32 s; + le_t pid; + le_t s; s8 socket_type; s8 policy; - s16 reserved16; - s32 recv_queue_length; - s32 send_queue_length; + le_t reserved16; + le_t recv_queue_length; + le_t send_queue_length; SceNetInAddr local_adr; SceNetInAddr remote_adr; - SceNetInPort_t local_port; - SceNetInPort_t remote_port; - SceNetInPort_t local_vport; - SceNetInPort_t remote_vport; - s32 state; - s32 flags; - s32 reserved[8]; + le_t local_port; + le_t remote_port; + le_t local_vport; + le_t remote_vport; + le_t state; + le_t flags; + le_t reserved[8]; }; struct SceNetStatisticsInfo { - s32 kernel_mem_free_size; - s32 kernel_mem_free_min; - s32 packet_count; - s32 packet_qos_count; - s32 libnet_mem_free_size; - s32 libnet_mem_free_min; + le_t kernel_mem_free_size; + le_t kernel_mem_free_min; + le_t packet_count; + le_t packet_qos_count; + le_t libnet_mem_free_size; + le_t libnet_mem_free_min; }; - extern psv_log_base sceNet; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp b/rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp index 7f15d6bf1f..46f3880b59 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNetCtl.cpp @@ -2,130 +2,86 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceNet.h" - -extern psv_log_base sceNetCtl; - -union SceNetCtlInfo -{ - char cnf_name[65]; - u32 device; - SceNetEtherAddr ether_addr; - u32 mtu; - u32 link; - SceNetEtherAddr bssid; - char ssid[33]; - u32 wifi_security; - u32 rssi_dbm; - u32 rssi_percentage; - u32 channel; - u32 ip_config; - char dhcp_hostname[256]; - char pppoe_auth_name[128]; - char ip_address[16]; - char netmask[16]; - char default_route[16]; - char primary_dns[16]; - char secondary_dns[16]; - u32 http_proxy_config; - char http_proxy_server[256]; - u32 http_proxy_port; -}; - -struct SceNetCtlNatInfo -{ - u32 size; - s32 stun_status; - s32 nat_type; - SceNetInAddr mapped_addr; -}; - -struct SceNetCtlAdhocPeerInfo -{ - vm::psv::ptr next; - SceNetInAddr inet_addr; -}; - -typedef vm::psv::ptr arg)> SceNetCtlCallback; +#include "sceNetCtl.h" s32 sceNetCtlInit() { - throw __FUNCTION__; + throw EXCEPTION(""); } void sceNetCtlTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetCtlCheckCallback() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlInetGetResult(s32 eventType, vm::psv::ptr errorCode) +s32 sceNetCtlInetGetResult(s32 eventType, vm::ptr errorCode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlAdhocGetResult(s32 eventType, vm::psv::ptr errorCode) +s32 sceNetCtlAdhocGetResult(s32 eventType, vm::ptr errorCode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlInetGetInfo(s32 code, vm::psv::ptr info) +s32 sceNetCtlInetGetInfo(s32 code, vm::ptr info) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlInetGetState(vm::psv::ptr state) +s32 sceNetCtlInetGetState(vm::ptr state) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlGetNatInfo(vm::psv::ptr natinfo) +s32 sceNetCtlGetNatInfo(vm::ptr natinfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlInetRegisterCallback(SceNetCtlCallback func, vm::psv::ptr arg, vm::psv::ptr cid) +s32 sceNetCtlInetRegisterCallback(vm::ptr func, vm::ptr arg, vm::ptr cid) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetCtlInetUnregisterCallback(s32 cid) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlAdhocRegisterCallback(SceNetCtlCallback func, vm::psv::ptr arg, vm::psv::ptr cid) +s32 sceNetCtlAdhocRegisterCallback(vm::ptr func, vm::ptr arg, vm::ptr cid) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetCtlAdhocUnregisterCallback(s32 cid) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlAdhocGetState(vm::psv::ptr state) +s32 sceNetCtlAdhocGetState(vm::ptr state) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNetCtlAdhocDisconnect() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlAdhocGetPeerList(vm::psv::ptr buflen, vm::psv::ptr buf) +s32 sceNetCtlAdhocGetPeerList(vm::ptr buflen, vm::ptr buf) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNetCtlAdhocGetInAddr(vm::psv::ptr inaddr) +s32 sceNetCtlAdhocGetInAddr(vm::ptr inaddr) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNetCtl, #name, name) @@ -135,6 +91,7 @@ psv_log_base sceNetCtl("SceNetCtl", []() sceNetCtl.on_load = nullptr; sceNetCtl.on_unload = nullptr; sceNetCtl.on_stop = nullptr; + sceNetCtl.on_error = nullptr; REG_FUNC(0x495CA1DB, sceNetCtlInit); REG_FUNC(0xCD188648, sceNetCtlTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNetCtl.h b/rpcs3/Emu/ARMv7/Modules/sceNetCtl.h new file mode 100644 index 0000000000..864194c30b --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNetCtl.h @@ -0,0 +1,47 @@ +#pragma once + +#include "sceNet.h" + +union SceNetCtlInfo +{ + char cnf_name[65]; + le_t device; + SceNetEtherAddr ether_addr; + le_t mtu; + le_t link; + SceNetEtherAddr bssid; + char ssid[33]; + le_t wifi_security; + le_t rssi_dbm; + le_t rssi_percentage; + le_t channel; + le_t ip_config; + char dhcp_hostname[256]; + char pppoe_auth_name[128]; + char ip_address[16]; + char netmask[16]; + char default_route[16]; + char primary_dns[16]; + char secondary_dns[16]; + le_t http_proxy_config; + char http_proxy_server[256]; + le_t http_proxy_port; +}; + +struct SceNetCtlNatInfo +{ + le_t size; + le_t stun_status; + le_t nat_type; + SceNetInAddr mapped_addr; +}; + +struct SceNetCtlAdhocPeerInfo +{ + vm::lptr next; + SceNetInAddr inet_addr; +}; + +using SceNetCtlCallback = func_def arg)>; + +extern psv_log_base sceNetCtl; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNgs.cpp b/rpcs3/Emu/ARMv7/Modules/sceNgs.cpp index f09993ba24..6f38a0aff6 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNgs.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNgs.cpp @@ -2,430 +2,321 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceNgs; +#include "sceNgs.h" -struct SceNgsVoiceDefinition; - -typedef u32 SceNgsModuleID; -typedef u32 SceNgsParamsID; -typedef vm::psv::ptr SceNgsHVoice; -typedef vm::psv::ptr SceNgsHPatch; -typedef vm::psv::ptr SceNgsHSynSystem; -typedef vm::psv::ptr SceNgsHRack; - -struct SceNgsModuleParamHeader +s32 sceNgsSystemGetRequiredMemorySize(vm::cptr pSynthParams, vm::ptr pnSize) { - s32 moduleId; - s32 chan; -}; - -struct SceNgsParamsDescriptor -{ - SceNgsParamsID id; - u32 size; -}; - -struct SceNgsBufferInfo -{ - vm::psv::ptr data; - u32 size; -}; - -struct SceNgsVoicePreset -{ - s32 nNameOffset; - u32 uNameLength; - s32 nPresetDataOffset; - u32 uSizePresetData; - s32 nBypassFlagsOffset; - u32 uNumBypassFlags; -}; - -struct SceNgsSystemInitParams -{ - s32 nMaxRacks; - s32 nMaxVoices; - s32 nGranularity; - s32 nSampleRate; - s32 nMaxModules; -}; - -struct SceNgsRackDescription -{ - vm::psv::ptr pVoiceDefn; - s32 nVoices; - s32 nChannelsPerVoice; - s32 nMaxPatchesPerInput; - s32 nPatchesPerOutput; - vm::psv::ptr pUserReleaseData; -}; - -struct SceNgsPatchSetupInfo -{ - SceNgsHVoice hVoiceSource; - s32 nSourceOutputIndex; - s32 nSourceOutputSubIndex; - SceNgsHVoice hVoiceDestination; - s32 nTargetInputIndex; -}; - -struct SceNgsVolumeMatrix -{ - float m[2][2]; -}; - -struct SceNgsPatchRouteInfo -{ - s32 nOutputChannels; - s32 nInputChannels; - SceNgsVolumeMatrix vols; -}; - -struct SceNgsVoiceInfo -{ - u32 uVoiceState; - u32 uNumModules; - u32 uNumInputs; - u32 uNumOutputs; - u32 uNumPatchesPerOutput; -}; - -struct SceNgsCallbackInfo -{ - SceNgsHVoice hVoiceHandle; - SceNgsHRack hRackHandle; - SceNgsModuleID uModuleID; - s32 nCallbackData; - s32 nCallbackData2; - vm::psv::ptr pCallbackPtr; - vm::psv::ptr pUserData; -}; - -typedef vm::psv::ptr pCallbackInfo)> SceNgsCallbackFunc; - -typedef SceNgsCallbackFunc SceNgsRackReleaseCallbackFunc; -typedef SceNgsCallbackFunc SceNgsModuleCallbackFunc; -typedef SceNgsCallbackFunc SceNgsParamsErrorCallbackFunc; - -struct SceSulphaNgsConfig -{ - u32 maxNamedObjects; - u32 maxTraceBufferBytes; -}; - -s32 sceNgsSystemGetRequiredMemorySize(vm::psv::ptr pSynthParams, vm::psv::ptr pnSize) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsSystemInit(vm::psv::ptr pSynthSysMemory, const u32 uMemSize, vm::psv::ptr pSynthParams, vm::psv::ptr pSystemHandle) +s32 sceNgsSystemInit(vm::ptr pSynthSysMemory, const u32 uMemSize, vm::cptr pSynthParams, vm::ptr pSystemHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsSystemUpdate(SceNgsHSynSystem hSystemHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsSystemRelease(SceNgsHSynSystem hSystemHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsSystemLock(SceNgsHSynSystem hSystemHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsSystemUnlock(SceNgsHSynSystem hSystemHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsSystemSetParamErrorCallback(SceNgsHSynSystem hSystemHandle, const SceNgsParamsErrorCallbackFunc callbackFuncPtr) +s32 sceNgsSystemSetParamErrorCallback(SceNgsHSynSystem hSystemHandle, vm::ptr callbackFuncPtr) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsSystemSetFlags(SceNgsHSynSystem hSystemHandle, const u32 uSystemFlags) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsRackGetRequiredMemorySize(SceNgsHSynSystem hSystemHandle, vm::psv::ptr pRackDesc, vm::psv::ptr pnSize) +s32 sceNgsRackGetRequiredMemorySize(SceNgsHSynSystem hSystemHandle, vm::cptr pRackDesc, vm::ptr pnSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsRackInit(SceNgsHSynSystem hSystemHandle, vm::psv::ptr pRackBuffer, vm::psv::ptr pRackDesc, vm::psv::ptr pRackHandle) +s32 sceNgsRackInit(SceNgsHSynSystem hSystemHandle, vm::ptr pRackBuffer, vm::cptr pRackDesc, vm::ptr pRackHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsRackGetVoiceHandle(SceNgsHRack hRackHandle, const u32 uIndex, vm::psv::ptr pVoiceHandle) +s32 sceNgsRackGetVoiceHandle(SceNgsHRack hRackHandle, const u32 uIndex, vm::ptr pVoiceHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsRackRelease(SceNgsHRack hRackHandle, const SceNgsRackReleaseCallbackFunc callbackFuncPtr) +s32 sceNgsRackRelease(SceNgsHRack hRackHandle, vm::ptr callbackFuncPtr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsRackSetParamErrorCallback(SceNgsHRack hRackHandle, const SceNgsParamsErrorCallbackFunc callbackFuncPtr) +s32 sceNgsRackSetParamErrorCallback(SceNgsHRack hRackHandle, vm::ptr callbackFuncPtr) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceInit(SceNgsHVoice hVoiceHandle, vm::psv::ptr pPreset, const u32 uInitFlags) +s32 sceNgsVoiceInit(SceNgsHVoice hVoiceHandle, vm::cptr pPreset, const u32 uInitFlags) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoicePlay(SceNgsHVoice hVoiceHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoiceKeyOff(SceNgsHVoice hVoiceHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoiceKill(SceNgsHVoice hVoiceHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoicePause(SceNgsHVoice hVoiceHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoiceResume(SceNgsHVoice hVoiceHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceSetPreset(SceNgsHVoice hVoiceHandle, vm::psv::ptr pVoicePreset) +s32 sceNgsVoiceSetPreset(SceNgsHVoice hVoiceHandle, vm::cptr pVoicePreset) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceLockParams(SceNgsHVoice hVoiceHandle, const u32 uModule, const SceNgsParamsID uParamsInterfaceId, vm::psv::ptr pParamsBuffer) +s32 sceNgsVoiceLockParams(SceNgsHVoice hVoiceHandle, const u32 uModule, const u32 uParamsInterfaceId, vm::ptr pParamsBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoiceUnlockParams(SceNgsHVoice hVoiceHandle, const u32 uModule) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceSetParamsBlock(SceNgsHVoice hVoiceHandle, vm::psv::ptr pParamData, const u32 uSize, vm::psv::ptr pnErrorCount) +s32 sceNgsVoiceSetParamsBlock(SceNgsHVoice hVoiceHandle, vm::cptr pParamData, const u32 uSize, vm::ptr pnErrorCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsVoiceBypassModule(SceNgsHVoice hVoiceHandle, const u32 uModule, const u32 uBypassFlag) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceSetModuleCallback(SceNgsHVoice hVoiceHandle, const u32 uModule, const SceNgsModuleCallbackFunc callbackFuncPtr, vm::psv::ptr pUserData) +s32 sceNgsVoiceSetModuleCallback(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::ptr callbackFuncPtr, vm::ptr pUserData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceSetFinishedCallback(SceNgsHVoice hVoiceHandle, const SceNgsCallbackFunc callbackFuncPtr, vm::psv::ptr pUserData) +s32 sceNgsVoiceSetFinishedCallback(SceNgsHVoice hVoiceHandle, vm::ptr callbackFuncPtr, vm::ptr pUserData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceGetStateData(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::psv::ptr pMem, const u32 uMemSize) +s32 sceNgsVoiceGetStateData(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::ptr pMem, const u32 uMemSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceGetInfo(SceNgsHVoice hVoiceHandle, vm::psv::ptr pInfo) +s32 sceNgsVoiceGetInfo(SceNgsHVoice hVoiceHandle, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceGetModuleType(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::psv::ptr pModuleType) +s32 sceNgsVoiceGetModuleType(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::ptr pModuleType) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceGetModuleBypass(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::psv::ptr puBypassFlag) +s32 sceNgsVoiceGetModuleBypass(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::ptr puBypassFlag) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceGetParamsOutOfRange(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::psv::ptr pszMessageBuffer) +s32 sceNgsVoiceGetParamsOutOfRange(SceNgsHVoice hVoiceHandle, const u32 uModule, vm::ptr pszMessageBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsPatchCreateRouting(vm::psv::ptr pPatchInfo, vm::psv::ptr pPatchHandle) +s32 sceNgsPatchCreateRouting(vm::cptr pPatchInfo, vm::ptr pPatchHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsPatchGetInfo(SceNgsHPatch hPatchHandle, vm::psv::ptr pRouteInfo, vm::psv::ptr pSetup) +s32 sceNgsPatchGetInfo(SceNgsHPatch hPatchHandle, vm::ptr pRouteInfo, vm::ptr pSetup) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoiceGetOutputPatch(SceNgsHVoice hVoiceHandle, const s32 nOutputIndex, const s32 nSubIndex, vm::psv::ptr pPatchHandle) +s32 sceNgsVoiceGetOutputPatch(SceNgsHVoice hVoiceHandle, const s32 nOutputIndex, const s32 nSubIndex, vm::ptr pPatchHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNgsPatchRemoveRouting(SceNgsHPatch hPatchHandle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//s32 sceNgsVoicePatchSetVolume(SceNgsHPatch hPatchHandle, const s32 nOutputChannel, const s32 nInputChannel, const float fVol) -//{ -// throw __FUNCTION__; -//} - -s32 sceNgsVoicePatchSetVolumes(SceNgsHPatch hPatchHandle, const s32 nOutputChannel, vm::psv::ptr pVolumes, const s32 nVols) +s32 sceNgsVoicePatchSetVolume(SceNgsHPatch hPatchHandle, const s32 nOutputChannel, const s32 nInputChannel, const float fVol) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsVoicePatchSetVolumesMatrix(SceNgsHPatch hPatchHandle, vm::psv::ptr pMatrix) +s32 sceNgsVoicePatchSetVolumes(SceNgsHPatch hPatchHandle, const s32 nOutputChannel, vm::cptr pVolumes, const s32 nVols) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsModuleGetNumPresets(SceNgsHSynSystem hSystemHandle, const SceNgsModuleID uModuleID, vm::psv::ptr puNumPresets) +s32 sceNgsVoicePatchSetVolumesMatrix(SceNgsHPatch hPatchHandle, vm::cptr pMatrix) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNgsModuleGetPreset(SceNgsHSynSystem hSystemHandle, const SceNgsModuleID uModuleID, const u32 uPresetIndex, vm::psv::ptr pParamsBuffer) +s32 sceNgsModuleGetNumPresets(SceNgsHSynSystem hSystemHandle, const u32 uModuleID, vm::ptr puNumPresets) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetCompressorBuss() +s32 sceNgsModuleGetPreset(SceNgsHSynSystem hSystemHandle, const u32 uModuleID, const u32 uPresetIndex, vm::ptr pParamsBuffer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetCompressorSideChainBuss() +vm::cptr sceNgsVoiceDefGetCompressorBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetDelayBuss() +vm::cptr sceNgsVoiceDefGetCompressorSideChainBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetDistortionBuss() +vm::cptr sceNgsVoiceDefGetDelayBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetEnvelopeBuss() +vm::cptr sceNgsVoiceDefGetDistortionBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetEqBuss() +vm::cptr sceNgsVoiceDefGetEnvelopeBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetMasterBuss() +vm::cptr sceNgsVoiceDefGetEqBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetMixerBuss() +vm::cptr sceNgsVoiceDefGetMasterBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetPauserBuss() +vm::cptr sceNgsVoiceDefGetMixerBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetReverbBuss() +vm::cptr sceNgsVoiceDefGetPauserBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetSasEmuVoice() +vm::cptr sceNgsVoiceDefGetReverbBuss() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetSimpleVoice() +vm::cptr sceNgsVoiceDefGetSasEmuVoice() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetTemplate1() +vm::cptr sceNgsVoiceDefGetSimpleVoice() { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceNgsVoiceDefGetAtrac9Voice() +vm::cptr sceNgsVoiceDefGetTemplate1() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsGetDefaultConfig(vm::psv::ptr config) +vm::cptr sceNgsVoiceDefGetAtrac9Voice() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsGetNeededMemory(vm::psv::ptr config, vm::psv::ptr sizeInBytes) +s32 sceSulphaNgsGetDefaultConfig(vm::ptr config) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsInit(vm::psv::ptr config, vm::psv::ptr buffer, u32 sizeInBytes) +s32 sceSulphaNgsGetNeededMemory(vm::cptr config, vm::ptr sizeInBytes) { - throw __FUNCTION__; + throw EXCEPTION(""); +} + +s32 sceSulphaNgsInit(vm::cptr config, vm::ptr buffer, u32 sizeInBytes) +{ + throw EXCEPTION(""); } s32 sceSulphaNgsShutdown() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsSetSynthName(SceNgsHSynSystem synthHandle, vm::psv::ptr name) +s32 sceSulphaNgsSetSynthName(SceNgsHSynSystem synthHandle, vm::cptr name) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsSetRackName(SceNgsHRack rackHandle, vm::psv::ptr name) +s32 sceSulphaNgsSetRackName(SceNgsHRack rackHandle, vm::cptr name) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsSetVoiceName(SceNgsHVoice voiceHandle, vm::psv::ptr name) +s32 sceSulphaNgsSetVoiceName(SceNgsHVoice voiceHandle, vm::cptr name) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsSetSampleName(vm::psv::ptr location, u32 length, vm::psv::ptr name) +s32 sceSulphaNgsSetSampleName(vm::cptr location, u32 length, vm::cptr name) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaNgsTrace(vm::psv::ptr message) +s32 sceSulphaNgsTrace(vm::cptr message) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -436,6 +327,7 @@ psv_log_base sceNgs("SceNgs", []() sceNgs.on_load = nullptr; sceNgs.on_unload = nullptr; sceNgs.on_stop = nullptr; + sceNgs.on_error = nullptr; REG_FUNC(0x6CE8B36F, sceNgsSystemGetRequiredMemorySize); REG_FUNC(0xED14CF4A, sceNgsSystemInit); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNgs.h b/rpcs3/Emu/ARMv7/Modules/sceNgs.h new file mode 100644 index 0000000000..c9955aa814 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNgs.h @@ -0,0 +1,106 @@ +#pragma once + +struct SceNgsVoiceDefinition; + +using SceNgsHVoice = vm::ptr; +using SceNgsHPatch = vm::ptr; +using SceNgsHSynSystem = vm::ptr; +using SceNgsHRack = vm::ptr; + +struct SceNgsModuleParamHeader +{ + le_t moduleId; + le_t chan; +}; + +struct SceNgsParamsDescriptor +{ + le_t id; + le_t size; +}; + +struct SceNgsBufferInfo +{ + vm::lptr data; + le_t size; +}; + +struct SceNgsVoicePreset +{ + le_t nNameOffset; + le_t uNameLength; + le_t nPresetDataOffset; + le_t uSizePresetData; + le_t nBypassFlagsOffset; + le_t uNumBypassFlags; +}; + +struct SceNgsSystemInitParams +{ + le_t nMaxRacks; + le_t nMaxVoices; + le_t nGranularity; + le_t nSampleRate; + le_t nMaxModules; +}; + +struct SceNgsRackDescription +{ + vm::lcptr pVoiceDefn; + le_t nVoices; + le_t nChannelsPerVoice; + le_t nMaxPatchesPerInput; + le_t nPatchesPerOutput; + vm::lptr pUserReleaseData; +}; + +struct SceNgsPatchSetupInfo +{ + SceNgsHVoice hVoiceSource; + le_t nSourceOutputIndex; + le_t nSourceOutputSubIndex; + SceNgsHVoice hVoiceDestination; + le_t nTargetInputIndex; +}; + +struct SceNgsVolumeMatrix +{ + le_t m[2][2]; +}; + +struct SceNgsPatchRouteInfo +{ + le_t nOutputChannels; + le_t nInputChannels; + SceNgsVolumeMatrix vols; +}; + +struct SceNgsVoiceInfo +{ + le_t uVoiceState; + le_t uNumModules; + le_t uNumInputs; + le_t uNumOutputs; + le_t uNumPatchesPerOutput; +}; + +struct SceNgsCallbackInfo +{ + SceNgsHVoice hVoiceHandle; + SceNgsHRack hRackHandle; + le_t uModuleID; + le_t nCallbackData; + le_t nCallbackData2; + vm::lptr pCallbackPtr; + vm::lptr pUserData; +}; + +using SceNgsCallbackFunc = func_def pCallbackInfo)>; + +struct SceSulphaNgsConfig +{ + le_t maxNamedObjects; + le_t maxTraceBufferBytes; +}; + +extern psv_log_base sceNgs; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp index e798df5f48..578d691725 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpBasic.cpp @@ -2,210 +2,96 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceNpCommon.h" +#include "sceNpBasic.h" -extern psv_log_base sceNpBasic; - -enum SceNpBasicFriendListEventType : s32 +s32 sceNpBasicInit(vm::ptr opt) { - SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_SYNC = 1, - SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_SYNC_DONE = 2, - SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_ADDED = 3, - SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_DELETED = 4 -}; - -typedef vm::psv::ptr friendId, vm::psv::ptr userdata)> SceNpBasicFriendListEventHandler; - -enum SceNpBasicFriendOnlineStatusEventType : s32 -{ - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_EVENT_TYPE_SYNC = 1, - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_EVENT_TYPE_SYNC_DONE = 2, - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_EVENT_TYPE_UPDATED = 3 -}; - -enum SceNpBasicFriendOnlineStatus : s32 -{ - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_UNKNOWN = 0, - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_OFFLINE = 1, - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_STANDBY = 2, - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_ONLINE_OUT_OF_CONTEXT = 3, - SCE_NP_BASIC_FRIEND_ONLINE_STATUS_ONLINE_IN_CONTEXT = 4 -}; - -typedef vm::psv::ptr friendId, SceNpBasicFriendOnlineStatus status, vm::psv::ptr userdata)> SceNpBasicFriendOnlineStatusEventHandler; - -enum SceNpBasicBlockListEventType : s32 -{ - SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_SYNC = 1, - SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_SYNC_DONE = 2, - SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_ADDED = 3, - SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_DELETED = 4 -}; - -typedef vm::psv::ptr playerId, vm::psv::ptr userdata)> SceNpBasicBlockListEventHandler; - -enum SceNpBasicFriendGamePresenceEventType : s32 -{ - SCE_NP_BASIC_FRIEND_GAME_PRESENCE_EVENT_TYPE_SYNC = 1, - SCE_NP_BASIC_FRIEND_GAME_PRESENCE_EVENT_TYPE_SYNC_DONE = 2, - SCE_NP_BASIC_FRIEND_GAME_PRESENCE_EVENT_TYPE_UPDATED = 3 -}; - -enum SceNpBasicInGamePresenceType -{ - SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_UNKNOWN = -1, - SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_NONE = 0, - SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_DEFAULT = 1, - SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_JOINABLE = 2, - SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_MAX = 3 -}; - -struct SceNpBasicInGamePresence -{ - u32 sdkVersion; - SceNpBasicInGamePresenceType type; - char status[192]; - u8 data[128]; - u32 dataSize; -}; - -struct SceNpBasicGamePresence -{ - u32 size; - char title[128]; - SceNpBasicInGamePresence inGamePresence; -}; - -typedef vm::psv::ptr friendId, vm::psv::ptr presence, vm::psv::ptr userdata)> SceNpBasicFriendGamePresenceEventHandler; - -struct SceNpBasicInGameDataMessage -{ - u8 data[128]; - u32 dataSize; -}; - -typedef vm::psv::ptr from, vm::psv::ptr message, vm::psv::ptr userdata)> SceNpBasicInGameDataMessageEventHandler; - -struct SceNpBasicEventHandlers -{ - u32 sdkVersion; - SceNpBasicFriendListEventHandler friendListEventHandler; - SceNpBasicFriendOnlineStatusEventHandler friendOnlineStatusEventHandler; - SceNpBasicBlockListEventHandler blockListEventHandler; - SceNpBasicFriendGamePresenceEventHandler friendGamePresenceEventHandler; - SceNpBasicInGameDataMessageEventHandler inGameDataMessageEventHandler; -}; - -struct SceNpBasicPlaySessionLogDescription -{ - char text[512]; -}; - -struct SceNpBasicPlaySessionLog -{ - u64 date; - SceNpId withWhom; - SceNpCommunicationId commId; - char title[128]; - SceNpBasicPlaySessionLogDescription description; -}; - -enum SceNpBasicPlaySessionLogType : s32 -{ - SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_INVALID = -1, - SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_ALL = 0, - SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_BY_NP_COMM_ID = 1, - SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_MAX = 2 -}; - -s32 sceNpBasicInit(vm::psv::ptr opt) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBasicTerm(ARMv7Context&) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicRegisterHandler(vm::psv::ptr handlers, vm::psv::ptr context, vm::psv::ptr userdata) +s32 sceNpBasicRegisterHandler(vm::cptr handlers, vm::cptr context, vm::ptr userdata) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBasicUnregisterHandler(ARMv7Context&) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBasicCheckCallback() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetFriendOnlineStatus(vm::psv::ptr friendId, vm::psv::ptr status) +s32 sceNpBasicGetFriendOnlineStatus(vm::cptr friendId, vm::ptr status) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetGamePresenceOfFriend(vm::psv::ptr friendId, vm::psv::ptr presence) +s32 sceNpBasicGetGamePresenceOfFriend(vm::cptr friendId, vm::ptr presence) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetFriendListEntryCount(vm::psv::ptr count) +s32 sceNpBasicGetFriendListEntryCount(vm::ptr count) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetFriendListEntries(u32 startIndex, vm::psv::ptr entries, u32 numEntries, vm::psv::ptr retrieved) +s32 sceNpBasicGetFriendListEntries(u32 startIndex, vm::ptr entries, u32 numEntries, vm::ptr retrieved) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetBlockListEntryCount(vm::psv::ptr count) +s32 sceNpBasicGetBlockListEntryCount(vm::ptr count) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetBlockListEntries(u32 startIndex, vm::psv::ptr entries, u32 numEntries, vm::psv::ptr retrieved) +s32 sceNpBasicGetBlockListEntries(u32 startIndex, vm::ptr entries, u32 numEntries, vm::ptr retrieved) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicCheckIfPlayerIsBlocked(vm::psv::ptr player, vm::psv::ptr playerIsBlocked) +s32 sceNpBasicCheckIfPlayerIsBlocked(vm::cptr player, vm::ptr playerIsBlocked) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicSetInGamePresence(vm::psv::ptr presence) +s32 sceNpBasicSetInGamePresence(vm::cptr presence) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBasicUnsetInGamePresence() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicSendInGameDataMessage(vm::psv::ptr to, vm::psv::ptr message) +s32 sceNpBasicSendInGameDataMessage(vm::cptr to, vm::cptr message) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicRecordPlaySessionLog(vm::psv::ptr withWhom, vm::psv::ptr description) +s32 sceNpBasicRecordPlaySessionLog(vm::cptr withWhom, vm::cptr description) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetPlaySessionLogSize(SceNpBasicPlaySessionLogType type, vm::psv::ptr size) +s32 sceNpBasicGetPlaySessionLogSize(SceNpBasicPlaySessionLogType type, vm::ptr size) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBasicGetPlaySessionLog(SceNpBasicPlaySessionLogType type, u32 index, vm::psv::ptr log) +s32 sceNpBasicGetPlaySessionLog(SceNpBasicPlaySessionLogType type, u32 index, vm::ptr log) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNpBasic, #name, name) @@ -215,6 +101,7 @@ psv_log_base sceNpBasic("SceNpBasic", []() sceNpBasic.on_load = nullptr; sceNpBasic.on_unload = nullptr; sceNpBasic.on_stop = nullptr; + sceNpBasic.on_error = nullptr; REG_FUNC(0xEFB91A99, sceNpBasicInit); REG_FUNC(0x389BCB3B, sceNpBasicTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpBasic.h b/rpcs3/Emu/ARMv7/Modules/sceNpBasic.h new file mode 100644 index 0000000000..acf4b67438 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNpBasic.h @@ -0,0 +1,117 @@ +#pragma once + +#include "sceNpCommon.h" + +enum SceNpBasicFriendListEventType : s32 +{ + SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_SYNC = 1, + SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_SYNC_DONE = 2, + SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_ADDED = 3, + SCE_NP_BASIC_FRIEND_LIST_EVENT_TYPE_DELETED = 4 +}; + +using SceNpBasicFriendListEventHandler = func_def friendId, vm::ptr userdata)>; + +enum SceNpBasicFriendOnlineStatusEventType : s32 +{ + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_EVENT_TYPE_SYNC = 1, + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_EVENT_TYPE_SYNC_DONE = 2, + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_EVENT_TYPE_UPDATED = 3 +}; + +enum SceNpBasicFriendOnlineStatus : s32 +{ + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_UNKNOWN = 0, + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_OFFLINE = 1, + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_STANDBY = 2, + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_ONLINE_OUT_OF_CONTEXT = 3, + SCE_NP_BASIC_FRIEND_ONLINE_STATUS_ONLINE_IN_CONTEXT = 4 +}; + +using SceNpBasicFriendOnlineStatusEventHandler = func_def friendId, SceNpBasicFriendOnlineStatus status, vm::ptr userdata)>; + +enum SceNpBasicBlockListEventType : s32 +{ + SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_SYNC = 1, + SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_SYNC_DONE = 2, + SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_ADDED = 3, + SCE_NP_BASIC_BLOCK_LIST_EVENT_TYPE_DELETED = 4 +}; + +using SceNpBasicBlockListEventHandler = func_def playerId, vm::ptr userdata)>; + +enum SceNpBasicFriendGamePresenceEventType : s32 +{ + SCE_NP_BASIC_FRIEND_GAME_PRESENCE_EVENT_TYPE_SYNC = 1, + SCE_NP_BASIC_FRIEND_GAME_PRESENCE_EVENT_TYPE_SYNC_DONE = 2, + SCE_NP_BASIC_FRIEND_GAME_PRESENCE_EVENT_TYPE_UPDATED = 3 +}; + +enum SceNpBasicInGamePresenceType : s32 +{ + SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_UNKNOWN = -1, + SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_NONE = 0, + SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_DEFAULT = 1, + SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_JOINABLE = 2, + SCE_NP_BASIC_IN_GAME_PRESENCE_TYPE_MAX = 3 +}; + +struct SceNpBasicInGamePresence +{ + le_t sdkVersion; + le_t type; // SceNpBasicInGamePresenceType + char status[192]; + u8 data[128]; + le_t dataSize; +}; + +struct SceNpBasicGamePresence +{ + le_t size; + char title[128]; + SceNpBasicInGamePresence inGamePresence; +}; + +using SceNpBasicFriendGamePresenceEventHandler = func_def friendId, vm::cptr presence, vm::ptr userdata)>; + +struct SceNpBasicInGameDataMessage +{ + u8 data[128]; + le_t dataSize; +}; + +using SceNpBasicInGameDataMessageEventHandler = func_def from, vm::cptr message, vm::ptr userdata)>; + +struct SceNpBasicEventHandlers +{ + le_t sdkVersion; + vm::lptr friendListEventHandler; + vm::lptr friendOnlineStatusEventHandler; + vm::lptr blockListEventHandler; + vm::lptr friendGamePresenceEventHandler; + vm::lptr inGameDataMessageEventHandler; +}; + +struct SceNpBasicPlaySessionLogDescription +{ + char text[512]; +}; + +struct SceNpBasicPlaySessionLog +{ + le_t date; + SceNpId withWhom; + SceNpCommunicationId commId; + char title[128]; + SceNpBasicPlaySessionLogDescription description; +}; + +enum SceNpBasicPlaySessionLogType : s32 +{ + SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_INVALID = -1, + SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_ALL = 0, + SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_BY_NP_COMM_ID = 1, + SCE_NP_BASIC_PLAY_SESSION_LOG_TYPE_MAX = 2 +}; + +extern psv_log_base sceNpBasic; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp index 095de28b17..477cab5523 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpCommon.cpp @@ -6,57 +6,57 @@ s32 sceNpAuthInit() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpAuthTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthCreateStartRequest(vm::psv::ptr param) +s32 sceNpAuthCreateStartRequest(vm::cptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthDestroyRequest(SceNpAuthRequestId id) +s32 sceNpAuthDestroyRequest(s32 id) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthAbortRequest(SceNpAuthRequestId id) +s32 sceNpAuthAbortRequest(s32 id) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthGetTicket(SceNpAuthRequestId id, vm::psv::ptr buf, u32 len) +s32 sceNpAuthGetTicket(s32 id, vm::ptr buf, u32 len) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthGetTicketParam(vm::psv::ptr ticket, u32 ticketSize, s32 paramId, vm::psv::ptr param) +s32 sceNpAuthGetTicketParam(vm::cptr ticket, u32 ticketSize, s32 paramId, vm::ptr param) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthGetEntitlementIdList(vm::psv::ptr ticket, u32 ticketSize, vm::psv::ptr entIdList, u32 entIdListNum) +s32 sceNpAuthGetEntitlementIdList(vm::cptr ticket, u32 ticketSize, vm::ptr entIdList, u32 entIdListNum) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpAuthGetEntitlementById(vm::psv::ptr ticket, u32 ticketSize, vm::psv::ptr entId, vm::psv::ptr ent) +s32 sceNpAuthGetEntitlementById(vm::cptr ticket, u32 ticketSize, vm::cptr entId, vm::ptr ent) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpCmpNpId(vm::psv::ptr npid1, vm::psv::ptr npid2) +s32 sceNpCmpNpId(vm::cptr npid1, vm::cptr npid2) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpCmpNpIdInOrder(vm::psv::ptr npid1, vm::psv::ptr npid2, vm::psv::ptr order) +s32 sceNpCmpNpIdInOrder(vm::cptr npid1, vm::cptr npid2, vm::ptr order) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNpCommon, #name, name) @@ -66,6 +66,7 @@ psv_log_base sceNpCommon("SceNpCommon", []() sceNpCommon.on_load = nullptr; sceNpCommon.on_unload = nullptr; sceNpCommon.on_stop = nullptr; + sceNpCommon.on_error = nullptr; REG_FUNC(0x441D8B4E, sceNpAuthInit); REG_FUNC(0x6093B689, sceNpAuthTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.h b/rpcs3/Emu/ARMv7/Modules/sceNpCommon.h index bd2b282301..56e2a65252 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpCommon.h +++ b/rpcs3/Emu/ARMv7/Modules/sceNpCommon.h @@ -28,9 +28,9 @@ struct SceNpCommunicationSignature struct SceNpCommunicationConfig { - vm::psv::ptr commId; - vm::psv::ptr commPassphrase; - vm::psv::ptr commSignature; + vm::lcptr commId; + vm::lcptr commPassphrase; + vm::lcptr commSignature; }; struct SceNpCountryCode @@ -69,16 +69,16 @@ struct SceNpUserInformation struct SceNpMyLanguages { - s32 language1; - s32 language2; - s32 language3; + le_t language1; + le_t language2; + le_t language3; u8 padding[4]; }; struct SceNpAvatarImage { u8 data[200 * 1024]; - u32 size; + le_t size; u8 reserved[12]; }; @@ -94,45 +94,42 @@ struct SceNpAboutMe char data[64]; }; -typedef s32 SceNpAuthRequestId; -typedef u64 SceNpTime; - struct SceNpDate { - u16 year; + le_t year; u8 month; u8 day; }; union SceNpTicketParam { - s32 _s32; - s64 _s64; - u32 _u32; - u64 _u64; + le_t _s32; + le_t _s64; + le_t _u32; + le_t _u64; SceNpDate date; u8 data[256]; }; struct SceNpTicketVersion { - u16 major; - u16 minor; + le_t major; + le_t minor; }; -typedef vm::psv::ptr arg)> SceNpAuthCallback; +using SceNpAuthCallback = func_def arg)>; struct SceNpAuthRequestParameter { - u32 size; + le_t size; SceNpTicketVersion version; - vm::psv::ptr serviceId; - vm::psv::ptr cookie; - u32 cookieSize; - vm::psv::ptr entitlementId; - u32 consumedCount; - SceNpAuthCallback ticketCb; - vm::psv::ptr cbArg; + vm::lcptr serviceId; + vm::lcptr cookie; + le_t cookieSize; + vm::lcptr entitlementId; + le_t consumedCount; + vm::lptr ticketCb; + vm::lptr cbArg; }; struct SceNpEntitlementId @@ -143,11 +140,11 @@ struct SceNpEntitlementId struct SceNpEntitlement { SceNpEntitlementId id; - SceNpTime createdDate; - SceNpTime expireDate; - u32 type; - s32 remainingCount; - u32 consumedCount; + le_t createdDate; + le_t expireDate; + le_t type; + le_t remainingCount; + le_t consumedCount; char padding[4]; }; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp index 5fce1c946e..aa1551bd30 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpManager.cpp @@ -2,65 +2,56 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceNpCommon.h" +#include "sceNpManager.h" -extern psv_log_base sceNpManager; - -struct SceNpOptParam +s32 sceNpInit(vm::cptr commConf, vm::ptr opt) { - u32 optParamSize; -}; - -typedef vm::psv::ptr userdata)> SceNpServiceStateCallback; - -s32 sceNpInit(vm::psv::ptr commConf, vm::psv::ptr opt) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpTerm(ARMv7Context&) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpCheckCallback() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpGetServiceState(vm::psv::ptr state) +s32 sceNpGetServiceState(vm::ptr state) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpRegisterServiceStateCallback(SceNpServiceStateCallback callback, vm::psv::ptr userdata) +s32 sceNpRegisterServiceStateCallback(vm::ptr callback, vm::ptr userdata) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpUnregisterServiceStateCallback() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpManagerGetNpId(vm::psv::ptr npId) +s32 sceNpManagerGetNpId(vm::ptr npId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpManagerGetAccountRegion(vm::psv::ptr countryCode, vm::psv::ptr languageCode) +s32 sceNpManagerGetAccountRegion(vm::ptr countryCode, vm::ptr languageCode) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpManagerGetContentRatingFlag(vm::psv::ptr isRestricted, vm::psv::ptr age) +s32 sceNpManagerGetContentRatingFlag(vm::ptr isRestricted, vm::ptr age) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpManagerGetChatRestrictionFlag(vm::psv::ptr isRestricted) +s32 sceNpManagerGetChatRestrictionFlag(vm::ptr isRestricted) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNpManager, #name, name) @@ -70,6 +61,7 @@ psv_log_base sceNpManager("SceNpManager", []() sceNpManager.on_load = nullptr; sceNpManager.on_unload = nullptr; sceNpManager.on_stop = nullptr; + sceNpManager.on_error = nullptr; REG_FUNC(0x04D9F484, sceNpInit); REG_FUNC(0x19E40AE1, sceNpTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpManager.h b/rpcs3/Emu/ARMv7/Modules/sceNpManager.h new file mode 100644 index 0000000000..3b07700d44 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNpManager.h @@ -0,0 +1,12 @@ +#pragma once + +#include "sceNpCommon.h" + +struct SceNpOptParam +{ + le_t optParamSize; +}; + +using SceNpServiceStateCallback = func_def userdata)>; + +extern psv_log_base sceNpManager; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp index 31c0d665f3..d267f98bb4 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpMatching.cpp @@ -2,1304 +2,226 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceNet.h" -#include "sceNpCommon.h" - -extern psv_log_base sceNpMatching; - -struct SceNpMatching2MemoryInfo -{ - u32 totalMemSize; - u32 curMemUsage; - u32 maxMemUsage; - u8 reserved[12]; -}; - -typedef u16 SceNpMatching2ServerId; -typedef u32 SceNpMatching2WorldId; -typedef u16 SceNpMatching2WorldNumber; -typedef u64 SceNpMatching2LobbyId; -typedef u16 SceNpMatching2LobbyNumber; -typedef u64 SceNpMatching2RoomId; -typedef u16 SceNpMatching2RoomNumber; -typedef u16 SceNpMatching2ContextId; -typedef u32 SceNpMatching2RequestId; -typedef u32 SceNpMatching2SignalingRequestId; -typedef u8 SceNpMatching2NatType; -typedef u8 SceNpMatching2Operator; -typedef u8 SceNpMatching2CastType; - -struct SceNpMatching2SessionPassword -{ - u8 data[8]; -}; - -typedef u8 SceNpMatching2SessionType; -typedef u8 SceNpMatching2EventCause; - -struct SceNpMatching2PresenceOptionData -{ - u8 data[16]; - u32 len; -}; - -typedef u16 SceNpMatching2AttributeId; -typedef u32 SceNpMatching2FlagAttr; - -struct SceNpMatching2IntAttr -{ - SceNpMatching2AttributeId id; - u8 padding[2]; - u32 num; -}; - - -struct SceNpMatching2BinAttr -{ - SceNpMatching2AttributeId id; - u8 padding[2]; - vm::psv::ptr ptr; - u32 size; -}; - - -struct SceNpMatching2RangeFilter -{ - u32 startIndex; - u32 max; -}; - - -struct SceNpMatching2IntSearchFilter -{ - SceNpMatching2Operator searchOperator; - u8 padding[3]; - SceNpMatching2IntAttr attr; -}; - - -struct SceNpMatching2BinSearchFilter -{ - SceNpMatching2Operator searchOperator; - u8 padding[3]; - SceNpMatching2BinAttr attr; -}; - - -struct SceNpMatching2Range -{ - u32 startIndex; - u32 total; - u32 resultCount; -}; - - -struct SceNpMatching2JoinedSessionInfo -{ - SceNpMatching2SessionType sessionType; - u8 padding1[1]; - SceNpMatching2ServerId serverId; - SceNpMatching2WorldId worldId; - SceNpMatching2LobbyId lobbyId; - SceNpMatching2RoomId roomId; - u64 joinDate; -}; - - -struct SceNpMatching2UserInfo -{ - vm::psv::ptr next; - SceNpId npId; - vm::psv::ptr userBinAttr; - u32 userBinAttrNum; - vm::psv::ptr joinedSessionInfo; - u32 joinedSessionInfoNum; -}; - -typedef u8 SceNpMatching2ServerStatus; - -struct SceNpMatching2Server -{ - SceNpMatching2ServerId serverId; - SceNpMatching2ServerStatus status; - u8 padding[1]; -}; - - -struct SceNpMatching2World -{ - vm::psv::ptr next; - SceNpMatching2WorldId worldId; - u32 numOfLobby; - u32 maxNumOfTotalLobbyMember; - u32 curNumOfTotalLobbyMember; - u32 curNumOfRoom; - u32 curNumOfTotalRoomMember; - bool withEntitlementId; - SceNpEntitlementId entitlementId; - u8 padding[3]; -}; - -typedef u16 SceNpMatching2LobbyMemberId; - -struct SceNpMatching2LobbyMemberBinAttrInternal -{ - u64 updateDate; - SceNpMatching2BinAttr data; - u8 padding[4]; -}; - - -struct SceNpMatching2LobbyMemberDataInternal -{ - vm::psv::ptr next; - SceNpId npId; - - u64 joinDate; - SceNpMatching2LobbyMemberId memberId; - u8 padding[2]; - - SceNpMatching2FlagAttr flagAttr; - - vm::psv::ptr joinedSessionInfo; - u32 joinedSessionInfoNum; - vm::psv::ptr lobbyMemberBinAttrInternal; - u32 lobbyMemberBinAttrInternalNum; -}; - - -struct SceNpMatching2LobbyMemberIdList -{ - vm::psv::ptr memberId; - u32 memberIdNum; - SceNpMatching2LobbyMemberId me; - u8 padding[6]; -}; - - -struct SceNpMatching2LobbyBinAttrInternal -{ - u64 updateDate; - SceNpMatching2LobbyMemberId updateMemberId; - u8 padding[2]; - SceNpMatching2BinAttr data; -}; - - -struct SceNpMatching2LobbyDataExternal -{ - vm::psv::ptr next; - SceNpMatching2ServerId serverId; - u8 padding1[2]; - SceNpMatching2WorldId worldId; - u8 padding2[4]; - SceNpMatching2LobbyId lobbyId; - u32 maxSlot; - u32 curMemberNum; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr lobbySearchableIntAttrExternal; - u32 lobbySearchableIntAttrExternalNum; - vm::psv::ptr lobbySearchableBinAttrExternal; - u32 lobbySearchableBinAttrExternalNum; - vm::psv::ptr lobbyBinAttrExternal; - u32 lobbyBinAttrExternalNum; - u8 padding3[4]; -}; - - -struct SceNpMatching2LobbyDataInternal -{ - SceNpMatching2ServerId serverId; - u8 padding1[2]; - SceNpMatching2WorldId worldId; - SceNpMatching2LobbyId lobbyId; - - u32 maxSlot; - SceNpMatching2LobbyMemberIdList memberIdList; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr lobbyBinAttrInternal; - u32 lobbyBinAttrInternalNum; -}; - - -union SceNpMatching2LobbyMessageDestination -{ - SceNpMatching2LobbyMemberId unicastTarget; - struct - { - vm::psv::ptr memberId; - u32 memberIdNum; - - } multicastTarget; -}; - -typedef u8 SceNpMatching2RoomGroupId; -typedef u16 SceNpMatching2RoomMemberId; -typedef u8 SceNpMatching2TeamId; -typedef u8 SceNpMatching2Role; -typedef u8 SceNpMatching2BlockKickFlag; - -struct SceNpMatching2GroupLabel -{ - u8 data[8]; -}; - -typedef u64 SceNpMatching2RoomPasswordSlotMask; -typedef u64 SceNpMatching2RoomJoinedSlotMask; - -struct SceNpMatching2RoomGroupConfig -{ - u32 slotNum; - bool withLabel; - SceNpMatching2GroupLabel label; - bool withPassword; - u8 padding[2]; -}; - - -struct SceNpMatching2RoomGroupPasswordConfig -{ - SceNpMatching2RoomGroupId groupId; - bool withPassword; - u8 padding[1]; -}; - - -struct SceNpMatching2RoomMemberBinAttrInternal -{ - u64 updateDate; - SceNpMatching2BinAttr data; - u8 padding[4]; -}; - - -struct SceNpMatching2RoomGroup -{ - SceNpMatching2RoomGroupId groupId; - bool withPassword; - bool withLabel; - u8 padding[1]; - SceNpMatching2GroupLabel label; - u32 slotNum; - u32 curGroupMemberNum; -}; - - -struct SceNpMatching2RoomMemberDataExternal -{ - vm::psv::ptr next; - SceNpId npId; - u64 joinDate; - SceNpMatching2Role role; - u8 padding[7]; -}; - - -struct SceNpMatching2RoomMemberDataInternal -{ - vm::psv::ptr next; - SceNpId npId; - - u64 joinDate; - SceNpMatching2RoomMemberId memberId; - SceNpMatching2TeamId teamId; - u8 padding1[1]; - - vm::psv::ptr roomGroup; - - SceNpMatching2NatType natType; - u8 padding2[3]; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr roomMemberBinAttrInternal; - u32 roomMemberBinAttrInternalNum; -}; - - -struct SceNpMatching2RoomMemberDataInternalList -{ - vm::psv::ptr members; - u32 membersNum; - vm::psv::ptr me; - vm::psv::ptr owner; -}; - - -struct SceNpMatching2RoomBinAttrInternal -{ - u64 updateDate; - SceNpMatching2RoomMemberId updateMemberId; - u8 padding[2]; - SceNpMatching2BinAttr data; -}; - - -struct SceNpMatching2RoomDataExternal -{ - vm::psv::ptr next; - - u16 maxSlot; - u16 curMemberNum; - - SceNpMatching2ServerId serverId; - u8 padding[2]; - SceNpMatching2WorldId worldId; - SceNpMatching2LobbyId lobbyId; - SceNpMatching2RoomId roomId; - - SceNpMatching2RoomPasswordSlotMask passwordSlotMask; - SceNpMatching2RoomJoinedSlotMask joinedSlotMask; - u16 publicSlotNum; - u16 privateSlotNum; - u16 openPublicSlotNum; - u16 openPrivateSlotNum; - - vm::psv::ptr owner; - SceNpMatching2FlagAttr flagAttr; - - vm::psv::ptr roomGroup; - u32 roomGroupNum; - vm::psv::ptr roomSearchableIntAttrExternal; - u32 roomSearchableIntAttrExternalNum; - vm::psv::ptr roomSearchableBinAttrExternal; - u32 roomSearchableBinAttrExternalNum; - vm::psv::ptr roomBinAttrExternal; - u32 roomBinAttrExternalNum; -}; - - -struct SceNpMatching2RoomDataInternal -{ - u16 maxSlot; - - SceNpMatching2ServerId serverId; - SceNpMatching2WorldId worldId; - SceNpMatching2LobbyId lobbyId; - SceNpMatching2RoomId roomId; - - SceNpMatching2RoomPasswordSlotMask passwordSlotMask; - SceNpMatching2RoomJoinedSlotMask joinedSlotMask; - u16 publicSlotNum; - u16 privateSlotNum; - u16 openPublicSlotNum; - u16 openPrivateSlotNum; - - SceNpMatching2RoomMemberDataInternalList memberList; - - vm::psv::ptr roomGroup; - u32 roomGroupNum; - - SceNpMatching2FlagAttr flagAttr; - u8 padding[4]; - vm::psv::ptr roomBinAttrInternal; - u32 roomBinAttrInternalNum; -}; - - -union SceNpMatching2RoomMessageDestination -{ - SceNpMatching2RoomMemberId unicastTarget; - struct - { - vm::psv::ptr memberId; - u32 memberIdNum; - - } multicastTarget; - SceNpMatching2TeamId multicastTargetTeamId; -}; - - -struct SceNpMatching2InvitationData -{ - vm::psv::ptr targetSession; - u32 targetSessionNum; - vm::psv::ptr optData; - u32 optDataLen; -}; - -typedef u16 SceNpMatching2Event; - -typedef vm::psv::ptr data, - vm::psv::ptr arg - )> SceNpMatching2RequestCallback; - -typedef vm::psv::ptr data, - vm::psv::ptr arg - )> SceNpMatching2LobbyEventCallback; - -typedef vm::psv::ptr data, - vm::psv::ptr arg - )> SceNpMatching2RoomEventCallback; - -typedef vm::psv::ptr data, - vm::psv::ptr arg - )> SceNpMatching2LobbyMessageCallback; - -typedef vm::psv::ptr data, - vm::psv::ptr arg - )> SceNpMatching2RoomMessageCallback; - -typedef vm::psv::ptr arg - )> SceNpMatching2SignalingCallback; - -typedef vm::psv::ptr arg - )> SceNpMatching2ContextCallback; - - -struct SceNpMatching2RequestOptParam -{ - SceNpMatching2RequestCallback cbFunc; - vm::psv::ptr cbFuncArg; - u32 timeout; - u16 appReqId; - u8 padding[2]; -}; - - -struct SceNpMatching2GetWorldInfoListRequest -{ - SceNpMatching2ServerId serverId; -}; - - - -struct SceNpMatching2GetWorldInfoListResponse -{ - vm::psv::ptr world; - u32 worldNum; -}; - -struct SceNpMatching2SetUserInfoRequest -{ - SceNpMatching2ServerId serverId; - u8 padding[2]; - vm::psv::ptr userBinAttr; - u32 userBinAttrNum; -}; - - -struct SceNpMatching2GetUserInfoListRequest -{ - SceNpMatching2ServerId serverId; - u8 padding[2]; - vm::psv::ptr npId; - u32 npIdNum; - vm::psv::ptr attrId; - u32 attrIdNum; - s32 option; -}; - - - -struct SceNpMatching2GetUserInfoListResponse -{ - vm::psv::ptr userInfo; - u32 userInfoNum; -}; - - -struct SceNpMatching2GetRoomMemberDataExternalListRequest -{ - SceNpMatching2RoomId roomId; -}; - - - -struct SceNpMatching2GetRoomMemberDataExternalListResponse -{ - vm::psv::ptr roomMemberDataExternal; - u32 roomMemberDataExternalNum; -}; - - -struct SceNpMatching2SetRoomDataExternalRequest -{ - SceNpMatching2RoomId roomId; - vm::psv::ptr roomSearchableIntAttrExternal; - u32 roomSearchableIntAttrExternalNum; - vm::psv::ptr roomSearchableBinAttrExternal; - u32 roomSearchableBinAttrExternalNum; - vm::psv::ptr roomBinAttrExternal; - u32 roomBinAttrExternalNum; -}; - - -struct SceNpMatching2GetRoomDataExternalListRequest -{ - vm::psv::ptr roomId; - u32 roomIdNum; - vm::psv::ptr attrId; - u32 attrIdNum; -}; - - - -struct SceNpMatching2GetRoomDataExternalListResponse -{ - vm::psv::ptr roomDataExternal; - u32 roomDataExternalNum; -}; - -typedef u8 SceNpMatching2SignalingType; -typedef u8 SceNpMatching2SignalingFlag; - -struct SceNpMatching2SignalingOptParam -{ - SceNpMatching2SignalingType type; - SceNpMatching2SignalingFlag flag; - SceNpMatching2RoomMemberId hubMemberId; - u8 reserved2[4]; -}; - - - -struct SceNpMatching2CreateJoinRoomRequest -{ - SceNpMatching2WorldId worldId; - u8 padding1[4]; - SceNpMatching2LobbyId lobbyId; - - u32 maxSlot; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr roomBinAttrInternal; - u32 roomBinAttrInternalNum; - vm::psv::ptr roomSearchableIntAttrExternal; - u32 roomSearchableIntAttrExternalNum; - vm::psv::ptr roomSearchableBinAttrExternal; - u32 roomSearchableBinAttrExternalNum; - vm::psv::ptr roomBinAttrExternal; - u32 roomBinAttrExternalNum; - vm::psv::ptr roomPassword; - vm::psv::ptr groupConfig; - u32 groupConfigNum; - vm::psv::ptr passwordSlotMask; - vm::psv::ptr allowedUser; - u32 allowedUserNum; - vm::psv::ptr blockedUser; - u32 blockedUserNum; - - vm::psv::ptr joinRoomGroupLabel; - vm::psv::ptr roomMemberBinAttrInternal; - u32 roomMemberBinAttrInternalNum; - SceNpMatching2TeamId teamId; - u8 padding2[3]; - - vm::psv::ptr sigOptParam; - u8 padding3[4]; -}; - - - -struct SceNpMatching2CreateJoinRoomResponse -{ - vm::psv::ptr roomDataInternal; -}; - - -struct SceNpMatching2JoinRoomRequest -{ - SceNpMatching2RoomId roomId; - vm::psv::ptr roomPassword; - vm::psv::ptr joinRoomGroupLabel; - vm::psv::ptr roomMemberBinAttrInternal; - u32 roomMemberBinAttrInternalNum; - SceNpMatching2PresenceOptionData optData; - SceNpMatching2TeamId teamId; - u8 padding[3]; - vm::psv::ptr blockedUser; - u32 blockedUserNum; -}; - - - -struct SceNpMatching2JoinRoomResponse -{ - vm::psv::ptr roomDataInternal; -}; - - -struct SceNpMatching2LeaveRoomRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2PresenceOptionData optData; - u8 padding[4]; -}; - - -struct SceNpMatching2GrantRoomOwnerRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2RoomMemberId newOwner; - u8 padding[2]; - SceNpMatching2PresenceOptionData optData; -}; - - -struct SceNpMatching2KickoutRoomMemberRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2RoomMemberId target; - SceNpMatching2BlockKickFlag blockKickFlag; - u8 padding[1]; - SceNpMatching2PresenceOptionData optData; -}; - - -struct SceNpMatching2SearchRoomRequest -{ - s32 option; - SceNpMatching2WorldId worldId; - SceNpMatching2LobbyId lobbyId; - SceNpMatching2RangeFilter rangeFilter; - SceNpMatching2FlagAttr flagFilter; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr intFilter; - u32 intFilterNum; - vm::psv::ptr binFilter; - u32 binFilterNum; - vm::psv::ptr attrId; - u32 attrIdNum; -}; - - - -struct SceNpMatching2SearchRoomResponse -{ - SceNpMatching2Range range; - vm::psv::ptr roomDataExternal; -}; - - -struct SceNpMatching2SendRoomMessageRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2CastType castType; - u8 padding[3]; - SceNpMatching2RoomMessageDestination dst; - vm::psv::ptr msg; - u32 msgLen; - s32 option; -}; - - -struct SceNpMatching2SendRoomChatMessageRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2CastType castType; - u8 padding[3]; - SceNpMatching2RoomMessageDestination dst; - vm::psv::ptr msg; - u32 msgLen; - s32 option; -}; - - - -struct SceNpMatching2SendRoomChatMessageResponse -{ - bool filtered; -}; - - -struct SceNpMatching2SetRoomDataInternalRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2FlagAttr flagFilter; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr roomBinAttrInternal; - u32 roomBinAttrInternalNum; - vm::psv::ptr passwordConfig; - u32 passwordConfigNum; - vm::psv::ptr passwordSlotMask; - vm::psv::ptr ownerPrivilegeRank; - u32 ownerPrivilegeRankNum; - u8 padding[4]; -}; - - -struct SceNpMatching2GetRoomDataInternalRequest -{ - SceNpMatching2RoomId roomId; - vm::psv::ptr attrId; - u32 attrIdNum; -}; - - - -struct SceNpMatching2GetRoomDataInternalResponse -{ - vm::psv::ptr roomDataInternal; -}; - - -struct SceNpMatching2SetRoomMemberDataInternalRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2RoomMemberId memberId; - SceNpMatching2TeamId teamId; - u8 padding[5]; - SceNpMatching2FlagAttr flagFilter; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr roomMemberBinAttrInternal; - u32 roomMemberBinAttrInternalNum; -}; - - -struct SceNpMatching2GetRoomMemberDataInternalRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2RoomMemberId memberId; - u8 padding[6]; - vm::psv::ptr attrId; - u32 attrIdNum; -}; - - - -struct SceNpMatching2GetRoomMemberDataInternalResponse -{ - vm::psv::ptr roomMemberDataInternal; -}; - - -struct SceNpMatching2SetSignalingOptParamRequest -{ - SceNpMatching2RoomId roomId; - SceNpMatching2SignalingOptParam sigOptParam; -}; - - -struct SceNpMatching2GetLobbyInfoListRequest -{ - SceNpMatching2WorldId worldId; - SceNpMatching2RangeFilter rangeFilter; - vm::psv::ptr attrId; - u32 attrIdNum; -}; - - - -struct SceNpMatching2GetLobbyInfoListResponse -{ - SceNpMatching2Range range; - vm::psv::ptr lobbyDataExternal; -}; - - -struct SceNpMatching2JoinLobbyRequest -{ - SceNpMatching2LobbyId lobbyId; - vm::psv::ptr joinedSessionInfo; - u32 joinedSessionInfoNum; - vm::psv::ptr lobbyMemberBinAttrInternal; - u32 lobbyMemberBinAttrInternalNum; - SceNpMatching2PresenceOptionData optData; - u8 padding[4]; -}; - - - -struct SceNpMatching2JoinLobbyResponse -{ - vm::psv::ptr lobbyDataInternal; -}; - - -struct SceNpMatching2LeaveLobbyRequest -{ - SceNpMatching2LobbyId lobbyId; - SceNpMatching2PresenceOptionData optData; - u8 padding[4]; -}; - - -struct SceNpMatching2SetLobbyMemberDataInternalRequest -{ - SceNpMatching2LobbyId lobbyId; - SceNpMatching2LobbyMemberId memberId; - u8 padding1[2]; - SceNpMatching2FlagAttr flagFilter; - SceNpMatching2FlagAttr flagAttr; - vm::psv::ptr joinedSessionInfo; - u32 joinedSessionInfoNum; - vm::psv::ptr lobbyMemberBinAttrInternal; - u32 lobbyMemberBinAttrInternalNum; - u8 padding2[4]; -}; - - -struct SceNpMatching2GetLobbyMemberDataInternalRequest -{ - SceNpMatching2LobbyId lobbyId; - SceNpMatching2LobbyMemberId memberId; - u8 padding[6]; - vm::psv::ptr attrId; - u32 attrIdNum; -}; - - - -struct SceNpMatching2GetLobbyMemberDataInternalResponse -{ - vm::psv::ptr lobbyMemberDataInternal; -}; - - - -struct SceNpMatching2GetLobbyMemberDataInternalListRequest -{ - SceNpMatching2LobbyId lobbyId; - vm::psv::ptr memberId; - u32 memberIdNum; - vm::psv::ptr attrId; - u32 attrIdNum; - bool extendedData; - u8 padding[7]; -}; - - - -struct SceNpMatching2GetLobbyMemberDataInternalListResponse -{ - vm::psv::ptr lobbyMemberDataInternal; - u32 lobbyMemberDataInternalNum; -}; - - -struct SceNpMatching2SendLobbyChatMessageRequest -{ - SceNpMatching2LobbyId lobbyId; - SceNpMatching2CastType castType; - u8 padding[3]; - SceNpMatching2LobbyMessageDestination dst; - vm::psv::ptr msg; - u32 msgLen; - s32 option; -}; - - - -struct SceNpMatching2SendLobbyChatMessageResponse -{ - bool filtered; -}; - - -struct SceNpMatching2SendLobbyInvitationRequest -{ - SceNpMatching2LobbyId lobbyId; - SceNpMatching2CastType castType; - u8 padding[3]; - SceNpMatching2LobbyMessageDestination dst; - SceNpMatching2InvitationData invitationData; - s32 option; -}; - - -struct SceNpMatching2RoomMemberUpdateInfo -{ - vm::psv::ptr roomMemberDataInternal; - SceNpMatching2EventCause eventCause; - u8 padding[3]; - SceNpMatching2PresenceOptionData optData; -}; - - -struct SceNpMatching2RoomOwnerUpdateInfo -{ - SceNpMatching2RoomMemberId prevOwner; - SceNpMatching2RoomMemberId newOwner; - SceNpMatching2EventCause eventCause; - u8 padding[3]; - vm::psv::ptr roomPassword; - SceNpMatching2PresenceOptionData optData; -}; - - -struct SceNpMatching2RoomUpdateInfo -{ - SceNpMatching2EventCause eventCause; - u8 padding[3]; - s32 errorCode; - SceNpMatching2PresenceOptionData optData; -}; - - -struct SceNpMatching2RoomDataInternalUpdateInfo -{ - vm::psv::ptr newRoomDataInternal; - vm::psv::ptr newFlagAttr; - vm::psv::ptr prevFlagAttr; - vm::psv::ptr newRoomPasswordSlotMask; - vm::psv::ptr prevRoomPasswordSlotMask; - vm::psv::ptr *newRoomGroup; - u32 newRoomGroupNum; - vm::psv::ptr *newRoomBinAttrInternal; - u32 newRoomBinAttrInternalNum; -}; - - -struct SceNpMatching2RoomMemberDataInternalUpdateInfo -{ - vm::psv::ptr newRoomMemberDataInternal; - vm::psv::ptr newFlagAttr; - vm::psv::ptr prevFlagAttr; - vm::psv::ptr newTeamId; - vm::psv::ptr *newRoomMemberBinAttrInternal; - u32 newRoomMemberBinAttrInternalNum; -}; - - -struct SceNpMatching2SignalingOptParamUpdateInfo -{ - SceNpMatching2SignalingOptParam newSignalingOptParam; -}; - - -struct SceNpMatching2RoomMessageInfo -{ - bool filtered; - SceNpMatching2CastType castType; - u8 padding[2]; - vm::psv::ptr dst; - vm::psv::ptr srcMember; - vm::psv::ptr msg; - u32 msgLen; -}; - - -struct SceNpMatching2LobbyMemberUpdateInfo -{ - vm::psv::ptr lobbyMemberDataInternal; - SceNpMatching2EventCause eventCause; - u8 padding[3]; - SceNpMatching2PresenceOptionData optData; -}; - - -struct SceNpMatching2LobbyUpdateInfo -{ - SceNpMatching2EventCause eventCause; - u8 padding[3]; - s32 errorCode; -}; - - -struct SceNpMatching2LobbyMemberDataInternalUpdateInfo -{ - SceNpMatching2LobbyMemberId memberId; - u8 padding[2]; - SceNpId npId; - SceNpMatching2FlagAttr flagFilter; - SceNpMatching2FlagAttr newFlagAttr; - vm::psv::ptr newJoinedSessionInfo; - u32 newJoinedSessionInfoNum; - vm::psv::ptr newLobbyMemberBinAttrInternal; - u32 newLobbyMemberBinAttrInternalNum; -}; - - -struct SceNpMatching2LobbyMessageInfo -{ - bool filtered; - SceNpMatching2CastType castType; - u8 padding[2]; - vm::psv::ptr dst; - vm::psv::ptr srcMember; - vm::psv::ptr msg; - u32 msgLen; -}; - - -struct SceNpMatching2LobbyInvitationInfo -{ - SceNpMatching2CastType castType; - u8 padding[3]; - vm::psv::ptr dst; - vm::psv::ptr srcMember; - SceNpMatching2InvitationData invitationData; -}; - -union SceNpMatching2SignalingConnectionInfo -{ - u32 rtt; - u32 bandwidth; - SceNpId npId; - struct - { - SceNetInAddr addr; - u16 port; - u8 padding[2]; - - } address; - u32 packetLoss; -}; - -struct SceNpMatching2SignalingNetInfo -{ - u32 size; - SceNetInAddr localAddr; - SceNetInAddr mappedAddr; - s32 natStatus; -}; +#include "sceNpMatching.h" // Functions -s32 sceNpMatching2Init( - const u32 poolSize, - const s32 threadPriority, - const s32 cpuAffinityMask, - const u32 threadStackSize) +s32 sceNpMatching2Init(u32 poolSize, s32 threadPriority, s32 cpuAffinityMask, u32 threadStackSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2Term() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2CreateContext( - vm::psv::ptr npId, - vm::psv::ptr commId, - vm::psv::ptr passPhrase, - vm::psv::ptr ctxId) + vm::cptr npId, + vm::cptr commId, + vm::cptr passPhrase, + vm::ptr ctxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2DestroyContext(const SceNpMatching2ContextId ctxId) +s32 sceNpMatching2DestroyContext(u16 ctxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2ContextStart(const SceNpMatching2ContextId ctxId, const u64 timeout) +s32 sceNpMatching2ContextStart(u16 ctxId, u64 timeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2AbortContextStart(const SceNpMatching2ContextId ctxId) +s32 sceNpMatching2AbortContextStart(u16 ctxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2ContextStop(const SceNpMatching2ContextId ctxId) +s32 sceNpMatching2ContextStop(u16 ctxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2SetDefaultRequestOptParam(const SceNpMatching2ContextId ctxId, vm::psv::ptr optParam) +s32 sceNpMatching2SetDefaultRequestOptParam(u16 ctxId, vm::cptr optParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2RegisterRoomEventCallback(const SceNpMatching2ContextId ctxId, SceNpMatching2RoomEventCallback cbFunc, vm::psv::ptr cbFuncArg) +s32 sceNpMatching2RegisterRoomEventCallback(u16 ctxId, vm::ptr cbFunc, vm::ptr cbFuncArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2RegisterRoomMessageCallback(const SceNpMatching2ContextId ctxId, SceNpMatching2RoomMessageCallback cbFunc, vm::psv::ptr cbFuncArg) +s32 sceNpMatching2RegisterRoomMessageCallback(u16 ctxId, vm::ptr cbFunc, vm::ptr cbFuncArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2RegisterSignalingCallback(const SceNpMatching2ContextId ctxId, SceNpMatching2SignalingCallback cbFunc, vm::psv::ptr cbFuncArg) +s32 sceNpMatching2RegisterSignalingCallback(u16 ctxId, vm::ptr cbFunc, vm::ptr cbFuncArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2RegisterContextCallback(SceNpMatching2ContextCallback cbFunc, vm::psv::ptr cbFuncArg) +s32 sceNpMatching2RegisterContextCallback(vm::ptr cbFunc, vm::ptr cbFuncArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2AbortRequest(const SceNpMatching2ContextId ctxId, const SceNpMatching2RequestId reqId) +s32 sceNpMatching2AbortRequest(u16 ctxId, u32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2GetMemoryInfo(vm::psv::ptr memInfo) +s32 sceNpMatching2GetMemoryInfo(vm::ptr memInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2GetServerLocal(const SceNpMatching2ContextId ctxId, vm::psv::ptr server) +s32 sceNpMatching2GetServerLocal(u16 ctxId, vm::ptr server) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2GetWorldInfoList( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2CreateJoinRoom( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SearchRoom( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2JoinRoom( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2LeaveRoom( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2GetSignalingOptParamLocal( - const SceNpMatching2ContextId ctxId, - const SceNpMatching2RoomId roomId, - vm::psv::ptr signalingOptParam) + u16 ctxId, + u64 roomId, + vm::ptr signalingOptParam) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SetRoomDataExternal( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2KickoutRoomMember( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SendRoomChatMessage( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SendRoomMessage( - const SceNpMatching2ContextId ctxId, - vm::psv::ptr reqParam, - vm::psv::ptr optParam, - vm::psv::ptr assignedReqId) + u16 ctxId, + vm::cptr reqParam, + vm::cptr optParam, + vm::ptr assignedReqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SignalingGetConnectionStatus( - SceNpMatching2ContextId ctxId, - SceNpMatching2RoomId roomId, - SceNpMatching2RoomMemberId memberId, - vm::psv::ptr connStatus, - vm::psv::ptr peerAddr, - vm::psv::ptr peerPort) + u16 ctxId, + u64 roomId, + u16 memberId, + vm::ptr connStatus, + vm::ptr peerAddr, + vm::ptr peerPort) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SignalingGetConnectionInfo( - SceNpMatching2ContextId ctxId, - SceNpMatching2RoomId roomId, - SceNpMatching2RoomMemberId memberId, + u16 ctxId, + u64 roomId, + u16 memberId, s32 code, - vm::psv::ptr info) + vm::ptr info) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpMatching2SignalingGetLocalNetInfo(vm::psv::ptr netinfo) +s32 sceNpMatching2SignalingGetLocalNetInfo(vm::ptr netinfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SignalingGetPeerNetInfo( - SceNpMatching2ContextId ctxId, - SceNpMatching2RoomId roomId, - SceNpMatching2RoomMemberId memberId, - vm::psv::ptr reqId) + u16 ctxId, + u64 roomId, + u16 memberId, + vm::ptr reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SignalingCancelPeerNetInfo( - SceNpMatching2ContextId ctxId, - SceNpMatching2SignalingRequestId reqId) + u16 ctxId, + u32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpMatching2SignalingGetPeerNetInfoResult( - SceNpMatching2ContextId ctxId, - SceNpMatching2SignalingRequestId reqId, - vm::psv::ptr netinfo) + u16 ctxId, + u32 reqId, + vm::ptr netinfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNpMatching, #name, name) @@ -1309,6 +231,7 @@ psv_log_base sceNpMatching("SceNpMatching2", []() sceNpMatching.on_load = nullptr; sceNpMatching.on_unload = nullptr; sceNpMatching.on_stop = nullptr; + sceNpMatching.on_error = nullptr; REG_FUNC(0xEBB1FE74, sceNpMatching2Init); REG_FUNC(0x0124641C, sceNpMatching2Term); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpMatching.h b/rpcs3/Emu/ARMv7/Modules/sceNpMatching.h new file mode 100644 index 0000000000..75b2053649 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNpMatching.h @@ -0,0 +1,989 @@ +#pragma once + +#include "sceNet.h" +#include "sceNpCommon.h" + +struct SceNpMatching2MemoryInfo +{ + le_t totalMemSize; + le_t curMemUsage; + le_t maxMemUsage; + u8 reserved[12]; +}; + +struct SceNpMatching2SessionPassword +{ + u8 data[8]; +}; + +struct SceNpMatching2PresenceOptionData +{ + u8 data[16]; + le_t len; +}; + +struct SceNpMatching2IntAttr +{ + le_t id; + u8 padding[2]; + le_t num; +}; + + +struct SceNpMatching2BinAttr +{ + le_t id; + u8 padding[2]; + vm::lptr ptr; + le_t size; +}; + + +struct SceNpMatching2RangeFilter +{ + le_t startIndex; + le_t max; +}; + + +struct SceNpMatching2IntSearchFilter +{ + u8 searchOperator; + u8 padding[3]; + SceNpMatching2IntAttr attr; +}; + + +struct SceNpMatching2BinSearchFilter +{ + u8 searchOperator; + u8 padding[3]; + SceNpMatching2BinAttr attr; +}; + + +struct SceNpMatching2Range +{ + le_t startIndex; + le_t total; + le_t resultCount; +}; + + +struct SceNpMatching2JoinedSessionInfo +{ + u8 sessionType; + u8 padding1[1]; + le_t serverId; + le_t worldId; + le_t lobbyId; + le_t roomId; + le_t joinDate; +}; + + +struct SceNpMatching2UserInfo +{ + vm::lptr next; + SceNpId npId; + vm::lptr userBinAttr; + le_t userBinAttrNum; + vm::lptr joinedSessionInfo; + le_t joinedSessionInfoNum; +}; + +struct SceNpMatching2Server +{ + le_t serverId; + u8 status; + u8 padding[1]; +}; + + +struct SceNpMatching2World +{ + vm::lptr next; + le_t worldId; + le_t numOfLobby; + le_t maxNumOfTotalLobbyMember; + le_t curNumOfTotalLobbyMember; + le_t curNumOfRoom; + le_t curNumOfTotalRoomMember; + bool withEntitlementId; + SceNpEntitlementId entitlementId; + u8 padding[3]; +}; + +struct SceNpMatching2LobbyMemberBinAttrInternal +{ + le_t updateDate; + SceNpMatching2BinAttr data; + u8 padding[4]; +}; + + +struct SceNpMatching2LobbyMemberDataInternal +{ + vm::lptr next; + SceNpId npId; + + le_t joinDate; + le_t memberId; + u8 padding[2]; + + le_t flagAttr; + + vm::lptr joinedSessionInfo; + le_t joinedSessionInfoNum; + vm::lptr lobbyMemberBinAttrInternal; + le_t lobbyMemberBinAttrInternalNum; +}; + + +struct SceNpMatching2LobbyMemberIdList +{ + vm::lptr memberId; + le_t memberIdNum; + le_t me; + u8 padding[6]; +}; + + +struct SceNpMatching2LobbyBinAttrInternal +{ + le_t updateDate; + le_t updateMemberId; + u8 padding[2]; + SceNpMatching2BinAttr data; +}; + + +struct SceNpMatching2LobbyDataExternal +{ + vm::lptr next; + le_t serverId; + u8 padding1[2]; + le_t worldId; + u8 padding2[4]; + le_t lobbyId; + le_t maxSlot; + le_t curMemberNum; + le_t flagAttr; + vm::lptr lobbySearchableIntAttrExternal; + le_t lobbySearchableIntAttrExternalNum; + vm::lptr lobbySearchableBinAttrExternal; + le_t lobbySearchableBinAttrExternalNum; + vm::lptr lobbyBinAttrExternal; + le_t lobbyBinAttrExternalNum; + u8 padding3[4]; +}; + + +struct SceNpMatching2LobbyDataInternal +{ + le_t serverId; + u8 padding1[2]; + le_t worldId; + le_t lobbyId; + + le_t maxSlot; + SceNpMatching2LobbyMemberIdList memberIdList; + le_t flagAttr; + vm::lptr lobbyBinAttrInternal; + le_t lobbyBinAttrInternalNum; +}; + + +union SceNpMatching2LobbyMessageDestination +{ + le_t unicastTarget; + + struct + { + vm::lptr memberId; + le_t memberIdNum; + } + multicastTarget; +}; + +struct SceNpMatching2GroupLabel +{ + u8 data[8]; +}; + +struct SceNpMatching2RoomGroupConfig +{ + le_t slotNum; + bool withLabel; + SceNpMatching2GroupLabel label; + bool withPassword; + u8 padding[2]; +}; + + +struct SceNpMatching2RoomGroupPasswordConfig +{ + u8 groupId; + bool withPassword; + u8 padding[1]; +}; + + +struct SceNpMatching2RoomMemberBinAttrInternal +{ + le_t updateDate; + SceNpMatching2BinAttr data; + u8 padding[4]; +}; + + +struct SceNpMatching2RoomGroup +{ + u8 groupId; + bool withPassword; + bool withLabel; + u8 padding[1]; + SceNpMatching2GroupLabel label; + le_t slotNum; + le_t curGroupMemberNum; +}; + + +struct SceNpMatching2RoomMemberDataExternal +{ + vm::lptr next; + SceNpId npId; + le_t joinDate; + u8 role; + u8 padding[7]; +}; + + +struct SceNpMatching2RoomMemberDataInternal +{ + vm::lptr next; + SceNpId npId; + + le_t joinDate; + le_t memberId; + u8 teamId; + u8 padding1[1]; + + vm::lptr roomGroup; + + u8 natType; + u8 padding2[3]; + le_t flagAttr; + vm::lptr roomMemberBinAttrInternal; + le_t roomMemberBinAttrInternalNum; +}; + + +struct SceNpMatching2RoomMemberDataInternalList +{ + vm::lptr members; + le_t membersNum; + vm::lptr me; + vm::lptr owner; +}; + + +struct SceNpMatching2RoomBinAttrInternal +{ + le_t updateDate; + le_t updateMemberId; + u8 padding[2]; + SceNpMatching2BinAttr data; +}; + + +struct SceNpMatching2RoomDataExternal +{ + vm::lptr next; + + le_t maxSlot; + le_t curMemberNum; + + le_t serverId; + u8 padding[2]; + le_t worldId; + le_t lobbyId; + le_t roomId; + + le_t passwordSlotMask; + le_t joinedSlotMask; + le_t publicSlotNum; + le_t privateSlotNum; + le_t openPublicSlotNum; + le_t openPrivateSlotNum; + + vm::lptr owner; + le_t flagAttr; + + vm::lptr roomGroup; + le_t roomGroupNum; + vm::lptr roomSearchableIntAttrExternal; + le_t roomSearchableIntAttrExternalNum; + vm::lptr roomSearchableBinAttrExternal; + le_t roomSearchableBinAttrExternalNum; + vm::lptr roomBinAttrExternal; + le_t roomBinAttrExternalNum; +}; + + +struct SceNpMatching2RoomDataInternal +{ + le_t maxSlot; + + le_t serverId; + le_t worldId; + le_t lobbyId; + le_t roomId; + + le_t passwordSlotMask; + le_t joinedSlotMask; + le_t publicSlotNum; + le_t privateSlotNum; + le_t openPublicSlotNum; + le_t openPrivateSlotNum; + + SceNpMatching2RoomMemberDataInternalList memberList; + + vm::lptr roomGroup; + le_t roomGroupNum; + + le_t flagAttr; + u8 padding[4]; + vm::lptr roomBinAttrInternal; + le_t roomBinAttrInternalNum; +}; + + +union SceNpMatching2RoomMessageDestination +{ + le_t unicastTarget; + + struct + { + vm::lptr memberId; + le_t memberIdNum; + } + multicastTarget; + + u8 multicastTargetTeamId; +}; + + +struct SceNpMatching2InvitationData +{ + vm::lptr targetSession; + le_t targetSessionNum; + vm::lptr optData; + le_t optDataLen; +}; + +using SceNpMatching2RequestCallback = func_def data, vm::ptr arg)>; +using SceNpMatching2LobbyEventCallback = func_def data, vm::ptr arg)>; +using SceNpMatching2RoomEventCallback = func_def data, vm::ptr arg)>; +using SceNpMatching2LobbyMessageCallback = func_def data, vm::ptr arg)>; +using SceNpMatching2RoomMessageCallback = func_def data, vm::ptr arg)>; +using SceNpMatching2SignalingCallback = func_def arg)>; +using SceNpMatching2ContextCallback = func_def arg)>; + +struct SceNpMatching2RequestOptParam +{ + vm::lptr cbFunc; + vm::lptr cbFuncArg; + le_t timeout; + le_t appReqId; + u8 padding[2]; +}; + + +struct SceNpMatching2GetWorldInfoListRequest +{ + le_t serverId; +}; + + + +struct SceNpMatching2GetWorldInfoListResponse +{ + vm::lptr world; + le_t worldNum; +}; + +struct SceNpMatching2SetUserInfoRequest +{ + le_t serverId; + u8 padding[2]; + vm::lptr userBinAttr; + le_t userBinAttrNum; +}; + + +struct SceNpMatching2GetUserInfoListRequest +{ + le_t serverId; + u8 padding[2]; + vm::lptr npId; + le_t npIdNum; + vm::lptr attrId; + le_t attrIdNum; + le_t option; +}; + + + +struct SceNpMatching2GetUserInfoListResponse +{ + vm::lptr userInfo; + le_t userInfoNum; +}; + + +struct SceNpMatching2GetRoomMemberDataExternalListRequest +{ + le_t roomId; +}; + + + +struct SceNpMatching2GetRoomMemberDataExternalListResponse +{ + vm::lptr roomMemberDataExternal; + le_t roomMemberDataExternalNum; +}; + + +struct SceNpMatching2SetRoomDataExternalRequest +{ + le_t roomId; + vm::lptr roomSearchableIntAttrExternal; + le_t roomSearchableIntAttrExternalNum; + vm::lptr roomSearchableBinAttrExternal; + le_t roomSearchableBinAttrExternalNum; + vm::lptr roomBinAttrExternal; + le_t roomBinAttrExternalNum; +}; + + +struct SceNpMatching2GetRoomDataExternalListRequest +{ + vm::lptr roomId; + le_t roomIdNum; + vm::lcptr attrId; + le_t attrIdNum; +}; + + + +struct SceNpMatching2GetRoomDataExternalListResponse +{ + vm::lptr roomDataExternal; + le_t roomDataExternalNum; +}; + +struct SceNpMatching2SignalingOptParam +{ + u8 type; + u8 flag; + le_t hubMemberId; + u8 reserved2[4]; +}; + + + +struct SceNpMatching2CreateJoinRoomRequest +{ + le_t worldId; + u8 padding1[4]; + le_t lobbyId; + + le_t maxSlot; + le_t flagAttr; + vm::lptr roomBinAttrInternal; + le_t roomBinAttrInternalNum; + vm::lptr roomSearchableIntAttrExternal; + le_t roomSearchableIntAttrExternalNum; + vm::lptr roomSearchableBinAttrExternal; + le_t roomSearchableBinAttrExternalNum; + vm::lptr roomBinAttrExternal; + le_t roomBinAttrExternalNum; + vm::lptr roomPassword; + vm::lptr groupConfig; + le_t groupConfigNum; + vm::lptr passwordSlotMask; + vm::lptr allowedUser; + le_t allowedUserNum; + vm::lptr blockedUser; + le_t blockedUserNum; + + vm::lptr joinRoomGroupLabel; + vm::lptr roomMemberBinAttrInternal; + le_t roomMemberBinAttrInternalNum; + u8 teamId; + u8 padding2[3]; + + vm::lptr sigOptParam; + u8 padding3[4]; +}; + + + +struct SceNpMatching2CreateJoinRoomResponse +{ + vm::lptr roomDataInternal; +}; + + +struct SceNpMatching2JoinRoomRequest +{ + le_t roomId; + vm::lptr roomPassword; + vm::lptr joinRoomGroupLabel; + vm::lptr roomMemberBinAttrInternal; + le_t roomMemberBinAttrInternalNum; + SceNpMatching2PresenceOptionData optData; + u8 teamId; + u8 padding[3]; + vm::lptr blockedUser; + le_t blockedUserNum; +}; + + + +struct SceNpMatching2JoinRoomResponse +{ + vm::lptr roomDataInternal; +}; + + +struct SceNpMatching2LeaveRoomRequest +{ + le_t roomId; + SceNpMatching2PresenceOptionData optData; + u8 padding[4]; +}; + + +struct SceNpMatching2GrantRoomOwnerRequest +{ + le_t roomId; + le_t newOwner; + u8 padding[2]; + SceNpMatching2PresenceOptionData optData; +}; + + +struct SceNpMatching2KickoutRoomMemberRequest +{ + le_t roomId; + le_t target; + u8 blockKickFlag; + u8 padding[1]; + SceNpMatching2PresenceOptionData optData; +}; + + +struct SceNpMatching2SearchRoomRequest +{ + le_t option; + le_t worldId; + le_t lobbyId; + SceNpMatching2RangeFilter rangeFilter; + le_t flagFilter; + le_t flagAttr; + vm::lptr intFilter; + le_t intFilterNum; + vm::lptr binFilter; + le_t binFilterNum; + vm::lptr attrId; + le_t attrIdNum; +}; + + + +struct SceNpMatching2SearchRoomResponse +{ + SceNpMatching2Range range; + vm::lptr roomDataExternal; +}; + + +struct SceNpMatching2SendRoomMessageRequest +{ + le_t roomId; + u8 castType; + u8 padding[3]; + SceNpMatching2RoomMessageDestination dst; + vm::lcptr msg; + le_t msgLen; + le_t option; +}; + + +struct SceNpMatching2SendRoomChatMessageRequest +{ + le_t roomId; + u8 castType; + u8 padding[3]; + SceNpMatching2RoomMessageDestination dst; + vm::lcptr msg; + le_t msgLen; + le_t option; +}; + + + +struct SceNpMatching2SendRoomChatMessageResponse +{ + bool filtered; +}; + + +struct SceNpMatching2SetRoomDataInternalRequest +{ + le_t roomId; + le_t flagFilter; + le_t flagAttr; + vm::lptr roomBinAttrInternal; + le_t roomBinAttrInternalNum; + vm::lptr passwordConfig; + le_t passwordConfigNum; + vm::lptr passwordSlotMask; + vm::lptr ownerPrivilegeRank; + le_t ownerPrivilegeRankNum; + u8 padding[4]; +}; + + +struct SceNpMatching2GetRoomDataInternalRequest +{ + le_t roomId; + vm::lcptr attrId; + le_t attrIdNum; +}; + + + +struct SceNpMatching2GetRoomDataInternalResponse +{ + vm::lptr roomDataInternal; +}; + + +struct SceNpMatching2SetRoomMemberDataInternalRequest +{ + le_t roomId; + le_t memberId; + u8 teamId; + u8 padding[5]; + le_t flagFilter; + le_t flagAttr; + vm::lptr roomMemberBinAttrInternal; + le_t roomMemberBinAttrInternalNum; +}; + + +struct SceNpMatching2GetRoomMemberDataInternalRequest +{ + le_t roomId; + le_t memberId; + u8 padding[6]; + vm::lcptr attrId; + le_t attrIdNum; +}; + + + +struct SceNpMatching2GetRoomMemberDataInternalResponse +{ + vm::lptr roomMemberDataInternal; +}; + + +struct SceNpMatching2SetSignalingOptParamRequest +{ + le_t roomId; + SceNpMatching2SignalingOptParam sigOptParam; +}; + + +struct SceNpMatching2GetLobbyInfoListRequest +{ + le_t worldId; + SceNpMatching2RangeFilter rangeFilter; + vm::lptr attrId; + le_t attrIdNum; +}; + + + +struct SceNpMatching2GetLobbyInfoListResponse +{ + SceNpMatching2Range range; + vm::lptr lobbyDataExternal; +}; + + +struct SceNpMatching2JoinLobbyRequest +{ + le_t lobbyId; + vm::lptr joinedSessionInfo; + le_t joinedSessionInfoNum; + vm::lptr lobbyMemberBinAttrInternal; + le_t lobbyMemberBinAttrInternalNum; + SceNpMatching2PresenceOptionData optData; + u8 padding[4]; +}; + + + +struct SceNpMatching2JoinLobbyResponse +{ + vm::lptr lobbyDataInternal; +}; + + +struct SceNpMatching2LeaveLobbyRequest +{ + le_t lobbyId; + SceNpMatching2PresenceOptionData optData; + u8 padding[4]; +}; + + +struct SceNpMatching2SetLobbyMemberDataInternalRequest +{ + le_t lobbyId; + le_t memberId; + u8 padding1[2]; + le_t flagFilter; + le_t flagAttr; + vm::lptr joinedSessionInfo; + le_t joinedSessionInfoNum; + vm::lptr lobbyMemberBinAttrInternal; + le_t lobbyMemberBinAttrInternalNum; + u8 padding2[4]; +}; + + +struct SceNpMatching2GetLobbyMemberDataInternalRequest +{ + le_t lobbyId; + le_t memberId; + u8 padding[6]; + vm::lcptr attrId; + le_t attrIdNum; +}; + + + +struct SceNpMatching2GetLobbyMemberDataInternalResponse +{ + vm::lptr lobbyMemberDataInternal; +}; + + + +struct SceNpMatching2GetLobbyMemberDataInternalListRequest +{ + le_t lobbyId; + vm::lptr memberId; + le_t memberIdNum; + vm::lcptr attrId; + le_t attrIdNum; + bool extendedData; + u8 padding[7]; +}; + + + +struct SceNpMatching2GetLobbyMemberDataInternalListResponse +{ + vm::lptr lobbyMemberDataInternal; + le_t lobbyMemberDataInternalNum; +}; + + +struct SceNpMatching2SendLobbyChatMessageRequest +{ + le_t lobbyId; + u8 castType; + u8 padding[3]; + SceNpMatching2LobbyMessageDestination dst; + vm::lcptr msg; + le_t msgLen; + le_t option; +}; + + + +struct SceNpMatching2SendLobbyChatMessageResponse +{ + bool filtered; +}; + + +struct SceNpMatching2SendLobbyInvitationRequest +{ + le_t lobbyId; + u8 castType; + u8 padding[3]; + SceNpMatching2LobbyMessageDestination dst; + SceNpMatching2InvitationData invitationData; + le_t option; +}; + + +struct SceNpMatching2RoomMemberUpdateInfo +{ + vm::lptr roomMemberDataInternal; + u8 eventCause; + u8 padding[3]; + SceNpMatching2PresenceOptionData optData; +}; + + +struct SceNpMatching2RoomOwnerUpdateInfo +{ + le_t prevOwner; + le_t newOwner; + u8 eventCause; + u8 padding[3]; + vm::lptr roomPassword; + SceNpMatching2PresenceOptionData optData; +}; + + +struct SceNpMatching2RoomUpdateInfo +{ + u8 eventCause; + u8 padding[3]; + le_t errorCode; + SceNpMatching2PresenceOptionData optData; +}; + + +struct SceNpMatching2RoomDataInternalUpdateInfo +{ + vm::lptr newRoomDataInternal; + vm::lptr newFlagAttr; + vm::lptr prevFlagAttr; + vm::lptr newRoomPasswordSlotMask; + vm::lptr prevRoomPasswordSlotMask; + vm::lptr *newRoomGroup; + le_t newRoomGroupNum; + vm::lptr *newRoomBinAttrInternal; + le_t newRoomBinAttrInternalNum; +}; + + +struct SceNpMatching2RoomMemberDataInternalUpdateInfo +{ + vm::lptr newRoomMemberDataInternal; + vm::lptr newFlagAttr; + vm::lptr prevFlagAttr; + vm::lptr newTeamId; + vm::lptr *newRoomMemberBinAttrInternal; + le_t newRoomMemberBinAttrInternalNum; +}; + + +struct SceNpMatching2SignalingOptParamUpdateInfo +{ + SceNpMatching2SignalingOptParam newSignalingOptParam; +}; + + +struct SceNpMatching2RoomMessageInfo +{ + bool filtered; + u8 castType; + u8 padding[2]; + vm::lptr dst; + vm::lptr srcMember; + vm::lcptr msg; + le_t msgLen; +}; + + +struct SceNpMatching2LobbyMemberUpdateInfo +{ + vm::lptr lobbyMemberDataInternal; + u8 eventCause; + u8 padding[3]; + SceNpMatching2PresenceOptionData optData; +}; + + +struct SceNpMatching2LobbyUpdateInfo +{ + u8 eventCause; + u8 padding[3]; + le_t errorCode; +}; + + +struct SceNpMatching2LobbyMemberDataInternalUpdateInfo +{ + le_t memberId; + u8 padding[2]; + SceNpId npId; + le_t flagFilter; + le_t newFlagAttr; + vm::lptr newJoinedSessionInfo; + le_t newJoinedSessionInfoNum; + vm::lptr newLobbyMemberBinAttrInternal; + le_t newLobbyMemberBinAttrInternalNum; +}; + + +struct SceNpMatching2LobbyMessageInfo +{ + bool filtered; + u8 castType; + u8 padding[2]; + vm::lptr dst; + vm::lptr srcMember; + vm::lcptr msg; + le_t msgLen; +}; + + +struct SceNpMatching2LobbyInvitationInfo +{ + u8 castType; + u8 padding[3]; + vm::lptr dst; + vm::lptr srcMember; + SceNpMatching2InvitationData invitationData; +}; + +union SceNpMatching2SignalingConnectionInfo +{ + le_t rtt; + le_t bandwidth; + SceNpId npId; + + struct + { + SceNetInAddr addr; + le_t port; + u8 padding[2]; + } + address; + + le_t packetLoss; +}; + +struct SceNpMatching2SignalingNetInfo +{ + le_t size; + SceNetInAddr localAddr; + SceNetInAddr mappedAddr; + le_t natStatus; +}; + +extern psv_log_base sceNpMatching; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp index f093ab8b31..4d3734e517 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpScore.cpp @@ -2,335 +2,278 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceNpCommon.h" +#include "sceNpScore.h" -extern psv_log_base sceNpScore; - -typedef u32 SceNpScoreBoardId; -typedef s64 SceNpScoreValue; -typedef u32 SceNpScoreRankNumber; -typedef s32 SceNpScorePcId; - -struct SceNpScoreGameInfo +s32 sceNpScoreInit(s32 threadPriority, s32 cpuAffinityMask, vm::ptr option) { - u32 infoSize; - u8 pad[4]; - u8 data[192]; -}; - -struct SceNpScoreComment -{ - char utf8Comment[64]; -}; - -struct SceNpScoreRankData -{ - SceNpId npId; - u8 reserved[49]; - u8 pad0[3]; - SceNpScorePcId pcId; - SceNpScoreRankNumber serialRank; - SceNpScoreRankNumber rank; - SceNpScoreRankNumber highestRank; - s32 hasGameData; - u8 pad1[4]; - SceNpScoreValue scoreValue; - u64 recordDate; -}; - -struct SceNpScorePlayerRankData -{ - s32 hasData; - u8 pad0[4]; - SceNpScoreRankData rankData; -}; - -struct SceNpScoreBoardInfo -{ - u32 rankLimit; - u32 updateMode; - u32 sortMode; - u32 uploadNumLimit; - u32 uploadSizeLimit; -}; - -struct SceNpScoreNpIdPcId -{ - SceNpId npId; - SceNpScorePcId pcId; - u8 pad[4]; -}; - -s32 sceNpScoreInit(s32 threadPriority, s32 cpuAffinityMask, vm::psv::ptr option) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreTerm(ARMv7Context&) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreCreateTitleCtx(vm::psv::ptr titleId, vm::psv::ptr passphrase, vm::psv::ptr selfNpId) +s32 sceNpScoreCreateTitleCtx(vm::cptr titleId, vm::cptr passphrase, vm::cptr selfNpId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreDeleteTitleCtx(s32 titleCtxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreCreateRequest(s32 titleCtxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreDeleteRequest(s32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreAbortRequest(s32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreSetTimeout(s32 id, s32 resolveRetry, s32 resolveTimeout, s32 connTimeout, s32 sendTimeout, s32 recvTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreSetPlayerCharacterId(s32 id, SceNpScorePcId pcId) +s32 sceNpScoreSetPlayerCharacterId(s32 id, s32 pcId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreGetBoardInfo(s32 reqId, SceNpScoreBoardId boardId, vm::psv::ptr boardInfo, vm::psv::ptr option) +s32 sceNpScoreGetBoardInfo(s32 reqId, u32 boardId, vm::ptr boardInfo, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreRecordScore( s32 reqId, - SceNpScoreBoardId boardId, - SceNpScoreValue score, - vm::psv::ptr scoreComment, - vm::psv::ptr gameInfo, - vm::psv::ptr tmpRank, - vm::psv::ptr compareDate, - vm::psv::ptr option) + u32 boardId, + s64 score, + vm::cptr scoreComment, + vm::cptr gameInfo, + vm::ptr tmpRank, + vm::cptr compareDate, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreRecordGameData( s32 reqId, - SceNpScoreBoardId boardId, - SceNpScoreValue score, + u32 boardId, + s64 score, u32 totalSize, u32 sendSize, - vm::psv::ptr data, - vm::psv::ptr option) + vm::cptr data, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetGameData( s32 reqId, - SceNpScoreBoardId boardId, - vm::psv::ptr npId, - vm::psv::ptr totalSize, + u32 boardId, + vm::cptr npId, + vm::ptr totalSize, u32 recvSize, - vm::psv::ptr data, - vm::psv::ptr option) + vm::ptr data, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetRankingByNpId( s32 reqId, - SceNpScoreBoardId boardId, - vm::psv::ptr npIdArray, + u32 boardId, + vm::cptr npIdArray, u32 npIdArraySize, - vm::psv::ptr rankArray, + vm::ptr rankArray, u32 rankArraySize, - vm::psv::ptr commentArray, + vm::ptr commentArray, u32 commentArraySize, - vm::psv::ptr infoArray, + vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, - vm::psv::ptr lastSortDate, - vm::psv::ptr totalRecord, - vm::psv::ptr option) + vm::ptr lastSortDate, + vm::ptr totalRecord, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetRankingByRange( s32 reqId, - SceNpScoreBoardId boardId, - SceNpScoreRankNumber startSerialRank, - vm::psv::ptr rankArray, + u32 boardId, + u32 startSerialRank, + vm::ptr rankArray, u32 rankArraySize, - vm::psv::ptr commentArray, + vm::ptr commentArray, u32 commentArraySize, - vm::psv::ptr infoArray, + vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, - vm::psv::ptr lastSortDate, - vm::psv::ptr totalRecord, - vm::psv::ptr option) + vm::ptr lastSortDate, + vm::ptr totalRecord, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetRankingByNpIdPcId( s32 reqId, - SceNpScoreBoardId boardId, - vm::psv::ptr idArray, + u32 boardId, + vm::cptr idArray, u32 idArraySize, - vm::psv::ptr rankArray, + vm::ptr rankArray, u32 rankArraySize, - vm::psv::ptr commentArray, + vm::ptr commentArray, u32 commentArraySize, - vm::psv::ptr infoArray, + vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, - vm::psv::ptr lastSortDate, - vm::psv::ptr totalRecord, - vm::psv::ptr option) + vm::ptr lastSortDate, + vm::ptr totalRecord, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreCensorComment(s32 reqId, vm::psv::ptr comment, vm::psv::ptr option) +s32 sceNpScoreCensorComment(s32 reqId, vm::cptr comment, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreSanitizeComment(s32 reqId, vm::psv::ptr comment, vm::psv::ptr sanitizedComment, vm::psv::ptr option) +s32 sceNpScoreSanitizeComment(s32 reqId, vm::cptr comment, vm::ptr sanitizedComment, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreWaitAsync(s32 id, vm::psv::ptr result) +s32 sceNpScoreWaitAsync(s32 id, vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScorePollAsync(s32 reqId, vm::psv::ptr result) +s32 sceNpScorePollAsync(s32 reqId, vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreGetBoardInfoAsync(s32 reqId, SceNpScoreBoardId boardId, vm::psv::ptr boardInfo, vm::psv::ptr option) +s32 sceNpScoreGetBoardInfoAsync(s32 reqId, u32 boardId, vm::ptr boardInfo, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreRecordScoreAsync( s32 reqId, - SceNpScoreBoardId boardId, - SceNpScoreValue score, - vm::psv::ptr scoreComment, - vm::psv::ptr gameInfo, - vm::psv::ptr tmpRank, - vm::psv::ptr compareDate, - vm::psv::ptr option) + u32 boardId, + s64 score, + vm::cptr scoreComment, + vm::cptr gameInfo, + vm::ptr tmpRank, + vm::cptr compareDate, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreRecordGameDataAsync( s32 reqId, - SceNpScoreBoardId boardId, - SceNpScoreValue score, + u32 boardId, + s64 score, u32 totalSize, u32 sendSize, - vm::psv::ptr data, - vm::psv::ptr option) + vm::cptr data, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetGameDataAsync( s32 reqId, - SceNpScoreBoardId boardId, - vm::psv::ptr npId, - vm::psv::ptr totalSize, + u32 boardId, + vm::cptr npId, + vm::ptr totalSize, u32 recvSize, - vm::psv::ptr data, - vm::psv::ptr option) + vm::ptr data, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetRankingByNpIdAsync( s32 reqId, - SceNpScoreBoardId boardId, - vm::psv::ptr npIdArray, + u32 boardId, + vm::cptr npIdArray, u32 npIdArraySize, - vm::psv::ptr rankArray, + vm::ptr rankArray, u32 rankArraySize, - vm::psv::ptr commentArray, + vm::ptr commentArray, u32 commentArraySize, - vm::psv::ptr infoArray, + vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, - vm::psv::ptr lastSortDate, - vm::psv::ptr totalRecord, - vm::psv::ptr option) + vm::ptr lastSortDate, + vm::ptr totalRecord, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetRankingByRangeAsync( s32 reqId, - SceNpScoreBoardId boardId, - SceNpScoreRankNumber startSerialRank, - vm::psv::ptr rankArray, + u32 boardId, + u32 startSerialRank, + vm::ptr rankArray, u32 rankArraySize, - vm::psv::ptr commentArray, + vm::ptr commentArray, u32 commentArraySize, - vm::psv::ptr infoArray, + vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, - vm::psv::ptr lastSortDate, - vm::psv::ptr totalRecord, - vm::psv::ptr option) + vm::ptr lastSortDate, + vm::ptr totalRecord, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpScoreGetRankingByNpIdPcIdAsync( s32 reqId, - SceNpScoreBoardId boardId, - vm::psv::ptr idArray, + u32 boardId, + vm::cptr idArray, u32 idArraySize, - vm::psv::ptr rankArray, + vm::ptr rankArray, u32 rankArraySize, - vm::psv::ptr commentArray, + vm::ptr commentArray, u32 commentArraySize, - vm::psv::ptr infoArray, + vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, - vm::psv::ptr lastSortDate, - vm::psv::ptr totalRecord, - vm::psv::ptr option) + vm::ptr lastSortDate, + vm::ptr totalRecord, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreCensorCommentAsync(s32 reqId, vm::psv::ptr comment, vm::psv::ptr option) +s32 sceNpScoreCensorCommentAsync(s32 reqId, vm::cptr comment, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpScoreSanitizeCommentAsync(s32 reqId, vm::psv::ptr comment, vm::psv::ptr sanitizedComment, vm::psv::ptr option) +s32 sceNpScoreSanitizeCommentAsync(s32 reqId, vm::cptr comment, vm::ptr sanitizedComment, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNpScore, #name, name) @@ -340,6 +283,7 @@ psv_log_base sceNpScore("SceNpScore", []() sceNpScore.on_load = nullptr; sceNpScore.on_unload = nullptr; sceNpScore.on_stop = nullptr; + sceNpScore.on_error = nullptr; REG_FUNC(0x0433069F, sceNpScoreInit); REG_FUNC(0x2050F98F, sceNpScoreTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpScore.h b/rpcs3/Emu/ARMv7/Modules/sceNpScore.h new file mode 100644 index 0000000000..038ca153c0 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNpScore.h @@ -0,0 +1,55 @@ +#pragma once + +#include "sceNpCommon.h" + +struct SceNpScoreGameInfo +{ + le_t infoSize; + u8 pad[4]; + u8 data[192]; +}; + +struct SceNpScoreComment +{ + char utf8Comment[64]; +}; + +struct SceNpScoreRankData +{ + SceNpId npId; + u8 reserved[49]; + u8 pad0[3]; + le_t pcId; + le_t serialRank; + le_t rank; + le_t highestRank; + le_t hasGameData; + u8 pad1[4]; + le_t scoreValue; + le_t recordDate; +}; + +struct SceNpScorePlayerRankData +{ + le_t hasData; + u8 pad0[4]; + SceNpScoreRankData rankData; +}; + +struct SceNpScoreBoardInfo +{ + le_t rankLimit; + le_t updateMode; + le_t sortMode; + le_t uploadNumLimit; + le_t uploadSizeLimit; +}; + +struct SceNpScoreNpIdPcId +{ + SceNpId npId; + le_t pcId; + u8 pad[4]; +}; + +extern psv_log_base sceNpScore; diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp b/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp index 1aab007361..51192366ba 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceNpUtility.cpp @@ -2,138 +2,128 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceNpCommon.h" +#include "sceNpUtility.h" -extern psv_log_base sceNpUtility; - -struct SceNpBandwidthTestResult +s32 sceNpLookupInit(s32 usesAsync, s32 threadPriority, s32 cpuAffinityMask, vm::ptr option) { - double uploadBps; - double downloadBps; - s32 result; - char padding[4]; -}; - -s32 sceNpLookupInit(s32 usesAsync, s32 threadPriority, s32 cpuAffinityMask, vm::psv::ptr option) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupTerm(ARMv7Context&) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupCreateTitleCtx(vm::psv::ptr titleId, vm::psv::ptr selfNpId) +s32 sceNpLookupCreateTitleCtx(vm::cptr titleId, vm::cptr selfNpId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupDeleteTitleCtx(s32 titleCtxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupCreateRequest(s32 titleCtxId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupDeleteRequest(s32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupAbortRequest(s32 reqId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupSetTimeout(s32 id, s32 resolveRetry, u32 resolveTimeout, u32 connTimeout, u32 sendTimeout, u32 recvTimeout) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupWaitAsync(s32 reqId, vm::psv::ptr result) +s32 sceNpLookupWaitAsync(s32 reqId, vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupPollAsync(s32 reqId, vm::psv::ptr result) +s32 sceNpLookupPollAsync(s32 reqId, vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupNpId(s32 reqId, vm::psv::ptr onlineId, vm::psv::ptr npId, vm::psv::ptr option) +s32 sceNpLookupNpId(s32 reqId, vm::cptr onlineId, vm::ptr npId, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupNpIdAsync(s32 reqId, vm::psv::ptr onlineId, vm::psv::ptr npId, vm::psv::ptr option) +s32 sceNpLookupNpIdAsync(s32 reqId, vm::cptr onlineId, vm::ptr npId, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupUserProfile( s32 reqId, s32 avatarSizeType, - vm::psv::ptr npId, - vm::psv::ptr userInfo, - vm::psv::ptr aboutMe, - vm::psv::ptr languages, - vm::psv::ptr countryCode, - vm::psv::ptr avatarImageData, + vm::cptr npId, + vm::ptr userInfo, + vm::ptr aboutMe, + vm::ptr languages, + vm::ptr countryCode, + vm::ptr avatarImageData, u32 avatarImageDataMaxSize, - vm::psv::ptr avatarImageDataSize, - vm::psv::ptr option) + vm::ptr avatarImageDataSize, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpLookupUserProfileAsync( s32 reqId, s32 avatarSizeType, - vm::psv::ptr npId, - vm::psv::ptr userInfo, - vm::psv::ptr aboutMe, - vm::psv::ptr languages, - vm::psv::ptr countryCode, - vm::psv::ptr avatarImageData, + vm::cptr npId, + vm::ptr userInfo, + vm::ptr aboutMe, + vm::ptr languages, + vm::ptr countryCode, + vm::ptr avatarImageData, u32 avatarImageDataMaxSize, - vm::psv::ptr avatarImageDataSize, - vm::psv::ptr option) + vm::ptr avatarImageDataSize, + vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupAvatarImage(s32 reqId, vm::psv::ptr avatarUrl, vm::psv::ptr avatarImage, vm::psv::ptr option) +s32 sceNpLookupAvatarImage(s32 reqId, vm::cptr avatarUrl, vm::ptr avatarImage, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpLookupAvatarImageAsync(s32 reqId, vm::psv::ptr avatarUrl, vm::psv::ptr avatarImage, vm::psv::ptr option) +s32 sceNpLookupAvatarImageAsync(s32 reqId, vm::cptr avatarUrl, vm::ptr avatarImage, vm::ptr option) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBandwidthTestInitStart(s32 initPriority, s32 cpuAffinityMask) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBandwidthTestGetStatus() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceNpBandwidthTestShutdown(vm::psv::ptr result) +s32 sceNpBandwidthTestShutdown(vm::ptr result) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceNpBandwidthTestAbort() { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceNpUtility, #name, name) @@ -143,6 +133,7 @@ psv_log_base sceNpUtility("SceNpUtility", []() sceNpUtility.on_load = nullptr; sceNpUtility.on_unload = nullptr; sceNpUtility.on_stop = nullptr; + sceNpUtility.on_error = nullptr; REG_FUNC(0x9246A673, sceNpLookupInit); REG_FUNC(0x0158B61B, sceNpLookupTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceNpUtility.h b/rpcs3/Emu/ARMv7/Modules/sceNpUtility.h new file mode 100644 index 0000000000..dd2adec373 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceNpUtility.h @@ -0,0 +1,13 @@ +#pragma once + +#include "sceNpCommon.h" + +struct SceNpBandwidthTestResult +{ + le_t uploadBps; + le_t downloadBps; + le_t result; + char padding[4]; +}; + +extern psv_log_base sceNpUtility; diff --git a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp b/rpcs3/Emu/ARMv7/Modules/scePerf.cpp index 38516caafe..9a5c2614f0 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePerf.cpp +++ b/rpcs3/Emu/ARMv7/Modules/scePerf.cpp @@ -2,101 +2,9 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/SysCalls/lv2/sys_time.h" +#include "scePerf.h" -#define RETURN_ERROR(code) { Emu.Pause(); scePerf.Error("%s() failed: %s", __FUNCTION__, #code); return code; } - -extern psv_log_base scePerf; - -enum -{ - // Error Codes - SCE_PERF_ERROR_INVALID_ARGUMENT = 0x80580000, -}; - -enum : s32 -{ - // Thread IDs - SCE_PERF_ARM_PMON_THREAD_ID_ALL = -1, - SCE_PERF_ARM_PMON_THREAD_ID_SELF = 0, -}; - -enum : u32 -{ - // Counter Numbers - SCE_PERF_ARM_PMON_CYCLE_COUNTER = 31, - SCE_PERF_ARM_PMON_COUNTER_5 = 5, - SCE_PERF_ARM_PMON_COUNTER_4 = 4, - SCE_PERF_ARM_PMON_COUNTER_3 = 3, - SCE_PERF_ARM_PMON_COUNTER_2 = 2, - SCE_PERF_ARM_PMON_COUNTER_1 = 1, - SCE_PERF_ARM_PMON_COUNTER_0 = 0, - - // Counter Masks - SCE_PERF_ARM_PMON_COUNTER_MASK_5 = 0x20, - SCE_PERF_ARM_PMON_COUNTER_MASK_4 = 0x10, - SCE_PERF_ARM_PMON_COUNTER_MASK_3 = 0x08, - SCE_PERF_ARM_PMON_COUNTER_MASK_2 = 0x04, - SCE_PERF_ARM_PMON_COUNTER_MASK_1 = 0x02, - SCE_PERF_ARM_PMON_COUNTER_MASK_0 = 0x01, - SCE_PERF_ARM_PMON_COUNTER_MASK_ALL = 0x3f, -}; - -enum : u8 -{ - // Performance Counter Events - SCE_PERF_ARM_PMON_SOFT_INCREMENT = 0x00, - SCE_PERF_ARM_PMON_ICACHE_MISS = 0x01, - SCE_PERF_ARM_PMON_ITLB_MISS = 0x02, - SCE_PERF_ARM_PMON_DCACHE_MISS = 0x03, - SCE_PERF_ARM_PMON_DCACHE_ACCESS = 0x04, - SCE_PERF_ARM_PMON_DTLB_MISS = 0x05, - SCE_PERF_ARM_PMON_DATA_READ = 0x06, - SCE_PERF_ARM_PMON_DATA_WRITE = 0x07, - SCE_PERF_ARM_PMON_EXCEPTION_TAKEN = 0x09, - SCE_PERF_ARM_PMON_EXCEPTION_RETURN = 0x0A, - SCE_PERF_ARM_PMON_WRITE_CONTEXTID = 0x0B, - SCE_PERF_ARM_PMON_SOFT_CHANGEPC = 0x0C, - SCE_PERF_ARM_PMON_IMMEDIATE_BRANCH = 0x0D, - SCE_PERF_ARM_PMON_UNALIGNED = 0x0F, - SCE_PERF_ARM_PMON_BRANCH_MISPREDICT = 0x10, - SCE_PERF_ARM_PMON_PREDICT_BRANCH = 0x12, - SCE_PERF_ARM_PMON_COHERENT_LF_MISS = 0x50, - SCE_PERF_ARM_PMON_COHERENT_LF_HIT = 0x51, - SCE_PERF_ARM_PMON_ICACHE_STALL = 0x60, - SCE_PERF_ARM_PMON_DCACHE_STALL = 0x61, - SCE_PERF_ARM_PMON_MAINTLB_STALL = 0x62, - SCE_PERF_ARM_PMON_STREX_PASSED = 0x63, - SCE_PERF_ARM_PMON_STREX_FAILED = 0x64, - SCE_PERF_ARM_PMON_DATA_EVICTION = 0x65, - SCE_PERF_ARM_PMON_ISSUE_NO_DISPATCH = 0x66, - SCE_PERF_ARM_PMON_ISSUE_EMPTY = 0x67, - SCE_PERF_ARM_PMON_INST_RENAME = 0x68, - SCE_PERF_ARM_PMON_PREDICT_FUNC_RET = 0x6E, - SCE_PERF_ARM_PMON_MAIN_PIPE = 0x70, - SCE_PERF_ARM_PMON_SECOND_PIPE = 0x71, - SCE_PERF_ARM_PMON_LS_PIPE = 0x72, - SCE_PERF_ARM_PMON_FPU_RENAME = 0x73, - SCE_PERF_ARM_PMON_PLD_STALL = 0x80, - SCE_PERF_ARM_PMON_WRITE_STALL = 0x81, - SCE_PERF_ARM_PMON_INST_MAINTLB_STALL = 0x82, - SCE_PERF_ARM_PMON_DATA_MAINTLB_STALL = 0x83, - SCE_PERF_ARM_PMON_INST_UTLB_STALL = 0x84, - SCE_PERF_ARM_PMON_DATA_UTLB_STALL = 0x85, - SCE_PERF_ARM_PMON_DMB_STALL = 0x86, - SCE_PERF_ARM_PMON_INTEGER_CLOCK = 0x8A, - SCE_PERF_ARM_PMON_DATAENGINE_CLOCK = 0x8B, - SCE_PERF_ARM_PMON_ISB = 0x90, - SCE_PERF_ARM_PMON_DSB = 0x91, - SCE_PERF_ARM_PMON_DMB = 0x92, - SCE_PERF_ARM_PMON_EXT_INTERRUPT = 0x93, - SCE_PERF_ARM_PMON_PLE_LINE_REQ_COMPLETED = 0xA0, - SCE_PERF_ARM_PMON_PLE_CHANNEL_SKIPPED = 0xA1, - SCE_PERF_ARM_PMON_PLE_FIFO_FLUSH = 0xA2, - SCE_PERF_ARM_PMON_PLE_REQ_COMPLETED = 0xA3, - SCE_PERF_ARM_PMON_PLE_FIFO_OVERFLOW = 0xA4, - SCE_PERF_ARM_PMON_PLE_REQ_PROGRAMMED = 0xA5, -}; +extern u64 get_system_time(); s32 scePerfArmPmonReset(ARMv7Context& context, s32 threadId) { @@ -104,7 +12,7 @@ s32 scePerfArmPmonReset(ARMv7Context& context, s32 threadId) if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected thread"); } context.counters = {}; @@ -118,12 +26,12 @@ s32 scePerfArmPmonSelectEvent(ARMv7Context& context, s32 threadId, u32 counter, if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected thread"); } if (counter >= 6) { - RETURN_ERROR(SCE_PERF_ERROR_INVALID_ARGUMENT); + return SCE_PERF_ERROR_INVALID_ARGUMENT; } u32 value = 0; // initial value @@ -152,7 +60,10 @@ s32 scePerfArmPmonSelectEvent(ARMv7Context& context, s32 threadId, u32 counter, break; } - default: throw "scePerfArmPmonSelectEvent(): unknown event requested"; + default: + { + throw EXCEPTION("Unknown event requested"); + } } context.counters[counter].event = eventCode; @@ -167,7 +78,7 @@ s32 scePerfArmPmonStart(ARMv7Context& context, s32 threadId) if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected thread"); } return SCE_OK; @@ -179,24 +90,24 @@ s32 scePerfArmPmonStop(ARMv7Context& context, s32 threadId) if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected thread"); } return SCE_OK; } -s32 scePerfArmPmonGetCounterValue(ARMv7Context& context, s32 threadId, u32 counter, vm::psv::ptr pValue) +s32 scePerfArmPmonGetCounterValue(ARMv7Context& context, s32 threadId, u32 counter, vm::ptr pValue) { scePerf.Warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue); if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected thread"); } if (counter >= 6 && counter != SCE_PERF_ARM_PMON_CYCLE_COUNTER) { - RETURN_ERROR(SCE_PERF_ERROR_INVALID_ARGUMENT); + return SCE_PERF_ERROR_INVALID_ARGUMENT; } if (counter < 6) @@ -205,7 +116,7 @@ s32 scePerfArmPmonGetCounterValue(ARMv7Context& context, s32 threadId, u32 count } else { - throw "scePerfArmPmonGetCounterValue(): cycle counter requested"; + throw EXCEPTION("Cycle counter requested"); } return SCE_OK; @@ -217,7 +128,7 @@ s32 scePerfArmPmonSoftwareIncrement(ARMv7Context& context, u32 mask) if (mask > SCE_PERF_ARM_PMON_COUNTER_MASK_ALL) { - RETURN_ERROR(SCE_PERF_ERROR_INVALID_ARGUMENT); + return SCE_PERF_ERROR_INVALID_ARGUMENT; } for (u32 i = 0; i < 6; i++, mask >>= 1) @@ -245,24 +156,24 @@ u32 scePerfGetTimebaseFrequency() return 1; } -s32 _sceRazorCpuInit(vm::psv::ptr pBufferBase, u32 bufferSize, u32 numPerfCounters, vm::psv::pptr psceRazorVars) +s32 _sceRazorCpuInit(vm::cptr pBufferBase, u32 bufferSize, u32 numPerfCounters, vm::pptr psceRazorVars) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRazorCpuPushMarker(vm::psv::ptr szLabel) +s32 sceRazorCpuPushMarker(vm::cptr szLabel) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceRazorCpuPopMarker() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceRazorCpuSync() { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &scePerf, #name, name) @@ -272,6 +183,7 @@ psv_log_base scePerf("ScePerf", []() scePerf.on_load = nullptr; scePerf.on_unload = nullptr; scePerf.on_stop = nullptr; + //scePerf.on_error = nullptr; // keep default error handler REG_FUNC(0x35151735, scePerfArmPmonReset); REG_FUNC(0x63CBEA8B, scePerfArmPmonSelectEvent); diff --git a/rpcs3/Emu/ARMv7/Modules/scePerf.h b/rpcs3/Emu/ARMv7/Modules/scePerf.h new file mode 100644 index 0000000000..cf8b27c891 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/scePerf.h @@ -0,0 +1,93 @@ +#pragma once + +enum +{ + // Error Codes + SCE_PERF_ERROR_INVALID_ARGUMENT = 0x80580000, +}; + +enum : s32 +{ + // Thread IDs + SCE_PERF_ARM_PMON_THREAD_ID_ALL = -1, + SCE_PERF_ARM_PMON_THREAD_ID_SELF = 0, +}; + +enum : u32 +{ + // Counter Numbers + SCE_PERF_ARM_PMON_CYCLE_COUNTER = 31, + SCE_PERF_ARM_PMON_COUNTER_5 = 5, + SCE_PERF_ARM_PMON_COUNTER_4 = 4, + SCE_PERF_ARM_PMON_COUNTER_3 = 3, + SCE_PERF_ARM_PMON_COUNTER_2 = 2, + SCE_PERF_ARM_PMON_COUNTER_1 = 1, + SCE_PERF_ARM_PMON_COUNTER_0 = 0, + + // Counter Masks + SCE_PERF_ARM_PMON_COUNTER_MASK_5 = 0x20, + SCE_PERF_ARM_PMON_COUNTER_MASK_4 = 0x10, + SCE_PERF_ARM_PMON_COUNTER_MASK_3 = 0x08, + SCE_PERF_ARM_PMON_COUNTER_MASK_2 = 0x04, + SCE_PERF_ARM_PMON_COUNTER_MASK_1 = 0x02, + SCE_PERF_ARM_PMON_COUNTER_MASK_0 = 0x01, + SCE_PERF_ARM_PMON_COUNTER_MASK_ALL = 0x3f, +}; + +enum : u8 +{ + // Performance Counter Events + SCE_PERF_ARM_PMON_SOFT_INCREMENT = 0x00, + SCE_PERF_ARM_PMON_ICACHE_MISS = 0x01, + SCE_PERF_ARM_PMON_ITLB_MISS = 0x02, + SCE_PERF_ARM_PMON_DCACHE_MISS = 0x03, + SCE_PERF_ARM_PMON_DCACHE_ACCESS = 0x04, + SCE_PERF_ARM_PMON_DTLB_MISS = 0x05, + SCE_PERF_ARM_PMON_DATA_READ = 0x06, + SCE_PERF_ARM_PMON_DATA_WRITE = 0x07, + SCE_PERF_ARM_PMON_EXCEPTION_TAKEN = 0x09, + SCE_PERF_ARM_PMON_EXCEPTION_RETURN = 0x0A, + SCE_PERF_ARM_PMON_WRITE_CONTEXTID = 0x0B, + SCE_PERF_ARM_PMON_SOFT_CHANGEPC = 0x0C, + SCE_PERF_ARM_PMON_IMMEDIATE_BRANCH = 0x0D, + SCE_PERF_ARM_PMON_UNALIGNED = 0x0F, + SCE_PERF_ARM_PMON_BRANCH_MISPREDICT = 0x10, + SCE_PERF_ARM_PMON_PREDICT_BRANCH = 0x12, + SCE_PERF_ARM_PMON_COHERENT_LF_MISS = 0x50, + SCE_PERF_ARM_PMON_COHERENT_LF_HIT = 0x51, + SCE_PERF_ARM_PMON_ICACHE_STALL = 0x60, + SCE_PERF_ARM_PMON_DCACHE_STALL = 0x61, + SCE_PERF_ARM_PMON_MAINTLB_STALL = 0x62, + SCE_PERF_ARM_PMON_STREX_PASSED = 0x63, + SCE_PERF_ARM_PMON_STREX_FAILED = 0x64, + SCE_PERF_ARM_PMON_DATA_EVICTION = 0x65, + SCE_PERF_ARM_PMON_ISSUE_NO_DISPATCH = 0x66, + SCE_PERF_ARM_PMON_ISSUE_EMPTY = 0x67, + SCE_PERF_ARM_PMON_INST_RENAME = 0x68, + SCE_PERF_ARM_PMON_PREDICT_FUNC_RET = 0x6E, + SCE_PERF_ARM_PMON_MAIN_PIPE = 0x70, + SCE_PERF_ARM_PMON_SECOND_PIPE = 0x71, + SCE_PERF_ARM_PMON_LS_PIPE = 0x72, + SCE_PERF_ARM_PMON_FPU_RENAME = 0x73, + SCE_PERF_ARM_PMON_PLD_STALL = 0x80, + SCE_PERF_ARM_PMON_WRITE_STALL = 0x81, + SCE_PERF_ARM_PMON_INST_MAINTLB_STALL = 0x82, + SCE_PERF_ARM_PMON_DATA_MAINTLB_STALL = 0x83, + SCE_PERF_ARM_PMON_INST_UTLB_STALL = 0x84, + SCE_PERF_ARM_PMON_DATA_UTLB_STALL = 0x85, + SCE_PERF_ARM_PMON_DMB_STALL = 0x86, + SCE_PERF_ARM_PMON_INTEGER_CLOCK = 0x8A, + SCE_PERF_ARM_PMON_DATAENGINE_CLOCK = 0x8B, + SCE_PERF_ARM_PMON_ISB = 0x90, + SCE_PERF_ARM_PMON_DSB = 0x91, + SCE_PERF_ARM_PMON_DMB = 0x92, + SCE_PERF_ARM_PMON_EXT_INTERRUPT = 0x93, + SCE_PERF_ARM_PMON_PLE_LINE_REQ_COMPLETED = 0xA0, + SCE_PERF_ARM_PMON_PLE_CHANNEL_SKIPPED = 0xA1, + SCE_PERF_ARM_PMON_PLE_FIFO_FLUSH = 0xA2, + SCE_PERF_ARM_PMON_PLE_REQ_COMPLETED = 0xA3, + SCE_PERF_ARM_PMON_PLE_FIFO_OVERFLOW = 0xA4, + SCE_PERF_ARM_PMON_PLE_REQ_PROGRAMMED = 0xA5, +}; + +extern psv_log_base scePerf; diff --git a/rpcs3/Emu/ARMv7/Modules/scePgf.cpp b/rpcs3/Emu/ARMv7/Modules/scePgf.cpp index c4a1f21065..ec4fb307bf 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePgf.cpp +++ b/rpcs3/Emu/ARMv7/Modules/scePgf.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base scePgf; +#include "scePgf.h" #define REG_FUNC(nid, name) reg_psv_func(nid, &scePgf, #name, name) @@ -11,6 +11,7 @@ psv_log_base scePgf("ScePgf", []() scePgf.on_load = nullptr; scePgf.on_unload = nullptr; scePgf.on_stop = nullptr; + scePgf.on_error = nullptr; //REG_FUNC(0x1055ABA3, sceFontNewLib); //REG_FUNC(0x07EE1733, sceFontDoneLib); diff --git a/rpcs3/Emu/ARMv7/Modules/scePgf.h b/rpcs3/Emu/ARMv7/Modules/scePgf.h new file mode 100644 index 0000000000..0b299c6785 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/scePgf.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base scePgf; diff --git a/rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp b/rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp index 2046dff9ca..a3bb019b95 100644 --- a/rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp +++ b/rpcs3/Emu/ARMv7/Modules/scePhotoExport.cpp @@ -2,42 +2,31 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base scePhotoExport; - -struct ScePhotoExportParam -{ - u32 version; - vm::psv::ptr photoTitle; - vm::psv::ptr gameTitle; - vm::psv::ptr gameComment; - char reserved[32]; -}; - -typedef vm::psv::ptr)> ScePhotoExportCancelFunc; +#include "scePhotoExport.h" s32 scePhotoExportFromData( - vm::psv::ptr photodata, + vm::cptr photodata, s32 photodataSize, - vm::psv::ptr param, - vm::psv::ptr workMemory, - ScePhotoExportCancelFunc cancelFunc, - vm::psv::ptr userdata, - vm::psv::ptr exportedPath, + vm::cptr param, + vm::ptr workMemory, + vm::ptr cancelFunc, + vm::ptr userdata, + vm::ptr exportedPath, s32 exportedPathLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 scePhotoExportFromFile( - vm::psv::ptr photodataPath, - vm::psv::ptr param, - vm::psv::ptr workMemory, - ScePhotoExportCancelFunc cancelFunc, - vm::psv::ptr userdata, - vm::psv::ptr exportedPath, + vm::cptr photodataPath, + vm::cptr param, + vm::ptr workMemory, + vm::ptr cancelFunc, + vm::ptr userdata, + vm::ptr exportedPath, s32 exportedPathLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &scePhotoExport, #name, name) @@ -47,6 +36,7 @@ psv_log_base scePhotoExport("ScePhotoExport", []() scePhotoExport.on_load = nullptr; scePhotoExport.on_unload = nullptr; scePhotoExport.on_stop = nullptr; + scePhotoExport.on_error = nullptr; REG_FUNC(0x70512321, scePhotoExportFromData); REG_FUNC(0x84FD9FC5, scePhotoExportFromFile); diff --git a/rpcs3/Emu/ARMv7/Modules/scePhotoExport.h b/rpcs3/Emu/ARMv7/Modules/scePhotoExport.h new file mode 100644 index 0000000000..ca7bb6931b --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/scePhotoExport.h @@ -0,0 +1,14 @@ +#pragma once + +struct ScePhotoExportParam +{ + le_t version; + vm::lcptr photoTitle; + vm::lcptr gameTitle; + vm::lcptr gameComment; + char reserved[32]; +}; + +using ScePhotoExportCancelFunc = func_def)>; + +extern psv_log_base scePhotoExport; diff --git a/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp b/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp index c14fba50b6..0bd13559a0 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.cpp @@ -2,21 +2,21 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceRazorCapture; +#include "sceRazorCapture.h" -void sceRazorCaptureSetTrigger(u32 frameIndex, vm::psv::ptr captureFilename) +void sceRazorCaptureSetTrigger(u32 frameIndex, vm::cptr captureFilename) { - throw __FUNCTION__; + throw EXCEPTION(""); } -void sceRazorCaptureSetTriggerNextFrame(vm::psv::ptr captureFilename) +void sceRazorCaptureSetTriggerNextFrame(vm::cptr captureFilename) { - throw __FUNCTION__; + throw EXCEPTION(""); } bool sceRazorCaptureIsInProgress() { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceRazorCapture, #name, name) @@ -26,6 +26,7 @@ psv_log_base sceRazorCapture("SceRazorCapture", []() sceRazorCapture.on_load = nullptr; sceRazorCapture.on_unload = nullptr; sceRazorCapture.on_stop = nullptr; + sceRazorCapture.on_error = nullptr; REG_FUNC(0x911E0AA0, sceRazorCaptureIsInProgress); REG_FUNC(0xE916B538, sceRazorCaptureSetTrigger); diff --git a/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.h b/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.h new file mode 100644 index 0000000000..25a64f6465 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceRazorCapture.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceRazorCapture; diff --git a/rpcs3/Emu/ARMv7/Modules/sceRtc.cpp b/rpcs3/Emu/ARMv7/Modules/sceRtc.cpp index 9b81d86072..2464327af3 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceRtc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceRtc.cpp @@ -2,191 +2,191 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceRtc; +#include "sceRtc.h" u32 sceRtcGetTickResolution() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetCurrentTick(vm::psv::ptr pTick) +s32 sceRtcGetCurrentTick(vm::ptr pTick) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetCurrentClock(vm::psv::ptr pTime, s32 iTimeZone) +s32 sceRtcGetCurrentClock(vm::ptr pTime, s32 iTimeZone) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetCurrentClockLocalTime(vm::psv::ptr pTime) +s32 sceRtcGetCurrentClockLocalTime(vm::ptr pTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetCurrentNetworkTick(vm::psv::ptr pTick) +s32 sceRtcGetCurrentNetworkTick(vm::ptr pTick) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcConvertUtcToLocalTime(vm::psv::ptr pUtc, vm::psv::ptr pLocalTime) +s32 sceRtcConvertUtcToLocalTime(vm::cptr pUtc, vm::ptr pLocalTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcConvertLocalTimeToUtc(vm::psv::ptr pLocalTime, vm::psv::ptr pUtc) +s32 sceRtcConvertLocalTimeToUtc(vm::cptr pLocalTime, vm::ptr pUtc) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceRtcIsLeapYear(s32 year) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceRtcGetDaysInMonth(s32 year, s32 month) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceRtcGetDayOfWeek(s32 year, s32 month, s32 day) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcCheckValid(vm::psv::ptr pTime) +s32 sceRtcCheckValid(vm::cptr pTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcSetTime_t(vm::psv::ptr pTime, u32 iTime) +s32 sceRtcSetTime_t(vm::ptr pTime, u32 iTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcSetTime64_t(vm::psv::ptr pTime, u64 ullTime) +s32 sceRtcSetTime64_t(vm::ptr pTime, u64 ullTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetTime_t(vm::psv::ptr pTime, vm::psv::ptr piTime) +s32 sceRtcGetTime_t(vm::cptr pTime, vm::ptr piTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetTime64_t(vm::psv::ptr pTime, vm::psv::ptr pullTime) +s32 sceRtcGetTime64_t(vm::cptr pTime, vm::ptr pullTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcSetDosTime(vm::psv::ptr pTime, u32 uiDosTime) +s32 sceRtcSetDosTime(vm::ptr pTime, u32 uiDosTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetDosTime(vm::psv::ptr pTime, vm::psv::ptr puiDosTime) +s32 sceRtcGetDosTime(vm::cptr pTime, vm::ptr puiDosTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcSetWin32FileTime(vm::psv::ptr pTime, u64 ulWin32Time) +s32 sceRtcSetWin32FileTime(vm::ptr pTime, u64 ulWin32Time) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetWin32FileTime(vm::psv::ptr pTime, vm::psv::ptr ulWin32Time) +s32 sceRtcGetWin32FileTime(vm::cptr pTime, vm::ptr ulWin32Time) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcSetTick(vm::psv::ptr pTime, vm::psv::ptr pTick) +s32 sceRtcSetTick(vm::ptr pTime, vm::cptr pTick) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcGetTick(vm::psv::ptr pTime, vm::psv::ptr pTick) +s32 sceRtcGetTick(vm::cptr pTime, vm::ptr pTick) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcCompareTick(vm::psv::ptr pTick1, vm::psv::ptr pTick2) +s32 sceRtcCompareTick(vm::cptr pTick1, vm::cptr pTick2) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddTicks(vm::psv::ptr pTick0, vm::psv::ptr pTick1, u64 lAdd) +s32 sceRtcTickAddTicks(vm::ptr pTick0, vm::cptr pTick1, u64 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddMicroseconds(vm::psv::ptr pTick0, vm::psv::ptr pTick1, u64 lAdd) +s32 sceRtcTickAddMicroseconds(vm::ptr pTick0, vm::cptr pTick1, u64 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddSeconds(vm::psv::ptr pTick0, vm::psv::ptr pTick1, u64 lAdd) +s32 sceRtcTickAddSeconds(vm::ptr pTick0, vm::cptr pTick1, u64 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddMinutes(vm::psv::ptr pTick0, vm::psv::ptr pTick1, u64 lAdd) +s32 sceRtcTickAddMinutes(vm::ptr pTick0, vm::cptr pTick1, u64 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddHours(vm::psv::ptr pTick0, vm::psv::ptr pTick1, s32 lAdd) +s32 sceRtcTickAddHours(vm::ptr pTick0, vm::cptr pTick1, s32 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddDays(vm::psv::ptr pTick0, vm::psv::ptr pTick1, s32 lAdd) +s32 sceRtcTickAddDays(vm::ptr pTick0, vm::cptr pTick1, s32 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddWeeks(vm::psv::ptr pTick0, vm::psv::ptr pTick1, s32 lAdd) +s32 sceRtcTickAddWeeks(vm::ptr pTick0, vm::cptr pTick1, s32 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddMonths(vm::psv::ptr pTick0, vm::psv::ptr pTick1, s32 lAdd) +s32 sceRtcTickAddMonths(vm::ptr pTick0, vm::cptr pTick1, s32 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcTickAddYears(vm::psv::ptr pTick0, vm::psv::ptr pTick1, s32 lAdd) +s32 sceRtcTickAddYears(vm::ptr pTick0, vm::cptr pTick1, s32 lAdd) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcFormatRFC2822(vm::psv::ptr pszDateTime, vm::psv::ptr pUtc, s32 iTimeZoneMinutes) +s32 sceRtcFormatRFC2822(vm::ptr pszDateTime, vm::cptr pUtc, s32 iTimeZoneMinutes) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcFormatRFC2822LocalTime(vm::psv::ptr pszDateTime, vm::psv::ptr pUtc) +s32 sceRtcFormatRFC2822LocalTime(vm::ptr pszDateTime, vm::cptr pUtc) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcFormatRFC3339(vm::psv::ptr pszDateTime, vm::psv::ptr pUtc, s32 iTimeZoneMinutes) +s32 sceRtcFormatRFC3339(vm::ptr pszDateTime, vm::cptr pUtc, s32 iTimeZoneMinutes) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcFormatRFC3339LocalTime(vm::psv::ptr pszDateTime, vm::psv::ptr pUtc) +s32 sceRtcFormatRFC3339LocalTime(vm::ptr pszDateTime, vm::cptr pUtc) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcParseDateTime(vm::psv::ptr pUtc, vm::psv::ptr pszDateTime) +s32 sceRtcParseDateTime(vm::ptr pUtc, vm::cptr pszDateTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceRtcParseRFC3339(vm::psv::ptr pUtc, vm::psv::ptr pszDateTime) +s32 sceRtcParseRFC3339(vm::ptr pUtc, vm::cptr pszDateTime) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -197,6 +197,7 @@ psv_log_base sceRtc("SceRtc", []() sceRtc.on_load = nullptr; sceRtc.on_unload = nullptr; sceRtc.on_stop = nullptr; + sceRtc.on_error = nullptr; REG_FUNC(0x23F79274, sceRtcGetCurrentTick); REG_FUNC(0xCDDD25FE, sceRtcGetCurrentNetworkTick); diff --git a/rpcs3/Emu/ARMv7/Modules/sceRtc.h b/rpcs3/Emu/ARMv7/Modules/sceRtc.h new file mode 100644 index 0000000000..2c60084b05 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceRtc.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceRtc; diff --git a/rpcs3/Emu/ARMv7/Modules/sceSas.cpp b/rpcs3/Emu/ARMv7/Modules/sceSas.cpp index b0961f2776..40ee51bfaf 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSas.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSas.cpp @@ -2,151 +2,151 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceSas; +#include "sceSas.h" -s32 sceSasGetNeededMemorySize(vm::psv::ptr config, vm::psv::ptr outSize) +s32 sceSasGetNeededMemorySize(vm::cptr config, vm::ptr outSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasInit(vm::psv::ptr config, vm::psv::ptr buffer, u32 bufferSize) +s32 sceSasInit(vm::cptr config, vm::ptr buffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasInitWithGrain(vm::psv::ptr config, u32 grain, vm::psv::ptr buffer, u32 bufferSize) +s32 sceSasInitWithGrain(vm::cptr config, u32 grain, vm::ptr buffer, u32 bufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasExit(vm::psv::pptr outBuffer, vm::psv::ptr outBufferSize) +s32 sceSasExit(vm::pptr outBuffer, vm::ptr outBufferSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetGrain(u32 grain) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasGetGrain() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetOutputmode(u32 outputmode) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasGetOutputmode() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasCore(vm::psv::ptr out) +s32 sceSasCore(vm::ptr out) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasCoreWithMix(vm::psv::ptr inOut, s32 lvol, s32 rvol) +s32 sceSasCoreWithMix(vm::ptr inOut, s32 lvol, s32 rvol) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasSetVoice(s32 iVoiceNum, vm::psv::ptr vagBuf, u32 size, u32 loopflag) +s32 sceSasSetVoice(s32 iVoiceNum, vm::cptr vagBuf, u32 size, u32 loopflag) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSasSetVoicePCM(s32 iVoiceNum, vm::psv::ptr pcmBuf, u32 size, s32 loopsize) +s32 sceSasSetVoicePCM(s32 iVoiceNum, vm::cptr pcmBuf, u32 size, s32 loopsize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetNoise(s32 iVoiceNum, u32 uClk) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetVolume(s32 iVoiceNum, s32 l, s32 r, s32 wl, s32 wr) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetPitch(s32 iVoiceNum, s32 pitch) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetADSR(s32 iVoiceNum, u32 flag, u32 ar, u32 dr, u32 sr, u32 rr) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetADSRmode(s32 iVoiceNum, u32 flag, u32 am, u32 dm, u32 sm, u32 rm) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetSL(s32 iVoiceNum, u32 sl) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetSimpleADSR(s32 iVoiceNum, u16 adsr1, u16 adsr2) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetKeyOn(s32 iVoiceNum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetKeyOff(s32 iVoiceNum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetPause(s32 iVoiceNum, u32 pauseFlag) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasGetPauseState(s32 iVoiceNum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasGetEndState(s32 iVoiceNum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasGetEnvelope(s32 iVoiceNum) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetEffect(s32 drySwitch, s32 wetSwitch) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetEffectType(s32 type) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetEffectVolume(s32 valL, s32 valR) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSasSetEffectParam(u32 delayTime, u32 feedback) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -157,6 +157,7 @@ psv_log_base sceSas("SceSas", []() sceSas.on_load = nullptr; sceSas.on_unload = nullptr; sceSas.on_stop = nullptr; + sceSas.on_error = nullptr; //REG_FUNC(0xA2209C58, sceAsSetRegisterReportHandler); //REG_FUNC(0xBB635544, sceAsSetUnregisterReportHandler); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSas.h b/rpcs3/Emu/ARMv7/Modules/sceSas.h new file mode 100644 index 0000000000..d60bd26155 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceSas.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceSas; diff --git a/rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp b/rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp index 07b3f0a467..62e4c88e00 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceScreenShot.cpp @@ -2,34 +2,26 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceScreenShot; +#include "sceScreenShot.h" -struct SceScreenShotParam +s32 sceScreenShotSetParam(vm::cptr param) { - vm::psv::ptr photoTitle; - vm::psv::ptr gameTitle; - vm::psv::ptr gameComment; - vm::psv::ptr reserved; -}; - -s32 sceScreenShotSetParam(vm::psv::ptr param) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceScreenShotSetOverlayImage(vm::psv::ptr filePath, s32 offsetX, s32 offsetY) +s32 sceScreenShotSetOverlayImage(vm::cptr filePath, s32 offsetX, s32 offsetY) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceScreenShotDisable() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceScreenShotEnable() { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -40,6 +32,7 @@ psv_log_base sceScreenShot("SceScreenShot", []() sceScreenShot.on_load = nullptr; sceScreenShot.on_unload = nullptr; sceScreenShot.on_stop = nullptr; + sceScreenShot.on_error = nullptr; REG_FUNC(0x05DB59C7, sceScreenShotSetParam); REG_FUNC(0x7061665B, sceScreenShotSetOverlayImage); diff --git a/rpcs3/Emu/ARMv7/Modules/sceScreenShot.h b/rpcs3/Emu/ARMv7/Modules/sceScreenShot.h new file mode 100644 index 0000000000..9aab6bef39 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceScreenShot.h @@ -0,0 +1,11 @@ +#pragma once + +struct SceScreenShotParam +{ + vm::lcptr photoTitle; + vm::lcptr gameTitle; + vm::lcptr gameComment; + vm::lptr reserved; +}; + +extern psv_log_base sceScreenShot; diff --git a/rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp b/rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp index e6d2f2a4be..57931d32be 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSfmt.cpp @@ -11,6 +11,7 @@ psv_log_base sceSfmt("SceSfmt", []() sceSfmt.on_load = nullptr; sceSfmt.on_unload = nullptr; sceSfmt.on_stop = nullptr; + sceSfmt.on_error = nullptr; //REG_FUNC(0x8FF464C9, sceSfmt11213InitGenRand); //REG_FUNC(0xBAF5F058, sceSfmt11213InitByArray); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSha.cpp b/rpcs3/Emu/ARMv7/Modules/sceSha.cpp index 5ec792b06d..2fb134841e 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSha.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSha.cpp @@ -11,6 +11,7 @@ psv_log_base sceSha("SceSha", []() sceSha.on_load = nullptr; sceSha.on_unload = nullptr; sceSha.on_stop = nullptr; + sceSha.on_error = nullptr; //REG_FUNC(0xD19A9AA8, sceSha0Digest); //REG_FUNC(0xBCF6DB3A, sceSha0BlockInit); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp b/rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp index 19f560c963..2acaffae9d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSqlite.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceSqlite; +#include "sceSqlite.h" #define REG_FUNC(nid, name) reg_psv_func(nid, &sceSqlite, #name, name) @@ -11,6 +11,7 @@ psv_log_base sceSqlite("SceSqlite", []() sceSqlite.on_load = nullptr; sceSqlite.on_unload = nullptr; sceSqlite.on_stop = nullptr; + sceSqlite.on_error = nullptr; //REG_FUNC(0x26E46324, sqlite3_libversion); //REG_FUNC(0x4CCB58A2, sqlite3_sourceid); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSqlite.h b/rpcs3/Emu/ARMv7/Modules/sceSqlite.h new file mode 100644 index 0000000000..be4fc046b7 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceSqlite.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceSqlite; diff --git a/rpcs3/Emu/ARMv7/Modules/sceSsl.cpp b/rpcs3/Emu/ARMv7/Modules/sceSsl.cpp index bd32cda9dd..75e72e4717 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSsl.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSsl.cpp @@ -6,57 +6,57 @@ s32 sceSslInit(u32 poolSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSslTerm() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslGetMemoryPoolStats(vm::psv::ptr currentStat) +s32 sceSslGetMemoryPoolStats(vm::ptr currentStat) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslGetSerialNumber(vm::psv::ptr sslCert, vm::psv::pptr sboData, vm::psv::ptr sboLen) +s32 sceSslGetSerialNumber(vm::ptr sslCert, vm::cpptr sboData, vm::ptr sboLen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceSslGetSubjectName(vm::psv::ptr sslCert) +vm::ptr sceSslGetSubjectName(vm::ptr sslCert) { - throw __FUNCTION__; + throw EXCEPTION(""); } -vm::psv::ptr sceSslGetIssuerName(vm::psv::ptr sslCert) +vm::ptr sceSslGetIssuerName(vm::ptr sslCert) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslGetNotBefore(vm::psv::ptr sslCert, vm::psv::ptr begin) +s32 sceSslGetNotBefore(vm::ptr sslCert, vm::ptr begin) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslGetNotAfter(vm::psv::ptr sslCert, vm::psv::ptr limit) +s32 sceSslGetNotAfter(vm::ptr sslCert, vm::ptr limit) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslGetNameEntryCount(vm::psv::ptr certName) +s32 sceSslGetNameEntryCount(vm::ptr certName) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslGetNameEntryInfo(vm::psv::ptr certName, s32 entryNum, vm::psv::ptr oidname, u32 maxOidnameLen, vm::psv::ptr value, u32 maxValueLen, vm::psv::ptr valueLen) +s32 sceSslGetNameEntryInfo(vm::ptr certName, s32 entryNum, vm::ptr oidname, u32 maxOidnameLen, vm::ptr value, u32 maxValueLen, vm::ptr valueLen) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSslFreeSslCertName(vm::psv::ptr certName) +s32 sceSslFreeSslCertName(vm::ptr certName) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -67,6 +67,7 @@ psv_log_base sceSsl("SceSsl", []() sceSsl.on_load = nullptr; sceSsl.on_unload = nullptr; sceSsl.on_stop = nullptr; + sceSsl.on_error = nullptr; REG_FUNC(0x3C733316, sceSslInit); REG_FUNC(0x03CE6E3A, sceSslTerm); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSsl.h b/rpcs3/Emu/ARMv7/Modules/sceSsl.h index 3d60ac45e5..4d9f7a9bb3 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSsl.h +++ b/rpcs3/Emu/ARMv7/Modules/sceSsl.h @@ -1,14 +1,14 @@ #pragma once -typedef void SceSslCert; -typedef void SceSslCertName; +using SceSslCert = void; +using SceSslCertName = void; struct SceSslMemoryPoolStats { - u32 poolSize; - u32 maxInuseSize; - u32 currentInuseSize; - s32 reserved; + le_t poolSize; + le_t maxInuseSize; + le_t currentInuseSize; + le_t reserved; }; extern psv_log_base sceSsl; diff --git a/rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp b/rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp index 3df26668a4..eabbe2c065 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSulpha.cpp @@ -2,83 +2,71 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceSulpha; - -typedef vm::psv::ptr arg)> SceSulphaCallback; - -struct SceSulphaConfig -{ - SceSulphaCallback notifyCallback; - u32 port; - u32 bookmarkCount; -}; - -struct SceSulphaAgentsRegister; -typedef void SceSulphaHandle; +#include "sceSulpha.h" s32 sceSulphaNetworkInit() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSulphaNetworkShutdown() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaGetDefaultConfig(vm::psv::ptr config) +s32 sceSulphaGetDefaultConfig(vm::ptr config) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaGetNeededMemory(vm::psv::ptr config, vm::psv::ptr sizeInBytes) +s32 sceSulphaGetNeededMemory(vm::cptr config, vm::ptr sizeInBytes) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaInit(vm::psv::ptr config, vm::psv::ptr buffer, u32 sizeInBytes) +s32 sceSulphaInit(vm::cptr config, vm::ptr buffer, u32 sizeInBytes) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSulphaShutdown() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSulphaUpdate() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaFileConnect(vm::psv::ptr filename) +s32 sceSulphaFileConnect(vm::cptr filename) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSulphaFileDisconnect() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaSetBookmark(vm::psv::ptr name, s32 id) +s32 sceSulphaSetBookmark(vm::cptr name, s32 id) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaAgentsGetNeededMemory(vm::psv::ptr config, vm::psv::ptr sizeInBytes) +s32 sceSulphaAgentsGetNeededMemory(vm::cptr config, vm::ptr sizeInBytes) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaAgentsRegister(vm::psv::ptr config, vm::psv::ptr buffer, u32 sizeInBytes, vm::psv::ptr handles) +s32 sceSulphaAgentsRegister(vm::cptr config, vm::ptr buffer, u32 sizeInBytes, vm::ptr handles) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSulphaAgentsUnregister(vm::psv::ptr handles, u32 agentCount) +s32 sceSulphaAgentsUnregister(vm::cptr handles, u32 agentCount) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -89,6 +77,7 @@ psv_log_base sceSulpha("SceSulpha", []() sceSulpha.on_load = nullptr; sceSulpha.on_unload = nullptr; sceSulpha.on_stop = nullptr; + sceSulpha.on_error = nullptr; REG_FUNC(0xB4668AEA, sceSulphaNetworkInit); REG_FUNC(0x0FC71B72, sceSulphaNetworkShutdown); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSulpha.h b/rpcs3/Emu/ARMv7/Modules/sceSulpha.h new file mode 100644 index 0000000000..646d73e2f1 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceSulpha.h @@ -0,0 +1,16 @@ +#pragma once + +using SceSulphaCallback = func_def arg)>; + +struct SceSulphaConfig +{ + vm::lptr notifyCallback; + le_t port; + le_t bookmarkCount; +}; + +struct SceSulphaAgentsRegister; + +using SceSulphaHandle = void; + +extern psv_log_base sceSulpha; diff --git a/rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp b/rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp index 51158c0226..194128abe7 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSysmodule.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceSysmodule; +#include "sceSysmodule.h" s32 sceSysmoduleLoadModule(u16 id) { @@ -32,6 +32,7 @@ psv_log_base sceSysmodule("SceSysmodule", []() sceSysmodule.on_load = nullptr; sceSysmodule.on_unload = nullptr; sceSysmodule.on_stop = nullptr; + sceSysmodule.on_error = nullptr; REG_FUNC(0x79A0160A, sceSysmoduleLoadModule); REG_FUNC(0x31D87805, sceSysmoduleUnloadModule); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSysmodule.h b/rpcs3/Emu/ARMv7/Modules/sceSysmodule.h new file mode 100644 index 0000000000..0153c8725d --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceSysmodule.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceSysmodule; diff --git a/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp b/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp index 0e894f79fb..f9e9c0f318 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.cpp @@ -2,247 +2,91 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceTouch.h" +#include "sceSystemGesture.h" -extern psv_log_base sceSystemGesture; - -enum SceSystemGestureTouchState : s32 +s32 sceSystemGestureInitializePrimitiveTouchRecognizer(vm::ptr parameter) { - SCE_SYSTEM_GESTURE_TOUCH_STATE_INACTIVE = 0, - SCE_SYSTEM_GESTURE_TOUCH_STATE_BEGIN = 1, - SCE_SYSTEM_GESTURE_TOUCH_STATE_ACTIVE = 2, - SCE_SYSTEM_GESTURE_TOUCH_STATE_END = 3 -}; - -enum SceSystemGestureType : s32 -{ - SCE_SYSTEM_GESTURE_TYPE_TAP = 1, - SCE_SYSTEM_GESTURE_TYPE_DRAG = 2, - SCE_SYSTEM_GESTURE_TYPE_TAP_AND_HOLD = 4, - SCE_SYSTEM_GESTURE_TYPE_PINCH_OUT_IN = 8 -}; - -struct SceSystemGestureVector2 -{ - s16 x; - s16 y; -}; - -struct SceSystemGestureRectangle -{ - s16 x; - s16 y; - s16 width; - s16 height; -}; - -struct SceSystemGesturePrimitiveTouchEvent -{ - SceSystemGestureTouchState eventState; - u16 primitiveID; - SceSystemGestureVector2 pressedPosition; - s16 pressedForce; - SceSystemGestureVector2 currentPosition; - s16 currentForce; - SceSystemGestureVector2 deltaVector; - s16 deltaForce; - u64 deltaTime; - u64 elapsedTime; - u8 reserved[56]; -}; - -struct SceSystemGesturePrimitiveTouchRecognizerParameter -{ - u8 reserved[64]; -}; - -struct SceSystemGestureTouchRecognizer -{ - u64 reserved[307]; -}; - -struct SceSystemGestureTouchRecognizerInformation -{ - SceSystemGestureType gestureType; - u32 touchPanelPortID; - SceSystemGestureRectangle rectangle; - u64 updatedTime; - u8 reserved[256]; -}; - -struct SceSystemGestureTapRecognizerParameter -{ - u8 maxTapCount; - u8 reserved[63]; -}; - -struct SceSystemGestureDragRecognizerParameter -{ - u8 reserved[64]; -}; - -struct SceSystemGestureTapAndHoldRecognizerParameter -{ - u64 timeToInvokeEvent; - u8 reserved[56]; -}; - -struct SceSystemGesturePinchOutInRecognizerParameter -{ - u8 reserved[64]; -}; - -union SceSystemGestureTouchRecognizerParameter -{ - u8 parameterBuf[64]; - SceSystemGestureTapRecognizerParameter tap; - SceSystemGestureDragRecognizerParameter drag; - SceSystemGestureTapAndHoldRecognizerParameter tapAndHold; - SceSystemGesturePinchOutInRecognizerParameter pinchOutIn; -}; - -struct SceSystemGestureTapEventProperty -{ - u16 primitiveID; - SceSystemGestureVector2 position; - u8 tappedCount; - u8 reserved[57]; -}; - -struct SceSystemGestureDragEventProperty -{ - u16 primitiveID; - SceSystemGestureVector2 deltaVector; - SceSystemGestureVector2 currentPosition; - SceSystemGestureVector2 pressedPosition; - u8 reserved[50]; -}; - -struct SceSystemGestureTapAndHoldEventProperty -{ - u16 primitiveID; - SceSystemGestureVector2 pressedPosition; - u8 reserved[58]; -}; - -struct SceSystemGesturePinchOutInEventProperty -{ - float scale; - - struct - { - u16 primitiveID; - SceSystemGestureVector2 currentPosition; - SceSystemGestureVector2 deltaVector; - SceSystemGestureVector2 pairedPosition; - } primitive[2]; - - u8 reserved[32]; -}; - -struct SceSystemGestureTouchEvent -{ - u32 eventID; - SceSystemGestureTouchState eventState; - SceSystemGestureType gestureType; - u8 padding[4]; - u64 updatedTime; - - union - { - u8 propertyBuf[64]; - SceSystemGestureTapEventProperty tap; - SceSystemGestureDragEventProperty drag; - SceSystemGestureTapAndHoldEventProperty tapAndHold; - SceSystemGesturePinchOutInEventProperty pinchOutIn; - } property; - - u8 reserved[56]; -}; - -s32 sceSystemGestureInitializePrimitiveTouchRecognizer(vm::psv::ptr parameter) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSystemGestureFinalizePrimitiveTouchRecognizer() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSystemGestureResetPrimitiveTouchRecognizer() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureUpdatePrimitiveTouchRecognizer(vm::psv::ptr pFrontData, vm::psv::ptr pBackData) +s32 sceSystemGestureUpdatePrimitiveTouchRecognizer(vm::cptr pFrontData, vm::cptr pBackData) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetPrimitiveTouchEvents(vm::psv::ptr primitiveEventBuffer, const u32 capacityOfBuffer, vm::psv::ptr numberOfEvent) +s32 sceSystemGestureGetPrimitiveTouchEvents(vm::ptr primitiveEventBuffer, const u32 capacityOfBuffer, vm::ptr numberOfEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceSystemGestureGetPrimitiveTouchEventsCount() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetPrimitiveTouchEventByIndex(const u32 index, vm::psv::ptr primitiveTouchEvent) +s32 sceSystemGestureGetPrimitiveTouchEventByIndex(const u32 index, vm::ptr primitiveTouchEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(const u16 primitiveID, vm::psv::ptr primitiveTouchEvent) +s32 sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(const u16 primitiveID, vm::ptr primitiveTouchEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureCreateTouchRecognizer(vm::psv::ptr touchRecognizer, const SceSystemGestureType gestureType, const u8 touchPanelPortID, vm::psv::ptr rectangle, vm::psv::ptr touchRecognizerParameter) +s32 sceSystemGestureCreateTouchRecognizer(vm::ptr touchRecognizer, const SceSystemGestureType gestureType, const u8 touchPanelPortID, vm::cptr rectangle, vm::cptr touchRecognizerParameter) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetTouchRecognizerInformation(vm::psv::ptr touchRecognizer, vm::psv::ptr information) +s32 sceSystemGestureGetTouchRecognizerInformation(vm::cptr touchRecognizer, vm::ptr information) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureResetTouchRecognizer(vm::psv::ptr touchRecognizer) +s32 sceSystemGestureResetTouchRecognizer(vm::ptr touchRecognizer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureUpdateTouchRecognizer(vm::psv::ptr touchRecognizer) +s32 sceSystemGestureUpdateTouchRecognizer(vm::ptr touchRecognizer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureUpdateTouchRecognizerRectangle(vm::psv::ptr touchRecognizer, vm::psv::ptr rectangle) +s32 sceSystemGestureUpdateTouchRecognizerRectangle(vm::ptr touchRecognizer, vm::cptr rectangle) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetTouchEvents(vm::psv::ptr touchRecognizer, vm::psv::ptr eventBuffer, const u32 capacityOfBuffer, vm::psv::ptr numberOfEvent) +s32 sceSystemGestureGetTouchEvents(vm::cptr touchRecognizer, vm::ptr eventBuffer, const u32 capacityOfBuffer, vm::ptr numberOfEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetTouchEventsCount(vm::psv::ptr touchRecognizer) +s32 sceSystemGestureGetTouchEventsCount(vm::cptr touchRecognizer) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetTouchEventByIndex(vm::psv::ptr touchRecognizer, const u32 index, vm::psv::ptr touchEvent) +s32 sceSystemGestureGetTouchEventByIndex(vm::cptr touchRecognizer, const u32 index, vm::ptr touchEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceSystemGestureGetTouchEventByEventID(vm::psv::ptr touchRecognizer, const u32 eventID, vm::psv::ptr touchEvent) +s32 sceSystemGestureGetTouchEventByEventID(vm::cptr touchRecognizer, const u32 eventID, vm::ptr touchEvent) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -253,6 +97,7 @@ psv_log_base sceSystemGesture("SceSystemGesture", []() sceSystemGesture.on_load = nullptr; sceSystemGesture.on_unload = nullptr; sceSystemGesture.on_stop = nullptr; + sceSystemGesture.on_error = nullptr; REG_FUNC(0x6078A08B, sceSystemGestureInitializePrimitiveTouchRecognizer); REG_FUNC(0xFD5A6504, sceSystemGestureResetPrimitiveTouchRecognizer); diff --git a/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.h b/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.h new file mode 100644 index 0000000000..4f3a85f66a --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceSystemGesture.h @@ -0,0 +1,161 @@ +#pragma once + +#include "sceTouch.h" + +enum SceSystemGestureTouchState : s32 +{ + SCE_SYSTEM_GESTURE_TOUCH_STATE_INACTIVE = 0, + SCE_SYSTEM_GESTURE_TOUCH_STATE_BEGIN = 1, + SCE_SYSTEM_GESTURE_TOUCH_STATE_ACTIVE = 2, + SCE_SYSTEM_GESTURE_TOUCH_STATE_END = 3 +}; + +enum SceSystemGestureType : s32 +{ + SCE_SYSTEM_GESTURE_TYPE_TAP = 1, + SCE_SYSTEM_GESTURE_TYPE_DRAG = 2, + SCE_SYSTEM_GESTURE_TYPE_TAP_AND_HOLD = 4, + SCE_SYSTEM_GESTURE_TYPE_PINCH_OUT_IN = 8 +}; + +struct SceSystemGestureVector2 +{ + le_t x; + le_t y; +}; + +struct SceSystemGestureRectangle +{ + le_t x; + le_t y; + le_t width; + le_t height; +}; + +struct SceSystemGesturePrimitiveTouchEvent +{ + le_t eventState; // SceSystemGestureTouchState + le_t primitiveID; + SceSystemGestureVector2 pressedPosition; + le_t pressedForce; + SceSystemGestureVector2 currentPosition; + le_t currentForce; + SceSystemGestureVector2 deltaVector; + le_t deltaForce; + le_t deltaTime; + le_t elapsedTime; + u8 reserved[56]; +}; + +struct SceSystemGesturePrimitiveTouchRecognizerParameter +{ + u8 reserved[64]; +}; + +struct SceSystemGestureTouchRecognizer +{ + le_t reserved[307]; +}; + +struct SceSystemGestureTouchRecognizerInformation +{ + le_t gestureType; // SceSystemGestureType + le_t touchPanelPortID; + SceSystemGestureRectangle rectangle; + le_t updatedTime; + u8 reserved[256]; +}; + +struct SceSystemGestureTapRecognizerParameter +{ + u8 maxTapCount; + u8 reserved[63]; +}; + +struct SceSystemGestureDragRecognizerParameter +{ + u8 reserved[64]; +}; + +struct SceSystemGestureTapAndHoldRecognizerParameter +{ + le_t timeToInvokeEvent; + u8 reserved[56]; +}; + +struct SceSystemGesturePinchOutInRecognizerParameter +{ + u8 reserved[64]; +}; + +union SceSystemGestureTouchRecognizerParameter +{ + u8 parameterBuf[64]; + SceSystemGestureTapRecognizerParameter tap; + SceSystemGestureDragRecognizerParameter drag; + SceSystemGestureTapAndHoldRecognizerParameter tapAndHold; + SceSystemGesturePinchOutInRecognizerParameter pinchOutIn; +}; + +struct SceSystemGestureTapEventProperty +{ + le_t primitiveID; + SceSystemGestureVector2 position; + u8 tappedCount; + u8 reserved[57]; +}; + +struct SceSystemGestureDragEventProperty +{ + le_t primitiveID; + SceSystemGestureVector2 deltaVector; + SceSystemGestureVector2 currentPosition; + SceSystemGestureVector2 pressedPosition; + u8 reserved[50]; +}; + +struct SceSystemGestureTapAndHoldEventProperty +{ + le_t primitiveID; + SceSystemGestureVector2 pressedPosition; + u8 reserved[58]; +}; + +struct SceSystemGesturePinchOutInEventProperty +{ + le_t scale; + + struct _primitive_t + { + le_t primitiveID; + SceSystemGestureVector2 currentPosition; + SceSystemGestureVector2 deltaVector; + SceSystemGestureVector2 pairedPosition; + }; + + _primitive_t primitive[2]; + u8 reserved[32]; +}; + +struct SceSystemGestureTouchEvent +{ + le_t eventID; + le_t eventState; // SceSystemGestureTouchState + le_t gestureType; // SceSystemGestureType + u8 padding[4]; + le_t updatedTime; + + union _property_t + { + u8 propertyBuf[64]; + SceSystemGestureTapEventProperty tap; + SceSystemGestureDragEventProperty drag; + SceSystemGestureTapAndHoldEventProperty tapAndHold; + SceSystemGesturePinchOutInEventProperty pinchOutIn; + }; + + _property_t property; + u8 reserved[56]; +}; + +extern psv_log_base sceSystemGesture; diff --git a/rpcs3/Emu/ARMv7/Modules/sceTouch.cpp b/rpcs3/Emu/ARMv7/Modules/sceTouch.cpp index b6ce6ccc77..07f74f710d 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceTouch.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceTouch.cpp @@ -4,29 +4,29 @@ #include "sceTouch.h" -s32 sceTouchGetPanelInfo(u32 port, vm::psv::ptr pPanelInfo) +s32 sceTouchGetPanelInfo(u32 port, vm::ptr pPanelInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceTouchRead(u32 port, vm::psv::ptr pData, u32 nBufs) +s32 sceTouchRead(u32 port, vm::ptr pData, u32 nBufs) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceTouchPeek(u32 port, vm::psv::ptr pData, u32 nBufs) +s32 sceTouchPeek(u32 port, vm::ptr pData, u32 nBufs) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceTouchSetSamplingState(u32 port, u32 state) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceTouchGetSamplingState(u32 port, vm::psv::ptr pState) +s32 sceTouchGetSamplingState(u32 port, vm::ptr pState) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -37,6 +37,7 @@ psv_log_base sceTouch("SceTouch", []() sceTouch.on_load = nullptr; sceTouch.on_unload = nullptr; sceTouch.on_stop = nullptr; + sceTouch.on_error = nullptr; REG_FUNC(0x169A1D58, sceTouchRead); REG_FUNC(0xFF082DF0, sceTouchPeek); diff --git a/rpcs3/Emu/ARMv7/Modules/sceTouch.h b/rpcs3/Emu/ARMv7/Modules/sceTouch.h index a71f6003c2..021f6a86c6 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceTouch.h +++ b/rpcs3/Emu/ARMv7/Modules/sceTouch.h @@ -2,14 +2,14 @@ struct SceTouchPanelInfo { - s16 minAaX; - s16 minAaY; - s16 maxAaX; - s16 maxAaY; - s16 minDispX; - s16 minDispY; - s16 maxDispX; - s16 maxDispY; + le_t minAaX; + le_t minAaY; + le_t maxAaX; + le_t maxAaY; + le_t minDispX; + le_t minDispY; + le_t maxDispX; + le_t maxDispY; u8 minForce; u8 maxForce; u8 rsv[30]; @@ -19,17 +19,17 @@ struct SceTouchReport { u8 id; u8 force; - s16 x; - s16 y; + le_t x; + le_t y; s8 rsv[8]; - u16 info; + le_t info; }; struct SceTouchData { - u64 timeStamp; - u32 status; - u32 reportNum; + le_t timeStamp; + le_t status; + le_t reportNum; SceTouchReport report[8]; }; diff --git a/rpcs3/Emu/ARMv7/Modules/sceUlt.cpp b/rpcs3/Emu/ARMv7/Modules/sceUlt.cpp index 5777638f92..4b47e74181 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceUlt.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceUlt.cpp @@ -2,543 +2,386 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -#include "sceLibKernel.h" - -extern psv_log_base sceUlt; - -#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " size") - -struct _SceUltOptParamHeader -{ - s64 reserved[2]; -}; - -struct SceUltWaitingQueueResourcePoolOptParam -{ - _SceUltOptParamHeader header; - u64 reserved[14]; -}; - -CHECK_SIZE(SceUltWaitingQueueResourcePoolOptParam, 128); - -struct SceUltWaitingQueueResourcePool -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltWaitingQueueResourcePool, 256); - -struct SceUltQueueDataResourcePoolOptParam -{ - _SceUltOptParamHeader header; - u64 reserved[14]; -}; - -CHECK_SIZE(SceUltQueueDataResourcePoolOptParam, 128); - -struct SceUltQueueDataResourcePool -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltQueueDataResourcePool, 256); - -struct SceUltMutexOptParam -{ - _SceUltOptParamHeader header; - u32 attribute; - u32 reserved_0; - u64 reserved[13]; -}; - -CHECK_SIZE(SceUltMutexOptParam, 128); - -struct SceUltMutex -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltMutex, 256); - -struct SceUltConditionVariableOptParam -{ - _SceUltOptParamHeader header; - u64 reserved[14]; -}; - -CHECK_SIZE(SceUltConditionVariableOptParam, 128); - -struct SceUltConditionVariable -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltConditionVariable, 256); - -struct SceUltQueueOptParam -{ - _SceUltOptParamHeader header; - u64 reserved[14]; -}; - -CHECK_SIZE(SceUltQueueOptParam, 128); - -struct SceUltQueue -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltQueue, 256); - -struct SceUltReaderWriterLockOptParam -{ - _SceUltOptParamHeader header; - u64 reserved[14]; -}; - -CHECK_SIZE(SceUltReaderWriterLockOptParam, 128); - -struct SceUltReaderWriterLock -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltReaderWriterLock, 256); - -struct SceUltSemaphoreOptParam -{ - _SceUltOptParamHeader header; - u64 reserved[14]; -}; - -CHECK_SIZE(SceUltSemaphoreOptParam, 128); - -struct SceUltSemaphore -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltSemaphore, 256); - -struct SceUltUlthreadRuntimeOptParam -{ - _SceUltOptParamHeader header; - - u32 oneShotThreadStackSize; - s32 workerThreadPriority; - u32 workerThreadCpuAffinityMask; - u32 workerThreadAttr; - vm::psv::ptr workerThreadOptParam; - - u64 reserved[11]; -}; - -CHECK_SIZE(SceUltUlthreadRuntimeOptParam, 128); - -struct SceUltUlthreadRuntime -{ - u64 reserved[128]; -}; - -CHECK_SIZE(SceUltUlthreadRuntime, 1024); - -struct SceUltUlthreadOptParam -{ - _SceUltOptParamHeader header; - u32 attribute; - u32 reserved_0; - u64 reserved[13]; -}; - -CHECK_SIZE(SceUltUlthreadOptParam, 128); - -struct SceUltUlthread -{ - u64 reserved[32]; -}; - -CHECK_SIZE(SceUltUlthread, 256); - -typedef vm::psv::ptr SceUltUlthreadEntry; +#include "sceUlt.h" // Functions -s32 _sceUltWaitingQueueResourcePoolOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltWaitingQueueResourcePoolOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceUltWaitingQueueResourcePoolGetWorkAreaSize(u32 numThreads, u32 numSyncObjects) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltWaitingQueueResourcePoolCreate( - vm::psv::ptr pool, - vm::psv::ptr name, + vm::ptr pool, + vm::cptr name, u32 numThreads, u32 numSyncObjects, - vm::psv::ptr workArea, - vm::psv::ptr optParam, + vm::ptr workArea, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltWaitingQueueResourcePoolDestroy(vm::psv::ptr pool) +s32 sceUltWaitingQueueResourcePoolDestroy(vm::ptr pool) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltQueueDataResourcePoolOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltQueueDataResourcePoolOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceUltQueueDataResourcePoolGetWorkAreaSize(u32 numData, u32 dataSize, u32 numQueueObject) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltQueueDataResourcePoolCreate( - vm::psv::ptr pool, - vm::psv::ptr name, + vm::ptr pool, + vm::cptr name, u32 numData, u32 dataSize, u32 numQueueObject, - vm::psv::ptr waitingQueueResourcePool, - vm::psv::ptr workArea, - vm::psv::ptr optParam, + vm::ptr waitingQueueResourcePool, + vm::ptr workArea, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltQueueDataResourcePoolDestroy(vm::psv::ptr pool) +s32 sceUltQueueDataResourcePoolDestroy(vm::ptr pool) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceUltMutexGetStandaloneWorkAreaSize(u32 waitingQueueDepth, u32 numConditionVariable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltMutexOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltMutexOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltMutexCreate( - vm::psv::ptr mutex, - vm::psv::ptr name, - vm::psv::ptr waitingQueueResourcePool, - vm::psv::ptr optParam, + vm::ptr mutex, + vm::cptr name, + vm::ptr waitingQueueResourcePool, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltMutexCreateStandalone( - vm::psv::ptr mutex, - vm::psv::ptr name, + vm::ptr mutex, + vm::cptr name, u32 numConditionVariable, u32 maxNumThreads, - vm::psv::ptr workArea, - vm::psv::ptr optParam, + vm::ptr workArea, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltMutexLock(vm::psv::ptr mutex) +s32 sceUltMutexLock(vm::ptr mutex) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltMutexTryLock(vm::psv::ptr mutex) +s32 sceUltMutexTryLock(vm::ptr mutex) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltMutexUnlock(vm::psv::ptr mutex) +s32 sceUltMutexUnlock(vm::ptr mutex) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltMutexDestroy(vm::psv::ptr mutex) +s32 sceUltMutexDestroy(vm::ptr mutex) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltConditionVariableOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltConditionVariableOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltConditionVariableCreate( - vm::psv::ptr conditionVariable, - vm::psv::ptr name, - vm::psv::ptr mutex, - vm::psv::ptr optParam, + vm::ptr conditionVariable, + vm::cptr name, + vm::ptr mutex, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltConditionVariableSignal(vm::psv::ptr conditionVariable) +s32 sceUltConditionVariableSignal(vm::ptr conditionVariable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltConditionVariableSignalAll(vm::psv::ptr conditionVariable) +s32 sceUltConditionVariableSignalAll(vm::ptr conditionVariable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltConditionVariableWait(vm::psv::ptr conditionVariable) +s32 sceUltConditionVariableWait(vm::ptr conditionVariable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltConditionVariableDestroy(vm::psv::ptr conditionVariable) +s32 sceUltConditionVariableDestroy(vm::ptr conditionVariable) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltQueueOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltQueueOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceUltQueueGetStandaloneWorkAreaSize(u32 queueDepth, u32 dataSize, u32 waitingQueueLength) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltQueueCreate( - vm::psv::ptr queue, - vm::psv::ptr _name, + vm::ptr queue, + vm::cptr _name, u32 dataSize, - vm::psv::ptr resourcePool, - vm::psv::ptr queueResourcePool, - vm::psv::ptr optParam, + vm::ptr resourcePool, + vm::ptr queueResourcePool, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltQueueCreateStandalone( - vm::psv::ptr queue, - vm::psv::ptr name, + vm::ptr queue, + vm::cptr name, u32 queueDepth, u32 dataSize, u32 waitingQueueLength, - vm::psv::ptr workArea, - vm::psv::ptr optParam, + vm::ptr workArea, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltQueuePush(vm::psv::ptr queue, vm::psv::ptr data) +s32 sceUltQueuePush(vm::ptr queue, vm::cptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltQueueTryPush(vm::psv::ptr queue, vm::psv::ptr data) +s32 sceUltQueueTryPush(vm::ptr queue, vm::cptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltQueuePop(vm::psv::ptr queue, vm::psv::ptr data) +s32 sceUltQueuePop(vm::ptr queue, vm::ptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltQueueTryPop(vm::psv::ptr queue, vm::psv::ptr data) +s32 sceUltQueueTryPop(vm::ptr queue, vm::ptr data) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltQueueDestroy(vm::psv::ptr queue) +s32 sceUltQueueDestroy(vm::ptr queue) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltReaderWriterLockOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltReaderWriterLockOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltReaderWriterLockCreate( - vm::psv::ptr rwlock, - vm::psv::ptr name, - vm::psv::ptr waitingQueueResourcePool, - vm::psv::ptr optParam, + vm::ptr rwlock, + vm::cptr name, + vm::ptr waitingQueueResourcePool, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltReaderWriterLockCreateStandalone( - vm::psv::ptr rwlock, - vm::psv::ptr name, + vm::ptr rwlock, + vm::cptr name, u32 waitingQueueDepth, - vm::psv::ptr workArea, - vm::psv::ptr optParam, + vm::ptr workArea, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceUltReaderWriterLockGetStandaloneWorkAreaSize(u32 waitingQueueDepth) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockLockRead(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockLockRead(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockTryLockRead(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockTryLockRead(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockUnlockRead(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockUnlockRead(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockLockWrite(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockLockWrite(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockTryLockWrite(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockTryLockWrite(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockUnlockWrite(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockUnlockWrite(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltReaderWriterLockDestroy(vm::psv::ptr rwlock) +s32 sceUltReaderWriterLockDestroy(vm::ptr rwlock) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltSemaphoreOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltSemaphoreOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltSemaphoreCreate( - vm::psv::ptr semaphore, - vm::psv::ptr name, + vm::ptr semaphore, + vm::cptr name, s32 numInitialResource, - vm::psv::ptr waitingQueueResourcePool, - vm::psv::ptr optParam, + vm::ptr waitingQueueResourcePool, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltSemaphoreAcquire(vm::psv::ptr semaphore, s32 numResource) +s32 sceUltSemaphoreAcquire(vm::ptr semaphore, s32 numResource) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltSemaphoreTryAcquire(vm::psv::ptr semaphore, s32 numResource) +s32 sceUltSemaphoreTryAcquire(vm::ptr semaphore, s32 numResource) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltSemaphoreRelease(vm::psv::ptr semaphore, s32 numResource) +s32 sceUltSemaphoreRelease(vm::ptr semaphore, s32 numResource) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltSemaphoreDestroy(vm::psv::ptr semaphore) +s32 sceUltSemaphoreDestroy(vm::ptr semaphore) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltUlthreadRuntimeOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltUlthreadRuntimeOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } u32 sceUltUlthreadRuntimeGetWorkAreaSize(u32 numMaxUlthread, u32 numWorkerThread) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltUlthreadRuntimeCreate( - vm::psv::ptr runtime, - vm::psv::ptr name, + vm::ptr runtime, + vm::cptr name, u32 numMaxUlthread, u32 numWorkerThread, - vm::psv::ptr workArea, - vm::psv::ptr optParam, + vm::ptr workArea, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltUlthreadRuntimeDestroy(vm::psv::ptr runtime) +s32 sceUltUlthreadRuntimeDestroy(vm::ptr runtime) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 _sceUltUlthreadOptParamInitialize(vm::psv::ptr optParam, u32 buildVersion) +s32 _sceUltUlthreadOptParamInitialize(vm::ptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _sceUltUlthreadCreate( - vm::psv::ptr ulthread, - vm::psv::ptr name, - SceUltUlthreadEntry entry, + vm::ptr ulthread, + vm::cptr name, + vm::ptr entry, u32 arg, - vm::psv::ptr context, + vm::ptr context, u32 sizeContext, - vm::psv::ptr runtime, - vm::psv::ptr optParam, + vm::ptr runtime, + vm::cptr optParam, u32 buildVersion) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceUltUlthreadYield() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceUltUlthreadExit(s32 status) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltUlthreadJoin(vm::psv::ptr ulthread, vm::psv::ptr status) +s32 sceUltUlthreadJoin(vm::ptr ulthread, vm::ptr status) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltUlthreadTryJoin(vm::psv::ptr ulthread, vm::psv::ptr status) +s32 sceUltUlthreadTryJoin(vm::ptr ulthread, vm::ptr status) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceUltUlthreadGetSelf(vm::psv::pptr ulthread) +s32 sceUltUlthreadGetSelf(vm::pptr ulthread) { - throw __FUNCTION__; + throw EXCEPTION(""); } #define REG_FUNC(nid, name) reg_psv_func(nid, &sceUlt, #name, name) @@ -548,6 +391,7 @@ psv_log_base sceUlt("SceUlt", []() sceUlt.on_load = nullptr; sceUlt.on_unload = nullptr; sceUlt.on_stop = nullptr; + sceUlt.on_error = nullptr; REG_FUNC(0xEF094E35, _sceUltWaitingQueueResourcePoolOptParamInitialize); REG_FUNC(0x644DA029, sceUltWaitingQueueResourcePoolGetWorkAreaSize); diff --git a/rpcs3/Emu/ARMv7/Modules/sceUlt.h b/rpcs3/Emu/ARMv7/Modules/sceUlt.h new file mode 100644 index 0000000000..f26f4d303f --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceUlt.h @@ -0,0 +1,158 @@ +#pragma once + +#include "sceLibKernel.h" + +struct _SceUltOptParamHeader +{ + le_t reserved[2]; +}; + +struct SceUltWaitingQueueResourcePoolOptParam +{ + _SceUltOptParamHeader header; + le_t reserved[14]; +}; + +CHECK_SIZE(SceUltWaitingQueueResourcePoolOptParam, 128); + +struct SceUltWaitingQueueResourcePool +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltWaitingQueueResourcePool, 256); + +struct SceUltQueueDataResourcePoolOptParam +{ + _SceUltOptParamHeader header; + le_t reserved[14]; +}; + +CHECK_SIZE(SceUltQueueDataResourcePoolOptParam, 128); + +struct SceUltQueueDataResourcePool +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltQueueDataResourcePool, 256); + +struct SceUltMutexOptParam +{ + _SceUltOptParamHeader header; + le_t attribute; + le_t reserved_0; + le_t reserved[13]; +}; + +CHECK_SIZE(SceUltMutexOptParam, 128); + +struct SceUltMutex +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltMutex, 256); + +struct SceUltConditionVariableOptParam +{ + _SceUltOptParamHeader header; + le_t reserved[14]; +}; + +CHECK_SIZE(SceUltConditionVariableOptParam, 128); + +struct SceUltConditionVariable +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltConditionVariable, 256); + +struct SceUltQueueOptParam +{ + _SceUltOptParamHeader header; + le_t reserved[14]; +}; + +CHECK_SIZE(SceUltQueueOptParam, 128); + +struct SceUltQueue +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltQueue, 256); + +struct SceUltReaderWriterLockOptParam +{ + _SceUltOptParamHeader header; + le_t reserved[14]; +}; + +CHECK_SIZE(SceUltReaderWriterLockOptParam, 128); + +struct SceUltReaderWriterLock +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltReaderWriterLock, 256); + +struct SceUltSemaphoreOptParam +{ + _SceUltOptParamHeader header; + le_t reserved[14]; +}; + +CHECK_SIZE(SceUltSemaphoreOptParam, 128); + +struct SceUltSemaphore +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltSemaphore, 256); + +struct SceUltUlthreadRuntimeOptParam +{ + _SceUltOptParamHeader header; + + le_t oneShotThreadStackSize; + le_t workerThreadPriority; + le_t workerThreadCpuAffinityMask; + le_t workerThreadAttr; + vm::lcptr workerThreadOptParam; + + le_t reserved[11]; +}; + +CHECK_SIZE(SceUltUlthreadRuntimeOptParam, 128); + +struct SceUltUlthreadRuntime +{ + le_t reserved[128]; +}; + +CHECK_SIZE(SceUltUlthreadRuntime, 1024); + +struct SceUltUlthreadOptParam +{ + _SceUltOptParamHeader header; + le_t attribute; + le_t reserved_0; + le_t reserved[13]; +}; + +CHECK_SIZE(SceUltUlthreadOptParam, 128); + +struct SceUltUlthread +{ + le_t reserved[32]; +}; + +CHECK_SIZE(SceUltUlthread, 256); + +using SceUltUlthreadEntry = func_def; + +extern psv_log_base sceUlt; diff --git a/rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp b/rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp index 7899777f97..190645df00 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceVideodec.cpp @@ -2,177 +2,51 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceVideodec; +#include "sceVideodec.h" -struct SceVideodecQueryInitInfoHwAvcdec +s32 sceVideodecInitLibrary(u32 codecType, vm::cptr pInitInfo) { - u32 size; - u32 horizontal; - u32 vertical; - u32 numOfRefFrames; - u32 numOfStreams; -}; - -union SceVideodecQueryInitInfo -{ - u8 reserved[32]; - SceVideodecQueryInitInfoHwAvcdec hwAvc; -}; - -struct SceVideodecTimeStamp -{ - u32 upper; - u32 lower; -}; - -struct SceAvcdecQueryDecoderInfo -{ - u32 horizontal; - u32 vertical; - u32 numOfRefFrames; - -}; - -struct SceAvcdecDecoderInfo -{ - u32 frameMemSize; - -}; - -struct SceAvcdecBuf -{ - vm::psv::ptr pBuf; - u32 size; -}; - -struct SceAvcdecCtrl -{ - u32 handle; - SceAvcdecBuf frameBuf; -}; - -struct SceAvcdecAu -{ - SceVideodecTimeStamp pts; - SceVideodecTimeStamp dts; - SceAvcdecBuf es; -}; - -struct SceAvcdecInfo -{ - u32 numUnitsInTick; - u32 timeScale; - u8 fixedFrameRateFlag; - - u8 aspectRatioIdc; - u16 sarWidth; - u16 sarHeight; - - u8 colourPrimaries; - u8 transferCharacteristics; - u8 matrixCoefficients; - - u8 videoFullRangeFlag; - - u8 picStruct[2]; - u8 ctType; - - u8 padding[3]; -}; - -struct SceAvcdecFrameOptionRGBA -{ - u8 alpha; - u8 cscCoefficient; - u8 reserved[14]; -}; - -union SceAvcdecFrameOption -{ - u8 reserved[16]; - SceAvcdecFrameOptionRGBA rgba; -}; - - -struct SceAvcdecFrame -{ - u32 pixelType; - u32 framePitch; - u32 frameWidth; - u32 frameHeight; - - u32 horizontalSize; - u32 verticalSize; - - u32 frameCropLeftOffset; - u32 frameCropRightOffset; - u32 frameCropTopOffset; - u32 frameCropBottomOffset; - - SceAvcdecFrameOption opt; - - vm::psv::ptr pPicture[2]; -}; - - -struct SceAvcdecPicture -{ - u32 size; - SceAvcdecFrame frame; - SceAvcdecInfo info; -}; - -struct SceAvcdecArrayPicture -{ - u32 numOfOutput; - u32 numOfElm; - vm::psv::lpptr pPicture; -}; - - -s32 sceVideodecInitLibrary(u32 codecType, vm::psv::ptr pInitInfo) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVideodecTermLibrary(u32 codecType) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecQueryDecoderMemSize(u32 codecType, vm::psv::ptr pDecoderInfo, vm::psv::ptr pMemInfo) +s32 sceAvcdecQueryDecoderMemSize(u32 codecType, vm::cptr pDecoderInfo, vm::ptr pMemInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecCreateDecoder(u32 codecType, vm::psv::ptr pCtrl, vm::psv::ptr pDecoderInfo) +s32 sceAvcdecCreateDecoder(u32 codecType, vm::ptr pCtrl, vm::cptr pDecoderInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecDeleteDecoder(vm::psv::ptr pCtrl) +s32 sceAvcdecDeleteDecoder(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecDecodeAvailableSize(vm::psv::ptr pCtrl) +s32 sceAvcdecDecodeAvailableSize(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecDecode(vm::psv::ptr pCtrl, vm::psv::ptr pAu, vm::psv::ptr pArrayPicture) +s32 sceAvcdecDecode(vm::ptr pCtrl, vm::cptr pAu, vm::ptr pArrayPicture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecDecodeStop(vm::psv::ptr pCtrl, vm::psv::ptr pArrayPicture) +s32 sceAvcdecDecodeStop(vm::ptr pCtrl, vm::ptr pArrayPicture) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceAvcdecDecodeFlush(vm::psv::ptr pCtrl) +s32 sceAvcdecDecodeFlush(vm::ptr pCtrl) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -183,6 +57,7 @@ psv_log_base sceVideodec("SceVideodec", []() sceVideodec.on_load = nullptr; sceVideodec.on_unload = nullptr; sceVideodec.on_stop = nullptr; + sceVideodec.on_error = nullptr; REG_FUNC(0xF1AF65A3, sceVideodecInitLibrary); REG_FUNC(0x3A5F4924, sceVideodecTermLibrary); diff --git a/rpcs3/Emu/ARMv7/Modules/sceVideodec.h b/rpcs3/Emu/ARMv7/Modules/sceVideodec.h new file mode 100644 index 0000000000..825d4fc1b3 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceVideodec.h @@ -0,0 +1,126 @@ +#pragma once + +struct SceVideodecQueryInitInfoHwAvcdec +{ + le_t size; + le_t horizontal; + le_t vertical; + le_t numOfRefFrames; + le_t numOfStreams; +}; + +union SceVideodecQueryInitInfo +{ + u8 reserved[32]; + SceVideodecQueryInitInfoHwAvcdec hwAvc; +}; + +struct SceVideodecTimeStamp +{ + le_t upper; + le_t lower; +}; + +struct SceAvcdecQueryDecoderInfo +{ + le_t horizontal; + le_t vertical; + le_t numOfRefFrames; +}; + +struct SceAvcdecDecoderInfo +{ + le_t frameMemSize; +}; + +struct SceAvcdecBuf +{ + vm::lptr pBuf; + le_t size; +}; + +struct SceAvcdecCtrl +{ + le_t handle; + SceAvcdecBuf frameBuf; +}; + +struct SceAvcdecAu +{ + SceVideodecTimeStamp pts; + SceVideodecTimeStamp dts; + SceAvcdecBuf es; +}; + +struct SceAvcdecInfo +{ + le_t numUnitsInTick; + le_t timeScale; + u8 fixedFrameRateFlag; + + u8 aspectRatioIdc; + le_t sarWidth; + le_t sarHeight; + + u8 colourPrimaries; + u8 transferCharacteristics; + u8 matrixCoefficients; + + u8 videoFullRangeFlag; + + u8 picStruct[2]; + u8 ctType; + + u8 padding[3]; +}; + +struct SceAvcdecFrameOptionRGBA +{ + u8 alpha; + u8 cscCoefficient; + u8 reserved[14]; +}; + +union SceAvcdecFrameOption +{ + u8 reserved[16]; + SceAvcdecFrameOptionRGBA rgba; +}; + + +struct SceAvcdecFrame +{ + le_t pixelType; + le_t framePitch; + le_t frameWidth; + le_t frameHeight; + + le_t horizontalSize; + le_t verticalSize; + + le_t frameCropLeftOffset; + le_t frameCropRightOffset; + le_t frameCropTopOffset; + le_t frameCropBottomOffset; + + SceAvcdecFrameOption opt; + + vm::lptr pPicture[2]; +}; + + +struct SceAvcdecPicture +{ + le_t size; + SceAvcdecFrame frame; + SceAvcdecInfo info; +}; + +struct SceAvcdecArrayPicture +{ + le_t numOfOutput; + le_t numOfElm; + vm::lpptr pPicture; +}; + +extern psv_log_base sceVideodec; diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp b/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp index cddc5f43d2..a76177503e 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceVoice.cpp @@ -2,251 +2,131 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceVoice; +#include "sceVoice.h" -enum SceVoicePortType : s32 +s32 sceVoiceInit(vm::ptr pArg, SceVoiceVersion version) { - SCEVOICE_PORTTYPE_NULL = -1, - SCEVOICE_PORTTYPE_IN_DEVICE = 0, - SCEVOICE_PORTTYPE_IN_PCMAUDIO = 1, - SCEVOICE_PORTTYPE_IN_VOICE = 2, - SCEVOICE_PORTTYPE_OUT_PCMAUDIO = 3, - SCEVOICE_PORTTYPE_OUT_VOICE = 4, - SCEVOICE_PORTTYPE_OUT_DEVICE = 5 -}; - -enum SceVoicePortState : s32 -{ - SCEVOICE_PORTSTATE_NULL = -1, - SCEVOICE_PORTSTATE_IDLE = 0, - SCEVOICE_PORTSTATE_READY = 1, - SCEVOICE_PORTSTATE_BUFFERING = 2, - SCEVOICE_PORTSTATE_RUNNING = 3 -}; - -enum SceVoiceBitRate : s32 -{ - SCEVOICE_BITRATE_NULL = -1, - SCEVOICE_BITRATE_3850 = 3850, - SCEVOICE_BITRATE_4650 = 4650, - SCEVOICE_BITRATE_5700 = 5700, - SCEVOICE_BITRATE_7300 = 7300 -}; - -enum SceVoiceSamplingRate : s32 -{ - SCEVOICE_SAMPLINGRATE_NULL = -1, - SCEVOICE_SAMPLINGRATE_16000 = 16000 -}; - -enum SceVoicePcmDataType : s32 -{ - SCEVOICE_PCM_NULL = -1, - SCEVOICE_PCM_SHORT_LITTLE_ENDIAN = 0 -}; - -enum SceVoiceVersion : s32 -{ - SCEVOICE_VERSION_100 = 100 -}; - -enum SceVoiceAppType : s32 -{ - SCEVOICE_APPTYPE_GAME = 1 << 29 -}; - -struct SceVoicePCMFormat -{ - SceVoicePcmDataType dataType; - SceVoiceSamplingRate sampleRate; -}; - -struct SceVoiceResourceInfo -{ - u16 maxInVoicePort; - u16 maxOutVoicePort; - u16 maxInDevicePort; - u16 maxOutDevicePort; - u16 maxTotalPort; -}; - -struct SceVoiceBasePortInfo -{ - SceVoicePortType portType; - SceVoicePortState state; - vm::psv::ptr pEdge; - u32 numByte; - u32 frameSize; - u16 numEdge; - u16 reserved; -}; - -struct SceVoicePortParam -{ - SceVoicePortType portType; - u16 threshold; - u16 bMute; - float volume; - - union - { - struct - { - SceVoiceBitRate bitrate; - } voice; - - struct - { - u32 bufSize; - SceVoicePCMFormat format; - } pcmaudio; - - - struct - { - u32 playerId; - } device; - }; -}; - -typedef vm::psv::ptr event)> SceVoiceEventCallback; - -struct SceVoiceInitParam -{ - s32 appType; - SceVoiceEventCallback onEvent; - u8 reserved[24]; -}; - -struct SceVoiceStartParam -{ - s32 container; - u8 reserved[28]; -}; - -s32 sceVoiceInit(vm::psv::ptr pArg, SceVoiceVersion version) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceEnd() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceStart(vm::psv::ptr pArg) +s32 sceVoiceStart(vm::ptr pArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceStop() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceResetPort(u32 portId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceCreatePort(vm::psv::ptr portId, vm::psv::ptr pArg) +s32 sceVoiceCreatePort(vm::ptr portId, vm::cptr pArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceUpdatePort(u32 portId, vm::psv::ptr pArg) +s32 sceVoiceUpdatePort(u32 portId, vm::cptr pArg) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceConnectIPortToOPort(u32 ips, u32 ops) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceDisconnectIPortFromOPort(u32 ips, u32 ops) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceDeletePort(u32 portId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceWriteToIPort(u32 ips, vm::psv::ptr data, vm::psv::ptr size, s16 frameGaps) +s32 sceVoiceWriteToIPort(u32 ips, vm::cptr data, vm::ptr size, s16 frameGaps) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceReadFromOPort(u32 ops, vm::psv::ptr data, vm::psv::ptr size) +s32 sceVoiceReadFromOPort(u32 ops, vm::ptr data, vm::ptr size) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceSetMuteFlagAll(u16 bMuted) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceSetMuteFlag(u32 portId, u16 bMuted) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceGetMuteFlag(u32 portId, vm::psv::ptr bMuted) +s32 sceVoiceGetMuteFlag(u32 portId, vm::ptr bMuted) { - throw __FUNCTION__; + throw EXCEPTION(""); } -//s32 sceVoiceSetVolume(u32 portId, float volume) -//{ -// throw __FUNCTION__; -//} - -s32 sceVoiceGetVolume(u32 portId, vm::psv::ptr volume) +s32 sceVoiceSetVolume(u32 portId, float volume) { - throw __FUNCTION__; + throw EXCEPTION(""); +} + +s32 sceVoiceGetVolume(u32 portId, vm::ptr volume) +{ + throw EXCEPTION(""); } s32 sceVoiceSetBitRate(u32 portId, SceVoiceBitRate bitrate) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceGetBitRate(u32 portId, vm::psv::ptr bitrate) +s32 sceVoiceGetBitRate(u32 portId, vm::ptr bitrate) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceGetPortInfo(u32 portId, vm::psv::ptr pInfo) +s32 sceVoiceGetPortInfo(u32 portId, vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoicePausePort(u32 portId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceResumePort(u32 portId) { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoicePausePortAll() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceResumePortAll() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceGetResourceInfo(vm::psv::ptr pInfo) +s32 sceVoiceGetResourceInfo(vm::ptr pInfo) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -257,6 +137,7 @@ psv_log_base sceVoice("SceVoice", []() sceVoice.on_load = nullptr; sceVoice.on_unload = nullptr; sceVoice.on_stop = nullptr; + sceVoice.on_error = nullptr; REG_FUNC(0xD02C00B4, sceVoiceGetBitRate); REG_FUNC(0xC913F7E9, sceVoiceGetMuteFlag); diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoice.h b/rpcs3/Emu/ARMv7/Modules/sceVoice.h new file mode 100644 index 0000000000..267ca6e335 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceVoice.h @@ -0,0 +1,132 @@ +#pragma once + +enum SceVoicePortType : s32 +{ + SCEVOICE_PORTTYPE_NULL = -1, + SCEVOICE_PORTTYPE_IN_DEVICE = 0, + SCEVOICE_PORTTYPE_IN_PCMAUDIO = 1, + SCEVOICE_PORTTYPE_IN_VOICE = 2, + SCEVOICE_PORTTYPE_OUT_PCMAUDIO = 3, + SCEVOICE_PORTTYPE_OUT_VOICE = 4, + SCEVOICE_PORTTYPE_OUT_DEVICE = 5 +}; + +enum SceVoicePortState : s32 +{ + SCEVOICE_PORTSTATE_NULL = -1, + SCEVOICE_PORTSTATE_IDLE = 0, + SCEVOICE_PORTSTATE_READY = 1, + SCEVOICE_PORTSTATE_BUFFERING = 2, + SCEVOICE_PORTSTATE_RUNNING = 3 +}; + +enum SceVoiceBitRate : s32 +{ + SCEVOICE_BITRATE_NULL = -1, + SCEVOICE_BITRATE_3850 = 3850, + SCEVOICE_BITRATE_4650 = 4650, + SCEVOICE_BITRATE_5700 = 5700, + SCEVOICE_BITRATE_7300 = 7300 +}; + +enum SceVoiceSamplingRate : s32 +{ + SCEVOICE_SAMPLINGRATE_NULL = -1, + SCEVOICE_SAMPLINGRATE_16000 = 16000 +}; + +enum SceVoicePcmDataType : s32 +{ + SCEVOICE_PCM_NULL = -1, + SCEVOICE_PCM_SHORT_LITTLE_ENDIAN = 0 +}; + +enum SceVoiceVersion : s32 +{ + SCEVOICE_VERSION_100 = 100 +}; + +enum SceVoiceAppType : s32 +{ + SCEVOICE_APPTYPE_GAME = 1 << 29 +}; + +struct SceVoicePCMFormat +{ + le_t dataType; // SceVoicePcmDataType + le_t sampleRate; // SceVoiceSamplingRate +}; + +struct SceVoiceResourceInfo +{ + le_t maxInVoicePort; + le_t maxOutVoicePort; + le_t maxInDevicePort; + le_t maxOutDevicePort; + le_t maxTotalPort; +}; + +struct SceVoiceBasePortInfo +{ + le_t portType; // SceVoicePortType + le_t state; // SceVoicePortState + vm::lptr pEdge; + le_t numByte; + le_t frameSize; + le_t numEdge; + le_t reserved; +}; + +struct SceVoicePortParam +{ + // aux structs + + struct _voice_t + { + le_t bitrate; // SceVoiceBitRate + }; + + struct _pcmaudio_t + { + using _format_t = SceVoicePCMFormat; + + le_t bufSize; + _format_t format; + }; + + struct _device_t + { + le_t playerId; + }; + + // struct members + + le_t portType; // SceVoicePortType + le_t threshold; + le_t bMute; + le_t volume; + + union + { + _pcmaudio_t pcmaudio; + _device_t device; + _voice_t voice; + }; +}; + +using SceVoiceEventCallback = func_def event)>; + +struct SceVoiceInitParam +{ + le_t appType; + vm::lptr onEvent; + u8 reserved[24]; +}; + +struct SceVoiceStartParam +{ + le_t container; + u8 reserved[28]; +}; + +extern psv_log_base sceVoice; diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp b/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp index 050570aaa9..0adead3bfc 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.cpp @@ -2,113 +2,91 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceVoiceQoS; - -typedef s32 SceVoiceQoSLocalId; -typedef s32 SceVoiceQoSRemoteId; -typedef s32 SceVoiceQoSConnectionId; - -enum SceVoiceQoSAttributeId : s32 -{ - SCE_VOICE_QOS_ATTR_MIC_VOLUME, - SCE_VOICE_QOS_ATTR_MIC_MUTE, - SCE_VOICE_QOS_ATTR_SPEAKER_VOLUME, - SCE_VOICE_QOS_ATTR_SPEAKER_MUTE, - SCE_VOICE_QOS_ATTR_DESIRED_OUT_BIT_RATE -}; - -enum SceVoiceQoSStatusId : s32 -{ - SCE_VOICE_QOS_IN_BITRATE, - SCE_VOICE_QOS_OUT_BITRATE, - SCE_VOICE_QOS_OUT_READ_BITRATE, - SCE_VOICE_QOS_IN_FRAME_RECEIVED_RATIO, - SCE_VOICE_QOS_HEARTBEAT_FLAG -}; +#include "sceVoiceQoS.h" s32 sceVoiceQoSInit() { - throw __FUNCTION__; + throw EXCEPTION(""); } s32 sceVoiceQoSEnd() { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSCreateLocalEndpoint(vm::psv::ptr pLocalId) +s32 sceVoiceQoSCreateLocalEndpoint(vm::ptr pLocalId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSDeleteLocalEndpoint(SceVoiceQoSLocalId localId) +s32 sceVoiceQoSDeleteLocalEndpoint(s32 localId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSCreateRemoteEndpoint(vm::psv::ptr pRemoteId) +s32 sceVoiceQoSCreateRemoteEndpoint(vm::ptr pRemoteId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSDeleteRemoteEndpoint(SceVoiceQoSRemoteId remoteId) +s32 sceVoiceQoSDeleteRemoteEndpoint(s32 remoteId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSConnect(vm::psv::ptr pConnectionId, SceVoiceQoSLocalId localId, SceVoiceQoSRemoteId remoteId) +s32 sceVoiceQoSConnect(vm::ptr pConnectionId, s32 localId, s32 remoteId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSDisconnect(SceVoiceQoSConnectionId connectionId) +s32 sceVoiceQoSDisconnect(s32 connectionId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSGetLocalEndpoint(SceVoiceQoSConnectionId connectionId, vm::psv::ptr pLocalId) +s32 sceVoiceQoSGetLocalEndpoint(s32 connectionId, vm::ptr pLocalId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSGetRemoteEndpoint(SceVoiceQoSConnectionId connectionId, vm::psv::ptr pRemoteId) +s32 sceVoiceQoSGetRemoteEndpoint(s32 connectionId, vm::ptr pRemoteId) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSSetLocalEndpointAttribute(SceVoiceQoSLocalId localId, SceVoiceQoSAttributeId attributeId, vm::psv::ptr pAttributeValue, s32 attributeSize) +s32 sceVoiceQoSSetLocalEndpointAttribute(s32 localId, SceVoiceQoSAttributeId attributeId, vm::cptr pAttributeValue, s32 attributeSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSGetLocalEndpointAttribute(SceVoiceQoSLocalId localId, SceVoiceQoSAttributeId attributeId, vm::psv::ptr pAttributeValue, s32 attributeSize) +s32 sceVoiceQoSGetLocalEndpointAttribute(s32 localId, SceVoiceQoSAttributeId attributeId, vm::ptr pAttributeValue, s32 attributeSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSSetConnectionAttribute(SceVoiceQoSConnectionId connectionId, SceVoiceQoSAttributeId attributeId, vm::psv::ptr pAttributeValue, s32 attributeSize) +s32 sceVoiceQoSSetConnectionAttribute(s32 connectionId, SceVoiceQoSAttributeId attributeId, vm::cptr pAttributeValue, s32 attributeSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSGetConnectionAttribute(SceVoiceQoSConnectionId connectionId, SceVoiceQoSAttributeId attributeId, vm::psv::ptr pAttributeValue, s32 attributeSize) +s32 sceVoiceQoSGetConnectionAttribute(s32 connectionId, SceVoiceQoSAttributeId attributeId, vm::ptr pAttributeValue, s32 attributeSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSGetStatus(SceVoiceQoSConnectionId connectionId, SceVoiceQoSStatusId statusId, vm::psv::ptr pStatusValue, s32 statusSize) +s32 sceVoiceQoSGetStatus(s32 connectionId, SceVoiceQoSStatusId statusId, vm::ptr pStatusValue, s32 statusSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSWritePacket(SceVoiceQoSConnectionId connectionId, vm::psv::ptr pData, vm::psv::ptr pSize) +s32 sceVoiceQoSWritePacket(s32 connectionId, vm::cptr pData, vm::ptr pSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } -s32 sceVoiceQoSReadPacket(SceVoiceQoSConnectionId connectionId, vm::psv::ptr pData, vm::psv::ptr pSize) +s32 sceVoiceQoSReadPacket(s32 connectionId, vm::ptr pData, vm::ptr pSize) { - throw __FUNCTION__; + throw EXCEPTION(""); } @@ -119,6 +97,7 @@ psv_log_base sceVoiceQoS("SceVoiceQos", []() sceVoiceQoS.on_load = nullptr; sceVoiceQoS.on_unload = nullptr; sceVoiceQoS.on_stop = nullptr; + sceVoiceQoS.on_error = nullptr; REG_FUNC(0x4B5FFF1C, sceVoiceQoSInit); REG_FUNC(0xFB0B747B, sceVoiceQoSEnd); diff --git a/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.h b/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.h new file mode 100644 index 0000000000..c66b56b366 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceVoiceQoS.h @@ -0,0 +1,21 @@ +#pragma once + +enum SceVoiceQoSAttributeId : s32 +{ + SCE_VOICE_QOS_ATTR_MIC_VOLUME, + SCE_VOICE_QOS_ATTR_MIC_MUTE, + SCE_VOICE_QOS_ATTR_SPEAKER_VOLUME, + SCE_VOICE_QOS_ATTR_SPEAKER_MUTE, + SCE_VOICE_QOS_ATTR_DESIRED_OUT_BIT_RATE +}; + +enum SceVoiceQoSStatusId : s32 +{ + SCE_VOICE_QOS_IN_BITRATE, + SCE_VOICE_QOS_OUT_BITRATE, + SCE_VOICE_QOS_OUT_READ_BITRATE, + SCE_VOICE_QOS_IN_FRAME_RECEIVED_RATIO, + SCE_VOICE_QOS_HEARTBEAT_FLAG +}; + +extern psv_log_base sceVoiceQoS; diff --git a/rpcs3/Emu/ARMv7/Modules/sceXml.cpp b/rpcs3/Emu/ARMv7/Modules/sceXml.cpp index 525ce21565..f07d94665b 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceXml.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceXml.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/ARMv7/PSVFuncList.h" -extern psv_log_base sceXml; +#include "sceXml.h" #define REG_FUNC(nid, name) reg_psv_func(nid, &sceXml, #name, name) @@ -11,6 +11,7 @@ psv_log_base sceXml("SceXml", []() sceXml.on_load = nullptr; sceXml.on_unload = nullptr; sceXml.on_stop = nullptr; + sceXml.on_error = nullptr; //REG_FUNC(0x57400A1A, _ZN3sce3Xml10SimpleDataC1EPKcj); //REG_FUNC(0x7E582075, _ZN3sce3Xml10SimpleDataC1Ev); diff --git a/rpcs3/Emu/ARMv7/Modules/sceXml.h b/rpcs3/Emu/ARMv7/Modules/sceXml.h new file mode 100644 index 0000000000..ea5d63ed71 --- /dev/null +++ b/rpcs3/Emu/ARMv7/Modules/sceXml.h @@ -0,0 +1,3 @@ +#pragma once + +extern psv_log_base sceXml; diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.cpp b/rpcs3/Emu/ARMv7/PSVFuncList.cpp index 220ca2c21d..0296e11714 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.cpp +++ b/rpcs3/Emu/ARMv7/PSVFuncList.cpp @@ -1,7 +1,22 @@ #include "stdafx.h" +#include "Emu/System.h" #include "ARMv7Thread.h" #include "PSVFuncList.h" +psv_log_base::psv_log_base(const std::string& name, init_func_t init) + : m_name(name) + , m_init(init) +{ + on_error = [this](s32 code, psv_func* func) + { + if (code < 0) + { + Error("%s() failed: 0x%08X", func->name, code); + Emu.Pause(); + } + }; +} + std::vector g_psv_func_list; std::vector g_psv_modules; @@ -55,8 +70,8 @@ void execute_psv_func_by_index(ARMv7Context& context, u32 index) { if (auto func = get_psv_func_by_index(index)) { - auto old_last_syscall = context.thread.m_last_syscall; - context.thread.m_last_syscall = func->nid; + const u32 old_func = context.hle_func; + context.hle_func = func->nid; if (func->func) { @@ -64,14 +79,20 @@ void execute_psv_func_by_index(ARMv7Context& context, u32 index) } else { - throw "Unimplemented function"; + throw EXCEPTION("Unimplemented function"); } - context.thread.m_last_syscall = old_last_syscall; + // rough error code processing + if (context.GPR[0] && func->module && func->module->on_error) + { + func->module->on_error(context.GPR[0], func); + } + + context.hle_func = old_func; } else { - throw "Invalid function index"; + throw EXCEPTION("Invalid function index"); } } @@ -210,7 +231,7 @@ void initialize_psv_modules() hle_return.name = "HLE_RETURN"; hle_return.func = [](ARMv7Context& context) { - context.thread.FastStop(); + static_cast(context).FastStop(); }; // load functions diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index 9bd061b512..c104585ebe 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -1,29 +1,31 @@ #pragma once + #include "Emu/Memory/Memory.h" #include "ARMv7Context.h" #include "Emu/SysCalls/LogBase.h" +namespace vm { using namespace psv; } + // PSV module class class psv_log_base : public LogBase { + using init_func_t = void(*)(); + std::string m_name; - void(*m_init_func)(); + init_func_t m_init; public: std::function on_load; std::function on_unload; std::function on_stop; + std::function on_error; public: - psv_log_base(const std::string& name, void(*init_func)()) - : m_name(name) - , m_init_func(init_func) - { - } + psv_log_base(const std::string& name, init_func_t init); void Init() { - m_init_func(); + m_init(); } virtual const std::string& GetName() const override @@ -33,27 +35,37 @@ public: }; -typedef void(*psv_func_caller)(ARMv7Context&); +using armv7_func_caller = void(*)(ARMv7Context&); + +struct armv7_va_args_t +{ + u32 g_count; + u32 f_count; + u32 v_count; +}; // Utilities for binding ARMv7Context to C++ function arguments received by HLE functions or sent to callbacks namespace psv_func_detail { - enum arg_class + enum arg_class : u32 { ARG_GENERAL, ARG_FLOAT, ARG_VECTOR, ARG_STACK, + ARG_CONTEXT, + ARG_VARIADIC, + ARG_UNKNOWN, }; static const auto FIXED_STACK_FRAME_SIZE = 0x80; // described in CB_FUNC.h - template - struct bind_arg; - - template - struct bind_arg + template + struct bind_arg { + static_assert(type == ARG_GENERAL, "Unknown function argument type"); + static_assert(!std::is_pointer::value, "Invalid function argument type (pointer)"); + static_assert(!std::is_reference::value, "Invalid function argument type (reference)"); static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL"); force_inline static T get_arg(ARMv7Context& context) @@ -67,40 +79,40 @@ namespace psv_func_detail } }; - template + template struct bind_arg { // first u64 argument is passed in r0-r1, second one is passed in r2-r3 (if g_count = 3) - static_assert(g_count == 1 || g_count == 3, "Wrong u64 argument position"); + static_assert(g_count == 2 || g_count == 4, "Wrong u64 argument position"); force_inline static u64 get_arg(ARMv7Context& context) { - return context.GPR_D[g_count >> 1]; + return context.GPR_D[(g_count - 1) >> 1]; } force_inline static void put_arg(ARMv7Context& context, u64 arg) { - context.GPR_D[g_count >> 1] = arg; + context.GPR_D[(g_count - 1) >> 1] = arg; } }; - template + template struct bind_arg { - static_assert(g_count == 1 || g_count == 3, "Wrong s64 argument position"); + static_assert(g_count == 2 || g_count == 4, "Wrong s64 argument position"); force_inline static s64 get_arg(ARMv7Context& context) { - return context.GPR_D[g_count >> 1]; + return context.GPR_D[(g_count - 1) >> 1]; } force_inline static void put_arg(ARMv7Context& context, s64 arg) { - context.GPR_D[g_count >> 1] = arg; + context.GPR_D[(g_count - 1) >> 1] = arg; } }; - template + template struct bind_arg { static_assert(f_count <= 0, "TODO: Unsupported argument type (float)"); @@ -115,11 +127,11 @@ namespace psv_func_detail } }; - template + template struct bind_arg { static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)"); - static_assert(std::is_same::value, "Invalid function argument type for ARG_VECTOR"); + static_assert(std::is_same, u128>::value, "Invalid function argument type for ARG_VECTOR"); force_inline static T get_arg(ARMv7Context& context) { @@ -130,7 +142,7 @@ namespace psv_func_detail } }; - template + template struct bind_arg { static_assert(f_count <= 0, "TODO: Unsupported stack argument type (float)"); @@ -140,7 +152,7 @@ namespace psv_func_detail force_inline static T get_arg(ARMv7Context& context) { // TODO: check - return cast_from_armv7_gpr(vm::psv::read32(context.SP + sizeof(u32) * (g_count - 5))); + return cast_from_armv7_gpr(vm::read32(context.SP + sizeof(u32) * (g_count - 5))); } force_inline static void put_arg(ARMv7Context& context, const T& arg) @@ -149,45 +161,71 @@ namespace psv_func_detail const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)"); - vm::psv::write32(context.SP + stack_pos, cast_to_armv7_gpr(arg)); + vm::write32(context.SP + stack_pos, cast_to_armv7_gpr(arg)); } }; - template + template struct bind_arg { force_inline static u64 get_arg(ARMv7Context& context) { // TODO: check - return vm::psv::read64(context.SP + sizeof(u32) * (g_count - 5)); + return vm::read64(context.SP + sizeof(u32) * (g_count - 6)); } force_inline static void put_arg(ARMv7Context& context, u64 arg) { // TODO: check - const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE; + const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < -4, "TODO: Increase fixed stack frame size (arg count limit broken)"); - vm::psv::write64(context.SP + stack_pos, arg); + vm::write64(context.SP + stack_pos, arg); } }; - template + template struct bind_arg { force_inline static s64 get_arg(ARMv7Context& context) { // TODO: check - return vm::psv::read64(context.SP + sizeof(u32) * (g_count - 5)); + return vm::read64(context.SP + sizeof(u32) * (g_count - 6)); } force_inline static void put_arg(ARMv7Context& context, s64 arg) { // TODO: check - const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE; + const int stack_pos = (g_count - 6) * 4 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < -4, "TODO: Increase fixed stack frame size (arg count limit broken)"); - vm::psv::write64(context.SP + stack_pos, arg); + vm::write64(context.SP + stack_pos, arg); + } + }; + + template + struct bind_arg + { + static_assert(std::is_same::value, "Invalid function argument type for ARG_CONTEXT"); + + force_inline static ARMv7Context& get_arg(ARMv7Context& context) + { + return context; + } + + force_inline static void put_arg(ARMv7Context& context, ARMv7Context& arg) + { + } + }; + + template + struct bind_arg + { + static_assert(std::is_same, armv7_va_args_t>::value, "Invalid function argument type for ARG_VARIADIC"); + + force_inline static armv7_va_args_t get_arg(ARMv7Context& context) + { + return{ g_count, f_count, v_count }; } }; @@ -251,7 +289,7 @@ namespace psv_func_detail //template //struct bind_result //{ - // static_assert(std::is_same::value, "Invalid function result type for ARG_VECTOR"); + // static_assert(std::is_same, u128>::value, "Invalid function result type for ARG_VECTOR"); // static force_inline void put_result(ARMv7Context& context, const T& result) // { @@ -264,94 +302,105 @@ namespace psv_func_detail static_assert(!std::is_pointer::value, "Invalid function result type (pointer)"); static_assert(!std::is_reference::value, "Invalid function result type (reference)"); static const bool is_float = std::is_floating_point::value; - static const bool is_vector = std::is_same::value; + static const bool is_vector = std::is_same, u128>::value; static const arg_class value = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL); }; - template + template struct arg_type { - static_assert(!std::is_pointer::value, "Invalid function argument type (pointer)"); - static_assert(!std::is_reference::value, "Invalid function argument type (reference)"); // TODO: check calculations static const bool is_float = std::is_floating_point::value; - static const bool is_vector = std::is_same::value; - static const int g_align = __alignof(T) > 4 ? __alignof(T) >> 2 : 1; - static const int g_pos = (is_float || is_vector) ? g_count : ((g_count + (g_align - 1)) & ~(g_align - 1)) + 1; - static const int g_next = g_pos + g_align - 1; - static const int f_value = !is_float ? f_count : f_count + 1; - static const int v_value = !is_vector ? v_count : v_count + 1; - static const arg_class value = is_float - ? ((f_value > 9000) ? ARG_STACK : ARG_FLOAT) - : (is_vector ? ((v_value > 9000) ? ARG_STACK : ARG_VECTOR) : ((g_pos > 4) ? ARG_STACK : ARG_GENERAL)); + static const bool is_vector = std::is_same, u128>::value; + static const bool is_context = std::is_same::value; + static const bool is_variadic = std::is_same, armv7_va_args_t>::value; + static const bool is_general = !is_float && !is_vector && !is_context && !is_variadic; + + static const u32 g_align = alignof32(T) > 4 ? alignof32(T) >> 2 : 1; + static const u32 g_value = is_general ? ((g_count + (g_align - 1)) & ~(g_align - 1)) + (g_align) : g_count; + static const u32 f_value = f_count + is_float; + static const u32 v_value = v_count + is_vector; + + static const arg_class value = + is_general ? (g_value > 4 ? ARG_STACK : ARG_GENERAL) : + is_float ? (f_value > 9000 ? ARG_STACK : ARG_FLOAT) : + is_vector ? (v_value > 9000 ? ARG_STACK : ARG_VECTOR) : + is_context ? ARG_CONTEXT : + is_variadic ? ARG_VARIADIC : + ARG_UNKNOWN; }; - template - struct call_impl + // wrapper for variadic argument info list, each value contains packed argument type and counts of GENERAL, FLOAT and VECTOR arguments + template struct arg_info_pack_t; + + template struct arg_info_pack_t { - static force_inline RT call(F f, Tuple && t) + static const u32 last_value = arg_info_pack_t::last_value; + }; + + template struct arg_info_pack_t + { + static const u32 last_value = First; + }; + + template<> struct arg_info_pack_t<> + { + static const u32 last_value = 0; + }; + + // argument type + g/f/v_count unpacker + template struct bind_arg_packed + { + force_inline static T get_arg(ARMv7Context& context) { - return call_impl::call(f, std::forward(t)); + return bind_arg(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(context); } }; - template - struct call_impl + template + force_inline RT call(ARMv7Context& context, RT(*func)(Args...), arg_info_pack_t info) { - static force_inline RT call(F f, Tuple && t) - { - return f(std::get(std::forward(t))...); - } - }; - - template - force_inline RT call(F f, Tuple && t) - { - using ttype = std::decay_t; - return psv_func_detail::call_impl::value, std::tuple_size::value>::call(f, std::forward(t)); + // do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...) + return func(bind_arg_packed::get_arg(context)...); } - template - force_inline std::tuple<> get_func_args(ARMv7Context& context) + template + force_inline RT call(ARMv7Context& context, RT(*func)(Args...), arg_info_pack_t info) { - // terminator - return std::tuple<>(); - } + // unpack previous type counts (0/0/0 for the first time) + const u32 g_count = (info.last_value >> 8) & 0xff; + const u32 f_count = (info.last_value >> 16) & 0xff; + const u32 v_count = (info.last_value >> 24); - template - force_inline std::tuple get_func_args(ARMv7Context& context) - { - typedef arg_type type; + using type = arg_type; const arg_class t = type::value; - const int g0 = type::g_pos; - const int g1 = type::g_next; - const int f = type::f_value; - const int v = type::v_value; + const u32 g = type::g_value; + const u32 f = type::f_value; + const u32 v = type::v_value; - return std::tuple_cat(std::tuple(bind_arg::get_arg(context)), get_func_args(context)); + return call(context, func, arg_info_pack_t{}); } - template + template force_inline static bool put_func_args(ARMv7Context& context) { // terminator return false; } - template + template force_inline static bool put_func_args(ARMv7Context& context, T1 arg, T... args) { - typedef arg_type type; + using type = arg_type; const arg_class t = type::value; - const int g0 = type::g_pos; - const int g1 = type::g_next; - const int f = type::f_value; - const int v = type::v_value; + const u32 g = type::g_value; + const u32 f = type::f_value; + const u32 v = type::v_value; - bind_arg::put_arg(context, arg); + bind_arg::put_arg(context, arg); // return true if stack was used - return put_func_args(context, args...) || (t == ARG_STACK); + return put_func_args(context, args...) || (t == ARG_STACK); } template @@ -360,44 +409,22 @@ namespace psv_func_detail template struct func_binder { - typedef void(*func_t)(T...); + using func_t = void(*)(T...); - static void do_call(ARMv7Context& context, func_t _func) + static void do_call(ARMv7Context& context, func_t func) { - call(_func, get_func_args<0, 0, 0, T...>(context)); - } - }; - - template - struct func_binder - { - typedef void(*func_t)(ARMv7Context&, T...); - - static void do_call(ARMv7Context& context, func_t _func) - { - call(_func, std::tuple_cat(std::tuple(context), get_func_args<0, 0, 0, T...>(context))); + call(context, func, arg_info_pack_t<>{}); } }; template struct func_binder { - typedef RT(*func_t)(T...); + using func_t = RT(*)(T...); - static void do_call(ARMv7Context& context, func_t _func) + static void do_call(ARMv7Context& context, func_t func) { - bind_result::value>::put_result(context, call(_func, get_func_args<0, 0, 0, T...>(context))); - } - }; - - template - struct func_binder - { - typedef RT(*func_t)(ARMv7Context&, T...); - - static void do_call(ARMv7Context& context, func_t _func) - { - bind_result::value>::put_result(context, call(_func, std::tuple_cat(std::tuple(context), get_func_args<0, 0, 0, T...>(context)))); + bind_result::value>::put_result(context, call(context, func, arg_info_pack_t<>{})); } }; @@ -437,14 +464,14 @@ struct psv_func u32 nid; // Unique function ID (should be generated individually for each elf loaded) u32 flags; const char* name; // Function name for information - psv_func_caller func; // Function caller + armv7_func_caller func; // Function caller psv_log_base* module; // Module for information psv_func() { } - psv_func(u32 nid, u32 flags, psv_log_base* module, const char* name, psv_func_caller func) + psv_func(u32 nid, u32 flags, psv_log_base* module, const char* name, armv7_func_caller func) : nid(nid) , flags(flags) , name(name) @@ -619,27 +646,34 @@ enum psv_error_codes struct SceDateTime { - u16 year; - u16 month; - u16 day; - u16 hour; - u16 minute; - u16 second; - u32 microsecond; + le_t year; + le_t month; + le_t day; + le_t hour; + le_t minute; + le_t second; + le_t microsecond; }; struct SceFVector3 { - float x, y, z; + le_t x, y, z; }; struct SceFQuaternion { - float x, y, z, w; + le_t x, y, z, w; }; union SceUMatrix4 { - float f[4][4]; - s32 i[4][4]; + struct + { + le_t f[4][4]; + }; + + struct + { + le_t i[4][4]; + }; }; diff --git a/rpcs3/Emu/ARMv7/PSVObjectList.h b/rpcs3/Emu/ARMv7/PSVObjectList.h index 3cf33b0b30..cb15c6f173 100644 --- a/rpcs3/Emu/ARMv7/PSVObjectList.h +++ b/rpcs3/Emu/ARMv7/PSVObjectList.h @@ -28,11 +28,6 @@ class psv_object_list_t // Class for managing object data std::atomic m_hint; // guessing next free position std::mutex m_mutex; - void error(s32 uid) - { - throw fmt::format("Invalid UID requested (type=0x%x, uid=0x%x)", uid_class, uid); - } - public: psv_object_list_t() : m_hint(0) diff --git a/rpcs3/Emu/Audio/AudioManager.cpp b/rpcs3/Emu/Audio/AudioManager.cpp index a48802136d..8d28c476a6 100644 --- a/rpcs3/Emu/Audio/AudioManager.cpp +++ b/rpcs3/Emu/Audio/AudioManager.cpp @@ -36,8 +36,3 @@ void AudioManager::Close() delete m_audio_out; m_audio_out = nullptr; } - -u8 AudioManager::GetState() -{ - return CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED; -} diff --git a/rpcs3/Emu/Audio/AudioManager.h b/rpcs3/Emu/Audio/AudioManager.h index 88eb3db216..a1f50c84da 100644 --- a/rpcs3/Emu/Audio/AudioManager.h +++ b/rpcs3/Emu/Audio/AudioManager.h @@ -1,31 +1,16 @@ #pragma once -#include "sysutil_audio.h" + #include "AudioThread.h" +// it cannot be configured currently, and it must NOT use cellSysutil definitions struct AudioInfo { - struct - { - u8 type; - u8 channel; - u8 encoder; - u8 fs; - u32 layout; - u32 downMixer; - } mode; - AudioInfo() { } void Init() { - mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; - mode.channel = CELL_AUDIO_OUT_CHNUM_8; - mode.fs = CELL_AUDIO_OUT_FS_48KHZ; - mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy; - mode.encoder = CELL_AUDIO_OUT_CODING_TYPE_LPCM; - mode.downMixer = CELL_AUDIO_OUT_DOWNMIXER_NONE; } }; @@ -42,6 +27,4 @@ public: AudioThread& GetAudioOut() { assert(m_audio_out); return *m_audio_out; } AudioInfo& GetInfo() { return m_audio_info; } - - u8 GetState(); -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/Audio/AudioThread.h b/rpcs3/Emu/Audio/AudioThread.h index fa600ba9cb..6932294bb3 100644 --- a/rpcs3/Emu/Audio/AudioThread.h +++ b/rpcs3/Emu/Audio/AudioThread.h @@ -12,4 +12,4 @@ public: virtual void Close() = 0; virtual void Stop() = 0; virtual void AddData(const void* src, int size) = 0; -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/CPU/CPUDecoder.h b/rpcs3/Emu/CPU/CPUDecoder.h index 5ff68f0e70..4a6d0021b0 100644 --- a/rpcs3/Emu/CPU/CPUDecoder.h +++ b/rpcs3/Emu/CPU/CPUDecoder.h @@ -59,7 +59,7 @@ public: virtual void operator ()(TO* op, u32 code) const { - (op->*m_func)((T1)m_arg_func_1(code)); + (op->*m_func)(static_cast(m_arg_func_1(code))); } }; @@ -83,8 +83,8 @@ public: virtual void operator ()(TO* op, u32 code) const { (op->*m_func)( - (T1)m_arg_func_1(code), - (T2)m_arg_func_2(code) + static_cast(m_arg_func_1(code)), + static_cast(m_arg_func_2(code)) ); } }; @@ -114,9 +114,9 @@ public: virtual void operator ()(TO* op, u32 code) const { (op->*m_func)( - (T1)m_arg_func_1(code), - (T2)m_arg_func_2(code), - (T3)m_arg_func_3(code) + static_cast(m_arg_func_1(code)), + static_cast(m_arg_func_2(code)), + static_cast(m_arg_func_3(code)) ); } }; @@ -149,10 +149,10 @@ public: virtual void operator ()(TO* op, u32 code) const { (op->*m_func)( - (T1)m_arg_func_1(code), - (T2)m_arg_func_2(code), - (T3)m_arg_func_3(code), - (T4)m_arg_func_4(code) + static_cast(m_arg_func_1(code)), + static_cast(m_arg_func_2(code)), + static_cast(m_arg_func_3(code)), + static_cast(m_arg_func_4(code)) ); } }; @@ -188,11 +188,11 @@ public: virtual void operator ()(TO* op, u32 code) const { (op->*m_func)( - (T1)m_arg_func_1(code), - (T2)m_arg_func_2(code), - (T3)m_arg_func_3(code), - (T4)m_arg_func_4(code), - (T5)m_arg_func_5(code) + static_cast(m_arg_func_1(code)), + static_cast(m_arg_func_2(code)), + static_cast(m_arg_func_3(code)), + static_cast(m_arg_func_4(code)), + static_cast(m_arg_func_5(code)) ); } }; @@ -231,12 +231,12 @@ public: virtual void operator ()(TO* op, u32 code) const { (op->*m_func)( - (T1)m_arg_func_1(code), - (T2)m_arg_func_2(code), - (T3)m_arg_func_3(code), - (T4)m_arg_func_4(code), - (T5)m_arg_func_5(code), - (T6)m_arg_func_6(code) + static_cast(m_arg_func_1(code)), + static_cast(m_arg_func_2(code)), + static_cast(m_arg_func_3(code)), + static_cast(m_arg_func_4(code)), + static_cast(m_arg_func_5(code)), + static_cast(m_arg_func_6(code)) ); } }; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index a490d187d4..4d8ece34af 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -3,351 +3,285 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/DbgCommand.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Emu/ARMv7/PSVFuncList.h" #include "CPUDecoder.h" #include "CPUThread.h" -CPUThread* GetCurrentCPUThread() -{ - return dynamic_cast(GetCurrentNamedThread()); -} - -CPUThread::CPUThread(CPUThreadType type) - : ThreadBase("CPUThread") - , m_events(0) +CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function thread_name) + : m_state({ CPU_STATE_STOPPED }) + , m_id(Emu.GetIdManager().get_current_id()) , m_type(type) - , m_stack_size(0) - , m_stack_addr(0) - , m_prio(0) - , m_dec(nullptr) - , m_is_step(false) - , m_is_branch(false) - , m_status(Stopped) - , m_last_syscall(0) - , m_trace_enabled(false) - , m_trace_call_stack(true) + , m_name(name) { - offset = 0; + start(std::move(thread_name), [this] + { + SendDbgCommand(DID_CREATE_THREAD, this); + + std::unique_lock lock(mutex); + + // check thread status + while (joinable() && IsActive()) + { + CHECK_EMU_STATUS; + + // check stop status + if (!IsStopped()) + { + if (lock) lock.unlock(); + + try + { + Task(); + } + catch (CPUThreadReturn) + { + ; + } + catch (CPUThreadStop) + { + m_state |= CPU_STATE_STOPPED; + } + catch (CPUThreadExit) + { + m_state |= CPU_STATE_DEAD; + break; + } + catch (const fmt::exception&) + { + DumpInformation(); + throw; + } + + m_state &= ~CPU_STATE_RETURN; + continue; + } + + if (!lock) + { + lock.lock(); + continue; + } + + cv.wait(lock); + } + }); } CPUThread::~CPUThread() { - safe_delete(m_dec); + if (joinable()) + { + throw EXCEPTION("Thread not joined"); + } + + SendDbgCommand(DID_REMOVE_THREAD, this); } -void CPUThread::DumpInformation() +bool CPUThread::IsPaused() const { - auto get_syscall_name = [this](u64 syscall) -> std::string - { - switch (GetType()) - { - case CPU_THREAD_ARMv7: - { - if ((u32)syscall == syscall) - { - if (syscall) - { - if (auto func = get_psv_func_by_nid((u32)syscall)) - { - return func->name; - } - } - else - { - return{}; - } - } + return (m_state.load() & CPU_STATE_PAUSED) != 0 || Emu.IsPaused(); +} - return "unknown function"; - } - - case CPU_THREAD_PPU: - { - if (syscall) - { - return SysCalls::GetFuncName(syscall); - } - else - { - return{}; - } - } - - case CPU_THREAD_SPU: - case CPU_THREAD_RAW_SPU: - default: - { - if (!syscall) - { - return{}; - } - - return "unknown function"; - } - } - }; - - LOG_ERROR(GENERAL, "Information: is_alive=%d, m_last_syscall=0x%llx (%s)", IsAlive(), m_last_syscall, get_syscall_name(m_last_syscall)); +void CPUThread::DumpInformation() const +{ LOG_WARNING(GENERAL, RegsToString()); } -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(false); - DoStop(); - - delete m_dec; - m_dec = nullptr; -} - -void CPUThread::Reset() -{ - CloseStack(); - - SetPc(0); - m_is_branch = false; - - m_status = Stopped; - - DoReset(); -} - -void CPUThread::SetId(const u32 id) -{ - m_id = id; -} - -void CPUThread::SetName(const std::string& name) -{ - NamedThreadBase::SetThreadName(name); -} - -int CPUThread::ThreadStatus() -{ - if(Emu.IsStopped() || IsStopped() || IsPaused()) - { - return CPUThread_Stopped; - } - - if(TestDestroy()) - { - return CPUThread_Break; - } - - if(m_is_step) - { - return CPUThread_Step; - } - - if (Emu.IsPaused()) - { - return CPUThread_Sleeping; - } - - return CPUThread_Running; -} - -void CPUThread::SetEntry(const u32 pc) -{ - entry = pc; -} - -void CPUThread::NextPc(u32 instr_size) -{ - if(m_is_branch) - { - m_is_branch = false; - - SetPc(nPC); - } - else - { - PC += instr_size; - } -} - -void CPUThread::SetBranch(const u32 pc, bool record_branch) -{ - m_is_branch = true; - nPC = pc; - - if(m_trace_call_stack && record_branch) - CallStackBranch(pc); -} - -void CPUThread::SetPc(const u32 pc) -{ - PC = pc; -} - void CPUThread::Run() { - if(!IsStopped()) - Stop(); - - Reset(); - SendDbgCommand(DID_START_THREAD, this); - m_status = Running; - - SetPc(entry); InitStack(); InitRegs(); DoRun(); - Emu.CheckStatus(); SendDbgCommand(DID_STARTED_THREAD, this); } +void CPUThread::Pause() +{ + SendDbgCommand(DID_PAUSE_THREAD, this); + + m_state |= CPU_STATE_PAUSED; + + SendDbgCommand(DID_PAUSED_THREAD, this); +} + void CPUThread::Resume() { - if(!IsPaused()) return; - SendDbgCommand(DID_RESUME_THREAD, this); - m_status = Running; - DoResume(); - Emu.CheckStatus(); + { + // lock for reliable notification + std::lock_guard lock(mutex); - ThreadBase::Start(); + m_state &= ~CPU_STATE_PAUSED; + + cv.notify_one(); + } SendDbgCommand(DID_RESUMED_THREAD, this); } -void CPUThread::Pause() -{ - if(!IsRunning()) return; - - SendDbgCommand(DID_PAUSE_THREAD, this); - - m_status = Paused; - DoPause(); - Emu.CheckStatus(); - - // ThreadBase::Stop(); // "Abort() called" exception - SendDbgCommand(DID_PAUSED_THREAD, this); -} - void CPUThread::Stop() { - if(IsStopped()) return; - SendDbgCommand(DID_STOP_THREAD, this); - m_status = Stopped; - m_events |= CPU_EVENT_STOP; - - if(static_cast(this) != GetCurrentNamedThread()) + if (is_current()) { - ThreadBase::Stop(); + throw CPUThreadStop{}; } + else + { + // lock for reliable notification + std::lock_guard lock(mutex); - Emu.CheckStatus(); + m_state |= CPU_STATE_STOPPED; + + cv.notify_one(); + } SendDbgCommand(DID_STOPED_THREAD, this); } void CPUThread::Exec() { - m_is_step = false; SendDbgCommand(DID_EXEC_THREAD, this); - if(IsRunning()) - ThreadBase::Start(); -} - -void CPUThread::ExecOnce() -{ - m_is_step = true; - SendDbgCommand(DID_EXEC_THREAD, this); - - m_status = Running; - ThreadBase::Start(); - ThreadBase::Stop(true,false); - m_status = Paused; - SendDbgCommand(DID_PAUSE_THREAD, this); - SendDbgCommand(DID_PAUSED_THREAD, this); -} - -void CPUThread::Task() -{ - if (Ini.HLELogging.GetValue()) LOG_NOTICE(GENERAL, "%s enter", CPUThread::GetFName().c_str()); - - const std::vector& bp = Emu.GetBreakPoints(); - - for (uint i = 0; i lock(mutex); - std::vector trace; + m_state &= ~CPU_STATE_STOPPED; + + cv.notify_one(); + } +} + +void CPUThread::Exit() +{ + if (is_current()) + { + throw CPUThreadExit{}; + } + else + { + throw EXCEPTION("Unable to exit another thread"); + } +} + +void CPUThread::Step() +{ + if (m_state.atomic_op([](u64& state) -> bool + { + const bool was_paused = (state & CPU_STATE_PAUSED) != 0; + + state |= CPU_STATE_STEP; + state &= ~CPU_STATE_PAUSED; + + return was_paused; + })) + { + if (is_current()) return; + + // lock for reliable notification (only if PAUSE was removed) + std::lock_guard lock(mutex); + + cv.notify_one(); + } +} + +void CPUThread::Sleep() +{ + m_state += CPU_STATE_MAX; + m_state |= CPU_STATE_SLEEP; +} + +void CPUThread::Awake() +{ + // must be called after the balanced Sleep() call + + if (m_state.atomic_op([](u64& state) -> bool + { + if (state < CPU_STATE_MAX) + { + throw EXCEPTION("Sleep()/Awake() inconsistency"); + } + + if ((state -= CPU_STATE_MAX) < CPU_STATE_MAX) + { + state &= ~CPU_STATE_SLEEP; + + // notify the condition variable as well + return true; + } + + return false; + })) + { + if (is_current()) return; + + // lock for reliable notification; the condition being checked is probably externally set + std::lock_guard lock(mutex); + + cv.notify_one(); + } +} + +bool CPUThread::Signal() +{ + // try to set SIGNAL + if (m_state._or(CPU_STATE_SIGNAL) & CPU_STATE_SIGNAL) + { + return false; + } + else + { + // not truly responsible for signal delivery, requires additional measures like LV2_LOCK + cv.notify_one(); + + return true; + } +} + +bool CPUThread::Signaled() +{ + // remove SIGNAL and return its old value + return (m_state._and_not(CPU_STATE_SIGNAL) & CPU_STATE_SIGNAL) != 0; +} + +bool CPUThread::CheckStatus() +{ + std::unique_lock lock(mutex, std::defer_lock); while (true) { - int status = ThreadStatus(); + CHECK_EMU_STATUS; // check at least once - if (status == CPUThread_Stopped || status == CPUThread_Break) - { - break; - } + if (!IsPaused()) break; - if (status == CPUThread_Sleeping) + if (!lock) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + lock.lock(); continue; } - Step(); - //if (m_trace_enabled) - //trace.push_back(PC); - NextPc(m_dec->DecodeMemory(PC + offset)); - - if (status == CPUThread_Step) - { - m_is_step = false; - break; - } - - for (uint i = 0; i < bp.size(); ++i) - { - if (bp[i] == PC) - { - Emu.Pause(); - break; - } - } + cv.wait(lock); } - if (trace.size()) + if (m_state.load() & CPU_STATE_RETURN || IsStopped()) { - LOG_NOTICE(GENERAL, "Trace begin (%d elements)", trace.size()); - - u32 start = trace[0], prev = trace[0] - 4; - - for (auto& v : trace) //LOG_NOTICE(GENERAL, "PC = 0x%x", v); - { - if (v - prev != 4 && v - prev != 2) - { - LOG_NOTICE(GENERAL, "Trace: 0x%08x .. 0x%08x", start, prev); - start = v; - } - prev = v; - } - - LOG_NOTICE(GENERAL, "Trace end: 0x%08x .. 0x%08x", start, prev); + return true; } - if (Ini.HLELogging.GetValue()) LOG_NOTICE(GENERAL, "%s leave", CPUThread::GetFName().c_str()); + if (m_state.load() & CPU_STATE_STEP) + { + // set PAUSE, but allow to execute once + m_state |= CPU_STATE_PAUSED; + m_state &= ~CPU_STATE_STEP; + } + + return false; } diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index d006ace661..9917a723ae 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -1,7 +1,8 @@ #pragma once + #include "Utilities/Thread.h" -enum CPUThreadType : unsigned char +enum CPUThreadType { CPU_THREAD_PPU, CPU_THREAD_SPU, @@ -9,80 +10,114 @@ enum CPUThreadType : unsigned char CPU_THREAD_ARMv7, }; -enum CPUThreadStatus -{ - CPUThread_Ready, - CPUThread_Running, - CPUThread_Paused, - CPUThread_Stopped, - CPUThread_Sleeping, - CPUThread_Break, - CPUThread_Step, -}; - -// CPU Thread Events +// CPU Thread State Flags enum : u64 { - CPU_EVENT_STOP = (1ull << 0), + CPU_STATE_STOPPED = (1ull << 0), // basic execution state (stopped by default), removed by Exec() + CPU_STATE_PAUSED = (1ull << 1), // pauses thread execution, set by the debugger (manually or after step execution) + CPU_STATE_SLEEP = (1ull << 2), // shouldn't affect thread execution, set by Sleep() call, removed by the latest Awake() call, may possibly indicate waiting state of the thread + CPU_STATE_STEP = (1ull << 3), // forces the thread to pause after executing just one instruction or something appropriate, set by the debugger + CPU_STATE_DEAD = (1ull << 4), // indicates irreversible exit of the thread + CPU_STATE_RETURN = (1ull << 5), // used for callback return + CPU_STATE_SIGNAL = (1ull << 6), + + CPU_STATE_MAX = (1ull << 7), // added to (subtracted from) m_state by Sleep()/Awake() calls to trigger status check }; +// "HLE return" exception event +class CPUThreadReturn{}; + +// CPUThread::Stop exception event +class CPUThreadStop{}; + +// CPUThread::Exit exception event +class CPUThreadExit{}; + class CPUDecoder; -class CPUThread : public ThreadBase +class CPUThread : protected thread_t, public std::enable_shared_from_this { protected: - std::atomic m_events; // flags + atomic_t m_state; // thread state flags - u32 m_status; - u32 m_id; - u64 m_prio; - CPUThreadType m_type; - bool m_joinable; - bool m_joining; - bool m_is_step; + std::unique_ptr m_dec; - u32 m_stack_addr; - u32 m_stack_size; - - u64 m_exit_status; - - CPUDecoder* m_dec; - - bool m_trace_call_stack; - - virtual void DumpInformation() override; + const u32 m_id; + const CPUThreadType m_type; + const std::string m_name; // changing m_name would be terribly thread-unsafe in current implementation public: - void AddEvent(const u64 event) { m_events |= event; } + using thread_t::mutex; + using thread_t::cv; + +protected: + CPUThread(CPUThreadType type, const std::string& name, std::function thread_name); + +public: + virtual ~CPUThread() override; + + u32 GetId() const { return m_id; } + CPUThreadType GetType() const { return m_type; } + std::string GetName() const { return m_name; } + + bool IsActive() const { return (m_state.load() & CPU_STATE_DEAD) == 0; } + bool IsStopped() const { return (m_state.load() & CPU_STATE_STOPPED) != 0; } + virtual bool IsPaused() const; + + virtual void DumpInformation() const; + virtual u32 GetPC() const = 0; + virtual u32 GetOffset() const = 0; + virtual void DoRun() = 0; + virtual void Task() = 0; virtual void InitRegs() = 0; - virtual void InitStack() = 0; virtual void CloseStack() = 0; - u32 GetStackAddr() const { return m_stack_addr; } - u32 GetStackSize() const { return m_stack_size; } + // initialize thread + void Run(); - void SetStackAddr(u32 stack_addr) { m_stack_addr = stack_addr; } - void SetStackSize(u32 stack_size) { m_stack_size = stack_size; } + // called by the debugger, don't use + void Pause(); - void SetId(const u32 id); - void SetName(const std::string& name); - void SetPrio(const u64 prio) { m_prio = prio; } - void SetExitStatus(const u64 status) { m_exit_status = status; } + // called by the debugger, don't use + void Resume(); - u64 GetPrio() const { return m_prio; } - u64 GetExitStatus() const { return m_exit_status; } + // stop thread execution + void Stop(); + + // start thread execution (removing STOP status) + void Exec(); + + // exit thread execution + void Exit(); + + // called by the debugger, don't use + void Step(); + + // trigger thread status check + void Sleep(); + + // untrigger thread status check + void Awake(); + + // set SIGNAL and notify (returns true if set) + bool Signal(); + + // test SIGNAL and reset + bool Signaled(); + + // process m_state flags, returns true if the checker must return + bool CheckStatus(); - std::string GetName() const { return NamedThreadBase::GetThreadName(); } std::string GetFName() const { - return fmt::format("%s[0x%x] Thread (%s)", GetTypeString(), m_id, GetName()); + return fmt::format("%s[0x%x] Thread (%s)", GetTypeString(), m_id, m_name); } - static std::string CPUThreadTypeToString(CPUThreadType type) + static const char* CPUThreadTypeToString(CPUThreadType type) { - switch(type) + switch (type) { case CPU_THREAD_PPU: return "PPU"; case CPU_THREAD_SPU: return "SPU"; @@ -93,82 +128,38 @@ public: return "Unknown"; } - std::string ThreadStatusToString() + const char* ThreadStatusToString() { - switch (ThreadStatus()) - { - case CPUThread_Ready: return "Ready"; - case CPUThread_Running: return "Running"; - case CPUThread_Paused: return "Paused"; - case CPUThread_Stopped: return "Stopped"; - case CPUThread_Sleeping: return "Sleeping"; - case CPUThread_Break: return "Break"; - case CPUThread_Step: return "Step"; + // TODO - default: return "Unknown status"; - } + //switch (ThreadStatus()) + //{ + //case CPUThread_Ready: return "Ready"; + //case CPUThread_Running: return "Running"; + //case CPUThread_Paused: return "Paused"; + //case CPUThread_Stopped: return "Stopped"; + //case CPUThread_Sleeping: return "Sleeping"; + //case CPUThread_Break: return "Break"; + //case CPUThread_Step: return "Step"; + //} + + return "Unknown"; } - std::string GetTypeString() const { return CPUThreadTypeToString(m_type); } - - virtual std::string GetThreadName() const + const char* GetTypeString() const { - return fmt::format("%s[0x%08x]", GetFName(), PC); + return CPUThreadTypeToString(m_type); } - CPUDecoder * GetDecoder() { return m_dec; }; + CPUDecoder* GetDecoder() + { + return m_dec.get(); + }; -public: - u32 entry; - u32 PC; - u32 nPC; - u32 index; - u32 offset; - bool m_is_branch; - bool m_trace_enabled; - u64 m_last_syscall; - -protected: - CPUThread(CPUThreadType type); - -public: - virtual ~CPUThread(); - - int ThreadStatus(); - - void NextPc(u32 instr_size); - void SetBranch(const u32 pc, bool record_branch = false); - void SetPc(const u32 pc); - void SetEntry(const u32 entry); - - bool IsRunning() const; - bool IsPaused() const; - bool IsStopped() const; - - bool IsJoinable() const { return m_joinable; } - bool IsJoining() const { return m_joining; } - void SetJoinable(bool joinable) { m_joinable = joinable; } - void SetJoining(bool joining) { m_joining = joining; } - - u32 GetId() const { return m_id; } - CPUThreadType GetType() const { return m_type; } - - void SetCallStackTracing(bool trace_call_stack) { m_trace_call_stack = trace_call_stack; } - - void Reset(); - void Close(); - void Run(); - void Pause(); - void Resume(); - void Stop(); - - virtual std::string RegsToString() = 0; - virtual std::string ReadRegString(const std::string& reg) = 0; + virtual std::string RegsToString() const = 0; + virtual std::string ReadRegString(const std::string& reg) const = 0; virtual bool WriteRegString(const std::string& reg, std::string value) = 0; - virtual void Exec(); - void ExecOnce(); - struct CallStackItem { u32 pc; @@ -207,7 +198,7 @@ public: CallStackItem new_item; new_item.branch_pc = pc; - new_item.pc = PC; + new_item.pc = GetPC(); m_call_stack.push_back(new_item); } @@ -216,53 +207,40 @@ public: { return pc + 4; } - -protected: - virtual void DoReset()=0; - virtual void DoRun()=0; - virtual void DoPause()=0; - virtual void DoResume()=0; - virtual void DoStop()=0; - -protected: - virtual void Step() {} - virtual void Task(); }; -CPUThread* GetCurrentCPUThread(); - class cpu_thread { protected: std::shared_ptr thread; public: - u32 get_entry() const - { - return thread->entry; - } + //u32 get_entry() const + //{ + // return thread->entry; + //} virtual cpu_thread& args(std::initializer_list values) = 0; virtual cpu_thread& run() = 0; - u64 join() - { - if (!joinable()) - throw "thread must be joinable for join"; + //u64 join() + //{ + // if (!joinable()) + // throw EXCEPTION("thread must be joinable for join"); - thread->SetJoinable(false); + // thread->SetJoinable(false); - while (thread->IsRunning()) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + // while (thread->IsRunning()) + // std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - return thread->GetExitStatus(); - } + // return thread->GetExitStatus(); + //} - bool joinable() const - { - return thread->IsJoinable(); - } + //bool joinable() const + //{ + // return thread->IsJoinable(); + //} u32 get_id() const { diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index 1fee8dd241..c6d902c530 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -2,13 +2,13 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/DbgCommand.h" - #include "Emu/IdManager.h" -#include "CPUThreadManager.h" + #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" #include "Emu/Cell/RawSPUThread.h" #include "Emu/ARMv7/ARMv7Thread.h" +#include "CPUThreadManager.h" CPUThreadManager::CPUThreadManager() { @@ -16,128 +16,84 @@ CPUThreadManager::CPUThreadManager() CPUThreadManager::~CPUThreadManager() { - Close(); } void CPUThreadManager::Close() { - while(m_threads.size()) RemoveThread(m_threads[0]->GetId()); + std::lock_guard lock(m_mutex); + + for (auto& x : m_raw_spu) + { + x.reset(); + } } -std::shared_ptr CPUThreadManager::AddThread(CPUThreadType type) +std::vector> CPUThreadManager::GetAllThreads() +{ + std::vector> result; + + for (auto& t : Emu.GetIdManager().get_all()) + { + result.emplace_back(t); + } + + for (auto& t : Emu.GetIdManager().get_all()) + { + result.emplace_back(t); + } + + for (auto& t : Emu.GetIdManager().get_all()) + { + result.emplace_back(t); + } + + for (auto& t : Emu.GetIdManager().get_all()) + { + result.emplace_back(t); + } + + return result; +} + +void CPUThreadManager::Exec() +{ + for (auto& t : Emu.GetIdManager().get_all()) + { + t->Exec(); + } + + for (auto& t : Emu.GetIdManager().get_all()) + { + t->Exec(); + } +} + +std::shared_ptr CPUThreadManager::NewRawSPUThread() { std::lock_guard lock(m_mutex); - std::shared_ptr new_thread; + std::shared_ptr result; - switch(type) + for (u32 i = 0; i < m_raw_spu.size(); i++) { - case CPU_THREAD_PPU: - { - new_thread = std::make_shared(); - break; - } - case CPU_THREAD_SPU: - { - new_thread = std::make_shared(); - break; - } - case CPU_THREAD_RAW_SPU: - { - for (u32 i = 0; i < m_raw_spu.size(); i++) + if (m_raw_spu[i].expired()) { - if (!m_raw_spu[i]) - { - new_thread = std::make_shared(); - new_thread->index = i; - - m_raw_spu[i] = new_thread; - break; - } - } - break; - } - case CPU_THREAD_ARMv7: - { - new_thread.reset(new ARMv7Thread()); - break; - } - default: assert(0); - } - - if (new_thread) - { - new_thread->SetId(Emu.GetIdManager().add(new_thread)); - - m_threads.push_back(new_thread); - SendDbgCommand(DID_CREATE_THREAD, new_thread.get()); - } - - return new_thread; -} - -void CPUThreadManager::RemoveThread(u32 id) -{ - std::lock_guard lock(m_mutex); - - std::shared_ptr thr; - u32 thread_index = 0; - - for (u32 i = 0; i < m_threads.size(); ++i) - { - if (m_threads[i]->GetId() != id) continue; - - thr = m_threads[i]; - thread_index = i; - } - - if (thr) - { - SendDbgCommand(DID_REMOVE_THREAD, thr.get()); - thr->Close(); - - m_threads.erase(m_threads.begin() + thread_index); - - if (thr->GetType() == CPU_THREAD_RAW_SPU) - { - assert(thr->index < m_raw_spu.size()); - m_raw_spu[thr->index] = nullptr; + m_raw_spu[i] = result = Emu.GetIdManager().make_ptr(std::to_string(i), i); + break; } } - // Removing the ID should trigger the actual deletion of the thread - Emu.GetIdManager().remove(id); - Emu.CheckStatus(); + return result; } -std::shared_ptr CPUThreadManager::GetThread(u32 id) -{ - return Emu.GetIdManager().get(id); -} - -std::shared_ptr CPUThreadManager::GetThread(u32 id, CPUThreadType type) -{ - const auto res = GetThread(id); - - return res && res->GetType() == type ? res : nullptr; -} - -std::shared_ptr CPUThreadManager::GetRawSPUThread(u32 index) +std::shared_ptr CPUThreadManager::GetRawSPUThread(u32 index) { if (index >= m_raw_spu.size()) { return nullptr; } - return m_raw_spu[index]; -} - -void CPUThreadManager::Exec() -{ std::lock_guard lock(m_mutex); - for(u32 i = 0; i < m_threads.size(); ++i) - { - m_threads[i]->Exec(); - } + return m_raw_spu[index].lock(); } diff --git a/rpcs3/Emu/CPU/CPUThreadManager.h b/rpcs3/Emu/CPU/CPUThreadManager.h index 0bdcb05ce4..5fa772e971 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.h +++ b/rpcs3/Emu/CPU/CPUThreadManager.h @@ -1,14 +1,13 @@ #pragma once class CPUThread; -enum CPUThreadType : unsigned char; +class RawSPUThread; -class CPUThreadManager +class CPUThreadManager final { std::mutex m_mutex; - std::vector> m_threads; - std::array, 5> m_raw_spu; + std::array, 5> m_raw_spu; public: CPUThreadManager(); @@ -16,16 +15,11 @@ public: void Close(); - std::shared_ptr AddThread(CPUThreadType type); + static std::vector> GetAllThreads(); - void RemoveThread(u32 id); + static void Exec(); - std::vector> GetThreads() { std::lock_guard lock(m_mutex); return m_threads; } + std::shared_ptr NewRawSPUThread(); - std::shared_ptr GetThread(u32 id); - std::shared_ptr GetThread(u32 id, CPUThreadType type); - std::shared_ptr GetRawSPUThread(u32 index); - - void Exec(); - void Task(); + std::shared_ptr GetRawSPUThread(u32 index); }; diff --git a/rpcs3/Emu/Cell/PPCDecoder.cpp b/rpcs3/Emu/Cell/PPCDecoder.cpp index 6425cf7c7a..7cbb50565f 100644 --- a/rpcs3/Emu/Cell/PPCDecoder.cpp +++ b/rpcs3/Emu/Cell/PPCDecoder.cpp @@ -4,8 +4,8 @@ u32 PPCDecoder::DecodeMemory(const u32 address) { - u32 instr = vm::read32(address); + u32 instr = vm::ps3::read32(address); Decode(instr); return sizeof(u32); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/Cell/PPCDisAsm.h b/rpcs3/Emu/Cell/PPCDisAsm.h index 2666033919..737c60dd60 100644 --- a/rpcs3/Emu/Cell/PPCDisAsm.h +++ b/rpcs3/Emu/Cell/PPCDisAsm.h @@ -43,7 +43,7 @@ protected: { Write(fmt::Format("%s v%d,r%d,r%d", FixOp(op).c_str(), v0, r1, r2)); } - void DisAsm_CR1_F2_RC(const std::string& op, u32 cr0, u32 f0, u32 f1, bool rc) + void DisAsm_CR1_F2_RC(const std::string& op, u32 cr0, u32 f0, u32 f1, u32 rc) { Write(fmt::Format("%s%s cr%d,f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), cr0, f0, f1)); } @@ -59,7 +59,7 @@ protected: { Write(fmt::Format("%s %d,r%d,%d #%x", FixOp(op).c_str(), i0, r0, imm0, imm0)); } - void DisAsm_INT1_R1_RC(const std::string& op, u32 i0, u32 r0, bool rc) + void DisAsm_INT1_R1_RC(const std::string& op, u32 i0, u32 r0, u32 rc) { Write(fmt::Format("%s%s %d,r%d", FixOp(op).c_str(), (rc ? "." : ""), i0, r0)); } @@ -67,11 +67,11 @@ protected: { DisAsm_INT1_R1_RC(op, i0, r0, false); } - void DisAsm_F4_RC(const std::string& op, u32 f0, u32 f1, u32 f2, u32 f3, bool rc) + void DisAsm_F4_RC(const std::string& op, u32 f0, u32 f1, u32 f2, u32 f3, u32 rc) { Write(fmt::Format("%s%s f%d,f%d,f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), f0, f1, f2, f3)); } - void DisAsm_F3_RC(const std::string& op, u32 f0, u32 f1, u32 f2, bool rc) + void DisAsm_F3_RC(const std::string& op, u32 f0, u32 f1, u32 f2, u32 rc) { Write(fmt::Format("%s%s f%d,f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), f0, f1, f2)); } @@ -79,7 +79,7 @@ protected: { DisAsm_F3_RC(op, f0, f1, f2, false); } - void DisAsm_F2_RC(const std::string& op, u32 f0, u32 f1, bool rc) + void DisAsm_F2_RC(const std::string& op, u32 f0, u32 f1, u32 rc) { Write(fmt::Format("%s%s f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), f0, f1)); } @@ -97,7 +97,7 @@ protected: Write(fmt::Format("%s f%d,r%d(r%d)", FixOp(op).c_str(), f0, r0, r1)); } - void DisAsm_F1_IMM_R1_RC(const std::string& op, u32 f0, s32 imm0, u32 r0, bool rc) + void DisAsm_F1_IMM_R1_RC(const std::string& op, u32 f0, s32 imm0, u32 r0, u32 rc) { if(m_mode == CPUDisAsm_CompilerElfMode) { @@ -111,11 +111,11 @@ protected: { DisAsm_F1_IMM_R1_RC(op, f0, imm0, r0, false); } - void DisAsm_F1_RC(const std::string& op, u32 f0, bool rc) + void DisAsm_F1_RC(const std::string& op, u32 f0, u32 rc) { Write(fmt::Format("%s%s f%d", FixOp(op).c_str(), (rc ? "." : ""), f0)); } - void DisAsm_R1_RC(const std::string& op, u32 r0, bool rc) + void DisAsm_R1_RC(const std::string& op, u32 r0, u32 rc) { Write(fmt::Format("%s%s r%d", FixOp(op).c_str(), (rc ? "." : ""), r0)); } @@ -123,11 +123,11 @@ protected: { DisAsm_R1_RC(op, r0, false); } - void DisAsm_R2_OE_RC(const std::string& op, u32 r0, u32 r1, u32 oe, bool rc) + void DisAsm_R2_OE_RC(const std::string& op, u32 r0, u32 r1, u32 oe, u32 rc) { Write(fmt::Format("%s%s%s r%d,r%d", FixOp(op).c_str(), (oe ? "o" : ""), (rc ? "." : ""), r0, r1)); } - void DisAsm_R2_RC(const std::string& op, u32 r0, u32 r1, bool rc) + void DisAsm_R2_RC(const std::string& op, u32 r0, u32 r1, u32 rc) { DisAsm_R2_OE_RC(op, r0, r1, false, rc); } @@ -135,15 +135,15 @@ protected: { DisAsm_R2_RC(op, r0, r1, false); } - void DisAsm_R3_OE_RC(const std::string& op, u32 r0, u32 r1, u32 r2, u32 oe, bool rc) + void DisAsm_R3_OE_RC(const std::string& op, u32 r0, u32 r1, u32 r2, u32 oe, u32 rc) { Write(fmt::Format("%s%s%s r%d,r%d,r%d", FixOp(op).c_str(), (oe ? "o" : ""), (rc ? "." : ""), r0, r1, r2)); } - void DisAsm_R3_INT2_RC(const std::string& op, u32 r0, u32 r1, u32 r2, s32 i0, s32 i1, bool rc) + void DisAsm_R3_INT2_RC(const std::string& op, u32 r0, u32 r1, u32 r2, s32 i0, s32 i1, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,r%d,%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, r2, i0, i1)); } - void DisAsm_R3_RC(const std::string& op, u32 r0, u32 r1, u32 r2, bool rc) + void DisAsm_R3_RC(const std::string& op, u32 r0, u32 r1, u32 r2, u32 rc) { DisAsm_R3_OE_RC(op, r0, r1, r2, false, rc); } @@ -151,7 +151,7 @@ protected: { DisAsm_R3_RC(op, r0, r1, r2, false); } - void DisAsm_R2_INT3_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, s32 i2, bool rc) + void DisAsm_R2_INT3_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, s32 i2, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,%d,%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, i0, i1, i2)); } @@ -159,7 +159,7 @@ protected: { DisAsm_R2_INT3_RC(op, r0, r1, i0, i1, i2, false); } - void DisAsm_R2_INT2_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, bool rc) + void DisAsm_R2_INT2_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, i0, i1)); } @@ -167,7 +167,7 @@ protected: { DisAsm_R2_INT2_RC(op, r0, r1, i0, i1, false); } - void DisAsm_R2_INT1_RC(const std::string& op, u32 r0, u32 r1, s32 i0, bool rc) + void DisAsm_R2_INT1_RC(const std::string& op, u32 r0, u32 r1, s32 i0, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, i0)); } @@ -197,7 +197,7 @@ protected: { Write(fmt::Format("%s cr%d,r%d,%d #%x", FixOp(op).c_str(), cr0, r0, imm0, imm0)); } - void DisAsm_CR1_R2_RC(const std::string& op, u32 cr0, u32 r0, u32 r1, bool rc) + void DisAsm_CR1_R2_RC(const std::string& op, u32 cr0, u32 r0, u32 r1, u32 rc) { Write(fmt::Format("%s%s cr%d,r%d,r%d", FixOp(op).c_str(), (rc ? "." : ""), cr0, r0, r1)); } diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 86d988ee67..0ad5d216c1 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -50,7 +50,7 @@ private: { Write(fmt::Format("%s v%d,r%d,r%d", FixOp(op).c_str(), v0, r1, r2)); } - void DisAsm_CR1_F2_RC(const std::string& op, u32 cr0, u32 f0, u32 f1, bool rc) + void DisAsm_CR1_F2_RC(const std::string& op, u32 cr0, u32 f0, u32 f1, u32 rc) { Write(fmt::Format("%s%s cr%d,f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), cr0, f0, f1)); } @@ -66,7 +66,7 @@ private: { Write(fmt::Format("%s %d,r%d,%d #%x", FixOp(op).c_str(), i0, r0, imm0, imm0)); } - void DisAsm_INT1_R1_RC(const std::string& op, u32 i0, u32 r0, bool rc) + void DisAsm_INT1_R1_RC(const std::string& op, u32 i0, u32 r0, u32 rc) { Write(fmt::Format("%s%s %d,r%d", FixOp(op).c_str(), (rc ? "." : ""), i0, r0)); } @@ -74,11 +74,11 @@ private: { DisAsm_INT1_R1_RC(op, i0, r0, false); } - void DisAsm_F4_RC(const std::string& op, u32 f0, u32 f1, u32 f2, u32 f3, bool rc) + void DisAsm_F4_RC(const std::string& op, u32 f0, u32 f1, u32 f2, u32 f3, u32 rc) { Write(fmt::Format("%s%s f%d,f%d,f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), f0, f1, f2, f3)); } - void DisAsm_F3_RC(const std::string& op, u32 f0, u32 f1, u32 f2, bool rc) + void DisAsm_F3_RC(const std::string& op, u32 f0, u32 f1, u32 f2, u32 rc) { Write(fmt::Format("%s%s f%d,f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), f0, f1, f2)); } @@ -86,7 +86,7 @@ private: { DisAsm_F3_RC(op, f0, f1, f2, false); } - void DisAsm_F2_RC(const std::string& op, u32 f0, u32 f1, bool rc) + void DisAsm_F2_RC(const std::string& op, u32 f0, u32 f1, u32 rc) { Write(fmt::Format("%s%s f%d,f%d", FixOp(op).c_str(), (rc ? "." : ""), f0, f1)); } @@ -104,7 +104,7 @@ private: Write(fmt::Format("%s f%d,r%d(r%d)", FixOp(op).c_str(), f0, r0, r1)); } - void DisAsm_F1_IMM_R1_RC(const std::string& op, u32 f0, s32 imm0, u32 r0, bool rc) + void DisAsm_F1_IMM_R1_RC(const std::string& op, u32 f0, s32 imm0, u32 r0, u32 rc) { if(m_mode == CPUDisAsm_CompilerElfMode) { @@ -118,11 +118,11 @@ private: { DisAsm_F1_IMM_R1_RC(op, f0, imm0, r0, false); } - void DisAsm_F1_RC(const std::string& op, u32 f0, bool rc) + void DisAsm_F1_RC(const std::string& op, u32 f0, u32 rc) { Write(fmt::Format("%s%s f%d", FixOp(op).c_str(), (rc ? "." : ""), f0)); } - void DisAsm_R1_RC(const std::string& op, u32 r0, bool rc) + void DisAsm_R1_RC(const std::string& op, u32 r0, u32 rc) { Write(fmt::Format("%s%s r%d", FixOp(op).c_str(), (rc ? "." : ""), r0)); } @@ -130,11 +130,11 @@ private: { DisAsm_R1_RC(op, r0, false); } - void DisAsm_R2_OE_RC(const std::string& op, u32 r0, u32 r1, u32 oe, bool rc) + void DisAsm_R2_OE_RC(const std::string& op, u32 r0, u32 r1, u32 oe, u32 rc) { Write(fmt::Format("%s%s%s r%d,r%d", FixOp(op).c_str(), (oe ? "o" : ""), (rc ? "." : ""), r0, r1)); } - void DisAsm_R2_RC(const std::string& op, u32 r0, u32 r1, bool rc) + void DisAsm_R2_RC(const std::string& op, u32 r0, u32 r1, u32 rc) { DisAsm_R2_OE_RC(op, r0, r1, false, rc); } @@ -142,15 +142,15 @@ private: { DisAsm_R2_RC(op, r0, r1, false); } - void DisAsm_R3_OE_RC(const std::string& op, u32 r0, u32 r1, u32 r2, u32 oe, bool rc) + void DisAsm_R3_OE_RC(const std::string& op, u32 r0, u32 r1, u32 r2, u32 oe, u32 rc) { Write(fmt::Format("%s%s%s r%d,r%d,r%d", FixOp(op).c_str(), (oe ? "o" : ""), (rc ? "." : ""), r0, r1, r2)); } - void DisAsm_R3_INT2_RC(const std::string& op, u32 r0, u32 r1, u32 r2, s32 i0, s32 i1, bool rc) + void DisAsm_R3_INT2_RC(const std::string& op, u32 r0, u32 r1, u32 r2, s32 i0, s32 i1, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,r%d,%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, r2, i0, i1)); } - void DisAsm_R3_RC(const std::string& op, u32 r0, u32 r1, u32 r2, bool rc) + void DisAsm_R3_RC(const std::string& op, u32 r0, u32 r1, u32 r2, u32 rc) { DisAsm_R3_OE_RC(op, r0, r1, r2, false, rc); } @@ -158,7 +158,7 @@ private: { DisAsm_R3_RC(op, r0, r1, r2, false); } - void DisAsm_R2_INT3_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, s32 i2, bool rc) + void DisAsm_R2_INT3_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, s32 i2, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,%d,%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, i0, i1, i2)); } @@ -166,7 +166,7 @@ private: { DisAsm_R2_INT3_RC(op, r0, r1, i0, i1, i2, false); } - void DisAsm_R2_INT2_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, bool rc) + void DisAsm_R2_INT2_RC(const std::string& op, u32 r0, u32 r1, s32 i0, s32 i1, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, i0, i1)); } @@ -174,7 +174,7 @@ private: { DisAsm_R2_INT2_RC(op, r0, r1, i0, i1, false); } - void DisAsm_R2_INT1_RC(const std::string& op, u32 r0, u32 r1, s32 i0, bool rc) + void DisAsm_R2_INT1_RC(const std::string& op, u32 r0, u32 r1, s32 i0, u32 rc) { Write(fmt::Format("%s%s r%d,r%d,%d", FixOp(op).c_str(), (rc ? "." : ""), r0, r1, i0)); } @@ -204,7 +204,7 @@ private: { Write(fmt::Format("%s cr%d,r%d,%d #%x", FixOp(op).c_str(), cr0, r0, imm0, imm0)); } - void DisAsm_CR1_R2_RC(const std::string& op, u32 cr0, u32 r0, u32 r1, bool rc) + void DisAsm_CR1_R2_RC(const std::string& op, u32 cr0, u32 r0, u32 r1, u32 rc) { Write(fmt::Format("%s%s cr%d,r%d,r%d", FixOp(op).c_str(), (rc ? "." : ""), cr0, r0, r1)); } @@ -1128,15 +1128,15 @@ private: case 1: DisAsm_INT3("bcctrl", bo, bi, bh); break; } } - void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) + void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { DisAsm_R2_INT3_RC("rlwimi", ra, rs, sh, mb, me, rc); } - void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) + void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { DisAsm_R2_INT3_RC("rlwinm", ra, rs, sh, mb, me, rc); } - void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, bool rc) + void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, u32 rc) { DisAsm_R3_INT2_RC("rlwnm", ra, rs, rb, MB, ME, rc); } @@ -1174,7 +1174,7 @@ private: { DisAsm_R2_IMM("andis.", ra, rs, uimm16); } - void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) + void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { if(sh == 0) { @@ -1193,19 +1193,19 @@ private: DisAsm_R2_INT2_RC("rldicl", ra, rs, sh, mb, rc); } } - void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) + void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, u32 rc) { DisAsm_R2_INT2_RC("rldicr", ra, rs, sh, me, rc); } - void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) + void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { DisAsm_R2_INT2_RC("rldic", ra, rs, sh, mb, rc); } - void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) + void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { DisAsm_R2_INT2_RC("rldimi", ra, rs, sh, mb, rc); } - void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) + void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, u32 is_r, u32 rc) { if (is_r) DisAsm_R3_INT2_RC("rldcr", ra, rs, rb, m_eb, 0, rc); @@ -1228,19 +1228,19 @@ private: { DisAsm_V1_R2("lvebx", vd, ra, rb); } - void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("subfc", rd, ra, rb, oe, rc); } - void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("addc", rd, ra, rb, oe, rc); } - void MULHDU(u32 rd, u32 ra, u32 rb, bool rc) + void MULHDU(u32 rd, u32 ra, u32 rb, u32 rc) { DisAsm_R3_RC("mulhdu", rd, ra, rb, rc); } - void MULHWU(u32 rd, u32 ra, u32 rb, bool rc) + void MULHWU(u32 rd, u32 ra, u32 rb, u32 rc) { DisAsm_R3_RC("mulhwu", rd, ra, rb, rc); } @@ -1267,19 +1267,19 @@ private: { DisAsm_R3("lwzx", rd, ra, rb); } - void SLW(u32 ra, u32 rs, u32 rb, bool rc) + void SLW(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("slw", ra, rs, rb, rc); } - void CNTLZW(u32 ra, u32 rs, bool rc) + void CNTLZW(u32 ra, u32 rs, u32 rc) { DisAsm_R2_RC("cntlzw", ra, rs, rc); } - void SLD(u32 ra, u32 rs, u32 rb, bool rc) + void SLD(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("sld", ra, rs, rb, rc); } - void AND(u32 ra, u32 rs, u32 rb, bool rc) + void AND(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("and", ra, rs, rb, rc); } @@ -1295,7 +1295,7 @@ private: { DisAsm_V1_R2("lvehx", vd, ra, rb); } - void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("subf", rd, ra, rb, oe, rc); } @@ -1311,11 +1311,11 @@ private: { DisAsm_R3("lwzux", rd, ra, rb); } - void CNTLZD(u32 ra, u32 rs, bool rc) + void CNTLZD(u32 ra, u32 rs, u32 rc) { DisAsm_R2_RC("cntlzd", ra, rs, rc); } - void ANDC(u32 ra, u32 rs, u32 rb, bool rc) + void ANDC(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("andc", ra, rs, rb, rc); } @@ -1327,11 +1327,11 @@ private: { DisAsm_V1_R2("lvewx", vd, ra, rb); } - void MULHD(u32 rd, u32 ra, u32 rb, bool rc) + void MULHD(u32 rd, u32 ra, u32 rb, u32 rc) { DisAsm_R3_RC("mulhd", rd, ra, rb, rc); } - void MULHW(u32 rd, u32 ra, u32 rb, bool rc) + void MULHW(u32 rd, u32 ra, u32 rb, u32 rc) { DisAsm_R3_RC("mulhw", rd, ra, rb, rc); } @@ -1351,7 +1351,7 @@ private: { DisAsm_V1_R2("lvx", vd, ra, rb); } - void NEG(u32 rd, u32 ra, u32 oe, bool rc) + void NEG(u32 rd, u32 ra, u32 oe, u32 rc) { DisAsm_R2_OE_RC("neg", rd, ra, oe, rc); } @@ -1359,7 +1359,7 @@ private: { DisAsm_R3("lbzux", rd, ra, rb); } - void NOR(u32 ra, u32 rs, u32 rb, bool rc) + void NOR(u32 ra, u32 rs, u32 rb, u32 rc) { if(rs == rb) { @@ -1374,11 +1374,11 @@ private: { DisAsm_V1_R2("stvebx", vs, ra, rb); } - void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("subfe", rd, ra, rb, oe, rc); } - void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("adde", rd, ra, rb, oe, rc); } @@ -1421,11 +1421,11 @@ private: { DisAsm_V1_R2("stvewx", vs, ra, rb); } - void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) + void SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) { DisAsm_R2_OE_RC("subfze", rd, ra, oe, rc); } - void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) + void ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) { DisAsm_R2_OE_RC("addze", rd, ra, oe, rc); } @@ -1441,19 +1441,19 @@ private: { DisAsm_V1_R2("stvx", vd, ra, rb); } - void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) + void SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) { DisAsm_R2_OE_RC("subfme", rd, ra, oe, rc); } - void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("mulld", rd, ra, rb, oe, rc); } - void ADDME(u32 rd, u32 ra, u32 oe, bool rc) + void ADDME(u32 rd, u32 ra, u32 oe, u32 rc) { DisAsm_R2_OE_RC("addme", rd, ra, oe, rc); } - void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("mullw", rd, ra, rb, oe, rc); } @@ -1465,7 +1465,7 @@ private: { DisAsm_R3("stbux", rs, ra, rb); } - void ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void ADD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("add", rd, ra, rb, oe, rc); } @@ -1477,7 +1477,7 @@ private: { DisAsm_R3("lhzx", rd, ra, rb); } - void EQV(u32 ra, u32 rs, u32 rb, bool rc) + void EQV(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("eqv", ra, rs, rb, rc); } @@ -1489,7 +1489,7 @@ private: { DisAsm_R3("lhzux", rd, ra, rb); } - void XOR(u32 ra, u32 rs, u32 rb, bool rc) + void XOR(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("xor", ra, rs, rb, rc); } @@ -1560,7 +1560,7 @@ private: { DisAsm_R3("sthx", rs, ra, rb); } - void ORC(u32 ra, u32 rs, u32 rb, bool rc) + void ORC(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("orc", ra, rs, rb, rc); } @@ -1572,7 +1572,7 @@ private: { DisAsm_R3("sthux", rs, ra, rb); } - void OR(u32 ra, u32 rs, u32 rb, bool rc) + void OR(u32 ra, u32 rs, u32 rb, u32 rc) { if(rs==rb) { @@ -1583,11 +1583,11 @@ private: DisAsm_R3_RC("or", ra, rs, rb, rc); } } - void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("divdu", rd, ra, rb, oe, rc); } - void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("divwu", rd, ra, rb, oe, rc); } @@ -1607,7 +1607,7 @@ private: { DisAsm_R2("dcbi", ra, rb); } - void NAND(u32 ra, u32 rs, u32 rb, bool rc) + void NAND(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("nand", ra, rs, rb, rc); } @@ -1615,11 +1615,11 @@ private: { DisAsm_V1_R2("stvxl", vs, ra, rb); } - void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("divd", rd, ra, rb, oe, rc); } - void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { DisAsm_R3_OE_RC("divw", rd, ra, rb, oe, rc); } @@ -1643,11 +1643,11 @@ private: { DisAsm_F1_R2("lfsx", frd, ra, rb); } - void SRW(u32 ra, u32 rs, u32 rb, bool rc) + void SRW(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("srw", ra, rs, rb, rc); } - void SRD(u32 ra, u32 rs, u32 rb, bool rc) + void SRD(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("srd", ra, rs, rb, rc); } @@ -1723,11 +1723,11 @@ private: { DisAsm_R3("lhbrx", rd, ra, rb); } - void SRAW(u32 ra, u32 rs, u32 rb, bool rc) + void SRAW(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("sraw", ra, rs, rb, rc); } - void SRAD(u32 ra, u32 rs, u32 rb, bool rc) + void SRAD(u32 ra, u32 rs, u32 rb, u32 rc) { DisAsm_R3_RC("srad", ra, rs, rb, rc); } @@ -1746,15 +1746,15 @@ private: DisAsm_INT1("dss", strm); } } - void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) + void SRAWI(u32 ra, u32 rs, u32 sh, u32 rc) { DisAsm_R2_INT1_RC("srawi", ra, rs, sh, rc); } - void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) + void SRADI1(u32 ra, u32 rs, u32 sh, u32 rc) { DisAsm_R2_INT1_RC("sradi", ra, rs, sh, rc); } - void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) + void SRADI2(u32 ra, u32 rs, u32 sh, u32 rc) { DisAsm_R2_INT1_RC("sradi", ra, rs, sh, rc); } @@ -1770,7 +1770,7 @@ private: { DisAsm_R3("sthbrx", rs, ra, rb); } - void EXTSH(u32 ra, u32 rs, bool rc) + void EXTSH(u32 ra, u32 rs, u32 rc) { DisAsm_R2_RC("extsh", ra, rs, rc); } @@ -1778,7 +1778,7 @@ private: { DisAsm_V1_R2("stvrxl", sd, ra, rb); } - void EXTSB(u32 ra, u32 rs, bool rc) + void EXTSB(u32 ra, u32 rs, u32 rc) { DisAsm_R2_RC("extsb", ra, rs, rc); } @@ -1786,7 +1786,7 @@ private: { DisAsm_F1_R2("stfiwx", frs, ra, rb); } - void EXTSW(u32 ra, u32 rs, bool rc) + void EXTSW(u32 ra, u32 rs, u32 rc) { DisAsm_R2_RC("extsw", ra, rs, rc); } @@ -1906,43 +1906,43 @@ private: { DisAsm_R2_IMM("lwa", rd, ra, ds); } - void FDIVS(u32 frd, u32 fra, u32 frb, bool rc) + void FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) { DisAsm_F3_RC("fdivs", frd, fra, frb, rc); } - void FSUBS(u32 frd, u32 fra, u32 frb, bool rc) + void FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) { DisAsm_F3_RC("fsubs", frd, fra, frb, rc); } - void FADDS(u32 frd, u32 fra, u32 frb, bool rc) + void FADDS(u32 frd, u32 fra, u32 frb, u32 rc) { DisAsm_F3_RC("fadds", frd, fra, frb, rc); } - void FSQRTS(u32 frd, u32 frb, bool rc) + void FSQRTS(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fsqrts", frd, frb, rc); } - void FRES(u32 frd, u32 frb, bool rc) + void FRES(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fres", frd, frb, rc); } - void FMULS(u32 frd, u32 fra, u32 frc, bool rc) + void FMULS(u32 frd, u32 fra, u32 frc, u32 rc) { DisAsm_F3_RC("fmuls", frd, fra, frc, rc); } - void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fmadds", frd, fra, frc, frb, rc); } - void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fmsubs", frd, fra, frc, frb, rc); } - void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fnmsubs", frd, fra, frc, frb, rc); } - void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fnmadds", frd, fra, frc, frb, rc); } @@ -1954,7 +1954,7 @@ private: { DisAsm_R2_IMM("stdu", rs, ra, ds); } - void MTFSB1(u32 bt, bool rc) + void MTFSB1(u32 bt, u32 rc) { DisAsm_F1_RC("mtfsb1", bt, rc); } @@ -1962,19 +1962,19 @@ private: { DisAsm_F2("mcrfs", bf, bfa); } - void MTFSB0(u32 bt, bool rc) + void MTFSB0(u32 bt, u32 rc) { DisAsm_F1_RC("mtfsb0", bt, rc); } - void MTFSFI(u32 crfd, u32 i, bool rc) + void MTFSFI(u32 crfd, u32 i, u32 rc) { DisAsm_F2_RC("mtfsfi", crfd, i, rc); } - void MFFS(u32 frd, bool rc) + void MFFS(u32 frd, u32 rc) { DisAsm_F1_RC("mffs", frd, rc); } - void MTFSF(u32 flm, u32 frb, bool rc) + void MTFSF(u32 flm, u32 frb, u32 rc) { DisAsm_F2_RC("mtfsf", flm, frb, rc); } @@ -1982,59 +1982,59 @@ private: { DisAsm_CR1_F2("fcmpu", crfd, fra, frb); } - void FRSP(u32 frd, u32 frb, bool rc) + void FRSP(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("frsp", frd, frb, rc); } - void FCTIW(u32 frd, u32 frb, bool rc) + void FCTIW(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fctiw", frd, frb, rc); } - void FCTIWZ(u32 frd, u32 frb, bool rc) + void FCTIWZ(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fctiwz", frd, frb, rc); } - void FDIV(u32 frd, u32 fra, u32 frb, bool rc) + void FDIV(u32 frd, u32 fra, u32 frb, u32 rc) { DisAsm_F3_RC("fdiv", frd, fra, frb, rc); } - void FSUB(u32 frd, u32 fra, u32 frb, bool rc) + void FSUB(u32 frd, u32 fra, u32 frb, u32 rc) { DisAsm_F3_RC("fsub", frd, fra, frb, rc); } - void FADD(u32 frd, u32 fra, u32 frb, bool rc) + void FADD(u32 frd, u32 fra, u32 frb, u32 rc) { DisAsm_F3_RC("fadd", frd, fra, frb, rc); } - void FSQRT(u32 frd, u32 frb, bool rc) + void FSQRT(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fsqrt", frd, frb, rc); } - void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fsel", frd, fra, frc, frb, rc); } - void FMUL(u32 frd, u32 fra, u32 frc, bool rc) + void FMUL(u32 frd, u32 fra, u32 frc, u32 rc) { DisAsm_F3_RC("fmul", frd, fra, frc, rc); } - void FRSQRTE(u32 frd, u32 frb, bool rc) + void FRSQRTE(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("frsqrte", frd, frb, rc); } - void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fmsub", frd, fra, frc, frb, rc); } - void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fmadd", frd, fra, frc, frb, rc); } - void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fnmsub", frd, fra, frc, frb, rc); } - void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { DisAsm_F4_RC("fnmadd", frd, fra, frc, frb, rc); } @@ -2042,31 +2042,31 @@ private: { DisAsm_F3("fcmpo", crfd, fra, frb); } - void FNEG(u32 frd, u32 frb, bool rc) + void FNEG(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fneg", frd, frb, rc); } - void FMR(u32 frd, u32 frb, bool rc) + void FMR(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fmr", frd, frb, rc); } - void FNABS(u32 frd, u32 frb, bool rc) + void FNABS(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fnabs", frd, frb, rc); } - void FABS(u32 frd, u32 frb, bool rc) + void FABS(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fabs", frd, frb, rc); } - void FCTID(u32 frd, u32 frb, bool rc) + void FCTID(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fctid", frd, frb, rc); } - void FCTIDZ(u32 frd, u32 frb, bool rc) + void FCTIDZ(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fctidz", frd, frb, rc); } - void FCFID(u32 frd, u32 frb, bool rc) + void FCFID(u32 frd, u32 frb, u32 rc) { DisAsm_F2_RC("fcfid", frd, frb, rc); } diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index 74152cfe60..949301ac7e 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -9,7 +9,6 @@ #include "PPUInstrTable.h" #include "PPUInterpreter.h" #include "PPUInterpreter2.h" -#include "Emu/CPU/CPUThreadManager.h" class ppu_scale_table_t { @@ -53,7 +52,7 @@ void ppu_interpreter::TDI(PPUThread& CPU, ppu_opcode_t op) ((op.bo & 0x2) && a_ < b_) || ((op.bo & 0x1) && a_ > b_)) { - throw __FUNCTION__; + throw EXCEPTION(""); } } @@ -68,14 +67,14 @@ void ppu_interpreter::TWI(PPUThread& CPU, ppu_opcode_t op) ((op.bo & 0x2) && a_ < b_) || ((op.bo & 0x1) && a_ > b_)) { - throw __FUNCTION__; + throw EXCEPTION(""); } } void ppu_interpreter::MFVSCR(PPUThread& CPU, ppu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION(""); } void ppu_interpreter::MTVSCR(PPUThread& CPU, ppu_opcode_t op) @@ -1462,7 +1461,7 @@ void ppu_interpreter::BC(PPUThread& CPU, ppu_opcode_t op) if (ctr_ok && cond_ok) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(PPUOpcodes::branchTarget((op.aa ? 0 : CPU.PC), op.simm16), op.lk); + CPU.PC = PPUOpcodes::branchTarget((op.aa ? 0 : CPU.PC), op.simm16) - 4; if (op.lk) CPU.LR = nextLR; } } @@ -1478,14 +1477,14 @@ void ppu_interpreter::SC(PPUThread& CPU, ppu_opcode_t op) { case 0x0: SysCalls::DoSyscall(CPU, CPU.GPR[11]); break; case 0x3: CPU.FastStop(); break; - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } } void ppu_interpreter::B(PPUThread& CPU, ppu_opcode_t op) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(PPUOpcodes::branchTarget(op.aa ? 0 : CPU.PC, op.ll), op.lk); + CPU.PC = PPUOpcodes::branchTarget(op.aa ? 0 : CPU.PC, op.ll) - 4; if (op.lk) CPU.LR = nextLR; } @@ -1509,7 +1508,7 @@ void ppu_interpreter::BCLR(PPUThread& CPU, ppu_opcode_t op) if (ctr_ok && cond_ok) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(PPUOpcodes::branchTarget(0, (u32)CPU.LR), true); + CPU.PC = PPUOpcodes::branchTarget(0, (u32)CPU.LR) - 4; if (op.lk) CPU.LR = nextLR; } } @@ -1572,7 +1571,7 @@ void ppu_interpreter::BCCTR(PPUThread& CPU, ppu_opcode_t op) if (op.bo & 0x10 || CPU.IsCR(op.bi) == ((op.bo & 0x8) != 0)) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(PPUOpcodes::branchTarget(0, (u32)CPU.CTR), true); + CPU.PC = PPUOpcodes::branchTarget(0, (u32)CPU.CTR) - 4; if (op.lk) CPU.LR = nextLR; } } @@ -1698,7 +1697,7 @@ void ppu_interpreter::TW(PPUThread& CPU, ppu_opcode_t op) ((u32)a < (u32)b && (op.bo & 0x2)) || ((u32)a >(u32)b && (op.bo & 0x1))) { - throw __FUNCTION__; + throw EXCEPTION(""); } } @@ -1733,7 +1732,7 @@ void ppu_interpreter::LVSL(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LVEBX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.VPR[op.vd]._u8[15 - (addr & 0xf)] = vm::read8(vm::cast(addr)); + CPU.VPR[op.vd]._u8[15 - (addr & 0xf)] = vm::read8(VM_CAST(addr)); } void ppu_interpreter::SUBFC(PPUThread& CPU, ppu_opcode_t op) @@ -1780,7 +1779,7 @@ void ppu_interpreter::LWARX(PPUThread& CPU, ppu_opcode_t op) const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; be_t value; - vm::reservation_acquire(&value, vm::cast(addr), sizeof(value)); + vm::reservation_acquire(&value, VM_CAST(addr), sizeof32(value)); CPU.GPR[op.rd] = value; } @@ -1788,13 +1787,13 @@ void ppu_interpreter::LWARX(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LDX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read64(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read64(VM_CAST(addr)); } void ppu_interpreter::LWZX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read32(VM_CAST(addr)); } void ppu_interpreter::SLW(PPUThread& CPU, ppu_opcode_t op) @@ -1873,7 +1872,7 @@ void ppu_interpreter::LVSR(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LVEHX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~1ULL; - CPU.VPR[op.vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(vm::cast(addr)); + CPU.VPR[op.vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(VM_CAST(addr)); } void ppu_interpreter::SUBF(PPUThread& CPU, ppu_opcode_t op) @@ -1888,7 +1887,7 @@ void ppu_interpreter::SUBF(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LDUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read64(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read64(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } @@ -1899,7 +1898,7 @@ void ppu_interpreter::DCBST(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LWZUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read32(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } @@ -1923,13 +1922,13 @@ void ppu_interpreter::ANDC(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::TD(PPUThread& CPU, ppu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION(""); } void ppu_interpreter::LVEWX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~3ULL; - CPU.VPR[op.vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(vm::cast(addr)); + CPU.VPR[op.vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(VM_CAST(addr)); } void ppu_interpreter::MULHD(PPUThread& CPU, ppu_opcode_t op) @@ -1951,7 +1950,7 @@ void ppu_interpreter::LDARX(PPUThread& CPU, ppu_opcode_t op) const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; be_t value; - vm::reservation_acquire(&value, vm::cast(addr), sizeof(value)); + vm::reservation_acquire(&value, VM_CAST(addr), sizeof32(value)); CPU.GPR[op.rd] = value; } @@ -1963,13 +1962,13 @@ void ppu_interpreter::DCBF(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LBZX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read8(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read8(VM_CAST(addr)); } void ppu_interpreter::LVX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~0xfull; - CPU.VPR[op.vd] = vm::read128(vm::cast(addr)); + CPU.VPR[op.vd] = vm::read128(VM_CAST(addr)); } void ppu_interpreter::NEG(PPUThread& CPU, ppu_opcode_t op) @@ -1983,7 +1982,7 @@ void ppu_interpreter::NEG(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LBZUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read8(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read8(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } @@ -1997,7 +1996,7 @@ void ppu_interpreter::STVEBX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; const u8 eb = addr & 0xf; - vm::write8(vm::cast(addr), CPU.VPR[op.vs]._u8[15 - eb]); + vm::write8(VM_CAST(addr), CPU.VPR[op.vs]._u8[15 - eb]); } void ppu_interpreter::SUBFE(PPUThread& CPU, ppu_opcode_t op) @@ -2073,41 +2072,41 @@ void ppu_interpreter::MTOCRF(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STDX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::write64(vm::cast(addr), CPU.GPR[op.rs]); + vm::write64(VM_CAST(addr), CPU.GPR[op.rs]); } void ppu_interpreter::STWCX_(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - const be_t value = be_t::make((u32)CPU.GPR[op.rs]); - CPU.SetCR_EQ(0, vm::reservation_update(vm::cast(addr), &value, sizeof(value))); + const be_t value = (u32)CPU.GPR[op.rs]; + CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, sizeof32(value))); } void ppu_interpreter::STWX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::write32(vm::cast(addr), (u32)CPU.GPR[op.rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[op.rs]); } void ppu_interpreter::STVEHX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~1ULL; const u8 eb = (addr & 0xf) >> 1; - vm::write16(vm::cast(addr), CPU.VPR[op.vs]._u16[7 - eb]); + vm::write16(VM_CAST(addr), CPU.VPR[op.vs]._u16[7 - eb]); } void ppu_interpreter::STDUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - vm::write64(vm::cast(addr), CPU.GPR[op.rs]); + vm::write64(VM_CAST(addr), CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STWUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - vm::write32(vm::cast(addr), (u32)CPU.GPR[op.rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } @@ -2115,7 +2114,7 @@ void ppu_interpreter::STVEWX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~3ULL; const u8 eb = (addr & 0xf) >> 2; - vm::write32(vm::cast(addr), CPU.VPR[op.vs]._u32[3 - eb]); + vm::write32(VM_CAST(addr), CPU.VPR[op.vs]._u32[3 - eb]); } void ppu_interpreter::SUBFZE(PPUThread& CPU, ppu_opcode_t op) @@ -2140,20 +2139,20 @@ void ppu_interpreter::STDCX_(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - const be_t value = be_t::make(CPU.GPR[op.rs]); - CPU.SetCR_EQ(0, vm::reservation_update(vm::cast(addr), &value, sizeof(value))); + const be_t value = CPU.GPR[op.rs]; + CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, sizeof32(value))); } void ppu_interpreter::STBX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::write8(vm::cast(addr), (u8)CPU.GPR[op.rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[op.rs]); } void ppu_interpreter::STVX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~0xfull; - vm::write128(vm::cast(addr), CPU.VPR[op.vs]); + vm::write128(VM_CAST(addr), CPU.VPR[op.vs]); } void ppu_interpreter::MULLD(PPUThread& CPU, ppu_opcode_t op) @@ -2202,7 +2201,7 @@ void ppu_interpreter::DCBTST(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STBUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - vm::write8(vm::cast(addr), (u8)CPU.GPR[op.rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } @@ -2222,7 +2221,7 @@ void ppu_interpreter::DCBT(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LHZX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read16(VM_CAST(addr)); } void ppu_interpreter::EQV(PPUThread& CPU, ppu_opcode_t op) @@ -2233,13 +2232,13 @@ void ppu_interpreter::EQV(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::ECIWX(PPUThread& CPU, ppu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION(""); } void ppu_interpreter::LHZUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read16(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } @@ -2261,8 +2260,8 @@ void ppu_interpreter::MFSPR(PPUThread& CPU, ppu_opcode_t op) case 0x100: CPU.GPR[op.rd] = CPU.VRSAVE; return; case 0x103: CPU.GPR[op.rd] = CPU.SPRG[3]; return; - case 0x10C: CPU.TB = get_time(); CPU.GPR[op.rd] = CPU.TB; return; - case 0x10D: CPU.TB = get_time(); CPU.GPR[op.rd] = CPU.TB >> 32; return; + case 0x10C: CPU.TB = get_timebased_time(); CPU.GPR[op.rd] = CPU.TB; return; + case 0x10D: CPU.TB = get_timebased_time(); CPU.GPR[op.rd] = CPU.TB >> 32; return; case 0x110: case 0x111: @@ -2274,13 +2273,13 @@ void ppu_interpreter::MFSPR(PPUThread& CPU, ppu_opcode_t op) case 0x117: CPU.GPR[op.rd] = CPU.SPRG[n - 0x110]; return; } - throw __FUNCTION__; + throw EXCEPTION(""); } void ppu_interpreter::LWAX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s32)vm::read32(VM_CAST(addr)); } void ppu_interpreter::DST(PPUThread& CPU, ppu_opcode_t op) @@ -2290,32 +2289,32 @@ void ppu_interpreter::DST(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LHAX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s16)vm::read16(VM_CAST(addr)); } void ppu_interpreter::LVXL(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~0xfull; - CPU.VPR[op.vd] = vm::read128(vm::cast(addr)); + CPU.VPR[op.vd] = vm::read128(VM_CAST(addr)); } void ppu_interpreter::MFTB(PPUThread& CPU, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); - CPU.TB = get_time(); + CPU.TB = get_timebased_time(); switch (n) { case 0x10C: CPU.GPR[op.rd] = CPU.TB; break; case 0x10D: CPU.GPR[op.rd] = CPU.TB >> 32; break; - default: throw __FUNCTION__; + default: throw EXCEPTION(""); } } void ppu_interpreter::LWAUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s32)vm::read32(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } @@ -2326,14 +2325,14 @@ void ppu_interpreter::DSTST(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LHAUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s16)vm::read16(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STHX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::write16(vm::cast(addr), (u16)CPU.GPR[op.rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[op.rs]); } void ppu_interpreter::ORC(PPUThread& CPU, ppu_opcode_t op) @@ -2344,13 +2343,13 @@ void ppu_interpreter::ORC(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::ECOWX(PPUThread& CPU, ppu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION(""); } void ppu_interpreter::STHUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - vm::write16(vm::cast(addr), (u16)CPU.GPR[op.rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } @@ -2419,7 +2418,7 @@ void ppu_interpreter::MTSPR(PPUThread& CPU, ppu_opcode_t op) case 0x117: CPU.SPRG[n - 0x110] = CPU.GPR[op.rs]; return; } - throw __FUNCTION__; + throw EXCEPTION(""); } void ppu_interpreter::DCBI(PPUThread& CPU, ppu_opcode_t op) @@ -2436,7 +2435,7 @@ void ppu_interpreter::NAND(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STVXL(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]) & ~0xfull; - vm::write128(vm::cast(addr), CPU.VPR[op.vs]); + vm::write128(VM_CAST(addr), CPU.VPR[op.vs]); } void ppu_interpreter::DIVD(PPUThread& CPU, ppu_opcode_t op) @@ -2483,13 +2482,13 @@ void ppu_interpreter::LVLX(PPUThread& CPU, ppu_opcode_t op) const u32 eb = addr & 0xf; CPU.VPR[op.vd].clear(); - for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i)); + for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i)); } void ppu_interpreter::LDBRX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::get_ref(vm::cast(addr)); + CPU.GPR[op.rd] = vm::get_ref(VM_CAST(addr)); } void ppu_interpreter::LSWX(PPUThread& CPU, ppu_opcode_t op) @@ -2498,14 +2497,14 @@ void ppu_interpreter::LSWX(PPUThread& CPU, ppu_opcode_t op) u32 count = CPU.XER.XER & 0x7F; for (; count >= 4; count -= 4, addr += 4, op.rd = (op.rd + 1) & 31) { - CPU.GPR[op.rd] = vm::get_ref>(vm::cast(addr)); + CPU.GPR[op.rd] = vm::get_ref>(VM_CAST(addr)); } if (count) { u32 value = 0; for (u32 byte = 0; byte < count; byte++) { - u32 byte_value = vm::get_ref(vm::cast(addr + byte)); + u32 byte_value = vm::get_ref(VM_CAST(addr + byte)); value |= byte_value << ((3 ^ byte) * 8); } CPU.GPR[op.rd] = value; @@ -2515,13 +2514,13 @@ void ppu_interpreter::LSWX(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LWBRX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::get_ref(vm::cast(addr)); + CPU.GPR[op.rd] = vm::get_ref(VM_CAST(addr)); } void ppu_interpreter::LFSX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); } void ppu_interpreter::SRW(PPUThread& CPU, ppu_opcode_t op) @@ -2550,7 +2549,7 @@ void ppu_interpreter::LVRX(PPUThread& CPU, ppu_opcode_t op) const u8 eb = addr & 0xf; CPU.VPR[op.vd].clear(); - for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16)); + for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i - 16)); } void ppu_interpreter::LSWI(PPUThread& CPU, ppu_opcode_t op) @@ -2563,7 +2562,7 @@ void ppu_interpreter::LSWI(PPUThread& CPU, ppu_opcode_t op) { if (N > 3) { - CPU.GPR[reg] = vm::read32(vm::cast(addr)); + CPU.GPR[reg] = vm::read32(VM_CAST(addr)); addr += 4; N -= 4; } @@ -2574,7 +2573,7 @@ void ppu_interpreter::LSWI(PPUThread& CPU, ppu_opcode_t op) while (N > 0) { N = N - 1; - buf |= vm::read8(vm::cast(addr)) << (i * 8); + buf |= vm::read8(VM_CAST(addr)) << (i * 8); addr++; i--; } @@ -2587,7 +2586,7 @@ void ppu_interpreter::LSWI(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LFSUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); CPU.GPR[op.ra] = addr; } @@ -2599,13 +2598,13 @@ void ppu_interpreter::SYNC(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::LFDX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); } void ppu_interpreter::LFDUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); CPU.GPR[op.ra] = addr; } @@ -2614,13 +2613,13 @@ void ppu_interpreter::STVLX(PPUThread& CPU, ppu_opcode_t op) const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; const u32 eb = addr & 0xf; - for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i), CPU.VPR[op.vs]._u8[15 - i]); + for (u32 i = 0; i < 16u - eb; ++i) vm::write8(VM_CAST(addr + i), CPU.VPR[op.vs]._u8[15 - i]); } void ppu_interpreter::STDBRX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::get_ref(vm::cast(addr)) = CPU.GPR[op.rs]; + vm::get_ref(VM_CAST(addr)) = CPU.GPR[op.rs]; } void ppu_interpreter::STSWX(PPUThread& CPU, ppu_opcode_t op) @@ -2629,7 +2628,7 @@ void ppu_interpreter::STSWX(PPUThread& CPU, ppu_opcode_t op) u32 count = CPU.XER.XER & 0x7F; for (; count >= 4; count -= 4, addr += 4, op.rs = (op.rs + 1) & 31) { - vm::write32(vm::cast(addr), (u32)CPU.GPR[op.rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[op.rs]); } if (count) { @@ -2637,7 +2636,7 @@ void ppu_interpreter::STSWX(PPUThread& CPU, ppu_opcode_t op) for (u32 byte = 0; byte < count; byte++) { u32 byte_value = (u8)(value >> ((3 ^ byte) * 8)); - vm::write8(vm::cast(addr + byte), byte_value); + vm::write8(VM_CAST(addr + byte), byte_value); } } } @@ -2645,13 +2644,13 @@ void ppu_interpreter::STSWX(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STWBRX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::get_ref(vm::cast(addr)) = (u32)CPU.GPR[op.rs]; + vm::get_ref(VM_CAST(addr)) = (u32)CPU.GPR[op.rs]; } void ppu_interpreter::STFSX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::get_ref>(vm::cast(addr)) = static_cast(CPU.FPR[op.frs]); + vm::get_ref>(VM_CAST(addr)) = static_cast(CPU.FPR[op.frs]); } void ppu_interpreter::STVRX(PPUThread& CPU, ppu_opcode_t op) @@ -2659,13 +2658,13 @@ void ppu_interpreter::STVRX(PPUThread& CPU, ppu_opcode_t op) const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; const u8 eb = addr & 0xf; - for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16), CPU.VPR[op.vs]._u8[15 - i]); + for (u32 i = 16 - eb; i < 16; ++i) vm::write8(VM_CAST(addr + i - 16), CPU.VPR[op.vs]._u8[15 - i]); } void ppu_interpreter::STFSUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - vm::get_ref>(vm::cast(addr)) = static_cast(CPU.FPR[op.frs]); + vm::get_ref>(VM_CAST(addr)) = static_cast(CPU.FPR[op.frs]); CPU.GPR[op.ra] = addr; } @@ -2679,7 +2678,7 @@ void ppu_interpreter::STSWI(PPUThread& CPU, ppu_opcode_t op) { if (N > 3) { - vm::write32(vm::cast(addr), (u32)CPU.GPR[reg]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[reg]); addr += 4; N -= 4; } @@ -2689,7 +2688,7 @@ void ppu_interpreter::STSWI(PPUThread& CPU, ppu_opcode_t op) while (N > 0) { N = N - 1; - vm::write8(vm::cast(addr), (0xFF000000 & buf) >> 24); + vm::write8(VM_CAST(addr), (0xFF000000 & buf) >> 24); buf <<= 8; addr++; } @@ -2701,13 +2700,13 @@ void ppu_interpreter::STSWI(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STFDX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[op.frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[op.frs]; } void ppu_interpreter::STFDUX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + CPU.GPR[op.rb]; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[op.frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[op.frs]; CPU.GPR[op.ra] = addr; } @@ -2717,13 +2716,13 @@ void ppu_interpreter::LVLXL(PPUThread& CPU, ppu_opcode_t op) const u32 eb = addr & 0xf; CPU.VPR[op.vd].clear(); - for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i)); + for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i)); } void ppu_interpreter::LHBRX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - CPU.GPR[op.rd] = vm::get_ref(vm::cast(addr)); + CPU.GPR[op.rd] = vm::get_ref(VM_CAST(addr)); } void ppu_interpreter::SRAW(PPUThread& CPU, ppu_opcode_t op) @@ -2768,7 +2767,7 @@ void ppu_interpreter::LVRXL(PPUThread& CPU, ppu_opcode_t op) const u8 eb = addr & 0xf; CPU.VPR[op.vd].clear(); - for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16)); + for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[op.vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i - 16)); } void ppu_interpreter::DSS(PPUThread& CPU, ppu_opcode_t op) @@ -2804,13 +2803,13 @@ void ppu_interpreter::STVLXL(PPUThread& CPU, ppu_opcode_t op) const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; const u32 eb = addr & 0xf; - for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i), CPU.VPR[op.vs]._u8[15 - i]); + for (u32 i = 0; i < 16u - eb; ++i) vm::write8(VM_CAST(addr + i), CPU.VPR[op.vs]._u8[15 - i]); } void ppu_interpreter::STHBRX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::get_ref(vm::cast(addr)) = (u16)CPU.GPR[op.rs]; + vm::get_ref(VM_CAST(addr)) = (u16)CPU.GPR[op.rs]; } void ppu_interpreter::EXTSH(PPUThread& CPU, ppu_opcode_t op) @@ -2824,7 +2823,7 @@ void ppu_interpreter::STVRXL(PPUThread& CPU, ppu_opcode_t op) const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; const u8 eb = addr & 0xf; - for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16), CPU.VPR[op.vs]._u8[15 - i]); + for (u32 i = 16 - eb; i < 16; ++i) vm::write8(VM_CAST(addr + i - 16), CPU.VPR[op.vs]._u8[15 - i]); } void ppu_interpreter::EXTSB(PPUThread& CPU, ppu_opcode_t op) @@ -2836,7 +2835,7 @@ void ppu_interpreter::EXTSB(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STFIWX(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - vm::write32(vm::cast(addr), (u32&)CPU.FPR[op.frs]); + vm::write32(VM_CAST(addr), (u32&)CPU.FPR[op.frs]); } void ppu_interpreter::EXTSW(PPUThread& CPU, ppu_opcode_t op) @@ -2853,97 +2852,97 @@ void ppu_interpreter::DCBZ(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb]; - memset(vm::get_ptr(vm::cast(addr) & ~127), 0, 128); + memset(vm::get_ptr(VM_CAST(addr) & ~127), 0, 128); } void ppu_interpreter::LWZ(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - CPU.GPR[op.rd] = vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read32(VM_CAST(addr)); } void ppu_interpreter::LWZU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - CPU.GPR[op.rd] = vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read32(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } void ppu_interpreter::LBZ(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - CPU.GPR[op.rd] = vm::read8(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read8(VM_CAST(addr)); } void ppu_interpreter::LBZU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - CPU.GPR[op.rd] = vm::read8(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read8(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STW(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - vm::write32(vm::cast(addr), (u32)CPU.GPR[op.rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[op.rs]); } void ppu_interpreter::STWU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - vm::write32(vm::cast(addr), (u32)CPU.GPR[op.rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STB(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - vm::write8(vm::cast(addr), (u8)CPU.GPR[op.rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[op.rs]); } void ppu_interpreter::STBU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - vm::write8(vm::cast(addr), (u8)CPU.GPR[op.rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } void ppu_interpreter::LHZ(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - CPU.GPR[op.rd] = vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read16(VM_CAST(addr)); } void ppu_interpreter::LHZU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - CPU.GPR[op.rd] = vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read16(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } void ppu_interpreter::LHA(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - CPU.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s16)vm::read16(VM_CAST(addr)); } void ppu_interpreter::LHAU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - CPU.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s16)vm::read16(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STH(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - vm::write16(vm::cast(addr), (u16)CPU.GPR[op.rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[op.rs]); } void ppu_interpreter::STHU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - vm::write16(vm::cast(addr), (u16)CPU.GPR[op.rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } @@ -2952,7 +2951,7 @@ void ppu_interpreter::LMW(PPUThread& CPU, ppu_opcode_t op) u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; for (u32 i = op.rd; i<32; ++i, addr += 4) { - CPU.GPR[i] = vm::read32(vm::cast(addr)); + CPU.GPR[i] = vm::read32(VM_CAST(addr)); } } @@ -2961,79 +2960,79 @@ void ppu_interpreter::STMW(PPUThread& CPU, ppu_opcode_t op) u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; for (u32 i = op.rs; i<32; ++i, addr += 4) { - vm::write32(vm::cast(addr), (u32)CPU.GPR[i]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[i]); } } void ppu_interpreter::LFS(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); } void ppu_interpreter::LFSU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); CPU.GPR[op.ra] = addr; } void ppu_interpreter::LFD(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); } void ppu_interpreter::LFDU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - CPU.FPR[op.frd]._double = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[op.frd]._double = vm::get_ref>(VM_CAST(addr)).value(); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STFS(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - vm::get_ref>(vm::cast(addr)) = static_cast(CPU.FPR[op.frs]); + vm::get_ref>(VM_CAST(addr)) = static_cast(CPU.FPR[op.frs]); } void ppu_interpreter::STFSU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - vm::get_ref>(vm::cast(addr)) = static_cast(CPU.FPR[op.frs]); + vm::get_ref>(VM_CAST(addr)) = static_cast(CPU.FPR[op.frs]); CPU.GPR[op.ra] = addr; } void ppu_interpreter::STFD(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = op.ra ? CPU.GPR[op.ra] + op.simm16 : op.simm16; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[op.frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[op.frs]; } void ppu_interpreter::STFDU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + op.simm16; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[op.frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[op.frs]; CPU.GPR[op.ra] = addr; } void ppu_interpreter::LD(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? CPU.GPR[op.ra] : 0); - CPU.GPR[op.rd] = vm::read64(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read64(VM_CAST(addr)); } void ppu_interpreter::LDU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + (op.simm16 & ~3); - CPU.GPR[op.rd] = vm::read64(vm::cast(addr)); + CPU.GPR[op.rd] = vm::read64(VM_CAST(addr)); CPU.GPR[op.ra] = addr; } void ppu_interpreter::LWA(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? CPU.GPR[op.ra] : 0); - CPU.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr)); + CPU.GPR[op.rd] = (s64)(s32)vm::read32(VM_CAST(addr)); } void ppu_interpreter::FDIVS(PPUThread& CPU, ppu_opcode_t op) @@ -3099,13 +3098,13 @@ void ppu_interpreter::FNMADDS(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::STD(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? CPU.GPR[op.ra] : 0); - vm::write64(vm::cast(addr), CPU.GPR[op.rs]); + vm::write64(VM_CAST(addr), CPU.GPR[op.rs]); } void ppu_interpreter::STDU(PPUThread& CPU, ppu_opcode_t op) { const u64 addr = CPU.GPR[op.ra] + (op.simm16 & ~3); - vm::write64(vm::cast(addr), CPU.GPR[op.rs]); + vm::write64(VM_CAST(addr), CPU.GPR[op.rs]); CPU.GPR[op.ra] = addr; } @@ -3324,5 +3323,5 @@ void ppu_interpreter::FCFID(PPUThread& CPU, ppu_opcode_t op) void ppu_interpreter::UNK(PPUThread& CPU, ppu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION(""); } diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 90f8acd973..ecfed898ff 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -5,7 +5,6 @@ #include "rpcs3/Ini.h" #include "Emu/SysCalls/Modules.h" #include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include #ifdef _MSC_VER @@ -18,6 +17,7 @@ #include extern u64 rotate_mask[64][64]; // defined in PPUThread.cpp, static didn't work correctly in GCC 4.9 for some reason +extern u64 get_timebased_time(); inline void InitRotateMask() { @@ -109,7 +109,7 @@ private: void NULL_OP() { - throw "Null operation"; + throw EXCEPTION("Null operation"); } void NOP() @@ -160,8 +160,8 @@ private: case 0x100: return CPU.VRSAVE; case 0x103: return CPU.SPRG[3]; - case 0x10C: CPU.TB = get_time(); return CPU.TB; - case 0x10D: CPU.TB = get_time(); return CPU.TB >> 32; + case 0x10C: CPU.TB = get_timebased_time(); return CPU.TB; + case 0x10D: CPU.TB = get_timebased_time(); return CPU.TB >> 32; case 0x110: case 0x111: @@ -173,7 +173,7 @@ private: case 0x117: return CPU.SPRG[n - 0x110]; } - throw fmt::Format("ReadSPR(0x%x) error: unknown SPR (0x%x)", spr, n); + throw EXCEPTION("Unknown SPR (spr=0x%x, n=0x%x)", spr, n); } void WriteSPR(u32 spr, u64 value) @@ -186,10 +186,10 @@ private: case 0x008: CPU.LR = value; return; case 0x009: CPU.CTR = value; return; case 0x100: CPU.VRSAVE = (u32)value; return; - case 0x103: throw fmt::Format("WriteSPR(0x103, 0x%llx): Write to read-only SPR", value); + case 0x103: throw EXCEPTION("WriteSPR(0x103, 0x%llx): Write to read-only SPR", value); - case 0x10C: throw fmt::Format("WriteSPR(0x10C, 0x%llx): Write to time-based SPR", value); - case 0x10D: throw fmt::Format("WriteSPR(0x10D, 0x%llx): Write to time-based SPR", value); + case 0x10C: throw EXCEPTION("WriteSPR(0x10C, 0x%llx): Write to time-based SPR", value); + case 0x10D: throw EXCEPTION("WriteSPR(0x10D, 0x%llx): Write to time-based SPR", value); case 0x110: case 0x111: @@ -201,7 +201,7 @@ private: case 0x117: CPU.SPRG[n - 0x110] = value; return; } - throw fmt::Format("WriteSPR(0x%x, 0x%llx) error: unknown SPR (0x%x)", spr, value, n); + throw EXCEPTION("Unknown SPR (spr=0x%x, n=0x%x, value=0x%llx)", spr, n, value); } void TDI(u32 to, u32 ra, s32 simm16) @@ -214,7 +214,7 @@ private: ((u64)a < (u64)simm16 && (to & 0x2)) || ((u64)a > (u64)simm16 && (to & 0x1)) ) { - throw fmt::Format("Trap! (tdi 0x%x, r%d, 0x%x)", to, ra, simm16); + throw EXCEPTION("Trap! (tdi 0x%x, r%d, 0x%x)", to, ra, simm16); } } @@ -228,7 +228,7 @@ private: ((u32)a < (u32)simm16 && (to & 0x2)) || ((u32)a > (u32)simm16 && (to & 0x1)) ) { - throw fmt::Format("Trap! (twi 0x%x, r%d, 0x%x)", to, ra, simm16); + throw EXCEPTION("Trap! (twi 0x%x, r%d, 0x%x)", to, ra, simm16); } } @@ -466,7 +466,7 @@ private: CPU.VPR[vd]._f[w] = ((float)CPU.VPR[vb]._u32[w]) / scale; } } - void VCMPBFP(u32 vd, u32 va, u32 vb, bool rc) + void VCMPBFP(u32 vd, u32 va, u32 vb, u32 rc) { bool allInBounds = true; @@ -495,7 +495,7 @@ private: } void VCMPBFP(u32 vd, u32 va, u32 vb) {VCMPBFP(vd, va, vb, false);} void VCMPBFP_(u32 vd, u32 va, u32 vb) {VCMPBFP(vd, va, vb, true);} - void VCMPEQFP(u32 vd, u32 va, u32 vb, bool rc) + void VCMPEQFP(u32 vd, u32 va, u32 vb, u32 rc) { int all_equal = 0x8; int none_equal = 0x2; @@ -518,7 +518,7 @@ private: } void VCMPEQFP(u32 vd, u32 va, u32 vb) {VCMPEQFP(vd, va, vb, false);} void VCMPEQFP_(u32 vd, u32 va, u32 vb) {VCMPEQFP(vd, va, vb, true);} - void VCMPEQUB(u32 vd, u32 va, u32 vb, bool rc) + void VCMPEQUB(u32 vd, u32 va, u32 vb, u32 rc) { int all_equal = 0x8; int none_equal = 0x2; @@ -541,7 +541,7 @@ private: } void VCMPEQUB(u32 vd, u32 va, u32 vb) {VCMPEQUB(vd, va, vb, false);} void VCMPEQUB_(u32 vd, u32 va, u32 vb) {VCMPEQUB(vd, va, vb, true);} - void VCMPEQUH(u32 vd, u32 va, u32 vb, bool rc) //nf + void VCMPEQUH(u32 vd, u32 va, u32 vb, u32 rc) //nf { int all_equal = 0x8; int none_equal = 0x2; @@ -564,7 +564,7 @@ private: } void VCMPEQUH(u32 vd, u32 va, u32 vb) {VCMPEQUH(vd, va, vb, false);} void VCMPEQUH_(u32 vd, u32 va, u32 vb) {VCMPEQUH(vd, va, vb, true);} - void VCMPEQUW(u32 vd, u32 va, u32 vb, bool rc) + void VCMPEQUW(u32 vd, u32 va, u32 vb, u32 rc) { int all_equal = 0x8; int none_equal = 0x2; @@ -587,7 +587,7 @@ private: } void VCMPEQUW(u32 vd, u32 va, u32 vb) {VCMPEQUW(vd, va, vb, false);} void VCMPEQUW_(u32 vd, u32 va, u32 vb) {VCMPEQUW(vd, va, vb, true);} - void VCMPGEFP(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGEFP(u32 vd, u32 va, u32 vb, u32 rc) { int all_ge = 0x8; int none_ge = 0x2; @@ -610,7 +610,7 @@ private: } void VCMPGEFP(u32 vd, u32 va, u32 vb) {VCMPGEFP(vd, va, vb, false);} void VCMPGEFP_(u32 vd, u32 va, u32 vb) {VCMPGEFP(vd, va, vb, true);} - void VCMPGTFP(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGTFP(u32 vd, u32 va, u32 vb, u32 rc) { int all_ge = 0x8; int none_ge = 0x2; @@ -633,7 +633,7 @@ private: } void VCMPGTFP(u32 vd, u32 va, u32 vb) {VCMPGTFP(vd, va, vb, false);} void VCMPGTFP_(u32 vd, u32 va, u32 vb) {VCMPGTFP(vd, va, vb, true);} - void VCMPGTSB(u32 vd, u32 va, u32 vb, bool rc) //nf + void VCMPGTSB(u32 vd, u32 va, u32 vb, u32 rc) //nf { int all_gt = 0x8; int none_gt = 0x2; @@ -656,7 +656,7 @@ private: } void VCMPGTSB(u32 vd, u32 va, u32 vb) {VCMPGTSB(vd, va, vb, false);} void VCMPGTSB_(u32 vd, u32 va, u32 vb) {VCMPGTSB(vd, va, vb, true);} - void VCMPGTSH(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGTSH(u32 vd, u32 va, u32 vb, u32 rc) { int all_gt = 0x8; int none_gt = 0x2; @@ -679,7 +679,7 @@ private: } void VCMPGTSH(u32 vd, u32 va, u32 vb) {VCMPGTSH(vd, va, vb, false);} void VCMPGTSH_(u32 vd, u32 va, u32 vb) {VCMPGTSH(vd, va, vb, true);} - void VCMPGTSW(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGTSW(u32 vd, u32 va, u32 vb, u32 rc) { int all_gt = 0x8; int none_gt = 0x2; @@ -702,7 +702,7 @@ private: } void VCMPGTSW(u32 vd, u32 va, u32 vb) {VCMPGTSW(vd, va, vb, false);} void VCMPGTSW_(u32 vd, u32 va, u32 vb) {VCMPGTSW(vd, va, vb, true);} - void VCMPGTUB(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGTUB(u32 vd, u32 va, u32 vb, u32 rc) { int all_gt = 0x8; int none_gt = 0x2; @@ -725,7 +725,7 @@ private: } void VCMPGTUB(u32 vd, u32 va, u32 vb) {VCMPGTUB(vd, va, vb, false);} void VCMPGTUB_(u32 vd, u32 va, u32 vb) {VCMPGTUB(vd, va, vb, true);} - void VCMPGTUH(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGTUH(u32 vd, u32 va, u32 vb, u32 rc) { int all_gt = 0x8; int none_gt = 0x2; @@ -748,7 +748,7 @@ private: } void VCMPGTUH(u32 vd, u32 va, u32 vb) {VCMPGTUH(vd, va, vb, false);} void VCMPGTUH_(u32 vd, u32 va, u32 vb) {VCMPGTUH(vd, va, vb, true);} - void VCMPGTUW(u32 vd, u32 va, u32 vb, bool rc) + void VCMPGTUW(u32 vd, u32 va, u32 vb, u32 rc) { int all_gt = 0x8; int none_gt = 0x2; @@ -2226,7 +2226,7 @@ private: if (CheckCondition(bo, bi)) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(branchTarget((aa ? 0 : CPU.PC), bd), lk); + CPU.PC = branchTarget((aa ? 0 : CPU.PC), bd) - 4; if(lk) CPU.LR = nextLR; } } @@ -2239,15 +2239,15 @@ private: switch (lev) { case 0x0: SysCalls::DoSyscall(CPU, CPU.GPR[11]); break; - case 0x1: throw "SC(): HyperCall LV1"; + case 0x1: throw EXCEPTION("HyperCall LV1"); case 0x3: CPU.FastStop(); break; - default: throw fmt::Format("SC(): unknown level (0x%x)", lev); + default: throw EXCEPTION("Unknown level (0x%x)", lev); } } void B(s32 ll, u32 aa, u32 lk) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(branchTarget(aa ? 0 : CPU.PC, ll), lk); + CPU.PC = branchTarget(aa ? 0 : CPU.PC, ll) - 4; if(lk) CPU.LR = nextLR; } void MCRF(u32 crfd, u32 crfs) @@ -2259,7 +2259,7 @@ private: if (CheckCondition(bo, bi)) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(branchTarget(0, (u32)CPU.LR), true); + CPU.PC = branchTarget(0, (u32)CPU.LR) - 4; if(lk) CPU.LR = nextLR; } } @@ -2312,22 +2312,22 @@ private: if(bo & 0x10 || CPU.IsCR(bi) == ((bo & 0x8) != 0)) { const u32 nextLR = CPU.PC + 4; - CPU.SetBranch(branchTarget(0, (u32)CPU.CTR), true); + CPU.PC = branchTarget(0, (u32)CPU.CTR) - 4; if(lk) CPU.LR = nextLR; } } - void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) + void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { const u64 mask = rotate_mask[32 + mb][32 + me]; CPU.GPR[ra] = (CPU.GPR[ra] & ~mask) | (rotl32(CPU.GPR[rs], sh) & mask); if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) + void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { CPU.GPR[ra] = rotl32(CPU.GPR[rs], sh) & rotate_mask[32 + mb][32 + me]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, bool rc) + void RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, u32 rc) { CPU.GPR[ra] = rotl32(CPU.GPR[rs], CPU.GPR[rb] & 0x1f) & rotate_mask[32 + mb][32 + me]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -2358,28 +2358,28 @@ private: CPU.GPR[ra] = CPU.GPR[rs] & ((u64)uimm16 << 16); CPU.UpdateCR0(CPU.GPR[ra]); } - void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) + void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { CPU.GPR[ra] = rotl64(CPU.GPR[rs], sh) & rotate_mask[mb][63]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) + void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, u32 rc) { CPU.GPR[ra] = rotl64(CPU.GPR[rs], sh) & rotate_mask[0][me]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) + void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { CPU.GPR[ra] = rotl64(CPU.GPR[rs], sh) & rotate_mask[mb][63-sh]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) + void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { const u64 mask = rotate_mask[mb][63-sh]; CPU.GPR[ra] = (CPU.GPR[ra] & ~mask) | (rotl64(CPU.GPR[rs], sh) & mask); if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) + void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, u32 is_r, u32 rc) { if (is_r) // rldcr { @@ -2405,7 +2405,7 @@ private: ((u32)a < (u32)b && (to & 0x2)) || ((u32)a > (u32)b && (to & 0x1)) ) { - throw fmt::Format("Trap! (tw 0x%x, r%d, r%d)", to, ra, rb); + throw EXCEPTION("Trap! (tw 0x%x, r%d, r%d)", to, ra, rb); } } void LVSL(u32 vd, u32 ra, u32 rb) @@ -2438,10 +2438,10 @@ private: void LVEBX(u32 vd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.VPR[vd]._u8[15 - (addr & 0xf)] = vm::read8(vm::cast(addr)); + CPU.VPR[vd]._u8[15 - (addr & 0xf)] = vm::read8(VM_CAST(addr)); // check LVEWX comments } - void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2450,12 +2450,12 @@ private: if(oe) CPU.SetOV((~RA>>63 == RB>>63) && (~RA>>63 != CPU.GPR[rd]>>63)); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void MULHDU(u32 rd, u32 ra, u32 rb, bool rc) + void MULHDU(u32 rd, u32 ra, u32 rb, u32 rc) { CPU.GPR[rd] = __umulh(CPU.GPR[ra], CPU.GPR[rb]); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2464,7 +2464,7 @@ private: if(oe) CPU.SetOV((RA>>63 == RB>>63) && (RA>>63 != CPU.GPR[rd]>>63)); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void MULHWU(u32 rd, u32 ra, u32 rb, bool rc) + void MULHWU(u32 rd, u32 ra, u32 rb, u32 rc) { u32 a = (u32)CPU.GPR[ra]; u32 b = (u32)CPU.GPR[rb]; @@ -2480,21 +2480,21 @@ private: const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; be_t value; - vm::reservation_acquire(&value, vm::cast(addr), sizeof(value)); + vm::reservation_acquire(&value, VM_CAST(addr), sizeof(value)); CPU.GPR[rd] = value; } void LDX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read64(vm::cast(addr)); + CPU.GPR[rd] = vm::read64(VM_CAST(addr)); } void LWZX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read32(vm::cast(addr)); + CPU.GPR[rd] = vm::read32(VM_CAST(addr)); } - void SLW(u32 ra, u32 rs, u32 rb, bool rc) + void SLW(u32 ra, u32 rs, u32 rb, u32 rc) { u32 n = CPU.GPR[rb] & 0x1f; u32 r = (u32)rotl32((u32)CPU.GPR[rs], n); @@ -2504,7 +2504,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void CNTLZW(u32 ra, u32 rs, bool rc) + void CNTLZW(u32 ra, u32 rs, u32 rc) { u32 i; for(i=0; i < 32; i++) @@ -2515,7 +2515,7 @@ private: CPU.GPR[ra] = i; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void SLD(u32 ra, u32 rs, u32 rb, bool rc) + void SLD(u32 ra, u32 rs, u32 rb, u32 rc) { u32 n = CPU.GPR[rb] & 0x3f; u64 r = rotl64(CPU.GPR[rs], n); @@ -2525,7 +2525,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void AND(u32 ra, u32 rs, u32 rb, bool rc) + void AND(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = CPU.GPR[rs] & CPU.GPR[rb]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -2564,10 +2564,10 @@ private: void LVEHX(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~1ULL; - CPU.VPR[vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(vm::cast(addr)); + CPU.VPR[vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(VM_CAST(addr)); // check LVEWX comments } - void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2578,7 +2578,7 @@ private: void LDUX(u32 rd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - CPU.GPR[rd] = vm::read64(vm::cast(addr)); + CPU.GPR[rd] = vm::read64(VM_CAST(addr)); CPU.GPR[ra] = addr; } void DCBST(u32 ra, u32 rb) @@ -2587,10 +2587,10 @@ private: void LWZUX(u32 rd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - CPU.GPR[rd] = vm::read32(vm::cast(addr)); + CPU.GPR[rd] = vm::read32(VM_CAST(addr)); CPU.GPR[ra] = addr; } - void CNTLZD(u32 ra, u32 rs, bool rc) + void CNTLZD(u32 ra, u32 rs, u32 rc) { u32 i; for(i=0; i < 64; i++) @@ -2601,29 +2601,29 @@ private: CPU.GPR[ra] = i; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void ANDC(u32 ra, u32 rs, u32 rb, bool rc) + void ANDC(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = CPU.GPR[rs] & ~CPU.GPR[rb]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void TD(u32 to, u32 ra, u32 rb) { - throw "TD()"; + throw EXCEPTION(""); } void LVEWX(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~3ULL; - CPU.VPR[vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(vm::cast(addr)); + CPU.VPR[vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(VM_CAST(addr)); // It's not very good idea to implement it using read128(), // because it can theoretically read RawSPU 32-bit MMIO register (read128() will fail) //CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL); } - void MULHD(u32 rd, u32 ra, u32 rb, bool rc) + void MULHD(u32 rd, u32 ra, u32 rb, u32 rc) { CPU.GPR[rd] = __mulh(CPU.GPR[ra], CPU.GPR[rb]); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void MULHW(u32 rd, u32 ra, u32 rb, bool rc) + void MULHW(u32 rd, u32 ra, u32 rb, u32 rc) { s32 a = (s32)CPU.GPR[ra]; s32 b = (s32)CPU.GPR[rb]; @@ -2635,7 +2635,7 @@ private: const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; be_t value; - vm::reservation_acquire(&value, vm::cast(addr), sizeof(value)); + vm::reservation_acquire(&value, VM_CAST(addr), sizeof(value)); CPU.GPR[rd] = value; } @@ -2645,14 +2645,14 @@ private: void LBZX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read8(vm::cast(addr)); + CPU.GPR[rd] = vm::read8(VM_CAST(addr)); } void LVX(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - CPU.VPR[vd] = vm::read128(vm::cast(addr)); + CPU.VPR[vd] = vm::read128(VM_CAST(addr)); } - void NEG(u32 rd, u32 ra, u32 oe, bool rc) + void NEG(u32 rd, u32 ra, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; CPU.GPR[rd] = 0 - RA; @@ -2661,13 +2661,11 @@ private: } void LBZUX(u32 rd, u32 ra, u32 rb) { - //if(ra == 0 || ra == rd) throw "Bad instruction [LBZUX]"; - const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - CPU.GPR[rd] = vm::read8(vm::cast(addr)); + CPU.GPR[rd] = vm::read8(VM_CAST(addr)); CPU.GPR[ra] = addr; } - void NOR(u32 ra, u32 rs, u32 rb, bool rc) + void NOR(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = ~(CPU.GPR[rs] | CPU.GPR[rb]); if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -2676,9 +2674,9 @@ private: { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u8 eb = addr & 0xf; - vm::write8(vm::cast(addr), CPU.VPR[vs]._u8[15 - eb]); + vm::write8(VM_CAST(addr), CPU.VPR[vs]._u8[15 - eb]); } - void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2687,7 +2685,7 @@ private: if(oe) CPU.SetOV((~RA>>63 == RB>>63) && (~RA>>63 != CPU.GPR[rd]>>63)); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2748,45 +2746,45 @@ private: void STDX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write64(vm::cast(addr), CPU.GPR[rs]); + vm::write64(VM_CAST(addr), CPU.GPR[rs]); } void STWCX_(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - const be_t value = be_t::make((u32)CPU.GPR[rs]); - CPU.SetCR_EQ(0, vm::reservation_update(vm::cast(addr), &value, sizeof(value))); + const be_t value = (u32)CPU.GPR[rs]; + CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, sizeof(value))); } void STWX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write32(vm::cast(addr), (u32)CPU.GPR[rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); } void STVEHX(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~1ULL; const u8 eb = (addr & 0xf) >> 1; - vm::write16(vm::cast(addr), CPU.VPR[vs]._u16[7 - eb]); + vm::write16(VM_CAST(addr), CPU.VPR[vs]._u16[7 - eb]); } void STDUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write64(vm::cast(addr), CPU.GPR[rs]); + vm::write64(VM_CAST(addr), CPU.GPR[rs]); CPU.GPR[ra] = addr; } void STWUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write32(vm::cast(addr), (u32)CPU.GPR[rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void STVEWX(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~3ULL; const u8 eb = (addr & 0xf) >> 2; - vm::write32(vm::cast(addr), CPU.VPR[vs]._u32[3 - eb]); + vm::write32(VM_CAST(addr), CPU.VPR[vs]._u32[3 - eb]); } - void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) + void SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; CPU.GPR[rd] = ~RA + CPU.XER.CA; @@ -2794,7 +2792,7 @@ private: if(oe) CPU.SetOV((~RA>>63 == 0) && (~RA>>63 != CPU.GPR[rd]>>63)); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) + void ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; CPU.GPR[rd] = RA + CPU.XER.CA; @@ -2806,20 +2804,20 @@ private: { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - const be_t value = be_t::make(CPU.GPR[rs]); - CPU.SetCR_EQ(0, vm::reservation_update(vm::cast(addr), &value, sizeof(value))); + const be_t value = CPU.GPR[rs]; + CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, sizeof(value))); } void STBX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write8(vm::cast(addr), (u8)CPU.GPR[rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[rs]); } void STVX(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - vm::write128(vm::cast(addr), CPU.VPR[vs]); + vm::write128(VM_CAST(addr), CPU.VPR[vs]); } - void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const s64 RA = CPU.GPR[ra]; const s64 RB = CPU.GPR[rb]; @@ -2831,7 +2829,7 @@ private: } if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) + void SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; CPU.GPR[rd] = ~RA + CPU.XER.CA + ~0ULL; @@ -2839,7 +2837,7 @@ private: if(oe) CPU.SetOV((~RA>>63 == 1) && (~RA>>63 != CPU.GPR[rd]>>63)); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void ADDME(u32 rd, u32 ra, u32 oe, bool rc) + void ADDME(u32 rd, u32 ra, u32 oe, u32 rc) { const s64 RA = CPU.GPR[ra]; CPU.GPR[rd] = RA + CPU.XER.CA - 1; @@ -2848,7 +2846,7 @@ private: if(oe) CPU.SetOV((u64(RA)>>63 == 1) && (u64(RA)>>63 != CPU.GPR[rd]>>63)); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { CPU.GPR[rd] = (s64)((s64)(s32)CPU.GPR[ra] * (s64)(s32)CPU.GPR[rb]); if(oe) CPU.SetOV(s64(CPU.GPR[rd]) < s64(-1)<<31 || s64(CPU.GPR[rd]) >= s64(1)<<31); @@ -2860,10 +2858,10 @@ private: void STBUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write8(vm::cast(addr), (u8)CPU.GPR[rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[rs]); CPU.GPR[ra] = addr; } - void ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void ADD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2877,24 +2875,24 @@ private: void LHZX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read16(vm::cast(addr)); + CPU.GPR[rd] = vm::read16(VM_CAST(addr)); } - void EQV(u32 ra, u32 rs, u32 rb, bool rc) + void EQV(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = ~(CPU.GPR[rs] ^ CPU.GPR[rb]); if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void ECIWX(u32 rd, u32 ra, u32 rb) { - throw __FUNCTION__; + throw EXCEPTION("Privileged instruction"); } void LHZUX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::read16(vm::cast(addr)); + CPU.GPR[rd] = vm::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } - void XOR(u32 ra, u32 rs, u32 rb, bool rc) + void XOR(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = CPU.GPR[rs] ^ CPU.GPR[rb]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -2906,7 +2904,7 @@ private: void LWAX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s32)vm::read32(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s32)vm::read32(VM_CAST(addr)); } void DST(u32 ra, u32 rb, u32 strm, u32 t) { @@ -2914,29 +2912,29 @@ private: void LHAX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); } void LVXL(u32 vd, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - CPU.VPR[vd] = vm::read128(vm::cast(addr)); + CPU.VPR[vd] = vm::read128(VM_CAST(addr)); } void MFTB(u32 rd, u32 spr) { const u32 n = (spr >> 5) | ((spr & 0x1f) << 5); - CPU.TB = get_time(); + CPU.TB = get_timebased_time(); switch(n) { case 0x10C: CPU.GPR[rd] = CPU.TB; break; case 0x10D: CPU.GPR[rd] = CPU.TB >> 32; break; - default: throw fmt::Format("mftb r%d, %d", rd, spr); + default: throw EXCEPTION("mftb r%d, %d", rd, spr); } } void LWAUX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s32)vm::read32(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s32)vm::read32(VM_CAST(addr)); CPU.GPR[ra] = addr; } void DSTST(u32 ra, u32 rb, u32 strm, u32 t) @@ -2945,35 +2943,35 @@ private: void LHAUX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void STHX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write16(vm::cast(addr), (u16)CPU.GPR[rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); } - void ORC(u32 ra, u32 rs, u32 rb, bool rc) + void ORC(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = CPU.GPR[rs] | ~CPU.GPR[rb]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void ECOWX(u32 rs, u32 ra, u32 rb) { - throw __FUNCTION__; + throw EXCEPTION("Privileged instruction"); } void STHUX(u32 rs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::write16(vm::cast(addr), (u16)CPU.GPR[rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); CPU.GPR[ra] = addr; } - void OR(u32 ra, u32 rs, u32 rb, bool rc) + void OR(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = CPU.GPR[rs] | CPU.GPR[rb]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; @@ -2991,7 +2989,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const u32 RA = (u32)CPU.GPR[ra]; const u32 RB = (u32)CPU.GPR[rb]; @@ -3016,7 +3014,7 @@ private: void DCBI(u32 ra, u32 rb) { } - void NAND(u32 ra, u32 rs, u32 rb, bool rc) + void NAND(u32 ra, u32 rs, u32 rb, u32 rc) { CPU.GPR[ra] = ~(CPU.GPR[rs] & CPU.GPR[rb]); @@ -3025,9 +3023,9 @@ private: void STVXL(u32 vs, u32 ra, u32 rb) { const u64 addr = (ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfull; - vm::write128(vm::cast(addr), CPU.VPR[vs]); + vm::write128(VM_CAST(addr), CPU.VPR[vs]); } - void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const s64 RA = CPU.GPR[ra]; const s64 RB = CPU.GPR[rb]; @@ -3045,7 +3043,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } - void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) + void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { const s32 RA = (s32)CPU.GPR[ra]; const s32 RB = (s32)CPU.GPR[rb]; @@ -3069,12 +3067,12 @@ private: const u32 eb = addr & 0xf; CPU.VPR[vd].clear(); - for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(vm::cast(addr + i)); + for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i)); } void LDBRX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::get_ref(vm::cast(addr)); + CPU.GPR[rd] = vm::get_ref(VM_CAST(addr)); } void LSWX(u32 rd, u32 ra, u32 rb) { @@ -3082,14 +3080,14 @@ private: u32 count = CPU.XER.XER & 0x7F; for (; count >= 4; count -= 4, addr += 4, rd = (rd+1) & 31) { - CPU.GPR[rd] = vm::get_ref>(vm::cast(addr)); + CPU.GPR[rd] = vm::get_ref>(VM_CAST(addr)); } if (count) { u32 value = 0; for (u32 byte = 0; byte < count; byte++) { - u32 byte_value = vm::get_ref(vm::cast(addr+byte)); + u32 byte_value = vm::get_ref(VM_CAST(addr+byte)); value |= byte_value << ((3^byte)*8); } CPU.GPR[rd] = value; @@ -3098,12 +3096,12 @@ private: void LWBRX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::get_ref(vm::cast(addr)); + CPU.GPR[rd] = vm::get_ref(VM_CAST(addr)); } void LFSX(u32 frd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - float val = vm::get_ref>(vm::cast(addr)).value(); + float val = vm::get_ref>(VM_CAST(addr)).value(); if (!FPRdouble::IsNaN(val)) { CPU.FPR[frd] = val; @@ -3114,7 +3112,7 @@ private: (u64&)CPU.FPR[frd] = (bits & 0x80000000) << 32 | 7ULL << 60 | (bits & 0x7fffffff) << 29; } } - void SRW(u32 ra, u32 rs, u32 rb, bool rc) + void SRW(u32 ra, u32 rs, u32 rb, u32 rc) { u32 n = CPU.GPR[rb] & 0x1f; u32 r = (u32)rotl32((u32)CPU.GPR[rs], 64 - n); @@ -3123,7 +3121,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void SRD(u32 ra, u32 rs, u32 rb, bool rc) + void SRD(u32 ra, u32 rs, u32 rb, u32 rc) { u32 n = CPU.GPR[rb] & 0x3f; u64 r = rotl64(CPU.GPR[rs], 64 - n); @@ -3138,7 +3136,7 @@ private: const u8 eb = addr & 0xf; CPU.VPR[vd].clear(); - for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16)); + for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i - 16)); } void LSWI(u32 rd, u32 ra, u32 nb) { @@ -3150,7 +3148,7 @@ private: { if (N > 3) { - CPU.GPR[reg] = vm::read32(vm::cast(addr)); + CPU.GPR[reg] = vm::read32(VM_CAST(addr)); addr += 4; N -= 4; } @@ -3161,7 +3159,7 @@ private: while (N > 0) { N = N - 1; - buf |= vm::read8(vm::cast(addr)) << (i * 8); + buf |= vm::read8(VM_CAST(addr)) << (i * 8); addr++; i--; } @@ -3173,7 +3171,7 @@ private: void LFSUX(u32 frd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - float val = vm::get_ref>(vm::cast(addr)).value(); + float val = vm::get_ref>(VM_CAST(addr)).value(); if (!FPRdouble::IsNaN(val)) { CPU.FPR[frd] = val; @@ -3192,12 +3190,12 @@ private: void LFDX(u32 frd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.FPR[frd] = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[frd] = vm::get_ref>(VM_CAST(addr)).value(); } void LFDUX(u32 frd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - CPU.FPR[frd] = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[frd] = vm::get_ref>(VM_CAST(addr)).value(); CPU.GPR[ra] = addr; } void STVLX(u32 vs, u32 ra, u32 rb) @@ -3205,12 +3203,12 @@ private: const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u32 eb = addr & 0xf; - for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i), CPU.VPR[vs]._u8[15 - i]); + for (u32 i = 0; i < 16u - eb; ++i) vm::write8(VM_CAST(addr + i), CPU.VPR[vs]._u8[15 - i]); } void STDBRX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::get_ref(vm::cast(addr)) = CPU.GPR[rs]; + vm::get_ref(VM_CAST(addr)) = CPU.GPR[rs]; } void STSWX(u32 rs, u32 ra, u32 rb) { @@ -3218,7 +3216,7 @@ private: u32 count = CPU.XER.XER & 0x7F; for (; count >= 4; count -= 4, addr += 4, rs = (rs+1) & 31) { - vm::write32(vm::cast(addr), (u32)CPU.GPR[rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); } if (count) { @@ -3226,14 +3224,14 @@ private: for (u32 byte = 0; byte < count; byte++) { u32 byte_value = (u8)(value >> ((3^byte)*8)); - vm::write8(vm::cast(addr+byte), byte_value); + vm::write8(VM_CAST(addr+byte), byte_value); } } } void STWBRX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::get_ref(vm::cast(addr)) = (u32)CPU.GPR[rs]; + vm::get_ref(VM_CAST(addr)) = (u32)CPU.GPR[rs]; } void STFSX(u32 frs, u32 ra, u32 rb) { @@ -3241,13 +3239,13 @@ private: double val = CPU.FPR[frs]; if (!FPRdouble::IsNaN(val)) { - vm::get_ref>(vm::cast(addr)) = (float)val; + vm::get_ref>(VM_CAST(addr)) = (float)val; } else { u64 bits = (u64&)val; u32 bits32 = (bits>>32 & 0x80000000) | (bits>>29 & 0x7fffffff); - vm::get_ref>(vm::cast(addr)) = bits32; + vm::get_ref>(VM_CAST(addr)) = bits32; } } void STVRX(u32 vs, u32 ra, u32 rb) @@ -3255,7 +3253,7 @@ private: const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u8 eb = addr & 0xf; - for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16), CPU.VPR[vs]._u8[15 - i]); + for (u32 i = 16 - eb; i < 16; ++i) vm::write8(VM_CAST(addr + i - 16), CPU.VPR[vs]._u8[15 - i]); } void STFSUX(u32 frs, u32 ra, u32 rb) { @@ -3263,13 +3261,13 @@ private: double val = CPU.FPR[frs]; if (!FPRdouble::IsNaN(val)) { - vm::get_ref>(vm::cast(addr)) = (float)val; + vm::get_ref>(VM_CAST(addr)) = (float)val; } else { u64 bits = (u64&)val; u32 bits32 = (bits>>32 & 0x80000000) | (bits>>29 & 0x7fffffff); - vm::get_ref>(vm::cast(addr)) = bits32; + vm::get_ref>(VM_CAST(addr)) = bits32; } CPU.GPR[ra] = addr; } @@ -3283,7 +3281,7 @@ private: { if (N > 3) { - vm::write32(vm::cast(addr), (u32)CPU.GPR[reg]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[reg]); addr += 4; N -= 4; } @@ -3293,7 +3291,7 @@ private: while (N > 0) { N = N - 1; - vm::write8(vm::cast(addr), (0xFF000000 & buf) >> 24); + vm::write8(VM_CAST(addr), (0xFF000000 & buf) >> 24); buf <<= 8; addr++; } @@ -3304,12 +3302,12 @@ private: void STFDX(u32 frs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[frs]; } void STFDUX(u32 frs, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[frs]; CPU.GPR[ra] = addr; } void LVLXL(u32 vd, u32 ra, u32 rb) @@ -3318,14 +3316,14 @@ private: const u32 eb = addr & 0xf; CPU.VPR[vd].clear(); - for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(vm::cast(addr + i)); + for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i)); } void LHBRX(u32 rd, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - CPU.GPR[rd] = vm::get_ref(vm::cast(addr)); + CPU.GPR[rd] = vm::get_ref(VM_CAST(addr)); } - void SRAW(u32 ra, u32 rs, u32 rb, bool rc) + void SRAW(u32 ra, u32 rs, u32 rb, u32 rc) { s32 RS = (s32)CPU.GPR[rs]; u8 shift = CPU.GPR[rb] & 63; @@ -3342,7 +3340,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void SRAD(u32 ra, u32 rs, u32 rb, bool rc) + void SRAD(u32 ra, u32 rs, u32 rb, u32 rc) { s64 RS = CPU.GPR[rs]; u8 shift = CPU.GPR[rb] & 127; @@ -3365,12 +3363,12 @@ private: const u8 eb = addr & 0xf; CPU.VPR[vd].clear(); - for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16)); + for (u32 i = 16 - eb; i < 16; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(VM_CAST(addr + i - 16)); } void DSS(u32 strm, u32 a) { } - void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) + void SRAWI(u32 ra, u32 rs, u32 sh, u32 rc) { s32 RS = (u32)CPU.GPR[rs]; CPU.GPR[ra] = RS >> sh; @@ -3378,7 +3376,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) + void SRADI1(u32 ra, u32 rs, u32 sh, u32 rc) { s64 RS = CPU.GPR[rs]; CPU.GPR[ra] = RS >> sh; @@ -3386,7 +3384,7 @@ private: if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } - void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) + void SRADI2(u32 ra, u32 rs, u32 sh, u32 rc) { SRADI1(ra, rs, sh, rc); } @@ -3399,14 +3397,14 @@ private: const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u32 eb = addr & 0xf; - for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i), CPU.VPR[vs]._u8[15 - i]); + for (u32 i = 0; i < 16u - eb; ++i) vm::write8(VM_CAST(addr + i), CPU.VPR[vs]._u8[15 - i]); } void STHBRX(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::get_ref(vm::cast(addr)) = (u16)CPU.GPR[rs]; + vm::get_ref(VM_CAST(addr)) = (u16)CPU.GPR[rs]; } - void EXTSH(u32 ra, u32 rs, bool rc) + void EXTSH(u32 ra, u32 rs, u32 rc) { CPU.GPR[ra] = (s64)(s16)CPU.GPR[rs]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -3416,9 +3414,9 @@ private: const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u8 eb = addr & 0xf; - for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16), CPU.VPR[vs]._u8[15 - i]); + for (u32 i = 16 - eb; i < 16; ++i) vm::write8(VM_CAST(addr + i - 16), CPU.VPR[vs]._u8[15 - i]); } - void EXTSB(u32 ra, u32 rs, bool rc) + void EXTSB(u32 ra, u32 rs, u32 rc) { CPU.GPR[ra] = (s64)(s8)CPU.GPR[rs]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -3426,9 +3424,9 @@ private: void STFIWX(u32 frs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - vm::write32(vm::cast(addr), (u32&)CPU.FPR[frs]); + vm::write32(VM_CAST(addr), (u32&)CPU.FPR[frs]); } - void EXTSW(u32 ra, u32 rs, bool rc) + void EXTSW(u32 ra, u32 rs, u32 rc) { CPU.GPR[ra] = (s64)(s32)CPU.GPR[rs]; if(rc) CPU.UpdateCR0(CPU.GPR[ra]); @@ -3441,83 +3439,83 @@ private: { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - memset(vm::get_ptr(vm::cast(addr) & ~127), 0, 128); + memset(vm::get_ptr(VM_CAST(addr) & ~127), 0, 128); } void LWZ(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = vm::read32(vm::cast(addr)); + CPU.GPR[rd] = vm::read32(VM_CAST(addr)); } void LWZU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = vm::read32(vm::cast(addr)); + CPU.GPR[rd] = vm::read32(VM_CAST(addr)); CPU.GPR[ra] = addr; } void LBZ(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = vm::read8(vm::cast(addr)); + CPU.GPR[rd] = vm::read8(VM_CAST(addr)); } void LBZU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = vm::read8(vm::cast(addr)); + CPU.GPR[rd] = vm::read8(VM_CAST(addr)); CPU.GPR[ra] = addr; } void STW(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write32(vm::cast(addr), (u32)CPU.GPR[rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); } void STWU(u32 rs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - vm::write32(vm::cast(addr), (u32)CPU.GPR[rs]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void STB(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write8(vm::cast(addr), (u8)CPU.GPR[rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[rs]); } void STBU(u32 rs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - vm::write8(vm::cast(addr), (u8)CPU.GPR[rs]); + vm::write8(VM_CAST(addr), (u8)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void LHZ(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = vm::read16(vm::cast(addr)); + CPU.GPR[rd] = vm::read16(VM_CAST(addr)); } void LHZU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = vm::read16(vm::cast(addr)); + CPU.GPR[rd] = vm::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void LHA(u32 rd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.GPR[rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); } void LHAU(u32 rd, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - CPU.GPR[rd] = (s64)(s16)vm::read16(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s16)vm::read16(VM_CAST(addr)); CPU.GPR[ra] = addr; } void STH(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write16(vm::cast(addr), (u16)CPU.GPR[rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); } void STHU(u32 rs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - vm::write16(vm::cast(addr), (u16)CPU.GPR[rs]); + vm::write16(VM_CAST(addr), (u16)CPU.GPR[rs]); CPU.GPR[ra] = addr; } void LMW(u32 rd, u32 ra, s32 d) @@ -3525,7 +3523,7 @@ private: u64 addr = ra ? CPU.GPR[ra] + d : d; for(u32 i=rd; i<32; ++i, addr += 4) { - CPU.GPR[i] = vm::read32(vm::cast(addr)); + CPU.GPR[i] = vm::read32(VM_CAST(addr)); } } void STMW(u32 rs, u32 ra, s32 d) @@ -3533,13 +3531,13 @@ private: u64 addr = ra ? CPU.GPR[ra] + d : d; for(u32 i=rs; i<32; ++i, addr += 4) { - vm::write32(vm::cast(addr), (u32)CPU.GPR[i]); + vm::write32(VM_CAST(addr), (u32)CPU.GPR[i]); } } void LFS(u32 frd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - float val = vm::get_ref>(vm::cast(addr)).value(); + float val = vm::get_ref>(VM_CAST(addr)).value(); if (!FPRdouble::IsNaN(val)) { CPU.FPR[frd] = val; @@ -3553,7 +3551,7 @@ private: void LFSU(u32 frd, u32 ra, s32 ds) { const u64 addr = CPU.GPR[ra] + ds; - float val = vm::get_ref>(vm::cast(addr)).value(); + float val = vm::get_ref>(VM_CAST(addr)).value(); if (!FPRdouble::IsNaN(val)) { CPU.FPR[frd] = val; @@ -3568,12 +3566,12 @@ private: void LFD(u32 frd, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - CPU.FPR[frd] = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[frd] = vm::get_ref>(VM_CAST(addr)).value(); } void LFDU(u32 frd, u32 ra, s32 ds) { const u64 addr = CPU.GPR[ra] + ds; - CPU.FPR[frd] = vm::get_ref>(vm::cast(addr)).value(); + CPU.FPR[frd] = vm::get_ref>(VM_CAST(addr)).value(); CPU.GPR[ra] = addr; } void STFS(u32 frs, u32 ra, s32 d) @@ -3582,13 +3580,13 @@ private: double val = CPU.FPR[frs]; if (!FPRdouble::IsNaN(val)) { - vm::get_ref>(vm::cast(addr)) = (float)val; + vm::get_ref>(VM_CAST(addr)) = (float)val; } else { u64 bits = (u64&)val; u32 bits32 = (bits>>32 & 0x80000000) | (bits>>29 & 0x7fffffff); - vm::get_ref>(vm::cast(addr)) = bits32; + vm::get_ref>(VM_CAST(addr)) = bits32; } } void STFSU(u32 frs, u32 ra, s32 d) @@ -3597,48 +3595,48 @@ private: double val = CPU.FPR[frs]; if (!FPRdouble::IsNaN(val)) { - vm::get_ref>(vm::cast(addr)) = (float)val; + vm::get_ref>(VM_CAST(addr)) = (float)val; } else { u64 bits = (u64&)val; u32 bits32 = (bits>>32 & 0x80000000) | (bits>>29 & 0x7fffffff); - vm::get_ref>(vm::cast(addr)) = bits32; + vm::get_ref>(VM_CAST(addr)) = bits32; } CPU.GPR[ra] = addr; } void STFD(u32 frs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[frs]; } void STFDU(u32 frs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - vm::get_ref>(vm::cast(addr)) = CPU.FPR[frs]; + vm::get_ref>(VM_CAST(addr)) = CPU.FPR[frs]; CPU.GPR[ra] = addr; } void LD(u32 rd, u32 ra, s32 ds) { const u64 addr = ra ? CPU.GPR[ra] + ds : ds; - CPU.GPR[rd] = vm::read64(vm::cast(addr)); + CPU.GPR[rd] = vm::read64(VM_CAST(addr)); } void LDU(u32 rd, u32 ra, s32 ds) { const u64 addr = CPU.GPR[ra] + ds; - CPU.GPR[rd] = vm::read64(vm::cast(addr)); + CPU.GPR[rd] = vm::read64(VM_CAST(addr)); CPU.GPR[ra] = addr; } void LWA(u32 rd, u32 ra, s32 ds) { const u64 addr = ra ? CPU.GPR[ra] + ds : ds; - CPU.GPR[rd] = (s64)(s32)vm::read32(vm::cast(addr)); + CPU.GPR[rd] = (s64)(s32)vm::read32(VM_CAST(addr)); } - void FDIVS(u32 frd, u32 fra, u32 frb, bool rc) {FDIV(frd, fra, frb, rc, true);} - void FSUBS(u32 frd, u32 fra, u32 frb, bool rc) {FSUB(frd, fra, frb, rc, true);} - void FADDS(u32 frd, u32 fra, u32 frb, bool rc) {FADD(frd, fra, frb, rc, true);} - void FSQRTS(u32 frd, u32 frb, bool rc) {FSQRT(frd, frb, rc, true);} - void FRES(u32 frd, u32 frb, bool rc) + void FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) {FDIV(frd, fra, frb, rc, true);} + void FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) {FSUB(frd, fra, frb, rc, true);} + void FADDS(u32 frd, u32 fra, u32 frb, u32 rc) {FADD(frd, fra, frb, rc, true);} + void FSQRTS(u32 frd, u32 frb, u32 rc) {FSQRT(frd, frb, rc, true);} + void FRES(u32 frd, u32 frb, u32 rc) { SetHostRoundingMode(CPU.FPSCR.RN); const double b = CPU.FPR[frb]; @@ -3678,23 +3676,23 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FMULS(u32 frd, u32 fra, u32 frc, bool rc) {FMUL(frd, fra, frc, rc, true);} - void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, false, false, true);} - void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, false, true, true);} - void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, true, true, true);} - void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, true, false, true);} + void FMULS(u32 frd, u32 fra, u32 frc, u32 rc) {FMUL(frd, fra, frc, rc, true);} + void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, false, false, true);} + void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, false, true, true);} + void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, true, true, true);} + void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, true, false, true);} void STD(u32 rs, u32 ra, s32 d) { const u64 addr = ra ? CPU.GPR[ra] + d : d; - vm::write64(vm::cast(addr), CPU.GPR[rs]); + vm::write64(VM_CAST(addr), CPU.GPR[rs]); } void STDU(u32 rs, u32 ra, s32 ds) { const u64 addr = CPU.GPR[ra] + ds; - vm::write64(vm::cast(addr), CPU.GPR[rs]); + vm::write64(VM_CAST(addr), CPU.GPR[rs]); CPU.GPR[ra] = addr; } - void MTFSB1(u32 crbd, bool rc) + void MTFSB1(u32 crbd, u32 rc) { u32 mask = 1 << (31 - crbd); if ((crbd >= 3 && crbd <= 6) && !(CPU.FPSCR.FPSCR & mask)) mask |= 1 << 31; //FPSCR.FX @@ -3709,7 +3707,7 @@ private: const u32 exceptions_mask = 0x9FF80700; CPU.SetFPSCR(CPU.FPSCR.FPSCR & ~(exceptions_mask & 0xf << ((7 - crbs) * 4))); } - void MTFSB0(u32 crbd, bool rc) + void MTFSB0(u32 crbd, u32 rc) { u32 mask = 1 << (31 - crbd); if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode disabled"); @@ -3717,7 +3715,7 @@ private: if(rc) CPU.UpdateCR1(); } - void MTFSFI(u32 crfd, u32 i, bool rc) + void MTFSFI(u32 crfd, u32 i, u32 rc) { u32 mask = 0xF0000000 >> (crfd * 4); u32 val = (i & 0xF) << ((7 - crfd) * 4); @@ -3734,12 +3732,12 @@ private: if(rc) CPU.UpdateCR1(); } - void MFFS(u32 frd, bool rc) + void MFFS(u32 frd, u32 rc) { (u64&)CPU.FPR[frd] = CPU.FPSCR.FPSCR; if(rc) CPU.UpdateCR1(); } - void MTFSF(u32 flm, u32 frb, bool rc) + void MTFSF(u32 flm, u32 frb, u32 rc) { u32 mask = 0; for(u32 i=0; i<8; ++i) @@ -3774,7 +3772,7 @@ private: CPU.FPSCR.FPRF = cmp_res; CPU.SetCR(crfd, cmp_res); } - void FRSP(u32 frd, u32 frb, bool rc) + void FRSP(u32 frd, u32 frb, u32 rc) { SetHostRoundingMode(CPU.FPSCR.RN); const double b = CPU.FPR[frb]; @@ -3813,8 +3811,8 @@ private: CPU.FPR[frd] = r; if(rc) CPU.UpdateCR1(); } - void FCTIW(u32 frd, u32 frb, bool rc) {FCTIW(frd, frb, rc, false);} - void FCTIW(u32 frd, u32 frb, bool rc, bool truncate) + void FCTIW(u32 frd, u32 frb, u32 rc) {FCTIW(frd, frb, rc, false);} + void FCTIW(u32 frd, u32 frb, u32 rc, bool truncate) { const double b = CPU.FPR[frb]; u32 r; @@ -3880,9 +3878,9 @@ private: (u64&)CPU.FPR[frd] = r; if(rc) CPU.UpdateCR1(); } - void FCTIWZ(u32 frd, u32 frb, bool rc) {FCTIW(frd, frb, rc, true);} - void FDIV(u32 frd, u32 fra, u32 frb, bool rc) {FDIV(frd, fra, frb, rc, false);} - void FDIV(u32 frd, u32 fra, u32 frb, bool rc, bool single) + void FCTIWZ(u32 frd, u32 frb, u32 rc) {FCTIW(frd, frb, rc, true);} + void FDIV(u32 frd, u32 fra, u32 frb, u32 rc) {FDIV(frd, fra, frb, rc, false);} + void FDIV(u32 frd, u32 fra, u32 frb, u32 rc, bool single) { SetHostRoundingMode(CPU.FPSCR.RN); const double a = CPU.FPR[fra]; @@ -3953,8 +3951,8 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FSUB(u32 frd, u32 fra, u32 frb, bool rc) {FSUB(frd, fra, frb, rc, false);} - void FSUB(u32 frd, u32 fra, u32 frb, bool rc, bool single) + void FSUB(u32 frd, u32 fra, u32 frb, u32 rc) {FSUB(frd, fra, frb, rc, false);} + void FSUB(u32 frd, u32 fra, u32 frb, u32 rc, bool single) { SetHostRoundingMode(CPU.FPSCR.RN); const double a = CPU.FPR[fra]; @@ -4001,8 +3999,8 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FADD(u32 frd, u32 fra, u32 frb, bool rc) {FADD(frd, fra, frb, rc, false);} - void FADD(u32 frd, u32 fra, u32 frb, bool rc, bool single) + void FADD(u32 frd, u32 fra, u32 frb, u32 rc) {FADD(frd, fra, frb, rc, false);} + void FADD(u32 frd, u32 fra, u32 frb, u32 rc, bool single) { SetHostRoundingMode(CPU.FPSCR.RN); const double a = CPU.FPR[fra]; @@ -4049,8 +4047,8 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FSQRT(u32 frd, u32 frb, bool rc) {FSQRT(frd, frb, rc, false);} - void FSQRT(u32 frd, u32 frb, bool rc, bool single) + void FSQRT(u32 frd, u32 frb, u32 rc) {FSQRT(frd, frb, rc, false);} + void FSQRT(u32 frd, u32 frb, u32 rc, bool single) { SetHostRoundingMode(CPU.FPSCR.RN); const double b = CPU.FPR[frb]; @@ -4092,13 +4090,13 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) + void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { CPU.FPR[frd] = CPU.FPR[fra] >= 0.0 ? CPU.FPR[frc] : CPU.FPR[frb]; if(rc) CPU.UpdateCR1(); } - void FMUL(u32 frd, u32 fra, u32 frc, bool rc) {FMUL(frd, fra, frc, rc, false);} - void FMUL(u32 frd, u32 fra, u32 frc, bool rc, bool single) + void FMUL(u32 frd, u32 fra, u32 frc, u32 rc) {FMUL(frd, fra, frc, rc, false);} + void FMUL(u32 frd, u32 fra, u32 frc, u32 rc, bool single) { SetHostRoundingMode(CPU.FPSCR.RN); const double a = CPU.FPR[fra]; @@ -4145,7 +4143,7 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FRSQRTE(u32 frd, u32 frb, bool rc) + void FRSQRTE(u32 frd, u32 frb, u32 rc) { SetHostRoundingMode(CPU.FPSCR.RN); const double b = CPU.FPR[frb]; @@ -4197,9 +4195,9 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, false, true, false);} - void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, false, false, false);} - void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc, bool neg, bool sub, bool single) + void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, false, true, false);} + void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, false, false, false);} + void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc, bool neg, bool sub, bool single) { SetHostRoundingMode(CPU.FPSCR.RN); const double a = CPU.FPR[fra]; @@ -4266,8 +4264,8 @@ private: CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) CPU.UpdateCR1(); } - void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, true, true, false);} - void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {FMADD(frd, fra, frc, frb, rc, true, false, false);} + void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, true, true, false);} + void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {FMADD(frd, fra, frc, frb, rc, true, false, false);} void FCMPO(u32 crfd, u32 fra, u32 frb) { int cmp_res = FPRdouble::Cmp(CPU.FPR[fra], CPU.FPR[frb]); @@ -4290,28 +4288,28 @@ private: CPU.FPSCR.FPRF = cmp_res; CPU.SetCR(crfd, cmp_res); } - void FNEG(u32 frd, u32 frb, bool rc) + void FNEG(u32 frd, u32 frb, u32 rc) { CPU.FPR[frd] = -CPU.FPR[frb]; if(rc) CPU.UpdateCR1(); } - void FMR(u32 frd, u32 frb, bool rc) + void FMR(u32 frd, u32 frb, u32 rc) { CPU.FPR[frd] = CPU.FPR[frb]; if(rc) CPU.UpdateCR1(); } - void FNABS(u32 frd, u32 frb, bool rc) + void FNABS(u32 frd, u32 frb, u32 rc) { CPU.FPR[frd] = -fabs(CPU.FPR[frb]); if(rc) CPU.UpdateCR1(); } - void FABS(u32 frd, u32 frb, bool rc) + void FABS(u32 frd, u32 frb, u32 rc) { CPU.FPR[frd] = fabs(CPU.FPR[frb]); if(rc) CPU.UpdateCR1(); } - void FCTID(u32 frd, u32 frb, bool rc) {FCTID(frd, frb, rc, false);} - void FCTID(u32 frd, u32 frb, bool rc, bool truncate) + void FCTID(u32 frd, u32 frb, u32 rc) {FCTID(frd, frb, rc, false);} + void FCTID(u32 frd, u32 frb, u32 rc, bool truncate) { const double b = CPU.FPR[frb]; u64 r; @@ -4377,8 +4375,8 @@ private: (u64&)CPU.FPR[frd] = r; if(rc) CPU.UpdateCR1(); } - void FCTIDZ(u32 frd, u32 frb, bool rc) {FCTID(frd, frb, rc, true);} - void FCFID(u32 frd, u32 frb, bool rc) + void FCTIDZ(u32 frd, u32 frb, u32 rc) {FCTID(frd, frb, rc, true);} + void FCFID(u32 frd, u32 frb, u32 rc) { s64 bi = (s64&)CPU.FPR[frb]; double bf = (double)bi; @@ -4403,6 +4401,6 @@ private: void UNK(const u32 code, const u32 opcode, const u32 gcode) { - throw fmt::Format("Unknown/Illegal opcode! (0x%08x : 0x%x : 0x%x)", code, opcode, gcode); + throw EXCEPTION("Unknown/Illegal opcode! (0x%08x : 0x%x : 0x%x)", code, opcode, gcode); } }; diff --git a/rpcs3/Emu/Cell/PPUInterpreter2.h b/rpcs3/Emu/Cell/PPUInterpreter2.h index 9ad6989714..0bed8052ef 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter2.h +++ b/rpcs3/Emu/Cell/PPUInterpreter2.h @@ -736,59 +736,59 @@ public: virtual void CRORC(u32 bt, u32 ba, u32 bb) { func = ppu_interpreter::CRORC; } virtual void CROR(u32 bt, u32 ba, u32 bb) { func = ppu_interpreter::CROR; } virtual void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { func = ppu_interpreter::BCCTR; } - virtual void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { func = ppu_interpreter::RLWIMI; } - virtual void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { func = ppu_interpreter::RLWINM; } - virtual void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, bool rc) { func = ppu_interpreter::RLWNM; } + virtual void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { func = ppu_interpreter::RLWIMI; } + virtual void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { func = ppu_interpreter::RLWINM; } + virtual void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, u32 rc) { func = ppu_interpreter::RLWNM; } virtual void ORI(u32 rs, u32 ra, u32 uimm16) { func = ppu_interpreter::ORI; } virtual void ORIS(u32 rs, u32 ra, u32 uimm16) { func = ppu_interpreter::ORIS; } virtual void XORI(u32 ra, u32 rs, u32 uimm16) { func = ppu_interpreter::XORI; } virtual void XORIS(u32 ra, u32 rs, u32 uimm16) { func = ppu_interpreter::XORIS; } virtual void ANDI_(u32 ra, u32 rs, u32 uimm16) { func = ppu_interpreter::ANDI_; } virtual void ANDIS_(u32 ra, u32 rs, u32 uimm16) { func = ppu_interpreter::ANDIS_; } - virtual void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { func = ppu_interpreter::RLDICL; } - virtual void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { func = ppu_interpreter::RLDICR; } - virtual void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { func = ppu_interpreter::RLDIC; } - virtual void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { func = ppu_interpreter::RLDIMI; } - virtual void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) { func = ppu_interpreter::RLDC_LR; } + virtual void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { func = ppu_interpreter::RLDICL; } + virtual void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, u32 rc) { func = ppu_interpreter::RLDICR; } + virtual void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { func = ppu_interpreter::RLDIC; } + virtual void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { func = ppu_interpreter::RLDIMI; } + virtual void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, u32 is_r, u32 rc) { func = ppu_interpreter::RLDC_LR; } virtual void CMP(u32 crfd, u32 l, u32 ra, u32 rb) { func = ppu_interpreter::CMP; } virtual void TW(u32 to, u32 ra, u32 rb) { func = ppu_interpreter::TW; } virtual void LVSL(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVSL; } virtual void LVEBX(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVEBX; } - virtual void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::SUBFC; } - virtual void MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { func = ppu_interpreter::MULHDU; } - virtual void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::ADDC; } - virtual void MULHWU(u32 rd, u32 ra, u32 rb, bool rc) { func = ppu_interpreter::MULHWU; } + virtual void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::SUBFC; } + virtual void MULHDU(u32 rd, u32 ra, u32 rb, u32 rc) { func = ppu_interpreter::MULHDU; } + virtual void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::ADDC; } + virtual void MULHWU(u32 rd, u32 ra, u32 rb, u32 rc) { func = ppu_interpreter::MULHWU; } virtual void MFOCRF(u32 a, u32 rd, u32 crm) { func = ppu_interpreter::MFOCRF; } virtual void LWARX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LWARX; } virtual void LDX(u32 ra, u32 rs, u32 rb) { func = ppu_interpreter::LDX; } virtual void LWZX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LWZX; } - virtual void SLW(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::SLW; } - virtual void CNTLZW(u32 ra, u32 rs, bool rc) { func = ppu_interpreter::CNTLZW; } - virtual void SLD(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::SLD; } - virtual void AND(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::AND; } + virtual void SLW(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::SLW; } + virtual void CNTLZW(u32 ra, u32 rs, u32 rc) { func = ppu_interpreter::CNTLZW; } + virtual void SLD(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::SLD; } + virtual void AND(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::AND; } virtual void CMPL(u32 bf, u32 l, u32 ra, u32 rb) { func = ppu_interpreter::CMPL; } virtual void LVSR(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVSR; } virtual void LVEHX(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVEHX; } - virtual void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::SUBF; } + virtual void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::SUBF; } virtual void LDUX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LDUX; } virtual void DCBST(u32 ra, u32 rb) { func = ppu_interpreter::DCBST; } virtual void LWZUX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LWZUX; } - virtual void CNTLZD(u32 ra, u32 rs, bool rc) { func = ppu_interpreter::CNTLZD; } - virtual void ANDC(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::ANDC; } + virtual void CNTLZD(u32 ra, u32 rs, u32 rc) { func = ppu_interpreter::CNTLZD; } + virtual void ANDC(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::ANDC; } virtual void TD(u32 to, u32 ra, u32 rb) { func = ppu_interpreter::TD; } virtual void LVEWX(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVEWX; } - virtual void MULHD(u32 rd, u32 ra, u32 rb, bool rc) { func = ppu_interpreter::MULHD; } - virtual void MULHW(u32 rd, u32 ra, u32 rb, bool rc) { func = ppu_interpreter::MULHW; } + virtual void MULHD(u32 rd, u32 ra, u32 rb, u32 rc) { func = ppu_interpreter::MULHD; } + virtual void MULHW(u32 rd, u32 ra, u32 rb, u32 rc) { func = ppu_interpreter::MULHW; } virtual void LDARX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LDARX; } virtual void DCBF(u32 ra, u32 rb) { func = ppu_interpreter::DCBF; } virtual void LBZX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LBZX; } virtual void LVX(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVX; } - virtual void NEG(u32 rd, u32 ra, u32 oe, bool rc) { func = ppu_interpreter::NEG; } + virtual void NEG(u32 rd, u32 ra, u32 oe, u32 rc) { func = ppu_interpreter::NEG; } virtual void LBZUX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LBZUX; } - virtual void NOR(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::NOR; } + virtual void NOR(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::NOR; } virtual void STVEBX(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVEBX; } - virtual void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::SUBFE; } - virtual void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::ADDE; } + virtual void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::SUBFE; } + virtual void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::ADDE; } virtual void MTOCRF(u32 l, u32 crm, u32 rs) { func = ppu_interpreter::MTOCRF; } virtual void STDX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STDX; } virtual void STWCX_(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STWCX_; } @@ -797,24 +797,24 @@ public: virtual void STDUX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STDUX; } virtual void STWUX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STWUX; } virtual void STVEWX(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVEWX; } - virtual void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { func = ppu_interpreter::SUBFZE; } - virtual void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { func = ppu_interpreter::ADDZE; } + virtual void SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) { func = ppu_interpreter::SUBFZE; } + virtual void ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) { func = ppu_interpreter::ADDZE; } virtual void STDCX_(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STDCX_; } virtual void STBX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STBX; } virtual void STVX(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVX; } - virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::MULLD; } - virtual void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { func = ppu_interpreter::SUBFME; } - virtual void ADDME(u32 rd, u32 ra, u32 oe, bool rc) { func = ppu_interpreter::ADDME; } - virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::MULLW; } + virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::MULLD; } + virtual void SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) { func = ppu_interpreter::SUBFME; } + virtual void ADDME(u32 rd, u32 ra, u32 oe, u32 rc) { func = ppu_interpreter::ADDME; } + virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::MULLW; } virtual void DCBTST(u32 ra, u32 rb, u32 th) { func = ppu_interpreter::DCBTST; } virtual void STBUX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STBUX; } - virtual void ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::ADD; } + virtual void ADD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::ADD; } virtual void DCBT(u32 ra, u32 rb, u32 th) { func = ppu_interpreter::DCBT; } virtual void LHZX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LHZX; } - virtual void EQV(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::EQV; } + virtual void EQV(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::EQV; } virtual void ECIWX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::ECIWX; } virtual void LHZUX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LHZUX; } - virtual void XOR(u32 rs, u32 ra, u32 rb, bool rc) { func = ppu_interpreter::XOR; } + virtual void XOR(u32 rs, u32 ra, u32 rb, u32 rc) { func = ppu_interpreter::XOR; } virtual void MFSPR(u32 rd, u32 spr) { func = ppu_interpreter::MFSPR; } virtual void LWAX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LWAX; } virtual void DST(u32 ra, u32 rb, u32 strm, u32 t) { func = ppu_interpreter::DST; } @@ -825,25 +825,25 @@ public: virtual void DSTST(u32 ra, u32 rb, u32 strm, u32 t) { func = ppu_interpreter::DSTST; } virtual void LHAUX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LHAUX; } virtual void STHX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STHX; } - virtual void ORC(u32 rs, u32 ra, u32 rb, bool rc) { func = ppu_interpreter::ORC; } + virtual void ORC(u32 rs, u32 ra, u32 rb, u32 rc) { func = ppu_interpreter::ORC; } virtual void ECOWX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::ECOWX; } virtual void STHUX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STHUX; } - virtual void OR(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::OR; } - virtual void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::DIVDU; } - virtual void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::DIVWU; } + virtual void OR(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::OR; } + virtual void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::DIVDU; } + virtual void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::DIVWU; } virtual void MTSPR(u32 spr, u32 rs) { func = ppu_interpreter::MTSPR; } virtual void DCBI(u32 ra, u32 rb) { func = ppu_interpreter::DCBI; } - virtual void NAND(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::NAND; } + virtual void NAND(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::NAND; } virtual void STVXL(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVXL; } - virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::DIVD; } - virtual void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { func = ppu_interpreter::DIVW; } + virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::DIVD; } + virtual void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { func = ppu_interpreter::DIVW; } virtual void LVLX(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVLX; } virtual void LDBRX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LDBRX; } virtual void LSWX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LSWX; } virtual void LWBRX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LWBRX; } virtual void LFSX(u32 frd, u32 ra, u32 rb) { func = ppu_interpreter::LFSX; } - virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::SRW; } - virtual void SRD(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::SRD; } + virtual void SRW(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::SRW; } + virtual void SRD(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::SRD; } virtual void LVRX(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVRX; } virtual void LSWI(u32 rd, u32 ra, u32 nb) { func = ppu_interpreter::LSWI; } virtual void LFSUX(u32 frd, u32 ra, u32 rb) { func = ppu_interpreter::LFSUX; } @@ -862,21 +862,21 @@ public: virtual void STFDUX(u32 frs, u32 ra, u32 rb) { func = ppu_interpreter::STFDUX; } virtual void LVLXL(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVLXL; } virtual void LHBRX(u32 rd, u32 ra, u32 rb) { func = ppu_interpreter::LHBRX; } - virtual void SRAW(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::SRAW; } - virtual void SRAD(u32 ra, u32 rs, u32 rb, bool rc) { func = ppu_interpreter::SRAD; } + virtual void SRAW(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::SRAW; } + virtual void SRAD(u32 ra, u32 rs, u32 rb, u32 rc) { func = ppu_interpreter::SRAD; } virtual void LVRXL(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVRXL; } virtual void DSS(u32 strm, u32 a) { func = ppu_interpreter::DSS; } - virtual void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRAWI; } - virtual void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI; } - virtual void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI; } + virtual void SRAWI(u32 ra, u32 rs, u32 sh, u32 rc) { func = ppu_interpreter::SRAWI; } + virtual void SRADI1(u32 ra, u32 rs, u32 sh, u32 rc) { func = ppu_interpreter::SRADI; } + virtual void SRADI2(u32 ra, u32 rs, u32 sh, u32 rc) { func = ppu_interpreter::SRADI; } virtual void EIEIO() { func = ppu_interpreter::EIEIO; } virtual void STVLXL(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVLXL; } virtual void STHBRX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STHBRX; } - virtual void EXTSH(u32 ra, u32 rs, bool rc) { func = ppu_interpreter::EXTSH; } + virtual void EXTSH(u32 ra, u32 rs, u32 rc) { func = ppu_interpreter::EXTSH; } virtual void STVRXL(u32 sd, u32 ra, u32 rb) { func = ppu_interpreter::STVRXL; } - virtual void EXTSB(u32 ra, u32 rs, bool rc) { func = ppu_interpreter::EXTSB; } + virtual void EXTSB(u32 ra, u32 rs, u32 rc) { func = ppu_interpreter::EXTSB; } virtual void STFIWX(u32 frs, u32 ra, u32 rb) { func = ppu_interpreter::STFIWX; } - virtual void EXTSW(u32 ra, u32 rs, bool rc) { func = ppu_interpreter::EXTSW; } + virtual void EXTSW(u32 ra, u32 rs, u32 rc) { func = ppu_interpreter::EXTSW; } virtual void ICBI(u32 ra, u32 rb) { func = ppu_interpreter::ICBI; } virtual void DCBZ(u32 ra, u32 rb) { func = ppu_interpreter::DCBZ; } virtual void LWZ(u32 rd, u32 ra, s32 d) { func = ppu_interpreter::LWZ; } @@ -906,48 +906,48 @@ public: virtual void LD(u32 rd, u32 ra, s32 ds) { func = ppu_interpreter::LD; } virtual void LDU(u32 rd, u32 ra, s32 ds) { func = ppu_interpreter::LDU; } virtual void LWA(u32 rd, u32 ra, s32 ds) { func = ppu_interpreter::LWA; } - virtual void FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { func = ppu_interpreter::FDIVS; } - virtual void FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { func = ppu_interpreter::FSUBS; } - virtual void FADDS(u32 frd, u32 fra, u32 frb, bool rc) { func = ppu_interpreter::FADDS; } - virtual void FSQRTS(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FSQRTS; } - virtual void FRES(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FRES; } - virtual void FMULS(u32 frd, u32 fra, u32 frc, bool rc) { func = ppu_interpreter::FMULS; } - virtual void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FMADDS; } - virtual void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FMSUBS; } - virtual void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FNMSUBS; } - virtual void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FNMADDS; } + virtual void FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) { func = ppu_interpreter::FDIVS; } + virtual void FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) { func = ppu_interpreter::FSUBS; } + virtual void FADDS(u32 frd, u32 fra, u32 frb, u32 rc) { func = ppu_interpreter::FADDS; } + virtual void FSQRTS(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FSQRTS; } + virtual void FRES(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FRES; } + virtual void FMULS(u32 frd, u32 fra, u32 frc, u32 rc) { func = ppu_interpreter::FMULS; } + virtual void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FMADDS; } + virtual void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FMSUBS; } + virtual void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FNMSUBS; } + virtual void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FNMADDS; } virtual void STD(u32 rs, u32 ra, s32 ds) { func = ppu_interpreter::STD; } virtual void STDU(u32 rs, u32 ra, s32 ds) { func = ppu_interpreter::STDU; } - virtual void MTFSB1(u32 bt, bool rc) { func = ppu_interpreter::MTFSB1; } + virtual void MTFSB1(u32 bt, u32 rc) { func = ppu_interpreter::MTFSB1; } virtual void MCRFS(u32 bf, u32 bfa) { func = ppu_interpreter::MCRFS; } - virtual void MTFSB0(u32 bt, bool rc) { func = ppu_interpreter::MTFSB0; } - virtual void MTFSFI(u32 crfd, u32 i, bool rc) { func = ppu_interpreter::MTFSFI; } - virtual void MFFS(u32 frd, bool rc) { func = ppu_interpreter::MFFS; } - virtual void MTFSF(u32 flm, u32 frb, bool rc) { func = ppu_interpreter::MTFSF; } + virtual void MTFSB0(u32 bt, u32 rc) { func = ppu_interpreter::MTFSB0; } + virtual void MTFSFI(u32 crfd, u32 i, u32 rc) { func = ppu_interpreter::MTFSFI; } + virtual void MFFS(u32 frd, u32 rc) { func = ppu_interpreter::MFFS; } + virtual void MTFSF(u32 flm, u32 frb, u32 rc) { func = ppu_interpreter::MTFSF; } virtual void FCMPU(u32 bf, u32 fra, u32 frb) { func = ppu_interpreter::FCMPU; } - virtual void FRSP(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FRSP; } - virtual void FCTIW(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FCTIW; } - virtual void FCTIWZ(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FCTIWZ; } - virtual void FDIV(u32 frd, u32 fra, u32 frb, bool rc) { func = ppu_interpreter::FDIV; } - virtual void FSUB(u32 frd, u32 fra, u32 frb, bool rc) { func = ppu_interpreter::FSUB; } - virtual void FADD(u32 frd, u32 fra, u32 frb, bool rc) { func = ppu_interpreter::FADD; } - virtual void FSQRT(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FSQRT; } - virtual void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FSEL; } - virtual void FMUL(u32 frd, u32 fra, u32 frc, bool rc) { func = ppu_interpreter::FMUL; } - virtual void FRSQRTE(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FRSQRTE; } - virtual void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FMSUB; } - virtual void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FMADD; } - virtual void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FNMSUB; } - virtual void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { func = ppu_interpreter::FNMADD; } + virtual void FRSP(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FRSP; } + virtual void FCTIW(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FCTIW; } + virtual void FCTIWZ(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FCTIWZ; } + virtual void FDIV(u32 frd, u32 fra, u32 frb, u32 rc) { func = ppu_interpreter::FDIV; } + virtual void FSUB(u32 frd, u32 fra, u32 frb, u32 rc) { func = ppu_interpreter::FSUB; } + virtual void FADD(u32 frd, u32 fra, u32 frb, u32 rc) { func = ppu_interpreter::FADD; } + virtual void FSQRT(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FSQRT; } + virtual void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FSEL; } + virtual void FMUL(u32 frd, u32 fra, u32 frc, u32 rc) { func = ppu_interpreter::FMUL; } + virtual void FRSQRTE(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FRSQRTE; } + virtual void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FMSUB; } + virtual void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FMADD; } + virtual void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FNMSUB; } + virtual void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { func = ppu_interpreter::FNMADD; } virtual void FCMPO(u32 crfd, u32 fra, u32 frb) { func = ppu_interpreter::FCMPO; } - virtual void FNEG(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FNEG; } - virtual void FMR(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FMR; } - virtual void FNABS(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FNABS; } - virtual void FABS(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FABS; } - virtual void FCTID(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FCTID; } - virtual void FCTIDZ(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FCTIDZ; } - virtual void FCFID(u32 frd, u32 frb, bool rc) { func = ppu_interpreter::FCFID; } + virtual void FNEG(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FNEG; } + virtual void FMR(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FMR; } + virtual void FNABS(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FNABS; } + virtual void FABS(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FABS; } + virtual void FCTID(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FCTID; } + virtual void FCTIDZ(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FCTIDZ; } + virtual void FCFID(u32 frd, u32 frb, u32 rc) { func = ppu_interpreter::FCFID; } virtual void UNK(const u32 code, const u32 opcode, const u32 gcode) { func = ppu_interpreter::UNK; } }; \ No newline at end of file diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 5ae0548f65..bd862d6792 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -148,7 +148,7 @@ Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & } if (instr_bb->empty()) { - u32 instr = re32(vm::get_ref(m_state.current_instruction_address)); + u32 instr = vm::ps3::read32(m_state.current_instruction_address); Decode(instr); if (!m_state.hit_branch_instruction) { m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); @@ -2158,7 +2158,7 @@ void Compiler::BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { CreateBranch(CheckBranchCondition(bo, bi), ctr_i32, lk ? true : false); } -void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { +void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); @@ -2182,7 +2182,7 @@ void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { } } -void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { +void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); @@ -2202,7 +2202,7 @@ void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { } } -void Compiler::RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, bool rc) { +void Compiler::RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); @@ -2259,7 +2259,7 @@ void Compiler::ANDIS_(u32 ra, u32 rs, u32 uimm16) { SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); } -void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { +void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { auto rs_i64 = GetGpr(rs); auto res_i64 = rs_i64; if (sh) { @@ -2276,7 +2276,7 @@ void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { } } -void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { +void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, u32 rc) { auto rs_i64 = GetGpr(rs); auto res_i64 = rs_i64; if (sh) { @@ -2293,7 +2293,7 @@ void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { } } -void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { +void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { auto rs_i64 = GetGpr(rs); auto res_i64 = rs_i64; if (sh) { @@ -2310,7 +2310,7 @@ void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { } } -void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { +void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) { auto rs_i64 = GetGpr(rs); auto ra_i64 = GetGpr(ra); auto res_i64 = rs_i64; @@ -2331,7 +2331,7 @@ void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { } } -void Compiler::RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) { +void Compiler::RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, u32 is_r, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x3F); @@ -2419,7 +2419,7 @@ void Compiler::LVEBX(u32 vd, u32 ra, u32 rb) { SetVr(vd, vd_v16i8); } -void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); ra_i64 = m_ir_builder->CreateNeg(ra_i64); auto rb_i64 = GetGpr(rb); @@ -2439,7 +2439,7 @@ void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { } } -void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); @@ -2457,7 +2457,7 @@ void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { } } -void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { +void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128)); @@ -2472,7 +2472,7 @@ void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { } } -void Compiler::MULHWU(u32 rd, u32 ra, u32 rb, bool rc) { +void Compiler::MULHWU(u32 rd, u32 ra, u32 rb, u32 rc) { auto ra_i32 = GetGpr(ra, 32); auto rb_i32 = GetGpr(rb, 32); auto ra_i64 = m_ir_builder->CreateZExt(ra_i32, m_ir_builder->getInt64Ty()); @@ -2532,7 +2532,7 @@ void Compiler::LWZX(u32 rd, u32 ra, u32 rb) { SetGpr(rd, mem_i64); } -void Compiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::SLW(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); auto rb_i8 = GetGpr(rb, 8); @@ -2548,7 +2548,7 @@ void Compiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) { } } -void Compiler::CNTLZW(u32 ra, u32 rs, bool rc) { +void Compiler::CNTLZW(u32 ra, u32 rs, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false)); auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); @@ -2559,7 +2559,7 @@ void Compiler::CNTLZW(u32 ra, u32 rs, bool rc) { } } -void Compiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::SLD(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); auto rb_i8 = GetGpr(rb, 8); @@ -2574,7 +2574,7 @@ void Compiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) { } } -void Compiler::AND(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::AND(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); @@ -2649,7 +2649,7 @@ void Compiler::LVEHX(u32 vd, u32 ra, u32 rb) { SetVr(vd, vd_v8i16); } -void Compiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto diff_i64 = m_ir_builder->CreateSub(rb_i64, ra_i64); @@ -2691,7 +2691,7 @@ void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) { SetGpr(ra, addr_i64); } -void Compiler::CNTLZD(u32 ra, u32 rs, bool rc) { +void Compiler::CNTLZD(u32 ra, u32 rs, u32 rc) { auto rs_i64 = GetGpr(rs); auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false)); SetGpr(ra, res_i64); @@ -2701,7 +2701,7 @@ void Compiler::CNTLZD(u32 ra, u32 rs, bool rc) { } } -void Compiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::ANDC(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); rb_i64 = m_ir_builder->CreateNot(rb_i64); @@ -2734,7 +2734,7 @@ void Compiler::LVEWX(u32 vd, u32 ra, u32 rb) { SetVr(vd, vd_v4i32); } -void Compiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) { +void Compiler::MULHD(u32 rd, u32 ra, u32 rb, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128)); @@ -2749,7 +2749,7 @@ void Compiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) { } } -void Compiler::MULHW(u32 rd, u32 ra, u32 rb, bool rc) { +void Compiler::MULHW(u32 rd, u32 ra, u32 rb, u32 rc) { auto ra_i32 = GetGpr(ra, 32); auto rb_i32 = GetGpr(rb, 32); auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); @@ -2808,7 +2808,7 @@ void Compiler::LVX(u32 vd, u32 ra, u32 rb) { SetVr(vd, mem_i128); } -void Compiler::NEG(u32 rd, u32 ra, u32 oe, bool rc) { +void Compiler::NEG(u32 rd, u32 ra, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto diff_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(0), ra_i64); SetGpr(rd, diff_i64); @@ -2834,7 +2834,7 @@ void Compiler::LBZUX(u32 rd, u32 ra, u32 rb) { SetGpr(ra, addr_i64); } -void Compiler::NOR(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::NOR(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); @@ -2860,7 +2860,7 @@ void Compiler::STVEBX(u32 vs, u32 ra, u32 rb) { WriteMemory(addr_i64, val_i8); } -void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ca_i64 = GetXerCa(); auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); @@ -2885,7 +2885,7 @@ void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { } } -void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ca_i64 = GetXerCa(); auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); @@ -3019,7 +3019,7 @@ void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) { WriteMemory(addr_i64, val_i32, 4); } -void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { +void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto ca_i64 = GetXerCa(); auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); @@ -3038,7 +3038,7 @@ void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { } } -void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { +void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); ra_i64 = m_ir_builder->CreateNot(ra_i64); auto ca_i64 = GetXerCa(); @@ -3099,7 +3099,7 @@ void Compiler::STVX(u32 vs, u32 ra, u32 rb) { WriteMemory(addr_i64, GetVr(vs), 16); } -void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { +void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) { auto ca_i64 = GetXerCa(); auto ra_i64 = GetGpr(ra); ra_i64 = m_ir_builder->CreateNot(ra_i64); @@ -3123,7 +3123,7 @@ void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { } } -void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); @@ -3139,7 +3139,7 @@ void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { } } -void Compiler::ADDME(u32 rd, u32 ra, u32 oe, bool rc) { +void Compiler::ADDME(u32 rd, u32 ra, u32 oe, u32 rc) { auto ca_i64 = GetXerCa(); auto ra_i64 = GetGpr(ra); auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); @@ -3162,7 +3162,7 @@ void Compiler::ADDME(u32 rd, u32 ra, u32 oe, bool rc) { } } -void Compiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i32 = GetGpr(ra, 32); auto rb_i32 = GetGpr(rb, 32); auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); @@ -3194,7 +3194,7 @@ void Compiler::STBUX(u32 rs, u32 ra, u32 rb) { SetGpr(ra, addr_i64); } -void Compiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, rb_i64); @@ -3227,7 +3227,7 @@ void Compiler::LHZX(u32 rd, u32 ra, u32 rb) { SetGpr(rd, mem_i64); } -void Compiler::EQV(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::EQV(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); @@ -3263,7 +3263,7 @@ void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) { SetGpr(ra, addr_i64); } -void Compiler::XOR(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::XOR(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); @@ -3292,10 +3292,10 @@ void Compiler::MFSPR(u32 rd, u32 spr) { rd_i64 = GetVrsave(); break; case 0x10C: - rd_i64 = Call("get_time", get_time); + rd_i64 = Call("get_timebased_time", get_timebased_time); break; case 0x10D: - rd_i64 = Call("get_time", get_time); + rd_i64 = Call("get_timebased_time", get_timebased_time); rd_i64 = m_ir_builder->CreateLShr(rd_i64, 32); break; default: @@ -3340,7 +3340,7 @@ void Compiler::LVXL(u32 vd, u32 ra, u32 rb) { } void Compiler::MFTB(u32 rd, u32 spr) { - auto tb_i64 = Call("get_time", get_time); + auto tb_i64 = Call("get_timebased_time", get_timebased_time); u32 n = (spr >> 5) | ((spr & 0x1f) << 5); if (n == 0x10D) { @@ -3387,7 +3387,7 @@ void Compiler::STHX(u32 rs, u32 ra, u32 rb) { WriteMemory(addr_i64, GetGpr(rs, 16)); } -void Compiler::ORC(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::ORC(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); rb_i64 = m_ir_builder->CreateNot(rb_i64); @@ -3419,7 +3419,7 @@ void Compiler::STHUX(u32 rs, u32 ra, u32 rb) { SetGpr(ra, addr_i64); } -void Compiler::OR(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::OR(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); @@ -3430,7 +3430,7 @@ void Compiler::OR(u32 ra, u32 rs, u32 rb, bool rc) { } } -void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateUDiv(ra_i64, rb_i64); @@ -3448,7 +3448,7 @@ void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { // TODO make sure an exception does not occur on divide by 0 and overflow } -void Compiler::DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i32 = GetGpr(ra, 32); auto rb_i32 = GetGpr(rb, 32); auto res_i32 = m_ir_builder->CreateUDiv(ra_i32, rb_i32); @@ -3491,7 +3491,7 @@ void Compiler::MTSPR(u32 spr, u32 rs) { } -void Compiler::NAND(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::NAND(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); @@ -3507,7 +3507,7 @@ void Compiler::STVXL(u32 vs, u32 ra, u32 rb) { STVX(vs, ra, rb); } -void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i64 = GetGpr(ra); auto rb_i64 = GetGpr(rb); auto res_i64 = m_ir_builder->CreateSDiv(ra_i64, rb_i64); @@ -3525,7 +3525,7 @@ void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { // TODO make sure an exception does not occur on divide by 0 and overflow } -void Compiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { +void Compiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) { auto ra_i32 = GetGpr(ra, 32); auto rb_i32 = GetGpr(rb, 32); auto res_i32 = m_ir_builder->CreateSDiv(ra_i32, rb_i32); @@ -3598,7 +3598,7 @@ void Compiler::LFSX(u32 frd, u32 ra, u32 rb) { SetFpr(frd, mem_i32); } -void Compiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::SRW(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); auto rb_i8 = GetGpr(rb, 8); @@ -3612,7 +3612,7 @@ void Compiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) { } } -void Compiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::SRD(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); auto rb_i8 = GetGpr(rb, 8); @@ -3866,7 +3866,7 @@ void Compiler::LHBRX(u32 rd, u32 ra, u32 rb) { SetGpr(rd, mem_i64); } -void Compiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::SRAW(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); @@ -3888,7 +3888,7 @@ void Compiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) { } } -void Compiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) { +void Compiler::SRAD(u32 ra, u32 rs, u32 rb, u32 rc) { auto rs_i64 = GetGpr(rs); auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); @@ -3920,7 +3920,7 @@ void Compiler::DSS(u32 strm, u32 a) { m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); } -void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { +void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); @@ -3939,7 +3939,7 @@ void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { } } -void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { +void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, u32 rc) { auto rs_i64 = GetGpr(rs); auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); @@ -3959,7 +3959,7 @@ void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { } } -void Compiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { +void Compiler::SRADI2(u32 ra, u32 rs, u32 sh, u32 rc) { SRADI1(ra, rs, sh, rc); } @@ -3981,7 +3981,7 @@ void Compiler::STHBRX(u32 rs, u32 ra, u32 rb) { WriteMemory(addr_i64, GetGpr(rs, 16), 0, false); } -void Compiler::EXTSH(u32 ra, u32 rs, bool rc) { +void Compiler::EXTSH(u32 ra, u32 rs, u32 rc) { auto rs_i16 = GetGpr(rs, 16); auto rs_i64 = m_ir_builder->CreateSExt(rs_i16, m_ir_builder->getInt64Ty()); SetGpr(ra, rs_i64); @@ -3995,7 +3995,7 @@ void Compiler::STVRXL(u32 vs, u32 ra, u32 rb) { STVRX(vs, ra, rb); } -void Compiler::EXTSB(u32 ra, u32 rs, bool rc) { +void Compiler::EXTSB(u32 ra, u32 rs, u32 rc) { auto rs_i8 = GetGpr(rs, 8); auto rs_i64 = m_ir_builder->CreateSExt(rs_i8, m_ir_builder->getInt64Ty()); SetGpr(ra, rs_i64); @@ -4017,7 +4017,7 @@ void Compiler::STFIWX(u32 frs, u32 ra, u32 rb) { WriteMemory(addr_i64, frs_i32); } -void Compiler::EXTSW(u32 ra, u32 rs, bool rc) { +void Compiler::EXTSW(u32 ra, u32 rs, u32 rc) { auto rs_i32 = GetGpr(rs, 32); auto rs_i64 = m_ir_builder->CreateSExt(rs_i32, m_ir_builder->getInt64Ty()); SetGpr(ra, rs_i64); @@ -4340,7 +4340,7 @@ void Compiler::LWA(u32 rd, u32 ra, s32 ds) { SetGpr(rd, mem_i64); } -void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { +void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); @@ -4355,7 +4355,7 @@ void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { +void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); @@ -4370,7 +4370,7 @@ void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) { +void Compiler::FADDS(u32 frd, u32 fra, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); @@ -4385,7 +4385,7 @@ void Compiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FSQRTS(u32 frd, u32 frb, bool rc) { +void Compiler::FSQRTS(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); @@ -4399,7 +4399,7 @@ void Compiler::FSQRTS(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FRES(u32 frd, u32 frb, bool rc) { +void Compiler::FRES(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), rb_f64); auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); @@ -4413,7 +4413,7 @@ void Compiler::FRES(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) { +void Compiler::FMULS(u32 frd, u32 fra, u32 frc, u32 rc) { auto ra_f64 = GetFpr(fra); auto rc_f64 = GetFpr(frc); auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); @@ -4428,7 +4428,7 @@ void Compiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) { // TODO: Set flags } -void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4444,7 +4444,7 @@ void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4461,7 +4461,7 @@ void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4479,7 +4479,7 @@ void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4515,7 +4515,7 @@ void Compiler::STDU(u32 rs, u32 ra, s32 ds) { SetGpr(ra, addr_i64); } -void Compiler::MTFSB1(u32 crbd, bool rc) { +void Compiler::MTFSB1(u32 crbd, u32 rc) { auto fpscr_i32 = GetFpscr(); fpscr_i32 = SetBit(fpscr_i32, crbd, m_ir_builder->getInt32(1), false); SetFpscr(fpscr_i32); @@ -4557,7 +4557,7 @@ void Compiler::MCRFS(u32 crbd, u32 crbs) { SetFpscr(fpscr_i32); } -void Compiler::MTFSB0(u32 crbd, bool rc) { +void Compiler::MTFSB0(u32 crbd, u32 rc) { auto fpscr_i32 = GetFpscr(); fpscr_i32 = ClrBit(fpscr_i32, crbd); SetFpscr(fpscr_i32); @@ -4568,7 +4568,7 @@ void Compiler::MTFSB0(u32 crbd, bool rc) { } } -void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) { +void Compiler::MTFSFI(u32 crfd, u32 i, u32 rc) { auto fpscr_i32 = GetFpscr(); fpscr_i32 = SetNibble(fpscr_i32, crfd, m_ir_builder->getInt32(i & 0xF)); SetFpscr(fpscr_i32); @@ -4579,7 +4579,7 @@ void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) { } } -void Compiler::MFFS(u32 frd, bool rc) { +void Compiler::MFFS(u32 frd, u32 rc) { auto fpscr_i32 = GetFpscr(); auto fpscr_i64 = m_ir_builder->CreateZExt(fpscr_i32, m_ir_builder->getInt64Ty()); SetFpr(frd, fpscr_i64); @@ -4590,7 +4590,7 @@ void Compiler::MFFS(u32 frd, bool rc) { } } -void Compiler::MTFSF(u32 flm, u32 frb, bool rc) { +void Compiler::MTFSF(u32 flm, u32 frb, u32 rc) { u32 mask = 0; for(u32 i = 0; i < 8; i++) { if (flm & (1 << i)) { @@ -4624,7 +4624,7 @@ void Compiler::FCMPU(u32 crfd, u32 fra, u32 frb) { // TODO: Set flags / Handle NaN } -void Compiler::FRSP(u32 frd, u32 frb, bool rc) { +void Compiler::FRSP(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f32 = m_ir_builder->CreateFPTrunc(rb_f64, m_ir_builder->getFloatTy()); auto res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy()); @@ -4639,7 +4639,7 @@ void Compiler::FRSP(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FCTIW(u32 frd, u32 frb, bool rc) { +void Compiler::FCTIW(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); @@ -4657,7 +4657,7 @@ void Compiler::FCTIW(u32 frd, u32 frb, bool rc) { // TODO: Set flags / Implement rounding modes } -void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) { +void Compiler::FCTIWZ(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); @@ -4675,7 +4675,7 @@ void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) { +void Compiler::FDIV(u32 frd, u32 fra, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); @@ -4689,7 +4689,7 @@ void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FSUB(u32 frd, u32 fra, u32 frb, bool rc) { +void Compiler::FSUB(u32 frd, u32 fra, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); @@ -4703,7 +4703,7 @@ void Compiler::FSUB(u32 frd, u32 fra, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FADD(u32 frd, u32 fra, u32 frb, bool rc) { +void Compiler::FADD(u32 frd, u32 fra, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); @@ -4717,7 +4717,7 @@ void Compiler::FADD(u32 frd, u32 fra, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FSQRT(u32 frd, u32 frb, bool rc) { +void Compiler::FSQRT(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); SetFpr(frd, res_f64); @@ -4730,7 +4730,7 @@ void Compiler::FSQRT(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4746,7 +4746,7 @@ void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FMUL(u32 frd, u32 fra, u32 frc, bool rc) { +void Compiler::FMUL(u32 frd, u32 fra, u32 frc, u32 rc) { auto ra_f64 = GetFpr(fra); auto rc_f64 = GetFpr(frc); auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); @@ -4760,7 +4760,7 @@ void Compiler::FMUL(u32 frd, u32 fra, u32 frc, bool rc) { // TODO: Set flags } -void Compiler::FRSQRTE(u32 frd, u32 frb, bool rc) { +void Compiler::FRSQRTE(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), res_f64); @@ -4772,7 +4772,7 @@ void Compiler::FRSQRTE(u32 frd, u32 frb, bool rc) { } } -void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4788,7 +4788,7 @@ void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4803,7 +4803,7 @@ void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4819,7 +4819,7 @@ void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { +void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) { auto ra_f64 = GetFpr(fra); auto rb_f64 = GetFpr(frb); auto rc_f64 = GetFpr(frc); @@ -4849,7 +4849,7 @@ void Compiler::FCMPO(u32 crfd, u32 fra, u32 frb) { // TODO: Set flags / Handle NaN } -void Compiler::FNEG(u32 frd, u32 frb, bool rc) { +void Compiler::FNEG(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); rb_f64 = m_ir_builder->CreateFNeg(rb_f64); SetFpr(frd, rb_f64); @@ -4862,7 +4862,7 @@ void Compiler::FNEG(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FMR(u32 frd, u32 frb, bool rc) { +void Compiler::FMR(u32 frd, u32 frb, u32 rc) { SetFpr(frd, GetFpr(frb)); if (rc) { @@ -4873,7 +4873,7 @@ void Compiler::FMR(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FNABS(u32 frd, u32 frb, bool rc) { +void Compiler::FNABS(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); res_f64 = m_ir_builder->CreateFNeg(res_f64); @@ -4887,7 +4887,7 @@ void Compiler::FNABS(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FABS(u32 frd, u32 frb, bool rc) { +void Compiler::FABS(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); SetFpr(frd, res_f64); @@ -4900,7 +4900,7 @@ void Compiler::FABS(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FCTID(u32 frd, u32 frb, bool rc) { +void Compiler::FCTID(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); @@ -4917,7 +4917,7 @@ void Compiler::FCTID(u32 frd, u32 frb, bool rc) { // TODO: Set flags / Implement rounding modes } -void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) { +void Compiler::FCTIDZ(u32 frd, u32 frb, u32 rc) { auto rb_f64 = GetFpr(frb); auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); @@ -4934,7 +4934,7 @@ void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) { // TODO: Set flags } -void Compiler::FCFID(u32 frd, u32 frb, bool rc) { +void Compiler::FCFID(u32 frd, u32 frb, u32 rc) { auto rb_i64 = GetFpr(frb, 64, true); auto res_f64 = m_ir_builder->CreateSIToFP(rb_i64, m_ir_builder->getDoubleTy()); SetFpr(frd, res_f64); @@ -5596,15 +5596,14 @@ std::mutex RecompilationEngine::s_mutex; std::shared_ptr RecompilationEngine::s_the_instance = nullptr; RecompilationEngine::RecompilationEngine() - : ThreadBase("PPU Recompilation Engine") - , m_log(nullptr) + : m_log(nullptr) , m_next_ordinal(0) , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn, ExecutionEngine::PollStatus) { m_compiler.RunAllTests(); } RecompilationEngine::~RecompilationEngine() { - Stop(); + join(); } u32 RecompilationEngine::AllocateOrdinal(u32 address, bool is_function) { @@ -5648,11 +5647,11 @@ void RecompilationEngine::NotifyTrace(ExecutionTrace * execution_trace) { m_pending_execution_traces.push_back(execution_trace); } - if (!IsAlive()) { - Start(); + if (!joinable()) { + start(WRAP_EXPR("PPU Recompilation Engine"), WRAP_EXPR(Task())); } - Notify(); + cv.notify_one(); // TODO: Increase the priority of the recompilation engine thread } @@ -5672,7 +5671,7 @@ void RecompilationEngine::Task() { std::chrono::nanoseconds recompiling_time(0); auto start = std::chrono::high_resolution_clock::now(); - while (!TestDestroy() && !Emu.IsStopped()) { + while (joinable() && !Emu.IsStopped()) { bool work_done_this_iteration = false; ExecutionTrace * execution_trace = nullptr; @@ -5729,7 +5728,8 @@ void RecompilationEngine::Task() { // Wait a few ms for something to happen auto idling_start = std::chrono::high_resolution_clock::now(); - WaitForAnySignal(250); + std::unique_lock lock(mutex); + cv.wait_for(lock, std::chrono::milliseconds(250)); auto idling_end = std::chrono::high_resolution_clock::now(); idling_time += std::chrono::duration_cast(idling_end - idling_start); } @@ -6025,10 +6025,10 @@ u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_stat } } else { execution_engine->m_tracer.Trace(Tracer::TraceType::Instruction, ppu_state->PC, 0); - auto instruction = re32(vm::get_ref(ppu_state->PC)); + u32 instruction = vm::ps3::read32(ppu_state->PC); execution_engine->m_decoder.Decode(instruction); - branch_type = ppu_state->m_is_branch ? GetBranchTypeFromInstruction(instruction) : BranchType::NonBranch; - ppu_state->NextPc(4); + branch_type = GetBranchTypeFromInstruction(instruction); + ppu_state->PC += 4; switch (branch_type) { case BranchType::Return: @@ -6055,15 +6055,7 @@ u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_stat } bool ppu_recompiler_llvm::ExecutionEngine::PollStatus(PPUThread * ppu_state) { - while (Emu.IsPaused() || ppu_state->IsPaused()) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - - if (Emu.IsStopped() || ppu_state->IsStopped()) { - return true; - } - - return false; + return ppu_state->CheckStatus(); } BranchType ppu_recompiler_llvm::GetBranchTypeFromInstruction(u32 instruction) { diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 5ab812e8b6..fc3867006e 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -486,59 +486,59 @@ namespace ppu_recompiler_llvm { void CRORC(u32 bt, u32 ba, u32 bb) override; void CROR(u32 bt, u32 ba, u32 bb) override; void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) override; - void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) override; - void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) override; - void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, bool rc) override; + void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) override; + void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) override; + void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, u32 rc) override; void ORI(u32 rs, u32 ra, u32 uimm16) override; void ORIS(u32 rs, u32 ra, u32 uimm16) override; void XORI(u32 ra, u32 rs, u32 uimm16) override; void XORIS(u32 ra, u32 rs, u32 uimm16) override; void ANDI_(u32 ra, u32 rs, u32 uimm16) override; void ANDIS_(u32 ra, u32 rs, u32 uimm16) override; - void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) override; - void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) override; - void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) override; - void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) override; - void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) override; + void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) override; + void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, u32 rc) override; + void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) override; + void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) override; + void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, u32 is_r, u32 rc) override; void CMP(u32 crfd, u32 l, u32 ra, u32 rb) override; void TW(u32 to, u32 ra, u32 rb) override; void LVSL(u32 vd, u32 ra, u32 rb) override; void LVEBX(u32 vd, u32 ra, u32 rb) override; - void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; - void MULHDU(u32 rd, u32 ra, u32 rb, bool rc) override; - void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; - void MULHWU(u32 rd, u32 ra, u32 rb, bool rc) override; + void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; + void MULHDU(u32 rd, u32 ra, u32 rb, u32 rc) override; + void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; + void MULHWU(u32 rd, u32 ra, u32 rb, u32 rc) override; void MFOCRF(u32 a, u32 rd, u32 crm) override; void LWARX(u32 rd, u32 ra, u32 rb) override; void LDX(u32 ra, u32 rs, u32 rb) override; void LWZX(u32 rd, u32 ra, u32 rb) override; - void SLW(u32 ra, u32 rs, u32 rb, bool rc) override; - void CNTLZW(u32 ra, u32 rs, bool rc) override; - void SLD(u32 ra, u32 rs, u32 rb, bool rc) override; - void AND(u32 ra, u32 rs, u32 rb, bool rc) override; + void SLW(u32 ra, u32 rs, u32 rb, u32 rc) override; + void CNTLZW(u32 ra, u32 rs, u32 rc) override; + void SLD(u32 ra, u32 rs, u32 rb, u32 rc) override; + void AND(u32 ra, u32 rs, u32 rb, u32 rc) override; void CMPL(u32 bf, u32 l, u32 ra, u32 rb) override; void LVSR(u32 vd, u32 ra, u32 rb) override; void LVEHX(u32 vd, u32 ra, u32 rb) override; - void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; + void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; void LDUX(u32 rd, u32 ra, u32 rb) override; void DCBST(u32 ra, u32 rb) override; void LWZUX(u32 rd, u32 ra, u32 rb) override; - void CNTLZD(u32 ra, u32 rs, bool rc) override; - void ANDC(u32 ra, u32 rs, u32 rb, bool rc) override; + void CNTLZD(u32 ra, u32 rs, u32 rc) override; + void ANDC(u32 ra, u32 rs, u32 rb, u32 rc) override; void TD(u32 to, u32 ra, u32 rb) override; void LVEWX(u32 vd, u32 ra, u32 rb) override; - void MULHD(u32 rd, u32 ra, u32 rb, bool rc) override; - void MULHW(u32 rd, u32 ra, u32 rb, bool rc) override; + void MULHD(u32 rd, u32 ra, u32 rb, u32 rc) override; + void MULHW(u32 rd, u32 ra, u32 rb, u32 rc) override; void LDARX(u32 rd, u32 ra, u32 rb) override; void DCBF(u32 ra, u32 rb) override; void LBZX(u32 rd, u32 ra, u32 rb) override; void LVX(u32 vd, u32 ra, u32 rb) override; - void NEG(u32 rd, u32 ra, u32 oe, bool rc) override; + void NEG(u32 rd, u32 ra, u32 oe, u32 rc) override; void LBZUX(u32 rd, u32 ra, u32 rb) override; - void NOR(u32 ra, u32 rs, u32 rb, bool rc) override; + void NOR(u32 ra, u32 rs, u32 rb, u32 rc) override; void STVEBX(u32 vs, u32 ra, u32 rb) override; - void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; - void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; + void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; + void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; void MTOCRF(u32 l, u32 crm, u32 rs) override; void STDX(u32 rs, u32 ra, u32 rb) override; void STWCX_(u32 rs, u32 ra, u32 rb) override; @@ -547,24 +547,24 @@ namespace ppu_recompiler_llvm { void STDUX(u32 rs, u32 ra, u32 rb) override; void STWUX(u32 rs, u32 ra, u32 rb) override; void STVEWX(u32 vs, u32 ra, u32 rb) override; - void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) override; - void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) override; + void SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) override; + void ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) override; void STDCX_(u32 rs, u32 ra, u32 rb) override; void STBX(u32 rs, u32 ra, u32 rb) override; void STVX(u32 vs, u32 ra, u32 rb) override; - void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; - void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) override; - void ADDME(u32 rd, u32 ra, u32 oe, bool rc) override; - void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; + void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; + void SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) override; + void ADDME(u32 rd, u32 ra, u32 oe, u32 rc) override; + void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; void DCBTST(u32 ra, u32 rb, u32 th) override; void STBUX(u32 rs, u32 ra, u32 rb) override; - void ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; + void ADD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; void DCBT(u32 ra, u32 rb, u32 th) override; void LHZX(u32 rd, u32 ra, u32 rb) override; - void EQV(u32 ra, u32 rs, u32 rb, bool rc) override; + void EQV(u32 ra, u32 rs, u32 rb, u32 rc) override; void ECIWX(u32 rd, u32 ra, u32 rb) override; void LHZUX(u32 rd, u32 ra, u32 rb) override; - void XOR(u32 rs, u32 ra, u32 rb, bool rc) override; + void XOR(u32 rs, u32 ra, u32 rb, u32 rc) override; void MFSPR(u32 rd, u32 spr) override; void LWAX(u32 rd, u32 ra, u32 rb) override; void DST(u32 ra, u32 rb, u32 strm, u32 t) override; @@ -575,25 +575,25 @@ namespace ppu_recompiler_llvm { void DSTST(u32 ra, u32 rb, u32 strm, u32 t) override; void LHAUX(u32 rd, u32 ra, u32 rb) override; void STHX(u32 rs, u32 ra, u32 rb) override; - void ORC(u32 rs, u32 ra, u32 rb, bool rc) override; + void ORC(u32 rs, u32 ra, u32 rb, u32 rc) override; void ECOWX(u32 rs, u32 ra, u32 rb) override; void STHUX(u32 rs, u32 ra, u32 rb) override; - void OR(u32 ra, u32 rs, u32 rb, bool rc) override; - void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; - void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; + void OR(u32 ra, u32 rs, u32 rb, u32 rc) override; + void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; + void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; void MTSPR(u32 spr, u32 rs) override; void DCBI(u32 ra, u32 rb) override; - void NAND(u32 ra, u32 rs, u32 rb, bool rc) override; + void NAND(u32 ra, u32 rs, u32 rb, u32 rc) override; void STVXL(u32 vs, u32 ra, u32 rb) override; - void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; - void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) override; + void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; + void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) override; void LVLX(u32 vd, u32 ra, u32 rb) override; void LDBRX(u32 rd, u32 ra, u32 rb) override; void LSWX(u32 rd, u32 ra, u32 rb) override; void LWBRX(u32 rd, u32 ra, u32 rb) override; void LFSX(u32 frd, u32 ra, u32 rb) override; - void SRW(u32 ra, u32 rs, u32 rb, bool rc) override; - void SRD(u32 ra, u32 rs, u32 rb, bool rc) override; + void SRW(u32 ra, u32 rs, u32 rb, u32 rc) override; + void SRD(u32 ra, u32 rs, u32 rb, u32 rc) override; void LVRX(u32 vd, u32 ra, u32 rb) override; void LSWI(u32 rd, u32 ra, u32 nb) override; void LFSUX(u32 frd, u32 ra, u32 rb) override; @@ -612,21 +612,21 @@ namespace ppu_recompiler_llvm { void STFDUX(u32 frs, u32 ra, u32 rb) override; void LVLXL(u32 vd, u32 ra, u32 rb) override; void LHBRX(u32 rd, u32 ra, u32 rb) override; - void SRAW(u32 ra, u32 rs, u32 rb, bool rc) override; - void SRAD(u32 ra, u32 rs, u32 rb, bool rc) override; + void SRAW(u32 ra, u32 rs, u32 rb, u32 rc) override; + void SRAD(u32 ra, u32 rs, u32 rb, u32 rc) override; void LVRXL(u32 vd, u32 ra, u32 rb) override; void DSS(u32 strm, u32 a) override; - void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) override; - void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) override; - void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) override; + void SRAWI(u32 ra, u32 rs, u32 sh, u32 rc) override; + void SRADI1(u32 ra, u32 rs, u32 sh, u32 rc) override; + void SRADI2(u32 ra, u32 rs, u32 sh, u32 rc) override; void EIEIO() override; void STVLXL(u32 vs, u32 ra, u32 rb) override; void STHBRX(u32 rs, u32 ra, u32 rb) override; - void EXTSH(u32 ra, u32 rs, bool rc) override; + void EXTSH(u32 ra, u32 rs, u32 rc) override; void STVRXL(u32 sd, u32 ra, u32 rb) override; - void EXTSB(u32 ra, u32 rs, bool rc) override; + void EXTSB(u32 ra, u32 rs, u32 rc) override; void STFIWX(u32 frs, u32 ra, u32 rb) override; - void EXTSW(u32 ra, u32 rs, bool rc) override; + void EXTSW(u32 ra, u32 rs, u32 rc) override; void ICBI(u32 ra, u32 rb) override; void DCBZ(u32 ra, u32 rb) override; void LWZ(u32 rd, u32 ra, s32 d) override; @@ -656,48 +656,48 @@ namespace ppu_recompiler_llvm { void LD(u32 rd, u32 ra, s32 ds) override; void LDU(u32 rd, u32 ra, s32 ds) override; void LWA(u32 rd, u32 ra, s32 ds) override; - void FDIVS(u32 frd, u32 fra, u32 frb, bool rc) override; - void FSUBS(u32 frd, u32 fra, u32 frb, bool rc) override; - void FADDS(u32 frd, u32 fra, u32 frb, bool rc) override; - void FSQRTS(u32 frd, u32 frb, bool rc) override; - void FRES(u32 frd, u32 frb, bool rc) override; - void FMULS(u32 frd, u32 fra, u32 frc, bool rc) override; - void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; + void FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) override; + void FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) override; + void FADDS(u32 frd, u32 fra, u32 frb, u32 rc) override; + void FSQRTS(u32 frd, u32 frb, u32 rc) override; + void FRES(u32 frd, u32 frb, u32 rc) override; + void FMULS(u32 frd, u32 fra, u32 frc, u32 rc) override; + void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; void STD(u32 rs, u32 ra, s32 ds) override; void STDU(u32 rs, u32 ra, s32 ds) override; - void MTFSB1(u32 bt, bool rc) override; + void MTFSB1(u32 bt, u32 rc) override; void MCRFS(u32 bf, u32 bfa) override; - void MTFSB0(u32 bt, bool rc) override; - void MTFSFI(u32 crfd, u32 i, bool rc) override; - void MFFS(u32 frd, bool rc) override; - void MTFSF(u32 flm, u32 frb, bool rc) override; + void MTFSB0(u32 bt, u32 rc) override; + void MTFSFI(u32 crfd, u32 i, u32 rc) override; + void MFFS(u32 frd, u32 rc) override; + void MTFSF(u32 flm, u32 frb, u32 rc) override; void FCMPU(u32 bf, u32 fra, u32 frb) override; - void FRSP(u32 frd, u32 frb, bool rc) override; - void FCTIW(u32 frd, u32 frb, bool rc) override; - void FCTIWZ(u32 frd, u32 frb, bool rc) override; - void FDIV(u32 frd, u32 fra, u32 frb, bool rc) override; - void FSUB(u32 frd, u32 fra, u32 frb, bool rc) override; - void FADD(u32 frd, u32 fra, u32 frb, bool rc) override; - void FSQRT(u32 frd, u32 frb, bool rc) override; - void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FMUL(u32 frd, u32 fra, u32 frc, bool rc) override; - void FRSQRTE(u32 frd, u32 frb, bool rc) override; - void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; - void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) override; + void FRSP(u32 frd, u32 frb, u32 rc) override; + void FCTIW(u32 frd, u32 frb, u32 rc) override; + void FCTIWZ(u32 frd, u32 frb, u32 rc) override; + void FDIV(u32 frd, u32 fra, u32 frb, u32 rc) override; + void FSUB(u32 frd, u32 fra, u32 frb, u32 rc) override; + void FADD(u32 frd, u32 fra, u32 frb, u32 rc) override; + void FSQRT(u32 frd, u32 frb, u32 rc) override; + void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FMUL(u32 frd, u32 fra, u32 frc, u32 rc) override; + void FRSQRTE(u32 frd, u32 frb, u32 rc) override; + void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; + void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) override; void FCMPO(u32 crfd, u32 fra, u32 frb) override; - void FNEG(u32 frd, u32 frb, bool rc) override; - void FMR(u32 frd, u32 frb, bool rc) override; - void FNABS(u32 frd, u32 frb, bool rc) override; - void FABS(u32 frd, u32 frb, bool rc) override; - void FCTID(u32 frd, u32 frb, bool rc) override; - void FCTIDZ(u32 frd, u32 frb, bool rc) override; - void FCFID(u32 frd, u32 frb, bool rc) override; + void FNEG(u32 frd, u32 frb, u32 rc) override; + void FMR(u32 frd, u32 frb, u32 rc) override; + void FNABS(u32 frd, u32 frb, u32 rc) override; + void FABS(u32 frd, u32 frb, u32 rc) override; + void FCTID(u32 frd, u32 frb, u32 rc) override; + void FCTIDZ(u32 frd, u32 frb, u32 rc) override; + void FCFID(u32 frd, u32 frb, u32 rc) override; void UNK(const u32 code, const u32 opcode, const u32 gcode) override; @@ -948,9 +948,9 @@ namespace ppu_recompiler_llvm { static void InitRotateMask(); }; - class RecompilationEngine : public ThreadBase { + class RecompilationEngine final : protected thread_t { public: - virtual ~RecompilationEngine(); + virtual ~RecompilationEngine() override; /// Allocate an ordinal u32 AllocateOrdinal(u32 address, bool is_function); @@ -970,7 +970,7 @@ namespace ppu_recompiler_llvm { /// Log llvm::raw_fd_ostream & Log(); - void Task() override; + void Task(); /// Get a pointer to the instance of this class static std::shared_ptr GetInstance(); diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index c23669d3bf..185f22905b 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -664,59 +664,59 @@ public: virtual void CRORC(u32 bt, u32 ba, u32 bb) = 0; virtual void CROR(u32 bt, u32 ba, u32 bb) = 0; virtual void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) = 0; - virtual void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) = 0; - virtual void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) = 0; - virtual void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, bool rc) = 0; + virtual void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) = 0; + virtual void RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, u32 rc) = 0; + virtual void RLWNM(u32 ra, u32 rs, u32 rb, u32 MB, u32 ME, u32 rc) = 0; virtual void ORI(u32 rs, u32 ra, u32 uimm16) = 0; virtual void ORIS(u32 rs, u32 ra, u32 uimm16) = 0; virtual void XORI(u32 ra, u32 rs, u32 uimm16) = 0; virtual void XORIS(u32 ra, u32 rs, u32 uimm16) = 0; virtual void ANDI_(u32 ra, u32 rs, u32 uimm16) = 0; virtual void ANDIS_(u32 ra, u32 rs, u32 uimm16) = 0; - virtual void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) = 0; - virtual void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) = 0; - virtual void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) = 0; - virtual void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) = 0; - virtual void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) = 0; + virtual void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) = 0; + virtual void RLDICR(u32 ra, u32 rs, u32 sh, u32 me, u32 rc) = 0; + virtual void RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) = 0; + virtual void RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 rc) = 0; + virtual void RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, u32 is_r, u32 rc) = 0; virtual void CMP(u32 crfd, u32 l, u32 ra, u32 rb) = 0; virtual void TW(u32 to, u32 ra, u32 rb) = 0; virtual void LVSL(u32 vd, u32 ra, u32 rb) = 0; virtual void LVEBX(u32 vd, u32 ra, u32 rb) = 0; - virtual void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; - virtual void MULHDU(u32 rd, u32 ra, u32 rb, bool rc) = 0; - virtual void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; - virtual void MULHWU(u32 rd, u32 ra, u32 rb, bool rc) = 0; + virtual void SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; + virtual void MULHDU(u32 rd, u32 ra, u32 rb, u32 rc) = 0; + virtual void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; + virtual void MULHWU(u32 rd, u32 ra, u32 rb, u32 rc) = 0; virtual void MFOCRF(u32 a, u32 rd, u32 crm) = 0; virtual void LWARX(u32 rd, u32 ra, u32 rb) = 0; virtual void LDX(u32 ra, u32 rs, u32 rb) = 0; virtual void LWZX(u32 rd, u32 ra, u32 rb) = 0; - virtual void SLW(u32 ra, u32 rs, u32 rb, bool rc) = 0; - virtual void CNTLZW(u32 ra, u32 rs, bool rc) = 0; - virtual void SLD(u32 ra, u32 rs, u32 rb, bool rc) = 0; - virtual void AND(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void SLW(u32 ra, u32 rs, u32 rb, u32 rc) = 0; + virtual void CNTLZW(u32 ra, u32 rs, u32 rc) = 0; + virtual void SLD(u32 ra, u32 rs, u32 rb, u32 rc) = 0; + virtual void AND(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void CMPL(u32 bf, u32 l, u32 ra, u32 rb) = 0; virtual void LVSR(u32 vd, u32 ra, u32 rb) = 0; virtual void LVEHX(u32 vd, u32 ra, u32 rb) = 0; - virtual void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void SUBF(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; virtual void LDUX(u32 rd, u32 ra, u32 rb) = 0; virtual void DCBST(u32 ra, u32 rb) = 0; virtual void LWZUX(u32 rd, u32 ra, u32 rb) = 0; - virtual void CNTLZD(u32 ra, u32 rs, bool rc) = 0; - virtual void ANDC(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void CNTLZD(u32 ra, u32 rs, u32 rc) = 0; + virtual void ANDC(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void TD(u32 to, u32 ra, u32 rb) = 0; virtual void LVEWX(u32 vd, u32 ra, u32 rb) = 0; - virtual void MULHD(u32 rd, u32 ra, u32 rb, bool rc) = 0; - virtual void MULHW(u32 rd, u32 ra, u32 rb, bool rc) = 0; + virtual void MULHD(u32 rd, u32 ra, u32 rb, u32 rc) = 0; + virtual void MULHW(u32 rd, u32 ra, u32 rb, u32 rc) = 0; virtual void LDARX(u32 rd, u32 ra, u32 rb) = 0; virtual void DCBF(u32 ra, u32 rb) = 0; virtual void LBZX(u32 rd, u32 ra, u32 rb) = 0; virtual void LVX(u32 vd, u32 ra, u32 rb) = 0; - virtual void NEG(u32 rd, u32 ra, u32 oe, bool rc) = 0; + virtual void NEG(u32 rd, u32 ra, u32 oe, u32 rc) = 0; virtual void LBZUX(u32 rd, u32 ra, u32 rb) = 0; - virtual void NOR(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void NOR(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void STVEBX(u32 vs, u32 ra, u32 rb) = 0; - virtual void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; - virtual void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; + virtual void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; virtual void MTOCRF(u32 l, u32 crm, u32 rs) = 0; virtual void STDX(u32 rs, u32 ra, u32 rb) = 0; virtual void STWCX_(u32 rs, u32 ra, u32 rb) = 0; @@ -725,24 +725,24 @@ public: virtual void STDUX(u32 rs, u32 ra, u32 rb) = 0; virtual void STWUX(u32 rs, u32 ra, u32 rb) = 0; virtual void STVEWX(u32 vs, u32 ra, u32 rb) = 0; - virtual void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) = 0; - virtual void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) = 0; + virtual void SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) = 0; + virtual void ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) = 0; virtual void STDCX_(u32 rs, u32 ra, u32 rb) = 0; virtual void STBX(u32 rs, u32 ra, u32 rb) = 0; virtual void STVX(u32 vs, u32 ra, u32 rb) = 0; - virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; - virtual void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) = 0; - virtual void ADDME(u32 rd, u32 ra, u32 oe, bool rc) = 0; - virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; + virtual void SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) = 0; + virtual void ADDME(u32 rd, u32 ra, u32 oe, u32 rc) = 0; + virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; virtual void DCBTST(u32 ra, u32 rb, u32 th) = 0; virtual void STBUX(u32 rs, u32 ra, u32 rb) = 0; - virtual void ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void ADD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; virtual void DCBT(u32 ra, u32 rb, u32 th) = 0; virtual void LHZX(u32 rd, u32 ra, u32 rb) = 0; - virtual void EQV(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void EQV(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void ECIWX(u32 rd, u32 ra, u32 rb) = 0; virtual void LHZUX(u32 rd, u32 ra, u32 rb) = 0; - virtual void XOR(u32 rs, u32 ra, u32 rb, bool rc) = 0; + virtual void XOR(u32 rs, u32 ra, u32 rb, u32 rc) = 0; virtual void MFSPR(u32 rd, u32 spr) = 0; virtual void LWAX(u32 rd, u32 ra, u32 rb) = 0; virtual void DST(u32 ra, u32 rb, u32 strm, u32 t) = 0; @@ -753,25 +753,25 @@ public: virtual void DSTST(u32 ra, u32 rb, u32 strm, u32 t) = 0; virtual void LHAUX(u32 rd, u32 ra, u32 rb) = 0; virtual void STHX(u32 rs, u32 ra, u32 rb) = 0; - virtual void ORC(u32 rs, u32 ra, u32 rb, bool rc) = 0; + virtual void ORC(u32 rs, u32 ra, u32 rb, u32 rc) = 0; virtual void ECOWX(u32 rs, u32 ra, u32 rb) = 0; virtual void STHUX(u32 rs, u32 ra, u32 rb) = 0; - virtual void OR(u32 ra, u32 rs, u32 rb, bool rc) = 0; - virtual void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; - virtual void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void OR(u32 ra, u32 rs, u32 rb, u32 rc) = 0; + virtual void DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; + virtual void DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; virtual void MTSPR(u32 spr, u32 rs) = 0; virtual void DCBI(u32 ra, u32 rb) = 0; - virtual void NAND(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void NAND(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void STVXL(u32 vs, u32 ra, u32 rb) = 0; - virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; - virtual void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; + virtual void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) = 0; virtual void LVLX(u32 vd, u32 ra, u32 rb) = 0; virtual void LDBRX(u32 rd, u32 ra, u32 rb) = 0; virtual void LSWX(u32 rd, u32 ra, u32 rb) = 0; virtual void LWBRX(u32 rd, u32 ra, u32 rb) = 0; virtual void LFSX(u32 frd, u32 ra, u32 rb) = 0; - virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) = 0; - virtual void SRD(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void SRW(u32 ra, u32 rs, u32 rb, u32 rc) = 0; + virtual void SRD(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void LVRX(u32 vd, u32 ra, u32 rb) = 0; virtual void LSWI(u32 rd, u32 ra, u32 nb) = 0; virtual void LFSUX(u32 frd, u32 ra, u32 rb) = 0; @@ -790,21 +790,21 @@ public: virtual void STFDUX(u32 frs, u32 ra, u32 rb) = 0; virtual void LVLXL(u32 vd, u32 ra, u32 rb) = 0; virtual void LHBRX(u32 rd, u32 ra, u32 rb) = 0; - virtual void SRAW(u32 ra, u32 rs, u32 rb, bool rc) = 0; - virtual void SRAD(u32 ra, u32 rs, u32 rb, bool rc) = 0; + virtual void SRAW(u32 ra, u32 rs, u32 rb, u32 rc) = 0; + virtual void SRAD(u32 ra, u32 rs, u32 rb, u32 rc) = 0; virtual void LVRXL(u32 vd, u32 ra, u32 rb) = 0; virtual void DSS(u32 strm, u32 a) = 0; - virtual void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) = 0; - virtual void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) = 0; - virtual void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) = 0; + virtual void SRAWI(u32 ra, u32 rs, u32 sh, u32 rc) = 0; + virtual void SRADI1(u32 ra, u32 rs, u32 sh, u32 rc) = 0; + virtual void SRADI2(u32 ra, u32 rs, u32 sh, u32 rc) = 0; virtual void EIEIO() = 0; virtual void STVLXL(u32 vs, u32 ra, u32 rb) = 0; virtual void STHBRX(u32 rs, u32 ra, u32 rb) = 0; - virtual void EXTSH(u32 ra, u32 rs, bool rc) = 0; + virtual void EXTSH(u32 ra, u32 rs, u32 rc) = 0; virtual void STVRXL(u32 sd, u32 ra, u32 rb) = 0; - virtual void EXTSB(u32 ra, u32 rs, bool rc) = 0; + virtual void EXTSB(u32 ra, u32 rs, u32 rc) = 0; virtual void STFIWX(u32 frs, u32 ra, u32 rb) = 0; - virtual void EXTSW(u32 ra, u32 rs, bool rc) = 0; + virtual void EXTSW(u32 ra, u32 rs, u32 rc) = 0; virtual void ICBI(u32 ra, u32 rb) = 0; virtual void DCBZ(u32 ra, u32 rb) = 0; virtual void LWZ(u32 rd, u32 ra, s32 d) = 0; @@ -834,48 +834,48 @@ public: virtual void LD(u32 rd, u32 ra, s32 ds) = 0; virtual void LDU(u32 rd, u32 ra, s32 ds) = 0; virtual void LWA(u32 rd, u32 ra, s32 ds) = 0; - virtual void FDIVS(u32 frd, u32 fra, u32 frb, bool rc) = 0; - virtual void FSUBS(u32 frd, u32 fra, u32 frb, bool rc) = 0; - virtual void FADDS(u32 frd, u32 fra, u32 frb, bool rc) = 0; - virtual void FSQRTS(u32 frd, u32 frb, bool rc) = 0; - virtual void FRES(u32 frd, u32 frb, bool rc) = 0; - virtual void FMULS(u32 frd, u32 fra, u32 frc, bool rc) = 0; - virtual void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; + virtual void FDIVS(u32 frd, u32 fra, u32 frb, u32 rc) = 0; + virtual void FSUBS(u32 frd, u32 fra, u32 frb, u32 rc) = 0; + virtual void FADDS(u32 frd, u32 fra, u32 frb, u32 rc) = 0; + virtual void FSQRTS(u32 frd, u32 frb, u32 rc) = 0; + virtual void FRES(u32 frd, u32 frb, u32 rc) = 0; + virtual void FMULS(u32 frd, u32 fra, u32 frc, u32 rc) = 0; + virtual void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; virtual void STD(u32 rs, u32 ra, s32 ds) = 0; virtual void STDU(u32 rs, u32 ra, s32 ds) = 0; - virtual void MTFSB1(u32 bt, bool rc) = 0; + virtual void MTFSB1(u32 bt, u32 rc) = 0; virtual void MCRFS(u32 bf, u32 bfa) = 0; - virtual void MTFSB0(u32 bt, bool rc) = 0; - virtual void MTFSFI(u32 crfd, u32 i, bool rc) = 0; - virtual void MFFS(u32 frd, bool rc) = 0; - virtual void MTFSF(u32 flm, u32 frb, bool rc) = 0; + virtual void MTFSB0(u32 bt, u32 rc) = 0; + virtual void MTFSFI(u32 crfd, u32 i, u32 rc) = 0; + virtual void MFFS(u32 frd, u32 rc) = 0; + virtual void MTFSF(u32 flm, u32 frb, u32 rc) = 0; virtual void FCMPU(u32 bf, u32 fra, u32 frb) = 0; - virtual void FRSP(u32 frd, u32 frb, bool rc) = 0; - virtual void FCTIW(u32 frd, u32 frb, bool rc) = 0; - virtual void FCTIWZ(u32 frd, u32 frb, bool rc) = 0; - virtual void FDIV(u32 frd, u32 fra, u32 frb, bool rc) = 0; - virtual void FSUB(u32 frd, u32 fra, u32 frb, bool rc) = 0; - virtual void FADD(u32 frd, u32 fra, u32 frb, bool rc) = 0; - virtual void FSQRT(u32 frd, u32 frb, bool rc) = 0; - virtual void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FMUL(u32 frd, u32 fra, u32 frc, bool rc) = 0; - virtual void FRSQRTE(u32 frd, u32 frb, bool rc) = 0; - virtual void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; - virtual void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) = 0; + virtual void FRSP(u32 frd, u32 frb, u32 rc) = 0; + virtual void FCTIW(u32 frd, u32 frb, u32 rc) = 0; + virtual void FCTIWZ(u32 frd, u32 frb, u32 rc) = 0; + virtual void FDIV(u32 frd, u32 fra, u32 frb, u32 rc) = 0; + virtual void FSUB(u32 frd, u32 fra, u32 frb, u32 rc) = 0; + virtual void FADD(u32 frd, u32 fra, u32 frb, u32 rc) = 0; + virtual void FSQRT(u32 frd, u32 frb, u32 rc) = 0; + virtual void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FMUL(u32 frd, u32 fra, u32 frc, u32 rc) = 0; + virtual void FRSQRTE(u32 frd, u32 frb, u32 rc) = 0; + virtual void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; + virtual void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) = 0; virtual void FCMPO(u32 crfd, u32 fra, u32 frb) = 0; - virtual void FNEG(u32 frd, u32 frb, bool rc) = 0; - virtual void FMR(u32 frd, u32 frb, bool rc) = 0; - virtual void FNABS(u32 frd, u32 frb, bool rc) = 0; - virtual void FABS(u32 frd, u32 frb, bool rc) = 0; - virtual void FCTID(u32 frd, u32 frb, bool rc) = 0; - virtual void FCTIDZ(u32 frd, u32 frb, bool rc) = 0; - virtual void FCFID(u32 frd, u32 frb, bool rc) = 0; + virtual void FNEG(u32 frd, u32 frb, u32 rc) = 0; + virtual void FMR(u32 frd, u32 frb, u32 rc) = 0; + virtual void FNABS(u32 frd, u32 frb, u32 rc) = 0; + virtual void FABS(u32 frd, u32 frb, u32 rc) = 0; + virtual void FCTID(u32 frd, u32 frb, u32 rc) = 0; + virtual void FCTIDZ(u32 frd, u32 frb, u32 rc) = 0; + virtual void FCFID(u32 frd, u32 frb, u32 rc) = 0; virtual void UNK(const u32 code, const u32 opcode, const u32 gcode) = 0; }; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index d7945fd2f9..d966331c76 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3,6 +3,7 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/Modules.h" @@ -11,7 +12,6 @@ #include "Emu/Cell/PPUInterpreter2.h" #include "Emu/Cell/PPULLVMRecompiler.h" //#include "Emu/Cell/PPURecompiler.h" -#include "Emu/CPU/CPUThreadManager.h" #ifdef _WIN32 #include @@ -489,56 +489,45 @@ void fill_ppu_exec_map(u32 addr, u32 size) } } -PPUThread& GetCurrentPPUThread() +PPUThread::PPUThread(const std::string& name) + : CPUThread(CPU_THREAD_PPU, name, WRAP_EXPR(fmt::format("PPU[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC))) { - CPUThread* thread = GetCurrentCPUThread(); - - if(!thread || thread->GetType() != CPU_THREAD_PPU) throw std::string("GetCurrentPPUThread: bad thread"); - - return *(PPUThread*)thread; -} - -PPUThread::PPUThread() : CPUThread(CPU_THREAD_PPU) -{ - Reset(); InitRotateMask(); } PPUThread::~PPUThread() { - ppu_free_tls(GetId()); + if (is_current()) + { + detach(); + } + else + { + join(); + } + + CloseStack(); + ppu_free_tls(m_id); } -void PPUThread::DoReset() +void PPUThread::DumpInformation() const { - //reset regs - memset(VPR, 0, sizeof(VPR)); - memset(FPR, 0, sizeof(FPR)); - memset(GPR, 0, sizeof(GPR)); - memset(SPRG, 0, sizeof(SPRG)); + if (~hle_code < 1024) + { + LOG_SUCCESS(HLE, "Last syscall: %lld (%s)", ~hle_code, SysCalls::GetFuncName(hle_code)); + } + else if (hle_code) + { + LOG_SUCCESS(HLE, "Last function: %s (0x%llx)", SysCalls::GetFuncName(hle_code), hle_code); + } - CR.CR = 0; - LR = 0; - CTR = 0; - TB = 0; - XER.XER = 0; - FPSCR.FPSCR = 0; - VSCR.VSCR = 0; - VRSAVE = 0; + CPUThread::DumpInformation(); } void PPUThread::InitRegs() { - const u32 pc = entry ? vm::read32(entry) : 0; - const u32 rtoc = entry ? vm::read32(entry + 4) : 0; - - SetPc(pc); - - GPR[1] = align(m_stack_addr + m_stack_size, 0x200) - 0x200; - GPR[2] = rtoc; - //GPR[11] = entry; - //GPR[12] = Emu.GetMallocPageSize(); - GPR[13] = ppu_get_tls(GetId()) + 0x7000; // 0x7000 is usually subtracted from r13 to access first TLS element (details are not clear) + GPR[1] = align(stack_addr + stack_size, 0x200) - 0x200; + GPR[13] = ppu_get_tls(m_id) + 0x7000; // 0x7000 is subtracted from r13 to access first TLS element LR = 0; CTR = PC; @@ -549,32 +538,40 @@ void PPUThread::InitRegs() void PPUThread::InitStack() { - if (!m_stack_addr) + if (!stack_addr) { - assert(m_stack_size); - m_stack_addr = Memory.StackMem.AllocAlign(m_stack_size, 4096); + if (!stack_size) + { + throw EXCEPTION("Invalid stack size"); + } + + stack_addr = Memory.StackMem.AllocAlign(stack_size, 4096); + + if (!stack_addr) + { + throw EXCEPTION("Out of stack memory"); + } } } void PPUThread::CloseStack() { - if (m_stack_addr) + if (stack_addr) { - Memory.StackMem.Free(m_stack_addr); - m_stack_addr = 0; + Memory.StackMem.Free(stack_addr); + stack_addr = 0; } } void PPUThread::DoRun() { - m_dec = nullptr; + m_dec.reset(); switch (auto mode = Ini.CPUDecoderMode.GetValue()) { case 0: // original interpreter { - auto ppui = new PPUInterpreter(*this); - m_dec = new PPUDecoder(ppui); + m_dec.reset(new PPUDecoder(new PPUInterpreter(*this))); break; } @@ -584,18 +581,17 @@ void PPUThread::DoRun() } case 2: + { #ifdef PPU_LLVM_RECOMPILER - SetCallStackTracing(false); - if (!m_dec) { - m_dec = new ppu_recompiler_llvm::ExecutionEngine(*this); - } + m_dec.reset(new ppu_recompiler_llvm::ExecutionEngine(*this)); #else LOG_ERROR(PPU, "This image does not include PPU JIT (LLVM)"); Emu.Pause(); #endif - break; + break; + } - //case 3: m_dec = new PPURecompiler(*this); break; + //case 3: m_dec.reset(new PPURecompiler(*this)); break; default: { @@ -605,20 +601,6 @@ void PPUThread::DoRun() } } -void PPUThread::DoResume() -{ -} - -void PPUThread::DoPause() -{ -} - -void PPUThread::DoStop() -{ - delete m_dec; - m_dec = nullptr; -} - bool FPRdouble::IsINF(PPCdouble d) { return ((u64&)d & 0x7FFFFFFFFFFFFFFFULL) == 0x7FF0000000000000ULL; @@ -656,47 +638,52 @@ int FPRdouble::Cmp(PPCdouble a, PPCdouble b) u64 PPUThread::GetStackArg(s32 i) { - return vm::read64(vm::cast(GPR[1] + 0x70 + 0x8 * (i - 9))); + return vm::read64(VM_CAST(GPR[1] + 0x70 + 0x8 * (i - 9))); } void PPUThread::FastCall2(u32 addr, u32 rtoc) { - auto old_status = m_status; + if (!is_current()) + { + throw EXCEPTION("Called from the wrong thread"); + } + auto old_PC = PC; auto old_stack = GPR[1]; auto old_rtoc = GPR[2]; auto old_LR = LR; - auto old_thread = GetCurrentNamedThread(); auto old_task = decltype(custom_task)(); - m_status = Running; PC = addr; GPR[2] = rtoc; LR = Emu.GetCPUThreadStop(); - SetCurrentNamedThread(this); custom_task.swap(old_task); - Task(); + try + { + Task(); + } + catch (CPUThreadReturn) + { + } + + m_state &= ~CPU_STATE_RETURN; - m_status = old_status; PC = old_PC; - if (GPR[1] != old_stack && !Emu.IsStopped()) // GPR[1] shouldn't change + if (GPR[1] != old_stack) // GPR[1] shouldn't change { - LOG_ERROR(PPU, "PPUThread::FastCall2(0x%x,0x%x): stack inconsistency (SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack); - GPR[1] = old_stack; + throw EXCEPTION("Stack inconsistency (addr=0x%x, rtoc=0x%x, SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack); } GPR[2] = old_rtoc; LR = old_LR; - SetCurrentNamedThread(old_thread); custom_task.swap(old_task); } void PPUThread::FastStop() { - m_status = Stopped; - m_events |= CPU_EVENT_STOP; + m_state |= CPU_STATE_RETURN; } void PPUThread::Task() @@ -705,54 +692,59 @@ void PPUThread::Task() if (custom_task) { + if (CheckStatus()) return; + return custom_task(*this); } if (m_dec) { - return CPUThread::Task(); - } - - while (true) - { - // get interpreter function - const auto func = g_ppu_inter_func_list[*(u32*)((u8*)g_ppu_exec_map + PC)]; - - if (m_events) + while (true) { - // process events - if (Emu.IsStopped()) - { - return; - } + if (m_state.load() && CheckStatus()) break; - if (m_events & CPU_EVENT_STOP && (IsStopped() || IsPaused())) - { - m_events &= ~CPU_EVENT_STOP; - return; - } + // decode instruction using specified decoder + m_dec->DecodeMemory(PC); + + // next instruction + PC += 4; } + } + else + { + while (true) + { + if (m_state.load() && CheckStatus()) break; - // read opcode - const ppu_opcode_t opcode = { vm::read32(PC) }; + // get interpreter function + const auto func = g_ppu_inter_func_list[*(u32*)((u8*)g_ppu_exec_map + PC)]; - // call interpreter function - func(*this, opcode); + // read opcode + const ppu_opcode_t opcode = { vm::read32(PC) }; - // next instruction - //PC += 4; - NextPc(4); + // call interpreter function + func(*this, opcode); + + // next instruction + PC += 4; + } } } -ppu_thread::ppu_thread(u32 entry, const std::string& name, u32 stack_size, u32 prio) +ppu_thread::ppu_thread(u32 entry, const std::string& name, u32 stack_size, s32 prio) { - thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + auto ppu = Emu.GetIdManager().make_ptr(name); - thread->SetName(name); - thread->SetEntry(entry); - thread->SetStackSize(stack_size ? stack_size : Emu.GetInfo().GetProcParam().primary_stacksize); - thread->SetPrio(prio ? prio : Emu.GetInfo().GetProcParam().primary_prio); + if (entry) + { + ppu->PC = vm::read32(entry); + ppu->GPR[2] = vm::read32(entry + 4); // rtoc + } + + ppu->stack_size = stack_size ? stack_size : Emu.GetPrimaryStackSize(); + ppu->prio = prio ? prio : Emu.GetPrimaryPrio(); + + thread = std::move(ppu); argc = 0; } @@ -764,16 +756,16 @@ cpu_thread& ppu_thread::args(std::initializer_list values) assert(argc == 0); - envp.set(vm::alloc(align((u32)sizeof(*envp), stack_align), vm::main)); + envp.set(vm::alloc(align(sizeof32(*envp), stack_align), vm::main)); *envp = 0; - argv.set(vm::alloc(sizeof(*argv) * values.size(), vm::main)); + argv.set(vm::alloc(sizeof32(*argv) * (u32)values.size(), vm::main)); for (auto &arg : values) { - u32 arg_size = align(u32(arg.size() + 1), stack_align); - u32 arg_addr = vm::alloc(arg_size, vm::main); + const u32 arg_size = align(u32(arg.size() + 1), stack_align); + const u32 arg_addr = vm::alloc(arg_size, vm::main); - std::strcpy(vm::get_ptr(arg_addr), arg.c_str()); + std::memcpy(vm::get_ptr(arg_addr), arg.c_str(), arg.size() + 1); argv[argc++] = arg_addr; } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 4a5ced3483..59a96297ba 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -1,4 +1,5 @@ #pragma once + #include "Emu/Cell/Common.h" #include "Emu/CPU/CPUThread.h" #include "Emu/Memory/vm.h" @@ -18,18 +19,6 @@ enum CR_SO = 0x1, }; -enum -{ - PPU_THREAD_STATUS_IDLE = (1 << 0), - PPU_THREAD_STATUS_RUNNABLE = (1 << 1), - PPU_THREAD_STATUS_ONPROC = (1 << 2), - PPU_THREAD_STATUS_SLEEP = (1 << 3), - PPU_THREAD_STATUS_STOP = (1 << 4), - PPU_THREAD_STATUS_ZOMBIE = (1 << 5), - PPU_THREAD_STATUS_DELETED = (1 << 6), - PPU_THREAD_STATUS_UNKNOWN = (1 << 7), -}; - enum FPSCR_EXP { FPSCR_FX = 0x80000000, @@ -363,7 +352,7 @@ struct PPCdouble case _FPCLASS_PD: return FPR_PD; case _FPCLASS_PN: return FPR_PN; case _FPCLASS_PINF: return FPR_PINF; - default: throw fmt::Format("PPCdouble::UpdateType() -> unknown fpclass (0x%04x).", fpc); + default: throw EXCEPTION("Unknown fpclass (0x%04x)", fpc); } #else switch (fpc) @@ -467,16 +456,16 @@ struct FPRdouble static int Cmp(PPCdouble a, PPCdouble b); }; -class PPUThread : public CPUThread +class PPUThread final : public CPUThread { public: - PPCdouble FPR[32]; //Floating Point Register - FPSCRhdr FPSCR; //Floating Point Status and Control Register - u64 GPR[32]; //General-Purpose Register - u128 VPR[32]; - u32 vpcr; + PPCdouble FPR[32]{}; //Floating Point Register + FPSCRhdr FPSCR{}; //Floating Point Status and Control Register + u64 GPR[32]{}; //General-Purpose Register + u128 VPR[32]{}; + u32 vpcr = 0; - CRhdr CR; //Condition Register + CRhdr CR{}; //Condition Register //CR0 // 0 : LT - Negative (is negative) // : 0 - Result is not negative @@ -507,7 +496,7 @@ public: //SPR : Special-Purpose Registers - XERhdr XER; //SPR 0x001 : Fixed-Point Expection Register + XERhdr XER{}; //SPR 0x001 : Fixed-Point Expection Register // 0 : SO - Summary overflow // : 0 - No overflow occurred // : 1 - Overflow occurred @@ -521,26 +510,45 @@ public: // 25 - 31 : TBC // Transfer-byte count - MSRhdr MSR; //Machine State Register - PVRhdr PVR; //Processor Version Register + MSRhdr MSR{}; //Machine State Register + PVRhdr PVR{}; //Processor Version Register - VSCRhdr VSCR; // Vector Status and Control Register + VSCRhdr VSCR{}; // Vector Status and Control Register - u64 LR; //SPR 0x008 : Link Register - u64 CTR; //SPR 0x009 : Count Register + u64 LR = 0; //SPR 0x008 : Link Register + u64 CTR = 0; //SPR 0x009 : Count Register - u32 VRSAVE; //SPR 0x100: VR Save/Restore Register (32 bits) + u32 VRSAVE = 0; //SPR 0x100: VR Save/Restore Register (32 bits) - u64 SPRG[8]; //SPR 0x110 - 0x117 : SPR General-Purpose Registers + u64 SPRG[8]{}; //SPR 0x110 - 0x117 : SPR General-Purpose Registers //TBR : Time-Base Registers - u64 TB; //TBR 0x10C - 0x10D + u64 TB = 0; //TBR 0x10C - 0x10D + + u32 PC = 0; + s32 prio = 0; // thread priority + u32 stack_addr = 0; // stack address + u32 stack_size = 0; // stack size + bool is_joinable = true; + bool is_joining = false; + + u64 hle_code = 0; // current syscall (~0..~1023) or function id (1..UINT32_MAX) std::function custom_task; public: - PPUThread(); - virtual ~PPUThread(); + PPUThread(const std::string& name); + virtual ~PPUThread() override; + + virtual void DumpInformation() const override; + virtual u32 GetPC() const override { return PC; } + virtual u32 GetOffset() const override { return 0; } + virtual void DoRun() override; + virtual void Task() override; + + virtual void InitRegs() override; + virtual void InitStack() override; + virtual void CloseStack() override; inline u8 GetCR(const u8 n) const { @@ -693,7 +701,7 @@ public: FPSCR.FI = val; } - virtual std::string RegsToString() + virtual std::string RegsToString() const { std::string ret = "Registers:\n=========\n"; @@ -721,7 +729,7 @@ public: return ret; } - virtual std::string ReadRegString(const std::string& reg) + virtual std::string ReadRegString(const std::string& reg) const { std::string::size_type first_brk = reg.find('['); if (first_brk != std::string::npos) @@ -807,33 +815,20 @@ public: } public: - virtual void InitRegs() override; - virtual void InitStack() override; - virtual void CloseStack() override; - virtual void Task() override; u64 GetStackArg(s32 i); void FastCall2(u32 addr, u32 rtoc); void FastStop(); - virtual void DoRun() override; - -protected: - virtual void DoReset() override; - virtual void DoPause() override; - virtual void DoResume() override; - virtual void DoStop() override; }; -PPUThread& GetCurrentPPUThread(); - class ppu_thread : cpu_thread { static const u32 stack_align = 0x10; - vm::ptr argv; + vm::_ptr_base> argv; u32 argc; - vm::ptr envp; + vm::_ptr_base> envp; public: - ppu_thread(u32 entry, const std::string& name = "", u32 stack_size = 0, u32 prio = 0); + ppu_thread(u32 entry, const std::string& name = "", u32 stack_size = 0, s32 prio = 0); cpu_thread& args(std::initializer_list values) override; cpu_thread& run() override; diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 52c0442956..4dcd291081 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -8,39 +8,37 @@ thread_local spu_mfc_arg_t raw_spu_mfc[8] = {}; -RawSPUThread::RawSPUThread(CPUThreadType type) - : SPUThread(type) +RawSPUThread::RawSPUThread(const std::string& name, u32 index) + : SPUThread(CPU_THREAD_RAW_SPU, name, COPY_EXPR(fmt::format("RawSPU_%d[0x%x] Thread (%s)[0x%08x]", index, GetId(), GetName(), PC)), index, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index) { + vm::page_map(offset, 0x40000, vm::page_readable | vm::page_writable); } RawSPUThread::~RawSPUThread() { + join(); + + vm::page_unmap(offset, 0x40000); } void RawSPUThread::start() { - bool do_start; - - status.atomic_op([&do_start](u32& status) + const bool do_start = status.atomic_op([](u32& status) -> bool { if (status & SPU_STATUS_RUNNING) { - do_start = false; + return false; } else { status = SPU_STATUS_RUNNING; - do_start = true; + return true; } }); if (do_start) { - // starting thread directly in SIGSEGV handler may cause problems - Emu.GetCallbackManager().Async([this](PPUThread& PPU) - { - FastRun(); - }); + Exec(); } } @@ -76,7 +74,7 @@ bool RawSPUThread::ReadReg(const u32 addr, u32& value) case SPU_Status_offs: { - value = status.read_relaxed(); + value = status.load(); return true; } } @@ -166,6 +164,7 @@ bool RawSPUThread::WriteReg(const u32 addr, const u32 value) case SPU_In_MBox_offs: { ch_in_mbox.push_uncond(value); + cv.notify_one(); return true; } @@ -178,14 +177,14 @@ bool RawSPUThread::WriteReg(const u32 addr, const u32 value) else if (value == SPU_RUNCNTL_STOP_REQUEST) { status &= ~SPU_STATUS_RUNNING; - FastStop(); + Stop(); } else { break; } - run_ctrl.write_relaxed(value); + run_ctrl.store(value); return true; } @@ -196,7 +195,7 @@ bool RawSPUThread::WriteReg(const u32 addr, const u32 value) break; } - npc.write_relaxed(value); + npc.store(value); return true; } @@ -223,5 +222,5 @@ void RawSPUThread::Task() SPUThread::Task(); - npc.write_relaxed(PC | 1); + npc.store(PC | 1); } diff --git a/rpcs3/Emu/Cell/RawSPUThread.h b/rpcs3/Emu/Cell/RawSPUThread.h index f4186ae4ed..dd41a9ef0c 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.h +++ b/rpcs3/Emu/Cell/RawSPUThread.h @@ -14,10 +14,10 @@ force_inline static u32 GetRawSPURegAddrByNum(int num, int offset) return RAW_SPU_OFFSET * num + RAW_SPU_BASE_ADDR + RAW_SPU_PROB_OFFSET + offset; } -class RawSPUThread : public SPUThread +class RawSPUThread final : public SPUThread { public: - RawSPUThread(CPUThreadType type = CPU_THREAD_RAW_SPU); + RawSPUThread(const std::string& name, u32 index); virtual ~RawSPUThread(); void start(); @@ -28,5 +28,3 @@ public: private: virtual void Task(); }; - -SPUThread& GetCurrentSPUThread(); diff --git a/rpcs3/Emu/Cell/SPUContext.h b/rpcs3/Emu/Cell/SPUContext.h index 93a2464038..2088497285 100644 --- a/rpcs3/Emu/Cell/SPUContext.h +++ b/rpcs3/Emu/Cell/SPUContext.h @@ -1,10 +1,6 @@ #pragma once -class SPUThread; - struct SPUContext { u128 gpr[128]; - - SPUThread& thread; }; diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index 40ae80fdde..b498573b1b 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -274,12 +274,12 @@ void spu_interpreter::BIZ(SPUThread& CPU, spu_opcode_t op) { if (op.d || op.e) { - throw __FUNCTION__; + throw EXCEPTION("Unimplemented interrupt flags (d=%d, e=%d)", op.d, op.e); } if (CPU.GPR[op.rt]._u32[3] == 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0)); + CPU.PC = SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0) - 4; } } @@ -287,12 +287,12 @@ void spu_interpreter::BINZ(SPUThread& CPU, spu_opcode_t op) { if (op.d || op.e) { - throw __FUNCTION__; + throw EXCEPTION("Unimplemented interrupt flags (d=%d, e=%d)", op.d, op.e); } if (CPU.GPR[op.rt]._u32[3] != 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0)); + CPU.PC = SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0) - 4; } } @@ -300,12 +300,12 @@ void spu_interpreter::BIHZ(SPUThread& CPU, spu_opcode_t op) { if (op.d || op.e) { - throw __FUNCTION__; + throw EXCEPTION("Unimplemented interrupt flags (d=%d, e=%d)", op.d, op.e); } if (CPU.GPR[op.rt]._u16[6] == 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0)); + CPU.PC = SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0) - 4; } } @@ -313,18 +313,18 @@ void spu_interpreter::BIHNZ(SPUThread& CPU, spu_opcode_t op) { if (op.d || op.e) { - throw __FUNCTION__; + throw EXCEPTION("Unimplemented interrupt flags (d=%d, e=%d)", op.d, op.e); } if (CPU.GPR[op.rt]._u16[6] != 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0)); + CPU.PC = SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0) - 4; } } void spu_interpreter::STOPD(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::STQX(SPUThread& CPU, spu_opcode_t op) @@ -336,32 +336,32 @@ void spu_interpreter::BI(SPUThread& CPU, spu_opcode_t op) { if (op.d || op.e) { - throw __FUNCTION__; + throw EXCEPTION("Unimplemented interrupt flags (d=%d, e=%d)", op.d, op.e); } - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0)); + CPU.PC = SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0) - 4; } void spu_interpreter::BISL(SPUThread& CPU, spu_opcode_t op) { if (op.d || op.e) { - throw __FUNCTION__; + throw EXCEPTION("Unimplemented interrupt flags (d=%d, e=%d)", op.d, op.e); } const u32 target = SPUOpcodes::branchTarget(CPU.GPR[op.ra]._u32[3], 0); CPU.GPR[op.rt] = u128::from32r(CPU.PC + 4); - CPU.SetBranch(target); + CPU.PC = target - 4; } void spu_interpreter::IRET(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::BISLED(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::HBR(SPUThread& CPU, spu_opcode_t op) @@ -656,7 +656,7 @@ void spu_interpreter::FCGT(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::DFCGT(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::FA(SPUThread& CPU, spu_opcode_t op) @@ -692,7 +692,7 @@ void spu_interpreter::FCMGT(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::DFCMGT(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::DFA(SPUThread& CPU, spu_opcode_t op) @@ -818,7 +818,7 @@ void spu_interpreter::FSCRWR(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::DFTSV(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::FCEQ(SPUThread& CPU, spu_opcode_t op) @@ -828,7 +828,7 @@ void spu_interpreter::FCEQ(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::DFCEQ(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::MPY(SPUThread& CPU, spu_opcode_t op) @@ -865,7 +865,7 @@ void spu_interpreter::FCMEQ(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::DFCMEQ(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected instruction"); } void spu_interpreter::MPYU(SPUThread& CPU, spu_opcode_t op) @@ -931,7 +931,7 @@ void spu_interpreter::BRZ(SPUThread& CPU, spu_opcode_t op) { if (CPU.GPR[op.rt]._u32[3] == 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.PC, op.i16)); + CPU.PC = SPUOpcodes::branchTarget(CPU.PC, op.i16) - 4; } } @@ -944,7 +944,7 @@ void spu_interpreter::BRNZ(SPUThread& CPU, spu_opcode_t op) { if (CPU.GPR[op.rt]._u32[3] != 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.PC, op.i16)); + CPU.PC = SPUOpcodes::branchTarget(CPU.PC, op.i16) - 4; } } @@ -952,7 +952,7 @@ void spu_interpreter::BRHZ(SPUThread& CPU, spu_opcode_t op) { if (CPU.GPR[op.rt]._u16[6] == 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.PC, op.i16)); + CPU.PC = SPUOpcodes::branchTarget(CPU.PC, op.i16) - 4; } } @@ -960,7 +960,7 @@ void spu_interpreter::BRHNZ(SPUThread& CPU, spu_opcode_t op) { if (CPU.GPR[op.rt]._u16[6] != 0) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.PC, op.i16)); + CPU.PC = SPUOpcodes::branchTarget(CPU.PC, op.i16) - 4; } } @@ -971,7 +971,7 @@ void spu_interpreter::STQR(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::BRA(SPUThread& CPU, spu_opcode_t op) { - CPU.SetBranch(SPUOpcodes::branchTarget(0, op.i16)); + CPU.PC = SPUOpcodes::branchTarget(0, op.i16) - 4; } void spu_interpreter::LQA(SPUThread& CPU, spu_opcode_t op) @@ -983,12 +983,12 @@ void spu_interpreter::BRASL(SPUThread& CPU, spu_opcode_t op) { const u32 target = SPUOpcodes::branchTarget(0, op.i16); CPU.GPR[op.rt] = u128::from32r(CPU.PC + 4); - CPU.SetBranch(target); + CPU.PC = target - 4; } void spu_interpreter::BR(SPUThread& CPU, spu_opcode_t op) { - CPU.SetBranch(SPUOpcodes::branchTarget(CPU.PC, op.i16)); + CPU.PC = SPUOpcodes::branchTarget(CPU.PC, op.i16) - 4; } void spu_interpreter::FSMBI(SPUThread& CPU, spu_opcode_t op) @@ -1000,7 +1000,7 @@ void spu_interpreter::BRSL(SPUThread& CPU, spu_opcode_t op) { const u32 target = SPUOpcodes::branchTarget(CPU.PC, op.i16); CPU.GPR[op.rt] = u128::from32r(CPU.PC + 4); - CPU.SetBranch(target); + CPU.PC = target - 4; } void spu_interpreter::LQR(SPUThread& CPU, spu_opcode_t op) @@ -1250,5 +1250,5 @@ void spu_interpreter::FMS(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::UNK(SPUThread& CPU, spu_opcode_t op) { - throw __FUNCTION__; + throw EXCEPTION("Unknown instruction (op=0x%08x)", op.opcode); } diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 97d4934b3c..0c0a61cbc2 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -325,7 +325,7 @@ private: if (CPU.GPR[rt]._u32[3] == 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -344,7 +344,7 @@ private: if (CPU.GPR[rt]._u32[3] != 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -363,7 +363,7 @@ private: if (CPU.GPR[rt]._u16[6] == 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -382,7 +382,7 @@ private: if (CPU.GPR[rt]._u16[6] != 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -409,7 +409,7 @@ private: u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0); LOG5_OPCODE("branch (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } void BISL(u32 intr, u32 rt, u32 ra) { @@ -422,7 +422,7 @@ private: u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0); CPU.GPR[rt] = u128::from32r(CPU.PC + 4); LOG5_OPCODE("branch (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } void IRET(u32 ra) { @@ -1536,7 +1536,7 @@ private: if (CPU.GPR[rt]._u32[3] == 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -1555,7 +1555,7 @@ private: if (CPU.GPR[rt]._u32[3] != 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -1568,7 +1568,7 @@ private: if (CPU.GPR[rt]._u16[6] == 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -1581,7 +1581,7 @@ private: if (CPU.GPR[rt]._u16[6] != 0) { LOG5_OPCODE("taken (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } else { @@ -1598,7 +1598,7 @@ private: { u32 target = branchTarget(0, i16); LOG5_OPCODE("branch (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } void LQA(u32 rt, s32 i16) { @@ -1611,13 +1611,13 @@ private: u32 target = branchTarget(0, i16); CPU.GPR[rt] = u128::from32r(CPU.PC + 4); LOG5_OPCODE("branch (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } void BR(s32 i16) { u32 target = branchTarget(CPU.PC, i16); LOG5_OPCODE("branch (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } void FSMBI(u32 rt, s32 i16) { @@ -1640,7 +1640,7 @@ private: u32 target = branchTarget(CPU.PC, i16); CPU.GPR[rt] = u128::from32r(CPU.PC + 4); LOG5_OPCODE("branch (0x%x)", target); - CPU.SetBranch(target); + CPU.PC = target - 4; } void LQR(u32 rt, s32 i16) { diff --git a/rpcs3/Emu/Cell/SPURSManager.cpp b/rpcs3/Emu/Cell/SPURSManager.cpp deleted file mode 100644 index 105cb2c79e..0000000000 --- a/rpcs3/Emu/Cell/SPURSManager.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" - -#include "SPURSManager.h" - -SPURSManagerEventFlag::SPURSManagerEventFlag(u32 flagClearMode, u32 flagDirection) -{ - this->flagClearMode = flagClearMode; - this->flagDirection = flagDirection; -} - -SPURSManagerTasksetAttribute::SPURSManagerTasksetAttribute(u64 args, vm::ptr priority, u32 maxContention) -{ - this->args = args; - this->maxContention = maxContention; -} - -SPURSManager::SPURSManager() -{ -} - -void SPURSManager::Finalize() -{ -} - -void SPURSManager::AttachLv2EventQueue(u32 queue, vm::ptr port, int isDynamic) -{ - //TODO: -} - -void SPURSManager::DetachLv2EventQueue(u8 port) -{ - //TODO: -} - -SPURSManagerTaskset::SPURSManagerTaskset(u32 address, SPURSManagerTasksetAttribute *tattr) -{ - 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 deleted file mode 100644 index 55bf5de181..0000000000 --- a/rpcs3/Emu/Cell/SPURSManager.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -class SPURSManagerEventFlag -{ -public: - SPURSManagerEventFlag(u32 flagClearMode, u32 flagDirection); - - u32 _getDirection() const - { - return this->flagDirection; - } - - u32 _getClearMode() const - { - return this->flagClearMode; - } - -protected: - be_t flagClearMode; - be_t flagDirection; -}; - -class SPURSManagerTasksetAttribute -{ -public: - SPURSManagerTasksetAttribute(u64 args, vm::ptr priority, u32 maxContention); - -protected: - be_t args; - be_t maxContention; -}; - -class SPURSManagerTaskset -{ -public: - SPURSManagerTaskset(u32 address, SPURSManagerTasksetAttribute *tattr); - -protected: - u32 address; - SPURSManagerTasksetAttribute *tattr; -}; - -// Main SPURS manager class. -class SPURSManager -{ -public: - SPURSManager(); - - void Finalize(); - void AttachLv2EventQueue(u32 queue, vm::ptr port, int isDynamic); - void DetachLv2EventQueue(u8 port); -}; diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 893e8d8f63..3780519975 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -28,7 +28,7 @@ public: struct SPURecEntry { u32 count; // count of instructions compiled from current point (and to be checked) - u32 valid; // copy of valid opcode for validation + be_t _valid; // copy of valid opcode for validation void* pointer; // pointer to executable memory object }; @@ -69,26 +69,16 @@ public: struct XmmLink { - asmjit::X86XmmVar* data; - s8 reg; - bool taken; - mutable bool got; - mutable u32 access; - - XmmLink() - : data(nullptr) - , reg(-1) - , taken(false) - , got(false) - , access(0) - { - } + asmjit::X86XmmVar* data = nullptr; + s8 reg = -1; + bool taken = false; + mutable bool got = false; + mutable u32 access = 0; const asmjit::X86XmmVar& get() const { assert(data); - assert(taken); - if (!taken) throw "XmmLink::get(): wrong use"; + if (!taken) throw EXCEPTION("Register not taken"); got = true; return *data; } diff --git a/rpcs3/Emu/Cell/SPURecompilerCore.cpp b/rpcs3/Emu/Cell/SPURecompilerCore.cpp index 6257baaf7e..15f2a2c400 100644 --- a/rpcs3/Emu/Cell/SPURecompilerCore.cpp +++ b/rpcs3/Emu/Cell/SPURecompilerCore.cpp @@ -4,8 +4,6 @@ #include "Emu/System.h" #include "Utilities/File.h" -#include "Emu/SysCalls/lv2/sys_time.h" - #include "SPUInstrTable.h" #include "SPUDisAsm.h" @@ -20,6 +18,8 @@ using namespace asmjit; using namespace asmjit::host; +extern u64 get_system_time(); + SPURecompilerCore::SPURecompilerCore(SPUThread& cpu) : m_enc(new SPURecompiler(cpu, *this)) , m_int(new SPUInterpreter(cpu)) @@ -95,9 +95,9 @@ void SPURecompilerCore::Compile(u16 pos) while (true) { - const u32 opcode = vm::read32(CPU.offset + pos * 4); + const be_t opcode = vm::ps3::read32(CPU.offset + pos * 4); m_enc->do_finalize = false; - if (opcode) + if (opcode.data()) { //const u64 stamp1 = get_system_time(); // disasm for logging: @@ -120,11 +120,11 @@ void SPURecompilerCore::Compile(u16 pos) m_enc->do_finalize = true; } bool fin = m_enc->do_finalize; - //if (entry[pos].valid == re32(opcode)) + //if (entry[pos]._valid == opcode) //{ // excess++; //} - entry[pos].valid = re32(opcode); + entry[pos]._valid = opcode; if (fin) break; CPU.PC += 4; @@ -169,7 +169,7 @@ void SPURecompilerCore::Compile(u16 pos) u32 SPURecompilerCore::DecodeMemory(const u32 address) { const u32 pos = CPU.PC >> 2; // 0x0..0xffff - const auto ls = vm::get_ptr(CPU.offset); + const auto _ls = vm::get_ptr>(CPU.offset); assert(CPU.offset == address - CPU.PC && pos < 0x10000); @@ -182,7 +182,7 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) { for (u32 i = 0; i < 0x10000; i++) { - if (entry[i].valid && entry[i].valid != ls[i]) + if (entry[i]._valid.data() && entry[i]._valid != _ls[i]) { is_valid = false; break; @@ -199,14 +199,14 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) { if (!entry[i].pointer) continue; - if (!entry[i].valid || entry[i].valid != ls[i] || (i + entry[i].count > pos && i < pos + entry[pos].count)) + if (!entry[i]._valid.data() || entry[i]._valid != _ls[i] || (i + entry[i].count > pos && i < pos + entry[pos].count)) { m_jit->release(entry[i].pointer); entry[i].pointer = nullptr; for (u32 j = i; j < i + entry[i].count; j++) { - entry[j].valid = 0; + entry[j]._valid = 0; } //need_check = true; @@ -225,9 +225,9 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) return 0; } - const auto func = asmjit_cast(entry[pos].pointer); + const auto func = asmjit_cast* _ls, const void* _imm, const void* _g_imm)>(entry[pos].pointer); - u32 res = func(CPU, ls, imm_table.data(), &g_spu_imm); + u32 res = func(&CPU, _ls, imm_table.data(), &g_spu_imm); if (res & 0x1000000) { @@ -247,7 +247,7 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) } else { - CPU.SetBranch((u64)res << 2); + CPU.PC = (res << 2) - 4; return 0; } } @@ -272,24 +272,22 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) #define LOG4_OPCODE(...) //c.addComment(fmt::Format("SPU info: "__FUNCTION__"(): "__VA_ARGS__).c_str()) -#define WRAPPER_BEGIN(a0, a1, a2, a3) struct opwr_##a0 \ +#define WRAPPER_BEGIN(a0, a1, a2) struct opwr_##a0 \ { \ - static void opcode(u32 a0, u32 a1, u32 a2, u32 a3) \ -{ \ - SPUThread& CPU = *(SPUThread*)GetCurrentNamedThread(); + static void opcode(SPUThread* CPU, u32 a0, u32 a1, u32 a2) \ +{ -#define WRAPPER_END(a0, a1, a2, a3) /*LOG2_OPCODE();*/ } \ +#define WRAPPER_END(a0, a1, a2) /*LOG2_OPCODE();*/ } \ }; \ /*XmmRelease();*/ \ if (#a0[0] == 'r') XmmInvalidate(a0); \ if (#a1[0] == 'r') XmmInvalidate(a1); \ if (#a2[0] == 'r') XmmInvalidate(a2); \ - if (#a3[0] == 'r') XmmInvalidate(a3); \ - X86CallNode* call##a0 = c.call(imm_ptr(reinterpret_cast(&opwr_##a0::opcode)), kFuncConvHost, FuncBuilder4()); \ - call##a0->setArg(0, imm_u(a0)); \ - call##a0->setArg(1, imm_u(a1)); \ - call##a0->setArg(2, imm_u(a2)); \ - call##a0->setArg(3, imm_u(a3)); \ + X86CallNode* call##a0 = c.call(imm_ptr(reinterpret_cast(&opwr_##a0::opcode)), kFuncConvHost, FuncBuilder4()); \ + call##a0->setArg(0, *cpu_var); \ + call##a0->setArg(1, imm_u(a0)); \ + call##a0->setArg(2, imm_u(a1)); \ + call##a0->setArg(3, imm_u(a2)); \ LOG3_OPCODE(/*#a0"=%d, "#a1"=%d, "#a2"=%d, "#a3"=%d", a0, a1, a2, a3*/); const SPURecompiler::XmmLink& SPURecompiler::XmmAlloc(s8 pref) // get empty xmm register @@ -305,6 +303,7 @@ const SPURecompiler::XmmLink& SPURecompiler::XmmAlloc(s8 pref) // get empty xmm return xmm_var[i]; } } + for (u32 i = 0; i < 16; i++) { if ((xmm_var[i].reg == -1) && !xmm_var[i].taken) @@ -316,6 +315,7 @@ const SPURecompiler::XmmLink& SPURecompiler::XmmAlloc(s8 pref) // get empty xmm return xmm_var[i]; } } + int last = -1, max = -1; for (u32 i = 0; i < 16; i++) { @@ -328,6 +328,7 @@ const SPURecompiler::XmmLink& SPURecompiler::XmmAlloc(s8 pref) // get empty xmm } } } + if (last >= 0) { // (saving cached data?) @@ -339,7 +340,8 @@ const SPURecompiler::XmmLink& SPURecompiler::XmmAlloc(s8 pref) // get empty xmm xmm_var[last].access = 0; return xmm_var[last]; } - throw "XmmAlloc() failed"; + + throw EXCEPTION("Failure"); } const SPURecompiler::XmmLink* SPURecompiler::XmmRead(const s8 reg) const // get xmm register with specific SPU reg or nullptr @@ -350,7 +352,7 @@ const SPURecompiler::XmmLink* SPURecompiler::XmmRead(const s8 reg) const // get if (xmm_var[i].reg == reg) { //assert(!xmm_var[i].got); - //if (xmm_var[i].got) throw "XmmRead(): wrong reuse"; + //if (xmm_var[i].got) throw EXCEPTION("Wrong reuse"); LOG4_OPCODE("GPR[%d] has been read (i=%d)", reg, i); xmm_var[i].access++; return &xmm_var[i]; @@ -371,13 +373,13 @@ const SPURecompiler::XmmLink& SPURecompiler::XmmGet(s8 reg, s8 target) // get xm if (xmm_var[i].reg == reg) { res = &xmm_var[i]; - if (xmm_var[i].taken) throw "XmmGet(): xmm_var is taken"; + if (xmm_var[i].taken) throw EXCEPTION("xmm_var is taken"); xmm_var[i].taken = true; xmm_var[i].got = false; //xmm_var[i].reg = -1; for (u32 j = i + 1; j < 16; j++) { - if (xmm_var[j].reg == reg) throw "XmmGet(): xmm_var duplicate"; + if (xmm_var[j].reg == reg) throw EXCEPTION("xmm_var duplicate"); } LOG4_OPCODE("cached GPR[%d] used (i=%d)", reg, i); break; @@ -424,7 +426,7 @@ void SPURecompiler::XmmInvalidate(const s8 reg) // invalidate cached register { if (xmm_var[i].reg == reg) { - if (xmm_var[i].taken) throw "XmmInvalidate(): xmm_var is taken"; + if (xmm_var[i].taken) throw EXCEPTION("xmm_var is taken"); LOG4_OPCODE("GPR[%d] invalidated (i=%d)", reg, i); xmm_var[i].reg = -1; xmm_var[i].access = 0; @@ -505,16 +507,16 @@ void SPURecompiler::STOP(u32 code) { struct STOP_wrapper { - static void STOP(u32 code) + static void STOP(SPUThread* CPU, u32 code) { - SPUThread& CPU = *(SPUThread*)GetCurrentNamedThread(); - CPU.stop_and_signal(code); + CPU->stop_and_signal(code); LOG2_OPCODE(); } }; c.mov(cpu_dword(PC), CPU.PC); - X86CallNode* call = c.call(imm_ptr(reinterpret_cast(&STOP_wrapper::STOP)), kFuncConvHost, FuncBuilder1()); - call->setArg(0, imm_u(code)); + X86CallNode* call = c.call(imm_ptr(reinterpret_cast(&STOP_wrapper::STOP)), kFuncConvHost, FuncBuilder2()); + call->setArg(0, *cpu_var); + call->setArg(1, imm_u(code)); c.mov(*pos_var, (CPU.PC >> 2) + 1); do_finalize = true; LOG_OPCODE(); @@ -550,18 +552,18 @@ void SPURecompiler::MFSPR(u32 rt, u32 sa) void SPURecompiler::RDCH(u32 rt, u32 ra) { c.mov(cpu_dword(PC), CPU.PC); - WRAPPER_BEGIN(rt, ra, yy, zz); - CPU.GPR[rt] = u128::from32r(CPU.get_ch_value(ra)); - WRAPPER_END(rt, ra, 0, 0); + WRAPPER_BEGIN(rt, ra, zz); + CPU->GPR[rt] = u128::from32r(CPU->get_ch_value(ra)); + WRAPPER_END(rt, ra, 0); // TODO } void SPURecompiler::RCHCNT(u32 rt, u32 ra) { c.mov(cpu_dword(PC), CPU.PC); - WRAPPER_BEGIN(rt, ra, yy, zz); - CPU.GPR[rt] = u128::from32r(CPU.get_ch_count(ra)); - WRAPPER_END(rt, ra, 0, 0); + WRAPPER_BEGIN(rt, ra, zz); + CPU->GPR[rt] = u128::from32r(CPU->get_ch_count(ra)); + WRAPPER_END(rt, ra, 0); // TODO } @@ -964,9 +966,9 @@ void SPURecompiler::MTSPR(u32 rt, u32 sa) void SPURecompiler::WRCH(u32 ra, u32 rt) { c.mov(cpu_dword(PC), CPU.PC); - WRAPPER_BEGIN(ra, rt, yy, zz); - CPU.set_ch_value(ra, CPU.GPR[rt]._u32[3]); - WRAPPER_END(ra, rt, 0, 0); + WRAPPER_BEGIN(ra, rt, yy); + CPU->set_ch_value(ra, CPU->GPR[rt]._u32[3]); + WRAPPER_END(ra, rt, 0); // TODO /*XmmInvalidate(rt); @@ -2208,23 +2210,23 @@ void SPURecompiler::SFX(u32 rt, u32 ra, u32 rb) void SPURecompiler::CGX(u32 rt, u32 ra, u32 rb) //nf { - WRAPPER_BEGIN(rt, ra, rb, zz); + WRAPPER_BEGIN(rt, ra, rb); 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; - WRAPPER_END(rt, ra, rb, 0); + 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; + WRAPPER_END(rt, ra, rb); } void SPURecompiler::BGX(u32 rt, u32 ra, u32 rb) //nf { - WRAPPER_BEGIN(rt, ra, rb, zz); + WRAPPER_BEGIN(rt, ra, rb); s64 nResult; for (int w = 0; w < 4; w++) { - nResult = (u64)CPU.GPR[rb]._u32[w] - (u64)CPU.GPR[ra]._u32[w] - (u64)(1 - (CPU.GPR[rt]._u32[w] & 1)); - CPU.GPR[rt]._u32[w] = nResult < 0 ? 0 : 1; + nResult = (u64)CPU->GPR[rb]._u32[w] - (u64)CPU->GPR[ra]._u32[w] - (u64)(1 - (CPU->GPR[rt]._u32[w] & 1)); + CPU->GPR[rt]._u32[w] = nResult < 0 ? 0 : 1; } - WRAPPER_END(rt, ra, rb, 0); + WRAPPER_END(rt, ra, rb); } void SPURecompiler::MPYHHA(u32 rt, u32 ra, u32 rb) @@ -3326,10 +3328,6 @@ void SPURecompiler::FMA(u32 rt, u32 ra, u32 rb, u32 rc) XmmFinalize(va, rt); XmmFinalize(vc); } - else - { - throw "FMA: invalid case"; // should never happen - } LOG_OPCODE(); } @@ -3412,10 +3410,6 @@ void SPURecompiler::FMS(u32 rt, u32 ra, u32 rb, u32 rc) XmmFinalize(va, rt); XmmFinalize(vc); } - else - { - throw "FMS: invalid case"; // should never happen - } LOG_OPCODE(); } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 29f209c3f4..15d89fb531 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -5,13 +5,11 @@ #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.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_event.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include "Emu/Cell/SPUDisAsm.h" #include "Emu/Cell/SPUThread.h" @@ -22,6 +20,8 @@ #include +extern u64 get_timebased_time(); + const g_spu_imm_table_t g_spu_imm; class spu_inter_func_list_t @@ -50,34 +50,62 @@ public: } } - force_inline spu_inter_func_t operator [] (u32 opcode) const + force_inline spu_inter_func_t operator [](u32 opcode) const { return funcs[opcode >> 21]; } } g_spu_inter_func_list; -SPUThread& GetCurrentSPUThread() +SPUThread::SPUThread(CPUThreadType type, const std::string& name, std::function thread_name, u32 index, u32 offset) + : CPUThread(type, name, std::move(thread_name)) + , index(index) + , offset(offset) { - CPUThread* thread = GetCurrentCPUThread(); - - if(!thread || (thread->GetType() != CPU_THREAD_SPU && thread->GetType() != CPU_THREAD_RAW_SPU)) - { - throw std::string("GetCurrentSPUThread: bad thread"); - } - - return *(SPUThread*)thread; } -SPUThread::SPUThread(CPUThreadType type) : CPUThread(type) +SPUThread::SPUThread(const std::string& name, u32 index) + : CPUThread(CPU_THREAD_SPU, name, WRAP_EXPR(fmt::format("SPU[0x%x] Thread (%s)[0x%08x]", GetId(), GetName(), PC))) + , index(index) + , offset(Memory.MainMem.AllocAlign(0x40000)) { - assert(type == CPU_THREAD_SPU || type == CPU_THREAD_RAW_SPU); - - Reset(); } SPUThread::~SPUThread() { + if (m_type == CPU_THREAD_SPU) + { + join(); + + Memory.MainMem.Free(offset); + } + else if (joinable()) + { + throw EXCEPTION("Thread not joined"); + } +} + +bool SPUThread::IsPaused() const +{ + if (CPUThread::IsPaused()) + { + return true; + } + + if (const auto group = tg.lock()) + { + if (group->state >= SPU_THREAD_GROUP_STATUS_WAITING && group->state <= SPU_THREAD_GROUP_STATUS_SUSPENDED) + { + return true; + } + } + + return false; +} + +void SPUThread::DumpInformation() const +{ + CPUThread::DumpInformation(); } void SPUThread::Task() @@ -86,49 +114,43 @@ void SPUThread::Task() if (m_custom_task) { + if (CheckStatus()) return; + return m_custom_task(*this); } if (m_dec) { - return CPUThread::Task(); - } - - while (true) - { - // read opcode - const spu_opcode_t opcode = { vm::read32(PC + offset) }; - - // get interpreter function - const auto func = g_spu_inter_func_list[opcode.opcode]; - - if (m_events) + while (true) { - // process events - if (Emu.IsStopped()) - { - return; - } + if (m_state.load() && CheckStatus()) break; - if (m_events & CPU_EVENT_STOP && (IsStopped() || IsPaused())) - { - m_events &= ~CPU_EVENT_STOP; - return; - } + // decode instruction using specified decoder + m_dec->DecodeMemory(PC + offset); + + // next instruction + PC += 4; } - - // call interpreter function - func(*this, opcode); - - // next instruction - //PC += 4; - NextPc(4); } -} + else + { + while (true) + { + if (m_state.load() && CheckStatus()) break; -void SPUThread::DoReset() -{ - InitRegs(); + // read opcode + const spu_opcode_t opcode = { vm::read32(PC + offset) }; + + // get interpreter function + const auto func = g_spu_inter_func_list[opcode.opcode]; + + // call interpreter function + func(*this, opcode); + + // next instruction + PC += 4; + } + } } void SPUThread::InitRegs() @@ -157,7 +179,7 @@ void SPUThread::InitRegs() ch_event_mask = 0; ch_event_stat = {}; - ch_dec_start_timestamp = get_time(); // ??? + ch_dec_start_timestamp = get_timebased_time(); // ??? ch_dec_value = 0; run_ctrl = {}; @@ -172,8 +194,7 @@ void SPUThread::InitRegs() void SPUThread::InitStack() { - m_stack_size = 0x2000; // this value is wrong - m_stack_addr = offset + 0x40000 - m_stack_size; // stack is the part of SPU Local Storage + // nothing to do } void SPUThread::CloseStack() @@ -189,7 +210,7 @@ void SPUThread::DoRun() { case 0: // original interpreter { - m_dec = new SPUDecoder(*new SPUInterpreter(*this)); + m_dec.reset(new SPUDecoder(*new SPUInterpreter(*this))); break; } @@ -201,7 +222,7 @@ void SPUThread::DoRun() case 2: { - m_dec = new SPURecompilerCore(*this); + m_dec.reset(new SPURecompilerCore(*this)); break; } @@ -213,27 +234,13 @@ void SPUThread::DoRun() } } -void SPUThread::DoResume() -{ -} - -void SPUThread::DoPause() -{ -} - -void SPUThread::DoStop() -{ - delete m_dec; - m_dec = nullptr; -} - -void SPUThread::DoClose() -{ -} - void SPUThread::FastCall(u32 ls_addr) { - // can't be called from another thread (because it doesn't make sense) + if (!is_current()) + { + throw EXCEPTION("Called from the wrong thread"); + } + write32(0x0, 2); auto old_PC = PC; @@ -241,12 +248,19 @@ void SPUThread::FastCall(u32 ls_addr) auto old_stack = GPR[1]._u32[3]; // only saved and restored (may be wrong) auto old_task = decltype(m_custom_task)(); - m_status = Running; PC = ls_addr; GPR[0]._u32[3] = 0x0; m_custom_task.swap(old_task); - SPUThread::Task(); + try + { + Task(); + } + catch (CPUThreadReturn) + { + } + + m_state &= ~CPU_STATE_RETURN; PC = old_PC; GPR[0]._u32[3] = old_LR; @@ -254,18 +268,6 @@ void SPUThread::FastCall(u32 ls_addr) m_custom_task.swap(old_task); } -void SPUThread::FastStop() -{ - m_status = Stopped; - m_events |= CPU_EVENT_STOP; -} - -void SPUThread::FastRun() -{ - m_status = Running; - Exec(); -} - void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args) { if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) @@ -273,7 +275,7 @@ void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args) _mm_mfence(); } - u32 eal = vm::cast(args.ea, "ea"); + u32 eal = VM_CAST(args.ea); if (eal >= SYS_SPU_THREAD_BASE_LOW && m_type == CPU_THREAD_SPU) // SPU Thread Group MMIO (LS and SNR) { @@ -297,14 +299,12 @@ void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args) } else { - LOG_ERROR(SPU, "do_dma_transfer(cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x): invalid MMIO offset", cmd, args.lsa, args.ea, args.tag, args.size); - throw __FUNCTION__; + throw EXCEPTION("Invalid MMIO offset (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)", cmd, args.lsa, args.ea, args.tag, args.size); } } else { - LOG_ERROR(SPU, "do_dma_transfer(cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x): invalid thread type", cmd, args.lsa, args.ea, args.tag, args.size); - throw __FUNCTION__; + throw EXCEPTION("Invalid thread type (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)", cmd, args.lsa, args.ea, args.tag, args.size); } } @@ -324,16 +324,14 @@ void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args) } } - LOG_ERROR(SPU, "do_dma_transfer(cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x): invalid cmd (%s)", cmd, args.lsa, args.ea, args.tag, args.size, get_mfc_cmd_name(cmd)); - throw __FUNCTION__; + throw EXCEPTION("Invalid command %s (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)", get_mfc_cmd_name(cmd), cmd, args.lsa, args.ea, args.tag, args.size); } void SPUThread::do_dma_list_cmd(u32 cmd, spu_mfc_arg_t args) { if (!(cmd & MFC_LIST_MASK)) { - LOG_ERROR(SPU, "do_dma_list_cmd(cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x): invalid cmd (%s)", cmd, args.lsa, args.ea, args.tag, args.size, get_mfc_cmd_name(cmd)); - throw __FUNCTION__; + throw EXCEPTION("Invalid command %s (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)", get_mfc_cmd_name(cmd), cmd, args.lsa, args.ea, args.tag, args.size); } const u32 list_addr = args.ea & 0x3ffff; @@ -367,7 +365,7 @@ void SPUThread::do_dma_list_cmd(u32 cmd, spu_mfc_arg_t args) args.lsa += std::max(size, 16); } - if (rec->sb.data() & se16(0x8000)) + if (rec->sb & 0x8000) { ch_stall_stat.push_bit_or(1 << args.tag); @@ -427,10 +425,10 @@ void SPUThread::process_mfc_cmd(u32 cmd) break; } - vm::reservation_acquire(vm::get_ptr(offset + ch_mfc_args.lsa), vm::cast(ch_mfc_args.ea), 128, [this]() + vm::reservation_acquire(vm::get_ptr(offset + ch_mfc_args.lsa), VM_CAST(ch_mfc_args.ea), 128, [this]() { ch_event_stat |= SPU_EVENT_LR; - Notify(); + cv.notify_one(); }); ch_atomic_stat.push_uncond(MFC_GETLLAR_SUCCESS); @@ -444,7 +442,7 @@ void SPUThread::process_mfc_cmd(u32 cmd) break; } - if (vm::reservation_update(vm::cast(ch_mfc_args.ea), vm::get_ptr(offset + ch_mfc_args.lsa), 128)) + if (vm::reservation_update(VM_CAST(ch_mfc_args.ea), vm::get_ptr(offset + ch_mfc_args.lsa), 128)) { ch_atomic_stat.push_uncond(MFC_PUTLLC_SUCCESS); } @@ -464,9 +462,9 @@ void SPUThread::process_mfc_cmd(u32 cmd) break; } - vm::reservation_op(vm::cast(ch_mfc_args.ea), 128, [this]() + vm::reservation_op(VM_CAST(ch_mfc_args.ea), 128, [this]() { - memcpy(vm::priv_ptr(vm::cast(ch_mfc_args.ea)), vm::get_ptr(offset + ch_mfc_args.lsa), 128); + memcpy(vm::priv_ptr(VM_CAST(ch_mfc_args.ea)), vm::get_ptr(offset + ch_mfc_args.lsa), 128); }); if (cmd == MFC_PUTLLUC_CMD) @@ -482,8 +480,7 @@ void SPUThread::process_mfc_cmd(u32 cmd) } } - LOG_ERROR(SPU, "Unknown DMA %s: cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x", get_mfc_cmd_name(cmd), cmd, ch_mfc_args.lsa, ch_mfc_args.ea, ch_mfc_args.tag, ch_mfc_args.size); - throw __FUNCTION__; + throw EXCEPTION("Unknown command %s (cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)", get_mfc_cmd_name(cmd), cmd, ch_mfc_args.lsa, ch_mfc_args.ea, ch_mfc_args.tag, ch_mfc_args.size); } u32 SPUThread::get_ch_count(u32 ch) @@ -507,11 +504,10 @@ u32 SPUThread::get_ch_count(u32 ch) case SPU_RdSigNotify1: return ch_snr1.get_count(); break; case SPU_RdSigNotify2: return ch_snr2.get_count(); break; case MFC_RdAtomicStat: return ch_atomic_stat.get_count(); break; - case SPU_RdEventStat: return ch_event_stat.read_relaxed() & ch_event_mask ? 1 : 0; break; + case SPU_RdEventStat: return ch_event_stat.load() & ch_event_mask ? 1 : 0; break; } - LOG_ERROR(SPU, "get_ch_count(ch=%d [%s]): unknown/illegal channel", ch, ch < 128 ? spu_ch_name[ch] : "???"); - throw __FUNCTION__; + throw EXCEPTION("Unknown/illegal channel (ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???"); } u32 SPUThread::get_ch_value(u32 ch) @@ -521,6 +517,30 @@ u32 SPUThread::get_ch_value(u32 ch) LOG_NOTICE(SPU, "get_ch_value(ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???"); } + auto read_channel = [this](spu_channel_t& channel) -> u32 + { + std::unique_lock lock(mutex, std::defer_lock); + + u32 result; + + while (!channel.try_pop(result)) + { + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + if (!lock) + { + lock.lock(); + continue; + } + + cv.wait_for(lock, std::chrono::milliseconds(1)); + } + + return result; + }; + switch (ch) { //case SPU_RdSRR0: @@ -528,10 +548,23 @@ u32 SPUThread::get_ch_value(u32 ch) // break; case SPU_RdInMbox: { + std::unique_lock lock(mutex, std::defer_lock); + u32 result, count; - while (!ch_in_mbox.pop(result, count) && !Emu.IsStopped()) + + while (!ch_in_mbox.try_pop(result, count)) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + if (!lock) + { + lock.lock(); + continue; + } + + cv.wait_for(lock, std::chrono::milliseconds(1)); } if (count + 1 == 4 /* SPU_IN_MBOX_THRESHOLD */) // TODO: check this @@ -544,13 +577,7 @@ u32 SPUThread::get_ch_value(u32 ch) case MFC_RdTagStat: { - u32 result; - while (!ch_tag_stat.pop(result) && !Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } - - return result; + return read_channel(ch_tag_stat); } case MFC_RdTagMask: @@ -560,51 +587,27 @@ u32 SPUThread::get_ch_value(u32 ch) case SPU_RdSigNotify1: { - u32 result; - while (!ch_snr1.pop(result) && !Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } - - return result; + return read_channel(ch_snr1); } case SPU_RdSigNotify2: { - u32 result; - while (!ch_snr2.pop(result) && !Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } - - return result; + return read_channel(ch_snr2); } case MFC_RdAtomicStat: { - u32 result; - while (!ch_atomic_stat.pop(result) && !Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } - - return result; + return read_channel(ch_atomic_stat); } case MFC_RdListStallStat: { - u32 result; - while (!ch_stall_stat.pop(result) && !Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - } - - return result; + return read_channel(ch_stall_stat); } case SPU_RdDec: { - return ch_dec_value - (u32)(get_time() - ch_dec_start_timestamp); + return ch_dec_value - (u32)(get_timebased_time() - ch_dec_start_timestamp); } case SPU_RdEventMask: @@ -614,10 +617,23 @@ u32 SPUThread::get_ch_value(u32 ch) case SPU_RdEventStat: { + std::unique_lock lock(mutex, std::defer_lock); + u32 result; - while (!(result = ch_event_stat.read_relaxed() & ch_event_mask) && !Emu.IsStopped()) + + while ((result = ch_event_stat.load() & ch_event_mask) == 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + if (!lock) + { + lock.lock(); + continue; + } + + cv.wait_for(lock, std::chrono::milliseconds(1)); } return result; @@ -629,8 +645,7 @@ u32 SPUThread::get_ch_value(u32 ch) } } - LOG_ERROR(SPU, "get_ch_value(ch=%d [%s]): unknown/illegal channel", ch, ch < 128 ? spu_ch_name[ch] : "???"); - throw __FUNCTION__; + throw EXCEPTION("Unknown/illegal channel (ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???"); } void SPUThread::set_ch_value(u32 ch, u32 value) @@ -649,9 +664,21 @@ void SPUThread::set_ch_value(u32 ch, u32 value) { if (m_type == CPU_THREAD_RAW_SPU) { - while (!ch_out_intr_mbox.push(value) && !Emu.IsStopped()) + std::unique_lock lock(mutex, std::defer_lock); + + while (!ch_out_intr_mbox.try_push(value)) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + if (!lock) + { + lock.lock(); + continue; + } + + cv.wait_for(lock, std::chrono::milliseconds(1)); } int2.set(SPU_INT2_STAT_MAILBOX_INT); @@ -667,10 +694,9 @@ void SPUThread::set_ch_value(u32 ch, u32 value) u8 spup = code & 63; u32 data; - if (!ch_out_mbox.pop(data)) + if (!ch_out_mbox.try_pop(data)) { - LOG_ERROR(SPU, "sys_spu_thread_send_event(value=0x%x, spup=%d): Out_MBox is empty", value, spup); - throw __FUNCTION__; + throw EXCEPTION("sys_spu_thread_send_event(value=0x%x, spup=%d): Out_MBox is empty", value, spup); } if (Ini.HLELogging.GetValue()) @@ -704,10 +730,9 @@ void SPUThread::set_ch_value(u32 ch, u32 value) const u8 spup = code & 63; u32 data; - if (!ch_out_mbox.pop(data)) + if (!ch_out_mbox.try_pop(data)) { - LOG_ERROR(SPU, "sys_spu_thread_throw_event(value=0x%x, spup=%d): Out_MBox is empty", value, spup); - throw __FUNCTION__; + throw EXCEPTION("sys_spu_thread_throw_event(value=0x%x, spup=%d): Out_MBox is empty", value, spup); } if (Ini.HLELogging.GetValue()) @@ -741,16 +766,14 @@ void SPUThread::set_ch_value(u32 ch, u32 value) u32 flag = value & 0xffffff; u32 data; - if (!ch_out_mbox.pop(data)) + if (!ch_out_mbox.try_pop(data)) { - LOG_ERROR(SPU, "sys_event_flag_set_bit(value=0x%x (flag=%d)): Out_MBox is empty", value, flag); - throw __FUNCTION__; + throw EXCEPTION("sys_event_flag_set_bit(value=0x%x (flag=%d)): Out_MBox is empty", value, flag); } if (flag > 63) { - LOG_ERROR(SPU, "sys_event_flag_set_bit(id=%d, value=0x%x): flag > 63", data, value, flag); - throw __FUNCTION__; + throw EXCEPTION("sys_event_flag_set_bit(id=%d, value=0x%x): flag > 63", data, value, flag); } if (Ini.HLELogging.GetValue()) @@ -787,16 +810,14 @@ void SPUThread::set_ch_value(u32 ch, u32 value) u32 flag = value & 0xffffff; u32 data; - if (!ch_out_mbox.pop(data)) + if (!ch_out_mbox.try_pop(data)) { - LOG_ERROR(SPU, "sys_event_flag_set_bit_impatient(value=0x%x (flag=%d)): Out_MBox is empty", value, flag); - throw __FUNCTION__; + throw EXCEPTION("sys_event_flag_set_bit_impatient(value=0x%x (flag=%d)): Out_MBox is empty", value, flag); } if (flag > 63) { - LOG_ERROR(SPU, "sys_event_flag_set_bit_impatient(id=%d, value=0x%x): flag > 63", data, value, flag); - throw __FUNCTION__; + throw EXCEPTION("sys_event_flag_set_bit_impatient(id=%d, value=0x%x): flag > 63", data, value, flag); } if (Ini.HLELogging.GetValue()) @@ -831,23 +852,33 @@ void SPUThread::set_ch_value(u32 ch, u32 value) { if (ch_out_mbox.get_count()) { - LOG_ERROR(SPU, "SPU_WrOutIntrMbox: unknown data (value=0x%x); Out_MBox = 0x%x", value, ch_out_mbox.get_value()); + throw EXCEPTION("SPU_WrOutIntrMbox: unknown data (value=0x%x); Out_MBox = 0x%x", value, ch_out_mbox.get_value()); } else { - LOG_ERROR(SPU, "SPU_WrOutIntrMbox: unknown data (value=0x%x)", value); + throw EXCEPTION("SPU_WrOutIntrMbox: unknown data (value=0x%x)", value); } - - throw __FUNCTION__; } } } case SPU_WrOutMbox: { - while (!ch_out_mbox.push(value) && !Emu.IsStopped()) + std::unique_lock lock(mutex, std::defer_lock); + + while (!ch_out_mbox.try_push(value)) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + if (!lock) + { + lock.lock(); + continue; + } + + cv.wait_for(lock, std::chrono::milliseconds(1)); } return; @@ -954,7 +985,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) case SPU_WrDec: { - ch_dec_start_timestamp = get_time(); + ch_dec_start_timestamp = get_timebased_time(); ch_dec_value = value; return; } @@ -977,8 +1008,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) } } - LOG_ERROR(SPU, "set_ch_value(ch=%d [%s], value=0x%x): unknown/illegal channel", ch, ch < 128 ? spu_ch_name[ch] : "???", value); - throw __FUNCTION__; + throw EXCEPTION("Unknown/illegal channel (ch=%d [%s], value=0x%x)", ch, ch < 128 ? spu_ch_name[ch] : "???", value); } void SPUThread::stop_and_signal(u32 code) @@ -997,10 +1027,9 @@ void SPUThread::stop_and_signal(u32 code) status &= ~SPU_STATUS_RUNNING; }); - FastStop(); - int2.set(SPU_INT2_STAT_SPU_STOP_AND_SIGNAL_INT); - return; + + return Stop(); } switch (code) @@ -1013,7 +1042,7 @@ void SPUThread::stop_and_signal(u32 code) case 0x002: { - FastStop(); + m_state |= CPU_STATE_RETURN; return; } @@ -1025,7 +1054,7 @@ void SPUThread::stop_and_signal(u32 code) auto return_to_caller = iter->second(*this); if (return_to_caller) { - SetBranch(GPR[0]._u32[3] & 0x3fffc); + PC = (GPR[0]._u32[3] & 0x3fffc) - 4; } return; } @@ -1035,10 +1064,9 @@ void SPUThread::stop_and_signal(u32 code) /* ===== sys_spu_thread_receive_event ===== */ u32 spuq = 0; - if (!ch_out_mbox.pop(spuq)) + if (!ch_out_mbox.try_pop(spuq)) { - LOG_ERROR(SPU, "sys_spu_thread_receive_event(): cannot read Out_MBox"); - throw __FUNCTION__; + throw EXCEPTION("sys_spu_thread_receive_event(): cannot read Out_MBox"); } if (ch_in_mbox.get_count()) @@ -1054,6 +1082,18 @@ void SPUThread::stop_and_signal(u32 code) LV2_LOCK; + const auto group = tg.lock(); + + if (!group) + { + throw EXCEPTION("Invalid SPU Thread Group"); + } + + if (group->type & SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT) // this check may be inaccurate + { + return ch_in_mbox.push_uncond(CELL_EINVAL); + } + std::shared_ptr queue; for (auto& v : this->spuq) @@ -1074,38 +1114,85 @@ void SPUThread::stop_and_signal(u32 code) return ch_in_mbox.push_uncond(CELL_EINVAL); // TODO: check error value } + // check thread group status + while (group->state >= SPU_THREAD_GROUP_STATUS_WAITING && group->state <= SPU_THREAD_GROUP_STATUS_SUSPENDED) + { + CHECK_EMU_STATUS; + + if (IsStopped()) throw CPUThreadStop{}; + + group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + } + + // change group status + if (group->state == SPU_THREAD_GROUP_STATUS_RUNNING) + { + group->state = SPU_THREAD_GROUP_STATUS_WAITING; + + for (auto& t : group->threads) + { + if (t) t->Sleep(); // trigger status check + } + } + else + { + throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state); + } + // protocol is ignored in current implementation queue->waiters++; - while (queue->events.empty()) + // wait on the event queue + while (queue->events.empty() && !queue->cancelled) { - if (queue->cancelled) - { - return ch_in_mbox.push_uncond(CELL_ECANCELED); - } + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - LOG_WARNING(SPU, "sys_spu_thread_receive_event(spuq=0x%x) aborted", spuq); - return; - } + if (IsStopped()) throw CPUThreadStop{}; queue->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } - auto& event = queue->events.front(); - ch_in_mbox.push_uncond(CELL_OK); - ch_in_mbox.push_uncond((u32)event.data1); - ch_in_mbox.push_uncond((u32)event.data2); - ch_in_mbox.push_uncond((u32)event.data3); - - queue->events.pop_front(); - queue->waiters--; - - if (queue->events.size()) + if (queue->cancelled) { - queue->cv.notify_one(); + ch_in_mbox.push_uncond(CELL_ECANCELED); } + else + { + auto& event = queue->events.front(); + ch_in_mbox.push_uncond(CELL_OK); + ch_in_mbox.push_uncond((u32)event.data1); + ch_in_mbox.push_uncond((u32)event.data2); + ch_in_mbox.push_uncond((u32)event.data3); + + queue->events.pop_front(); + queue->waiters--; + + if (queue->events.size()) + { + queue->cv.notify_one(); + } + } + + // restore thread group status + if (group->state == SPU_THREAD_GROUP_STATUS_WAITING) + { + group->state = SPU_THREAD_GROUP_STATUS_RUNNING; + } + else if (group->state == SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED) + { + group->state = SPU_THREAD_GROUP_STATUS_SUSPENDED; + } + else + { + throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state); + } + + for (auto& t : group->threads) + { + if (t) t->Awake(); // untrigger status check + } + + group->cv.notify_all(); return; } @@ -1115,10 +1202,9 @@ void SPUThread::stop_and_signal(u32 code) /* ===== sys_spu_thread_group_exit ===== */ u32 value; - if (!ch_out_mbox.pop(value)) + if (!ch_out_mbox.try_pop(value)) { - LOG_ERROR(SPU, "sys_spu_thread_group_exit(): cannot read Out_MBox"); - throw __FUNCTION__; + throw EXCEPTION("sys_spu_thread_group_exit(): cannot read Out_MBox"); } if (Ini.HLELogging.GetValue()) @@ -1132,25 +1218,23 @@ void SPUThread::stop_and_signal(u32 code) if (!group) { - LOG_ERROR(SPU, "sys_spu_thread_group_exit(status=0x%x): invalid group", value); - throw __FUNCTION__; + throw EXCEPTION("Invalid SPU Thread Group"); } for (auto t : group->threads) { - if (t) + if (t && t.get() != this) { - auto& spu = static_cast(*t); - - spu.FastStop(); + t->Stop(); } } group->state = SPU_THREAD_GROUP_STATUS_INITIALIZED; group->exit_status = value; group->join_state |= SPU_TGJSF_GROUP_EXIT; - group->join_cv.notify_one(); - return; + group->cv.notify_one(); + + return Stop(); } case 0x102: @@ -1159,8 +1243,7 @@ void SPUThread::stop_and_signal(u32 code) if (!ch_out_mbox.get_count()) { - LOG_ERROR(SPU, "sys_spu_thread_exit(): Out_MBox is empty"); - throw __FUNCTION__; + throw EXCEPTION("sys_spu_thread_exit(): Out_MBox is empty"); } if (Ini.HLELogging.GetValue()) @@ -1170,29 +1253,35 @@ void SPUThread::stop_and_signal(u32 code) LV2_LOCK; + const auto group = tg.lock(); + + if (!group) + { + throw EXCEPTION("Invalid SPU Thread Group"); + } + status |= SPU_STATUS_STOPPED_BY_STOP; - FastStop(); - return; + group->cv.notify_one(); + + return Stop(); } } if (!ch_out_mbox.get_count()) { - LOG_ERROR(SPU, "Unknown STOP code: 0x%x", code); + throw EXCEPTION("Unknown STOP code: 0x%x", code); } else { - LOG_ERROR(SPU, "Unknown STOP code: 0x%x; Out_MBox=0x%x", code, ch_out_mbox.get_value()); + throw EXCEPTION("Unknown STOP code: 0x%x; Out_MBox=0x%x", code, ch_out_mbox.get_value()); } - - throw __FUNCTION__; } void SPUThread::halt() { if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(SPU, "halt(code=0x%x)"); + LOG_NOTICE(SPU, "halt()"); } if (m_type == CPU_THREAD_RAW_SPU) @@ -1203,24 +1292,20 @@ void SPUThread::halt() status &= ~SPU_STATUS_RUNNING; }); - FastStop(); - int2.set(SPU_INT2_STAT_SPU_HALT_OR_STEP_INT); - return; + + return Stop(); } status |= SPU_STATUS_STOPPED_BY_HALT; - throw "HALT"; + throw EXCEPTION("Halt"); } spu_thread::spu_thread(u32 entry, const std::string& name, u32 stack_size, u32 prio) { - thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU); + auto spu = Emu.GetIdManager().make_ptr(name, 0x13370666); - thread->SetName(name); - thread->SetEntry(entry); - thread->SetStackSize(stack_size ? stack_size : Emu.GetInfo().GetProcParam().primary_stacksize); - thread->SetPrio(prio ? prio : Emu.GetInfo().GetProcParam().primary_prio); + spu->PC = entry; - argc = 0; + thread = std::move(spu); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index b76fda8e1c..ecc3ccf31e 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -137,10 +137,10 @@ union spu_channel_t u32 value; }; - atomic sync_var; // atomic variable + atomic_t sync_var; // atomic variable public: - bool push(u32 value) + bool try_push(u32 value) { bool out_result; @@ -166,7 +166,7 @@ public: sync_var.exchange({ 1, value }); } - bool pop(u32& out_value) + bool try_pop(u32& out_value) { bool out_result; @@ -199,7 +199,7 @@ public: void set_value(u32 value, u32 count = 1) { - sync_var.write_relaxed({ count, value }); + sync_var.store({ count, value }); } u32 get_value() volatile @@ -223,8 +223,8 @@ struct spu_channel_4_t u32 value2; }; - atomic sync_var; - atomic value3; + atomic_t sync_var; + atomic_t value3; public: void clear() @@ -250,11 +250,11 @@ public: } // out_count: count after removing first element - bool pop(u32& out_value, u32& out_count) + bool try_pop(u32& out_value, u32& out_count) { bool out_result; - const u32 last_value = value3.read_sync(); + const u32 last_value = value3.load_sync(); sync_var.atomic_op([&out_result, &out_value, &out_count, last_value](sync_var_t& data) { @@ -280,10 +280,10 @@ public: struct spu_interrupt_tag_t { - atomic mask; - atomic stat; + atomic_t mask; + atomic_t stat; - atomic assigned; + atomic_t assigned; std::mutex handler_mutex; std::condition_variable cond; @@ -292,7 +292,7 @@ public: void set(u64 ints) { // leave only enabled interrupts - ints &= mask.read_relaxed(); + ints &= mask.load(); if (ints && ~stat._or(ints) & ints) { @@ -452,8 +452,7 @@ public: return this->_u32[3] >> 10 & 0x3; default: - throw fmt::Format("Unexpected slice value in FPSCR::checkSliceRounding(): %d", slice); - return 0; + throw EXCEPTION("Unexpected slice value (%d)", slice); } } @@ -527,14 +526,14 @@ public: spu_channel_t ch_snr2; // SPU Signal Notification Register 2 u32 ch_event_mask; - atomic ch_event_stat; + atomic_t ch_event_stat; u64 ch_dec_start_timestamp; // timestamp of writing decrementer value u32 ch_dec_value; // written decrementer value - atomic run_ctrl; // SPU Run Control register (only provided to get latest data written) - atomic status; // SPU Status register - atomic npc; // SPU Next Program Counter register + atomic_t run_ctrl; // SPU Run Control register (only provided to get latest data written) + atomic_t status; // SPU Status register + atomic_t npc; // SPU Next Program Counter register spu_interrupt_tag_t int0; // SPU Class 0 Interrupt Management spu_interrupt_tag_t int2; // SPU Class 2 Interrupt Management @@ -544,6 +543,10 @@ public: std::array>, 32> spuq; // Event Queue Keys for SPU Thread std::weak_ptr spup[64]; // SPU Ports + u32 PC = 0; + const u32 index; // SPU index + const u32 offset; // SPU LS offset + void write_snr(bool number, u32 value) { if (!number) @@ -568,6 +571,8 @@ public: ch_snr2.push_uncond(value); } } + + cv.notify_one(); } void do_dma_transfer(u32 cmd, spu_mfc_arg_t args); @@ -582,21 +587,21 @@ public: void halt(); u8 read8(u32 lsa) const { return vm::read8(lsa + offset); } - u16 read16(u32 lsa) const { return vm::read16(lsa + offset); } - u32 read32(u32 lsa) const { return vm::read32(lsa + offset); } - u64 read64(u32 lsa) const { return vm::read64(lsa + offset); } - u128 read128(u32 lsa) const { return vm::read128(lsa + offset); } + u16 read16(u32 lsa) const { return vm::ps3::read16(lsa + offset); } + u32 read32(u32 lsa) const { return vm::ps3::read32(lsa + offset); } + u64 read64(u32 lsa) const { return vm::ps3::read64(lsa + offset); } + u128 read128(u32 lsa) const { return vm::ps3::read128(lsa + offset); } void write8(u32 lsa, u8 data) const { vm::write8(lsa + offset, data); } - void write16(u32 lsa, u16 data) const { vm::write16(lsa + offset, data); } - void write32(u32 lsa, u32 data) const { vm::write32(lsa + offset, data); } - void write64(u32 lsa, u64 data) const { vm::write64(lsa + offset, data); } - void write128(u32 lsa, u128 data) const { vm::write128(lsa + offset, data); } + void write16(u32 lsa, u16 data) const { vm::ps3::write16(lsa + offset, data); } + void write32(u32 lsa, u32 data) const { vm::ps3::write32(lsa + offset, data); } + void write64(u32 lsa, u64 data) const { vm::ps3::write64(lsa + offset, data); } + void write128(u32 lsa, u128 data) const { vm::ps3::write128(lsa + offset, data); } - void write16(u32 lsa, be_t data) const { vm::write16(lsa + offset, data); } - void write32(u32 lsa, be_t data) const { vm::write32(lsa + offset, data); } - void write64(u32 lsa, be_t data) const { vm::write64(lsa + offset, data); } - void write128(u32 lsa, be_t data) const { vm::write128(lsa + offset, data); } + void write16(u32 lsa, be_t data) const { vm::ps3::write16(lsa + offset, data); } + void write32(u32 lsa, be_t data) const { vm::ps3::write32(lsa + offset, data); } + void write64(u32 lsa, be_t data) const { vm::ps3::write64(lsa + offset, data); } + void write128(u32 lsa, be_t data) const { vm::ps3::write128(lsa + offset, data); } void RegisterHleFunction(u32 addr, std::function function) { @@ -626,11 +631,28 @@ public: std::function m_custom_task; -public: - SPUThread(CPUThreadType type = CPU_THREAD_SPU); - virtual ~SPUThread(); +protected: + SPUThread(CPUThreadType type, const std::string& name, std::function thread_name, u32 index, u32 offset); - virtual std::string RegsToString() +public: + SPUThread(const std::string& name, u32 index); + virtual ~SPUThread() override; + + virtual bool IsPaused() const override; + + virtual void DumpInformation() const override; + virtual u32 GetPC() const override { return PC; } + virtual u32 GetOffset() const override { return offset; } + virtual void DoRun() override; + virtual void Task() override; + + virtual void InitRegs() override; + virtual void InitStack() override; + virtual void CloseStack() override; + + void FastCall(u32 ls_addr); + + virtual std::string RegsToString() const { std::string ret = "Registers:\n=========\n"; @@ -639,7 +661,7 @@ public: return ret; } - virtual std::string ReadRegString(const std::string& reg) + virtual std::string ReadRegString(const std::string& reg) const { std::string::size_type first_brk = reg.find('['); if (first_brk != std::string::npos) @@ -679,58 +701,15 @@ public: } return false; } - -public: - virtual void InitRegs(); - virtual void InitStack(); - virtual void CloseStack(); - virtual void Task(); - void FastCall(u32 ls_addr); - void FastStop(); - void FastRun(); - -protected: - virtual void DoReset(); - virtual void DoRun(); - virtual void DoPause(); - virtual void DoResume(); - virtual void DoStop(); - virtual void DoClose(); }; -SPUThread& GetCurrentSPUThread(); - class spu_thread : cpu_thread { - static const u32 stack_align = 0x10; - vm::ptr argv; - u32 argc; - vm::ptr envp; - public: spu_thread(u32 entry, const std::string& name = "", u32 stack_size = 0, u32 prio = 0); cpu_thread& args(std::initializer_list values) override { - if (!values.size()) - return *this; - - assert(argc == 0); - - envp.set(Memory.MainMem.AllocAlign((u32)sizeof(envp), stack_align)); - *envp = 0; - argv.set(Memory.MainMem.AllocAlign(u32(sizeof(argv)* values.size()), stack_align)); - - for (auto &arg : values) - { - u32 arg_size = align(u32(arg.size() + 1), stack_align); - u32 arg_addr = (u32)Memory.MainMem.AllocAlign(arg_size, stack_align); - - std::strcpy(vm::get_ptr(arg_addr), arg.c_str()); - - argv[argc++] = arg_addr; - } - return *this; } @@ -740,10 +719,6 @@ public: spu.Run(); - spu.GPR[3].from64(argc); - spu.GPR[4].from64(argv.addr()); - spu.GPR[5].from64(envp.addr()); - return *this; } }; diff --git a/rpcs3/Emu/DbgCommand.h b/rpcs3/Emu/DbgCommand.h index f3e7f03943..2973079729 100644 --- a/rpcs3/Emu/DbgCommand.h +++ b/rpcs3/Emu/DbgCommand.h @@ -32,7 +32,6 @@ enum DbgCommand DID_EXEC_THREAD, DID_REGISTRED_CALLBACK, DID_UNREGISTRED_CALLBACK, - DID_EXIT_THR_SYSCALL, DID_LAST_COMMAND, }; diff --git a/rpcs3/Emu/Event.cpp b/rpcs3/Emu/Event.cpp index 531d974fe7..107474b0a6 100644 --- a/rpcs3/Emu/Event.cpp +++ b/rpcs3/Emu/Event.cpp @@ -12,7 +12,7 @@ void EventManager::Init() void EventManager::Clear() { - eq_map.clear(); + m_map.clear(); } bool EventManager::CheckKey(u64 key) @@ -23,29 +23,9 @@ bool EventManager::CheckKey(u64 key) return false; } - std::lock_guard lock(m_lock); + std::lock_guard lock(m_mutex); - return eq_map.find(key) != eq_map.end(); -} - -bool EventManager::RegisterKey(const std::shared_ptr& data) -{ - if (!data->key) - { - // always ok - return true; - } - - std::lock_guard lock(m_lock); - - if (eq_map.find(data->key) != eq_map.end()) - { - return false; - } - - eq_map[data->key] = data; - - return true; + return m_map.find(key) != m_map.end(); } bool EventManager::UnregisterKey(u64 key) @@ -56,12 +36,12 @@ bool EventManager::UnregisterKey(u64 key) return true; } - std::lock_guard lock(m_lock); + std::lock_guard lock(m_mutex); - auto f = eq_map.find(key); - if (f != eq_map.end()) + auto f = m_map.find(key); + if (f != m_map.end()) { - eq_map.erase(f); + m_map.erase(f); return true; } @@ -76,10 +56,10 @@ std::shared_ptr EventManager::GetEventQueue(u64 key) return nullptr; } - std::lock_guard lock(m_lock); + std::lock_guard lock(m_mutex); - auto f = eq_map.find(key); - if (f != eq_map.end()) + auto f = m_map.find(key); + if (f != m_map.end()) { return f->second; } diff --git a/rpcs3/Emu/Event.h b/rpcs3/Emu/Event.h index 6569f54a55..b4099938c9 100644 --- a/rpcs3/Emu/Event.h +++ b/rpcs3/Emu/Event.h @@ -1,24 +1,37 @@ #pragma once +#include "Emu/IdManager.h" + struct lv2_event_queue_t; class EventManager { - std::mutex m_lock; - std::unordered_map> eq_map; + std::mutex m_mutex; + std::unordered_map> m_map; public: void Init(); void Clear(); bool CheckKey(u64 key); - bool RegisterKey(const std::shared_ptr& data); bool UnregisterKey(u64 key); - template std::shared_ptr MakeEventQueue(Args&&... args) + template::value>> std::shared_ptr MakeEventQueue(u64 key, Args&&... args) { - const auto queue = std::make_shared(args...); + std::lock_guard lock(m_mutex); - return RegisterKey(queue) ? queue : nullptr; + if (key && m_map.find(key) != m_map.end()) + { + return nullptr; + } + + auto queue = Emu.GetIdManager().make_ptr(std::forward(args)...); + + if (key) + { + m_map[key] = queue; + } + + return queue; } std::shared_ptr GetEventQueue(u64 key); diff --git a/rpcs3/Emu/FS/vfsStreamMemory.cpp b/rpcs3/Emu/FS/vfsStreamMemory.cpp index 67134f8d3c..c05196adaf 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.cpp +++ b/rpcs3/Emu/FS/vfsStreamMemory.cpp @@ -10,7 +10,7 @@ u64 vfsStreamMemory::Write(const void* src, u64 count) count = m_size - m_pos; } - memcpy(vm::get_ptr(vm::cast(m_addr + m_pos)), src, count); + memcpy(vm::get_ptr(VM_CAST(m_addr + m_pos)), src, count); m_pos += count; return count; } @@ -23,7 +23,7 @@ u64 vfsStreamMemory::Read(void* dst, u64 count) count = m_size - m_pos; } - memcpy(dst, vm::get_ptr(vm::cast(m_addr + m_pos)), count); + memcpy(dst, vm::get_ptr(VM_CAST(m_addr + m_pos)), count); m_pos += count; return count; } diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 6cee9d4bfc..1b8994f4eb 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -21,23 +21,36 @@ class ID_data_t final public: const std::shared_ptr data; const std::type_info& info; + const std::size_t hash; const u32 type; + const u32 id; - template force_inline ID_data_t(std::shared_ptr data, u32 type) + template force_inline ID_data_t(std::shared_ptr data, u32 type, u32 id) : data(std::move(data)) , info(typeid(T)) + , hash(typeid(T).hash_code()) , type(type) + , id(id) { } - ID_data_t(const ID_data_t& right) = delete; + ID_data_t(const ID_data_t& right) + : data(right.data) + , info(right.info) + , hash(right.hash) + , type(right.type) + , id(right.id) + { + } ID_data_t& operator =(const ID_data_t& right) = delete; ID_data_t(ID_data_t&& right) : data(std::move(const_cast&>(right.data))) , info(right.info) + , hash(right.hash) , type(right.type) + , id(right.id) { } @@ -53,7 +66,7 @@ class ID_manager public: // check if ID exists and has specified type - template bool check_id(const u32 id) + template bool check_id(u32 id) { std::lock_guard lock(m_mutex); @@ -62,8 +75,18 @@ public: return f != m_id_map.end() && f->second.info == typeid(T); } + // check if ID exists and has specified type + bool check_id(u32 id, u32 type) + { + std::lock_guard lock(m_mutex); + + auto f = m_id_map.find(id); + + return f != m_id_map.end() && f->second.type == type; + } + // must be called from the constructor called through make() to get further ID of current object - u32 get_cur_id() + u32 get_current_id() { // if called correctly from make(), the mutex is locked // if called illegally, the mutex is unlocked with high probability (wrong ID is returned otherwise) @@ -73,7 +96,7 @@ public: // schedule unlocking std::lock_guard lock(m_mutex, std::adopt_lock); - throw "Invalid get_cur_id() usage"; + throw EXCEPTION("Current ID is not available"); } return m_cur_id; @@ -86,36 +109,41 @@ public: m_id_map.clear(); m_cur_id = 1; // first ID } - - // add new ID using existing std::shared_ptr (not recommended, use make() instead) - template u32 add(std::shared_ptr data, u32 type = ID_type::type) - { - std::lock_guard lock(m_mutex); - m_id_map.emplace(m_cur_id, ID_data_t(std::move(data), type)); - - return m_cur_id++; - } - - // add new ID of specified type with specified constructor arguments (passed to std::make_shared<>) - template u32 make(Args&&... args) + // add new ID of specified type with specified constructor arguments (returns object) + template::value>> std::shared_ptr make_ptr(Args&&... args) { std::lock_guard lock(m_mutex); const u32 type = ID_type::type; - m_id_map.emplace(m_cur_id, ID_data_t(std::make_shared(args...), type)); + auto ptr = std::make_shared(std::forward(args)...); + + m_id_map.emplace(m_cur_id, ID_data_t(ptr, type, m_cur_id)); + + return m_cur_id++, std::move(ptr); + } + + // add new ID of specified type with specified constructor arguments (returns id) + template std::enable_if_t::value, u32> make(Args&&... args) + { + std::lock_guard lock(m_mutex); + + const u32 type = ID_type::type; + + m_id_map.emplace(m_cur_id, ID_data_t(std::make_shared(std::forward(args)...), type, m_cur_id)); return m_cur_id++; } - template std::shared_ptr get(u32 id) + // load ID created with type Orig, optionally static_cast to T + template auto get(u32 id) -> decltype(std::shared_ptr(static_cast(std::declval()))) { std::lock_guard lock(m_mutex); auto f = m_id_map.find(id); - if (f == m_id_map.end() || f->second.info != typeid(T)) + if (f == m_id_map.end() || f->second.info != typeid(Orig)) { return nullptr; } @@ -123,6 +151,26 @@ public: return std::static_pointer_cast(f->second.data); } + // load all IDs created with type Orig, optionally static_cast to T + template auto get_all() -> std::vector(static_cast(std::declval())))> + { + std::lock_guard lock(m_mutex); + + std::vector> result; + + const std::size_t hash = typeid(Orig).hash_code(); + + for (auto& v : m_id_map) + { + if (v.second.hash == hash && v.second.info == typeid(Orig)) + { + result.emplace_back(std::static_pointer_cast(v.second.data)); + } + } + + return result; + } + template bool remove(u32 id) { std::lock_guard lock(m_mutex); @@ -139,7 +187,26 @@ public: return true; } - u32 get_count_by_type(u32 type) + template u32 get_count() + { + std::lock_guard lock(m_mutex); + + u32 result = 0; + + const std::size_t hash = typeid(T).hash_code(); + + for (auto& v : m_id_map) + { + if (v.second.hash == hash && v.second.info == typeid(T)) + { + result++; + } + } + + return result; + } + + u32 get_count(u32 type) { std::lock_guard lock(m_mutex); @@ -156,7 +223,28 @@ public: return result; } - std::set get_IDs_by_type(u32 type) + // get sorted ID list + template std::set get_IDs() + { + std::lock_guard lock(m_mutex); + + std::set result; + + const std::size_t hash = typeid(T).hash_code(); + + for (auto& v : m_id_map) + { + if (v.second.hash == hash && v.second.info == typeid(T)) + { + result.insert(v.first); + } + } + + return result; + } + + // get sorted ID list + std::set get_IDs(u32 type) { std::lock_guard lock(m_mutex); @@ -172,4 +260,40 @@ public: return result; } + + template std::vector get_data() + { + std::lock_guard lock(m_mutex); + + std::vector result; + + const std::size_t hash = typeid(T).hash_code(); + + for (auto& v : m_id_map) + { + if (v.second.hash == hash && v.second.info == typeid(T)) + { + result.emplace_back(v.second); + } + } + + return result; + } + + std::vector get_data(u32 type) + { + std::lock_guard lock(m_mutex); + + std::vector result; + + for (auto& v : m_id_map) + { + if (v.second.type == type) + { + result.emplace_back(v.second); + } + } + + return result; + } }; diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 9c8f038187..25d21fd717 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -4,8 +4,6 @@ MemoryBase Memory; -std::mutex g_memory_mutex; - void MemoryBase::Init(MemoryType type) { if (m_inited) return; @@ -68,9 +66,25 @@ void MemoryBase::Close() bool MemoryBase::Map(const u32 addr, const u32 size) { - assert(size && (size | addr) % 4096 == 0); + if (!size || (size | addr) % 4096) + { + throw EXCEPTION("Invalid arguments (addr=0x%x, size=0x%x)", addr, size); + } - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); + + for (auto& block : MemoryBlocks) + { + if (block->GetStartAddr() >= addr && block->GetStartAddr() <= addr + size - 1) + { + return false; + } + + if (addr >= block->GetStartAddr() && addr <= block->GetEndAddr()) + { + return false; + } + } for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { @@ -80,15 +94,14 @@ bool MemoryBase::Map(const u32 addr, const u32 size) } } - MemoryBlocks.push_back((new MemoryBlock())->SetRange(addr, size)); + MemoryBlocks.push_back((new DynamicMemoryBlock())->SetRange(addr, size)); - LOG_WARNING(MEMORY, "Memory mapped at 0x%x: size=0x%x", addr, size); return true; } bool MemoryBase::Unmap(const u32 addr) { - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); for (u32 i = 0; i < MemoryBlocks.size(); i++) { @@ -99,9 +112,25 @@ bool MemoryBase::Unmap(const u32 addr) return true; } } + return false; } +MemoryBlock* MemoryBase::Get(const u32 addr) +{ + std::lock_guard lock(Memory.mutex); + + for (auto& block : MemoryBlocks) + { + if (block->GetStartAddr() == addr) + { + return block; + } + } + + return nullptr; +} + MemBlockInfo::MemBlockInfo(u32 addr, u32 size) : MemInfo(addr, size) { @@ -175,7 +204,7 @@ DynamicMemoryBlockBase::DynamicMemoryBlockBase() const u32 DynamicMemoryBlockBase::GetUsedSize() const { - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); u32 size = 0; @@ -194,7 +223,7 @@ bool DynamicMemoryBlockBase::IsInMyRange(const u32 addr, const u32 size) MemoryBlock* DynamicMemoryBlockBase::SetRange(const u32 start, const u32 size) { - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); m_max_size = PAGE_4K(size); if (!MemoryBlock::SetRange(start, 0)) @@ -208,7 +237,7 @@ MemoryBlock* DynamicMemoryBlockBase::SetRange(const u32 start, const u32 size) void DynamicMemoryBlockBase::Delete() { - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); m_allocated.clear(); m_max_size = 0; @@ -230,7 +259,7 @@ bool DynamicMemoryBlockBase::AllocFixed(u32 addr, u32 size) return false; } - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); for (u32 i = 0; i lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); for (u32 addr = MemoryBlock::GetStartAddr(); addr <= MemoryBlock::GetEndAddr() - exsize;) { @@ -312,7 +341,7 @@ bool DynamicMemoryBlockBase::Alloc() bool DynamicMemoryBlockBase::Free(u32 addr) { - std::lock_guard lock(g_memory_mutex); + std::lock_guard lock(Memory.mutex); for (u32 num = 0; num < m_allocated.size(); num++) { @@ -436,7 +465,7 @@ bool VirtualMemoryBlock::Read32(const u32 addr, u32* value) u32 realAddr; if (!getRealAddr(addr, realAddr)) return false; - *value = vm::read32(realAddr); + *value = vm::ps3::read32(realAddr); return true; } @@ -445,7 +474,7 @@ bool VirtualMemoryBlock::Write32(const u32 addr, const u32 value) u32 realAddr; if (!getRealAddr(addr, realAddr)) return false; - vm::write32(realAddr, value); + vm::ps3::write32(realAddr, value); return true; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index a7d82989ac..c21b34bb49 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -2,11 +2,6 @@ #include "MemoryBlock.h" -using std::nullptr_t; - -#define safe_delete(x) do {delete (x);(x)=nullptr;} while(0) -#define safe_free(x) do {free(x);(x)=nullptr;} while(0) - enum MemoryType { Memory_PS3, @@ -19,6 +14,8 @@ class MemoryBase std::vector MemoryBlocks; public: + std::mutex mutex; + MemoryBlock* UserMemory; DynamicMemoryBlock MainMem; @@ -31,7 +28,8 @@ public: { DynamicMemoryBlock RAM; DynamicMemoryBlock Userspace; - } PSV; + } + PSV; struct { @@ -40,7 +38,8 @@ public: DynamicMemoryBlock RAM; DynamicMemoryBlock Kernel; DynamicMemoryBlock Userspace; - } PSP; + } + PSP; bool m_inited; @@ -54,10 +53,6 @@ public: Close(); } - void RegisterPages(u32 addr, u32 size); - - void UnregisterPages(u32 addr, u32 size); - void Init(MemoryType type); void Close(); @@ -85,6 +80,8 @@ public: bool Map(const u32 addr, const u32 size); bool Unmap(const u32 addr); + + MemoryBlock* Get(const u32 addr); }; extern MemoryBase Memory; diff --git a/rpcs3/Emu/Memory/atomic.h b/rpcs3/Emu/Memory/atomic.h index 6eea856d7c..385a3477db 100644 --- a/rpcs3/Emu/Memory/atomic.h +++ b/rpcs3/Emu/Memory/atomic.h @@ -32,6 +32,35 @@ template struct _to_atomic_subtype template using atomic_subtype_t = typename _to_atomic_subtype::type; +// result wrapper to deal with void result type +template struct atomic_op_result_t +{ + RT result; + + template inline atomic_op_result_t(T func, Args&&... args) + : result(std::move(func(std::forward(args)...))) + { + } + + inline RT move() + { + return std::move(result); + } +}; + +// void specialization +template<> struct atomic_op_result_t +{ + template inline atomic_op_result_t(T func, Args&&... args) + { + func(std::forward(args)...); + } + + inline void move() + { + } +}; + template union _atomic_base { using type = std::remove_cv_t; @@ -55,6 +84,27 @@ template union _atomic_base return reinterpret_cast(value); } +private: + template force_inline static void write_relaxed(volatile T2& data, const T2& value) + { + data = value; + } + + force_inline static void write_relaxed(volatile u128& data, const u128& value) + { + sync_lock_test_and_set(&data, value); + } + + template force_inline static T2 read_relaxed(const volatile T2& data) + { + return data; + } + + force_inline static u128 read_relaxed(const volatile u128& value) + { + return sync_val_compare_and_swap(const_cast(&value), {}, {}); + } + public: // atomically compare data with cmp, replace with exch if equal, return previous data value anyway force_inline const type compare_and_swap(const type& cmp, const type& exch) volatile @@ -69,7 +119,7 @@ public: } // read data with memory barrier - force_inline const type read_sync() const volatile + force_inline const type load_sync() const volatile { const subtype zero = {}; return from_subtype(sync_val_compare_and_swap(const_cast(&sub_data), zero, zero)); @@ -81,73 +131,41 @@ public: return from_subtype(sync_lock_test_and_set(&sub_data, to_subtype(exch))); } - // read data without memory barrier - force_inline const type read_relaxed() const volatile + // read data without memory barrier (works as load_sync() for 128 bit) + force_inline const type load() const volatile { - const subtype value = const_cast(sub_data); - return from_subtype(value); + return from_subtype(read_relaxed(sub_data)); } - // write data without memory barrier - force_inline void write_relaxed(const type& value) volatile + // write data without memory barrier (works as exchange() for 128 bit, discarding result) + force_inline void store(const type& value) volatile { - const_cast(sub_data) = to_subtype(value); + write_relaxed(sub_data, to_subtype(value)); } - // perform atomic operation on data - template force_inline void atomic_op(const FT atomic_proc) volatile + // perform an atomic operation on data (callable object version, first arg is a reference to atomic type) + template auto atomic_op(F func, Args&&... args) volatile -> decltype(func(std::declval(), args...)) { while (true) { - const subtype old = const_cast(sub_data); + // read the old value from memory + const subtype old = read_relaxed(sub_data); + + // copy the old value subtype _new = old; - atomic_proc(to_type(_new)); // function should accept reference to T type - if (sync_bool_compare_and_swap(&sub_data, old, _new)) return; + + // call atomic op for the local copy of the old value and save the return value of the function + atomic_op_result_t> result(func, to_type(_new), args...); + + // atomically compare value with `old`, replace with `_new` and return on success + if (sync_bool_compare_and_swap(&sub_data, old, _new)) return result.move(); } } - // perform atomic operation on data with special exit condition (if intermediate result != proceed_value) - template force_inline RT atomic_op(const RT proceed_value, const FT atomic_proc) volatile + // perform an atomic operation on data (member function version) + template::value>> auto atomic_op(RT(CT::* func)(FArgs...), Args&&... args) volatile -> decltype((std::declval().*func)(args...)) { - while (true) - { - const subtype old = const_cast(sub_data); - subtype _new = old; - auto res = static_cast(atomic_proc(to_type(_new))); // function should accept reference to T type and return some value - if (res != proceed_value) return res; - if (sync_bool_compare_and_swap(&sub_data, old, _new)) return proceed_value; - } - } - - // perform atomic operation on data with additional memory barrier - template force_inline void atomic_op_sync(const FT atomic_proc) volatile - { - const subtype zero = {}; - subtype old = sync_val_compare_and_swap(&sub_data, zero, zero); - while (true) - { - subtype _new = old; - atomic_proc(to_type(_new)); // function should accept reference to T type - const subtype val = sync_val_compare_and_swap(&sub_data, old, _new); - if (val == old) return; - old = val; - } - } - - // perform atomic operation on data with additional memory barrier and special exit condition (if intermediate result != proceed_value) - template force_inline RT atomic_op_sync(const RT proceed_value, const FT atomic_proc) volatile - { - const subtype zero = {}; - subtype old = sync_val_compare_and_swap(&sub_data, zero, zero); - while (true) - { - subtype _new = old; - auto res = static_cast(atomic_proc(to_type(_new))); // function should accept reference to T type and return some value - if (res != proceed_value) return res; - const subtype val = sync_val_compare_and_swap(&sub_data, old, _new); - if (val == old) return proceed_value; - old = val; - } + return atomic_op(std::mem_fn(func), std::forward(args)...); } // atomic bitwise OR, returns previous data @@ -174,128 +192,133 @@ public: return from_subtype(sync_fetch_and_xor(&sub_data, to_subtype(right))); } - force_inline const type operator |= (const type& right) volatile + force_inline const type operator |=(const type& right) volatile { return from_subtype(sync_fetch_and_or(&sub_data, to_subtype(right)) | to_subtype(right)); } - force_inline const type operator &= (const type& right) volatile + force_inline const type operator &=(const type& right) volatile { return from_subtype(sync_fetch_and_and(&sub_data, to_subtype(right)) & to_subtype(right)); } - force_inline const type operator ^= (const type& right) volatile + force_inline const type operator ^=(const type& right) volatile { return from_subtype(sync_fetch_and_xor(&sub_data, to_subtype(right)) ^ to_subtype(right)); } }; -template using if_integral_le_t = std::enable_if_t::value && std::is_integral::value, le_t>; -template using if_integral_be_t = std::enable_if_t::value && std::is_integral::value, be_t>; +template using if_integral_t = std::enable_if_t::value>; -template inline if_integral_le_t operator ++(_atomic_base>& left) +template> inline T operator ++(_atomic_base& left) { return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1) + 1); } -template inline if_integral_le_t operator --(_atomic_base>& left) +template> inline T operator --(_atomic_base& left) { return left.from_subtype(sync_fetch_and_sub(&left.sub_data, 1) - 1); } -template inline if_integral_le_t operator ++(_atomic_base>& left, int) +template> inline T operator ++(_atomic_base& left, int) { return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1)); } -template inline if_integral_le_t operator --(_atomic_base>& left, int) +template> inline T operator --(_atomic_base& left, int) { return left.from_subtype(sync_fetch_and_sub(&left.sub_data, 1)); } -template inline if_integral_le_t operator +=(_atomic_base>& left, T2 right) +template> inline auto operator +=(_atomic_base& left, T2 right) -> decltype(std::declval() + std::declval()) { return left.from_subtype(sync_fetch_and_add(&left.sub_data, right) + right); } -template inline if_integral_le_t operator -=(_atomic_base>& left, T2 right) +template> inline auto operator -=(_atomic_base& left, T2 right) -> decltype(std::declval() - std::declval()) { return left.from_subtype(sync_fetch_and_sub(&left.sub_data, right) - right); } -template inline if_integral_be_t operator ++(_atomic_base>& left) +template> inline le_t operator ++(_atomic_base>& left) { - be_t result; - - left.atomic_op([&result](be_t& value) - { - result = ++value; - }); - - return result; + return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1) + 1); } -template inline if_integral_be_t operator --(_atomic_base>& left) +template> inline le_t operator --(_atomic_base>& left) { - be_t result; - - left.atomic_op([&result](be_t& value) - { - result = --value; - }); - - return result; + return left.from_subtype(sync_fetch_and_sub(&left.sub_data, 1) - 1); } -template inline if_integral_be_t operator ++(_atomic_base>& left, int) +template> inline le_t operator ++(_atomic_base>& left, int) { - be_t result; - - left.atomic_op([&result](be_t& value) - { - result = value++; - }); - - return result; + return left.from_subtype(sync_fetch_and_add(&left.sub_data, 1)); } -template inline if_integral_be_t operator --(_atomic_base>& left, int) +template> inline le_t operator --(_atomic_base>& left, int) { - be_t result; - - left.atomic_op([&result](be_t& value) - { - result = value--; - }); - - return result; + return left.from_subtype(sync_fetch_and_sub(&left.sub_data, 1)); } -template inline if_integral_be_t operator +=(_atomic_base>& left, T2 right) +template> inline auto operator +=(_atomic_base>& left, T2 right) -> decltype(std::declval() + std::declval()) { - be_t result; - - left.atomic_op([&result, right](be_t& value) - { - result = (value += right); - }); - - return result; + return left.from_subtype(sync_fetch_and_add(&left.sub_data, right) + right); } -template inline if_integral_be_t operator -=(_atomic_base>& left, T2 right) +template> inline auto operator -=(_atomic_base>& left, T2 right) -> decltype(std::declval() - std::declval()) { - be_t result; - - left.atomic_op([&result, right](be_t& value) - { - result = (value -= right); - }); - - return result; + return left.from_subtype(sync_fetch_and_sub(&left.sub_data, right) - right); } -template using atomic = _atomic_base; // Atomic Type with native endianness (for emulator memory) +template> inline be_t operator ++(_atomic_base>& left) +{ + return left.atomic_op([](be_t& value) -> be_t + { + return ++value; + }); +} + +template> inline be_t operator --(_atomic_base>& left) +{ + return left.atomic_op([](be_t& value) -> be_t + { + return --value; + }); +} + +template> inline be_t operator ++(_atomic_base>& left, int) +{ + return left.atomic_op([](be_t& value) -> be_t + { + return value++; + }); +} + +template> inline be_t operator --(_atomic_base>& left, int) +{ + return left.atomic_op([](be_t& value) -> be_t + { + return value--; + }); +} + +template> inline auto operator +=(_atomic_base>& left, T2 right) -> be_t() + std::declval())> +{ + return left.atomic_op([right](be_t& value) -> be_t + { + return value += right; + }); +} + +template> inline auto operator -=(_atomic_base>& left, T2 right) -> be_t() - std::declval())> +{ + return left.atomic_op([right](be_t& value) -> be_t + { + return value -= right; + }); +} + +template using atomic_t = _atomic_base; // Atomic Type with native endianness (for emulator memory) template using atomic_be_t = _atomic_base>; // Atomic BE Type (for PS3 virtual memory) diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index ef10b43fe6..d1e11c1562 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -4,10 +4,9 @@ #include "Emu/System.h" #include "Emu/CPU/CPUThread.h" #include "Emu/Cell/PPUThread.h" +#include "Emu/Cell/SPUThread.h" #include "Emu/ARMv7/ARMv7Thread.h" -#include "Emu/SysCalls/lv2/sys_time.h" - #ifdef _WIN32 #include #else @@ -75,17 +74,16 @@ namespace vm void* g_base_addr = (atexit(finalize), initialize()); void* g_priv_addr; - std::array, 0x100000000ull / 4096> g_page_info = {}; // information about every page + std::array, 0x100000000ull / 4096> g_page_info = {}; // information about every page class reservation_mutex_t { - std::atomic m_owner; + atomic_t m_owner{}; std::condition_variable m_cv; - std::mutex m_cv_mutex; + std::mutex m_mutex; public: reservation_mutex_t() - : m_owner(nullptr) { } @@ -93,21 +91,24 @@ namespace vm never_inline void lock() { - NamedThreadBase* owner = GetCurrentNamedThread(); - NamedThreadBase* old = nullptr; + auto owner = get_current_thread_ctrl(); - while (!m_owner.compare_exchange_strong(old, owner)) + std::unique_lock lock(m_mutex, std::defer_lock); + + while (auto old = m_owner.compare_and_swap(nullptr, owner)) { - std::unique_lock cv_lock(m_cv_mutex); - - m_cv.wait_for(cv_lock, std::chrono::milliseconds(1)); - if (old == owner) { - throw __FUNCTION__; + throw EXCEPTION("Deadlock"); } - old = nullptr; + if (!lock) + { + lock.lock(); + continue; + } + + m_cv.wait_for(lock, std::chrono::milliseconds(1)); } do_notify = true; @@ -115,11 +116,11 @@ namespace vm never_inline void unlock() { - NamedThreadBase* owner = GetCurrentNamedThread(); + auto owner = get_current_thread_ctrl(); - if (!m_owner.compare_exchange_strong(owner, nullptr)) + if (!m_owner.compare_and_swap_test(owner, nullptr)) { - throw __FUNCTION__; + throw EXCEPTION("Lost lock"); } if (do_notify) @@ -131,7 +132,7 @@ namespace vm }; std::function g_reservation_cb = nullptr; - NamedThreadBase* g_reservation_owner = nullptr; + const thread_ctrl_t* g_reservation_owner = nullptr; u32 g_reservation_addr = 0; u32 g_reservation_size = 0; @@ -140,8 +141,6 @@ namespace vm void _reservation_set(u32 addr, bool no_access = false) { - //const auto stamp0 = get_time(); - #ifdef _WIN32 DWORD old; if (!VirtualProtect(vm::get_ptr(addr & ~0xfff), 4096, no_access ? PAGE_NOACCESS : PAGE_READONLY, &old)) @@ -149,18 +148,14 @@ namespace vm if (mprotect(vm::get_ptr(addr & ~0xfff), 4096, no_access ? PROT_NONE : PROT_READ)) #endif { - throw fmt::format("vm::_reservation_set() failed (addr=0x%x)", addr); + throw EXCEPTION("System failure (addr=0x%x)", addr); } - - //LOG_NOTICE(MEMORY, "VirtualProtect: %f us", (get_time() - stamp0) / 80.f); } bool _reservation_break(u32 addr) { if (g_reservation_addr >> 12 == addr >> 12) { - //const auto stamp0 = get_time(); - #ifdef _WIN32 DWORD old; if (!VirtualProtect(vm::get_ptr(addr & ~0xfff), 4096, PAGE_READWRITE, &old)) @@ -168,11 +163,9 @@ namespace vm if (mprotect(vm::get_ptr(addr & ~0xfff), 4096, PROT_READ | PROT_WRITE)) #endif { - throw fmt::format("vm::_reservation_break() failed (addr=0x%x)", addr); + throw EXCEPTION("System failure (addr=0x%x)", addr); } - //LOG_NOTICE(MEMORY, "VirtualAlloc: %f us", (get_time() - stamp0) / 80.f); - if (g_reservation_cb) { g_reservation_cb(); @@ -196,10 +189,8 @@ namespace vm return _reservation_break(addr); } - bool reservation_acquire(void* data, u32 addr, u32 size, const std::function& callback) + bool reservation_acquire(void* data, u32 addr, u32 size, std::function callback) { - //const auto stamp0 = get_time(); - bool broken = false; assert(size == 1 || size == 2 || size == 4 || size == 8 || size == 128); @@ -208,10 +199,10 @@ namespace vm { std::lock_guard lock(g_reservation_mutex); - u8 flags = g_page_info[addr >> 12].read_relaxed(); + u8 flags = g_page_info[addr >> 12].load(); if (!(flags & page_writable) || !(flags & page_allocated) || (flags & page_no_reservations)) { - throw fmt::format("vm::reservation_acquire(addr=0x%x, size=0x%x) failed (invalid page flags: 0x%x)", addr, size, flags); + throw EXCEPTION("Invalid page flags (addr=0x%x, size=0x%x, flags=0x%x)", addr, size, flags); } // silent unlocking to prevent priority boost for threads going to break reservation @@ -232,8 +223,8 @@ namespace vm // set additional information g_reservation_addr = addr; g_reservation_size = size; - g_reservation_owner = GetCurrentNamedThread(); - g_reservation_cb = callback; + g_reservation_owner = get_current_thread_ctrl(); + g_reservation_cb = std::move(callback); // copy data memcpy(data, vm::get_ptr(addr), size); @@ -244,7 +235,7 @@ namespace vm bool reservation_acquire_no_cb(void* data, u32 addr, u32 size) { - return reservation_acquire(data, addr, size); + return reservation_acquire(data, addr, size, nullptr); } bool reservation_update(u32 addr, const void* data, u32 size) @@ -254,7 +245,7 @@ namespace vm std::lock_guard lock(g_reservation_mutex); - if (g_reservation_owner != GetCurrentNamedThread() || g_reservation_addr != addr || g_reservation_size != size) + if (g_reservation_owner != get_current_thread_ctrl() || g_reservation_addr != addr || g_reservation_size != size) { // atomic update failed return false; @@ -304,10 +295,10 @@ namespace vm void reservation_free() { - std::lock_guard lock(g_reservation_mutex); - - if (g_reservation_owner == GetCurrentNamedThread()) + if (g_reservation_owner == get_current_thread_ctrl()) { + std::lock_guard lock(g_reservation_mutex); + _reservation_break(g_reservation_addr); } } @@ -320,7 +311,7 @@ namespace vm std::lock_guard lock(g_reservation_mutex); // break previous reservation - if (g_reservation_owner != GetCurrentNamedThread() || g_reservation_addr != addr || g_reservation_size != size) + if (g_reservation_owner != get_current_thread_ctrl() || g_reservation_addr != addr || g_reservation_size != size) { if (g_reservation_owner) { @@ -334,7 +325,7 @@ namespace vm // set additional information g_reservation_addr = addr; g_reservation_size = size; - g_reservation_owner = GetCurrentNamedThread(); + g_reservation_owner = get_current_thread_ctrl(); g_reservation_cb = nullptr; // may not be necessary @@ -355,9 +346,9 @@ namespace vm for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - if (g_page_info[i].read_relaxed()) + if (g_page_info[i].load()) { - throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (already mapped at 0x%x)", addr, size, flags, i * 4096); + throw EXCEPTION("Memory already mapped (addr=0x%x, size=0x%x, flags=0x%x, current_addr=0x%x)", addr, size, flags, i * 4096); } } @@ -372,14 +363,14 @@ namespace vm if (mprotect(priv_addr, size, PROT_READ | PROT_WRITE) || mprotect(real_addr, size, protection)) #endif { - throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (API)", addr, size, flags); + throw EXCEPTION("System failure (addr=0x%x, size=0x%x, flags=0x%x)", addr, size, flags); } for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { if (g_page_info[i].exchange(flags | page_allocated)) { - throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (concurrent access at 0x%x)", addr, size, flags, i * 4096); + throw EXCEPTION("Concurrent access (addr=0x%x, size=0x%x, flags=0x%x, current_addr=0x%x)", addr, size, flags, i * 4096); } } @@ -398,7 +389,7 @@ namespace vm for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - if ((g_page_info[i].read_relaxed() & flags_test) != (flags_test | page_allocated)) + if ((g_page_info[i].load() & flags_test) != (flags_test | page_allocated)) { return false; } @@ -431,7 +422,7 @@ namespace vm if (mprotect(real_addr, 4096, protection)) #endif { - throw fmt::format("vm::page_protect(addr=0x%x, size=0x%x, flags_test=0x%x, flags_set=0x%x, flags_clear=0x%x) failed (API)", addr, size, flags_test, flags_set, flags_clear); + throw EXCEPTION("System failure (addr=0x%x, size=0x%x, flags_test=0x%x, flags_set=0x%x, flags_clear=0x%x)", addr, size, flags_test, flags_set, flags_clear); } } } @@ -447,9 +438,9 @@ namespace vm for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - if (!(g_page_info[i].read_relaxed() & page_allocated)) + if (!(g_page_info[i].load() & page_allocated)) { - throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (not mapped at 0x%x)", addr, size, i * 4096); + throw EXCEPTION("Memory not mapped (addr=0x%x, size=0x%x, current_addr=0x%x)", addr, size, i * 4096); } } @@ -459,7 +450,7 @@ namespace vm if (!(g_page_info[i].exchange(0) & page_allocated)) { - throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (concurrent access at 0x%x)", addr, size, i * 4096); + throw EXCEPTION("Concurrent access (addr=0x%x, size=0x%x, current_addr=0x%x)", addr, size, i * 4096); } } @@ -474,7 +465,7 @@ namespace vm if (mprotect(real_addr, size, PROT_NONE) || mprotect(priv_addr, size, PROT_NONE)) #endif { - throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (API)", addr, size); + throw EXCEPTION("System failure (addr=0x%x, size=0x%x)", addr, size); } } @@ -491,7 +482,7 @@ namespace vm for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++) { - if ((g_page_info[i].read_sync() & page_allocated) != page_allocated) + if ((g_page_info[i].load() & page_allocated) != page_allocated) { return false; } @@ -526,29 +517,6 @@ namespace vm return g_locations[location].deallocator(addr); } - u32 get_addr(const void* real_pointer) - { - const u64 diff = (u64)real_pointer - (u64)g_base_addr; - const u32 res = (u32)diff; - - if (res == diff) - { - return res; - } - - if (real_pointer) - { - throw fmt::format("vm::get_addr(0x%016llx) failed: not a part of virtual memory", (u64)real_pointer); - } - - return 0; - } - - void error(const u64 addr, const char* func) - { - throw fmt::format("%s(): failed to cast 0x%llx (too big value)", func, addr); - } - namespace ps3 { u32 main_alloc(u32 size) @@ -634,15 +602,13 @@ namespace vm { PPUThread& context = static_cast(CPU); - old_pos = vm::cast(context.GPR[1], "SP"); + old_pos = VM_CAST(context.GPR[1]); context.GPR[1] -= align(size, 8); // room minimal possible size context.GPR[1] &= ~(align_v - 1); // fix stack alignment - if (context.GPR[1] < CPU.GetStackAddr()) + if (context.GPR[1] < context.stack_addr) { - LOG_ERROR(PPU, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%llx, stack=*0x%x)", size, align_v, context.GPR[1], CPU.GetStackAddr()); - context.GPR[1] = old_pos; - return 0; + throw EXCEPTION("Stack overflow (size=0x%x, align=0x%x, SP=0x%llx, stack=*0x%x)", size, align_v, old_pos, context.stack_addr); } else { @@ -653,23 +619,33 @@ namespace vm case CPU_THREAD_SPU: case CPU_THREAD_RAW_SPU: { - assert(!"stack_push(): SPU not supported"); - return 0; + SPUThread& context = static_cast(CPU); + + old_pos = context.GPR[1]._u32[3]; + context.GPR[1]._u32[3] -= align(size, 16); + context.GPR[1]._u32[3] &= ~(align_v - 1); + + if (context.GPR[1]._u32[3] >= 0x40000) // extremely rough + { + throw EXCEPTION("Stack overflow (size=0x%x, align=0x%x, SP=LS:0x%05x)", size, align_v, old_pos); + } + else + { + return context.GPR[1]._u32[3] + context.offset; + } } case CPU_THREAD_ARMv7: { - ARMv7Context& context = static_cast(CPU).context; + ARMv7Context& context = static_cast(CPU); old_pos = context.SP; context.SP -= align(size, 4); // room minimal possible size context.SP &= ~(align_v - 1); // fix stack alignment - if (context.SP < CPU.GetStackAddr()) + if (context.SP < context.stack_addr) { - LOG_ERROR(ARMv7, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%x, stack=*0x%x)", size, align_v, context.SP, CPU.GetStackAddr()); - context.SP = old_pos; - return 0; + throw EXCEPTION("Stack overflow (size=0x%x, align=0x%x, SP=0x%x, stack=*0x%x)", size, align_v, context.SP, context.stack_addr); } else { @@ -679,8 +655,7 @@ namespace vm default: { - assert(!"stack_push(): invalid thread type"); - return 0; + throw EXCEPTION("Invalid thread type (%d)", CPU.GetId()); } } } @@ -693,9 +668,9 @@ namespace vm { PPUThread& context = static_cast(CPU); - if (context.GPR[1] != addr && !Emu.IsStopped()) + if (context.GPR[1] != addr) { - LOG_ERROR(PPU, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%llx)", addr, old_pos, context.GPR[1]); + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=0x%llx, old_pos=0x%x)", addr, context.GPR[1], old_pos); } context.GPR[1] = old_pos; @@ -705,17 +680,24 @@ namespace vm case CPU_THREAD_SPU: case CPU_THREAD_RAW_SPU: { - assert(!"stack_pop(): SPU not supported"); + SPUThread& context = static_cast(CPU); + + if (context.GPR[1]._u32[3] + context.offset != addr) + { + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=LS:0x%05x, old_pos=LS:0x%05x)", addr, context.GPR[1]._u32[3], old_pos); + } + + context.GPR[1]._u32[3] = old_pos; return; } case CPU_THREAD_ARMv7: { - ARMv7Context& context = static_cast(CPU).context; + ARMv7Context& context = static_cast(CPU); - if (context.SP != addr && !Emu.IsStopped()) + if (context.SP != addr) { - LOG_ERROR(ARMv7, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%x)", addr, old_pos, context.SP); + throw EXCEPTION("Stack inconsistency (addr=0x%x, SP=0x%x, old_pos=0x%x)", addr, context.SP, old_pos); } context.SP = old_pos; @@ -724,8 +706,7 @@ namespace vm default: { - assert(!"stack_pop(): invalid thread type"); - return; + throw EXCEPTION("Invalid thread type (%d)", CPU.GetType()); } } } diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 8dea66bff7..f9d8b2b2ad 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -35,7 +35,7 @@ namespace vm // break the reservation, return true if it was successfully broken bool reservation_break(u32 addr); // read memory and reserve it for further atomic update, return true if the previous reservation was broken - bool reservation_acquire(void* data, u32 addr, u32 size, const std::function& callback = nullptr); + bool reservation_acquire(void* data, u32 addr, u32 size, std::function callback = nullptr); // same as reservation_acquire but does not have the callback argument // used by the PPU LLVM JIT since creating a std::function object in LLVM IR is too complicated bool reservation_acquire_no_cb(void* data, u32 addr, u32 size); @@ -64,149 +64,169 @@ namespace vm u32 alloc(u32 addr, u32 size, memory_location location = user_space); void dealloc(u32 addr, memory_location location = user_space); - template - T* get_ptr(u32 addr) + template T* get_ptr(u32 addr) { return reinterpret_cast(static_cast(g_base_addr) + addr); } - template - T& get_ref(u32 addr) + template T& get_ref(u32 addr) { return *get_ptr(addr); } - template - T* priv_ptr(u32 addr) + template T* priv_ptr(u32 addr) { return reinterpret_cast(static_cast(g_priv_addr) + addr); } - template - T& priv_ref(u32 addr) + template T& priv_ref(u32 addr) { return *priv_ptr(addr); } - u32 get_addr(const void* real_pointer); - - never_inline void error(const u64 addr, const char* func); - - template - struct cast_ptr + inline u32 get_addr(const void* real_pointer) { - static_assert(std::is_same::value, "Unsupported vm::cast() type"); + const std::uintptr_t diff = reinterpret_cast(real_pointer) - reinterpret_cast(g_base_addr); + const u32 res = static_cast(diff); - force_inline static u32 cast(const T& addr, const char* func) + if (res == diff) + { + return res; + } + + if (real_pointer) + { + throw EXCEPTION("Not a virtual memory pointer (%p)", real_pointer); + } + + return 0; + } + + template struct cast_ptr + { + static_assert(std::is_same::value, "Unsupported VM_CAST() type"); + + force_inline static u32 cast(const T& addr, const char* file, int line, const char* func) { return 0; } }; - template<> - struct cast_ptr + template<> struct cast_ptr { - force_inline static u32 cast(const u32 addr, const char* func) + force_inline static u32 cast(const u32 addr, const char* file, int line, const char* func) { return addr; } }; - template<> - struct cast_ptr + template<> struct cast_ptr { - force_inline static u32 cast(const u64 addr, const char* func) + force_inline static u32 cast(const u64 addr, const char* file, int line, const char* func) { const u32 res = static_cast(addr); + if (res != addr) { - vm::error(addr, func); + throw fmt::exception(file, line, func, "VM_CAST failed (addr=0x%llx)", addr); } return res; } }; - template - struct cast_ptr> + template struct cast_ptr> { - force_inline static u32 cast(const be_t& addr, const char* func) + force_inline static u32 cast(const be_t& addr, const char* file, int line, const char* func) { - return cast_ptr::cast(addr.value(), func); + return cast_ptr::cast(addr.value(), file, line, func); } }; - template - force_inline static u32 cast(const T& addr, const char* func = "vm::cast") + template struct cast_ptr> { - return cast_ptr::cast(addr, func); + force_inline static u32 cast(const le_t& addr, const char* file, int line, const char* func) + { + return cast_ptr::cast(addr.value(), file, line, func); + } + }; + + // function for VM_CAST + template force_inline static u32 impl_cast(const T& addr, const char* file, int line, const char* func) + { + return cast_ptr::cast(addr, file, line, func); + } + + static u8 read8(u32 addr) + { + return get_ref(addr); + } + + static void write8(u32 addr, u8 value) + { + get_ref(addr) = value; } namespace ps3 { void init(); - static u8 read8(u32 addr) + inline const be_t& read16(u32 addr) { - return get_ref(addr); + return get_ref>(addr); } - static void write8(u32 addr, u8 value) - { - get_ref(addr) = value; - } - - static u16 read16(u32 addr) - { - return get_ref>(addr); - } - - static void write16(u32 addr, be_t value) + inline void write16(u32 addr, be_t value) { get_ref>(addr) = value; } - static u32 read32(u32 addr) + inline void write16(u32 addr, u16 value) { - return get_ref>(addr); + get_ref>(addr) = value; } - static void write32(u32 addr, be_t value) + inline const be_t& read32(u32 addr) + { + return get_ref>(addr); + } + + inline void write32(u32 addr, be_t value) { get_ref>(addr) = value; } - static u64 read64(u32 addr) + inline void write32(u32 addr, u32 value) { - return get_ref>(addr); + get_ref>(addr) = value; } - static void write64(u32 addr, be_t value) + inline const be_t& read64(u32 addr) + { + return get_ref>(addr); + } + + inline void write64(u32 addr, be_t value) { get_ref>(addr) = value; } - static void write16(u32 addr, u16 value) + inline void write64(u32 addr, u64 value) { - write16(addr, be_t::make(value)); + get_ref>(addr) = value; } - static void write32(u32 addr, u32 value) + inline const be_t& read128(u32 addr) { - write32(addr, be_t::make(value)); + return get_ref>(addr); } - static void write64(u32 addr, u64 value) + inline void write128(u32 addr, be_t value) { - write64(addr, be_t::make(value)); + get_ref>(addr) = value; } - static u128 read128(u32 addr) - { - return get_ref>(addr); - } - - static void write128(u32 addr, u128 value) + inline void write128(u32 addr, u128 value) { get_ref>(addr) = value; } @@ -216,54 +236,64 @@ namespace vm { void init(); - static u8 read8(u32 addr) + inline const le_t& read16(u32 addr) { - return get_ref(addr); + return get_ref>(addr); } - static void write8(u32 addr, u8 value) + inline void write16(u32 addr, le_t value) { - get_ref(addr) = value; + get_ref>(addr) = value; } - static u16 read16(u32 addr) + inline void write16(u32 addr, u16 value) { - return get_ref(addr); + get_ref>(addr) = value; } - static void write16(u32 addr, u16 value) + inline const le_t& read32(u32 addr) { - get_ref(addr) = value; + return get_ref>(addr); } - static u32 read32(u32 addr) + inline void write32(u32 addr, le_t value) { - return get_ref(addr); + get_ref>(addr) = value; } - static void write32(u32 addr, u32 value) + inline void write32(u32 addr, u32 value) { - get_ref(addr) = value; + get_ref>(addr) = value; } - static u64 read64(u32 addr) + inline const le_t& read64(u32 addr) { - return get_ref(addr); + return get_ref>(addr); } - static void write64(u32 addr, u64 value) + inline void write64(u32 addr, le_t value) { - get_ref(addr) = value; + get_ref>(addr) = value; } - static u128 read128(u32 addr) + inline void write64(u32 addr, u64 value) { - return get_ref(addr); + get_ref>(addr) = value; } - static void write128(u32 addr, u128 value) + inline const le_t& read128(u32 addr) { - get_ref(addr) = value; + return get_ref>(addr); + } + + inline void write128(u32 addr, le_t value) + { + get_ref>(addr) = value; + } + + inline void write128(u32 addr, u128 value) + { + get_ref>(addr) = value; } } @@ -298,15 +328,15 @@ namespace vm u32 alloc_offset; template - ptr alloc(u32 count = 1) const + _ptr_base alloc(u32 count = 1) const { - return ptr::make(allocator(count * sizeof(T))); + return{ allocator(count * sizeof32(T)) }; } template - ptr fixed_alloc(u32 addr, u32 count = 1) const + _ptr_base fixed_alloc(u32 addr, u32 count = 1) const { - return ptr::make(fixed_allocator(addr, count * sizeof(T))); + return{ fixed_allocator(addr, count * sizeof32(T)) }; } }; diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 61c828f57b..66a68f9976 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -5,10 +5,23 @@ struct ARMv7Context; namespace vm { + // helper SFINAE type for vm::_ptr_base comparison operators (enables comparison between equal types and between any type and void*) + template using if_comparable_t = std::enable_if_t< + std::is_void::value || + std::is_void::value || + std::is_same, std::remove_cv_t>::value, + RT>; + + // helper SFINAE type for vm::_ptr_base pointer arithmetic operators and indirection (disabled for void and function pointers) + template using if_arithmetical_ptr_t = std::enable_if_t< + !std::is_void::value && + !std::is_function::value, + RT>; + template struct _ptr_base { - AT m_addr; + AT m_addr; // don't access directly using type = T; @@ -19,25 +32,40 @@ namespace vm { return m_addr; } + + // get vm pointer to member + template> _ptr_base of(MT T2::*const member) const + { + const u32 offset = static_cast(reinterpret_cast(&(reinterpret_cast(0ull)->*member))); + return{ VM_CAST(m_addr + offset) }; + } + + // get vm pointer to array member with array subscribtion + template> _ptr_base> of(MT T2::*const member, u32 index) const + { + const u32 offset = static_cast(reinterpret_cast(&(reinterpret_cast(0ull)->*member))); + return{ VM_CAST(m_addr + offset + sizeof32(T) * index) }; + } template std::enable_if_t::value> set(const CT& value) { m_addr = value; } - template static _ptr_base make(const AT2& addr) + template static std::enable_if_t::value, _ptr_base> make(const AT2& addr) { - return{ convert_le_be(addr) }; + const AT value = addr; + return{ value }; } T* get_ptr() const { - return vm::get_ptr(vm::cast(m_addr)); + return vm::get_ptr(VM_CAST(m_addr)); } T* priv_ptr() const { - return vm::priv_ptr(vm::cast(m_addr)); + return vm::priv_ptr(VM_CAST(m_addr)); } T* operator ->() const @@ -49,16 +77,16 @@ namespace vm { static_assert(!std::is_void::value, "vm::_ptr_base<> error: operator[] is not available for void pointers"); - return vm::get_ref(vm::cast(m_addr + sizeof32(T) * index)); + return vm::get_ref(VM_CAST(m_addr + sizeof32(T) * index)); } // enable only the conversions which are originally possible between pointer types - template::value>> operator _ptr_base() const + template::value>> operator _ptr_base() const { - return{ convert_le_be(vm::cast(m_addr)) }; + return{ VM_CAST(m_addr) }; } - template::value>> explicit operator T2*() const + template::value>> explicit operator T2*() const { return get_ptr(); } @@ -68,10 +96,22 @@ namespace vm return m_addr != 0; } + // test address alignment using alignof(T) + bool aligned() const + { + return m_addr % alignof32(T) == 0; + } + + // test address for arbitrary alignment or something + force_inline explicit_bool_t operator %(to_ne_t right) const + { + return m_addr % right != 0; + } + _ptr_base& operator =(const _ptr_base&) = default; }; - template + template struct _ptr_base { AT m_addr; @@ -88,35 +128,22 @@ namespace vm m_addr = value; } - template static _ptr_base make(const AT2& addr) + template static std::enable_if_t::value, _ptr_base> make(const AT2& addr) { - return{ convert_le_be(addr) }; + const AT value = addr; + return{ value }; } - // defined in CB_FUNC.h, call using specified PPU thread context + // defined in CB_FUNC.h, passing context is mandatory RT operator()(PPUThread& CPU, T... args) const; // defined in ARMv7Callback.h, passing context is mandatory RT operator()(ARMv7Context& context, T... args) const; - // defined in CB_FUNC.h, call using current PPU thread context - RT operator()(T... args) const; - - // conversion to function object - operator std::function() const - { - const u32 addr = vm::cast(m_addr); - - return [addr](T... args) -> RT - { - return _ptr_base{ addr }(args...); - }; - } - // conversion to another function pointer template operator _ptr_base() const { - return{ convert_le_be(vm::cast(m_addr)) }; + return{ VM_CAST(m_addr) }; } explicit operator bool() const @@ -127,7 +154,7 @@ namespace vm _ptr_base& operator =(const _ptr_base&) = default; }; - template + template struct _ptr_base { AT m_addr; @@ -166,6 +193,15 @@ namespace vm // default pointer to pointer for PS3 HLE structures (BE pointer to BE pointer to BE data) template using bpptr = bptr, AT>; + + // native endianness pointer to const BE data + template using cptr = ptr; + + // BE pointer to const BE data + template using bcptr = bptr; + + template using cpptr = pptr; + template using bcpptr = bpptr; } namespace psv @@ -181,10 +217,16 @@ namespace vm // default pointer to pointer for PSV HLE structures (LE pointer to LE pointer to LE data) template using lpptr = lptr>; - } - // PS3 emulation is main now, so lets it be as default - using namespace ps3; + // native endianness pointer to const LE data + template using cptr = ptr; + + // LE pointer to const LE data + template using lcptr = lptr; + + template using cpptr = pptr; + template using lcpptr = lpptr; + } struct null_t { @@ -197,17 +239,23 @@ namespace vm // vm::null is convertible to any vm::ptr type as null pointer in virtual memory static null_t null; - // helper SFINAE type for vm::_ptr_base comparison operators (enables comparison between equal types and between any type and void*) - template using if_comparable_t = std::enable_if_t< - std::is_void::value || - std::is_void::value || - std::is_same, std::remove_cv_t>::value, - RT>; + // perform static_cast (for example, vm::ptr to vm::ptr) + template(std::declval()))> inline _ptr_base static_ptr_cast(const _ptr_base& other) + { + return{ other.m_addr }; + } - // helper SFINAE type for vm::_ptr_base pointer arithmetic operators and indirection (disabled for void and function pointers) - template using if_arithmetical_t = std::enable_if_t< - !std::is_void::value && !std::is_function::value, - RT>; + // perform const_cast (for example, vm::cptr to vm::ptr) + template(std::declval()))> inline _ptr_base const_ptr_cast(const _ptr_base& other) + { + return{ other.m_addr }; + } + + // perform reinterpret_cast (for example, vm::ptr to vm::ptr) + template(std::declval()))> inline _ptr_base reinterpret_ptr_cast(const _ptr_base& other) + { + return{ other.m_addr }; + } } // unary plus operator for vm::_ptr_base (always available) @@ -217,13 +265,13 @@ template inline vm::_ptr_base operator +(const v } // indirection operator for vm::_ptr_base -template inline vm::if_arithmetical_t operator *(const vm::_ptr_base& ptr) +template inline vm::if_arithmetical_ptr_t operator *(const vm::_ptr_base& ptr) { - return vm::get_ref(vm::cast(ptr.m_addr)); + return vm::get_ref(VM_CAST(ptr.m_addr)); } // postfix increment operator for vm::_ptr_base -template inline vm::if_arithmetical_t> operator ++(vm::_ptr_base& ptr, int) +template inline vm::if_arithmetical_ptr_t> operator ++(vm::_ptr_base& ptr, int) { const AT result = ptr.m_addr; ptr.m_addr += sizeof32(T); @@ -231,14 +279,14 @@ template inline vm::if_arithmetical_t inline vm::if_arithmetical_t&> operator ++(vm::_ptr_base& ptr) +template inline vm::if_arithmetical_ptr_t&> operator ++(vm::_ptr_base& ptr) { ptr.m_addr += sizeof32(T); return ptr; } // postfix decrement operator for vm::_ptr_base -template inline vm::if_arithmetical_t> operator --(vm::_ptr_base& ptr, int) +template inline vm::if_arithmetical_ptr_t> operator --(vm::_ptr_base& ptr, int) { const AT result = ptr.m_addr; ptr.m_addr -= sizeof32(T); @@ -246,42 +294,42 @@ template inline vm::if_arithmetical_t inline vm::if_arithmetical_t&> operator --(vm::_ptr_base& ptr) +template inline vm::if_arithmetical_ptr_t&> operator --(vm::_ptr_base& ptr) { ptr.m_addr -= sizeof32(T); return ptr; } // addition assignment operator for vm::_ptr_base (pointer += integer) -template inline vm::if_arithmetical_t&> operator +=(vm::_ptr_base& ptr, to_ne_t count) +template inline vm::if_arithmetical_ptr_t&> operator +=(vm::_ptr_base& ptr, to_ne_t count) { ptr.m_addr += count * sizeof32(T); return ptr; } // subtraction assignment operator for vm::_ptr_base (pointer -= integer) -template inline vm::if_arithmetical_t&> operator -=(vm::_ptr_base& ptr, to_ne_t count) +template inline vm::if_arithmetical_ptr_t&> operator -=(vm::_ptr_base& ptr, to_ne_t count) { ptr.m_addr -= count * sizeof32(T); return ptr; } // addition operator for vm::_ptr_base (pointer + integer) -template inline vm::if_arithmetical_t> operator +(const vm::_ptr_base& ptr, to_ne_t count) +template inline vm::if_arithmetical_ptr_t> operator +(const vm::_ptr_base& ptr, to_ne_t count) { - return{ convert_le_be(ptr.m_addr + count * sizeof32(T)) }; + return{ ptr.m_addr + count * sizeof32(T) }; } // addition operator for vm::_ptr_base (integer + pointer) -template inline vm::if_arithmetical_t> operator +(to_ne_t count, const vm::_ptr_base& ptr) +template inline vm::if_arithmetical_ptr_t> operator +(to_ne_t count, const vm::_ptr_base& ptr) { - return{ convert_le_be(ptr.m_addr + count * sizeof32(T)) }; + return{ ptr.m_addr + count * sizeof32(T) }; } // subtraction operator for vm::_ptr_base (pointer - integer) -template inline vm::if_arithmetical_t> operator -(const vm::_ptr_base& ptr, to_ne_t count) +template inline vm::if_arithmetical_ptr_t> operator -(const vm::_ptr_base& ptr, to_ne_t count) { - return{ convert_le_be(ptr.m_addr - count * sizeof32(T)) }; + return{ ptr.m_addr - count * sizeof32(T) }; } // pointer difference operator for vm::_ptr_base @@ -291,9 +339,9 @@ template inline std::enabl !std::is_function::value && !std::is_function::value && std::is_same, std::remove_cv_t>::value, - u32> operator -(const vm::_ptr_base& left, const vm::_ptr_base& right) + s32> operator -(const vm::_ptr_base& left, const vm::_ptr_base& right) { - return static_cast((left.m_addr - right.m_addr) / sizeof32(T1)); + return static_cast(left.m_addr - right.m_addr) / sizeof32(T1); } // comparison operator for vm::_ptr_base (pointer1 == pointer2) @@ -302,36 +350,96 @@ template vm::if_comparable return left.m_addr == right.m_addr; } +template bool operator ==(const vm::null_t&, const vm::_ptr_base& ptr) +{ + return ptr.m_addr == 0; +} + +template bool operator ==(const vm::_ptr_base& ptr, const vm::null_t&) +{ + return ptr.m_addr == 0; +} + // comparison operator for vm::_ptr_base (pointer1 != pointer2) template vm::if_comparable_t operator !=(const vm::_ptr_base& left, const vm::_ptr_base& right) { return left.m_addr != right.m_addr; } +template bool operator !=(const vm::null_t&, const vm::_ptr_base& ptr) +{ + return ptr.m_addr != 0; +} + +template bool operator !=(const vm::_ptr_base& ptr, const vm::null_t&) +{ + return ptr.m_addr != 0; +} + // comparison operator for vm::_ptr_base (pointer1 < pointer2) template vm::if_comparable_t operator <(const vm::_ptr_base& left, const vm::_ptr_base& right) { return left.m_addr < right.m_addr; } +template bool operator <(const vm::null_t&, const vm::_ptr_base& ptr) +{ + return ptr.m_addr != 0; +} + +template bool operator <(const vm::_ptr_base&, const vm::null_t&) +{ + return false; +} + // comparison operator for vm::_ptr_base (pointer1 <= pointer2) template vm::if_comparable_t operator <=(const vm::_ptr_base& left, const vm::_ptr_base& right) { return left.m_addr <= right.m_addr; } +template bool operator <=(const vm::null_t&, const vm::_ptr_base&) +{ + return true; +} + +template bool operator <=(const vm::_ptr_base& ptr, const vm::null_t&) +{ + return ptr.m_addr == 0; +} + // comparison operator for vm::_ptr_base (pointer1 > pointer2) template vm::if_comparable_t operator >(const vm::_ptr_base& left, const vm::_ptr_base& right) { return left.m_addr > right.m_addr; } +template bool operator >(const vm::null_t&, const vm::_ptr_base&) +{ + return false; +} + +template bool operator >(const vm::_ptr_base& ptr, const vm::null_t&) +{ + return ptr.m_addr != 0; +} + // comparison operator for vm::_ptr_base (pointer1 >= pointer2) template vm::if_comparable_t operator >=(const vm::_ptr_base& left, const vm::_ptr_base& right) { return left.m_addr >= right.m_addr; } +template bool operator >=(const vm::null_t&, const vm::_ptr_base& ptr) +{ + return ptr.m_addr == 0; +} + +template bool operator >=(const vm::_ptr_base&, const vm::null_t&) +{ + return true; +} + // external specialization for is_be_t<> (true if AT is be_t<>) template diff --git a/rpcs3/Emu/Memory/vm_ref.h b/rpcs3/Emu/Memory/vm_ref.h index acd62e58f1..5189a13ed2 100644 --- a/rpcs3/Emu/Memory/vm_ref.h +++ b/rpcs3/Emu/Memory/vm_ref.h @@ -5,7 +5,7 @@ namespace vm template struct _ref_base { - AT m_addr; + AT m_addr; // don't access directly static_assert(!std::is_pointer::value, "vm::_ref_base<> error: invalid type (pointer)"); static_assert(!std::is_reference::value, "vm::_ref_base<> error: invalid type (reference)"); @@ -17,19 +17,19 @@ namespace vm return m_addr; } - template static _ref_base make(const AT2& addr) + template static std::enable_if_t::value, _ref_base> make(const AT2& addr) { - return{ convert_le_be(addr) }; + return{ addr }; } T& get_ref() const { - return vm::get_ref(vm::cast(m_addr)); + return vm::get_ref(VM_CAST(m_addr)); } T& priv_ref() const { - return vm::priv_ref(vm::cast(m_addr)); + return vm::priv_ref(VM_CAST(m_addr)); } // TODO: conversion operator (seems hard to define it correctly) @@ -103,9 +103,6 @@ namespace vm // default reference for PSV HLE structures (LE reference to LE data) template using lref = lrefl; } - - //PS3 emulation is main now, so lets it be as default - using namespace ps3; } // postfix increment operator for vm::_ref_base diff --git a/rpcs3/Emu/Memory/vm_var.h b/rpcs3/Emu/Memory/vm_var.h index a342f7df2a..ecf56e2058 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -539,7 +539,7 @@ namespace vm CPUThread& m_thread; public: - stackvar(CPUThread& CPU, u32 size = sizeof(T), u32 align = __alignof(T)) + stackvar(CPUThread& CPU, u32 size = sizeof32(T), u32 align = alignof32(T)) : m_data(CPU, size, align) , m_thread(CPU) { @@ -554,9 +554,12 @@ namespace vm stackvar(stackvar&& r) = delete; - ~stackvar() + ~stackvar() noexcept(false) // allow exceptions { - stack_pop(m_thread, m_data.addr, m_data.old_pos); + if (!std::uncaught_exception()) // don't call during stack unwinding + { + stack_pop(m_thread, m_data.addr, m_data.old_pos); + } } stackvar& operator = (const stackvar& r) @@ -597,6 +600,16 @@ namespace vm return *m_data.ptr; } + T& operator [](u32 index) + { + return m_data.ptr[index]; + } + + const T& operator [](u32 index) const + { + return m_data.ptr[index]; + } + u32 addr() const { return m_data.addr; diff --git a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp index c7c82a42e8..0725d69783 100644 --- a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp @@ -227,7 +227,7 @@ void CgBinaryDisasm::TaskFP() assert((m_buffer_size - m_offset) % sizeof(u32) == 0); for (u32 i = 0; i < (m_buffer_size - m_offset) / sizeof(u32); i++) { - data[i] = re32(data[i]); + data[i] = _byteswap_ulong(data[i]); // WTF, cannot use be_t<> there? } enum diff --git a/rpcs3/Emu/RSX/CgBinaryProgram.h b/rpcs3/Emu/RSX/CgBinaryProgram.h index 89959d0300..9f40dd61e1 100644 --- a/rpcs3/Emu/RSX/CgBinaryProgram.h +++ b/rpcs3/Emu/RSX/CgBinaryProgram.h @@ -365,7 +365,7 @@ public: assert((m_buffer_size - m_offset) % sizeof(u32) == 0); for (u32 i = 0; i < (m_buffer_size - m_offset) / sizeof(u32); i++) { - vdata[i] = re32(vdata[i]); + vdata[i] = _byteswap_ulong(vdata[i]); // WTF, cannot use be_t<> there? } for (u32 i = 0; i < prog.ucodeSize / sizeof(u32); i++) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index eeefd1d3b9..7a457bb15d 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" -#include "FragmentProgramDecompiler.h" - #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "FragmentProgramDecompiler.h" + FragmentProgramDecompiler::FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl) : m_addr(addr), m_size(size), @@ -114,7 +114,7 @@ std::string FragmentProgramDecompiler::AddConst() return name; } - auto data = vm::ptr::make(m_addr + m_size + 4 * sizeof(u32)); + auto data = vm::ps3::ptr::make(m_addr + m_size + 4 * sizeof32(u32)); m_offset = 2 * 4 * sizeof(u32); u32 x = GetData(data[0]); @@ -335,7 +335,7 @@ std::string FragmentProgramDecompiler::BuildCode() std::string FragmentProgramDecompiler::Decompile() { - auto data = vm::ptr::make(m_addr); + auto data = vm::ps3::ptr::make(m_addr); m_size = 0; m_location = 0; m_loop_count = 0; diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index 6a732e7bd7..5466b2d87f 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -2,7 +2,6 @@ #include "Emu/RSX/RSXFragmentProgram.h" #include "Emu/RSX/RSXVertexProgram.h" -#include "Utilities/Log.h" enum class SHADER_TYPE diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index 5505f4cde9..3c8792611c 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -1,8 +1,9 @@ #include "stdafx.h" -#include "VertexProgramDecompiler.h" #include "Utilities/Log.h" #include "Emu/System.h" +#include "VertexProgramDecompiler.h" + std::string VertexProgramDecompiler::GetMask(bool is_sca) { std::string ret; diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 39c15ab2ca..375788fdb7 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum { CELL_GCM_DISPLAY_HSYNC = 1, diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index de5a403275..50abd60569 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -119,35 +119,33 @@ void GLFragmentDecompilerThread::Task() } GLFragmentProgram::GLFragmentProgram() - : m_decompiler_thread(nullptr) - , id(0) { } GLFragmentProgram::~GLFragmentProgram() { - if (m_decompiler_thread) - { - Wait(); - if (m_decompiler_thread->IsAlive()) - { - m_decompiler_thread->Stop(); - } + //if (m_decompiler_thread) + //{ + // Wait(); + // if (m_decompiler_thread->IsAlive()) + // { + // m_decompiler_thread->Stop(); + // } - delete m_decompiler_thread; - m_decompiler_thread = nullptr; - } + // delete m_decompiler_thread; + // m_decompiler_thread = nullptr; + //} Delete(); } -void GLFragmentProgram::Wait() -{ - if (m_decompiler_thread && m_decompiler_thread->IsAlive()) - { - m_decompiler_thread->Join(); - } -} +//void GLFragmentProgram::Wait() +//{ +// if (m_decompiler_thread && m_decompiler_thread->IsAlive()) +// { +// m_decompiler_thread->Join(); +// } +//} void GLFragmentProgram::Decompile(RSXFragmentProgram& prog) { @@ -163,23 +161,23 @@ void GLFragmentProgram::Decompile(RSXFragmentProgram& prog) } } -void GLFragmentProgram::DecompileAsync(RSXFragmentProgram& prog) -{ - if (m_decompiler_thread) - { - Wait(); - if (m_decompiler_thread->IsAlive()) - { - m_decompiler_thread->Stop(); - } - - delete m_decompiler_thread; - m_decompiler_thread = nullptr; - } - - m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size, prog.ctrl); - m_decompiler_thread->Start(); -} +//void GLFragmentProgram::DecompileAsync(RSXFragmentProgram& prog) +//{ +// if (m_decompiler_thread) +// { +// Wait(); +// if (m_decompiler_thread->IsAlive()) +// { +// m_decompiler_thread->Stop(); +// } +// +// delete m_decompiler_thread; +// m_decompiler_thread = nullptr; +// } +// +// m_decompiler_thread = new GLFragmentDecompilerThread(shader, parr, prog.addr, prog.size, prog.ctrl); +// m_decompiler_thread->Start(); +//} void GLFragmentProgram::Compile() { diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.h b/rpcs3/Emu/RSX/GL/GLFragmentProgram.h index 7b16b5974d..ad20788ea5 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.h +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.h @@ -4,16 +4,17 @@ #include "Utilities/Thread.h" #include "OpenGL.h" -struct GLFragmentDecompilerThread : public ThreadBase, public FragmentProgramDecompiler +struct GLFragmentDecompilerThread : public FragmentProgramDecompiler { std::string& m_shader; ParamArray& m_parrDummy; public: GLFragmentDecompilerThread(std::string& shader, ParamArray& parr, u32 addr, u32& size, u32 ctrl) - : ThreadBase("Fragment Shader Decompiler Thread"), FragmentProgramDecompiler(addr, size, ctrl) + : FragmentProgramDecompiler(addr, size, ctrl) , m_shader(shader) , m_parrDummy(parr) - {} + { + } void Task(); @@ -41,7 +42,7 @@ public: ~GLFragmentProgram(); ParamArray parr; - u32 id; + u32 id = 0; std::string shader; std::vector FragmentConstantOffsetCache; @@ -51,23 +52,10 @@ public: */ void Decompile(RSXFragmentProgram& prog); - /** - * Asynchronously decompile a fragment shader located in the PS3's Memory. - * When this function is called you must call Wait() before GetShaderText() will return valid data. - * @param prog RSXShaderProgram specifying the location and size of the shader in memory - */ - void DecompileAsync(RSXFragmentProgram& prog); - - /** Wait for the decompiler task to complete decompilation. */ - void Wait(); - /** Compile the decompiled fragment shader into a format we can use with OpenGL. */ void Compile(); private: - /** Threaded fragment shader decompiler responsible for decompiling this program */ - GLFragmentDecompilerThread* m_decompiler_thread; - /** Deletes the shader and any stored information */ void Delete(); }; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 08adde2fb3..9b9ea7c484 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -794,6 +794,11 @@ GLGSRender::GLGSRender() GLGSRender::~GLGSRender() { + if (joinable()) + { + throw EXCEPTION("Thread not joined"); + } + m_frame->Close(); m_frame->DeleteContext(m_context); } @@ -814,7 +819,10 @@ extern CellGcmContextData current_context; void GLGSRender::Close() { - Stop(); + if (joinable()) + { + join(); + } if (m_frame->IsShown()) { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index f1ea9cb83f..20daf4c088 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -134,9 +134,7 @@ typedef GSFrameBase*(*GetGSFrameCb)(); void SetGetGSFrameCallback(GetGSFrameCb value); -class GLGSRender //TODO: find out why this used to inherit from wxWindow - : //public wxWindow - /*,*/ public GSRender +class GLGSRender final : public GSRender { private: std::vector m_vdata; @@ -167,7 +165,7 @@ public: bool is_intel_vendor; GLGSRender(); - virtual ~GLGSRender(); + virtual ~GLGSRender() override; private: void EnableVertexData(bool indexed_draw = false); diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 0379592402..10af89a112 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -131,35 +131,33 @@ void GLVertexDecompilerThread::Task() } GLVertexProgram::GLVertexProgram() - : m_decompiler_thread(nullptr) - , id(0) { } GLVertexProgram::~GLVertexProgram() { - if (m_decompiler_thread) - { - Wait(); - if (m_decompiler_thread->IsAlive()) - { - m_decompiler_thread->Stop(); - } + //if (m_decompiler_thread) + //{ + // Wait(); + // if (m_decompiler_thread->IsAlive()) + // { + // m_decompiler_thread->Stop(); + // } - delete m_decompiler_thread; - m_decompiler_thread = nullptr; - } + // delete m_decompiler_thread; + // m_decompiler_thread = nullptr; + //} Delete(); } -void GLVertexProgram::Wait() -{ - if (m_decompiler_thread && m_decompiler_thread->IsAlive()) - { - m_decompiler_thread->Join(); - } -} +//void GLVertexProgram::Wait() +//{ +// if (m_decompiler_thread && m_decompiler_thread->IsAlive()) +// { +// m_decompiler_thread->Join(); +// } +//} void GLVertexProgram::Decompile(RSXVertexProgram& prog) { @@ -167,23 +165,23 @@ void GLVertexProgram::Decompile(RSXVertexProgram& prog) decompiler.Task(); } -void GLVertexProgram::DecompileAsync(RSXVertexProgram& prog) -{ - if (m_decompiler_thread) - { - Wait(); - if (m_decompiler_thread->IsAlive()) - { - m_decompiler_thread->Stop(); - } - - delete m_decompiler_thread; - m_decompiler_thread = nullptr; - } - - m_decompiler_thread = new GLVertexDecompilerThread(prog.data, shader, parr); - m_decompiler_thread->Start(); -} +//void GLVertexProgram::DecompileAsync(RSXVertexProgram& prog) +//{ +// if (m_decompiler_thread) +// { +// Wait(); +// if (m_decompiler_thread->IsAlive()) +// { +// m_decompiler_thread->Stop(); +// } +// +// delete m_decompiler_thread; +// m_decompiler_thread = nullptr; +// } +// +// m_decompiler_thread = new GLVertexDecompilerThread(prog.data, shader, parr); +// m_decompiler_thread->Start(); +//} void GLVertexProgram::Compile() { diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.h b/rpcs3/Emu/RSX/GL/GLVertexProgram.h index d9664a9ede..9b01045dd1 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.h +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.h @@ -4,7 +4,7 @@ #include "Utilities/Thread.h" #include "OpenGL.h" -struct GLVertexDecompilerThread : public ThreadBase, public VertexProgramDecompiler +struct GLVertexDecompilerThread : public VertexProgramDecompiler { std::string &m_shader; protected: @@ -20,11 +20,12 @@ protected: virtual void insertMainEnd(std::stringstream &OS) override; public: GLVertexDecompilerThread(std::vector& data, std::string& shader, ParamArray& parr) - : ThreadBase("Vertex Shader Decompiler Thread"), VertexProgramDecompiler(data), m_shader(shader) + : VertexProgramDecompiler(data) + , m_shader(shader) { } - virtual void Task() override; + void Task(); }; class GLVertexProgram @@ -34,15 +35,12 @@ public: ~GLVertexProgram(); ParamArray parr; - u32 id; + u32 id = 0; std::string shader; void Decompile(RSXVertexProgram& prog); - void DecompileAsync(RSXVertexProgram& prog); - void Wait(); void Compile(); private: - GLVertexDecompilerThread* m_decompiler_thread; void Delete(); }; diff --git a/rpcs3/Emu/RSX/GSManager.cpp b/rpcs3/Emu/RSX/GSManager.cpp index e4870d13ad..ed26fc0790 100644 --- a/rpcs3/Emu/RSX/GSManager.cpp +++ b/rpcs3/Emu/RSX/GSManager.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "rpcs3/Ini.h" +#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "sysutil_video.h" diff --git a/rpcs3/Emu/RSX/GSManager.h b/rpcs3/Emu/RSX/GSManager.h index 68d9db987a..7d8a185364 100644 --- a/rpcs3/Emu/RSX/GSManager.h +++ b/rpcs3/Emu/RSX/GSManager.h @@ -1,5 +1,6 @@ #pragma once -#include "GSRender.h" + +struct GSRender; struct GSInfo { @@ -13,7 +14,6 @@ struct GSInfo u16 refreshRates; u32 pitch; } mode; - //CellVideoOutDisplayMode mode; GSInfo() { diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index 2a58e463a1..4b376e5187 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -3,8 +3,12 @@ struct GSRender : public RSXThread { - virtual ~GSRender() + virtual ~GSRender() override { + if (joinable()) + { + throw EXCEPTION("Thread not joined"); + } } virtual void Close()=0; diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.h b/rpcs3/Emu/RSX/Null/NullGSRender.h index a68e70a44e..1bd5a26a16 100644 --- a/rpcs3/Emu/RSX/Null/NullGSRender.h +++ b/rpcs3/Emu/RSX/Null/NullGSRender.h @@ -1,8 +1,7 @@ #pragma once #include "Emu/RSX/GSRender.h" -class NullGSRender - : public GSRender +class NullGSRender final : public GSRender { public: @@ -10,8 +9,12 @@ public: { } - virtual ~NullGSRender() + virtual ~NullGSRender() override { + if (joinable()) + { + throw EXCEPTION("Thread not joined"); + } } private: @@ -45,6 +48,10 @@ private: virtual void Close() { + if (joinable()) + { + join(); + } } virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override @@ -58,4 +65,4 @@ private: virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override { } -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/RSX/RSXDMA.cpp b/rpcs3/Emu/RSX/RSXDMA.cpp deleted file mode 100644 index ad6bc06a74..0000000000 --- a/rpcs3/Emu/RSX/RSXDMA.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2015 AlexAltea (https://github.com/AlexAltea/nucleus) -#include "stdafx.h" -#include "RSXDMA.h" -#include "Emu/Memory/Memory.h" -#include "Utilities/Log.h" - -DMAObject dma_address(u32 dma_object) -{ - // NOTE: RAMIN is not emulated, therefore DMA Objects are hardcoded in this function - switch (dma_object) { - case RSX_CONTEXT_DMA_REPORT_LOCATION_LOCAL: - return DMAObject{ 0x40300000, 0x8000, DMAObject::READWRITE }; // TODO: Inconsistency: Gitbrew says R starting at 0x1400, test says RW starting at 0x0. - case RSX_CONTEXT_DMA_DEVICE_RW: - return DMAObject{ 0x40000000, 0x1000, DMAObject::READWRITE }; - case RSX_CONTEXT_DMA_DEVICE_R: - return DMAObject{ 0x40000000, 0x1000, DMAObject::READWRITE }; // TODO: Inconsistency: Gitbrew says R, test says RW - case RSX_CONTEXT_DMA_SEMAPHORE_RW: - return DMAObject{ 0x40100000, 0x1000, DMAObject::READWRITE }; - case RSX_CONTEXT_DMA_SEMAPHORE_R: - return DMAObject{ 0x40100000, 0x1000, DMAObject::READWRITE }; // TODO: Inconsistency: Gitbrew says R, test says RW - default: - LOG_WARNING(RSX, "Unknown DMA object (0x%08x)", dma_object); - return DMAObject{}; - } -} - -u8 dma_read8(u32 dma_object, u8 offset) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::READ) - { - return vm::read8(dma.addr + offset); - } - - LOG_WARNING(RSX, "Illegal DMA 8-bit read"); - return 0; -} - -u16 dma_read16(u32 dma_object, u16 offset) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::READ) - { - return vm::read16(dma.addr + offset); - } - - LOG_WARNING(RSX, "Illegal DMA 16-bit read"); - return 0; -} - -u32 dma_read32(u32 dma_object, u32 offset) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::READ) - { - return vm::read32(dma.addr + offset); - } - - LOG_WARNING(RSX, "Illegal DMA 32-bit read"); - return 0; -} - -u64 dma_read64(u32 dma_object, u64 offset) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::READ) - { - return vm::read64(dma.addr + offset); - } - - LOG_WARNING(RSX, "Illegal DMA 64-bit read"); - return 0; -} - -void dma_write8(u32 dma_object, u32 offset, u8 value) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::WRITE) - { - return vm::write8(dma.addr + offset, value); - } - - LOG_WARNING(RSX, "Illegal DMA 32-bit write"); -} - -void dma_write16(u32 dma_object, u32 offset, u16 value) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::WRITE) - { - return vm::write16(dma.addr + offset, value); - } - - LOG_WARNING(RSX, "Illegal DMA 32-bit write"); -} - -void dma_write32(u32 dma_object, u32 offset, u32 value) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::WRITE) - { - return vm::write32(dma.addr + offset, value); - } - - LOG_WARNING(RSX, "Illegal DMA 32-bit write"); -} - -void dma_write64(u32 dma_object, u32 offset, u64 value) -{ - const DMAObject& dma = dma_address(dma_object); - - if (dma.addr && dma.flags & DMAObject::WRITE) - { - return vm::write64(dma.addr + offset, value); - } - - LOG_WARNING(RSX, "Illegal DMA 64-bit write"); -} \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXDMA.h b/rpcs3/Emu/RSX/RSXDMA.h deleted file mode 100644 index e5da8918eb..0000000000 --- a/rpcs3/Emu/RSX/RSXDMA.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2015 AlexAltea (https://github.com/AlexAltea/nucleus) -#pragma once - -enum { - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0 = 0x66604200, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY1 = 0x66604201, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY2 = 0x66604202, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY3 = 0x66604203, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY4 = 0x66604204, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY5 = 0x66604205, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY6 = 0x66604206, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY7 = 0x66604207, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY8 = 0x66604208, // Target: lpar_reports[0x1000 : 0x????] - RSX_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F, - RSX_CONTEXT_DMA_SEMAPHORE_RW = 0x66606660, // Target: lpar_reports[0x0000 : 0x1000] (Read/Write) - RSX_CONTEXT_DMA_SEMAPHORE_R = 0x66616661, // Target: lpar_reports[0x0000 : 0x1000] (Read) - RSX_CONTEXT_DMA_REPORT_LOCATION_LOCAL = 0x66626660, // Target: lpar_reports[0x1400 : 0x9400] - RSX_CONTEXT_DMA_REPORT_LOCATION_MAIN = 0xBAD68000, - RSX_CONTEXT_DMA_DEVICE_RW = 0x56616660, - RSX_CONTEXT_DMA_DEVICE_R = 0x56616661, -}; - -struct DMAObject { - // Flags - enum { - READ = 1 << 0, - WRITE = 1 << 1, - READWRITE = READ | WRITE, - }; - u32 addr; - u32 size; - u32 flags; -}; - -// RSX Direct Memory Access -DMAObject dma_address(u32 dma_object); - -u8 dma_read8(u32 dma_object, u32 offset); -u16 dma_read16(u32 dma_object, u32 offset); -u32 dma_read32(u32 dma_object, u32 offset); -u64 dma_read64(u32 dma_object, u32 offset); - -void dma_write8(u32 dma_object, u32 offset, u8 value); -void dma_write16(u32 dma_object, u32 offset, u16 value); -void dma_write32(u32 dma_object, u32 offset, u32 value); -void dma_write64(u32 dma_object, u32 offset, u64 value); \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 6725a190f1..10e41e70c7 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -4,19 +4,20 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/RSX/GSManager.h" -#include "Emu/RSX/RSXDMA.h" +#include "Emu/RSX/GSRender.h" #include "Emu/RSX/sysutil_video.h" #include "RSXThread.h" #include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/CB_FUNC.h" -#include "Emu/SysCalls/lv2/sys_time.h" extern "C" { #include "libswscale/swscale.h" } +extern u64 get_system_time(); + #define ARGS(x) (x >= count ? OutOfArgsCount(x, cmd, count, args.addr()) : args[x].value()) #define CMD_DEBUG 0 @@ -38,7 +39,7 @@ u32 GetAddress(u32 offset, u32 location) res = (u32)Memory.RSXIOMem.RealAddr(offset); // TODO: Error Check? if (res == 0) { - throw fmt::format("GetAddress(offset=0x%x, location=0x%x): RSXIO memory not mapped", offset, location); + throw EXCEPTION("RSXIO memory not mapped (offset=0x%x)", offset); } if (Emu.GetGSManager().GetRender().m_strict_ordering[offset >> 20]) @@ -50,7 +51,7 @@ u32 GetAddress(u32 offset, u32 location) } default: { - throw fmt::format("GetAddress(offset=0x%x, location=0x%x): invalid location", offset, location); + throw EXCEPTION("Invalid location (offset=0x%x, location=0x%x)", offset, location); } } @@ -100,17 +101,17 @@ void RSXVertexData::Load(u32 start, u32 count, u32 baseOffset, u32 baseIndex = 0 case 2: { - const u16* c_src = (const u16*)src; - u16* c_dst = (u16*)dst; - for (u32 j = 0; j < size; ++j) *c_dst++ = re16(*c_src++); + auto c_src = (const be_t*)src; + auto c_dst = (u16*)dst; + for (u32 j = 0; j < size; ++j) *c_dst++ = *c_src++; break; } case 4: { - const u32* c_src = (const u32*)src; - u32* c_dst = (u32*)dst; - for (u32 j = 0; j < size; ++j) *c_dst++ = re32(*c_src++); + auto c_src = (const be_t*)src; + auto c_dst = (u32*)dst; + for (u32 j = 0; j < size; ++j) *c_dst++ = *c_src++; break; } } @@ -187,7 +188,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const // NV406E case NV406E_SET_REFERENCE: { - m_ctrl->ref.exchange(be_t::make(ARGS(0))); + m_ctrl->ref.exchange(ARGS(0)); break; } @@ -251,9 +252,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if (m_flip_handler) { auto cb = m_flip_handler; - Emu.GetCallbackManager().Async([cb](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](CPUThread& CPU) { - cb(CPU, 1); + cb(static_cast(CPU), 1); }); } @@ -2306,9 +2307,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const { const u32 cause = ARGS(0); auto cb = m_user_handler; - Emu.GetCallbackManager().Async([cb, cause](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](CPUThread& CPU) { - cb(CPU, cause); + cb(static_cast(CPU), cause); }); break; } @@ -2455,23 +2456,25 @@ void RSXThread::Task() m_last_flip_time = get_system_time() - 1000000; - thread_t vblank("VBlank thread", true /* autojoin */, [this]() + autojoin_thread_t vblank(WRAP_EXPR("VBlank Thread"), [this]() { const u64 start_time = get_system_time(); m_vblank_count = 0; - while (!TestDestroy() && !Emu.IsStopped()) + while (joinable()) { + CHECK_EMU_STATUS; + if (get_system_time() - start_time > m_vblank_count * 1000000 / 60) { m_vblank_count++; if (auto cb = m_vblank_handler) { - Emu.GetCallbackManager().Async([=](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](CPUThread& CPU) { - cb(CPU, 1); + cb(static_cast(CPU), 1); }); } } @@ -2482,19 +2485,14 @@ void RSXThread::Task() } }); - while (!TestDestroy()) try + while (joinable() && !Emu.IsStopped()) { - if (Emu.IsStopped()) - { - LOG_WARNING(RSX, "RSX thread aborted"); - break; - } std::lock_guard lock(m_cs_main); inc = 1; - u32 get = m_ctrl->get.read_sync(); - u32 put = m_ctrl->put.read_sync(); + u32 put = m_ctrl->put.load(); + u32 get = m_ctrl->get.load(); if (put == get || !Emu.IsRunning()) { @@ -2522,7 +2520,7 @@ void RSXThread::Task() { u32 offs = cmd & 0x1fffffff; //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); - m_ctrl->get.exchange(be_t::make(offs)); + m_ctrl->get.exchange(offs); continue; } if (cmd & CELL_GCM_METHOD_FLAG_CALL) @@ -2530,7 +2528,7 @@ void RSXThread::Task() m_call_stack.push(get + 4); u32 offs = cmd & ~3; //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x", offs, cmd, get); - m_ctrl->get.exchange(be_t::make(offs)); + m_ctrl->get.exchange(offs); continue; } if (cmd == CELL_GCM_METHOD_FLAG_RETURN) @@ -2538,7 +2536,7 @@ void RSXThread::Task() u32 get = m_call_stack.top(); m_call_stack.pop(); //LOG_WARNING(RSX, "rsx return(0x%x)", get); - m_ctrl->get.exchange(be_t::make(get)); + m_ctrl->get.exchange(get); continue; } if (cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) @@ -2570,18 +2568,6 @@ void RSXThread::Task() value += (count + 1) * 4; }); } - catch (const std::string& e) - { - LOG_ERROR(RSX, "Exception: %s", e.c_str()); - Emu.Pause(); - } - catch (const char* e) - { - LOG_ERROR(RSX, "Exception: %s", e); - Emu.Pause(); - } - - LOG_NOTICE(RSX, "RSX thread ended"); OnExitThread(); } @@ -2601,16 +2587,19 @@ void RSXThread::Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddres m_used_gcm_commands.clear(); OnInit(); - ThreadBase::Start(); + + start(WRAP_EXPR("RSXThread"), WRAP_EXPR(Task())); } u32 RSXThread::ReadIO32(u32 addr) { u32 value; + if (!Memory.RSXIOMem.Read32(addr, &value)) { - throw fmt::Format("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr); + throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); } + return value; } @@ -2618,6 +2607,6 @@ void RSXThread::WriteIO32(u32 addr, u32 value) { if (!Memory.RSXIOMem.Write32(addr, value)) { - throw fmt::Format("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr); + throw EXCEPTION("RSXIO memory not mapped (addr=0x%x)", addr); } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index aa3f74e83f..ce0d92c819 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -90,7 +90,7 @@ struct RSXTransformConstant } }; -class RSXThread : public ThreadBase +class RSXThread : protected thread_t { public: static const uint m_textures_count = 16; @@ -449,8 +449,7 @@ public: protected: RSXThread() - : ThreadBase("RSXThread") - , m_ctrl(nullptr) + : m_ctrl(nullptr) , m_shader_ctrl(0x40) , m_flip_status(0) , m_flip_mode(CELL_GCM_DISPLAY_VSYNC) @@ -551,7 +550,13 @@ protected: Reset(); } - virtual ~RSXThread() {} + virtual ~RSXThread() override + { + if (joinable()) + { + throw EXCEPTION("Thread not joined"); + } + } void Reset() { diff --git a/rpcs3/Emu/RSX/sysutil_video.h b/rpcs3/Emu/RSX/sysutil_video.h index 9975a33046..eac1effdff 100644 --- a/rpcs3/Emu/RSX/sysutil_video.h +++ b/rpcs3/Emu/RSX/sysutil_video.h @@ -229,15 +229,15 @@ enum CellVideoOutRGBOutputRange static const CellVideoOutResolution ResolutionTable[] = { - { be_t::make(0xffff), be_t::make(0xffff) }, //0 - 0 - { be_t::make(1920), be_t::make(1080) }, //1 - 1 - { be_t::make(1280), be_t::make(720) }, //2 - 2 - { be_t::make(720), be_t::make(480) }, //4 - 3 - { be_t::make(720), be_t::make(576) }, //5 - 4 - { be_t::make(1600), be_t::make(1080) }, //10 - 5 - { be_t::make(1440), be_t::make(1080) }, //11 - 6 - { be_t::make(1280), be_t::make(1080) }, //12 - 7 - { be_t::make(960), be_t::make(1080) }, //13 - 8 + { 0xffff, 0xffff }, //0 - 0 + { 1920, 1080 }, //1 - 1 + { 1280, 720 }, //2 - 2 + { 720, 480 }, //4 - 3 + { 720, 576 }, //5 - 4 + { 1600, 1080 }, //10 - 5 + { 1440, 1080 }, //11 - 6 + { 1280, 1080 }, //12 - 7 + { 960, 1080 }, //13 - 8 }; inline static u32 ResolutionIdToNum(u32 id) diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index 148feb5426..c68ea8dbcb 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -1,4 +1,5 @@ #pragma once + #include "Emu/Cell/PPUThread.h" namespace cb_detail @@ -9,6 +10,8 @@ namespace cb_detail ARG_FLOAT, ARG_VECTOR, ARG_STACK, + ARG_CONTEXT, // for compatibility with SC_FUNC and CALL_FUNC + ARG_UNKNOWN, }; // Current implementation can handle only fixed amount of stack arguments. @@ -17,11 +20,11 @@ namespace cb_detail static const auto FIXED_STACK_FRAME_SIZE = 0x90; template - struct _func_arg; - - template - struct _func_arg + struct _func_arg { + static_assert(type == ARG_GENERAL, "Unknown callback argument type"); + static_assert(!std::is_pointer::value, "Invalid callback argument type (pointer)"); + static_assert(!std::is_reference::value, "Invalid callback argument type (reference)"); static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_GENERAL"); force_inline static void set_value(PPUThread& CPU, const T& arg) @@ -44,7 +47,7 @@ namespace cb_detail template struct _func_arg { - static_assert(std::is_same::value, "Invalid callback argument type for ARG_VECTOR"); + static_assert(std::is_same, u128>::value, "Invalid callback argument type for ARG_VECTOR"); force_inline static void set_value(PPUThread& CPU, const T& arg) { @@ -63,7 +66,17 @@ namespace cb_detail { const int stack_pos = (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)"); - vm::write64(CPU.GPR[1] + stack_pos, cast_to_ppu_gpr(arg)); + vm::ps3::write64(CPU.GPR[1] + stack_pos, cast_to_ppu_gpr(arg)); + } + }; + + template + struct _func_arg + { + static_assert(std::is_same::value, "Invalid callback argument type for ARG_CONTEXT"); + + force_inline static void set_value(PPUThread& CPU, const T& arg) + { } }; @@ -77,18 +90,24 @@ namespace cb_detail template force_inline static bool _bind_func_args(PPUThread& CPU, T1 arg1, T... args) { - static_assert(!std::is_pointer::value, "Invalid callback argument type (pointer)"); - static_assert(!std::is_reference::value, "Invalid callback argument type (reference)"); const bool is_float = std::is_floating_point::value; - const bool is_vector = std::is_same::value; - const _func_arg_type t = is_float - ? ((f_count >= 13) ? ARG_STACK : ARG_FLOAT) - : (is_vector ? ((v_count >= 12) ? ARG_STACK : ARG_VECTOR) : ((g_count >= 8) ? ARG_STACK : ARG_GENERAL)); - const int g = g_count + (is_float || is_vector ? 0 : 1); - const int f = f_count + (is_float ? 1 : 0); - const int v = v_count + (is_vector ? 1 : 0); + const bool is_vector = std::is_same, u128>::value; + const bool is_context = std::is_same::value; + const bool is_general = !is_float && !is_vector && !is_context; + + const _func_arg_type t = + is_general ? (g_count >= 8 ? ARG_STACK : ARG_GENERAL) : + is_float ? (f_count >= 13 ? ARG_STACK : ARG_FLOAT) : + is_vector ? (v_count >= 12 ? ARG_STACK : ARG_VECTOR) : + is_context ? ARG_CONTEXT : + ARG_UNKNOWN; + + const int g = g_count + is_general; + const int f = f_count + is_float; + const int v = v_count + is_vector; _func_arg::set_value(CPU, arg1); + // return true if stack was used return _bind_func_args(CPU, args...) || (t == ARG_STACK); } @@ -96,7 +115,7 @@ namespace cb_detail template struct _func_res { - static_assert(type == ARG_GENERAL, "Wrong use of _func_res template"); + static_assert(type == ARG_GENERAL, "Unknown callback result type"); static_assert(sizeof(T) <= 8, "Invalid callback result type for ARG_GENERAL"); force_inline static T get_value(const PPUThread& CPU) @@ -119,7 +138,7 @@ namespace cb_detail template struct _func_res { - static_assert(std::is_same::value, "Invalid callback result type for ARG_VECTOR"); + static_assert(std::is_same, u128>::value, "Invalid callback result type for ARG_VECTOR"); force_inline static T get_value(const PPUThread& CPU) { @@ -137,7 +156,7 @@ namespace cb_detail static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); static_assert(!std::is_reference::value, "Invalid callback result type (reference)"); const bool is_float = std::is_floating_point::value; - const bool is_vector = std::is_same::value; + const bool is_vector = std::is_same, u128>::value; const _func_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL); return _func_res::get_value(CPU); @@ -164,29 +183,15 @@ namespace vm template force_inline RT _ptr_base::operator()(PPUThread& CPU, T... args) const { - const auto data = vm::get_ptr>(vm::cast(m_addr)); + const auto data = vm::get_ptr>(VM_CAST(m_addr)); const u32 pc = data[0]; const u32 rtoc = data[1]; return cb_detail::_func_caller::call(CPU, pc, rtoc, args...); } - - template - force_inline RT _ptr_base::operator()(T... args) const - { - return operator()(GetCurrentPPUThread(), args...); - } } -template -force_inline RT cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args) +template inline RT cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args) { return cb_detail::_func_caller::call(CPU, pc, rtoc, args...); } - -// Something is wrong with it (but cb_call() should work anyway) -//template -//void cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args) -//{ -// cb_detail::_func_caller::call(CPU, pc, rtoc, args...); -//} diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index b8e319ac73..6d75393a22 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -2,153 +2,114 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/CPU/CPUThreadManager.h" +#include "Emu/IdManager.h" + #include "Emu/Cell/PPUThread.h" #include "Emu/ARMv7/ARMv7Thread.h" #include "Callback.h" -void CallbackManager::Register(const std::function& func) +void CallbackManager::Register(check_cb_t func) { - { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); - m_cb_list.push_back([=](CPUThread& CPU) -> s32 - { - assert(CPU.GetType() == CPU_THREAD_PPU); - return func(static_cast(CPU)); - }); - } + m_check_cb.emplace(std::move(func)); } -void CallbackManager::Async(const std::function& func) +void CallbackManager::Async(async_cb_t func) { - { - std::lock_guard lock(m_mutex); + std::lock_guard lock(m_mutex); - m_async_list.push_back([=](CPUThread& CPU) - { - assert(CPU.GetType() == CPU_THREAD_PPU); - func(static_cast(CPU)); - }); + if (!m_cb_thread) + { + throw EXCEPTION("Callback thread not found"); } - m_cv.notify_one(); + m_async_cb.emplace(std::move(func)); + + m_cb_thread->cv.notify_one(); } -bool CallbackManager::Check(CPUThread& CPU, s32& result) +CallbackManager::check_cb_t CallbackManager::Check() { - std::function func; + std::lock_guard lock(m_mutex); + if (m_check_cb.size()) { - std::lock_guard lock(m_mutex); + check_cb_t func = std::move(m_check_cb.front()); - if (m_cb_list.size()) - { - func = m_cb_list[0]; - m_cb_list.erase(m_cb_list.begin()); - } + m_check_cb.pop(); + + return func; } - - return func ? result = func(CPU), true : false; + + return nullptr; } void CallbackManager::Init() { std::lock_guard lock(m_mutex); - if (Memory.PSV.RAM.GetStartAddr()) + auto task = [this](CPUThread& cpu) { - m_cb_thread = Emu.GetCPU().AddThread(CPU_THREAD_ARMv7); - m_cb_thread->SetName("Callback Thread"); - m_cb_thread->SetEntry(0); - m_cb_thread->SetPrio(1001); - m_cb_thread->SetStackSize(0x10000); - m_cb_thread->InitStack(); - m_cb_thread->InitRegs(); - static_cast(*m_cb_thread).DoRun(); - } - else - { - m_cb_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - m_cb_thread->SetName("Callback Thread"); - m_cb_thread->SetEntry(0); - m_cb_thread->SetPrio(1001); - m_cb_thread->SetStackSize(0x10000); - m_cb_thread->InitStack(); - m_cb_thread->InitRegs(); - static_cast(*m_cb_thread).DoRun(); - } - - thread_t cb_async_thread("CallbackManager thread", [this]() - { - SetCurrentNamedThread(&*m_cb_thread); - std::unique_lock lock(m_mutex); - while (!Emu.IsStopped()) + while (true) { - std::function func; + CHECK_EMU_STATUS; - if (m_async_list.size()) + if (!lock) { - func = m_async_list[0]; - m_async_list.erase(m_async_list.begin()); - } - - if (func) - { - lock.unlock(); - func(*m_cb_thread); lock.lock(); continue; } - m_cv.wait_for(lock, std::chrono::milliseconds(1)); + if (m_async_cb.size()) + { + async_cb_t func = std::move(m_async_cb.front()); + + m_async_cb.pop(); + + if (lock) lock.unlock(); + + func(cpu); + + continue; + } + + cpu.cv.wait(lock); } - }); + }; + + if (Memory.PSV.RAM.GetStartAddr()) + { + auto thread = Emu.GetIdManager().make_ptr("Callback Thread"); + + thread->prio = 1001; + thread->stack_size = 0x10000; + thread->custom_task = task; + thread->Run(); + + m_cb_thread = thread; + } + else + { + auto thread = Emu.GetIdManager().make_ptr("Callback Thread"); + + thread->prio = 1001; + thread->stack_size = 0x10000; + thread->custom_task = task; + thread->Run(); + + m_cb_thread = thread; + } } void CallbackManager::Clear() { std::lock_guard lock(m_mutex); - m_cb_list.clear(); - m_async_list.clear(); -} - -u64 CallbackManager::AddPauseCallback(const std::function& func) -{ - std::lock_guard lock(m_mutex); - - m_pause_cb_list.push_back({ func, next_tag }); - return next_tag++; -} - -void CallbackManager::RemovePauseCallback(const u64 tag) -{ - std::lock_guard lock(m_mutex); - - for (auto& data : m_pause_cb_list) - { - if (data.tag == tag) - { - m_pause_cb_list.erase(m_pause_cb_list.begin() + (&data - m_pause_cb_list.data())); - return; - } - } - - assert(!"CallbackManager()::RemovePauseCallback(): tag not found"); -} - -void CallbackManager::RunPauseCallbacks(const bool is_paused) -{ - std::lock_guard lock(m_mutex); - - for (auto& data : m_pause_cb_list) - { - if (data.cb) - { - data.cb(is_paused); - } - } + m_check_cb = decltype(m_check_cb){}; + m_async_cb = decltype(m_async_cb){}; + + m_cb_thread.reset(); } diff --git a/rpcs3/Emu/SysCalls/Callback.h b/rpcs3/Emu/SysCalls/Callback.h index 2b1cfe59d8..aa6f803980 100644 --- a/rpcs3/Emu/SysCalls/Callback.h +++ b/rpcs3/Emu/SysCalls/Callback.h @@ -1,66 +1,30 @@ #pragma once class CPUThread; -class PPUThread; - -typedef void(PauseResumeCB)(bool is_paused); class CallbackManager { - std::mutex m_mutex; - std::condition_variable m_cv; + using check_cb_t = std::function; + using async_cb_t = std::function; + + std::mutex m_mutex; + + std::queue m_check_cb; + std::queue m_async_cb; - std::vector> m_cb_list; - std::vector> m_async_list; std::shared_ptr m_cb_thread; - struct PauseResumeCBS - { - std::function cb; - u64 tag; - }; - - u64 next_tag; // not initialized, only increased - std::vector m_pause_cb_list; - public: - void Register(const std::function& func); // register callback (called in Check() method) + // register checked callback (accepts CPUThread&, returns s32) + void Register(check_cb_t func); - void Async(const std::function& func); // register callback for callback thread (called immediately) + // register async callback, called in callback thread (accepts CPUThread&) + void Async(async_cb_t func); - bool Check(CPUThread& CPU, s32& result); // call one callback registered by Register() method + // get one registered callback + check_cb_t Check(); void Init(); void Clear(); - - u64 AddPauseCallback(const std::function& func); // register callback for pausing/resuming emulation events - void RemovePauseCallback(const u64 tag); // unregister callback (uses the result of AddPauseCallback() function) - void RunPauseCallbacks(const bool is_paused); -}; - -class PauseCallbackRegisterer -{ - CallbackManager& cb_manager; - u64 cb_tag; - -private: - PauseCallbackRegisterer() = delete; - PauseCallbackRegisterer(const PauseCallbackRegisterer& right) = delete; - PauseCallbackRegisterer(PauseCallbackRegisterer&& right) = delete; - - PauseCallbackRegisterer& operator =(const PauseCallbackRegisterer& right) = delete; - PauseCallbackRegisterer& operator =(PauseCallbackRegisterer&& right) = delete; - -public: - PauseCallbackRegisterer(CallbackManager& cb_manager, const std::function& func) - : cb_manager(cb_manager) - , cb_tag(cb_manager.AddPauseCallback(func)) - { - } - - ~PauseCallbackRegisterer() - { - cb_manager.RemovePauseCallback(cb_tag); - } }; diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index b240a0d6ed..90d8bfdcc0 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -125,7 +125,7 @@ std::string SysCalls::GetFuncName(const u64 fid) case 145: return "sys_time_get_current_time"; case 146: return "sys_time_get_system_time"; case 147: return "sys_time_get_timebase_frequency"; - case 148: return "sys_rwlock_trywlock"; + case 148: return "_sys_rwlock_trywlock"; case 150: return "sys_raw_spu_create_interrupt_tag"; case 151: return "sys_raw_spu_set_int_mask"; case 152: return "sys_raw_spu_get_int_mask"; diff --git a/rpcs3/Emu/SysCalls/LogBase.cpp b/rpcs3/Emu/SysCalls/LogBase.cpp index 651e131eea..eaf112e0fb 100644 --- a/rpcs3/Emu/SysCalls/LogBase.cpp +++ b/rpcs3/Emu/SysCalls/LogBase.cpp @@ -16,58 +16,7 @@ void LogBase::LogOutput(LogType type, const std::string& text) const case LogNotice: LOG_NOTICE(HLE, GetName() + ": " + text); break; case LogSuccess: LOG_SUCCESS(HLE, GetName() + ": " + text); break; case LogWarning: LOG_WARNING(HLE, GetName() + ": " + text); break; - case LogError: LOG_ERROR(HLE, GetName() + " error: " + text); break; + case LogError: LOG_ERROR(HLE, GetName() + ": " + text); break; case LogTodo: LOG_ERROR(HLE, GetName() + " TODO: " + text); break; - case LogFatal: throw GetName() + " error: " + text; - } -} - -hle::error::error(s32 errorCode, const char* errorText) - : code(errorCode) - , base(nullptr) - , text(errorText ? errorText : "") -{ -} - -hle::error::error(s32 errorCode, const LogBase& errorBase, const char* errorText) - : code(errorCode) - , base(&errorBase) - , text(errorText ? errorText : "") -{ -} - -hle::error::error(s32 errorCode, const LogBase* errorBase, const char* errorText) - : code(errorCode) - , base(errorBase) - , text(errorText ? errorText : "") -{ -} - -void hle::error::print(const char* func) -{ - if (!text.empty()) - { - if (base) - { - if (func) - { - base->Error("%s(): %s (0x%x)", func, text.c_str(), code); - } - else - { - base->Error("%s (0x%x)", text.c_str(), code); - } - } - else - { - if (func) - { - LOG_ERROR(HLE, "%s(): %s (0x%x)", func, text.c_str(), code); - } - else - { - LOG_ERROR(HLE, "%s (0x%x)", text.c_str(), code); - } - } } } diff --git a/rpcs3/Emu/SysCalls/LogBase.h b/rpcs3/Emu/SysCalls/LogBase.h index 4acdc0d11b..f5f94455a4 100644 --- a/rpcs3/Emu/SysCalls/LogBase.h +++ b/rpcs3/Emu/SysCalls/LogBase.h @@ -11,7 +11,6 @@ class LogBase LogSuccess, LogWarning, LogError, - LogFatal, LogTodo, }; @@ -63,29 +62,8 @@ public: LogPrepare(LogError, fmt, fmt::do_unveil(args)...); } - template force_inline void Fatal(const char* fmt, Args... args) const - { - LogPrepare(LogFatal, fmt, fmt::do_unveil(args)...); - } - template force_inline void Todo(const char* fmt, Args... args) const { LogPrepare(LogTodo, fmt, fmt::do_unveil(args)...); } }; - -namespace hle -{ - struct error - { - const s32 code; - const LogBase* const base; - const std::string text; - - error(s32 errorCode, const char* errorText = nullptr); - error(s32 errorCode, const LogBase& base, const char* errorText = nullptr); - error(s32 errorCode, const LogBase* base, const char* errorText = nullptr); - - void print(const char* func = nullptr); - }; -} diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp index e0256fd20e..1fd79115ed 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ b/rpcs3/Emu/SysCalls/ModuleManager.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Modules.h" #include "ModuleManager.h" extern Module cellAdec; @@ -54,6 +55,7 @@ extern Module sys_io; extern Module sys_net; extern Module sysPrxForUser; extern Module sys_libc; +extern Module sys_lv2dbg; struct ModuleInfo { @@ -106,7 +108,7 @@ static const g_module_list[] = { 0x0028, "cellAdecAtx", nullptr }, { 0x0029, "cellAdecAt3", nullptr }, { 0x002a, "cellDmuxPamf", nullptr }, - { 0x002e, "cellLv2dbg", nullptr }, + { 0x002e, "sys_lv2dbg", &sys_lv2dbg }, { 0x0030, "cellUsbpspcm", nullptr }, { 0x0031, "cellAvconfExt", &cellAvconfExt }, { 0x0032, "cellUserInfo", &cellUserInfo }, diff --git a/rpcs3/Emu/SysCalls/ModuleManager.h b/rpcs3/Emu/SysCalls/ModuleManager.h index 4da02e2539..68dc46444d 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.h +++ b/rpcs3/Emu/SysCalls/ModuleManager.h @@ -1,5 +1,6 @@ #pragma once -#include "Modules.h" + +class Module; class ModuleManager { diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index a73da6981c..c20010f7bf 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -5,7 +5,6 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Crypto/sha1.h" #include "ModuleManager.h" #include "Emu/Cell/PPUInstrTable.h" @@ -25,8 +24,8 @@ u32 add_ppu_func(ModuleFunc func) { if (f.id == func.id) { - // TODO: if NIDs overlap or if the same function is added twice - assert(!"add_ppu_func(): NID already exists"); + // if NIDs overlap or if the same function is added twice + throw EXCEPTION("NID already exists: 0x%08x (%s)", f.id, f.name); } } @@ -59,8 +58,8 @@ u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], const { SearchPatternEntry op; op.type = ops[i].type; - op.data = re32(ops[i].data); - op.mask = re32(ops[i].mask); + op.data = _byteswap_ulong(ops[i].data); // TODO: use be_t<> + op.mask = _byteswap_ulong(ops[i].mask); op.num = ops[i].num; assert(!op.mask || (op.data & ~op.mask) == 0); sf.ops.push_back(op); @@ -106,56 +105,52 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) // save RTOC if necessary if (index & EIF_SAVE_RTOC) { - vm::write64(vm::cast(CPU.GPR[1] + 0x28), CPU.GPR[2]); + vm::write64(VM_CAST(CPU.GPR[1] + 0x28), CPU.GPR[2]); } // save old syscall/NID value - auto old_last_syscall = CPU.m_last_syscall; + const auto last_code = CPU.hle_code; // branch directly to the LLE function if (index & EIF_USE_BRANCH) { // for example, FastCall2 can't work with functions which do user level context switch - if (old_last_syscall) + if (last_code) { - CPU.m_last_syscall = func->id; - throw "Unfortunately, this function cannot be called from the callback."; + throw EXCEPTION("This function cannot be called from the callback: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); } if (!func->lle_func) { - CPU.m_last_syscall = func->id; - throw "Wrong usage: LLE function not set."; + throw EXCEPTION("LLE function not set: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); } if (func->flags & MFF_FORCED_HLE) { - CPU.m_last_syscall = func->id; - throw "Wrong usage: Forced HLE enabled."; + throw EXCEPTION("Forced HLE enabled: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); } if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(HLE, "Branch to LLE function: %s", SysCalls::GetFuncName(func->id)); + LOG_NOTICE(HLE, "Branch to LLE function: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); } if (index & EIF_PERFORM_BLR) { - CPU.m_last_syscall = func->id; - throw "TODO: Branch with link"; + throw EXCEPTION("TODO: Branch with link: %s (0x%llx)", SysCalls::GetFuncName(func->id), func->id); // CPU.LR = CPU.PC + 4; } const auto data = vm::get_ptr>(func->lle_func.addr()); - CPU.SetBranch(data[0]); + CPU.PC = data[0] - 4; CPU.GPR[2] = data[1]; // set rtoc return; } // change current syscall/NID value - CPU.m_last_syscall = func->id; + CPU.hle_code = func->id; if (func->lle_func && !(func->flags & MFF_FORCED_HLE)) { @@ -200,14 +195,14 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) if (index & EIF_PERFORM_BLR) { // return if necessary - CPU.SetBranch(vm::cast(CPU.LR & ~3), true); + CPU.PC = VM_CAST(CPU.LR & ~3) - 4; } - CPU.m_last_syscall = old_last_syscall; + CPU.hle_code = last_code; } else { - throw "Invalid function index"; + throw EXCEPTION("Invalid function index (0x%x)", index); } } @@ -250,7 +245,7 @@ void hook_ppu_func(vm::ptr base, u32 pos, u32 size) } // skip NOP - if (base[k].data() == se32(0x60000000)) + if (base[k] == 0x60000000) { x--; continue; @@ -308,7 +303,7 @@ void hook_ppu_func(vm::ptr base, u32 pos, u32 size) break; } - const auto addr = (base[k].data() & se32(2) ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); + const auto addr = (base[k] & 2 ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); const auto lnum = sub.ops[x].num; const auto label = sub.labels.find(lnum); @@ -331,15 +326,13 @@ void hook_ppu_func(vm::ptr base, u32 pos, u32 size) // break; // } - // const auto addr = (base[k].data() & se32(2) ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); + // const auto addr = (base[k] & 2 ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); // const auto nid = sub.ops[x].num; // // TODO: recursive call //} default: { - LOG_ERROR(LOADER, "Unknown search pattern type (%d)", sub.ops[x].type); - assert(0); - return; + throw EXCEPTION("Unknown search pattern type (%d)", sub.ops[x].type); } } @@ -376,7 +369,7 @@ void hook_ppu_funcs(vm::ptr base, u32 size) for (u32 i = 0; i < size; i++) { // skip NOP - if (base[i].data() == se32(0x60000000)) + if (base[i] == 0x60000000) { continue; } @@ -397,12 +390,13 @@ void hook_ppu_funcs(vm::ptr base, u32 size) continue; } - enum GroupSearchResult : u32 + enum : u32 { GSR_SUCCESS = 0, // every function from this group has been found once GSR_MISSING = 1, // (error) some function not found GSR_EXCESS = 2, // (error) some function found twice or more }; + u32 res = GSR_SUCCESS; // analyse @@ -478,7 +472,7 @@ void hook_ppu_funcs(vm::ptr base, u32 size) bool patch_ppu_import(u32 addr, u32 index) { - const auto data = vm::ptr::make(addr); + const auto data = vm::cptr::make(addr); using namespace PPU_instr; @@ -512,7 +506,7 @@ bool patch_ppu_import(u32 addr, u32 index) (data[1] & 0xffff0000) == ORIS(r0, r0, 0) && (data[2] & 0xfc000003) == B(0, 0, 0)) { - const auto sub = vm::ptr::make(addr + 8 + ((s32)data[2] << 6 >> 8 << 2)); + const auto sub = vm::cptr::make(addr + 8 + ((s32)data[2] << 6 >> 8 << 2)); if (vm::check_addr(sub.addr(), 60) && sub[0x0] == STDU(r1, r1, -0x80) && diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 67f68567b8..10203a49bc 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -1,8 +1,12 @@ #pragma once + #include "Emu/SysCalls/SC_FUNC.h" +#include "Emu/SysCalls/CB_FUNC.h" #include "ErrorCodes.h" #include "LogBase.h" +namespace vm { using namespace ps3; } + class Module; // flags set in ModuleFunc @@ -121,6 +125,26 @@ void hook_ppu_funcs(vm::ptr base, u32 size); bool patch_ppu_import(u32 addr, u32 index); +// call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise +template inline auto hle_call_func(PPUThread& CPU, T func, u32 index, Args&&... args) -> decltype(func(std::forward(args)...)) +{ + const auto mfunc = get_ppu_func_by_index(index); + + if (mfunc && mfunc->lle_func && (mfunc->flags & MFF_FORCED_HLE) == 0 && (mfunc->flags & MFF_NO_RETURN) == 0) + { + const u32 pc = vm::read32(mfunc->lle_func.addr()); + const u32 rtoc = vm::read32(mfunc->lle_func.addr() + 4); + + return cb_call(args)...)), Args...>(CPU, pc, rtoc, std::forward(args)...); + } + else + { + return func(std::forward(args)...); + } +} + +#define CALL_FUNC(cpu, func, ...) hle_call_func(cpu, func, g_ppu_func_index__##func, __VA_ARGS__) + #define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, #name, bind_func(name))) #define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, #name, bind_func(name))) #define REG_FUNC_NR(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_NO_RETURN, &module, #name, bind_func(name))) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 4e410636b1..524d5973fc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -3,7 +3,6 @@ #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" extern std::mutex g_mutex_avcodec_open2; @@ -14,7 +13,6 @@ extern "C" #include "libswresample/swresample.h" } -#include "Emu/CPU/CPUThreadManager.h" #include "cellPamf.h" #include "cellAdec.h" @@ -22,14 +20,13 @@ extern Module cellAdec; #define ADEC_ERROR(...) { cellAdec.Error(__VA_ARGS__); Emu.Pause(); return; } // only for decoder thread -AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr func, u32 arg) +AudioDecoder::AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr func, u32 arg) : type(type) , memAddr(addr) , memSize(size) , memBias(0) , cbFunc(func) , cbArg(arg) - , adecCb(nullptr) , is_closed(false) , is_finished(false) , just_started(false) @@ -223,16 +220,10 @@ void adecOpen(u32 adec_id) // TODO: call from the constructor adec.id = adec_id; - adec.adecCb = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_PPU).get()); - adec.adecCb->SetName(fmt::format("AudioDecoder[0x%x] Callback", adec_id)); - adec.adecCb->SetEntry(0); - adec.adecCb->SetPrio(1001); - adec.adecCb->SetStackSize(0x10000); - adec.adecCb->InitStack(); - adec.adecCb->InitRegs(); - adec.adecCb->DoRun(); - - thread_t t(fmt::format("AudioDecoder[0x%x] Thread", adec_id), [sptr]() + adec.adecCb = Emu.GetIdManager().make_ptr(fmt::format("Demuxer[0x%x] Thread", adec_id)); + adec.adecCb->prio = 1001; + adec.adecCb->stack_size = 0x10000; + adec.adecCb->custom_task = [sptr](PPUThread& CPU) { AudioDecoder& adec = *sptr; AdecTask& task = adec.task; @@ -277,7 +268,7 @@ void adecOpen(u32 adec_id) // TODO: call from the constructor { // TODO: finalize cellAdec.Warning("adecEndSeq:"); - adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); + adec.cbFunc(CPU, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); adec.just_finished = true; break; @@ -453,12 +444,12 @@ void adecOpen(u32 adec_id) // TODO: call from the constructor if (adec.frames.push(frame, &adec.is_closed)) { frame.data = nullptr; // to prevent destruction - adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); + adec.cbFunc(CPU, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg); } } } - adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); + adec.cbFunc(CPU, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg); break; } @@ -475,10 +466,14 @@ void adecOpen(u32 adec_id) // TODO: call from the constructor } adec.is_finished = true; - }); + + }; + + adec.adecCb->Run(); + adec.adecCb->Exec(); } -bool adecCheckType(AudioCodecType type) +bool adecCheckType(s32 type) { switch (type) { @@ -572,15 +567,12 @@ s32 cellAdecClose(u32 handle) while (!adec->is_finished) { - if (Emu.IsStopped()) - { - cellAdec.Warning("cellAdecClose(%d) aborted", handle); - break; - } + CHECK_EMU_STATUS; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - if (adec->adecCb) Emu.GetCPU().RemoveThread(adec->adecCb->GetId()); + Emu.GetIdManager().remove(adec->adecCb->GetId()); Emu.GetIdManager().remove(handle); return CELL_OK; } @@ -605,7 +597,7 @@ s32 cellAdecStartSeq(u32 handle, u32 param) case CELL_ADEC_TYPE_ATRACX_6CH: case CELL_ADEC_TYPE_ATRACX_8CH: { - const auto atx = vm::ptr::make(param); + const auto atx = vm::cptr::make(param); task.at3p.sample_rate = atx->sampling_freq; task.at3p.channel_config = atx->ch_config_idx; @@ -621,7 +613,7 @@ s32 cellAdecStartSeq(u32 handle, u32 param) } case CELL_ADEC_TYPE_MP3: { - const auto mp3 = vm::ptr::make(param); + const auto mp3 = vm::cptr::make(param); cellAdec.Todo("*** CellAdecParamMP3: bw_pcm=%d", mp3->bw_pcm); break; @@ -785,7 +777,7 @@ s32 cellAdecGetPcm(u32 handle, vm::ptr outBuffer) } else { - cellAdec.Fatal("cellAdecGetPcm(): unsupported frame format (channels=%d, format=%d)", frame->channels, frame->format); + throw EXCEPTION("Unsupported frame format (channels=%d, format=%d)", frame->channels, frame->format); } } @@ -825,8 +817,8 @@ s32 cellAdecGetPcmItem(u32 handle, vm::pptr pcmItem) pcm->startAddr = 0x00000312; // invalid address (no output) pcm->size = af.size; pcm->status = CELL_OK; - pcm->auInfo.pts.lower = (u32)af.pts; - pcm->auInfo.pts.upper = af.pts >> 32; + pcm->auInfo.pts.lower = (u32)(af.pts); + pcm->auInfo.pts.upper = (u32)(af.pts >> 32); pcm->auInfo.size = af.auSize; pcm->auInfo.startAddr = af.auAddr; pcm->auInfo.userData = af.userdata; @@ -836,7 +828,7 @@ s32 cellAdecGetPcmItem(u32 handle, vm::pptr pcmItem) auto atx = vm::ptr::make(pcm.addr() + sizeof32(CellAdecPcmItem)); atx->samplingFreq = frame->sample_rate; - atx->nbytes = frame->nb_samples * sizeof(float); + atx->nbytes = frame->nb_samples * sizeof32(float); if (frame->channels == 1) { atx->channelConfigIndex = 1; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index 00c5a58c3e..5ef4594a5d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -246,7 +248,7 @@ enum }; // Audio Codec Type -enum AudioCodecType +enum AudioCodecType : s32 { CELL_ADEC_TYPE_RESERVED1, CELL_ADEC_TYPE_LPCM_PAMF, @@ -282,7 +284,7 @@ enum AudioCodecType CELL_ADEC_TYPE_RESERVED25, }; -static bool adecIsAtracX(const AudioCodecType type) +inline bool adecIsAtracX(s32 type) { return type == CELL_ADEC_TYPE_ATRACX || type == CELL_ADEC_TYPE_ATRACX_2CH @@ -291,7 +293,7 @@ static bool adecIsAtracX(const AudioCodecType type) } // Output Channel Number -enum CellAdecChannel +enum CellAdecChannel : s32 { CELL_ADEC_CH_RESERVED1, CELL_ADEC_CH_MONO, @@ -309,7 +311,7 @@ enum CellAdecChannel }; // Sampling Rate -enum CellAdecSampleRate +enum CellAdecSampleRate : s32 { CELL_ADEC_FS_RESERVED1 = 0, CELL_ADEC_FS_48kHz = 1, @@ -317,7 +319,7 @@ enum CellAdecSampleRate CELL_ADEC_FS_8kHz = 5, }; -enum CellAdecBitLength +enum CellAdecBitLength : s32 { CELL_ADEC_BIT_LENGTH_RESERVED1, CELL_ADEC_BIT_LENGTH_16, @@ -327,7 +329,7 @@ enum CellAdecBitLength struct CellAdecType { - be_t audioCodecType; + be_t audioCodecType; // AudioCodecType }; struct CellAdecAttr @@ -358,7 +360,7 @@ struct CellAdecResourceEx }; // Callback Messages -enum CellAdecMsgType +enum CellAdecMsgType : s32 { CELL_ADEC_MSG_TYPE_AUDONE, CELL_ADEC_MSG_TYPE_PCMOUT, @@ -366,7 +368,7 @@ enum CellAdecMsgType CELL_ADEC_MSG_TYPE_SEQDONE, }; -typedef s32(CellAdecCbMsg)(u32 handle, CellAdecMsgType msgType, s32 msgData, u32 cbArg); +using CellAdecCbMsg = func_def; struct CellAdecCb { @@ -374,8 +376,6 @@ struct CellAdecCb be_t cbArg; }; -typedef CellCodecTimeStamp CellAdecTimeStamp; - // AU Info struct CellAdecAuInfo { @@ -418,13 +418,13 @@ struct CellAdecLpcmInfo }; // CELP Excitation Mode -enum CELP_ExcitationMode +enum CELP_ExcitationMode : s32 { CELL_ADEC_CELP_EXCITATION_MODE_RPE = 1, }; // CELP RPE Configuration -enum CELP_RPEConfig +enum CELP_RPEConfig : s32 { CELL_ADEC_CELP_RPE_CONFIG_0, CELL_ADEC_CELP_RPE_CONFIG_1, @@ -433,7 +433,7 @@ enum CELP_RPEConfig }; // CELP Word Size -enum CELP_WordSize +enum CELP_WordSize : s32 { CELL_ADEC_CELP_WORD_SZ_INT16_LE, CELL_ADEC_CELP_WORD_SZ_FLOAT, @@ -458,13 +458,13 @@ struct CellAdecCelpInfo }; // CELP8 Excitation Mode -enum CELP8_ExcitationMode +enum CELP8_ExcitationMode : s32 { CELL_ADEC_CELP8_EXCITATION_MODE_MPE = 0, }; // CELP8 MPE Configuration -enum CELP8_MPEConfig +enum CELP8_MPEConfig : s32 { CELL_ADEC_CELP8_MPE_CONFIG_0 = 0, CELL_ADEC_CELP8_MPE_CONFIG_2 = 2, @@ -479,7 +479,7 @@ enum CELP8_MPEConfig }; // CELP8 Word Size -enum CELP8_WordSize +enum CELP8_WordSize : s32 { CELL_ADEC_CELP8_WORD_SZ_FLOAT, }; @@ -502,14 +502,14 @@ struct CellAdecCelp8Info be_t wordSize; }; -enum MPEG4AAC_ConfigType +enum MPEG4AAC_ConfigType : s32 { ADIFHeader = 0, ADTSHeader = 1, RawDataBlockOnly = 2, }; -enum MPEG4AAC_SamplingFreq +enum MPEG4AAC_SamplingFreq : s32 { SF_96000 = 0, SF_88200 = 1, @@ -528,26 +528,30 @@ enum MPEG4AAC_SamplingFreq // MPEG4 AAC Parameters struct CellAdecParamM4Aac { - be_t configNumber; + be_t configNumber; // MPEG4AAC_ConfigType - union { - struct mp { struct mp2 + union + { + struct { - be_t adifProgramNumber; // 0 - } adifConfig; }; + be_t programNumber; + } + adifConfig; - struct mp3 { struct mp4 + struct { - be_t samplingFreqIndex; + be_t samplingFreqIndex; // MPEG4AAC_SamplingFreq be_t profile; // LC profile (1) - } rawDataBlockConfig; }; - } configInfo; + } + rawDataBlockConfig; + } + configInfo; be_t enableDownmix; // enable downmix to 2.0 (if (enableDownmix)) }; // MPEG4 AAC BSI -struct CellAdecM4AacInfo +struct set_alignment(16) CellAdecM4AacInfo { be_t samplingFreq; // [Hz] be_t numberOfChannels; @@ -559,55 +563,52 @@ struct CellAdecM4AacInfo be_t enableSBR; be_t SBRUpsamplingFactor; be_t isBsiValid; - be_t configNumber; - - be_t pad1; // TODO: check alignment + be_t configNumber; // MPEG4AAC_ConfigType - union { - struct mp5 { - struct m6 - { - be_t copyrightIdPresent; - char copyrightId[9]; - be_t originalCopy; - be_t home; - be_t bitstreamType; - be_t bitrate; - be_t numberOfProgramConfigElements; - be_t bufferFullness; - } adif; - }; + union + { + struct + { + be_t copyrightIdPresent; + char copyrightId[9]; + be_t originalCopy; + be_t home; + be_t bitstreamType; + be_t bitrate; + be_t numberOfProgramConfigElements; + be_t bufferFullness; + } + adif; - struct mp7 { - struct mp8 - { - be_t id; - be_t layer; - be_t protectionAbsent; - be_t profile; - be_t samplingFreqIndex; - be_t privateBit; - be_t channelConfiguration; - be_t originalCopy; - be_t home; - be_t copyrightIdBit; - be_t copyrightIdStart; - be_t frameLength; - be_t bufferFullness; - be_t numberOfRawDataBlocks; - be_t crcCheck; - } adts; - }; - } bsi; + struct mp8 + { + be_t id; + be_t layer; + be_t protectionAbsent; + be_t profile; + be_t samplingFreqIndex; + be_t privateBit; + be_t channelConfiguration; + be_t originalCopy; + be_t home; + be_t copyrightIdBit; + be_t copyrightIdStart; + be_t frameLength; + be_t bufferFullness; + be_t numberOfRawDataBlocks; + be_t crcCheck; + } + adts; + } + bsi; - be_t pad2; // TODO: check alignment - - struct mp9 + struct { be_t matrixMixdownPresent; be_t mixdownIndex; be_t pseudoSurroundEnable; - } matrixMixdown; + } + matrixMixdown; be_t reserved; }; @@ -758,15 +759,15 @@ enum ATRAC3_JointType : s32 struct CellAdecParamAtrac3 { be_t nch; // channel count - be_t isJoint; + be_t isJoint; // ATRAC3_JointType be_t nbytes; // byte count of single AU (???) - be_t bw_pcm; // bit length of output PCM sample + be_t bw_pcm; // ATRAC3_WordSize, bit length of output PCM sample }; struct CellAdecAtrac3Info { be_t nch; - be_t isJoint; + be_t isJoint; // ATRAC3_JointType be_t nbytes; }; @@ -797,7 +798,7 @@ struct CellAdecParamAtracX be_t nch_out; be_t nbytes; std::array extra_config_data; // downmix coefficients - be_t bw_pcm; + be_t bw_pcm; // ATRACX_WordSize ATRACX_DownmixFlag downmix_flag; ATRACX_ATSHeaderInclude au_includes_ats_hdr_flg; }; @@ -831,7 +832,7 @@ enum MP3_CRCMode : u8 struct CellAdecParamMP3 { - be_t bw_pcm; + be_t bw_pcm; // MP3_WordSize }; struct CellAdecMP3Info @@ -850,20 +851,20 @@ struct CellAdecMP3Info be_t i_error_code; }; -enum M2BC_SampleFrequency +enum M2BC_SampleFrequency : s32 { CELL_ADEC_BSI_M2BC_SAMPLE_FREQUENCY_44 = 0, CELL_ADEC_BSI_M2BC_SAMPLE_FREQUENCY_48 = 1, CELL_ADEC_BSI_M2BC_SAMPLE_FREQUENCY_32 = 2, }; -enum M2BC_ErrorProtection +enum M2BC_ErrorProtection : s32 { CELL_ADEC_BSI_M2BC_ERROR_PROTECTION_NONE = 0, CELL_ADEC_BSI_M2BC_ERROR_PROTECTION_EXIST = 1, }; -enum M2BC_BitrateIndex +enum M2BC_BitrateIndex : s32 { CELL_ADEC_BSI_M2BC_BITRATE_32 = 1, CELL_ADEC_BSI_M2BC_BITRATE_48 = 2, @@ -881,7 +882,7 @@ enum M2BC_BitrateIndex CELL_ADEC_BSI_M2BC_BITRATE_384 = 14, }; -enum M2BC_StereoMode +enum M2BC_StereoMode : s32 { CELL_ADEC_BSI_M2BC_STEREO_MODE_STERO = 0, CELL_ADEC_BSI_M2BC_STEREO_MODE_JOINTSTERO = 1, @@ -889,7 +890,7 @@ enum M2BC_StereoMode CELL_ADEC_BSI_M2BC_STEREO_MODE_MONO = 3, }; -enum M2BC_StereoModeEx +enum M2BC_StereoModeEx : s32 { CELL_ADEC_BSI_M2BC_STEREO_EXMODE_0 = 0, CELL_ADEC_BSI_M2BC_STEREO_EXMODE_1 = 1, @@ -897,26 +898,26 @@ enum M2BC_StereoModeEx CELL_ADEC_BSI_M2BC_STEREO_EXMODE_3 = 3, }; -enum M2BC_Emphasis +enum M2BC_Emphasis : s32 { CELL_ADEC_BSI_M2BC_EMPHASIS_NONE = 0, CELL_ADEC_BSI_M2BC_EMPHASIS_50_15 = 1, CELL_ADEC_BSI_M2BC_EMPHASIS_CCITT = 3, }; -enum M2BC_CopyrightBit +enum M2BC_CopyrightBit : s32 { CELL_ADEC_BSI_M2BC_COPYRIGHT_NONE = 0, CELL_ADEC_BSI_M2BC_COPYRIGHT_ON = 1, }; -enum M2BC_OriginalBit +enum M2BC_OriginalBit : s32 { CELL_ADEC_BSI_M2BC_ORIGINAL_COPY = 0, CELL_ADEC_BSI_M2BC_ORIGINAL_ORIGINAL = 1, }; -enum M2BC_SurroundMode +enum M2BC_SurroundMode : s32 { CELL_ADEC_BSI_M2BC_SURROUND_NONE = 0, CELL_ADEC_BSI_M2BC_SURROUND_MONO = 1, @@ -924,33 +925,33 @@ enum M2BC_SurroundMode CELL_ADEC_BSI_M2BC_SURROUND_SECOND = 3, }; -enum M2BC_CenterMode +enum M2BC_CenterMode : s32 { CELL_ADEC_BSI_M2BC_CENTER_NONE = 0, CELL_ADEC_BSI_M2BC_CENTER_EXIST = 1, CELL_ADEC_BSI_M2BC_CENTER_PHANTOM = 3, }; -enum M2BC_LFE +enum M2BC_LFE : s32 { CELL_ADEC_BSI_M2BC_LFE_NONE = 0, CELL_ADEC_BSI_M2BC_LFE_EXIST = 1, }; -enum M2BC_AudioMixMode +enum M2BC_AudioMixMode : s32 { CELL_ADEC_BSI_M2BC_AUDIOMIX_LARGE = 0, CELL_ADEC_BSI_M2BC_AUDIOMIX_SMALLE = 1, }; -enum M2BC_MCExtension +enum M2BC_MCExtension : s32 { CELL_ADEC_BSI_M2BC_MCEXTENSION_2CH = 0, CELL_ADEC_BSI_M2BC_MCEXTENSION_5CH = 1, CELL_ADEC_BSI_M2BC_MCEXTENSION_7CH = 2, }; -enum M2BC_ChannelConfig +enum M2BC_ChannelConfig : s32 { CELL_ADEC_BSI_M2BC_CH_CONFIG_MONO = 0, CELL_ADEC_BSI_M2BC_CH_CONFIG_DUAL = 1, @@ -1094,7 +1095,7 @@ struct OMAHeader // OMA Header } }; -static_assert(sizeof(OMAHeader) == 96, "Wrong OMAHeader size"); +CHECK_SIZE(OMAHeader, 96); class AudioDecoder { @@ -1128,7 +1129,7 @@ public: squeue_t frames; - const AudioCodecType type; + const s32 type; const u32 memAddr; const u32 memSize; const vm::ptr cbFunc; @@ -1144,9 +1145,9 @@ public: u32 sample_rate; bool use_ats_headers; - PPUThread* adecCb; + std::shared_ptr adecCb; - AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr func, u32 arg); + AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr func, u32 arg); ~AudioDecoder(); }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp index 464ac26224..f3553f463f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp @@ -7,44 +7,40 @@ extern Module cellAtrac; #include "cellAtrac.h" -s32 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr puiWorkMemByte) +s32 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, vm::ptr pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr puiWorkMemByte) { - cellAtrac.Warning("cellAtracSetDataAndGetMemSize(pHandle=0x%x, pucBufferAddr=0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte_addr=0x%x)", - pHandle.addr(), pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte.addr()); + cellAtrac.Warning("cellAtracSetDataAndGetMemSize(pHandle=*0x%x, pucBufferAddr=*0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte=*0x%x)", pHandle, pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte); - *puiWorkMemByte = 0x1000; // unproved + *puiWorkMemByte = 0x1000; return CELL_OK; } -s32 cellAtracCreateDecoder(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority) +s32 cellAtracCreateDecoder(vm::ptr pHandle, vm::ptr pucWorkMem, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority) { - cellAtrac.Warning("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)", - pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority); + cellAtrac.Warning("cellAtracCreateDecoder(pHandle=*0x%x, pucWorkMem=*0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)", pHandle, pucWorkMem, uiPpuThreadPriority, uiSpuThreadPriority); - pHandle->data.pucWorkMem_addr = pucWorkMem_addr; + pHandle->pucWorkMem = pucWorkMem; return CELL_OK; } -s32 cellAtracCreateDecoderExt(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, vm::ptr pExtRes) +s32 cellAtracCreateDecoderExt(vm::ptr pHandle, vm::ptr pucWorkMem, u32 uiPpuThreadPriority, vm::ptr pExtRes) { - cellAtrac.Warning("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)", - pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.addr()); + cellAtrac.Warning("cellAtracCreateDecoderExt(pHandle=*0x%x, pucWorkMem=*0x%x, uiPpuThreadPriority=%d, pExtRes=*0x%x)", pHandle, pucWorkMem, uiPpuThreadPriority, pExtRes); - pHandle->data.pucWorkMem_addr = pucWorkMem_addr; + pHandle->pucWorkMem = pucWorkMem; return CELL_OK; } s32 cellAtracDeleteDecoder(vm::ptr pHandle) { - cellAtrac.Warning("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr()); + cellAtrac.Warning("cellAtracDeleteDecoder(pHandle=*0x%x)", pHandle); return CELL_OK; } -s32 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr puiSamples, vm::ptr puiFinishflag, vm::ptr piRemainFrame) +s32 cellAtracDecode(vm::ptr pHandle, vm::ptr pfOutAddr, vm::ptr puiSamples, vm::ptr puiFinishflag, vm::ptr piRemainFrame) { - cellAtrac.Warning("cellAtracDecode(pHandle=0x%x, pfOutAddr=0x%x, puiSamples_addr=0x%x, puiFinishFlag_addr=0x%x, piRemainFrame_addr=0x%x)", - pHandle.addr(), pfOutAddr, puiSamples.addr(), puiFinishflag.addr(), piRemainFrame.addr()); + cellAtrac.Warning("cellAtracDecode(pHandle=*0x%x, pfOutAddr=*0x%x, puiSamples=*0x%x, puiFinishFlag=*0x%x, piRemainFrame=*0x%x)", pHandle, pfOutAddr, puiSamples, puiFinishflag, piRemainFrame); *puiSamples = 0; *puiFinishflag = 1; @@ -52,12 +48,11 @@ s32 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr pHandle, vm::ptr ppucWritePointer, vm::ptr puiWritableByte, vm::ptr puiReadPosition) +s32 cellAtracGetStreamDataInfo(vm::ptr pHandle, vm::pptr ppucWritePointer, vm::ptr puiWritableByte, vm::ptr puiReadPosition) { - cellAtrac.Warning("cellAtracGetStreamDataInfo(pHandle=0x%x, ppucWritePointer_addr=0x%x, puiWritableByte_addr=0x%x, puiReadPosition_addr=0x%x)", - pHandle.addr(), ppucWritePointer.addr(), puiWritableByte.addr(), puiReadPosition.addr()); + cellAtrac.Warning("cellAtracGetStreamDataInfo(pHandle=*0x%x, ppucWritePointer=**0x%x, puiWritableByte=*0x%x, puiReadPosition=*0x%x)", pHandle, ppucWritePointer, puiWritableByte, puiReadPosition); - *ppucWritePointer = pHandle->data.pucWorkMem_addr; + *ppucWritePointer = pHandle->pucWorkMem; *puiWritableByte = 0x1000; *puiReadPosition = 0; return CELL_OK; @@ -65,14 +60,14 @@ s32 cellAtracGetStreamDataInfo(vm::ptr pHandle, vm::ptr pp s32 cellAtracAddStreamData(vm::ptr pHandle, u32 uiAddByte) { - cellAtrac.Warning("cellAtracAddStreamData(pHandle=0x%x, uiAddByte=0x%x)", pHandle.addr(), uiAddByte); + cellAtrac.Warning("cellAtracAddStreamData(pHandle=*0x%x, uiAddByte=0x%x)", pHandle, uiAddByte); return CELL_OK; } -s32 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRemainFrame) +s32 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRemainFrame) { - cellAtrac.Warning("cellAtracGetRemainFrame(pHandle=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), piRemainFrame.addr()); + cellAtrac.Warning("cellAtracGetRemainFrame(pHandle=*0x%x, piRemainFrame=*0x%x)", pHandle, piRemainFrame); *piRemainFrame = CELL_ATRAC_ALLDATA_IS_ON_MEMORY; return CELL_OK; @@ -80,7 +75,7 @@ s32 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRem s32 cellAtracGetVacantSize(vm::ptr pHandle, vm::ptr puiVacantSize) { - cellAtrac.Warning("cellAtracGetVacantSize(pHandle=0x%x, puiVacantSize_addr=0x%x)", pHandle.addr(), puiVacantSize.addr()); + cellAtrac.Warning("cellAtracGetVacantSize(pHandle=*0x%x, puiVacantSize=*0x%x)", pHandle, puiVacantSize); *puiVacantSize = 0x1000; return CELL_OK; @@ -88,32 +83,30 @@ s32 cellAtracGetVacantSize(vm::ptr pHandle, vm::ptr puiVac s32 cellAtracIsSecondBufferNeeded(vm::ptr pHandle) { - cellAtrac.Warning("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr()); + cellAtrac.Warning("cellAtracIsSecondBufferNeeded(pHandle=*0x%x)", pHandle); - return CELL_OK; + return 0; } s32 cellAtracGetSecondBufferInfo(vm::ptr pHandle, vm::ptr puiReadPosition, vm::ptr puiDataByte) { - cellAtrac.Warning("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)", - pHandle.addr(), puiReadPosition.addr(), puiDataByte.addr()); + cellAtrac.Warning("cellAtracGetSecondBufferInfo(pHandle=*0x%x, puiReadPosition=*0x%x, puiDataByte=*0x%x)", pHandle, puiReadPosition, puiDataByte); *puiReadPosition = 0; *puiDataByte = 0; // write to null block will occur return CELL_OK; } -s32 cellAtracSetSecondBuffer(vm::ptr pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte) +s32 cellAtracSetSecondBuffer(vm::ptr pHandle, vm::ptr pucSecondBufferAddr, u32 uiSecondBufferByte) { - cellAtrac.Warning("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)", - pHandle.addr(), pucSecondBufferAddr, uiSecondBufferByte); + cellAtrac.Warning("cellAtracSetSecondBuffer(pHandle=*0x%x, pucSecondBufferAddr=*0x%x, uiSecondBufferByte=0x%x)", pHandle, pucSecondBufferAddr, uiSecondBufferByte); return CELL_OK; } s32 cellAtracGetChannel(vm::ptr pHandle, vm::ptr puiChannel) { - cellAtrac.Warning("cellAtracGetChannel(pHandle=0x%x, puiChannel_addr=0x%x)", pHandle.addr(), puiChannel.addr()); + cellAtrac.Warning("cellAtracGetChannel(pHandle=*0x%x, puiChannel=*0x%x)", pHandle, puiChannel); *puiChannel = 2; return CELL_OK; @@ -121,7 +114,7 @@ s32 cellAtracGetChannel(vm::ptr pHandle, vm::ptr puiChanne s32 cellAtracGetMaxSample(vm::ptr pHandle, vm::ptr puiMaxSample) { - cellAtrac.Warning("cellAtracGetMaxSample(pHandle=0x%x, puiMaxSample_addr=0x%x)", pHandle.addr(), puiMaxSample.addr()); + cellAtrac.Warning("cellAtracGetMaxSample(pHandle=*0x%x, puiMaxSample=*0x%x)", pHandle, puiMaxSample); *puiMaxSample = 512; return CELL_OK; @@ -129,16 +122,15 @@ s32 cellAtracGetMaxSample(vm::ptr pHandle, vm::ptr puiMaxS s32 cellAtracGetNextSample(vm::ptr pHandle, vm::ptr puiNextSample) { - cellAtrac.Warning("cellAtracGetNextSample(pHandle=0x%x, puiNextSample_addr=0x%x)", pHandle.addr(), puiNextSample.addr()); + cellAtrac.Warning("cellAtracGetNextSample(pHandle=*0x%x, puiNextSample=*0x%x)", pHandle, puiNextSample); *puiNextSample = 0; return CELL_OK; } -s32 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSample, vm::ptr piLoopStartSample, vm::ptr piLoopEndSample) +s32 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSample, vm::ptr piLoopStartSample, vm::ptr piLoopEndSample) { - cellAtrac.Warning("cellAtracGetSoundInfo(pHandle=0x%x, piEndSample_addr=0x%x, piLoopStartSample_addr=0x%x, piLoopEndSample_addr=0x%x)", - pHandle.addr(), piEndSample.addr(), piLoopStartSample.addr(), piLoopEndSample.addr()); + cellAtrac.Warning("cellAtracGetSoundInfo(pHandle=*0x%x, piEndSample=*0x%x, piLoopStartSample=*0x%x, piLoopEndSample=*0x%x)", pHandle, piEndSample, piLoopStartSample, piLoopEndSample); *piEndSample = 0; *piLoopStartSample = 0; @@ -148,8 +140,7 @@ s32 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSa s32 cellAtracGetNextDecodePosition(vm::ptr pHandle, vm::ptr puiSamplePosition) { - cellAtrac.Warning("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)", - pHandle.addr(), puiSamplePosition.addr()); + cellAtrac.Warning("cellAtracGetNextDecodePosition(pHandle=*0x%x, puiSamplePosition=*0x%x)", pHandle, puiSamplePosition); *puiSamplePosition = 0; return CELL_ATRAC_ERROR_ALLDATA_WAS_DECODED; @@ -157,36 +148,33 @@ s32 cellAtracGetNextDecodePosition(vm::ptr pHandle, vm::ptr pHandle, vm::ptr puiBitrate) { - cellAtrac.Warning("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)", - pHandle.addr(), puiBitrate.addr()); + cellAtrac.Warning("cellAtracGetBitrate(pHandle=*0x%x, puiBitrate=*0x%x)", pHandle, puiBitrate); *puiBitrate = 128; return CELL_OK; } -s32 cellAtracGetLoopInfo(vm::ptr pHandle, vm::ptr piLoopNum, vm::ptr puiLoopStatus) +s32 cellAtracGetLoopInfo(vm::ptr pHandle, vm::ptr piLoopNum, vm::ptr puiLoopStatus) { - cellAtrac.Warning("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)", - pHandle.addr(), piLoopNum.addr(), puiLoopStatus.addr()); + cellAtrac.Warning("cellAtracGetLoopInfo(pHandle=*0x%x, piLoopNum=*0x%x, puiLoopStatus=*0x%x)", pHandle, piLoopNum, puiLoopStatus); *piLoopNum = 0; *puiLoopStatus = 0; return CELL_OK; } -s32 cellAtracSetLoopNum(vm::ptr pHandle, int iLoopNum) +s32 cellAtracSetLoopNum(vm::ptr pHandle, s32 iLoopNum) { - cellAtrac.Warning("cellAtracSetLoopNum(pHandle=0x%x, iLoopNum=0x%x)", pHandle.addr(), iLoopNum); + cellAtrac.Warning("cellAtracSetLoopNum(pHandle=*0x%x, iLoopNum=%d)", pHandle, iLoopNum); return CELL_OK; } s32 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiSample, vm::ptr pBufferInfo) { - cellAtrac.Warning("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)", - pHandle.addr(), uiSample, pBufferInfo.addr()); + cellAtrac.Warning("cellAtracGetBufferInfoForResetting(pHandle=*0x%x, uiSample=0x%x, pBufferInfo=*0x%x)", pHandle, uiSample, pBufferInfo); - pBufferInfo->pucWriteAddr = pHandle->data.pucWorkMem_addr; + pBufferInfo->pucWriteAddr = pHandle->pucWorkMem; pBufferInfo->uiWritableByte = 0x1000; pBufferInfo->uiMinWriteByte = 0; pBufferInfo->uiReadPosition = 0; @@ -195,16 +183,14 @@ s32 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiS s32 cellAtracResetPlayPosition(vm::ptr pHandle, u32 uiSample, u32 uiWriteByte) { - cellAtrac.Warning("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)", - pHandle.addr(), uiSample, uiWriteByte); + cellAtrac.Warning("cellAtracResetPlayPosition(pHandle=*0x%x, uiSample=0x%x, uiWriteByte=0x%x)", pHandle, uiSample, uiWriteByte); return CELL_OK; } -s32 cellAtracGetInternalErrorInfo(vm::ptr pHandle, vm::ptr piResult) +s32 cellAtracGetInternalErrorInfo(vm::ptr pHandle, vm::ptr piResult) { - cellAtrac.Warning("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)", - pHandle.addr(), piResult.addr()); + cellAtrac.Warning("cellAtracGetInternalErrorInfo(pHandle=*0x%x, piResult=*0x%x)", pHandle, piResult); *piResult = 0; return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.h b/rpcs3/Emu/SysCalls/Modules/cellAtrac.h index c6102316b9..639afbc122 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -53,26 +55,24 @@ enum }; // Remain Frame -enum +enum : s32 { - CELL_ATRAC_ALLDATA_IS_ON_MEMORY = -1, + CELL_ATRAC_ALLDATA_IS_ON_MEMORY = -1, CELL_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY = -2, - CELL_ATRAC_LOOP_STREAM_DATA_IS_ON_MEMORY = -3, + CELL_ATRAC_LOOP_STREAM_DATA_IS_ON_MEMORY = -3, }; union CellAtracHandle { - u8 uiWorkMem[512]; - - struct AtracHandle - { - u32 pucWorkMem_addr; - } data; + vm::ptr pucWorkMem; + // ... }; +CHECK_MAX_SIZE(CellAtracHandle, 512); + struct CellAtracBufferInfo { - be_t pucWriteAddr; + vm::ptr pucWriteAddr; be_t uiWritableByte; be_t uiMinWriteByte; be_t uiReadPosition; @@ -80,6 +80,6 @@ struct CellAtracBufferInfo struct CellAtracExtRes { - be_t pSpurs_addr; + vm::ptr pSpurs; u8 priority[8]; }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index e857e9acf8..e7d5ab7611 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -7,7 +7,6 @@ #include "rpcs3/Ini.h" #include "Emu/SysCalls/lv2/sleep_queue.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include "Emu/SysCalls/lv2/sys_event.h" #include "Emu/Event.h" #include "Emu/Audio/AudioManager.h" @@ -17,6 +16,8 @@ extern Module cellAudio; +extern u64 get_system_time(); + AudioConfig g_audio; s32 cellAudioInit() @@ -31,32 +32,39 @@ s32 cellAudioInit() // clear ports for (auto& port : g_audio.ports) { - port.state.write_relaxed(AUDIO_PORT_STATE_CLOSED); + port.state.store(AUDIO_PORT_STATE_CLOSED); } // reset variables - g_audio.start_time = 0; g_audio.counter = 0; g_audio.keys.clear(); g_audio.start_time = get_system_time(); // alloc memory (only once until the emulator is stopped) g_audio.buffer = g_audio.buffer ? g_audio.buffer : Memory.MainMem.AllocAlign(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, 4096); - g_audio.indexes = g_audio.indexes ? g_audio.indexes : Memory.MainMem.AllocAlign(sizeof(u64) * AUDIO_PORT_COUNT, __alignof(u64)); + g_audio.indexes = g_audio.indexes ? g_audio.indexes : Memory.MainMem.AllocAlign(sizeof32(u64) * AUDIO_PORT_COUNT, alignof32(u64)); // clear memory memset(vm::get_ptr(g_audio.buffer), 0, AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT); - memset(vm::get_ptr(g_audio.indexes), 0, sizeof(u64) * AUDIO_PORT_COUNT); + memset(vm::get_ptr(g_audio.indexes), 0, sizeof32(u64) * AUDIO_PORT_COUNT); + + // check thread status + if (g_audio.thread.joinable()) + { + g_audio.thread.join(); + } // start audio thread - g_audio.audio_thread.start([]() + g_audio.thread.start(WRAP_EXPR("Audio Thread"), []() { + std::unique_lock lock(g_audio.thread.mutex); + const bool do_dump = Ini.AudioDumpToFile.GetValue(); AudioDumper m_dump; if (do_dump && !m_dump.Init(2)) // Init AudioDumper for 2 channels { - throw "AudioDumper::Init() failed"; + throw EXCEPTION("AudioDumper::Init() failed"); } float buf2ch[2 * BUFFER_SIZE]; // intermediate buffer for 2 channels @@ -73,7 +81,7 @@ s32 cellAudioInit() squeue_t out_queue; - thread_t iat("Internal Audio Thread", true /* autojoin */, [&out_queue]() + autojoin_thread_t iat(WRAP_EXPR("Internal Audio Thread"), [&out_queue]() { const bool use_u16 = Ini.AudioConvertToU16.GetValue(); @@ -82,7 +90,7 @@ s32 cellAudioInit() bool opened = false; float* buffer; - while (out_queue.pop(buffer, [](){ return g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED; })) + while (out_queue.pop(buffer, [](){ return g_audio.state.load() != AUDIO_STATE_INITIALIZED; })) { if (use_u16) { @@ -129,71 +137,46 @@ s32 cellAudioInit() Emu.GetAudioManager().GetAudioOut().Quit(); }); - u64 last_pause_time; - std::atomic added_time(0); - NamedThreadBase* audio_thread = GetCurrentNamedThread(); - - PauseCallbackRegisterer pcb(Emu.GetCallbackManager(), [&last_pause_time, &added_time, audio_thread](bool is_paused) - { - if (is_paused) - { - last_pause_time = get_system_time(); - } - else - { - added_time += get_system_time() - last_pause_time; - audio_thread->Notify(); - } - }); - - while (g_audio.state.read_relaxed() == AUDIO_STATE_INITIALIZED && !Emu.IsStopped()) + while (g_audio.state.load() == AUDIO_STATE_INITIALIZED && !Emu.IsStopped()) { if (Emu.IsPaused()) { - GetCurrentNamedThread()->WaitForAnySignal(); + g_audio.thread.cv.wait_for(lock, std::chrono::milliseconds(1)); continue; } - if (added_time) - { - g_audio.start_time += added_time.exchange(0); - } - const u64 stamp0 = get_system_time(); + const u64 time_pos = stamp0 - g_audio.start_time - Emu.GetPauseTime(); + // TODO: send beforemix event (in ~2,6 ms before mixing) // precise time of sleeping: 5,(3) ms (or 256/48000 sec) - const u64 expected_time = g_audio.counter * AUDIO_SAMPLES * MHZ / 48000; - if (expected_time >= stamp0 - g_audio.start_time) + const u64 expected_time = g_audio.counter * AUDIO_SAMPLES * 1000000 / 48000; + if (expected_time >= time_pos) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + g_audio.thread.cv.wait_for(lock, std::chrono::milliseconds(1)); continue; } - // crutch to hide giant lags caused by debugger - const u64 missed_time = stamp0 - g_audio.start_time - expected_time; - if (missed_time > AUDIO_SAMPLES * MHZ / 48000) - { - cellAudio.Notice("%f ms adjusted", (float)missed_time / 1000); - g_audio.start_time += missed_time; - } + //// crutch to hide giant lags caused by debugger + //const u64 missed_time = time_pos - expected_time; + //if (missed_time > AUDIO_SAMPLES * MHZ / 48000) + //{ + // cellAudio.Notice("%f ms adjusted", (float)missed_time / 1000); + // g_audio.start_time += missed_time; + //} g_audio.counter++; const u32 out_pos = g_audio.counter % BUFFER_NUM; - //if (Emu.IsPaused()) - //{ - // continue; - //} - bool first_mix = true; // mixing: for (auto& port : g_audio.ports) { - if (port.state.read_relaxed() != AUDIO_PORT_STATE_STARTED) continue; + if (port.state.load() != AUDIO_PORT_STATE_STARTED) continue; const u32 block_size = port.channel * AUDIO_SAMPLES; const u32 position = port.tag % port.block; // old value @@ -206,7 +189,7 @@ s32 cellAudioInit() auto step_volume = [](AudioPortConfig& port) // part of cellAudioSetPortLevel functionality { - const auto param = port.level_set.read_sync(); + const auto param = port.level_set.load(); if (param.inc != 0.0f) { @@ -328,7 +311,7 @@ s32 cellAudioInit() } else { - throw fmt::format("Unknown channel count (port=%d, channel=%d)", &port - g_audio.ports, port.channel); + throw EXCEPTION("Unknown channel count (port=%lld, channel=%d)", &port - g_audio.ports, port.channel); } memset(buf, 0, block_size * sizeof(float)); @@ -357,7 +340,7 @@ s32 cellAudioInit() memset(out_buffer[out_pos].get(), 0, out_buffer_size * sizeof(float)); } - if (!out_queue.push(out_buffer[out_pos].get(), [](){ return g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED; })) + if (!out_queue.push(out_buffer[out_pos].get(), [](){ return g_audio.state.load() != AUDIO_STATE_INITIALIZED; })) { break; } @@ -365,8 +348,6 @@ s32 cellAudioInit() //const u64 stamp2 = get_system_time(); { - std::lock_guard lock(g_audio.mutex); - // update indices: auto indexes = vm::ptr::make(g_audio.indexes); @@ -375,7 +356,7 @@ s32 cellAudioInit() { AudioPortConfig& port = g_audio.ports[i]; - if (port.state.read_relaxed() != AUDIO_PORT_STATE_STARTED) continue; + if (port.state.load() != AUDIO_PORT_STATE_STARTED) continue; u32 position = port.tag % port.block; // old value port.counter = g_audio.counter; @@ -405,24 +386,24 @@ s32 cellAudioInit() { if (m_dump.WriteData(&buf8ch, sizeof(buf8ch)) != sizeof(buf8ch)) // write file data (8 ch) { - throw "AudioDumper::WriteData() failed (8 ch)"; + throw EXCEPTION("AudioDumper::WriteData() failed (8 ch)"); } } else if (m_dump.GetCh() == 2) { if (m_dump.WriteData(&buf2ch, sizeof(buf2ch)) != sizeof(buf2ch)) // write file data (2 ch) { - throw "AudioDumper::WriteData() failed (2 ch)"; + throw EXCEPTION("AudioDumper::WriteData() failed (2 ch)"); } } else { - throw fmt::format("AudioDumper::GetCh() returned unknown value (%d)", m_dump.GetCh()); + throw EXCEPTION("AudioDumper::GetCh() returned unknown value (%d)", m_dump.GetCh()); } } //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); + //time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3); } }); @@ -438,7 +419,7 @@ s32 cellAudioQuit() return CELL_AUDIO_ERROR_NOT_INIT; } - g_audio.audio_thread.join(); + g_audio.thread.join(); g_audio.state.exchange(AUDIO_STATE_NOT_INITIALIZED); return CELL_OK; } @@ -447,7 +428,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN { cellAudio.Warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -551,7 +532,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) { cellAudio.Warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -565,12 +546,12 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) portConfig->readIndexAddr = port.read_index_addr; - switch (auto state = port.state.read_sync()) + switch (auto state = port.state.load()) { case AUDIO_PORT_STATE_CLOSED: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break; case AUDIO_PORT_STATE_OPENED: portConfig->status = CELL_AUDIO_STATUS_READY; break; case AUDIO_PORT_STATE_STARTED: portConfig->status = CELL_AUDIO_STATUS_RUN; break; - default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (%d)", portNum, state); + default: throw EXCEPTION("Invalid port state (%d: %d)", portNum, state); } portConfig->nChannel = port.channel; @@ -584,7 +565,7 @@ s32 cellAudioPortStart(u32 portNum) { cellAudio.Warning("cellAudioPortStart(portNum=%d)", portNum); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -599,7 +580,7 @@ s32 cellAudioPortStart(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case AUDIO_PORT_STATE_STARTED: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN; case AUDIO_PORT_STATE_OPENED: return CELL_OK; - default: throw fmt::format("cellAudioPortStart(%d): invalid port state (%d)", portNum, state); + default: throw EXCEPTION("Invalid port state (%d: %d)", portNum, state); } } @@ -607,7 +588,7 @@ s32 cellAudioPortClose(u32 portNum) { cellAudio.Warning("cellAudioPortClose(portNum=%d)", portNum); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -622,7 +603,7 @@ s32 cellAudioPortClose(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case AUDIO_PORT_STATE_STARTED: return CELL_OK; case AUDIO_PORT_STATE_OPENED: return CELL_OK; - default: throw fmt::format("cellAudioPortClose(%d): invalid port state (%d)", portNum, state); + default: throw EXCEPTION("Invalid port state (%d: %d)", portNum, state); } } @@ -630,7 +611,7 @@ s32 cellAudioPortStop(u32 portNum) { cellAudio.Warning("cellAudioPortStop(portNum=%d)", portNum); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -645,7 +626,7 @@ s32 cellAudioPortStop(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_RUN; case AUDIO_PORT_STATE_STARTED: return CELL_OK; case AUDIO_PORT_STATE_OPENED: return CELL_AUDIO_ERROR_PORT_NOT_RUN; - default: throw fmt::format("cellAudioPortStop(%d): invalid port state (%d)", portNum, state); + default: throw EXCEPTION("Invalid port state (%d: %d)", portNum, state); } } @@ -653,7 +634,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) { cellAudio.Log("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -665,16 +646,16 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) AudioPortConfig& port = g_audio.ports[portNum]; - if (port.state.read_relaxed() == AUDIO_PORT_STATE_CLOSED) + if (port.state.load() == AUDIO_PORT_STATE_CLOSED) { return CELL_AUDIO_ERROR_PORT_NOT_OPEN; } // TODO: check tag (CELL_AUDIO_ERROR_TAG_NOT_FOUND error) - std::lock_guard lock(g_audio.mutex); + std::lock_guard lock(g_audio.thread.mutex); - *stamp = g_audio.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000; + *stamp = g_audio.start_time + Emu.GetPauseTime() + (port.counter + (tag - port.tag)) * 256000000 / 48000; return CELL_OK; } @@ -683,7 +664,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) { cellAudio.Log("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -695,7 +676,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) AudioPortConfig& port = g_audio.ports[portNum]; - if (port.state.read_relaxed() == AUDIO_PORT_STATE_CLOSED) + if (port.state.load() == AUDIO_PORT_STATE_CLOSED) { return CELL_AUDIO_ERROR_PORT_NOT_OPEN; } @@ -705,7 +686,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) return CELL_AUDIO_ERROR_PARAM; } - std::lock_guard lock(g_audio.mutex); + std::lock_guard lock(g_audio.thread.mutex); u64 tag_base = port.tag; if (tag_base % port.block > blockNo) @@ -726,7 +707,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) { cellAudio.Log("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } @@ -738,7 +719,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) AudioPortConfig& port = g_audio.ports[portNum]; - if (port.state.read_relaxed() == AUDIO_PORT_STATE_CLOSED) + if (port.state.load() == AUDIO_PORT_STATE_CLOSED) { return CELL_AUDIO_ERROR_PORT_NOT_OPEN; } @@ -763,12 +744,10 @@ s32 cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) { const u64 key_value = 0x80004d494f323221ull + k; - auto queue = std::make_shared(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32); - // register key if not used yet - if (Emu.GetEventManager().RegisterKey(queue)) + if (const auto queue = Emu.GetEventManager().MakeEventQueue(key_value, SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32)) { - *id = Emu.GetIdManager().add(std::move(queue)); + *id = queue->id; *key = key_value; return CELL_OK; @@ -796,12 +775,12 @@ s32 cellAudioSetNotifyEventQueue(u64 key) { cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } - std::lock_guard lock(g_audio.mutex); + std::lock_guard lock(g_audio.thread.mutex); for (auto k : g_audio.keys) // check for duplicates { @@ -829,12 +808,12 @@ s32 cellAudioRemoveNotifyEventQueue(u64 key) { cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } - std::lock_guard lock(g_audio.mutex); + std::lock_guard lock(g_audio.thread.mutex); for (auto i = g_audio.keys.begin(); i != g_audio.keys.end(); i++) { @@ -862,12 +841,12 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) { cellAudio.Log("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } - if (portNum >= AUDIO_PORT_COUNT || !src || src.addr() % 4) + if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned()) { return CELL_AUDIO_ERROR_PARAM; } @@ -881,7 +860,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) const AudioPortConfig& port = g_audio.ports[portNum]; - const auto dst = vm::ptr::make(port.addr + (port.tag % port.block) * port.channel * 256 * sizeof(float)); + const auto dst = vm::ptr::make(port.addr + u32(port.tag % port.block) * port.channel * 256 * sizeof32(float)); for (u32 i = 0; i < samples * port.channel; i++) { @@ -895,12 +874,12 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu { cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } - if (portNum >= AUDIO_PORT_COUNT || !src || src.addr() % 4) + if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned()) { return CELL_AUDIO_ERROR_PARAM; } @@ -914,7 +893,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu const AudioPortConfig& port = g_audio.ports[portNum]; - const auto dst = vm::ptr::make(port.addr + (port.tag % port.block) * port.channel * 256 * sizeof(float)); + const auto dst = vm::ptr::make(port.addr + s32(port.tag % port.block) * port.channel * 256 * sizeof32(float)); if (port.channel == 2) { @@ -958,19 +937,19 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) { cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume); - if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + if (g_audio.state.load() != AUDIO_STATE_INITIALIZED) { return CELL_AUDIO_ERROR_NOT_INIT; } - if (portNum >= AUDIO_PORT_COUNT || !src || src.addr() % 4) + if (portNum >= AUDIO_PORT_COUNT || !src || !src.aligned()) { return CELL_AUDIO_ERROR_PARAM; } const AudioPortConfig& port = g_audio.ports[portNum]; - const auto dst = vm::ptr::make(port.addr + (port.tag % port.block) * port.channel * 256 * sizeof(float)); + const auto dst = vm::ptr::make(port.addr + s32(port.tag % port.block) * port.channel * 256 * sizeof32(float)); if (port.channel == 2 || port.channel == 6) { @@ -1024,7 +1003,7 @@ s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream) Module cellAudio("cellAudio", []() { - g_audio.state.write_relaxed(AUDIO_STATE_NOT_INITIALIZED); + g_audio.state.store(AUDIO_STATE_NOT_INITIALIZED); g_audio.buffer = 0; g_audio.indexes = 0; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.h b/rpcs3/Emu/SysCalls/Modules/cellAudio.h index 08356a506a..6b8c3d12ce 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error codes enum { @@ -98,7 +100,7 @@ enum AudioPortState : u32 struct AudioPortConfig { std::mutex mutex; - atomic state; + atomic_t state; u32 channel; u32 block; @@ -116,14 +118,13 @@ struct AudioPortConfig }; float level; - atomic level_set; + atomic_t level_set; }; -struct AudioConfig //custom structure +struct AudioConfig final // custom structure { - std::mutex mutex; - atomic state; - thread_t audio_thread; + atomic_t state; + thread_t thread; AudioPortConfig ports[AUDIO_PORT_COUNT]; u32 buffer; // 1 MB memory for audio ports @@ -132,8 +133,14 @@ struct AudioConfig //custom structure u64 start_time; std::vector keys; - AudioConfig() : audio_thread("Audio Thread") + AudioConfig() = default; + + ~AudioConfig() { + if (thread.joinable()) + { + thread.join(); + } } u32 open_port() diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudioIn.h b/rpcs3/Emu/SysCalls/Modules/cellAudioIn.h new file mode 100644 index 0000000000..300869111c --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellAudioIn.h @@ -0,0 +1,90 @@ +#pragma once + +namespace vm { using namespace ps3; } + +// Error codes +enum +{ + CELL_AUDIO_IN_ERROR_NOT_IMPLEMENTED = 0x8002b260, + CELL_AUDIO_IN_ERROR_ILLEGAL_CONFIGURATION = 0x8002b261, + CELL_AUDIO_IN_ERROR_ILLEGAL_PARAMETER = 0x8002b262, + CELL_AUDIO_IN_ERROR_PARAMETER_OUT_OF_RANGE = 0x8002b263, + CELL_AUDIO_IN_ERROR_DEVICE_NOT_FOUND = 0x8002b264, + CELL_AUDIO_IN_ERROR_UNSUPPORTED_AUDIO_IN = 0x8002b265, + CELL_AUDIO_IN_ERROR_UNSUPPORTED_SOUND_MODE = 0x8002b266, + CELL_AUDIO_IN_ERROR_CONDITION_BUSY = 0x8002b267, +}; + +enum +{ + CELL_AUDIO_IN_SINGLE_DEVICE_MODE = 0, + CELL_AUDIO_IN_MULTI_DEVICE_MODE = 1, + CELL_AUDIO_IN_MULTI_DEVICE_MODE_2 = 2, +}; + +enum CellAudioInPortType +{ + CELL_AUDIO_IN_PORT_USB = 3, + CELL_AUDIO_IN_PORT_BLUETOOTH = 4, +}; + +enum CellAudioInDeviceState +{ + CELL_AUDIO_IN_DEVICE_STATE_UNAVAILABLE = 0, + CELL_AUDIO_IN_DEVICE_STATE_AVAILABLE = 1, +}; + +enum CellAudioInCodingType +{ + CELL_AUDIO_IN_CODING_TYPE_LPCM = 0, +}; + +enum CellAudioInChnum +{ + CELL_AUDIO_IN_CHNUM_NONE = 0, + CELL_AUDIO_IN_CHNUM_1 = 1, + CELL_AUDIO_IN_CHNUM_2 = 2, +}; + +enum CellAudioInFs +{ + CELL_AUDIO_IN_FS_UNDEFINED = 0x00, + CELL_AUDIO_IN_FS_8KHZ = 0x01, + CELL_AUDIO_IN_FS_12KHZ = 0x02, + CELL_AUDIO_IN_FS_16KHZ = 0x04, + CELL_AUDIO_IN_FS_24KHZ = 0x08, + CELL_AUDIO_IN_FS_32KHZ = 0x10, + CELL_AUDIO_IN_FS_48KHZ = 0x20, +}; + +struct CellAudioInSoundMode +{ + u8 type; + u8 channel; + be_t fs; + u8 reserved[4]; +}; + +struct CellAudioInDeviceInfo +{ + u8 portType; + u8 availableModeCount; + u8 state; + u8 deviceNumber; + u8 reserved[12]; + be_t deviceId; + be_t type; + char name[64]; + CellAudioInSoundMode availableModes[16]; +}; + +struct CellAudioInRegistrationOption +{ + //(Omitted) +}; + +struct CellAudioInDeviceConfiguration +{ + u8 volume; + u8 reserved[31]; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudioOut.h b/rpcs3/Emu/SysCalls/Modules/cellAudioOut.h new file mode 100644 index 0000000000..92ab800e3d --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellAudioOut.h @@ -0,0 +1,179 @@ +#pragma once + +namespace vm { using namespace ps3; } + +// Error codes +enum +{ + CELL_AUDIO_OUT_ERROR_NOT_IMPLEMENTED = 0x8002b240, + CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION = 0x8002b241, + CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER = 0x8002b242, + CELL_AUDIO_OUT_ERROR_PARAMETER_OUT_OF_RANGE = 0x8002b243, + CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND = 0x8002b244, + CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT = 0x8002b245, + CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE = 0x8002b246, + CELL_AUDIO_OUT_ERROR_CONDITION_BUSY = 0x8002b247, +}; + + +enum CellAudioOut +{ + CELL_AUDIO_OUT_PRIMARY = 0, + CELL_AUDIO_OUT_SECONDARY = 1, +}; + +enum CellAudioOutDownMixer +{ + CELL_AUDIO_OUT_DOWNMIXER_NONE = 0, + CELL_AUDIO_OUT_DOWNMIXER_TYPE_A = 1, + CELL_AUDIO_OUT_DOWNMIXER_TYPE_B = 2, +}; + +enum +{ + CELL_AUDIO_OUT_SINGLE_DEVICE_MODE = 0, + CELL_AUDIO_OUT_MULTI_DEVICE_MODE = 1, + CELL_AUDIO_OUT_MULTI_DEVICE_MODE_2 = 2, +}; + +enum CellAudioOutPortType +{ + CELL_AUDIO_OUT_PORT_HDMI = 0, + CELL_AUDIO_OUT_PORT_SPDIF = 1, + CELL_AUDIO_OUT_PORT_ANALOG = 2, + CELL_AUDIO_OUT_PORT_USB = 3, + CELL_AUDIO_OUT_PORT_BLUETOOTH = 4, + CELL_AUDIO_OUT_PORT_NETWORK = 5, +}; + +enum CellAudioOutDeviceState +{ + CELL_AUDIO_OUT_DEVICE_STATE_UNAVAILABLE = 0, + CELL_AUDIO_OUT_DEVICE_STATE_AVAILABLE = 1, +}; + +enum CellAudioOutOutputState +{ + CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED = 0, + CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED = 1, + CELL_AUDIO_OUT_OUTPUT_STATE_PREPARING = 2, +}; + +enum CellAudioOutCodingType +{ + CELL_AUDIO_OUT_CODING_TYPE_LPCM = 0, + CELL_AUDIO_OUT_CODING_TYPE_AC3 = 1, + CELL_AUDIO_OUT_CODING_TYPE_MPEG1 = 2, + CELL_AUDIO_OUT_CODING_TYPE_MP3 = 3, + CELL_AUDIO_OUT_CODING_TYPE_MPEG2 = 4, + CELL_AUDIO_OUT_CODING_TYPE_AAC = 5, + CELL_AUDIO_OUT_CODING_TYPE_DTS = 6, + CELL_AUDIO_OUT_CODING_TYPE_ATRAC = 7, + CELL_AUDIO_OUT_CODING_TYPE_BITSTREAM = 0xff, +}; + +enum CellAudioOutChnum +{ + CELL_AUDIO_OUT_CHNUM_2 = 2, + CELL_AUDIO_OUT_CHNUM_4 = 4, + CELL_AUDIO_OUT_CHNUM_6 = 6, + CELL_AUDIO_OUT_CHNUM_8 = 8, +}; + +enum CellAudioOutFs +{ + CELL_AUDIO_OUT_FS_32KHZ = 0x01, + CELL_AUDIO_OUT_FS_44KHZ = 0x02, + CELL_AUDIO_OUT_FS_48KHZ = 0x04, + CELL_AUDIO_OUT_FS_88KHZ = 0x08, + CELL_AUDIO_OUT_FS_96KHZ = 0x10, + CELL_AUDIO_OUT_FS_176KHZ = 0x20, + CELL_AUDIO_OUT_FS_192KHZ = 0x40, +}; + +enum +{ + CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH = 0x00000001, + CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr = 0x00010000, + CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy = 0x40000000, +}; + +enum +{ + CELL_AUDIO_OUT_COPY_CONTROL_COPY_FREE = 0, + CELL_AUDIO_OUT_COPY_CONTROL_COPY_ONCE = 1, + CELL_AUDIO_OUT_COPY_CONTROL_COPY_NEVER = 2, +}; + + +struct CellAudioOutConfiguration +{ + u8 channel; + u8 encoder; + u8 reserved[10]; + be_t downMixer; +}; + +struct CellAudioOutSoundMode +{ + u8 type; + u8 channel; + u8 fs; + u8 reserved; + be_t layout; +}; + +struct CellAudioOutDeviceInfo +{ + u8 portType; + u8 availableModeCount; + u8 state; + u8 reserved[3]; + be_t latency; + CellAudioOutSoundMode availableModes[16]; +}; + +struct CellAudioOutState +{ + u8 state; + u8 encoder; + u8 reserved[6]; + be_t downMixer; + CellAudioOutSoundMode soundMode; +}; + +struct CellAudioOutSoundMode2 +{ + u8 type; + u8 channel; + be_t fs; + u8 reserved[4]; +}; + +struct CellAudioOutDeviceInfo2 +{ + u8 portType; + u8 availableModeCount; + u8 state; + u8 deviceNumber; + u8 reserved[12]; + be_t deviceId; + be_t type; + char name[64]; + CellAudioOutSoundMode2 availableModes2[16]; +}; + +struct CellAudioOutOption +{ + //(Omitted) +}; + +struct CellAudioOutRegistrationOption +{ + //(Omitted) +}; + +struct CellAudioOutDeviceConfiguration +{ + //(Omitted) +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp b/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp index 4e51060ee0..5499ac05b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp @@ -4,6 +4,8 @@ #include "Emu/SysCalls/Modules.h" #include "Emu/RSX/sysutil_video.h" +namespace vm { using namespace ps3; } + extern Module cellAvconfExt; s32 cellVideoOutConvertCursorColor() diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp index a6f8ee0372..2a62b2a9ea 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp @@ -6,136 +6,107 @@ #include "cellCamera.h" extern Module cellCamera; -const char* attributes[] = {"GAIN", "REDBLUEGAIN", "SATURATION", "EXPOSURE", "BRIGHTNESS", "AEC", "AGC", "AWB", "ABC", "LED", "AUDIOGAIN", "QS", "NONZEROCOEFFS", "YUVFLAG", - "JPEGFLAG", "BACKLIGHTCOMP", "MIRRORFLAG", "MEASUREDQS", "422FLAG", "USBLOAD", "GAMMA", "GREENGAIN", "AGCLIMIT", "DENOISE", "FRAMERATEADJUST", - "PIXELOUTLIERFILTER", "AGCLOW", "AGCHIGH", "DEVICELOCATION", "FORMATCAP", "FORMATINDEX", "NUMFRAME", "FRAMEINDEX", "FRAMESIZE", "INTERVALTYPE", - "INTERVALINDEX", "INTERVALVALUE", "COLORMATCHING", "PLFREQ", "DEVICEID", "DEVICECAP", "DEVICESPEED", "UVCREQCODE", "UVCREQDATA", "DEVICEID2", - "READMODE", "GAMEPID", "PBUFFER", "READFINISH", "ATTRIBUTE_UNKNOWN"}; -struct cellCameraInternal -{ - bool m_bInitialized; - CellCamera m_camera; +std::unique_ptr g_camera; - cellCameraInternal() - : m_bInitialized(false) - { - } -}; - -cellCameraInternal cellCameraInstance; - -int cellCameraInit() +s32 cellCameraInit() { cellCamera.Warning("cellCameraInit()"); - if (cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_ALREADY_INIT; - if (Ini.Camera.GetValue() == 0) + { return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND; + } + + if (g_camera->init.exchange(true)) + { + return CELL_CAMERA_ERROR_ALREADY_INIT; + } if (Ini.CameraType.GetValue() == 1) { - CellCamera camera; - camera.attributes.SATURATION = 164; - camera.attributes.BRIGHTNESS = 96; - camera.attributes.AEC = 1; - camera.attributes.AGC = 1; - camera.attributes.AWB = 1; - camera.attributes.ABC = 0; - camera.attributes.LED = 1; - camera.attributes.QS = 0; - camera.attributes.NONZEROCOEFFS[0] = 32; - camera.attributes.NONZEROCOEFFS[1] = 32; - camera.attributes.YUVFLAG = 0; - camera.attributes.BACKLIGHTCOMP = 0; - camera.attributes.MIRRORFLAG = 1; - camera.attributes._422FLAG = 1; - camera.attributes.USBLOAD = 4; - cellCameraInstance.m_camera = camera; + g_camera->attr[CELL_CAMERA_SATURATION] = { 164 }; + g_camera->attr[CELL_CAMERA_BRIGHTNESS] = { 96 }; + g_camera->attr[CELL_CAMERA_AEC] = { 1 }; + g_camera->attr[CELL_CAMERA_AGC] = { 1 }; + g_camera->attr[CELL_CAMERA_AWB] = { 1 }; + g_camera->attr[CELL_CAMERA_ABC] = { 0 }; + g_camera->attr[CELL_CAMERA_LED] = { 1 }; + g_camera->attr[CELL_CAMERA_QS] = { 0 }; + g_camera->attr[CELL_CAMERA_NONZEROCOEFFS] = { 32, 32 }; + g_camera->attr[CELL_CAMERA_YUVFLAG] = { 0 }; + g_camera->attr[CELL_CAMERA_BACKLIGHTCOMP] = { 0 }; + g_camera->attr[CELL_CAMERA_MIRRORFLAG] = { 1 }; + g_camera->attr[CELL_CAMERA_422FLAG] = { 1 }; + g_camera->attr[CELL_CAMERA_USBLOAD] = { 4 }; } else if (Ini.CameraType.GetValue() == 2) { - CellCamera camera; - camera.attributes.SATURATION = 64; - camera.attributes.BRIGHTNESS = 8; - camera.attributes.AEC = 1; - camera.attributes.AGC = 1; - camera.attributes.AWB = 1; - camera.attributes.LED = 1; - camera.attributes.BACKLIGHTCOMP = 0; - camera.attributes.MIRRORFLAG = 1; - camera.attributes.GAMMA = 1; - camera.attributes.AGCLIMIT = 4; - camera.attributes.DENOISE = 0; - camera.attributes.FRAMERATEADJUST = 0; - camera.attributes.PIXELOUTLIERFILTER = 1; - camera.attributes.AGCLOW = 48; - camera.attributes.AGCHIGH = 64; - cellCameraInstance.m_camera = camera; + g_camera->attr[CELL_CAMERA_SATURATION] = { 64 }; + g_camera->attr[CELL_CAMERA_BRIGHTNESS] = { 8 }; + g_camera->attr[CELL_CAMERA_AEC] = { 1 }; + g_camera->attr[CELL_CAMERA_AGC] = { 1 }; + g_camera->attr[CELL_CAMERA_AWB] = { 1 }; + g_camera->attr[CELL_CAMERA_LED] = { 1 }; + g_camera->attr[CELL_CAMERA_BACKLIGHTCOMP] = { 0 }; + g_camera->attr[CELL_CAMERA_MIRRORFLAG] = { 1 }; + g_camera->attr[CELL_CAMERA_GAMMA] = { 1 }; + g_camera->attr[CELL_CAMERA_AGCLIMIT] = { 4 }; + g_camera->attr[CELL_CAMERA_DENOISE] = { 0 }; + g_camera->attr[CELL_CAMERA_FRAMERATEADJUST] = { 0 }; + g_camera->attr[CELL_CAMERA_PIXELOUTLIERFILTER] = { 1 }; + g_camera->attr[CELL_CAMERA_AGCLOW] = { 48 }; + g_camera->attr[CELL_CAMERA_AGCHIGH] = { 64 }; } // TODO: Some other default attributes? Need to check the actual behaviour on a real PS3. - cellCameraInstance.m_bInitialized = true; - return CELL_OK; } -int cellCameraEnd() +s32 cellCameraEnd() { cellCamera.Warning("cellCameraEnd()"); - if (!cellCameraInstance.m_bInitialized) + if (!g_camera->init.exchange(false)) + { return CELL_CAMERA_ERROR_NOT_INIT; - - cellCameraInstance.m_bInitialized = false; + } return CELL_OK; } -int cellCameraOpen() +s32 cellCameraOpen() { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraOpenEx() +s32 cellCameraOpenEx(s32 dev_num, vm::ptr info) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraClose() +s32 cellCameraClose(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraGetDeviceGUID() +s32 cellCameraGetDeviceGUID(s32 dev_num, vm::ptr guid) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraGetType(s32 dev_num, vm::ptr type) +s32 cellCameraGetType(s32 dev_num, vm::ptr type) { - cellCamera.Warning("cellCameraGetType(dev_num=%d, type_addr=0x%x)", dev_num, type.addr()); + cellCamera.Warning("cellCameraGetType(dev_num=%d, type=*0x%x)", dev_num, type); - if (!cellCameraInstance.m_bInitialized) + if (!g_camera->init.load()) + { return CELL_CAMERA_ERROR_NOT_INIT; + } switch (Ini.CameraType.GetValue()) { @@ -148,423 +119,178 @@ int cellCameraGetType(s32 dev_num, vm::ptr type) return CELL_OK; } -int cellCameraIsAvailable() +s32 cellCameraIsAvailable(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraIsAttached() +s32 cellCameraIsAttached(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraIsOpen() +s32 cellCameraIsOpen(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraIsStarted() +s32 cellCameraIsStarted(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraGetAttribute(s32 dev_num, CellCameraAttribute attrib, vm::ptr arg1, vm::ptr arg2) +s32 cellCameraGetAttribute(s32 dev_num, s32 attrib, vm::ptr arg1, vm::ptr arg2) { - cellCamera.Warning("cellCameraGetAttribute(dev_num=%d, attrib=%s(%d), arg1=0x%x, arg2=0x%x)", dev_num, attributes[attrib], arg1.addr(), arg2.addr()); + cellCamera.Warning("cellCameraGetAttribute(dev_num=%d, attrib=%d, arg1=*0x%x, arg2=*0x%x)", dev_num, attrib, arg1, arg2); - if (!cellCameraInstance.m_bInitialized) + const auto attr_name = camera_t::get_attr_name(attrib); + + if (!g_camera->init.load()) + { return CELL_CAMERA_ERROR_NOT_INIT; - - switch (attrib) - { - case 0: - *arg1 = cellCameraInstance.m_camera.attributes.GAIN; break; - case 1: - *arg1 = cellCameraInstance.m_camera.attributes.REDBLUEGAIN; break; - case 2: - *arg1 = cellCameraInstance.m_camera.attributes.SATURATION; break; - case 3: - *arg1 = cellCameraInstance.m_camera.attributes.EXPOSURE; break; - case 4: - *arg1 = cellCameraInstance.m_camera.attributes.BRIGHTNESS; break; - case 5: - *arg1 = cellCameraInstance.m_camera.attributes.AEC; break; - case 6: - *arg1 = cellCameraInstance.m_camera.attributes.AGC; break; - case 7: - *arg1 = cellCameraInstance.m_camera.attributes.AWB; break; - case 8: - *arg1 = cellCameraInstance.m_camera.attributes.ABC; break; - case 9: - *arg1 = cellCameraInstance.m_camera.attributes.LED; break; - case 10: - *arg1 = cellCameraInstance.m_camera.attributes.AUDIOGAIN; break; - case 11: - *arg1 = cellCameraInstance.m_camera.attributes.QS; break; - case 12: - { - *arg1 = cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[0]; - *arg2 = cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[1]; - break; - } - case 13: - *arg1 = cellCameraInstance.m_camera.attributes.YUVFLAG; break; - case 14: - *arg1 = cellCameraInstance.m_camera.attributes.JPEGFLAG; break; - case 15: - *arg1 = cellCameraInstance.m_camera.attributes.BACKLIGHTCOMP; break; - case 16: - *arg1 = cellCameraInstance.m_camera.attributes.MIRRORFLAG; break; - case 17: - *arg1 = cellCameraInstance.m_camera.attributes.MEASUREDQS; break; - case 18: - *arg1 = cellCameraInstance.m_camera.attributes._422FLAG; break; - case 19: - *arg1 = cellCameraInstance.m_camera.attributes.USBLOAD; break; - case 20: - *arg1 = cellCameraInstance.m_camera.attributes.GAMMA; break; - case 21: - *arg1 = cellCameraInstance.m_camera.attributes.GREENGAIN; break; - case 22: - *arg1 = cellCameraInstance.m_camera.attributes.AGCLIMIT; break; - case 23: - *arg1 = cellCameraInstance.m_camera.attributes.DENOISE; break; - case 24: - *arg1 = cellCameraInstance.m_camera.attributes.FRAMERATEADJUST; break; - case 25: - *arg1 = cellCameraInstance.m_camera.attributes.PIXELOUTLIERFILTER; break; - case 26: - *arg1 = cellCameraInstance.m_camera.attributes.AGCLOW; break; - case 27: - *arg1 = cellCameraInstance.m_camera.attributes.AGCHIGH; break; - case 28: - *arg1 = cellCameraInstance.m_camera.attributes.DEVICELOCATION; break; - case 29: - *arg1 = cellCameraInstance.m_camera.attributes.FORMATCAP; break; - case 30: - *arg1 = cellCameraInstance.m_camera.attributes.FORMATINDEX; break; - case 31: - *arg1 = cellCameraInstance.m_camera.attributes.NUMFRAME; break; - case 32: - *arg1 = cellCameraInstance.m_camera.attributes.FRAMEINDEX; break; - case 33: - *arg1 = cellCameraInstance.m_camera.attributes.FRAMESIZE; break; - case 34: - *arg1 = cellCameraInstance.m_camera.attributes.INTERVALTYPE; break; - case 35: - *arg1 = cellCameraInstance.m_camera.attributes.INTERVALINDEX; break; - case 36: - *arg1 = cellCameraInstance.m_camera.attributes.INTERVALVALUE; break; - case 37: - *arg1 = cellCameraInstance.m_camera.attributes.COLORMATCHING; break; - case 38: - *arg1 = cellCameraInstance.m_camera.attributes.PLFREQ; break; - case 39: - *arg1 = cellCameraInstance.m_camera.attributes.DEVICEID; break; - case 40: - *arg1 = cellCameraInstance.m_camera.attributes.DEVICECAP; break; - case 41: - *arg1 = cellCameraInstance.m_camera.attributes.DEVICESPEED; break; - case 42: - *arg1 = cellCameraInstance.m_camera.attributes.UVCREQCODE; break; - case 43: - *arg1 = cellCameraInstance.m_camera.attributes.UVCREQDATA; break; - case 44: - *arg1 = cellCameraInstance.m_camera.attributes.DEVICEID2; break; - case 45: - *arg1 = cellCameraInstance.m_camera.attributes.READMODE; break; - case 46: - *arg1 = cellCameraInstance.m_camera.attributes.GAMEPID; break; - case 47: - *arg1 = cellCameraInstance.m_camera.attributes.PBUFFER; break; - case 48: - *arg1 = cellCameraInstance.m_camera.attributes.READFINISH; break; - case 49: - *arg1 = cellCameraInstance.m_camera.attributes.ATTRIBUTE_UNKNOWN; break; - default: - cellCamera.Error("Unexpected cellCameraGetAttribute attribute: %d", attrib); break; } - return CELL_OK; -} - -int cellCameraSetAttribute(s32 dev_num, CellCameraAttribute attrib, u32 arg1, u32 arg2) -{ - cellCamera.Warning("cellCameraSetAttribute(dev_num=%d, attrib=%s(%d), arg1=%d, arg2=%d)", dev_num, attributes[attrib], attrib, arg1, arg2); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - - switch (attrib) + if (!attr_name) // invalid attributes don't have a name { - case 0: - cellCameraInstance.m_camera.attributes.GAIN = arg1; break; - case 1: - cellCameraInstance.m_camera.attributes.REDBLUEGAIN = arg1; break; - case 2: - cellCameraInstance.m_camera.attributes.SATURATION = arg1; break; - case 3: - cellCameraInstance.m_camera.attributes.EXPOSURE = arg1; break; - case 4: - cellCameraInstance.m_camera.attributes.BRIGHTNESS = arg1; break; - case 5: - cellCameraInstance.m_camera.attributes.AEC = arg1; break; - case 6: - cellCameraInstance.m_camera.attributes.AGC = arg1; break; - case 7: - cellCameraInstance.m_camera.attributes.AWB = arg1; break; - case 8: - cellCameraInstance.m_camera.attributes.ABC = arg1; break; - case 9: - cellCameraInstance.m_camera.attributes.LED = arg1; break; - case 10: - cellCameraInstance.m_camera.attributes.AUDIOGAIN = arg1; break; - case 11: - cellCameraInstance.m_camera.attributes.QS = arg1; break; - case 12: - { - cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[0] = arg1; - cellCameraInstance.m_camera.attributes.NONZEROCOEFFS[1] = arg2; - break; - } - case 13: - cellCameraInstance.m_camera.attributes.YUVFLAG = arg1; break; - case 14: - cellCameraInstance.m_camera.attributes.JPEGFLAG = arg1; break; - case 15: - cellCameraInstance.m_camera.attributes.BACKLIGHTCOMP = arg1; break; - case 16: - cellCameraInstance.m_camera.attributes.MIRRORFLAG = arg1; break; - case 17: - return CELL_CAMERA_ERROR_PARAM; break; - case 18: - cellCameraInstance.m_camera.attributes._422FLAG = arg1; break; - case 19: - cellCameraInstance.m_camera.attributes.USBLOAD = arg1; break; - case 20: - cellCameraInstance.m_camera.attributes.GAMMA = arg1; break; - case 21: - cellCameraInstance.m_camera.attributes.GREENGAIN = arg1; break; - case 22: - cellCameraInstance.m_camera.attributes.AGCLIMIT = arg1; break; - case 23: - cellCameraInstance.m_camera.attributes.DENOISE = arg1; break; - case 24: - cellCameraInstance.m_camera.attributes.FRAMERATEADJUST = arg1; break; - case 25: - cellCameraInstance.m_camera.attributes.PIXELOUTLIERFILTER = arg1; break; - case 26: - cellCameraInstance.m_camera.attributes.AGCLOW = arg1; break; - case 27: - cellCameraInstance.m_camera.attributes.AGCHIGH = arg1; break; - case 28: - cellCameraInstance.m_camera.attributes.DEVICELOCATION = arg1; break; - case 29: - cellCamera.Error("Tried to write to read-only (?) value: FORMATCAP"); break; - case 30: - cellCameraInstance.m_camera.attributes.FORMATINDEX = arg1; break; - case 31: - cellCameraInstance.m_camera.attributes.NUMFRAME = arg1; break; - case 32: - cellCameraInstance.m_camera.attributes.FRAMEINDEX = arg1; break; - case 33: - cellCameraInstance.m_camera.attributes.FRAMESIZE = arg1; break; - case 34: - cellCameraInstance.m_camera.attributes.INTERVALTYPE = arg1; break; - case 35: - cellCameraInstance.m_camera.attributes.INTERVALINDEX = arg1; break; - case 36: - cellCameraInstance.m_camera.attributes.INTERVALVALUE = arg1; break; - case 37: - cellCameraInstance.m_camera.attributes.COLORMATCHING = arg1; break; - case 38: - cellCameraInstance.m_camera.attributes.PLFREQ = arg1; break; - case 39: - return CELL_CAMERA_ERROR_PARAM; break; - case 40: - cellCameraInstance.m_camera.attributes.DEVICECAP = arg1; break; - case 41: - cellCameraInstance.m_camera.attributes.DEVICESPEED = arg1; break; - case 42: - cellCameraInstance.m_camera.attributes.UVCREQCODE = arg1; break; - case 43: - cellCameraInstance.m_camera.attributes.UVCREQDATA = arg1; break; - case 44: - return CELL_CAMERA_ERROR_PARAM; break; - case 45: - cellCamera.Error("Tried to write to read-only (?) value: READMODE"); break; - case 46: - cellCameraInstance.m_camera.attributes.GAMEPID = arg1; break; - case 47: - cellCameraInstance.m_camera.attributes.PBUFFER = arg1; break; - case 48: - cellCameraInstance.m_camera.attributes.READFINISH = arg1; break; - case 49: - cellCamera.Error("Tried to write to read-only (?) value: ATTRIBUTE_UNKNOWN"); break; - default: - cellCamera.Error("Unexpected cellCameraGetAttribute attribute: %d", attrib); break; + return CELL_CAMERA_ERROR_PARAM; } + *arg1 = g_camera->attr[attrib].v1; + *arg2 = g_camera->attr[attrib].v2; + return CELL_OK; } -int cellCameraGetBufferSize() +s32 cellCameraSetAttribute(s32 dev_num, s32 attrib, u32 arg1, u32 arg2) { - UNIMPLEMENTED_FUNC(cellCamera); + cellCamera.Warning("cellCameraSetAttribute(dev_num=%d, attrib=%d, arg1=%d, arg2=%d)", dev_num, attrib, arg1, arg2); - if (!cellCameraInstance.m_bInitialized) + const auto attr_name = camera_t::get_attr_name(attrib); + + if (!g_camera->init.load()) + { return CELL_CAMERA_ERROR_NOT_INIT; + } + + if (!attr_name) // invalid attributes don't have a name + { + return CELL_CAMERA_ERROR_PARAM; + } + + g_camera->attr[attrib] = { arg1, arg2 }; return CELL_OK; } -int cellCameraGetBufferInfo() +s32 cellCameraGetBufferSize(s32 dev_num, vm::ptr info) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraGetBufferInfoEx() -{ - UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - - return CELL_OK; -} - -int cellCameraPrepExtensionUnit() +s32 cellCameraGetBufferInfo() { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraCtrlExtensionUnit() +s32 cellCameraGetBufferInfoEx(s32 dev_num, vm::ptr info) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraGetExtensionUnit() +s32 cellCameraPrepExtensionUnit(s32 dev_num, vm::ptr guidExtensionCode) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraSetExtensionUnit() +s32 cellCameraCtrlExtensionUnit(s32 dev_num, u8 request, u16 value, u16 length, vm::ptr data) { UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } -int cellCameraReset() +s32 cellCameraGetExtensionUnit(s32 dev_num, u16 value, u16 length, vm::ptr data) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraStart() +s32 cellCameraSetExtensionUnit(s32 dev_num, u16 value, u16 length, vm::ptr data) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraRead() +s32 cellCameraReset(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraReadEx() +s32 cellCameraStart(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraReadComplete() +s32 cellCameraRead(s32 dev_num, vm::ptr frame_num, vm::ptr bytes_read) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraStop() +s32 cellCameraReadEx(s32 dev_num, vm::ptr read) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraSetNotifyEventQueue() +s32 cellCameraReadComplete(s32 dev_num, u32 bufnum, u32 arg2) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraRemoveNotifyEventQueue() +s32 cellCameraStop(s32 dev_num) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraSetNotifyEventQueue2() +s32 cellCameraSetNotifyEventQueue(u64 key) { UNIMPLEMENTED_FUNC(cellCamera); - - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; - return CELL_OK; } -int cellCameraRemoveNotifyEventQueue2() +s32 cellCameraRemoveNotifyEventQueue(u64 key) { UNIMPLEMENTED_FUNC(cellCamera); + return CELL_OK; +} - if (!cellCameraInstance.m_bInitialized) - return CELL_CAMERA_ERROR_NOT_INIT; +s32 cellCameraSetNotifyEventQueue2(u64 key, u64 source, u64 flag) +{ + UNIMPLEMENTED_FUNC(cellCamera); + return CELL_OK; +} +s32 cellCameraRemoveNotifyEventQueue2(u64 key) +{ + UNIMPLEMENTED_FUNC(cellCamera); return CELL_OK; } Module cellCamera("cellCamera", []() { - cellCameraInstance.m_bInitialized = false; + g_camera = std::make_unique(); REG_FUNC(cellCamera, cellCameraInit); REG_FUNC(cellCamera, cellCameraEnd); diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.h b/rpcs3/Emu/SysCalls/Modules/cellCamera.h index 12ae95270a..4a82a0b5b8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.h +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.h @@ -1,21 +1,23 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { - CELL_CAMERA_ERROR_ALREADY_INIT = 0x80140801, - CELL_CAMERA_ERROR_NOT_INIT = 0x80140803, - CELL_CAMERA_ERROR_PARAM = 0x80140804, - CELL_CAMERA_ERROR_ALREADY_OPEN = 0x80140805, - CELL_CAMERA_ERROR_NOT_OPEN = 0x80140806, - CELL_CAMERA_ERROR_DEVICE_NOT_FOUND = 0x80140807, + CELL_CAMERA_ERROR_ALREADY_INIT = 0x80140801, + CELL_CAMERA_ERROR_NOT_INIT = 0x80140803, + CELL_CAMERA_ERROR_PARAM = 0x80140804, + CELL_CAMERA_ERROR_ALREADY_OPEN = 0x80140805, + CELL_CAMERA_ERROR_NOT_OPEN = 0x80140806, + CELL_CAMERA_ERROR_DEVICE_NOT_FOUND = 0x80140807, CELL_CAMERA_ERROR_DEVICE_DEACTIVATED = 0x80140808, - CELL_CAMERA_ERROR_NOT_STARTED = 0x80140809, - CELL_CAMERA_ERROR_FORMAT_UNKNOWN = 0x8014080a, + CELL_CAMERA_ERROR_NOT_STARTED = 0x80140809, + CELL_CAMERA_ERROR_FORMAT_UNKNOWN = 0x8014080a, CELL_CAMERA_ERROR_RESOLUTION_UNKNOWN = 0x8014080b, - CELL_CAMERA_ERROR_BAD_FRAMERATE = 0x8014080c, - CELL_CAMERA_ERROR_TIMEOUT = 0x8014080d, - CELL_CAMERA_ERROR_FATAL = 0x8014080f, + CELL_CAMERA_ERROR_BAD_FRAMERATE = 0x8014080c, + CELL_CAMERA_ERROR_TIMEOUT = 0x8014080d, + CELL_CAMERA_ERROR_FATAL = 0x8014080f, }; // Event types @@ -192,7 +194,7 @@ enum }; // Camera types -enum CellCameraType +enum CellCameraType : s32 { CELL_CAMERA_TYPE_UNKNOWN, CELL_CAMERA_EYETOY, @@ -201,7 +203,7 @@ enum CellCameraType }; // Image format -enum CellCameraFormat +enum CellCameraFormat : s32 { CELL_CAMERA_FORMAT_UNKNOWN, CELL_CAMERA_JPG, @@ -215,7 +217,7 @@ enum CellCameraFormat }; // Image resolution -enum CellCameraResolution +enum CellCameraResolution : s32 { CELL_CAMERA_RESOLUTION_UNKNOWN, CELL_CAMERA_VGA, @@ -225,7 +227,7 @@ enum CellCameraResolution }; // Camera attributes -enum CellCameraAttribute +enum CellCameraAttribute : s32 { CELL_CAMERA_GAIN, CELL_CAMERA_REDBLUEGAIN, @@ -284,84 +286,21 @@ enum CellCameraAttribute struct CellCameraInfoEx { - CellCameraFormat format; - CellCameraResolution resolution; + be_t format; // CellCameraFormat + be_t resolution; // CellCameraResolution be_t framerate; - be_t buffer; + + vm::bptr buffer; be_t bytesize; be_t width; be_t height; be_t dev_num; be_t guid; + be_t info_ver; be_t container; be_t read_mode; - be_t pbuf[2]; -}; - -// Custom struct for keeping track of camera attributes -struct CellCameraAttributes -{ - u32 GAIN; - u32 REDBLUEGAIN; - u32 SATURATION; - u32 EXPOSURE; - u32 BRIGHTNESS; - u32 AEC; - u32 AGC; - u32 AWB; - u32 ABC; - u32 LED; - u32 AUDIOGAIN; - u32 QS; - u32 NONZEROCOEFFS[2]; - u32 YUVFLAG; - u32 JPEGFLAG; - u32 BACKLIGHTCOMP; - u32 MIRRORFLAG; - u32 MEASUREDQS; - u32 _422FLAG; - u32 USBLOAD; - u32 GAMMA; - u32 GREENGAIN; - u32 AGCLIMIT; - u32 DENOISE; - u32 FRAMERATEADJUST; - u32 PIXELOUTLIERFILTER; - u32 AGCLOW; - u32 AGCHIGH; - u32 DEVICELOCATION; - - u32 FORMATCAP = 100; - u32 FORMATINDEX; - u32 NUMFRAME; - u32 FRAMEINDEX; - u32 FRAMESIZE; - u32 INTERVALTYPE; - u32 INTERVALINDEX; - u32 INTERVALVALUE; - u32 COLORMATCHING; - u32 PLFREQ; - u32 DEVICEID; - u32 DEVICECAP; - u32 DEVICESPEED; - u32 UVCREQCODE; - u32 UVCREQDATA; - u32 DEVICEID2; - - u32 READMODE = 300; - u32 GAMEPID; - u32 PBUFFER; - u32 READFINISH; - - u32 ATTRIBUTE_UNKNOWN = 500; -}; - -// Custom struct to keep track of cameras -struct CellCamera -{ - CellCameraAttributes attributes; - CellCameraInfoEx info; + vm::bptr pbuf[2]; }; struct CellCameraReadEx @@ -369,6 +308,77 @@ struct CellCameraReadEx be_t version; be_t frame; be_t bytesread; - //system_time_t timestamp; // TODO: Replace this with something - be_t pbuf; -}; \ No newline at end of file + be_t timestamp; + vm::bptr pbuf; +}; + +// Custom struct to keep track of cameras +struct camera_t +{ + struct attr_t + { + u32 v1, v2; + }; + + std::atomic init{ false }; + + attr_t attr[500]{}; + + static const char* get_attr_name(s32 value) + { + switch (value) + { + case CELL_CAMERA_GAIN: return "CELL_CAMERA_GAIN"; + case CELL_CAMERA_REDBLUEGAIN: return "CELL_CAMERA_REDBLUEGAIN"; + case CELL_CAMERA_SATURATION: return "CELL_CAMERA_SATURATION"; + case CELL_CAMERA_EXPOSURE: return "CELL_CAMERA_EXPOSURE"; + case CELL_CAMERA_BRIGHTNESS: return "CELL_CAMERA_BRIGHTNESS"; + case CELL_CAMERA_AEC: return "CELL_CAMERA_AEC"; + case CELL_CAMERA_AGC: return "CELL_CAMERA_AGC"; + case CELL_CAMERA_AWB: return "CELL_CAMERA_AWB"; + case CELL_CAMERA_ABC: return "CELL_CAMERA_ABC"; + case CELL_CAMERA_LED: return "CELL_CAMERA_LED"; + case CELL_CAMERA_AUDIOGAIN: return "CELL_CAMERA_AUDIOGAIN"; + case CELL_CAMERA_QS: return "CELL_CAMERA_QS"; + case CELL_CAMERA_NONZEROCOEFFS: return "CELL_CAMERA_NONZEROCOEFFS"; + case CELL_CAMERA_YUVFLAG: return "CELL_CAMERA_YUVFLAG"; + case CELL_CAMERA_JPEGFLAG: return "CELL_CAMERA_JPEGFLAG"; + case CELL_CAMERA_BACKLIGHTCOMP: return "CELL_CAMERA_BACKLIGHTCOMP"; + case CELL_CAMERA_MIRRORFLAG: return "CELL_CAMERA_MIRRORFLAG"; + case CELL_CAMERA_MEASUREDQS: return "CELL_CAMERA_MEASUREDQS"; + case CELL_CAMERA_422FLAG: return "CELL_CAMERA_422FLAG"; + case CELL_CAMERA_USBLOAD: return "CELL_CAMERA_USBLOAD"; + case CELL_CAMERA_GAMMA: return "CELL_CAMERA_GAMMA"; + case CELL_CAMERA_GREENGAIN: return "CELL_CAMERA_GREENGAIN"; + case CELL_CAMERA_AGCLIMIT: return "CELL_CAMERA_AGCLIMIT"; + case CELL_CAMERA_DENOISE: return "CELL_CAMERA_DENOISE"; + case CELL_CAMERA_FRAMERATEADJUST: return "CELL_CAMERA_FRAMERATEADJUST"; + case CELL_CAMERA_PIXELOUTLIERFILTER: return "CELL_CAMERA_PIXELOUTLIERFILTER"; + case CELL_CAMERA_AGCLOW: return "CELL_CAMERA_AGCLOW"; + case CELL_CAMERA_AGCHIGH: return "CELL_CAMERA_AGCHIGH"; + case CELL_CAMERA_DEVICELOCATION: return "CELL_CAMERA_DEVICELOCATION"; + case CELL_CAMERA_FORMATCAP: return "CELL_CAMERA_FORMATCAP"; + case CELL_CAMERA_FORMATINDEX: return "CELL_CAMERA_FORMATINDEX"; + case CELL_CAMERA_NUMFRAME: return "CELL_CAMERA_NUMFRAME"; + case CELL_CAMERA_FRAMEINDEX: return "CELL_CAMERA_FRAMEINDEX"; + case CELL_CAMERA_FRAMESIZE: return "CELL_CAMERA_FRAMESIZE"; + case CELL_CAMERA_INTERVALTYPE: return "CELL_CAMERA_INTERVALTYPE"; + case CELL_CAMERA_INTERVALINDEX: return "CELL_CAMERA_INTERVALINDEX"; + case CELL_CAMERA_INTERVALVALUE: return "CELL_CAMERA_INTERVALVALUE"; + case CELL_CAMERA_COLORMATCHING: return "CELL_CAMERA_COLORMATCHING"; + case CELL_CAMERA_PLFREQ: return "CELL_CAMERA_PLFREQ"; + case CELL_CAMERA_DEVICEID: return "CELL_CAMERA_DEVICEID"; + case CELL_CAMERA_DEVICECAP: return "CELL_CAMERA_DEVICECAP"; + case CELL_CAMERA_DEVICESPEED: return "CELL_CAMERA_DEVICESPEED"; + case CELL_CAMERA_UVCREQCODE: return "CELL_CAMERA_UVCREQCODE"; + case CELL_CAMERA_UVCREQDATA: return "CELL_CAMERA_UVCREQDATA"; + case CELL_CAMERA_DEVICEID2: return "CELL_CAMERA_DEVICEID2"; + case CELL_CAMERA_READMODE: return "CELL_CAMERA_READMODE"; + case CELL_CAMERA_GAMEPID: return "CELL_CAMERA_GAMEPID"; + case CELL_CAMERA_PBUFFER: return "CELL_CAMERA_PBUFFER"; + case CELL_CAMERA_READFINISH: return "CELL_CAMERA_READFINISH"; + } + + return nullptr; + } +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 7bb177751f..3609545cd6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -3,9 +3,7 @@ #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" -#include "Emu/CPU/CPUThreadManager.h" #include "cellPamf.h" #include "cellDmux.h" @@ -84,6 +82,7 @@ PesHeader::PesHeader(DemuxerStream& stream) ElementaryStream::ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec) : dmux(dmux) + , id(Emu.GetIdManager().get_current_id()) , memAddr(align(addr, 128)) , memSize(size - (addr - memAddr)) , fidMajor(fidMajor) @@ -169,7 +168,7 @@ void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool ra info->reserved = 0; info->userData = userdata; - auto spec = vm::ptr::make(put + sizeof(CellDmuxAuInfoEx)); + auto spec = vm::ptr::make(put + sizeof32(CellDmuxAuInfoEx)); *spec = specific; auto inf = vm::ptr::make(put + 64); @@ -284,7 +283,7 @@ void dmuxQueryAttr(u32 info_addr /* may be 0 */, vm::ptr attr) attr->memSize = 0x10000; // 0x3e8e6 from ps3 } -void dmuxQueryEsAttr(u32 info /* may be 0 */, vm::ptr esFilterId, u32 esSpecificInfo, vm::ptr attr) +void dmuxQueryEsAttr(u32 info /* may be 0 */, vm::cptr esFilterId, u32 esSpecificInfo, vm::ptr attr) { if (esFilterId->filterIdMajor >= 0xe0) { @@ -305,16 +304,10 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor dmux.id = dmux_id; - dmux.dmuxCb = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_PPU).get()); - dmux.dmuxCb->SetName(fmt::format("Demuxer[0x%x] Callback", dmux_id)); - dmux.dmuxCb->SetEntry(0); - dmux.dmuxCb->SetPrio(1001); - dmux.dmuxCb->SetStackSize(0x10000); - dmux.dmuxCb->InitStack(); - dmux.dmuxCb->InitRegs(); - dmux.dmuxCb->DoRun(); - - thread_t t(fmt::format("Demuxer[0x%x] Thread", dmux_id), [sptr]() + dmux.dmuxCb = Emu.GetIdManager().make_ptr(fmt::format("Demuxer[0x%x] Thread", dmux_id)); + dmux.dmuxCb->prio = 1001; + dmux.dmuxCb->stack_size = 0x10000; + dmux.dmuxCb->custom_task = [sptr](PPUThread& CPU) { Demuxer& dmux = *sptr; @@ -352,7 +345,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor auto dmuxMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->supplementalInfo = stream.userdata; - dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); + dmux.cbFunc(CPU, dmux.id, dmuxMsg, dmux.cbArg); dmux.is_working = false; @@ -505,7 +498,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor auto esMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->supplementalInfo = stream.userdata; - es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + es.cbFunc(CPU, dmux.id, es.id, esMsg, es.cbArg); } } else @@ -570,7 +563,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor auto esMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->supplementalInfo = stream.userdata; - es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + es.cbFunc(CPU, dmux.id, es.id, esMsg, es.cbArg); } if (pes.has_ts) @@ -646,7 +639,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor auto dmuxMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->supplementalInfo = stream.userdata; - dmux.cbFunc(*dmux.dmuxCb, dmux.id, dmuxMsg, dmux.cbArg); + dmux.cbFunc(CPU, dmux.id, dmuxMsg, dmux.cbArg); stream = {}; @@ -734,7 +727,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor auto esMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; esMsg->supplementalInfo = stream.userdata; - es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + es.cbFunc(CPU, dmux.id, es.id, esMsg, es.cbArg); } if (es.raw_data.size()) @@ -746,7 +739,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor auto esMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE; esMsg->supplementalInfo = stream.userdata; - es.cbFunc(*dmux.dmuxCb, dmux.id, es.id, esMsg, es.cbArg); + es.cbFunc(CPU, dmux.id, es.id, esMsg, es.cbArg); break; } @@ -769,10 +762,13 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor } dmux.is_finished = true; - }); + }; + + dmux.dmuxCb->Run(); + dmux.dmuxCb->Exec(); } -s32 cellDmuxQueryAttr(vm::ptr type, vm::ptr attr) +s32 cellDmuxQueryAttr(vm::cptr type, vm::ptr attr) { cellDmux.Warning("cellDmuxQueryAttr(type=*0x%x, attr=*0x%x)", type, attr); @@ -785,7 +781,7 @@ s32 cellDmuxQueryAttr(vm::ptr type, vm::ptr at return CELL_OK; } -s32 cellDmuxQueryAttr2(vm::ptr type2, vm::ptr attr) +s32 cellDmuxQueryAttr2(vm::cptr type2, vm::ptr attr) { cellDmux.Warning("cellDmuxQueryAttr2(demuxerType2=*0x%x, demuxerAttr=*0x%x)", type2, attr); @@ -798,7 +794,7 @@ s32 cellDmuxQueryAttr2(vm::ptr type2, vm::ptr return CELL_OK; } -s32 cellDmuxOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellDmuxOpen(vm::cptr type, vm::cptr res, vm::cptr cb, vm::ptr handle) { cellDmux.Warning("cellDmuxOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); @@ -814,7 +810,7 @@ s32 cellDmuxOpen(vm::ptr type, vm::ptr type, vm::ptr resEx, vm::ptr cb, vm::ptr handle) +s32 cellDmuxOpenEx(vm::cptr type, vm::cptr resEx, vm::cptr cb, vm::ptr handle) { cellDmux.Warning("cellDmuxOpenEx(type=*0x%x, resEx=*0x%x, cb=*0x%x, handle=*0x%x)", type, resEx, cb, handle); @@ -830,12 +826,12 @@ s32 cellDmuxOpenEx(vm::ptr type, vm::ptr type, vm::ptr resEx, vm::ptr cb, vm::ptr handle) +s32 _nid_e075fabc(vm::cptr type, vm::cptr resEx, vm::cptr cb, vm::ptr handle) { return cellDmuxOpenEx(type, resEx, cb, handle); } -s32 cellDmuxOpen2(vm::ptr type2, vm::ptr res2, vm::ptr cb, vm::ptr handle) +s32 cellDmuxOpen2(vm::cptr type2, vm::cptr res2, vm::cptr cb, vm::ptr handle) { cellDmux.Warning("cellDmuxOpen2(type2=*0x%x, res2=*0x%x, cb=*0x%x, handle=*0x%x)", type2, res2, cb, handle); @@ -876,7 +872,7 @@ s32 cellDmuxClose(u32 handle) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - if (dmux->dmuxCb) Emu.GetCPU().RemoveThread(dmux->dmuxCb->GetId()); + Emu.GetIdManager().remove(dmux->dmuxCb->GetId()); Emu.GetIdManager().remove(handle); return CELL_OK; } @@ -957,7 +953,7 @@ s32 cellDmuxResetStreamAndWaitDone(u32 handle) return CELL_OK; } -s32 cellDmuxQueryEsAttr(vm::ptr type, vm::ptr esFilterId, u32 esSpecificInfo, vm::ptr esAttr) +s32 cellDmuxQueryEsAttr(vm::cptr type, vm::cptr esFilterId, u32 esSpecificInfo, vm::ptr esAttr) { cellDmux.Warning("cellDmuxQueryEsAttr(demuxerType=*0x%x, esFilterId=*0x%x, esSpecificInfo=*0x%x, esAttr=*0x%x)", type, esFilterId, esSpecificInfo, esAttr); @@ -971,7 +967,7 @@ s32 cellDmuxQueryEsAttr(vm::ptr type, vm::ptr type2, vm::ptr esFilterId, u32 esSpecificInfo, vm::ptr esAttr) +s32 cellDmuxQueryEsAttr2(vm::cptr type2, vm::cptr esFilterId, u32 esSpecificInfo, vm::ptr esAttr) { cellDmux.Warning("cellDmuxQueryEsAttr2(type2=*0x%x, esFilterId=*0x%x, esSpecificInfo=*0x%x, esAttr=*0x%x)", type2, esFilterId, esSpecificInfo, esAttr); @@ -985,7 +981,7 @@ s32 cellDmuxQueryEsAttr2(vm::ptr type2, vm::ptr esFilterId, vm::ptr esResourceInfo, vm::ptr esCb, u32 esSpecificInfo, vm::ptr esHandle) +s32 cellDmuxEnableEs(u32 handle, vm::cptr esFilterId, vm::cptr esResourceInfo, vm::cptr esCb, u32 esSpecificInfo, vm::ptr esHandle) { cellDmux.Warning("cellDmuxEnableEs(handle=0x%x, esFilterId=*0x%x, esResourceInfo=*0x%x, esCb=*0x%x, esSpecificInfo=*0x%x, esHandle=*0x%x)", handle, esFilterId, esResourceInfo, esCb, esSpecificInfo, esHandle); @@ -998,19 +994,17 @@ s32 cellDmuxEnableEs(u32 handle, vm::ptr esFilterId, // TODO: check esFilterId, esResourceInfo, esCb and esSpecificInfo correctly - auto es = std::make_shared(dmux.get(), esResourceInfo->memAddr, esResourceInfo->memSize, + const auto es = Emu.GetIdManager().make_ptr(dmux.get(), esResourceInfo->memAddr, esResourceInfo->memSize, esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2, esCb->cbEsMsgFunc, esCb->cbArg, esSpecificInfo); - u32 id = Emu.GetIdManager().add(es); - es->id = id; - *esHandle = id; + *esHandle = es->id; - cellDmux.Warning("*** New ES(dmux=0x%x, addr=0x%x, size=0x%x, filter={0x%x, 0x%x, 0x%x, 0x%x}, cb=0x%x, arg=0x%x, spec=0x%x): id = %d", - handle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, es->cbFunc, es->cbArg, es->spec, id); + cellDmux.Warning("*** New ES(dmux=0x%x, addr=0x%x, size=0x%x, filter={0x%x, 0x%x, 0x%x, 0x%x}, cb=0x%x, arg=0x%x, spec=0x%x): id = 0x%x", + handle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, es->cbFunc, es->cbArg, es->spec, es->id); DemuxerTask task(dmuxEnableEs); - task.es.es = id; + task.es.es = es->id; task.es.es_ptr = es.get(); dmux->job.push(task, &dmux->is_closed); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index 69ca3645d0..ea7d3cc83b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -10,27 +12,27 @@ enum CELL_DMUX_ERROR_FATAL = 0x80610205, }; -enum CellDmuxStreamType +enum CellDmuxStreamType : s32 { CELL_DMUX_STREAM_TYPE_UNDEF = 0, CELL_DMUX_STREAM_TYPE_PAMF = 1, CELL_DMUX_STREAM_TYPE_TERMINATOR = 2, }; -enum CellDmuxMsgType +enum CellDmuxMsgType : s32 { CELL_DMUX_MSG_TYPE_DEMUX_DONE = 0, CELL_DMUX_MSG_TYPE_FATAL_ERR = 1, CELL_DMUX_MSG_TYPE_PROG_END_CODE = 2, }; -enum CellDmuxEsMsgType +enum CellDmuxEsMsgType : s32 { CELL_DMUX_ES_MSG_TYPE_AU_FOUND = 0, CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE = 1, }; -enum CellDmuxPamfM2vLevel +enum CellDmuxPamfM2vLevel : s32 { CELL_DMUX_PAMF_M2V_MP_LL = 0, CELL_DMUX_PAMF_M2V_MP_ML, @@ -38,7 +40,7 @@ enum CellDmuxPamfM2vLevel CELL_DMUX_PAMF_M2V_MP_HL, }; -enum CellDmuxPamfAvcLevel +enum CellDmuxPamfAvcLevel : s32 { CELL_DMUX_PAMF_AVC_LEVEL_2P1 = 21, CELL_DMUX_PAMF_AVC_LEVEL_3P0 = 30, @@ -112,18 +114,18 @@ struct CellDmuxPamfEsSpecificInfoUserData be_t reserved1; }; -enum CellDmuxPamfSamplingFrequency +enum CellDmuxPamfSamplingFrequency : s32 { CELL_DMUX_PAMF_FS_48K = 48000, }; -enum CellDmuxPamfBitsPerSample +enum CellDmuxPamfBitsPerSample : s32 { CELL_DMUX_PAMF_BITS_PER_SAMPLE_16 = 16, CELL_DMUX_PAMF_BITS_PER_SAMPLE_24 = 24, }; -enum CellDmuxPamfLpcmChannelAssignmentInfo +enum CellDmuxPamfLpcmChannelAssignmentInfo : s32 { CELL_DMUX_PAMF_LPCM_CH_M1 = 1, CELL_DMUX_PAMF_LPCM_CH_LR = 3, @@ -131,12 +133,12 @@ enum CellDmuxPamfLpcmChannelAssignmentInfo CELL_DMUX_PAMF_LPCM_CH_LRCLSCS1CS2RSLFE = 11, }; -enum CellDmuxPamfLpcmFs +enum CellDmuxPamfLpcmFs : s32 { CELL_DMUX_PAMF_LPCM_FS_48K = 1, }; -enum CellDmuxPamfLpcmBitsPerSamples +enum CellDmuxPamfLpcmBitsPerSamples : s32 { CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_16 = 1, CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_24 = 3, @@ -144,20 +146,20 @@ enum CellDmuxPamfLpcmBitsPerSamples struct CellDmuxMsg { - be_t msgType; //CellDmuxMsgType enum + be_t msgType; // CellDmuxMsgType be_t supplementalInfo; }; struct CellDmuxEsMsg { - be_t msgType; //CellDmuxEsMsgType enum + be_t msgType; // CellDmuxEsMsgType be_t supplementalInfo; }; struct CellDmuxType { - be_t streamType; - be_t reserved[2]; //0 + be_t streamType; // CellDmuxStreamType + be_t reserved[2]; }; struct CellDmuxPamfSpecificInfo @@ -168,7 +170,7 @@ struct CellDmuxPamfSpecificInfo struct CellDmuxType2 { - be_t streamType; + be_t streamType; // CellDmuxStreamType be_t streamSpecificInfo; }; @@ -217,7 +219,7 @@ struct CellDmuxResource2 be_t shit[4]; }; -typedef u32(CellDmuxCbMsg)(u32 demuxerHandle, vm::ptr demuxerMsg, u32 cbArg); +using CellDmuxCbMsg = func_def demuxerMsg, u32 cbArg)>; struct CellDmuxCb { @@ -225,7 +227,7 @@ struct CellDmuxCb be_t cbArg; }; -typedef u32(CellDmuxCbEsMsg)(u32 demuxerHandle, u32 esHandle, vm::ptr esMsg, u32 cbArg); +using CellDmuxCbEsMsg = func_def esMsg, u32 cbArg)>; struct CellDmuxEsCb { @@ -406,7 +408,7 @@ public: std::atomic is_running; std::atomic is_working; - PPUThread* dmuxCb; + std::shared_ptr dmuxCb; Demuxer(u32 addr, u32 size, vm::ptr func, u32 arg) : is_finished(false) @@ -417,7 +419,6 @@ public: , memSize(size) , cbFunc(func) , cbArg(arg) - , dmuxCb(nullptr) { } }; @@ -439,7 +440,7 @@ public: ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, vm::ptr cbFunc, u32 cbArg, u32 spec); Demuxer* dmux; - u32 id; + const u32 id; const u32 memAddr; const u32 memSize; const u32 fidMajor; diff --git a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp index 77d1c9aa7b..6336a1949b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp @@ -7,73 +7,73 @@ extern Module cellFiber; -int _cellFiberPpuInitialize() +s32 _cellFiberPpuInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int _cellFiberPpuSchedulerAttributeInitialize() +s32 _cellFiberPpuSchedulerAttributeInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuInitializeScheduler() +s32 cellFiberPpuInitializeScheduler() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuFinalizeScheduler() +s32 cellFiberPpuFinalizeScheduler() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuRunFibers() +s32 cellFiberPpuRunFibers() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuCheckFlags() +s32 cellFiberPpuCheckFlags() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuHasRunnableFiber() +s32 cellFiberPpuHasRunnableFiber() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int _cellFiberPpuAttributeInitialize() +s32 _cellFiberPpuAttributeInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuCreateFiber() +s32 cellFiberPpuCreateFiber() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuExit() +s32 cellFiberPpuExit() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuYield() +s32 cellFiberPpuYield() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuJoinFiber() +s32 cellFiberPpuJoinFiber() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; @@ -87,205 +87,205 @@ vm::ptr cellFiberPpuSelf() return vm::null; } -int cellFiberPpuSendSignal() +s32 cellFiberPpuSendSignal() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuWaitSignal() +s32 cellFiberPpuWaitSignal() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuWaitFlag() +s32 cellFiberPpuWaitFlag() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuGetScheduler() +s32 cellFiberPpuGetScheduler() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuSetPriority() +s32 cellFiberPpuSetPriority() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuCheckStackLimit() +s32 cellFiberPpuCheckStackLimit() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int _cellFiberPpuContextAttributeInitialize() +s32 _cellFiberPpuContextAttributeInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextInitialize() +s32 cellFiberPpuContextInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextFinalize() +s32 cellFiberPpuContextFinalize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextRun() +s32 cellFiberPpuContextRun() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextSwitch() +s32 cellFiberPpuContextSwitch() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextSelf() +s32 cellFiberPpuContextSelf() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextReturnToThread() +s32 cellFiberPpuContextReturnToThread() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextCheckStackLimit() +s32 cellFiberPpuContextCheckStackLimit() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextRunScheduler() +s32 cellFiberPpuContextRunScheduler() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuContextEnterScheduler() +s32 cellFiberPpuContextEnterScheduler() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuSchedulerTraceInitialize() +s32 cellFiberPpuSchedulerTraceInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuSchedulerTraceFinalize() +s32 cellFiberPpuSchedulerTraceFinalize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuSchedulerTraceStart() +s32 cellFiberPpuSchedulerTraceStart() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuSchedulerTraceStop() +s32 cellFiberPpuSchedulerTraceStop() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int _cellFiberPpuUtilWorkerControlAttributeInitialize() +s32 _cellFiberPpuUtilWorkerControlAttributeInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlRunFibers() +s32 cellFiberPpuUtilWorkerControlRunFibers() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlInitialize() +s32 cellFiberPpuUtilWorkerControlInitialize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlSetPollingMode() +s32 cellFiberPpuUtilWorkerControlSetPollingMode() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlJoinFiber() +s32 cellFiberPpuUtilWorkerControlJoinFiber() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlDisconnectEventQueue() +s32 cellFiberPpuUtilWorkerControlDisconnectEventQueue() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlSendSignal() +s32 cellFiberPpuUtilWorkerControlSendSignal() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlConnectEventQueueToSpurs() +s32 cellFiberPpuUtilWorkerControlConnectEventQueueToSpurs() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlFinalize() +s32 cellFiberPpuUtilWorkerControlFinalize() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlWakeup() +s32 cellFiberPpuUtilWorkerControlWakeup() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlCreateFiber() +s32 cellFiberPpuUtilWorkerControlCreateFiber() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlShutdown() +s32 cellFiberPpuUtilWorkerControlShutdown() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlCheckFlags() +s32 cellFiberPpuUtilWorkerControlCheckFlags() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; } -int cellFiberPpuUtilWorkerControlInitializeWithAttribute() +s32 cellFiberPpuUtilWorkerControlInitializeWithAttribute() { UNIMPLEMENTED_FUNC(cellFiber); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellFiber.h b/rpcs3/Emu/SysCalls/Modules/cellFiber.h index cfeaac2323..36c3421c21 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFiber.h +++ b/rpcs3/Emu/SysCalls/Modules/cellFiber.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp index 3d574a2486..9494a24241 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp @@ -11,9 +11,9 @@ extern Module cellFont; CCellFontInternal* s_fontInternalInstance = nullptr; // Functions -int cellFontInitializeWithRevision(u64 revisionFlags, vm::ptr config) +s32 cellFontInitializeWithRevision(u64 revisionFlags, vm::ptr config) { - cellFont.Warning("cellFontInitializeWithRevision(revisionFlags=0x%llx, config=0x%x)", revisionFlags, config.addr()); + cellFont.Warning("cellFontInitializeWithRevision(revisionFlags=0x%llx, config=*0x%x)", revisionFlags, config); if (s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_ALREADY_INITIALIZED; @@ -27,18 +27,18 @@ int cellFontInitializeWithRevision(u64 revisionFlags, vm::ptr co s_fontInternalInstance->m_userFontEntrys_addr = config->userFontEntrys_addr; s_fontInternalInstance->m_userFontEntryMax = config->userFontEntryMax; s_fontInternalInstance->m_bInitialized = true; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetRevisionFlags(vm::ptr revisionFlags) +s32 cellFontGetRevisionFlags(vm::ptr revisionFlags) { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontInit(PPUThread& CPU, vm::ptr config) +s32 cellFontInit(PPUThread& CPU, vm::ptr config) { - cellFont.Log("cellFontInit(config=0x%x)", config.addr()); + cellFont.Warning("cellFontInit(config=*0x%x)", config); vm::stackvar> revisionFlags(CPU); revisionFlags.value() = 0; @@ -46,28 +46,26 @@ int cellFontInit(PPUThread& CPU, vm::ptr config) return cellFontInitializeWithRevision(revisionFlags.value(), config); } -int cellFontEnd() +s32 cellFontEnd() { - cellFont.Log("cellFontEnd()"); + cellFont.Warning("cellFontEnd()"); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; s_fontInternalInstance->m_bInitialized = false; - return CELL_FONT_OK; + return CELL_OK; } s32 cellFontSetFontsetOpenMode(u32 openMode) { - cellFont.Log("cellFontSetFontsetOpenMode(openMode=0x%x)", openMode); - UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + cellFont.Todo("cellFontSetFontsetOpenMode(openMode=0x%x)", openMode); + return CELL_OK; } -int cellFontOpenFontMemory(vm::ptr library, u32 fontAddr, u32 fontSize, u32 subNum, u32 uniqueId, vm::ptr font) +s32 cellFontOpenFontMemory(vm::ptr library, u32 fontAddr, u32 fontSize, u32 subNum, u32 uniqueId, vm::ptr font) { - cellFont.Warning("cellFontOpenFontMemory(library_addr=0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font_addr=0x%x)", - library.addr(), fontAddr, fontSize, subNum, uniqueId, font.addr()); + cellFont.Warning("cellFontOpenFontMemory(library=*0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font=*0x%x)", library, fontAddr, fontSize, subNum, uniqueId, font); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; @@ -80,31 +78,28 @@ int cellFontOpenFontMemory(vm::ptr library, u32 fontAddr, u32 f font->renderer_addr = 0; font->fontdata_addr = fontAddr; font->origin = CELL_FONT_OPEN_MEMORY; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontOpenFontFile(vm::ptr library, vm::ptr fontPath, u32 subNum, s32 uniqueId, vm::ptr font) +s32 cellFontOpenFontFile(vm::ptr library, vm::cptr fontPath, u32 subNum, s32 uniqueId, vm::ptr font) { - std::string fp(fontPath.get_ptr()); - cellFont.Warning("cellFontOpenFontFile(library_addr=0x%x, fontPath=\"%s\", subNum=%d, uniqueId=%d, font_addr=0x%x)", - library.addr(), fp.c_str(), subNum, uniqueId, font.addr()); + cellFont.Warning("cellFontOpenFontFile(library=*0x%x, fontPath=*0x%x, subNum=%d, uniqueId=%d, font=*0x%x)", library, fontPath, subNum, uniqueId, font); - vfsFile f(fp); + vfsFile f(fontPath.get_ptr()); if (!f.IsOpened()) return CELL_FONT_ERROR_FONT_OPEN_FAILED; u32 fileSize = (u32)f.GetSize(); u32 bufferAddr = (u32)Memory.Alloc(fileSize, 1); // Freed in cellFontCloseFont f.Read(vm::get_ptr(bufferAddr), fileSize); - int ret = cellFontOpenFontMemory(library, bufferAddr, fileSize, subNum, uniqueId, font); + s32 ret = cellFontOpenFontMemory(library, bufferAddr, fileSize, subNum, uniqueId, font); font->origin = CELL_FONT_OPEN_FONT_FILE; return ret; } -int cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::ptr fontType, vm::ptr font) +s32 cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::ptr fontType, vm::ptr font) { - cellFont.Log("cellFontOpenFontset(library_addr=0x%x, fontType_addr=0x%x, font_addr=0x%x)", - library.addr(), fontType.addr(), font.addr()); + cellFont.Warning("cellFontOpenFontset(library=*0x%x, fontType=*0x%x, font=*0x%x)", library, fontType, font); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; @@ -179,14 +174,14 @@ int cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::pt vm::stackvar f(CPU, (u32)file.length() + 1, 1); memcpy(f.get_ptr(), file.c_str(), file.size() + 1); - int ret = cellFontOpenFontFile(library, f, 0, 0, font); //TODO: Find the correct values of subNum, uniqueId + s32 ret = cellFontOpenFontFile(library, f, 0, 0, font); //TODO: Find the correct values of subNum, uniqueId font->origin = CELL_FONT_OPEN_FONTSET; return ret; } -int cellFontOpenFontInstance(vm::ptr openedFont, vm::ptr font) +s32 cellFontOpenFontInstance(vm::ptr openedFont, vm::ptr font) { - cellFont.Warning("cellFontOpenFontInstance(openedFont=0x%x, font=0x%x)", openedFont.addr(), font.addr()); + cellFont.Warning("cellFontOpenFontInstance(openedFont=*0x%x, font=*0x%x)", openedFont, font); font->renderer_addr = openedFont->renderer_addr; font->scale_x = openedFont->scale_x; @@ -195,48 +190,44 @@ int cellFontOpenFontInstance(vm::ptr openedFont, vm::ptr fon font->stbfont = openedFont->stbfont; font->origin = CELL_FONT_OPEN_FONT_INSTANCE; - return CELL_FONT_OK; + return CELL_OK; } s32 cellFontSetFontOpenMode(u32 openMode) { - cellFont.Log("cellFontSetFontOpenMode(openMode=0x%x)", openMode); - UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + cellFont.Todo("cellFontSetFontOpenMode(openMode=0x%x)", openMode); + return CELL_OK; } -int cellFontCreateRenderer(vm::ptr library, vm::ptr config, vm::ptr Renderer) +s32 cellFontCreateRenderer(vm::ptr library, vm::ptr config, vm::ptr Renderer) { - cellFont.Warning("cellFontCreateRenderer(library_addr=0x%x, config_addr=0x%x, Renderer_addr=0x%x)", - library.addr(), config.addr(), Renderer.addr()); + cellFont.Warning("cellFontCreateRenderer(library=*0x%x, config=*0x%x, Renderer=*0x%x)", library, config, Renderer); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; //Write data in Renderer - return CELL_FONT_OK; + return CELL_OK; } -void cellFontRenderSurfaceInit(vm::ptr surface, u32 buffer_addr, s32 bufferWidthByte, s32 pixelSizeByte, s32 w, s32 h) +void cellFontRenderSurfaceInit(vm::ptr surface, vm::ptr buffer, s32 bufferWidthByte, s32 pixelSizeByte, s32 w, s32 h) { - cellFont.Warning("cellFontRenderSurfaceInit(surface_addr=0x%x, buffer_addr=0x%x, bufferWidthByte=%d, pixelSizeByte=%d, w=%d, h=%d)", - surface.addr(), buffer_addr, bufferWidthByte, pixelSizeByte, w, h); + cellFont.Warning("cellFontRenderSurfaceInit(surface=*0x%x, buffer=*0x%x, bufferWidthByte=%d, pixelSizeByte=%d, w=%d, h=%d)", surface, buffer, bufferWidthByte, pixelSizeByte, w, h); - surface->buffer_addr = buffer_addr; + surface->buffer_addr = buffer.addr(); surface->widthByte = bufferWidthByte; surface->pixelSizeByte = pixelSizeByte; surface->width = w; surface->height = h; - if (!buffer_addr) + if (!buffer) surface->buffer_addr = (u32)Memory.Alloc(bufferWidthByte * h, 1); // TODO: Huge memory leak } void cellFontRenderSurfaceSetScissor(vm::ptr surface, s32 x0, s32 y0, s32 w, s32 h) { - cellFont.Warning("cellFontRenderSurfaceSetScissor(surface_addr=0x%x, x0=%d, y0=%d, w=%d, h=%d)", - surface.addr(), x0, y0, w, h); + cellFont.Warning("cellFontRenderSurfaceSetScissor(surface=*0x%x, x0=%d, y0=%d, w=%d, h=%d)", surface, x0, y0, w, h); surface->Scissor.x0 = x0; surface->Scissor.y0 = y0; @@ -244,99 +235,95 @@ void cellFontRenderSurfaceSetScissor(vm::ptr surface, s32 surface->Scissor.y1 = h; } -int cellFontSetScalePixel(vm::ptr font, float w, float h) +s32 cellFontSetScalePixel(vm::ptr font, float w, float h) { - cellFont.Log("cellFontSetScalePixel(font_addr=0x%x, w=%f, h=%f)", font.addr(), w, h); + cellFont.Log("cellFontSetScalePixel(font=*0x%x, w=%f, h=%f)", font, w, h); font->scale_x = w; font->scale_y = h; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetHorizontalLayout(vm::ptr font, vm::ptr layout) +s32 cellFontGetHorizontalLayout(vm::ptr font, vm::ptr layout) { - cellFont.Log("cellFontGetHorizontalLayout(font_addr=0x%x, layout_addr=0x%x)", - font.addr(), layout.addr()); + cellFont.Log("cellFontGetHorizontalLayout(font=*0x%x, layout=*0x%x)", font, layout); - int ascent, descent, lineGap; + s32 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; layout->effectHeight = lineGap * scale; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontBindRenderer(vm::ptr font, vm::ptr renderer) +s32 cellFontBindRenderer(vm::ptr font, vm::ptr renderer) { - cellFont.Warning("cellFontBindRenderer(font_addr=0x%x, renderer_addr=0x%x)", - font.addr(), renderer.addr()); + cellFont.Warning("cellFontBindRenderer(font=*0x%x, renderer=*0x%x)", font, renderer); if (font->renderer_addr) return CELL_FONT_ERROR_RENDERER_ALREADY_BIND; font->renderer_addr = renderer.addr(); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontUnbindRenderer(vm::ptr font) +s32 cellFontUnbindRenderer(vm::ptr font) { - cellFont.Warning("cellFontBindRenderer(font_addr=0x%x)", font.addr()); + cellFont.Warning("cellFontBindRenderer(font=*0x%x)", font); if (!font->renderer_addr) return CELL_FONT_ERROR_RENDERER_UNBIND; font->renderer_addr = 0; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontDestroyRenderer() +s32 cellFontDestroyRenderer() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontSetupRenderScalePixel(vm::ptr font, float w, float h) +s32 cellFontSetupRenderScalePixel(vm::ptr font, float w, float h) { - cellFont.Log("cellFontSetupRenderScalePixel(font_addr=0x%x, w=%f, h=%f)", font.addr(), w, h); + cellFont.Log("cellFontSetupRenderScalePixel(font=*0x%x, w=%f, h=%f)", font, w, h); if (!font->renderer_addr) return CELL_FONT_ERROR_RENDERER_UNBIND; // TODO: ? - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetRenderCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr metrics) +s32 cellFontGetRenderCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr metrics) { - cellFont.Log("cellFontGetRenderCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)", - font.addr(), code, metrics.addr()); + cellFont.Log("cellFontGetRenderCharGlyphMetrics(font=*0x%x, code=0x%x, metrics=*0x%x)", font, code, metrics); if (!font->renderer_addr) return CELL_FONT_ERROR_RENDERER_UNBIND; // TODO: ? - return CELL_FONT_OK; + return CELL_OK; } -int cellFontRenderCharGlyphImage(vm::ptr font, u32 code, vm::ptr surface, float x, float y, vm::ptr metrics, vm::ptr transInfo) +s32 cellFontRenderCharGlyphImage(vm::ptr font, u32 code, vm::ptr surface, float x, float y, vm::ptr metrics, vm::ptr transInfo) { - cellFont.Log("cellFontRenderCharGlyphImage(font_addr=0x%x, code=0x%x, surface_addr=0x%x, x=%f, y=%f, metrics_addr=0x%x, trans_addr=0x%x)", - font.addr(), code, surface.addr(), x, y, metrics.addr(), transInfo.addr()); + cellFont.Log("cellFontRenderCharGlyphImage(font=*0x%x, code=0x%x, surface=*0x%x, x=%f, y=%f, metrics=*0x%x, trans=*0x%x)", font, code, surface, x, y, metrics, transInfo); if (!font->renderer_addr) return CELL_FONT_ERROR_RENDERER_UNBIND; // Render the character - int width, height, xoff, yoff; + s32 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; + s32 baseLineY; + s32 ascent, descent, lineGap; stbtt_GetFontVMetrics(font->stbfont, &ascent, &descent, &lineGap); baseLineY = (int)((float)ascent * scale); // ??? @@ -355,60 +342,60 @@ int cellFontRenderCharGlyphImage(vm::ptr font, u32 code, vm::ptr font, float slantParam) +s32 cellFontSetEffectSlant(vm::ptr font, float slantParam) { - cellFont.Log("cellFontSetEffectSlant(font_addr=0x%x, slantParam=%f)", font.addr(), slantParam); + cellFont.Log("cellFontSetEffectSlant(font=*0x%x, slantParam=%f)", font, slantParam); if (slantParam < -1.0 || slantParam > 1.0) return CELL_FONT_ERROR_INVALID_PARAMETER; font->slant = slantParam; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetEffectSlant(vm::ptr font, vm::ptr slantParam) +s32 cellFontGetEffectSlant(vm::ptr font, vm::ptr slantParam) { - cellFont.Warning("cellFontSetEffectSlant(font_addr=0x%x, slantParam_addr=0x%x)", font.addr(), slantParam.addr()); + cellFont.Warning("cellFontSetEffectSlant(font=*0x%x, slantParam=*0x%x)", font, slantParam); *slantParam = font->slant; - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetFontIdCode(vm::ptr font, u32 code, vm::ptr fontId, vm::ptr fontCode) +s32 cellFontGetFontIdCode(vm::ptr font, u32 code, vm::ptr fontId, vm::ptr fontCode) { - cellFont.Todo("cellFontGetFontIdCode(font_addr=0x%x, code=0x%x, fontId_addr=0x%x, fontCode_addr=0x%x)", font.addr(), code, fontId.addr(), fontCode.addr()); + cellFont.Todo("cellFontGetFontIdCode(font=*0x%x, code=0x%x, fontId=*0x%x, fontCode=*0x%x)", font, code, fontId, fontCode); // TODO: ? - return CELL_FONT_OK; + return CELL_OK; } -int cellFontCloseFont(vm::ptr font) +s32 cellFontCloseFont(vm::ptr font) { - cellFont.Warning("cellFontCloseFont(font_addr=0x%x)", font.addr()); + cellFont.Warning("cellFontCloseFont(font=*0x%x)", font); if (font->origin == CELL_FONT_OPEN_FONTSET || font->origin == CELL_FONT_OPEN_FONT_FILE || font->origin == CELL_FONT_OPEN_MEMORY) Memory.Free(font->fontdata_addr); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr metrics) +s32 cellFontGetCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr metrics) { - cellFont.Log("cellFontGetCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)", font.addr(), code, metrics.addr()); + cellFont.Log("cellFontGetCharGlyphMetrics(font=*0x%x, code=0x%x, metrics=*0x%x)", font, code, metrics); - int x0, y0, x1, y1; - int advanceWidth, leftSideBearing; + s32 x0, y0, x1, y1; + s32 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); @@ -417,129 +404,129 @@ int cellFontGetCharGlyphMetrics(vm::ptr font, u32 code, vm::ptrwidth = (x1-x0) * scale; metrics->height = (y1-y0) * scale; metrics->Horizontal.bearingX = (float)leftSideBearing * scale; - metrics->Horizontal.bearingY = 0; + metrics->Horizontal.bearingY = 0.f; metrics->Horizontal.advance = (float)advanceWidth * scale; - metrics->Vertical.bearingX = 0; - metrics->Vertical.bearingY = 0; - metrics->Vertical.advance = 0; - return CELL_FONT_OK; + metrics->Vertical.bearingX = 0.f; + metrics->Vertical.bearingY = 0.f; + metrics->Vertical.advance = 0.f; + return CELL_OK; } -int cellFontGraphicsSetFontRGBA() +s32 cellFontGraphicsSetFontRGBA() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontOpenFontsetOnMemory() +s32 cellFontOpenFontsetOnMemory() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGraphicsSetScalePixel() +s32 cellFontGraphicsSetScalePixel() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGraphicsGetScalePixel() +s32 cellFontGraphicsGetScalePixel() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontSetEffectWeight() +s32 cellFontSetEffectWeight() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGlyphSetupVertexesGlyph() +s32 cellFontGlyphSetupVertexesGlyph() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetVerticalLayout() +s32 cellFontGetVerticalLayout() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetRenderCharGlyphMetricsVertical() +s32 cellFontGetRenderCharGlyphMetricsVertical() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontSetScalePoint() +s32 cellFontSetScalePoint() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontSetupRenderEffectSlant() +s32 cellFontSetupRenderEffectSlant() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGraphicsSetLineRGBA() +s32 cellFontGraphicsSetLineRGBA() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGraphicsSetDrawType() +s32 cellFontGraphicsSetDrawType() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontEndGraphics() +s32 cellFontEndGraphics() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGraphicsSetupDrawContext() +s32 cellFontGraphicsSetupDrawContext() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontSetupRenderEffectWeight() +s32 cellFontSetupRenderEffectWeight() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGlyphGetOutlineControlDistance() +s32 cellFontGlyphGetOutlineControlDistance() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGlyphGetVertexesGlyphSize() +s32 cellFontGlyphGetVertexesGlyphSize() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGenerateCharGlyph() +s32 cellFontGenerateCharGlyph() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontDeleteGlyph() +s32 cellFontDeleteGlyph() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontExtend(u32 a1, u32 a2, u32 a3) +s32 cellFontExtend(u32 a1, u32 a2, u32 a3) { cellFont.Warning("cellFontExtend(a1=0x%x, a2=0x%x, a3=0x%x)", a1, a2, a3); //In a test I did: a1=0xcfe00000, a2=0x0, a3=(pointer to something) @@ -556,25 +543,25 @@ int cellFontExtend(u32 a1, u32 a2, u32 a3) //Something happens } //Something happens? - return CELL_FONT_OK; + return CELL_OK; } -int cellFontRenderCharGlyphImageVertical() +s32 cellFontRenderCharGlyphImageVertical() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontSetResolutionDpi() +s32 cellFontSetResolutionDpi() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } -int cellFontGetCharGlyphMetricsVertical() +s32 cellFontGetCharGlyphMetricsVertical() { UNIMPLEMENTED_FUNC(cellFont); - return CELL_FONT_OK; + return CELL_OK; } Module cellFont("cellFont", []() diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.h b/rpcs3/Emu/SysCalls/Modules/cellFont.h index 2f4dee8410..95394a0802 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.h +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.h @@ -1,9 +1,10 @@ #pragma once +namespace vm { using namespace ps3; } + // Error codes enum { - CELL_FONT_OK = 0, CELL_FONT_ERROR_FATAL = 0x80540001, CELL_FONT_ERROR_INVALID_PARAMETER = 0x80540002, CELL_FONT_ERROR_UNINITIALIZED = 0x80540003, diff --git a/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp b/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp index 3234b40621..d4bd4cab47 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp @@ -9,26 +9,25 @@ extern Module cellFontFT; CCellFontFTInternal* s_fontFtInternalInstance = nullptr; -int cellFontInitLibraryFreeTypeWithRevision(u64 revisionFlags, vm::ptr config, u32 lib_addr_addr) +s32 cellFontInitLibraryFreeTypeWithRevision(u64 revisionFlags, vm::ptr config, vm::pptr lib) { - cellFontFT.Warning("cellFontInitLibraryFreeTypeWithRevision(revisionFlags=0x%llx, config_addr=0x%x, lib_addr_addr=0x%x", - revisionFlags, config.addr(), lib_addr_addr); + cellFontFT.Warning("cellFontInitLibraryFreeTypeWithRevision(revisionFlags=0x%llx, config=*0x%x, lib=**0x%x)", revisionFlags, config, lib); //if (s_fontInternalInstance->m_bInitialized) //return CELL_FONT_ERROR_UNINITIALIZED; - vm::write32(lib_addr_addr, (u32)Memory.Alloc(sizeof(CellFontLibrary), 1)); + lib->set(Memory.Alloc(sizeof(CellFontLibrary), 1)); return CELL_OK; } -int cellFontFTGetRevisionFlags() +s32 cellFontFTGetRevisionFlags() { UNIMPLEMENTED_FUNC(cellFontFT); return CELL_OK; } -int cellFontFTGetInitializedRevisionFlags() +s32 cellFontFTGetInitializedRevisionFlags() { UNIMPLEMENTED_FUNC(cellFontFT); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellFontFT.h b/rpcs3/Emu/SysCalls/Modules/cellFontFT.h index fb8a0c109f..541f5f287d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFontFT.h +++ b/rpcs3/Emu/SysCalls/Modules/cellFontFT.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct CellFontLibraryConfigFT { u32 library_addr; //void* diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index c0aa4254d2..5fe9eeaf1a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -4,7 +4,6 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Callback.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" @@ -15,7 +14,7 @@ extern Module cellFs; -s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr fd, vm::ptr arg, u64 size) +s32 cellFsOpen(vm::cptr path, s32 flags, vm::ptr fd, vm::cptr arg, u64 size) { cellFs.Warning("cellFsOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx) -> sys_fs_open()", path, flags, fd, arg, size); @@ -33,7 +32,7 @@ s32 cellFsRead(PPUThread& CPU, u32 fd, vm::ptr buf, u64 nbytes, vm::ptr>(CPU)); } -s32 cellFsWrite(PPUThread& CPU, u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite) +s32 cellFsWrite(PPUThread& CPU, u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwrite) { cellFs.Log("cellFsWrite(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); @@ -49,7 +48,7 @@ s32 cellFsClose(u32 fd) return sys_fs_close(fd); } -s32 cellFsOpendir(vm::ptr path, vm::ptr fd) +s32 cellFsOpendir(vm::cptr path, vm::ptr fd) { cellFs.Warning("cellFsOpendir(path=*0x%x, fd=*0x%x) -> sys_fs_opendir()", path, fd); @@ -75,7 +74,7 @@ s32 cellFsClosedir(u32 fd) return sys_fs_closedir(fd); } -s32 cellFsStat(vm::ptr path, vm::ptr sb) +s32 cellFsStat(vm::cptr path, vm::ptr sb) { cellFs.Warning("cellFsStat(path=*0x%x, sb=*0x%x) -> sys_fs_stat()", path, sb); @@ -93,7 +92,7 @@ s32 cellFsFstat(u32 fd, vm::ptr sb) return sys_fs_fstat(fd, sb); } -s32 cellFsMkdir(vm::ptr path, s32 mode) +s32 cellFsMkdir(vm::cptr path, s32 mode) { cellFs.Warning("cellFsMkdir(path=*0x%x, mode=%#o) -> sys_fs_mkdir()", path, mode); @@ -103,7 +102,7 @@ s32 cellFsMkdir(vm::ptr path, s32 mode) return sys_fs_mkdir(path, mode); } -s32 cellFsRename(vm::ptr from, vm::ptr to) +s32 cellFsRename(vm::cptr from, vm::cptr to) { cellFs.Warning("cellFsRename(from=*0x%x, to=*0x%x) -> sys_fs_rename()", from, to); @@ -113,7 +112,7 @@ s32 cellFsRename(vm::ptr from, vm::ptr to) return sys_fs_rename(from, to); } -s32 cellFsRmdir(vm::ptr path) +s32 cellFsRmdir(vm::cptr path) { cellFs.Warning("cellFsRmdir(path=*0x%x) -> sys_fs_rmdir()", path); @@ -123,7 +122,7 @@ s32 cellFsRmdir(vm::ptr path) return sys_fs_rmdir(path); } -s32 cellFsUnlink(vm::ptr path) +s32 cellFsUnlink(vm::cptr path) { cellFs.Warning("cellFsUnlink(path=*0x%x) -> sys_fs_unlink()", path); @@ -156,7 +155,7 @@ s32 cellFsFGetBlockSize(PPUThread& CPU, u32 fd, vm::ptr sector_size, vm::pt return sector_size && block_size ? sys_fs_fget_block_size(fd, sector_size, block_size, vm::stackvar>(CPU), vm::stackvar>(CPU)) : CELL_FS_EFAULT; } -s32 cellFsGetBlockSize(PPUThread& CPU, vm::ptr path, vm::ptr sector_size, vm::ptr block_size) +s32 cellFsGetBlockSize(PPUThread& CPU, vm::cptr path, vm::ptr sector_size, vm::ptr block_size) { cellFs.Warning("cellFsGetBlockSize(path=*0x%x, sector_size=*0x%x, block_size=*0x%x) -> sys_fs_get_block_size()", path, sector_size, block_size); @@ -166,7 +165,7 @@ s32 cellFsGetBlockSize(PPUThread& CPU, vm::ptr path, vm::ptr se return sys_fs_get_block_size(path, sector_size, block_size, vm::stackvar>(CPU)); } -s32 cellFsTruncate(vm::ptr path, u64 size) +s32 cellFsTruncate(vm::cptr path, u64 size) { cellFs.Warning("cellFsTruncate(path=*0x%x, size=0x%llx) -> sys_fs_truncate()", path, size); @@ -184,7 +183,7 @@ s32 cellFsFtruncate(u32 fd, u64 size) return sys_fs_ftruncate(fd, size); } -s32 cellFsChmod(vm::ptr path, s32 mode) +s32 cellFsChmod(vm::cptr path, s32 mode) { cellFs.Warning("cellFsChmod(path=*0x%x, mode=%#o) -> sys_fs_chmod()", path, mode); @@ -194,7 +193,7 @@ s32 cellFsChmod(vm::ptr path, s32 mode) return sys_fs_chmod(path, mode); } -s32 cellFsGetFreeSize(vm::ptr path, vm::ptr block_size, vm::ptr block_count) +s32 cellFsGetFreeSize(vm::cptr path, vm::ptr block_size, vm::ptr block_count) { cellFs.Warning("cellFsGetFreeSize(path=*0x%x, block_size=*0x%x, block_count=*0x%x)", path, block_size, block_count); cellFs.Warning("*** path = '%s'", path.get_ptr()); @@ -223,7 +222,7 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 for (; count < entries_size; count++) { - if (const auto info = directory->Read()) + if (const auto info = directory->dir->Read()) { entries[count].attribute.mode = info->flags & DirEntry_TypeDir ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; entries[count].attribute.uid = 1; // ??? @@ -280,7 +279,7 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, return CELL_OK; } -s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_size, vm::ptr nwrite) +s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::cptr buf, u64 data_size, vm::ptr nwrite) { cellFs.Log("cellFsWriteWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite); @@ -311,16 +310,16 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_ return CELL_OK; } -s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) +s32 cellFsStReadInit(u32 fd, vm::cptr ringbuf) { cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); - if (ringbuf->copy.data() & ~se32(CELL_FS_ST_COPYLESS)) + if (ringbuf->copy & ~CELL_FS_ST_COPYLESS) { return CELL_FS_EINVAL; } - if (ringbuf->block_size.data() & se64(0xfff)) // check if a multiple of sector size + if (ringbuf->block_size & 0xfff) // check if a multiple of sector size { return CELL_FS_EINVAL; } @@ -352,7 +351,7 @@ s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) file->st_ringbuf_size = ringbuf->ringbuf_size; file->st_block_size = ringbuf->ringbuf_size; file->st_trans_rate = ringbuf->transfer_rate; - file->st_copyless = ringbuf->copy.data() == se32(CELL_FS_ST_COPYLESS); + file->st_copyless = ringbuf->copy == CELL_FS_ST_COPYLESS; const u64 alloc_size = align(file->st_ringbuf_size, file->st_ringbuf_size < 1024 * 1024 ? 64 * 1024 : 1024 * 1024); @@ -398,7 +397,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + if (file->st_status.load() == SSS_NOT_INITIALIZED) { return CELL_FS_ENXIO; } @@ -422,7 +421,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) return CELL_FS_EBADF; } - switch (file->st_status.read_sync()) + switch (file->st_status.load()) { case SSS_INITIALIZED: case SSS_STOPPED: @@ -456,7 +455,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + if (file->st_status.load() == SSS_NOT_INITIALIZED) { return CELL_FS_ENXIO; } @@ -493,20 +492,19 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) offset = std::min(file->file->GetSize(), offset); size = std::min(file->file->GetSize() - offset, size); - file->st_thread.set_name(fmt::format("FS ST Thread[0x%x]", fd)); file->st_read_size = size; - file->st_thread.start([=]() + file->st_thread.start([=]{ return fmt::format("FS ST Thread[0x%x]", fd); }, [=]() { std::unique_lock lock(file->mutex); - while (file->st_status.read_relaxed() == SSS_STARTED && !Emu.IsStopped()) + while (file->st_status.load() == SSS_STARTED && !Emu.IsStopped()) { // check free space in buffer and available data in stream if (file->st_total_read - file->st_copied <= file->st_ringbuf_size - file->st_block_size && file->st_total_read < file->st_read_size) { // get buffer position - const u32 position = vm::cast(file->st_buffer + file->st_total_read % file->st_ringbuf_size); + const u32 position = VM_CAST(file->st_buffer + file->st_total_read % file->st_ringbuf_size); // read data auto old = file->file->Tell(); @@ -528,9 +526,9 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { const auto func = file->st_callback.exchange({}).func; - Emu.GetCallbackManager().Async([=](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](CPUThread& CPU) { - func(CPU, fd, available); + func(static_cast(CPU), fd, available); }); } } @@ -590,13 +588,13 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || file->st_copyless) + if (file->st_status.load() == SSS_NOT_INITIALIZED || file->st_copyless) { return CELL_FS_ENXIO; } const u64 copied = file->st_copied.load(); - const u32 position = vm::cast(file->st_buffer + copied % file->st_ringbuf_size); + const u32 position = VM_CAST(file->st_buffer + copied % file->st_ringbuf_size); const u64 total_read = file->st_total_read.load(); const u64 copy_size = (*rsize = std::min(size, total_read - copied)); // write rsize @@ -624,13 +622,13 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || !file->st_copyless) + if (file->st_status.load() == SSS_NOT_INITIALIZED || !file->st_copyless) { return CELL_FS_ENXIO; } const u64 copied = file->st_copied.load(); - const u32 position = vm::cast(file->st_buffer + copied % file->st_ringbuf_size); + const u32 position = VM_CAST(file->st_buffer + copied % file->st_ringbuf_size); const u64 total_read = file->st_total_read.load(); if ((*size = std::min(file->st_ringbuf_size - (position - file->st_buffer), total_read - copied)).data()) @@ -657,7 +655,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED || !file->st_copyless) + if (file->st_status.load() == SSS_NOT_INITIALIZED || !file->st_copyless) { return CELL_FS_ENXIO; } @@ -684,22 +682,17 @@ s32 cellFsStReadWait(u32 fd, u64 size) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + if (file->st_status.load() == SSS_NOT_INITIALIZED) { return CELL_FS_ENXIO; } std::unique_lock lock(file->mutex); + // wait for size availability or stream end while (file->st_total_read - file->st_copied < size && file->st_total_read < file->st_read_size) { - // wait for size availability or stream end - - if (Emu.IsStopped()) - { - cellFs.Warning("cellFsStReadWait(0x%x) aborted", fd); - return CELL_OK; - } + CHECK_EMU_STATUS; file->cv.wait_for(lock, std::chrono::milliseconds(1)); } @@ -718,7 +711,7 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func) return CELL_FS_EBADF; } - if (file->st_status.read_sync() == SSS_NOT_INITIALIZED) + if (file->st_status.load() == SSS_NOT_INITIALIZED) { return CELL_FS_ENXIO; } @@ -757,7 +750,7 @@ bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) return true; } -int sdata_unpack(const std::string& packed_file, const std::string& unpacked_file) +s32 sdata_unpack(const std::string& packed_file, const std::string& unpacked_file) { std::shared_ptr packed_stream(Emu.GetVFS().OpenFile(packed_file, vfsRead)); std::shared_ptr unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, vfsWriteNew)); @@ -776,17 +769,17 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil char buffer[10200]; packed_stream->Read(buffer, 256); - u32 format = re32(*(u32*)&buffer[0]); + u32 format = *(be_t*)&buffer[0]; if (format != 0x4E504400) // "NPD\x00" { cellFs.Error("Illegal format. Expected 0x4E504400, but got 0x%08x", format); return CELL_EFSSPECIFIC; } - u32 version = re32(*(u32*)&buffer[0x04]); - u32 flags = re32(*(u32*)&buffer[0x80]); - u32 blockSize = re32(*(u32*)&buffer[0x84]); - u64 filesizeOutput = re64(*(u64*)&buffer[0x88]); + u32 version = *(be_t*)&buffer[0x04]; + u32 flags = *(be_t*)&buffer[0x80]; + u32 blockSize = *(be_t*)&buffer[0x84]; + u64 filesizeOutput = *(be_t*)&buffer[0x88]; u64 filesizeInput = packed_stream->GetSize(); u32 blockCount = (u32)((filesizeOutput + blockSize - 1) / blockSize); @@ -831,7 +824,7 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil return CELL_OK; } -s32 cellFsSdataOpen(PPUThread& CPU, vm::ptr path, s32 flags, vm::ptr fd, vm::ptr arg, u64 size) +s32 cellFsSdataOpen(PPUThread& CPU, vm::cptr path, s32 flags, vm::ptr fd, vm::cptr arg, u64 size) { cellFs.Log("cellFsSdataOpen(path=*0x%x, flags=%#o, fd=*0x%x, arg=*0x%x, size=0x%llx)", path, flags, fd, arg, size); @@ -852,7 +845,7 @@ s32 cellFsSdataOpen(PPUThread& CPU, vm::ptr path, s32 flags, vm::ptr std::string::size_type last_slash = path.rfind('/'); //TODO: use a filesystem library to solve this more robustly last_slash = last_slash == std::string::npos ? 0 : last_slash+1; std::string unpacked_path = "/dev_hdd1/"+path.substr(last_slash,path.length()-last_slash)+".unpacked"; - int ret = sdata_unpack(path, unpacked_path); + s32 ret = sdata_unpack(path, unpacked_path); if (ret) return ret; fd = Emu.GetIdManager().GetNewID(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE); @@ -861,7 +854,7 @@ s32 cellFsSdataOpen(PPUThread& CPU, vm::ptr path, s32 flags, vm::ptr */ } -s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr sdata_fd, u64 offset, vm::ptr arg, u64 size) +s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr sdata_fd, u64 offset, vm::cptr arg, u64 size) { cellFs.Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=%#o, sdata_fd=*0x%x, offset=0x%llx, arg=*0x%x, size=0x%llx)", mself_fd, flags, sdata_fd, offset, arg, size); @@ -899,13 +892,13 @@ void fsAio(vm::ptr aio, bool write, s32 xid, fs_aio_cb_t func) } // should be executed directly by FS AIO thread - Emu.GetCallbackManager().Async([=](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](CPUThread& CPU) { - func(CPU, aio, error, xid, result); + func(static_cast(CPU), aio, error, xid, result); }); } -s32 cellFsAioInit(vm::ptr mount_point) +s32 cellFsAioInit(vm::cptr mount_point) { cellFs.Warning("cellFsAioInit(mount_point=*0x%x)", mount_point); cellFs.Warning("*** mount_point = '%s'", mount_point.get_ptr()); @@ -915,7 +908,7 @@ s32 cellFsAioInit(vm::ptr mount_point) return CELL_OK; } -s32 cellFsAioFinish(vm::ptr mount_point) +s32 cellFsAioFinish(vm::cptr mount_point) { cellFs.Warning("cellFsAioFinish(mount_point=*0x%x)", mount_point); cellFs.Warning("*** mount_point = '%s'", mount_point.get_ptr()); @@ -925,7 +918,7 @@ s32 cellFsAioFinish(vm::ptr mount_point) return CELL_OK; } -std::atomic g_fs_aio_id(0); +std::atomic g_fs_aio_id; s32 cellFsAioRead(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) { @@ -935,7 +928,7 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) const s32 xid = (*id = ++g_fs_aio_id); - thread_t("FS AIO Read Thread", [=]{ fsAio(aio, false, xid, func); }).detach(); + thread_t(WRAP_EXPR("FS AIO Read Thread"), [=]{ fsAio(aio, false, xid, func); }).detach(); return CELL_OK; } @@ -948,7 +941,7 @@ s32 cellFsAioWrite(vm::ptr aio, vm::ptr id, fs_aio_cb_t func) const s32 xid = (*id = ++g_fs_aio_id); - thread_t("FS AIO Write Thread", [=]{ fsAio(aio, true, xid, func); }).detach(); + thread_t(WRAP_EXPR("FS AIO Write Thread"), [=]{ fsAio(aio, true, xid, func); }).detach(); return CELL_OK; } @@ -985,6 +978,8 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type Module cellFs("cellFs", []() { + g_fs_aio_id = 1; + REG_FUNC(cellFs, cellFsOpen); REG_FUNC(cellFs, cellFsSdataOpen); REG_FUNC(cellFs, cellFsSdataOpenByFd); diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.h b/rpcs3/Emu/SysCalls/Modules/cellFs.h index c5cc965795..b74d0df31b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct CellFsDirectoryEntry { CellFsStat attribute; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index d89d3dbbb6..70aa44ec38 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -2,7 +2,6 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Utilities/rMsgBox.h" #include "Emu/FS/VFS.h" @@ -17,7 +16,7 @@ std::string contentInfo; std::string usrdir; bool path_set = false; -s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) +s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::cptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { cellGame.Warning("cellHddGameCheck(version=%d, dirName=*0x%x, errDialog=%d, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); @@ -28,10 +27,10 @@ s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::ptr dirName, u return CELL_HDDGAME_ERROR_PARAM; } - vm::var param; - vm::var result; - vm::var get; - vm::var set; + vm::stackvar param(CPU); + vm::stackvar result(CPU); + vm::stackvar get(CPU); + vm::stackvar set(CPU); get->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. get->isNewData = CELL_HDDGAME_ISNEWDATA_EXIST; @@ -188,7 +187,7 @@ s32 cellGamePatchCheck(vm::ptr size, vm::ptr reserved return CELL_GAME_RET_OK; } -s32 cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptr size) +s32 cellGameDataCheck(u32 type, vm::cptr dirName, vm::ptr size) { cellGame.Warning("cellGameDataCheck(type=%d, dirName=*0x%x, size=*0x%x)", type, dirName, size); @@ -283,7 +282,7 @@ s32 cellGameContentPermit(vm::ptr contentInfoPath, vm: return CELL_GAME_RET_OK; } -s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) +s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::cptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { cellGame.Warning("cellGameDataCheckCreate2(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); @@ -341,7 +340,7 @@ s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di strcpy_trunc(cbGet->getParam.title, psf.GetString("TITLE")); // TODO: write lang titles - funcStat(cbResult, cbGet, cbSet); + funcStat(CPU, cbResult, cbGet, cbSet); if (cbSet->setParam) { @@ -380,7 +379,7 @@ s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di } } -s32 cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) +s32 cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::cptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { cellGame.Warning("cellGameDataCheckCreate(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); @@ -528,7 +527,7 @@ s32 cellGameGetLocalWebContentPath() return CELL_OK; } -s32 cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr dirName) +s32 cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr dirName) { cellGame.Warning("cellGameContentErrorDialog(type=%d, errNeedSizeKB=%d, dirName=*0x%x)", type, errNeedSizeKB, dirName); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h index 284f89a75b..f95f28629a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index bfbfe1eeee..f00bba0fce 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -2,11 +2,12 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" + #include "sysPrxForUser.h" //#include "Emu/RSX/GCM.h" #include "Emu/RSX/GSManager.h" +#include "Emu/RSX/GSRender.h" //#include "Emu/SysCalls/lv2/sys_process.h" #include "cellGcmSys.h" @@ -62,8 +63,8 @@ CellGcmOffsetTable offsetTable; void InitOffsetTable() { - offsetTable.ioAddress.set(be_t::make((u32)Memory.Alloc(3072 * sizeof(u16), 1))); - offsetTable.eaAddress.set(be_t::make((u32)Memory.Alloc(512 * sizeof(u16), 1))); + offsetTable.ioAddress.set((u32)Memory.Alloc(3072 * sizeof(u16), 1)); + offsetTable.eaAddress.set((u32)Memory.Alloc(512 * sizeof(u16), 1)); memset(offsetTable.ioAddress.get_ptr(), 0xFF, 3072 * sizeof(u16)); memset(offsetTable.eaAddress.get_ptr(), 0xFF, 512 * sizeof(u16)); @@ -276,7 +277,7 @@ s32 cellGcmBindZcull(u8 index) s32 cellGcmGetConfiguration(vm::ptr config) { - cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config.addr()); + cellGcmSys.Log("cellGcmGetConfiguration(config=*0x%x)", config); *config = current_config; @@ -312,16 +313,16 @@ void _cellGcmFunc1() void _cellGcmFunc15(vm::ptr context) { - cellGcmSys.Todo("_cellGcmFunc15(context_addr=0x%x)", context.addr()); + cellGcmSys.Todo("_cellGcmFunc15(context=*0x%x)", context); return; } -size_t g_defaultCommandBufferBegin, g_defaultCommandBufferFragmentCount; +u32 g_defaultCommandBufferBegin, g_defaultCommandBufferFragmentCount; // Called by cellGcmInit s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSize, u32 ioAddress) { - cellGcmSys.Warning("_cellGcmInitBody(context_addr=0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context.addr(), cmdSize, ioSize, ioAddress); + cellGcmSys.Warning("_cellGcmInitBody(context=*0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context, cmdSize, ioSize, ioAddress); if(!local_size && !local_addr) { @@ -367,7 +368,7 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz current_context.begin = g_defaultCommandBufferBegin + 4096; // 4 kb reserved at the beginning current_context.end = g_defaultCommandBufferBegin + 32 * 1024 - 4; // 4b at the end for jump current_context.current = current_context.begin; - current_context.callback.set(be_t::make(Emu.GetRSXCallback() - 4)); + current_context.callback.set(Emu.GetRSXCallback() - 4); gcm_info.context_addr = Memory.MainMem.AllocAlign(0x1000); gcm_info.control_addr = gcm_info.context_addr + 0x40; @@ -378,9 +379,9 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz vm::write32(context.addr(), gcm_info.context_addr); auto& ctrl = vm::get_ref(gcm_info.control_addr); - ctrl.put.write_relaxed(be_t::make(0)); - ctrl.get.write_relaxed(be_t::make(0)); - ctrl.ref.write_relaxed(be_t::make(-1)); + ctrl.put.store(0); + ctrl.get.store(0); + ctrl.ref.store(-1); auto& render = Emu.GetGSManager().GetRender(); render.m_ctxt_addr = context.addr(); @@ -448,7 +449,7 @@ s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height void cellGcmSetFlipHandler(vm::ptr handler) { - cellGcmSys.Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler.addr()); + cellGcmSys.Warning("cellGcmSetFlipHandler(handler=*0x%x)", handler); Emu.GetGSManager().GetRender().m_flip_handler = handler; } @@ -479,7 +480,7 @@ void cellGcmSetFlipStatus() Emu.GetGSManager().GetRender().m_flip_status = 0; } -s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) +s32 cellGcmSetPrepareFlip(PPUThread& CPU, vm::ptr ctxt, u32 id) { cellGcmSys.Log("cellGcmSetPrepareFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); @@ -502,7 +503,7 @@ s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) if (current + 8 >= ctxt->end) { cellGcmSys.Error("Bad flip!"); - if (s32 res = ctxt->callback(ctxt, 8 /* ??? */)) + if (s32 res = ctxt->callback(CPU, ctxt, 8 /* ??? */)) { cellGcmSys.Error("cellGcmSetPrepareFlip : callback failed (0x%08x)", res); return res; @@ -526,11 +527,11 @@ s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) return id; } -s32 cellGcmSetFlip(vm::ptr ctxt, u32 id) +s32 cellGcmSetFlip(PPUThread& CPU, vm::ptr ctxt, u32 id) { cellGcmSys.Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); - s32 res = cellGcmSetPrepareFlip(ctxt, id); + s32 res = cellGcmSetPrepareFlip(CPU, ctxt, id); return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } @@ -595,21 +596,21 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u void cellGcmSetUserHandler(vm::ptr handler) { - cellGcmSys.Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler.addr()); + cellGcmSys.Warning("cellGcmSetUserHandler(handler=*0x%x)", handler); Emu.GetGSManager().GetRender().m_user_handler = handler; } void cellGcmSetVBlankHandler(vm::ptr handler) { - cellGcmSys.Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler.addr()); + cellGcmSys.Warning("cellGcmSetVBlankHandler(handler=*0x%x)", handler); Emu.GetGSManager().GetRender().m_vblank_handler = handler; } s32 cellGcmSetWaitFlip(vm::ptr ctxt) { - cellGcmSys.Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.addr()); + cellGcmSys.Log("cellGcmSetWaitFlip(ctx=*0x%x)", ctxt); GSLockCurrent lock(GS_LOCK_WAIT_FLIP); return CELL_OK; @@ -693,11 +694,16 @@ u32 cellGcmGetDisplayInfo() return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; } -s32 cellGcmGetCurrentDisplayBufferId(u32 id_addr) +s32 cellGcmGetCurrentDisplayBufferId(vm::ptr id) { - cellGcmSys.Warning("cellGcmGetCurrentDisplayBufferId(id_addr=0x%x)", id_addr); + cellGcmSys.Warning("cellGcmGetCurrentDisplayBufferId(id=*0x%x)", id); - vm::write32(id_addr, Emu.GetGSManager().GetRender().m_gcm_current_buffer); + if (Emu.GetGSManager().GetRender().m_gcm_current_buffer > UINT8_MAX) + { + throw EXCEPTION("Unexpected"); + } + + *id = Emu.GetGSManager().GetRender().m_gcm_current_buffer; return CELL_OK; } @@ -797,9 +803,9 @@ s32 cellGcmSortRemapEaIoAddress() //---------------------------------------------------------------------------- // Memory Mapping //---------------------------------------------------------------------------- -s32 cellGcmAddressToOffset(u32 address, vm::ptr> offset) +s32 cellGcmAddressToOffset(u32 address, vm::ptr offset) { - cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr()); + cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x, offset=*0x%x)", address, offset); // Address not on main memory or local memory if (address >= 0xD0000000) @@ -843,7 +849,7 @@ u32 cellGcmGetMaxIoMapSize() void cellGcmGetOffsetTable(vm::ptr table) { - cellGcmSys.Log("cellGcmGetOffsetTable(table_addr=0x%x)", table.addr()); + cellGcmSys.Log("cellGcmGetOffsetTable(table=*0x%x)", table); table->ioAddress = offsetTable.ioAddress; table->eaAddress = offsetTable.eaAddress; @@ -851,7 +857,7 @@ void cellGcmGetOffsetTable(vm::ptr table) s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr address) { - cellGcmSys.Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%x)", ioOffset, address); + cellGcmSys.Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=*0x%x)", ioOffset, address); u32 realAddr; @@ -923,7 +929,7 @@ s32 cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) { - cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.addr()); + cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x, size=0x%x, offset=*0x%x)", ea, size, offset); if ((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; @@ -1095,19 +1101,18 @@ void cellGcmSetDefaultCommandBuffer() // Other //------------------------------------------------------------------------ -s32 _cellGcmSetFlipCommand(vm::ptr ctx, u32 id) +s32 _cellGcmSetFlipCommand(PPUThread& CPU, vm::ptr ctx, u32 id) { - cellGcmSys.Log("cellGcmSetFlipCommand(ctx_addr=0x%x, id=0x%x)", ctx.addr(), id); + cellGcmSys.Log("cellGcmSetFlipCommand(ctx=*0x%x, id=0x%x)", ctx, id); - return cellGcmSetPrepareFlip(ctx, id); + return cellGcmSetPrepareFlip(CPU, ctx, id); } -s32 _cellGcmSetFlipCommandWithWaitLabel(vm::ptr ctx, u32 id, u32 label_index, u32 label_value) +s32 _cellGcmSetFlipCommandWithWaitLabel(PPUThread& CPU, vm::ptr ctx, u32 id, u32 label_index, u32 label_value) { - cellGcmSys.Log("cellGcmSetFlipCommandWithWaitLabel(ctx_addr=0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", - ctx.addr(), id, label_index, label_value); + cellGcmSys.Log("cellGcmSetFlipCommandWithWaitLabel(ctx=*0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", ctx, id, label_index, label_value); - s32 res = cellGcmSetPrepareFlip(ctx, id); + s32 res = cellGcmSetPrepareFlip(CPU, ctx, id); vm::write32(gcm_info.label_addr + 0x10 * label_index, label_value); return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } @@ -1163,7 +1168,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co */ static std::pair getNextCommandBufferBeginEnd(u32 current) { - size_t currentRange = (current - g_defaultCommandBufferBegin) / (32 * 1024); + u32 currentRange = (current - g_defaultCommandBufferBegin) / (32 * 1024); if (currentRange >= g_defaultCommandBufferFragmentCount - 1) return std::make_pair(g_defaultCommandBufferBegin + 4096, g_defaultCommandBufferBegin + 32 * 1024 - 4); return std::make_pair(g_defaultCommandBufferBegin + (currentRange + 1) * 32 * 1024, @@ -1200,12 +1205,12 @@ static bool isInCommandBufferExcept(u32 getPos, u32 bufferBegin, u32 bufferEnd) s32 cellGcmCallback(vm::ptr context, u32 count) { - cellGcmSys.Log("cellGcmCallback(context_addr=0x%x, count=0x%x)", context.addr(), count); + cellGcmSys.Log("cellGcmCallback(context=*0x%x, count=0x%x)", context, count); auto& ctrl = vm::get_ref(gcm_info.control_addr); const std::chrono::time_point enterWait = std::chrono::system_clock::now(); // Flush command buffer (ie allow RSX to read up to context->current) - ctrl.put.exchange(be_t::make(getOffsetFromAddress(context->current))); + ctrl.put.exchange(getOffsetFromAddress(context->current)); std::pair newCommandBuffer = getNextCommandBufferBeginEnd(context->current); u32 offset = getOffsetFromAddress(newCommandBuffer.first); @@ -1217,9 +1222,9 @@ s32 cellGcmCallback(vm::ptr context, u32 count) context->end = newCommandBuffer.second; // Wait for rsx to "release" the new command buffer - while (true) + while (!Emu.IsStopped()) { - u32 getPos = ctrl.get.read_sync().value(); + u32 getPos = ctrl.get.load().value(); if (isInCommandBufferExcept(getPos, newCommandBuffer.first, newCommandBuffer.second)) break; std::chrono::time_point waitPoint = std::chrono::system_clock::now(); @@ -1231,24 +1236,24 @@ s32 cellGcmCallback(vm::ptr context, u32 count) return CELL_OK; - if (0) - { - auto& ctrl = vm::get_ref(gcm_info.control_addr); - be_t res = be_t::make(context->current - context->begin - ctrl.put.read_relaxed()); + //if (0) + //{ + // auto& ctrl = vm::get_ref(gcm_info.control_addr); + // be_t res = context->current - context->begin - ctrl.put.load(); - if (res != 0) - { - GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); - } + // if (res != 0) + // { + // GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); + // } - memmove(vm::get_ptr(context->begin), vm::get_ptr(context->current - res), res); + // memmove(vm::get_ptr(context->begin), vm::get_ptr(context->current - res), res); - context->current = context->begin + res; - ctrl.put.write_relaxed(res); - ctrl.get.write_relaxed(be_t::make(0)); + // context->current = context->begin + res; + // ctrl.put.store(res); + // ctrl.get.store(0); - return CELL_OK; - } + // return CELL_OK; + //} //auto& ctrl = vm::get_ref(gcm_info.control_addr); @@ -1260,23 +1265,23 @@ s32 cellGcmCallback(vm::ptr context, u32 count) //cmd[3] = 0; // some incrementing by module value //context->current += 0x10; - if (0) - { - const u32 address = context->begin; - const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits - assert(upper != 0xFFFF); - const u32 offset = (upper << 20) | (address & 0xFFFFF); - vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | offset); // set JUMP cmd + //if (0) + //{ + // const u32 address = context->begin; + // const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits + // assert(upper != 0xFFFF); + // const u32 offset = (upper << 20) | (address & 0xFFFFF); + // vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | offset); // set JUMP cmd - auto& ctrl = vm::get_ref(gcm_info.control_addr); - ctrl.put.exchange(be_t::make(offset)); - } - else - { - vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT | (0)); - } + // auto& ctrl = vm::get_ref(gcm_info.control_addr); + // ctrl.put.exchange(offset); + //} + //else + //{ + // vm::write32(context->current, CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT | (0)); + //} - context->current = context->begin; // rewind to the beginning + //context->current = context->begin; // rewind to the beginning // TODO: something is missing return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h index 82c53937f8..58f7a7dc1a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h @@ -1,4 +1,7 @@ #pragma once + +namespace vm { using namespace ps3; } + #include "Emu/RSX/GCM.h" enum diff --git a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp index 01d7ef6ed0..506d1accd3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp @@ -19,7 +19,7 @@ struct cellGemInternal cellGemInternal cellGemInstance; -int cellGemCalibrate() +s32 cellGemCalibrate() { UNIMPLEMENTED_FUNC(cellGem); @@ -29,7 +29,7 @@ int cellGemCalibrate() return CELL_OK; } -int cellGemClearStatusFlags() +s32 cellGemClearStatusFlags() { UNIMPLEMENTED_FUNC(cellGem); @@ -39,7 +39,7 @@ int cellGemClearStatusFlags() return CELL_OK; } -int cellGemConvertVideoFinish() +s32 cellGemConvertVideoFinish() { UNIMPLEMENTED_FUNC(cellGem); @@ -49,7 +49,7 @@ int cellGemConvertVideoFinish() return CELL_OK; } -int cellGemConvertVideoStart() +s32 cellGemConvertVideoStart() { UNIMPLEMENTED_FUNC(cellGem); @@ -59,7 +59,7 @@ int cellGemConvertVideoStart() return CELL_OK; } -int cellGemEnableCameraPitchAngleCorrection() +s32 cellGemEnableCameraPitchAngleCorrection() { UNIMPLEMENTED_FUNC(cellGem); @@ -69,7 +69,7 @@ int cellGemEnableCameraPitchAngleCorrection() return CELL_OK; } -int cellGemEnableMagnetometer() +s32 cellGemEnableMagnetometer() { UNIMPLEMENTED_FUNC(cellGem); @@ -79,7 +79,7 @@ int cellGemEnableMagnetometer() return CELL_OK; } -int cellGemEnd() +s32 cellGemEnd() { cellGem.Warning("cellGemEnd()"); @@ -91,7 +91,7 @@ int cellGemEnd() return CELL_OK; } -int cellGemFilterState() +s32 cellGemFilterState() { UNIMPLEMENTED_FUNC(cellGem); @@ -101,7 +101,7 @@ int cellGemFilterState() return CELL_OK; } -int cellGemForceRGB() +s32 cellGemForceRGB() { UNIMPLEMENTED_FUNC(cellGem); @@ -111,7 +111,7 @@ int cellGemForceRGB() return CELL_OK; } -int cellGemGetAccelerometerPositionInDevice() +s32 cellGemGetAccelerometerPositionInDevice() { UNIMPLEMENTED_FUNC(cellGem); @@ -121,7 +121,7 @@ int cellGemGetAccelerometerPositionInDevice() return CELL_OK; } -int cellGemGetAllTrackableHues() +s32 cellGemGetAllTrackableHues() { UNIMPLEMENTED_FUNC(cellGem); @@ -131,7 +131,7 @@ int cellGemGetAllTrackableHues() return CELL_OK; } -int cellGemGetCameraState() +s32 cellGemGetCameraState() { UNIMPLEMENTED_FUNC(cellGem); @@ -141,7 +141,7 @@ int cellGemGetCameraState() return CELL_OK; } -int cellGemGetEnvironmentLightingColor() +s32 cellGemGetEnvironmentLightingColor() { UNIMPLEMENTED_FUNC(cellGem); @@ -151,7 +151,7 @@ int cellGemGetEnvironmentLightingColor() return CELL_OK; } -int cellGemGetHuePixels() +s32 cellGemGetHuePixels() { UNIMPLEMENTED_FUNC(cellGem); @@ -161,7 +161,7 @@ int cellGemGetHuePixels() return CELL_OK; } -int cellGemGetImageState() +s32 cellGemGetImageState() { UNIMPLEMENTED_FUNC(cellGem); @@ -171,7 +171,7 @@ int cellGemGetImageState() return CELL_OK; } -int cellGemGetInertialState() +s32 cellGemGetInertialState() { UNIMPLEMENTED_FUNC(cellGem); @@ -181,7 +181,7 @@ int cellGemGetInertialState() return CELL_OK; } -int cellGemGetInfo(vm::ptr info) +s32 cellGemGetInfo(vm::ptr info) { cellGem.Warning("cellGemGetInfo(info=0x%x)", info.addr()); @@ -207,7 +207,7 @@ s32 cellGemGetMemorySize(s32 max_connect) return 1024 * 1024 * max_connect; // 1 MB * max_connect } -int cellGemGetRGB() +s32 cellGemGetRGB() { UNIMPLEMENTED_FUNC(cellGem); @@ -217,7 +217,7 @@ int cellGemGetRGB() return CELL_OK; } -int cellGemGetRumble() +s32 cellGemGetRumble() { UNIMPLEMENTED_FUNC(cellGem); @@ -227,7 +227,7 @@ int cellGemGetRumble() return CELL_OK; } -int cellGemGetState() +s32 cellGemGetState() { UNIMPLEMENTED_FUNC(cellGem); @@ -237,7 +237,7 @@ int cellGemGetState() return CELL_OK; } -int cellGemGetStatusFlags() +s32 cellGemGetStatusFlags() { UNIMPLEMENTED_FUNC(cellGem); @@ -247,7 +247,7 @@ int cellGemGetStatusFlags() return CELL_OK; } -int cellGemGetTrackerHue() +s32 cellGemGetTrackerHue() { UNIMPLEMENTED_FUNC(cellGem); @@ -257,15 +257,15 @@ int cellGemGetTrackerHue() return CELL_OK; } -int cellGemHSVtoRGB() +s32 cellGemHSVtoRGB() { UNIMPLEMENTED_FUNC(cellGem); return CELL_OK; } -int cellGemInit(vm::ptr attribute) +s32 cellGemInit(vm::ptr attribute) { - cellGem.Warning("cellGemInit(attribute_addr=0x%x)", attribute.addr()); + cellGem.Warning("cellGemInit(attribute=*0x%x)", attribute); if (cellGemInstance.m_bInitialized) return CELL_GEM_ERROR_ALREADY_INITIALIZED; @@ -276,7 +276,7 @@ int cellGemInit(vm::ptr attribute) return CELL_OK; } -int cellGemInvalidateCalibration() +s32 cellGemInvalidateCalibration() { UNIMPLEMENTED_FUNC(cellGem); @@ -286,13 +286,13 @@ int cellGemInvalidateCalibration() return CELL_OK; } -int cellGemIsTrackableHue() +s32 cellGemIsTrackableHue() { UNIMPLEMENTED_FUNC(cellGem); return CELL_OK; } -int cellGemPrepareCamera() +s32 cellGemPrepareCamera() { UNIMPLEMENTED_FUNC(cellGem); @@ -302,7 +302,7 @@ int cellGemPrepareCamera() return CELL_OK; } -int cellGemPrepareVideoConvert() +s32 cellGemPrepareVideoConvert() { UNIMPLEMENTED_FUNC(cellGem); @@ -312,7 +312,7 @@ int cellGemPrepareVideoConvert() return CELL_OK; } -int cellGemReset() +s32 cellGemReset() { UNIMPLEMENTED_FUNC(cellGem); @@ -322,7 +322,7 @@ int cellGemReset() return CELL_OK; } -int cellGemSetRumble() +s32 cellGemSetRumble() { UNIMPLEMENTED_FUNC(cellGem); @@ -332,7 +332,7 @@ int cellGemSetRumble() return CELL_OK; } -int cellGemSetYaw() +s32 cellGemSetYaw() { UNIMPLEMENTED_FUNC(cellGem); @@ -342,7 +342,7 @@ int cellGemSetYaw() return CELL_OK; } -int cellGemTrackHues() +s32 cellGemTrackHues() { UNIMPLEMENTED_FUNC(cellGem); @@ -352,7 +352,7 @@ int cellGemTrackHues() return CELL_OK; } -int cellGemUpdateFinish() +s32 cellGemUpdateFinish() { UNIMPLEMENTED_FUNC(cellGem); @@ -362,7 +362,7 @@ int cellGemUpdateFinish() return CELL_OK; } -int cellGemUpdateStart() +s32 cellGemUpdateStart() { UNIMPLEMENTED_FUNC(cellGem); @@ -372,7 +372,7 @@ int cellGemUpdateStart() return CELL_OK; } -int cellGemWriteExternalPort() +s32 cellGemWriteExternalPort() { UNIMPLEMENTED_FUNC(cellGem); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGem.h b/rpcs3/Emu/SysCalls/Modules/cellGem.h index 712e406998..d86af2edf1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGem.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGem.h @@ -1,7 +1,8 @@ #pragma once -// Had to use define, since enum doesn't allow floats -#define CELL_GEM_SPHERE_RADIUS_MM = 22.5f; +namespace vm { using namespace ps3; } + +static const float CELL_GEM_SPHERE_RADIUS_MM = 22.5f; // Error Codes enum diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index c1717474df..1e332cdab0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -20,7 +20,7 @@ extern Module cellGifDec; s32 cellGifDecCreate( vm::ptr mainHandle, - vm::ptr threadInParam, + vm::cptr threadInParam, vm::ptr threadOutParam) { UNIMPLEMENTED_FUNC(cellGifDec); @@ -29,9 +29,9 @@ s32 cellGifDecCreate( s32 cellGifDecExtCreate( vm::ptr mainHandle, - vm::ptr threadInParam, + vm::cptr threadInParam, vm::ptr threadOutParam, - vm::ptr extThreadInParam, + vm::cptr extThreadInParam, vm::ptr extThreadOutParam) { UNIMPLEMENTED_FUNC(cellGifDec); @@ -41,35 +41,35 @@ s32 cellGifDecExtCreate( s32 cellGifDecOpen( CellGifDecMainHandle mainHandle, vm::ptr subHandle, - vm::ptr src, + vm::cptr src, vm::ptr openInfo) { cellGifDec.Warning("cellGifDecOpen(mainHandle=0x%x, subHandle=*0x%x, src=*0x%x, openInfo=*0x%x)", mainHandle, subHandle, src, openInfo); - auto current_subHandle = std::make_shared(); - current_subHandle->fd = 0; - current_subHandle->src = *src; + GifStream current_subHandle; + current_subHandle.fd = 0; + current_subHandle.src = *src; - switch(src->srcSelect.data()) + switch (src->srcSelect.value()) { - case se32(CELL_GIFDEC_BUFFER): - current_subHandle->fileSize = src->streamSize; + case CELL_GIFDEC_BUFFER: + current_subHandle.fileSize = src->streamSize; break; - case se32(CELL_GIFDEC_FILE): + case CELL_GIFDEC_FILE: { // Get file descriptor and size std::shared_ptr file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); if (!file_s) return CELL_GIFDEC_ERROR_OPEN_FILE; - current_subHandle->fd = Emu.GetIdManager().make(file_s, 0, 0); - current_subHandle->fileSize = file_s->GetSize(); + current_subHandle.fd = Emu.GetIdManager().make(file_s, 0, 0); + current_subHandle.fileSize = file_s->GetSize(); break; } } // From now, every u32 subHandle argument is a pointer to a CellGifDecSubHandle struct. - *subHandle = Emu.GetIdManager().add(std::move(current_subHandle)); + *subHandle = Emu.GetIdManager().make(current_subHandle); return CELL_OK; } @@ -92,26 +92,26 @@ s32 cellGifDecReadHeader( const u64& fileSize = subHandle_data->fileSize; CellGifDecInfo& current_info = subHandle_data->info; - //Write the header to buffer - vm::var buffer; // Alloc buffer for GIF header + // Write the header to buffer + u8 buffer[13]; - switch(subHandle_data->src.srcSelect.data()) + switch(subHandle_data->src.srcSelect.value()) { - case se32(CELL_GIFDEC_BUFFER): - memmove(buffer.begin(), subHandle_data->src.streamPtr.get_ptr(), buffer.size()); + case CELL_GIFDEC_BUFFER: + std::memcpy(buffer, subHandle_data->src.streamPtr.get_ptr(), sizeof(buffer)); break; - case se32(CELL_GIFDEC_FILE): + case CELL_GIFDEC_FILE: { auto file = Emu.GetIdManager().get(fd); file->file->Seek(0); - file->file->Read(buffer.begin(), buffer.size()); + file->file->Read(buffer, sizeof(buffer)); break; } } - if (*buffer.To>(0) != 0x47494638 || - (*buffer.To(4) != 0x6139 && *buffer.To(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature + if (*(be_t*)buffer != 0x47494638 || + (*(le_t*)(buffer + 4) != 0x6139 && *(le_t*)(buffer + 4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature { return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss } @@ -134,7 +134,7 @@ s32 cellGifDecReadHeader( s32 cellGifDecSetParameter( CellGifDecMainHandle mainHandle, CellGifDecSubHandle subHandle, - vm::ptr inParam, + vm::cptr inParam, vm::ptr outParam) { cellGifDec.Warning("cellGifDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam=*0x%x, outParam=*0x%x)", mainHandle, subHandle, inParam, outParam); @@ -171,7 +171,7 @@ s32 cellGifDecDecodeData( CellGifDecMainHandle mainHandle, CellGifDecSubHandle subHandle, vm::ptr data, - vm::ptr dataCtrlParam, + vm::cptr dataCtrlParam, vm::ptr dataOutInfo) { cellGifDec.Warning("cellGifDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x)", mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); @@ -190,19 +190,19 @@ s32 cellGifDecDecodeData( const CellGifDecOutParam& current_outParam = subHandle_data->outParam; //Copy the GIF file to a buffer - vm::var gif((u32)fileSize); + std::unique_ptr gif(new u8[fileSize]); - switch(subHandle_data->src.srcSelect.data()) + switch(subHandle_data->src.srcSelect.value()) { - case se32(CELL_GIFDEC_BUFFER): - memmove(gif.begin(), subHandle_data->src.streamPtr.get_ptr(), gif.size()); + case CELL_GIFDEC_BUFFER: + std::memcpy(gif.get(), subHandle_data->src.streamPtr.get_ptr(), fileSize); break; - case se32(CELL_GIFDEC_FILE): + case CELL_GIFDEC_FILE: { auto file = Emu.GetIdManager().get(fd); file->file->Seek(0); - file->file->Read(gif.ptr(), gif.size()); + file->file->Read(gif.get(), fileSize); break; } } @@ -211,7 +211,7 @@ s32 cellGifDecDecodeData( int width, height, actual_components; auto image = std::unique_ptr ( - stbi_load_from_memory(gif.ptr(), (s32)fileSize, &width, &height, &actual_components, 4), + stbi_load_from_memory(gif.get(), (s32)fileSize, &width, &height, &actual_components, 4), &::free ); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.h b/rpcs3/Emu/SysCalls/Modules/cellGifDec.h index ec00dedd82..5e17576136 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -90,7 +92,7 @@ struct CellGifDecExtThreadOutParam struct CellGifDecSrc { be_t srcSelect; // CellGifDecStreamSrcSel - vm::bptr fileName; + vm::bcptr fileName; be_t fileOffset; be_t fileSize; vm::bptr streamPtr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 4f04d0ab20..0548d82ac0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -39,31 +39,31 @@ s32 cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr(); + CellJpgDecSubHandle current_subHandle; - current_subHandle->fd = 0; - current_subHandle->src = *src; + current_subHandle.fd = 0; + current_subHandle.src = *src; - switch(src->srcSelect.data()) + switch(src->srcSelect.value()) { - case se32(CELL_JPGDEC_BUFFER): - current_subHandle->fileSize = src->streamSize; + case CELL_JPGDEC_BUFFER: + current_subHandle.fileSize = src->streamSize; break; - case se32(CELL_JPGDEC_FILE): + case CELL_JPGDEC_FILE: { // Get file descriptor and size std::shared_ptr file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); if (!file_s) return CELL_JPGDEC_ERROR_OPEN_FILE; - current_subHandle->fd = Emu.GetIdManager().make(file_s, 0, 0); - current_subHandle->fileSize = file_s->GetSize(); + current_subHandle.fd = Emu.GetIdManager().make(file_s, 0, 0); + current_subHandle.fileSize = file_s->GetSize(); break; } } // From now, every u32 subHandle argument is a pointer to a CellJpgDecSubHandle struct. - *subHandle = Emu.GetIdManager().add(std::move(current_subHandle)); + *subHandle = Emu.GetIdManager().make(current_subHandle); return CELL_OK; } @@ -100,26 +100,26 @@ s32 cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr const u64& fileSize = subHandle_data->fileSize; CellJpgDecInfo& current_info = subHandle_data->info; - //Write the header to buffer - vm::var buffer((u32)fileSize); + // Write the header to buffer + std::unique_ptr buffer(new u8[fileSize]); - switch(subHandle_data->src.srcSelect.data()) + switch(subHandle_data->src.srcSelect.value()) { - case se32(CELL_JPGDEC_BUFFER): - memmove(buffer.begin(), vm::get_ptr(subHandle_data->src.streamPtr), buffer.size()); + case CELL_JPGDEC_BUFFER: + std::memcpy(buffer.get(), vm::get_ptr(subHandle_data->src.streamPtr), fileSize); break; - case se32(CELL_JPGDEC_FILE): + case CELL_JPGDEC_FILE: { auto file = Emu.GetIdManager().get(fd); file->file->Seek(0); - file->file->Read(buffer.ptr(), buffer.size()); + file->file->Read(buffer.get(), fileSize); break; } } - if (*buffer.To(0) != 0xE0FFD8FF || // Error: Not a valid SOI header - *buffer.To(6) != 0x4649464A) // Error: Not a valid JFIF string + if ((le_t&)(buffer[0]) != 0xE0FFD8FF || // Error: Not a valid SOI header + (le_t&)(buffer[6]) != 0x4649464A) // Error: Not a valid JFIF string { return CELL_JPGDEC_ERROR_HEADER; } @@ -157,7 +157,7 @@ s32 cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr return CELL_OK; } -s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) +s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::cptr dataCtrlParam, vm::ptr dataOutInfo) { cellJpgDec.Log("cellJpgDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x)", mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); @@ -175,19 +175,19 @@ s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt const CellJpgDecOutParam& current_outParam = subHandle_data->outParam; //Copy the JPG file to a buffer - vm::var jpg((u32)fileSize); + std::unique_ptr jpg(new u8[fileSize]); - switch(subHandle_data->src.srcSelect.data()) + switch(subHandle_data->src.srcSelect.value()) { - case se32(CELL_JPGDEC_BUFFER): - memmove(jpg.begin(), vm::get_ptr(subHandle_data->src.streamPtr), jpg.size()); + case CELL_JPGDEC_BUFFER: + std::memcpy(jpg.get(), vm::get_ptr(subHandle_data->src.streamPtr), fileSize); break; - case se32(CELL_JPGDEC_FILE): + case CELL_JPGDEC_FILE: { auto file = Emu.GetIdManager().get(fd); file->file->Seek(0); - file->file->Read(jpg.ptr(), jpg.size()); + file->file->Read(jpg.get(), fileSize); break; } } @@ -196,7 +196,7 @@ s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt int width, height, actual_components; auto image = std::unique_ptr ( - stbi_load_from_memory(jpg.ptr(), (s32)fileSize, &width, &height, &actual_components, 4), + stbi_load_from_memory(jpg.get(), (s32)fileSize, &width, &height, &actual_components, 4), &::free ); @@ -293,7 +293,7 @@ s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt return CELL_OK; } -s32 cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) +s32 cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::cptr inParam, vm::ptr outParam) { cellJpgDec.Log("cellJpgDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam=*0x%x, outParam=*0x%x)", mainHandle, subHandle, inParam, outParam); diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h index 2450eb9977..3b9e030405 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + //Return Codes enum { @@ -56,7 +58,7 @@ struct CellJpgDecInfo struct CellJpgDecSrc { be_t srcSelect; // CellJpgDecStreamSrcSel - vm::bptr fileName; + vm::bcptr fileName; be_t fileOffset; // int64_t be_t fileSize; be_t streamPtr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellKb.cpp b/rpcs3/Emu/SysCalls/Modules/cellKb.cpp index 4e59df7d75..99595c16b6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellKb.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellKb.cpp @@ -8,7 +8,7 @@ extern Module sys_io; -int cellKbInit(u32 max_connect) +s32 cellKbInit(u32 max_connect) { sys_io.Warning("cellKbInit(max_connect=%d)", max_connect); @@ -22,7 +22,7 @@ int cellKbInit(u32 max_connect) return CELL_OK; } -int cellKbEnd() +s32 cellKbEnd() { sys_io.Log("cellKbEnd()"); @@ -33,7 +33,7 @@ int cellKbEnd() return CELL_OK; } -int cellKbClearBuf(u32 port_no) +s32 cellKbClearBuf(u32 port_no) { sys_io.Log("cellKbClearBuf(port_no=%d)", port_no); @@ -94,9 +94,9 @@ u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode) return 0x0000; } -int cellKbGetInfo(vm::ptr info) +s32 cellKbGetInfo(vm::ptr info) { - sys_io.Log("cellKbGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Log("cellKbGetInfo(info=*0x%x)", info); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -114,9 +114,9 @@ int cellKbGetInfo(vm::ptr info) return CELL_OK; } -int cellKbRead(u32 port_no, vm::ptr data) +s32 cellKbRead(u32 port_no, vm::ptr data) { - sys_io.Log("cellKbRead(port_no=%d,info_addr=0x%x)", port_no, data.addr()); + sys_io.Log("cellKbRead(port_no=%d, data=*0x%x)", port_no, data); const std::vector& keyboards = Emu.GetKeyboardManager().GetKeyboards(); if (!Emu.GetKeyboardManager().IsInited()) @@ -140,7 +140,7 @@ int cellKbRead(u32 port_no, vm::ptr data) return CELL_OK; } -int cellKbSetCodeType(u32 port_no, u32 type) +s32 cellKbSetCodeType(u32 port_no, u32 type) { sys_io.Log("cellKbSetCodeType(port_no=%d,type=%d)", port_no, type); @@ -152,13 +152,13 @@ int cellKbSetCodeType(u32 port_no, u32 type) return CELL_OK; } -int cellKbSetLEDStatus(u32 port_no, u8 led) +s32 cellKbSetLEDStatus(u32 port_no, u8 led) { UNIMPLEMENTED_FUNC(sys_io); return CELL_OK; } -int cellKbSetReadMode(u32 port_no, u32 rmode) +s32 cellKbSetReadMode(u32 port_no, u32 rmode) { sys_io.Log("cellKbSetReadMode(port_no=%d,rmode=%d)", port_no, rmode); @@ -171,9 +171,9 @@ int cellKbSetReadMode(u32 port_no, u32 rmode) return CELL_OK; } -int cellKbGetConfiguration(u32 port_no, vm::ptr config) +s32 cellKbGetConfiguration(u32 port_no, vm::ptr config) { - sys_io.Log("cellKbGetConfiguration(port_no=%d,config_addr=0x%x)", port_no, config.addr()); + sys_io.Log("cellKbGetConfiguration(port_no=%d, config=*0x%x)", port_no, config); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; diff --git a/rpcs3/Emu/SysCalls/Modules/cellKb.h b/rpcs3/Emu/SysCalls/Modules/cellKb.h index af23ce6226..21eb4a044f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellKb.h +++ b/rpcs3/Emu/SysCalls/Modules/cellKb.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum CELL_KB_ERROR_CODE { CELL_KB_ERROR_FATAL = 0x80121001, @@ -38,14 +40,3 @@ struct CellKbConfig be_t read_mode; be_t code_type; }; - -int cellKbInit(u32 max_connect); -int cellKbEnd(); -int cellKbClearBuf(u32 port_no); -u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode); -int cellKbGetInfo(vm::ptr info); -int cellKbRead(u32 port_no, vm::ptr data); -int cellKbSetCodeType(u32 port_no, u32 type); -int cellKbSetLEDStatus(u32 port_no, u8 led); -int cellKbSetReadMode(u32 port_no, u32 rmode); -int cellKbGetConfiguration(u32 port_no, vm::ptr config); diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index 3bb1b38525..59685fa4f6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -13,7 +13,7 @@ extern Module cellL10n; -s32 UTF16stoUTF8s(vm::ptr utf16, vm::ref utf16_len, vm::ptr utf8, vm::ref utf8_len) +s32 UTF16stoUTF8s(vm::cptr utf16, vm::ref utf16_len, vm::ptr utf8, vm::ref utf8_len) { cellL10n.Todo("UTF16stoUTF8s(utf16=*0x%x, utf16_len=*0x%x, utf8=*0x%x, utf8_len=*0x%x)", utf16, utf16_len, utf8, utf8_len); @@ -33,7 +33,7 @@ s32 UTF16stoUTF8s(vm::ptr utf16, vm::ref utf16_len, vm::ptr // return SRCIllegal; //} - if (utf8) + if (utf8 != vm::null) { if (len > max_len) { @@ -55,9 +55,9 @@ s32 UTF16stoUTF8s(vm::ptr utf16, vm::ref utf16_len, vm::ptr return ConversionOK; } -s32 jstrchk(vm::ptr jstr) +s32 jstrchk(vm::cptr jstr) { - cellL10n.Warning("jstrchk(jstr_addr=0x%x) -> utf8", jstr.addr()); + cellL10n.Warning("jstrchk(jstr=*0x%x) -> utf8", jstr); return L10N_STR_UTF8; } @@ -297,10 +297,9 @@ s32 _L10nConvertStr(s32 src_code, const void* src, size_t * src_len, s32 dst_cod #endif //TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful. -s32 L10nConvertStr(s32 src_code, vm::ptr src, vm::ptr src_len, s32 dst_code, vm::ptr dst, vm::ptr dst_len) +s32 L10nConvertStr(s32 src_code, vm::cptr src, vm::ptr src_len, s32 dst_code, vm::ptr dst, vm::ptr dst_len) { - cellL10n.Error("L10nConvertStr(src_code=%d, srca_addr=0x%x, src_len_addr=0x%x, dst_code=%d, dst_addr=0x%x, dst_len_addr=0x%x)", - src_code, src.addr(), src_len.addr(), dst_code, dst.addr(), dst_len.addr()); + cellL10n.Error("L10nConvertStr(src_code=%d, srca=*0x%x, src_len=*0x%x, dst_code=%d, dst=*0x%x, dst_len=*0x%x)", src_code, src, src_len, dst_code, dst, dst_len); //cellL10n.Todo("L10nConvertStr: 1st char at dst: 0x%x", *((char*)src.get_ptr())); #ifdef _MSC_VER u32 srcCode = 0, dstCode = 0; //OEM code pages diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.h b/rpcs3/Emu/SysCalls/Modules/cellL10n.h index 74a8b6cec9..0c8057744f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.h +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // L10nResult enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp b/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp deleted file mode 100644 index eb05b6320d..0000000000 --- a/rpcs3/Emu/SysCalls/Modules/cellLv2dbg.cpp +++ /dev/null @@ -1,269 +0,0 @@ -#include "stdafx.h" -#if 0 - -void cellLv2dbg_init(); -Module cellLv2dbg(0x002e, cellLv2dbg_init); - -// Return Codes -enum -{ - CELL_LV2DBG_ERROR_DEINVALIDARGUMENTS = 0x80010409, - CELL_LV2DBG_ERROR_DEOPERATIONDENIED = 0x8001042c, -}; - -int sys_dbg_read_spu_thread_context() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_initialize_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_register_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_finalize_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_unregister_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_set_stacksize_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_signal_to_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_enable_floating_point_enabled_exception() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_disable_floating_point_enabled_exception() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_set_address_to_dabr() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_address_from_dabr() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_set_mask_to_ppu_exception_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_read_ppu_thread_context() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_read_spu_thread_context2() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_ppu_thread_name() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_spu_thread_name() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_spu_thread_group_name() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_ppu_thread_status() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_spu_thread_group_status() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_ppu_thread_ids() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_spu_thread_ids() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_spu_thread_group_ids() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_mutex_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_lwmutex_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_rwlock_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_semaphore_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_cond_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_lwcond_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_event_queue_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_event_flag_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_vm_get_page_information() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_mat_set_condition() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_mat_get_condition() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_signal_to_coredump_handler() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -int sys_dbg_get_coredump_params() -{ - UNIMPLEMENTED_FUNC(cellLv2dbg); - return CELL_OK; -} - -void cellLv2dbg_init() -{ - REG_FUNC(cellLv2dbg, sys_dbg_read_spu_thread_context); - REG_FUNC(cellLv2dbg, sys_dbg_initialize_ppu_exception_handler); - REG_FUNC(cellLv2dbg, sys_dbg_register_ppu_exception_handler); - REG_FUNC(cellLv2dbg, sys_dbg_finalize_ppu_exception_handler); - REG_FUNC(cellLv2dbg, sys_dbg_unregister_ppu_exception_handler); - REG_FUNC(cellLv2dbg, sys_dbg_set_stacksize_ppu_exception_handler); - REG_FUNC(cellLv2dbg, sys_dbg_signal_to_ppu_exception_handler); - REG_FUNC(cellLv2dbg, sys_dbg_enable_floating_point_enabled_exception); - REG_FUNC(cellLv2dbg, sys_dbg_disable_floating_point_enabled_exception); - REG_FUNC(cellLv2dbg, sys_dbg_set_address_to_dabr); - REG_FUNC(cellLv2dbg, sys_dbg_get_address_from_dabr); - REG_FUNC(cellLv2dbg, sys_dbg_set_mask_to_ppu_exception_handler); - - REG_FUNC(cellLv2dbg, sys_dbg_read_ppu_thread_context); - REG_FUNC(cellLv2dbg, sys_dbg_read_spu_thread_context2); - - REG_FUNC(cellLv2dbg, sys_dbg_get_ppu_thread_name); - REG_FUNC(cellLv2dbg, sys_dbg_get_spu_thread_name); - REG_FUNC(cellLv2dbg, sys_dbg_get_spu_thread_group_name); - REG_FUNC(cellLv2dbg, sys_dbg_get_ppu_thread_status); - REG_FUNC(cellLv2dbg, sys_dbg_get_spu_thread_group_status); - - REG_FUNC(cellLv2dbg, sys_dbg_get_ppu_thread_ids); - REG_FUNC(cellLv2dbg, sys_dbg_get_spu_thread_ids); - REG_FUNC(cellLv2dbg, sys_dbg_get_spu_thread_group_ids); - - REG_FUNC(cellLv2dbg, sys_dbg_get_mutex_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_lwmutex_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_rwlock_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_semaphore_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_cond_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_lwcond_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_event_queue_information); - REG_FUNC(cellLv2dbg, sys_dbg_get_event_flag_information); - - REG_FUNC(cellLv2dbg, sys_dbg_vm_get_page_information); - - REG_FUNC(cellLv2dbg, sys_dbg_mat_set_condition); - REG_FUNC(cellLv2dbg, sys_dbg_mat_get_condition); - - REG_FUNC(cellLv2dbg, sys_dbg_signal_to_coredump_handler); - REG_FUNC(cellLv2dbg, sys_dbg_get_coredump_params); -} -#endif diff --git a/rpcs3/Emu/SysCalls/Modules/cellMic.cpp b/rpcs3/Emu/SysCalls/Modules/cellMic.cpp index e9c0c252e1..1328d9d589 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMic.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMic.cpp @@ -19,7 +19,7 @@ struct cellMicInternal cellMicInternal cellMicInstance; -int cellMicInit() +s32 cellMicInit() { cellMic.Warning("cellMicInit()"); @@ -31,7 +31,7 @@ int cellMicInit() return CELL_OK; } -int cellMicEnd() +s32 cellMicEnd() { cellMic.Warning("cellMicEnd()"); @@ -43,241 +43,241 @@ int cellMicEnd() return CELL_OK; } -int cellMicOpen() +s32 cellMicOpen() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicClose() +s32 cellMicClose() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetDeviceGUID() +s32 cellMicGetDeviceGUID() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetType() +s32 cellMicGetType() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicIsAttached() +s32 cellMicIsAttached() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicIsOpen() +s32 cellMicIsOpen() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetDeviceAttr() +s32 cellMicGetDeviceAttr() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSetDeviceAttr() +s32 cellMicSetDeviceAttr() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetSignalAttr() +s32 cellMicGetSignalAttr() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSetSignalAttr() +s32 cellMicSetSignalAttr() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetSignalState() +s32 cellMicGetSignalState() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicStart() +s32 cellMicStart() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicRead() +s32 cellMicRead() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicStop() +s32 cellMicStop() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicReset() +s32 cellMicReset() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSetNotifyEventQueue() +s32 cellMicSetNotifyEventQueue() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSetNotifyEventQueue2() +s32 cellMicSetNotifyEventQueue2() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicRemoveNotifyEventQueue() +s32 cellMicRemoveNotifyEventQueue() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicOpenEx() +s32 cellMicOpenEx() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicStartEx() +s32 cellMicStartEx() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetFormatRaw() +s32 cellMicGetFormatRaw() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetFormatAux() +s32 cellMicGetFormatAux() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetFormatDsp() +s32 cellMicGetFormatDsp() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicOpenRaw() +s32 cellMicOpenRaw() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicReadRaw() +s32 cellMicReadRaw() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicReadAux() +s32 cellMicReadAux() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicReadDsp() +s32 cellMicReadDsp() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetStatus() +s32 cellMicGetStatus() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicStopEx() +s32 cellMicStopEx() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSysShareClose() +s32 cellMicSysShareClose() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetFormat() +s32 cellMicGetFormat() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSetMultiMicNotifyEventQueue() +s32 cellMicSetMultiMicNotifyEventQueue() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetFormatEx() +s32 cellMicGetFormatEx() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSysShareStop() +s32 cellMicSysShareStop() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSysShareOpen() +s32 cellMicSysShareOpen() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicCommand() +s32 cellMicCommand() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSysShareStart() +s32 cellMicSysShareStart() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSysShareInit() +s32 cellMicSysShareInit() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicSysShareEnd() +s32 cellMicSysShareEnd() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; } -int cellMicGetDeviceIdentifier() +s32 cellMicGetDeviceIdentifier() { UNIMPLEMENTED_FUNC(cellMic); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellMic.h b/rpcs3/Emu/SysCalls/Modules/cellMic.h index 4fbc695af2..2050f5aa79 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMic.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMic.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -20,4 +22,4 @@ enum CELL_MICIN_ERROR_SYSTEM_NOT_FOUND = 0x8014010e, CELL_MICIN_ERROR_FATAL = 0x8014010f, CELL_MICIN_ERROR_DEVICE_NOT_SUPPORT = 0x80140110, -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp b/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp index fc1cd1431f..df354a0442 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp @@ -8,7 +8,7 @@ extern Module sys_io; -int cellMouseInit(u32 max_connect) +s32 cellMouseInit(u32 max_connect) { sys_io.Warning("cellMouseInit(max_connect=%d)", max_connect); if(Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_ALREADY_INITIALIZED; @@ -19,7 +19,7 @@ int cellMouseInit(u32 max_connect) } -int cellMouseClearBuf(u32 port_no) +s32 cellMouseClearBuf(u32 port_no) { sys_io.Log("cellMouseClearBuf(port_no=%d)", port_no); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; @@ -30,7 +30,7 @@ int cellMouseClearBuf(u32 port_no) return CELL_OK; } -int cellMouseEnd() +s32 cellMouseEnd() { sys_io.Log("cellMouseEnd()"); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; @@ -38,9 +38,9 @@ int cellMouseEnd() return CELL_OK; } -int cellMouseGetInfo(vm::ptr info) +s32 cellMouseGetInfo(vm::ptr info) { - sys_io.Log("cellMouseGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Log("cellMouseGetInfo(info=*0x%x)", info); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; const MouseInfo& current_info = Emu.GetMouseManager().GetInfo(); @@ -54,9 +54,9 @@ int cellMouseGetInfo(vm::ptr info) return CELL_OK; } -int cellMouseInfoTabletMode(u32 port_no, vm::ptr info) +s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr info) { - sys_io.Log("cellMouseInfoTabletMode(port_no=%d,info_addr=0x%x)", port_no, info.addr()); + sys_io.Log("cellMouseInfoTabletMode(port_no=%d, info=*0x%x)", port_no, info); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_INVALID_PARAMETER; @@ -66,9 +66,9 @@ int cellMouseInfoTabletMode(u32 port_no, vm::ptr info) return CELL_OK; } -int cellMouseGetData(u32 port_no, vm::ptr data) +s32 cellMouseGetData(u32 port_no, vm::ptr data) { - sys_io.Log("cellMouseGetData(port_no=%d,data_addr=0x%x)", port_no, data.addr()); + sys_io.Log("cellMouseGetData(port_no=%d, data=*0x%x)", port_no, data); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; @@ -88,33 +88,31 @@ int cellMouseGetData(u32 port_no, vm::ptr data) return CELL_OK; } -int cellMouseGetDataList(u32 port_no, vm::ptr data) +s32 cellMouseGetDataList(u32 port_no, vm::ptr data) { UNIMPLEMENTED_FUNC(sys_io); return CELL_OK; } -int cellMouseSetTabletMode(u32 port_no, u32 mode) +s32 cellMouseSetTabletMode(u32 port_no, u32 mode) { UNIMPLEMENTED_FUNC(sys_io); return CELL_OK; } -int cellMouseGetTabletDataList(u32 port_no, u32 data_addr) +s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr) { UNIMPLEMENTED_FUNC(sys_io); return CELL_OK; } -int cellMouseGetRawData(u32 port_no, u32 data_addr) +s32 cellMouseGetRawData(u32 port_no, vm::ptr data) { - UNIMPLEMENTED_FUNC(sys_io); - - /*sys_io.Log("cellMouseGetRawData(port_no=%d,data_addr=0x%x)", port_no, data.addr()); - if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; + sys_io.Todo("cellMouseGetRawData(port_no=%d, data=*0x%x)", port_no, data); + /*if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; CellMouseRawData& current_rawdata = Emu.GetMouseManager().GetRawData(port_no); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMouse.h b/rpcs3/Emu/SysCalls/Modules/cellMouse.h index 123de6076e..3831a6bea3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMouse.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMouse.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum CELL_MOUSE_ERROR_CODE { CELL_MOUSE_ERROR_FATAL = 0x80121201, @@ -49,14 +51,3 @@ struct CellMouseDataList }; static const u32 CELL_MOUSE_MAX_CODES = 64; - -int cellMouseInit(u32 max_connect); -int cellMouseClearBuf(u32 port_no); -int cellMouseEnd(); -int cellMouseGetInfo(vm::ptr info); -int cellMouseInfoTabletMode(u32 port_no, vm::ptr info); -int cellMouseGetData(u32 port_no, vm::ptr data); -int cellMouseGetDataList(u32 port_no, vm::ptr data); -int cellMouseSetTabletMode(u32 port_no, u32 mode); -int cellMouseGetTabletDataList(u32 port_no, u32 data_addr); -int cellMouseGetRawData(u32 port_no, u32 data_addr); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index cbf57a31aa..485635e15d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -3,14 +3,14 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Callback.h" -#include "Emu/SysCalls/CB_FUNC.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include "cellSysutil.h" #include "cellMsgDialog.h" extern Module cellSysutil; +extern u64 get_system_time(); + std::unique_ptr g_msg_dialog; MsgDialogInstance::MsgDialogInstance() @@ -24,7 +24,7 @@ void MsgDialogInstance::Close() wait_until = get_system_time(); } -s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam) +s32 cellMsgDialogOpen2(u32 type, vm::cptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam) { cellSysutil.Warning("cellMsgDialogOpen2(type=0x%x, msgString=*0x%x, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", type, msgString, callback, userData, extParam); @@ -105,7 +105,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr msgString, vm::ptr msgString, vm::ptrstatus; - Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32 + Emu.GetCallbackManager().Register([=](CPUThread& CPU) -> s32 { - callback(PPU, status, userData); + callback(static_cast(CPU), status, userData); return CELL_OK; }); } @@ -161,7 +158,8 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrDestroy(); g_msg_dialog->state = msgDialogNone; }); - }); + + }).detach(); return CELL_OK; } @@ -293,7 +291,7 @@ s32 cellMsgDialogAbort() return CELL_OK; } -s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msgString) +s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::cptr msgString) { cellSysutil.Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString=*0x%x)", progressBarIndex, msgString); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h index 25c1434fcc..f861c054af 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum { CELL_MSGDIALOG_ERROR_PARAM = 0x8002b301, diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp index 1dcd8a5ed8..1c4b3cb23b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp @@ -21,7 +21,7 @@ struct cellNetCtlInternal cellNetCtlInternal cellNetCtlInstance; -int cellNetCtlInit() +s32 cellNetCtlInit() { cellNetCtl.Log("cellNetCtlInit()"); @@ -33,7 +33,7 @@ int cellNetCtlInit() return CELL_OK; } -int cellNetCtlTerm() +s32 cellNetCtlTerm() { cellNetCtl.Log("cellNetCtlTerm()"); @@ -45,9 +45,9 @@ int cellNetCtlTerm() return CELL_OK; } -int cellNetCtlGetState(vm::ptr state) +s32 cellNetCtlGetState(vm::ptr state) { - cellNetCtl.Log("cellNetCtlGetState(state_addr=0x%x)", state.addr()); + cellNetCtl.Log("cellNetCtlGetState(state=*0x%x)", state); if (Ini.NETStatus.GetValue() == 0) { @@ -69,23 +69,23 @@ int cellNetCtlGetState(vm::ptr state) return CELL_OK; } -int cellNetCtlAddHandler(vm::ptr handler, vm::ptr arg, vm::ptr hid) +s32 cellNetCtlAddHandler(vm::ptr handler, vm::ptr arg, vm::ptr hid) { - cellNetCtl.Todo("cellNetCtlAddHandler(handler_addr=0x%x, arg_addr=0x%x, hid_addr=0x%x)", handler.addr(), arg.addr(), hid.addr()); + cellNetCtl.Todo("cellNetCtlAddHandler(handler=*0x%x, arg=*0x%x, hid=*0x%x)", handler, arg, hid); return CELL_OK; } -int cellNetCtlDelHandler(s32 hid) +s32 cellNetCtlDelHandler(s32 hid) { cellNetCtl.Todo("cellNetCtlDelHandler(hid=0x%x)", hid); return CELL_OK; } -int cellNetCtlGetInfo(s32 code, vm::ptr info) +s32 cellNetCtlGetInfo(s32 code, vm::ptr info) { - cellNetCtl.Todo("cellNetCtlGetInfo(code=0x%x, info_addr=0x%x)", code, info.addr()); + cellNetCtl.Todo("cellNetCtlGetInfo(code=0x%x, info=*0x%x)", code, info); if (code == CELL_NET_CTL_INFO_IP_ADDRESS) { @@ -95,9 +95,9 @@ int cellNetCtlGetInfo(s32 code, vm::ptr info) return CELL_OK; } -int cellNetCtlNetStartDialogLoadAsync(vm::ptr param) +s32 cellNetCtlNetStartDialogLoadAsync(vm::ptr param) { - cellNetCtl.Warning("cellNetCtlNetStartDialogLoadAsync(param_addr=0x%x)", param.addr()); + cellNetCtl.Warning("cellNetCtlNetStartDialogLoadAsync(param=*0x%x)", param); // TODO: Actually sign into PSN or an emulated network similar to PSN sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); @@ -105,25 +105,25 @@ int cellNetCtlNetStartDialogLoadAsync(vm::ptr par return CELL_OK; } -int cellNetCtlNetStartDialogAbortAsync() +s32 cellNetCtlNetStartDialogAbortAsync() { cellNetCtl.Todo("cellNetCtlNetStartDialogAbortAsync()"); return CELL_OK; } -int cellNetCtlNetStartDialogUnloadAsync(vm::ptr result) +s32 cellNetCtlNetStartDialogUnloadAsync(vm::ptr result) { - cellNetCtl.Warning("cellNetCtlNetStartDialogUnloadAsync(result_addr=0x%x)", result.addr()); + cellNetCtl.Warning("cellNetCtlNetStartDialogUnloadAsync(result=*0x%x)", result); sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0); return CELL_OK; } -int cellNetCtlGetNatInfo(vm::ptr natInfo) +s32 cellNetCtlGetNatInfo(vm::ptr natInfo) { - cellNetCtl.Todo("cellNetCtlGetNatInfo(natInfo_addr=0x%x)", natInfo.addr()); + cellNetCtl.Todo("cellNetCtlGetNatInfo(natInfo=*0x%x)", natInfo); if (natInfo->size == 0) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h index 3b3b0db019..adf5f172d5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp b/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp index 0c9c779f6a..500c053db2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp @@ -2,6 +2,8 @@ #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" +namespace vm { using namespace ps3; } + extern Module cellOvis; // Return Codes @@ -12,25 +14,25 @@ enum CELL_OVIS_ERROR_ALIGN = 0x80410410, }; -int cellOvisGetOverlayTableSize(vm::ptr elf) +s32 cellOvisGetOverlayTableSize(vm::cptr elf) { - cellOvis.Todo("cellOvisGetOverlayTableSize(elf_addr=0x%x)", elf.addr()); + cellOvis.Todo("cellOvisGetOverlayTableSize(elf=*0x%x)", elf); return CELL_OK; } -int cellOvisInitializeOverlayTable() +s32 cellOvisInitializeOverlayTable() { UNIMPLEMENTED_FUNC(cellOvis); return CELL_OK; } -int cellOvisFixSpuSegments() +s32 cellOvisFixSpuSegments() { UNIMPLEMENTED_FUNC(cellOvis); return CELL_OK; } -int cellOvisInvalidateOverlappedSegments() +s32 cellOvisInvalidateOverlappedSegments() { UNIMPLEMENTED_FUNC(cellOvis); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPad.cpp b/rpcs3/Emu/SysCalls/Modules/cellPad.cpp index 7b09ba37d7..6f84a61b73 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPad.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPad.cpp @@ -72,10 +72,10 @@ s32 cellPadClearBuf(u32 port_no) s32 cellPadPeriphGetInfo(vm::ptr info) { - sys_io.Warning("cellPadPeriphGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Warning("cellPadPeriphGetInfo(info=*0x%x)", info); // TODO: Support other types of controllers - for (int i = 0; i < info->now_connect; i++) + for (u32 i = 0; i < info->now_connect; i++) { info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD; } @@ -85,7 +85,7 @@ s32 cellPadPeriphGetInfo(vm::ptr info) s32 cellPadGetData(u32 port_no, vm::ptr data) { - sys_io.Log("cellPadGetData(port_no=%d, data_addr=0x%x)", port_no, data.addr()); + sys_io.Log("cellPadGetData(port_no=%d, data=*0x%x)", port_no, data); std::vector& pads = Emu.GetPadManager().GetPads(); @@ -262,9 +262,9 @@ s32 cellPadGetData(u32 port_no, vm::ptr data) return CELL_OK; } -s32 cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr) +s32 cellPadGetDataExtra(u32 port_no, vm::ptr device_type, vm::ptr data) { - sys_io.Log("cellPadGetDataExtra(port_no=%d, device_type_addr=0x%x, device_type_addr=0x%x)", port_no, device_type_addr, data_addr); + sys_io.Log("cellPadGetDataExtra(port_no=%d, device_type=*0x%x, device_type=*0x%x)", port_no, device_type, data); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; @@ -279,9 +279,9 @@ s32 cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr) return CELL_OK; } -s32 cellPadSetActDirect(u32 port_no, u32 param_addr) +s32 cellPadSetActDirect(u32 port_no, vm::ptr param) { - sys_io.Log("cellPadSetActDirect(port_no=%d, param_addr=0x%x)", port_no, param_addr); + sys_io.Log("cellPadSetActDirect(port_no=%d, param=*0x%x)", port_no, param); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; @@ -298,7 +298,7 @@ s32 cellPadSetActDirect(u32 port_no, u32 param_addr) s32 cellPadGetInfo(vm::ptr info) { - sys_io.Log("cellPadGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Log("cellPadGetInfo(info=*0x%x)", info); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; @@ -327,7 +327,7 @@ s32 cellPadGetInfo(vm::ptr info) s32 cellPadGetInfo2(vm::ptr info) { - sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info.addr()); + sys_io.Log("cellPadGetInfo2(info=*0x%x)", info); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; @@ -498,7 +498,7 @@ s32 cellPadLddRegisterController() s32 cellPadLddDataInsert(s32 handle, vm::ptr data) { - sys_io.Todo("cellPadLddDataInsert(handle=%d, data_addr=0x%x)", handle, data.addr()); + sys_io.Todo("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPad.h b/rpcs3/Emu/SysCalls/Modules/cellPad.h index c87a6c8dc5..c189c791f8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPad.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPad.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum CELL_PAD_ERROR_CODE { CELL_PAD_ERROR_FATAL = 0x80121101, @@ -69,18 +71,3 @@ struct CellCapabilityInfo { be_t info[CELL_PAD_MAX_CAPABILITY_INFO]; }; - -int cellPadInit(u32 max_connect); -int cellPadEnd(); -int cellPadClearBuf(u32 port_no); -int cellPadGetData(u32 port_no, vm::ptr data); -int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr); -int cellPadSetActDirect(u32 port_no, u32 param_addr); -int cellPadGetInfo(vm::ptr info); -int cellPadGetInfo2(vm::ptr info); -int cellPadGetCapabilityInfo(u32 port_no, vm::ptr info); -int cellPadSetPortSetting(u32 port_no, u32 port_setting); -int cellPadInfoPressMode(u32 port_no); -int cellPadInfoSensorMode(u32 port_no); -int cellPadSetPressMode(u32 port_no, u32 mode); -int cellPadSetSensorMode(u32 port_no, u32 mode); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index 22ad3eb8e8..b08b31ccc5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -173,7 +173,7 @@ u8 pamfGetStreamChannel(vm::ptr pSelf, u32 stream) s32 cellPamfGetHeaderSize(vm::ptr pAddr, u64 fileSize, vm::ptr pSize) { - cellPamf.Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)", pAddr.addr(), fileSize, pSize.addr()); + cellPamf.Warning("cellPamfGetHeaderSize(pAddr=*0x%x, fileSize=0x%llx, pSize=*0x%x)", pAddr, fileSize, pSize); //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -184,7 +184,7 @@ s32 cellPamfGetHeaderSize(vm::ptr pAddr, u64 fileSize, vm::ptr s32 cellPamfGetHeaderSize2(vm::ptr pAddr, u64 fileSize, u32 attribute, vm::ptr pSize) { - cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, attribute, pSize.addr()); + cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=*0x%x, fileSize=0x%llx, attribute=0x%x, pSize=*0x%x)", pAddr, fileSize, attribute, pSize); //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -195,7 +195,7 @@ s32 cellPamfGetHeaderSize2(vm::ptr pAddr, u64 fileSize, u32 attribut s32 cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm::ptr pOffset, vm::ptr pSize) { - cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, pOffset.addr(), pSize.addr()); + cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=*0x%x, fileSize=0x%llx, pOffset=*0x%x, pSize=*0x%x)", pAddr, fileSize, pOffset, pSize); //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -208,15 +208,15 @@ s32 cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm:: s32 cellPamfVerify(vm::ptr pAddr, u64 fileSize) { - cellPamf.Todo("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.addr(), fileSize); + cellPamf.Todo("cellPamfVerify(pAddr=*0x%x, fileSize=0x%llx)", pAddr, fileSize); // TODO return CELL_OK; } -s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pAddr, u64 fileSize, u32 attribute) +s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::cptr pAddr, u64 fileSize, u32 attribute) { - cellPamf.Warning("cellPamfReaderInitialize(pSelf=0x%x, pAddr=0x%x, fileSize=%d, attribute=0x%x)", pSelf.addr(), pAddr.addr(), fileSize, attribute); + cellPamf.Warning("cellPamfReaderInitialize(pSelf=*0x%x, pAddr=*0x%x, fileSize=0x%llx, attribute=0x%x)", pSelf, pAddr, fileSize, attribute); if (fileSize) { @@ -240,7 +240,7 @@ s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pSelf, vm::ptr pTimeStamp) { - cellPamf.Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); + cellPamf.Warning("cellPamfReaderGetPresentationStartTime(pSelf=*0x%x, pTimeStamp=*0x%x)", pSelf, pTimeStamp); // always returns CELL_OK @@ -251,7 +251,7 @@ s32 cellPamfReaderGetPresentationStartTime(vm::ptr pSelf, vm::pt s32 cellPamfReaderGetPresentationEndTime(vm::ptr pSelf, vm::ptr pTimeStamp) { - cellPamf.Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); + cellPamf.Warning("cellPamfReaderGetPresentationEndTime(pSelf=*0x%x, pTimeStamp=*0x%x)", pSelf, pTimeStamp); // always returns CELL_OK @@ -262,7 +262,7 @@ s32 cellPamfReaderGetPresentationEndTime(vm::ptr pSelf, vm::ptr< u32 cellPamfReaderGetMuxRateBound(vm::ptr pSelf) { - cellPamf.Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.addr()); + cellPamf.Warning("cellPamfReaderGetMuxRateBound(pSelf=*0x%x)", pSelf); // cannot return error code return pSelf->pAddr->mux_rate_max; @@ -270,7 +270,7 @@ u32 cellPamfReaderGetMuxRateBound(vm::ptr pSelf) u8 cellPamfReaderGetNumberOfStreams(vm::ptr pSelf) { - cellPamf.Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.addr()); + cellPamf.Warning("cellPamfReaderGetNumberOfStreams(pSelf=*0x%x)", pSelf); // cannot return error code return pSelf->pAddr->stream_count; @@ -278,7 +278,7 @@ u8 cellPamfReaderGetNumberOfStreams(vm::ptr pSelf) u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 streamType) { - cellPamf.Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)", pSelf.addr(), streamType); + cellPamf.Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=*0x%x, streamType=%d)", pSelf, streamType); // cannot return error code @@ -319,7 +319,7 @@ u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 st s32 cellPamfReaderSetStreamWithIndex(vm::ptr pSelf, u8 streamIndex) { - cellPamf.Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)", pSelf.addr(), streamIndex); + cellPamf.Warning("cellPamfReaderSetStreamWithIndex(pSelf=*0x%x, streamIndex=%d)", pSelf, streamIndex); if (streamIndex >= pSelf->pAddr->stream_count) { @@ -332,7 +332,7 @@ s32 cellPamfReaderSetStreamWithIndex(vm::ptr pSelf, u8 streamInd s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 streamType, u8 ch) { - cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)", pSelf.addr(), streamType, ch); + cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=*0x%x, streamType=%d, ch=%d)", pSelf, streamType, ch); // it probably doesn't support "any audio" or "any video" argument if (streamType > 5 || ch >= 16) @@ -359,7 +359,7 @@ s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 streamType, u8 streamIndex) { - cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)", pSelf.addr(), streamType, streamIndex); + cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=*0x%x, streamType=%d, streamIndex=%d)", pSelf, streamType, streamIndex); u32 found = 0; @@ -412,7 +412,7 @@ s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 st s32 cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr pEsFilterId) { - cellPamf.Warning("cellPamfStreamTypeToEsFilterId(type=%d, ch=%d, pEsFilterId_addr=0x%x)", type, ch, pEsFilterId.addr()); + cellPamf.Warning("cellPamfStreamTypeToEsFilterId(type=%d, ch=%d, pEsFilterId=*0x%x)", type, ch, pEsFilterId); if (!pEsFilterId) { @@ -424,7 +424,7 @@ s32 cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr s32 cellPamfReaderGetStreamIndex(vm::ptr pSelf) { - cellPamf.Log("cellPamfReaderGetStreamIndex(pSelf=0x%x)", pSelf.addr()); + cellPamf.Log("cellPamfReaderGetStreamIndex(pSelf=*0x%x)", pSelf); // seems that CELL_PAMF_ERROR_INVALID_PAMF must be already written in pSelf->stream if it's the case return pSelf->stream; @@ -432,8 +432,7 @@ s32 cellPamfReaderGetStreamIndex(vm::ptr pSelf) s32 cellPamfReaderGetStreamTypeAndChannel(vm::ptr pSelf, vm::ptr pType, vm::ptr pCh) { - cellPamf.Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=0x%x (stream=%d), pType_addr=0x%x, pCh_addr=0x%x", - pSelf.addr(), pSelf->stream, pType.addr(), pCh.addr()); + cellPamf.Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=*0x%x, pType=*0x%x, pCh=*0x%x", pSelf, pType, pCh); // unclear @@ -444,7 +443,7 @@ s32 cellPamfReaderGetStreamTypeAndChannel(vm::ptr pSelf, vm::ptr s32 cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptr pEsFilterId) { - cellPamf.Warning("cellPamfReaderGetEsFilterId(pSelf=0x%x (stream=%d), pEsFilterId_addr=0x%x)", pSelf.addr(), pSelf->stream, pEsFilterId.addr()); + cellPamf.Warning("cellPamfReaderGetEsFilterId(pSelf=*0x%x, pEsFilterId=*0x%x)", pSelf, pEsFilterId); // always returns CELL_OK @@ -457,9 +456,9 @@ s32 cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptr pSelf, u32 pInfo_addr, u32 size) +s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, vm::ptr pInfo, u32 size) { - cellPamf.Warning("cellPamfReaderGetStreamInfo(pSelf=0x%x, stream=%d, pInfo_addr=0x%x, size=%d)", pSelf.addr(), pSelf->stream, pInfo_addr, size); + cellPamf.Warning("cellPamfReaderGetStreamInfo(pSelf=*0x%x, pInfo_addr=0x%x, size=%d)", pSelf, pInfo, size); assert((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; @@ -475,7 +474,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - auto info = vm::ptr::make(pInfo_addr); + auto info = vm::static_ptr_cast(pInfo); info->profileIdc = header.AVC.profileIdc; info->levelIdc = header.AVC.levelIdc; @@ -486,8 +485,8 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u if (header.AVC.aspectRatioIdc == 0xff) { - info->sarWidth = header.AVC.sarWidth; - info->sarHeight = header.AVC.sarHeight; + info->sarWidth = header.AVC.sarInfo.width; + info->sarHeight = header.AVC.sarInfo.height; } else { @@ -536,7 +535,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - auto info = vm::ptr::make(pInfo_addr); + auto info = vm::static_ptr_cast(pInfo); switch (header.M2V.x0) { @@ -594,7 +593,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - auto info = vm::ptr::make(pInfo_addr); + auto info = vm::static_ptr_cast(pInfo); info->samplingFrequency = header.audio.freq & 0xf; info->numberOfChannels = header.audio.channels & 0xf; @@ -610,7 +609,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - auto info = vm::ptr::make(pInfo_addr); + auto info = vm::static_ptr_cast(pInfo); info->samplingFrequency = header.audio.freq & 0xf; info->numberOfChannels = header.audio.channels & 0xf; @@ -627,7 +626,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - auto info = vm::ptr::make(pInfo_addr); + auto info = vm::static_ptr_cast(pInfo); info->samplingFrequency = header.audio.freq & 0xf; info->numberOfChannels = header.audio.channels & 0xf; @@ -694,7 +693,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u u32 cellPamfReaderGetNumberOfEp(vm::ptr pSelf) { - cellPamf.Todo("cellPamfReaderGetNumberOfEp(pSelf=0x%x, stream=%d)", pSelf.addr(), pSelf->stream); + cellPamf.Todo("cellPamfReaderGetNumberOfEp(pSelf=*0x%x)", pSelf); // cannot return error code return 0; //pSelf->pAddr->stream_headers[pSelf->stream].ep_num; @@ -702,7 +701,7 @@ u32 cellPamfReaderGetNumberOfEp(vm::ptr pSelf) s32 cellPamfReaderGetEpIteratorWithIndex(vm::ptr pSelf, u32 epIndex, vm::ptr pIt) { - cellPamf.Todo("cellPamfReaderGetEpIteratorWithIndex(pSelf=0x%x, stream=%d, epIndex=%d, pIt_addr=0x%x)", pSelf.addr(), pSelf->stream, epIndex, pIt.addr()); + cellPamf.Todo("cellPamfReaderGetEpIteratorWithIndex(pSelf=*0x%x, epIndex=%d, pIt=*0x%x)", pSelf, epIndex, pIt); // TODO return CELL_OK; @@ -710,7 +709,7 @@ s32 cellPamfReaderGetEpIteratorWithIndex(vm::ptr pSelf, u32 epIn s32 cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr pSelf, vm::ptr pTimeStamp, vm::ptr pIt) { - cellPamf.Todo("cellPamfReaderGetEpIteratorWithTimeStamp(pSelf=0x%x, pTimeStamp_addr=0x%x, pIt_addr=0x%x)", pSelf.addr(), pTimeStamp.addr(), pIt.addr()); + cellPamf.Todo("cellPamfReaderGetEpIteratorWithTimeStamp(pSelf=*0x%x, pTimeStamp=*0x%x, pIt=*0x%x)", pSelf, pTimeStamp, pIt); // TODO return CELL_OK; @@ -718,7 +717,7 @@ s32 cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr pSelf, vm:: s32 cellPamfEpIteratorGetEp(vm::ptr pIt, vm::ptr pEp) { - cellPamf.Todo("cellPamfEpIteratorGetEp(pIt_addr=0x%x, pEp_addr=0x%x)", pIt.addr(), pEp.addr()); + cellPamf.Todo("cellPamfEpIteratorGetEp(pIt=*0x%x, pEp=*0x%x)", pIt, pEp); // always returns CELL_OK // TODO @@ -727,7 +726,7 @@ s32 cellPamfEpIteratorGetEp(vm::ptr pIt, vm::ptr s32 cellPamfEpIteratorMove(vm::ptr pIt, s32 steps, vm::ptr pEp) { - cellPamf.Todo("cellPamfEpIteratorMove(pIt_addr=0x%x, steps=%d, pEp_addr=0x%x)", pIt.addr(), steps, pEp.addr()); + cellPamf.Todo("cellPamfEpIteratorMove(pIt=*0x%x, steps=%d, pEp=*0x%x)", pIt, steps, pEp); // cannot return error code // TODO diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.h b/rpcs3/Emu/SysCalls/Modules/cellPamf.h index 33904beb97..d919b491ea 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -198,7 +200,7 @@ struct CellPamfAvcInfo u8 maxMeanBitrate; }; -static_assert(sizeof(CellPamfAvcInfo) == 0x20, "Invalid CellPamfAvcInfo size"); +CHECK_SIZE(CellPamfAvcInfo, 0x20); // M2V (MPEG2 Video) Specific Information struct CellPamfM2vInfo @@ -221,7 +223,7 @@ struct CellPamfM2vInfo u8 matrixCoefficients; }; -static_assert(sizeof(CellPamfM2vInfo) == 0x18, "Invalid CellPamfM2vInfo size"); +CHECK_SIZE(CellPamfM2vInfo, 0x18); // ATRAC3+ Audio Specific Information struct CellPamfAtrac3plusInfo @@ -230,7 +232,7 @@ struct CellPamfAtrac3plusInfo u8 numberOfChannels; }; -static_assert(sizeof(CellPamfAtrac3plusInfo) == 8, "Invalid CellPamfAtrac3plusInfo size"); +CHECK_SIZE(CellPamfAtrac3plusInfo, 8); // AC3 Audio Specific Information struct CellPamfAc3Info @@ -239,7 +241,7 @@ struct CellPamfAc3Info u8 numberOfChannels; }; -static_assert(sizeof(CellPamfAc3Info) == 8, "Invalid CellPamfAc3Info size"); +CHECK_SIZE(CellPamfAc3Info, 8); // LPCM Audio Specific Information struct CellPamfLpcmInfo @@ -282,13 +284,16 @@ struct PamfStreamHeader be_t frameCropRightOffset; be_t frameCropTopOffset; be_t frameCropBottomOffset; + union { struct { - be_t sarWidth; - be_t sarHeight; - }; + be_t width; + be_t height; + } + sarInfo; + struct { u8 x14; // contains videoFormat and videoFullRangeFlag @@ -297,10 +302,11 @@ struct PamfStreamHeader u8 matrixCoefficients; }; }; + u8 x18; // contains entropyCodingModeFlag, deblockingFilterFlag, minNumSlicePerPictureIdc, nfwIdc u8 maxMeanBitrate; - - } AVC; + } + AVC; // M2V specific information struct @@ -320,8 +326,8 @@ struct PamfStreamHeader u8 colourPrimaries; u8 transferCharacteristics; u8 matrixCoefficients; - - } M2V; + } + M2V; // Audio specific information struct @@ -330,12 +336,12 @@ struct PamfStreamHeader u8 channels; // number of channels (1, 2, 6, 8) u8 freq; // 1 (always 48000) u8 bps; // LPCM only - - } audio; + } + audio; }; }; -static_assert(sizeof(PamfStreamHeader) == 48, "Invalid PamfStreamHeader size"); +CHECK_SIZE(PamfStreamHeader, 48); struct PamfHeader { @@ -377,19 +383,19 @@ struct PamfEpHeader be_t rpnOffset; }; -static_assert(sizeof(PamfEpHeader) == 12, "Invalid PamfEpHeader size"); +CHECK_SIZE(PamfEpHeader, 12); #pragma pack(pop) // not directly accessed by virtual CPU, fields are unknown struct CellPamfReader { - vm::ptr pAddr; + vm::cptr pAddr; s32 stream; u64 fileSize; u32 internalData[28]; }; -static_assert(sizeof(CellPamfReader) == 128, "Invalid CellPamfReader size"); +CHECK_SIZE(CellPamfReader, 128); -s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pAddr, u64 fileSize, u32 attribute); \ No newline at end of file +s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::cptr pAddr, u64 fileSize, u32 attribute); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPng.h b/rpcs3/Emu/SysCalls/Modules/cellPng.h index 3237fcd869..9066aee992 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPng.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPng.h @@ -1,6 +1,8 @@ #pragma once -enum CellPngTxtType +namespace vm { using namespace ps3; } + +enum CellPngTxtType : s32 { CELL_PNG_TEXT = 0, CELL_PNG_ZTXT = 1, @@ -31,7 +33,7 @@ struct CellPngSPLTentry be_t paletteEntriesNumber; }; -enum CellPngUnknownLocation +enum CellPngUnknownLocation : s32 { CELL_PNG_BEFORE_PLTE = 1, CELL_PNG_BEFORE_IDAT = 2, @@ -40,7 +42,7 @@ enum CellPngUnknownLocation struct CellPngTextInfo { - be_t txtType; + be_t txtType; // CellPngTxtType vm::bptr keyword; vm::bptr text; be_t textLength; @@ -170,5 +172,5 @@ struct CellPngUnknownChunk char chunkType[5]; vm::bptr chunkData; be_t length; - be_t location; + be_t location; // CellPngUnknownLocation }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index c6180006a1..2ae0411a9e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -19,8 +19,8 @@ extern Module cellPngDec; s32 pngDecCreate( vm::ptr mainHandle, - vm::ptr param, - vm::ptr ext = vm::null) + vm::cptr param, + vm::cptr ext = vm::null) { // alloc memory (should probably use param->cbCtrlMallocFunc) auto dec = CellPngDecMainHandle::make(Memory.Alloc(sizeof(PngDecoder), 128)); @@ -59,10 +59,10 @@ s32 pngDecDestroy(CellPngDecMainHandle dec) s32 pngDecOpen( CellPngDecMainHandle dec, vm::ptr subHandle, - vm::ptr src, + vm::cptr src, vm::ptr openInfo, - vm::ptr cb = vm::null, - vm::ptr param = vm::null) + vm::cptr cb = vm::null, + vm::cptr param = vm::null) { // alloc memory (should probably use dec->malloc) auto stream = CellPngDecSubHandle::make(Memory.Alloc(sizeof(PngStream), 128)); @@ -76,13 +76,13 @@ s32 pngDecOpen( stream->fd = 0; stream->src = *src; - switch (src->srcSelect.data()) + switch (src->srcSelect.value()) { - case se32(CELL_PNGDEC_BUFFER): + case CELL_PNGDEC_BUFFER: stream->fileSize = src->streamSize; break; - case se32(CELL_PNGDEC_FILE): + case CELL_PNGDEC_FILE: { // Get file descriptor and size std::shared_ptr file_s(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); @@ -137,27 +137,26 @@ s32 pngReadHeader( return CELL_PNGDEC_ERROR_HEADER; // The file is smaller than the length of a PNG header } - //Write the header to buffer - vm::var buffer; // Alloc buffer for PNG header - auto buffer_32 = buffer.To>(); + // Write the header to buffer + u8 buffer[34]; be_t* buffer_32 = reinterpret_cast*>(buffer); - switch (stream->src.srcSelect.data()) + switch (stream->src.srcSelect.value()) { - case se32(CELL_PNGDEC_BUFFER): - memmove(buffer.begin(), stream->src.streamPtr.get_ptr(), buffer.size()); + case CELL_PNGDEC_BUFFER: + std::memcpy(buffer, stream->src.streamPtr.get_ptr(), sizeof(buffer)); break; - case se32(CELL_PNGDEC_FILE): + case CELL_PNGDEC_FILE: { auto file = Emu.GetIdManager().get(stream->fd); file->file->Seek(0); - file->file->Read(buffer.begin(), buffer.size()); + file->file->Read(buffer, sizeof(buffer)); break; } } - if (buffer_32[0].data() != se32(0x89504E47) || - buffer_32[1].data() != se32(0x0D0A1A0A) || // Error: The first 8 bytes are not a valid PNG signature - buffer_32[3].data() != se32(0x49484452)) // Error: The PNG file does not start with an IHDR chunk + if (buffer_32[0] != 0x89504E47 || + buffer_32[1] != 0x0D0A1A0A || // Error: The first 8 bytes are not a valid PNG signature + buffer_32[3] != 0x49484452) // Error: The PNG file does not start with an IHDR chunk { return CELL_PNGDEC_ERROR_HEADER; } @@ -192,9 +191,9 @@ s32 pngReadHeader( s32 pngDecSetParameter( CellPngDecSubHandle stream, - vm::ptr inParam, + vm::cptr inParam, vm::ptr outParam, - vm::ptr extInParam = vm::null, + vm::cptr extInParam = vm::null, vm::ptr extOutParam = vm::null) { CellPngDecInfo& current_info = stream->info; @@ -205,20 +204,20 @@ s32 pngDecSetParameter( current_outParam.outputHeight = current_info.imageHeight; current_outParam.outputColorSpace = inParam->outputColorSpace; - switch (current_outParam.outputColorSpace.data()) + switch (current_outParam.outputColorSpace.value()) { - case se32(CELL_PNGDEC_PALETTE): - case se32(CELL_PNGDEC_GRAYSCALE): + case CELL_PNGDEC_PALETTE: + case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; break; - case se32(CELL_PNGDEC_GRAYSCALE_ALPHA): + case CELL_PNGDEC_GRAYSCALE_ALPHA: current_outParam.outputComponents = 2; break; - case se32(CELL_PNGDEC_RGB): + case CELL_PNGDEC_RGB: current_outParam.outputComponents = 3; break; - case se32(CELL_PNGDEC_RGBA): - case se32(CELL_PNGDEC_ARGB): + case CELL_PNGDEC_RGBA: + case CELL_PNGDEC_ARGB: current_outParam.outputComponents = 4; break; default: @@ -238,9 +237,9 @@ s32 pngDecSetParameter( s32 pngDecodeData( CellPngDecSubHandle stream, vm::ptr data, - vm::ptr dataCtrlParam, + vm::cptr dataCtrlParam, vm::ptr dataOutInfo, - vm::ptr cbCtrlDisp = vm::null, + vm::cptr cbCtrlDisp = vm::null, vm::ptr dispParam = vm::null) { dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP; @@ -249,20 +248,20 @@ s32 pngDecodeData( const u64& fileSize = stream->fileSize; const CellPngDecOutParam& current_outParam = stream->outParam; - //Copy the PNG file to a buffer - vm::var png((u32)fileSize); + // Copy the PNG file to a buffer + std::unique_ptr png(new u8[fileSize]); - switch (stream->src.srcSelect.data()) + switch (stream->src.srcSelect.value()) { - case se32(CELL_PNGDEC_BUFFER): - memmove(png.begin(), stream->src.streamPtr.get_ptr(), png.size()); + case CELL_PNGDEC_BUFFER: + std::memcpy(png.get(), stream->src.streamPtr.get_ptr(), fileSize); break; - case se32(CELL_PNGDEC_FILE): + case CELL_PNGDEC_FILE: { auto file = Emu.GetIdManager().get(stream->fd); file->file->Seek(0); - file->file->Read(png.ptr(), png.size()); + file->file->Read(png.get(), fileSize); break; } } @@ -271,7 +270,7 @@ s32 pngDecodeData( int width, height, actual_components; auto image = std::unique_ptr ( - stbi_load_from_memory(png.ptr(), (s32)fileSize, &width, &height, &actual_components, 4), + stbi_load_from_memory(png.get(), (s32)fileSize, &width, &height, &actual_components, 4), &::free ); if (!image) @@ -284,10 +283,10 @@ s32 pngDecodeData( const int bytesPerLine = (u32)dataCtrlParam->outputBytesPerLine; uint image_size = width * height; - switch (current_outParam.outputColorSpace.data()) + switch (current_outParam.outputColorSpace.value()) { - case se32(CELL_PNGDEC_RGB): - case se32(CELL_PNGDEC_RGBA): + case CELL_PNGDEC_RGB: + case CELL_PNGDEC_RGBA: { const char nComponents = current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 3; image_size *= nComponents; @@ -308,7 +307,7 @@ s32 pngDecodeData( break; } - case se32(CELL_PNGDEC_ARGB): + case CELL_PNGDEC_ARGB: { const int nComponents = 4; image_size *= nComponents; @@ -350,9 +349,9 @@ s32 pngDecodeData( break; } - case se32(CELL_PNGDEC_GRAYSCALE): - case se32(CELL_PNGDEC_PALETTE): - case se32(CELL_PNGDEC_GRAYSCALE_ALPHA): + case CELL_PNGDEC_GRAYSCALE: + case CELL_PNGDEC_PALETTE: + case CELL_PNGDEC_GRAYSCALE_ALPHA: cellPngDec.Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); break; @@ -368,7 +367,7 @@ s32 pngDecodeData( s32 cellPngDecCreate( vm::ptr mainHandle, - vm::ptr threadInParam, + vm::cptr threadInParam, vm::ptr threadOutParam) { cellPngDec.Warning("cellPngDecCreate(mainHandle=**0x%x, threadInParam=*0x%x, threadOutParam=*0x%x)", mainHandle, threadInParam, threadOutParam); @@ -384,9 +383,9 @@ s32 cellPngDecCreate( s32 cellPngDecExtCreate( vm::ptr mainHandle, - vm::ptr threadInParam, + vm::cptr threadInParam, vm::ptr threadOutParam, - vm::ptr extThreadInParam, + vm::cptr extThreadInParam, vm::ptr extThreadOutParam) { cellPngDec.Warning("cellPngDecCreate(mainHandle=**0x%x, threadInParam=*0x%x, threadOutParam=*0x%x, extThreadInParam=*0x%x, extThreadOutParam=*0x%x)", @@ -414,7 +413,7 @@ s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle) s32 cellPngDecOpen( CellPngDecMainHandle mainHandle, vm::ptr subHandle, - vm::ptr src, + vm::cptr src, vm::ptr openInfo) { cellPngDec.Warning("cellPngDecOpen(mainHandle=*0x%x, subHandle=**0x%x, src=*0x%x, openInfo=*0x%x)", mainHandle, subHandle, src, openInfo); @@ -426,10 +425,10 @@ s32 cellPngDecOpen( s32 cellPngDecExtOpen( CellPngDecMainHandle mainHandle, vm::ptr subHandle, - vm::ptr src, + vm::cptr src, vm::ptr openInfo, - vm::ptr cbCtrlStrm, - vm::ptr opnParam) + vm::cptr cbCtrlStrm, + vm::cptr opnParam) { cellPngDec.Warning("cellPngDecExtOpen(mainHandle=*0x%x, subHandle=**0x%x, src=*0x%x, openInfo=*0x%x, cbCtrlStrm=*0x%x, opnParam=*0x%x)", mainHandle, subHandle, src, openInfo, cbCtrlStrm, opnParam); @@ -465,7 +464,7 @@ s32 cellPngDecExtReadHeader( s32 cellPngDecSetParameter( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, - vm::ptr inParam, + vm::cptr inParam, vm::ptr outParam) { cellPngDec.Warning("cellPngDecSetParameter(mainHandle=*0x%x, subHandle=*0x%x, inParam=*0x%x, outParam=*0x%x)", mainHandle, subHandle, inParam, outParam); @@ -476,9 +475,9 @@ s32 cellPngDecSetParameter( s32 cellPngDecExtSetParameter( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, - vm::ptr inParam, + vm::cptr inParam, vm::ptr outParam, - vm::ptr extInParam, + vm::cptr extInParam, vm::ptr extOutParam) { cellPngDec.Warning("cellPngDecExtSetParameter(mainHandle=*0x%x, subHandle=*0x%x, inParam=*0x%x, outParam=*0x%x, extInParam=*0x%x, extOutParam=*0x%x", mainHandle, subHandle, inParam, outParam, extInParam, extOutParam); @@ -490,7 +489,7 @@ s32 cellPngDecDecodeData( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr data, - vm::ptr dataCtrlParam, + vm::cptr dataCtrlParam, vm::ptr dataOutInfo) { cellPngDec.Warning("cellPngDecDecodeData(mainHandle=*0x%x, subHandle=*0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x)", @@ -503,9 +502,9 @@ s32 cellPngDecExtDecodeData( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr data, - vm::ptr dataCtrlParam, + vm::cptr dataCtrlParam, vm::ptr dataOutInfo, - vm::ptr cbCtrlDisp, + vm::cptr cbCtrlDisp, vm::ptr dispParam) { cellPngDec.Warning("cellPngDecExtDecodeData(mainHandle=*0x%x, subHandle=*0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x, cbCtrlDisp=*0x%x, dispParam=*0x%x)", diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h index 037019fe65..9606576d2f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -1,4 +1,7 @@ #pragma once + +namespace vm { using namespace ps3; } + #include "cellPng.h" enum : u32 @@ -120,7 +123,7 @@ struct CellPngDecExtThreadOutParam struct CellPngDecSrc { be_t srcSelect; // CellPngDecStreamSrcSel - vm::bptr fileName; + vm::bcptr fileName; be_t fileOffset; be_t fileSize; vm::bptr streamPtr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 3cda3208f7..ac2b403f04 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -6,6 +6,7 @@ #include "cellSysutil.h" #include "Emu/RSX/sysutil_video.h" #include "Emu/RSX/GSManager.h" +#include "Emu/RSX/GSRender.h" #include "cellResc.h" extern Module cellResc; @@ -16,7 +17,7 @@ extern void cellGcmSetFlipHandler(vm::ptr handler); extern void cellGcmSetVBlankHandler(vm::ptr handler); extern s32 cellGcmAddressToOffset(u32 address, vm::ptr offset); extern s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); -extern s32 cellGcmSetPrepareFlip(vm::ptr ctx, u32 id); +extern s32 cellGcmSetPrepareFlip(PPUThread& CPU, vm::ptr ctx, u32 id); extern s32 cellGcmSetSecondVFrequency(u32 freq); extern u32 cellGcmGetLabelAddress(u8 index); extern u32 cellGcmGetTiledPitchSize(u32 size); @@ -24,7 +25,7 @@ extern u32 cellGcmGetTiledPitchSize(u32 size); CCellRescInternal* s_rescInternalInstance = nullptr; // Local Functions -int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved); +s32 cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved); // Help Functions inline bool IsPal() { return s_rescInternalInstance->m_dstMode == CELL_RESC_720x576; } @@ -43,7 +44,7 @@ inline bool IsGcmFlip() { return (IsNotPal() || (IsPal() && (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_50 || s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_FOR_HSYNC))); } -inline int GetNumColorBuffers(){ return IsPalInterpolate() ? 6 : (IsPalDrop() ? 3 : 2); } +inline s32 GetNumColorBuffers(){ return IsPalInterpolate() ? 6 : (IsPalDrop() ? 3 : 2); } inline bool IsInterlace() { return s_rescInternalInstance->m_initConfig.interlaceMode == CELL_RESC_INTERLACE_FILTER; } inline bool IsTextureNR() { return !IsInterlace(); } @@ -208,7 +209,7 @@ UN_PANSCAN: return; } -inline int InternalVersion(vm::ptr conf) +inline s32 InternalVersion(vm::ptr conf) { switch ((u32)conf->size) { @@ -222,7 +223,7 @@ inline int InternalVersion(vm::ptr conf) } } -inline int InternalVersion() { +inline s32 InternalVersion() { switch ((u32)s_rescInternalInstance->m_initConfig.size) { case 20: @@ -295,7 +296,7 @@ u8 GcmSurfaceFormat2GcmTextureFormat(u8 surfaceFormat, u8 surfaceType) return result; } -int GetRescDestsIndex(u32 dstMode) +s32 GetRescDestsIndex(u32 dstMode) { switch(dstMode) { @@ -334,14 +335,14 @@ void GetScreenSize(u32 mode, s32 *width, s32 *height) } } -int CalculateSurfaceByteSize(u32 mode, CellRescDsts *dsts) +s32 CalculateSurfaceByteSize(u32 mode, CellRescDsts *dsts) { s32 width, height; GetScreenSize(mode, &width, &height); return dsts->pitch * roundup(height, dsts->heightAlign); } -int CalculateMaxColorBuffersSize() +s32 CalculateMaxColorBuffersSize() { s32 oneBufSize, bufNum, totalBufSize, maxBufSize; maxBufSize = 0; @@ -432,7 +433,7 @@ void InitMembers() //s_rescInternalInstance->m_feedback.interval60 = 1; - for (int i = 0; im_rescSrc[i].format = 0; s_rescInternalInstance->m_rescSrc[i].pitch = 0; s_rescInternalInstance->m_rescSrc[i].width = 0; @@ -440,11 +441,11 @@ void InitMembers() s_rescInternalInstance->m_rescSrc[i].offset = 0; } - for (int i = 0; im_dstOffsets[i] = 0; } - for (int i = 0; im_cgParamIndex[i] = 0xFF; } { @@ -567,9 +568,9 @@ void SetupSurfaces(vm::ptr& cntxt) } // Module Functions -int cellRescInit(vm::ptr initConfig) +s32 cellRescInit(vm::ptr initConfig) { - cellResc.Warning("cellRescInit(initConfig_addr=0x%x)", initConfig.addr()); + cellResc.Warning("cellRescInit(initConfig=*0x%x)", initConfig); if (s_rescInternalInstance->m_bInitialized) { @@ -609,7 +610,7 @@ void cellRescExit() if (IsPalInterpolate()) { // TODO: ExitSystemResource() - //int ret = ExitSystemResource(); + //s32 ret = ExitSystemResource(); //if (ret != CELL_OK) //{ // cellResc.Error("failed to clean up system resources.. continue. 0x%x\n", ret); @@ -620,9 +621,9 @@ void cellRescExit() s_rescInternalInstance->m_bInitialized = false; } -int cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr bufferMode) +s32 cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr bufferMode) { - cellResc.Log("cellRescVideoOutResolutionId2RescBufferMode(resolutionId=%d, bufferMode_addr=0x%x)", resolutionId, bufferMode.addr()); + cellResc.Log("cellRescVideoOutResolutionId2RescBufferMode(resolutionId=%d, bufferMode=*0x%x)", resolutionId, bufferMode); switch (resolutionId) { @@ -646,9 +647,9 @@ int cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr b return CELL_OK; } -int cellRescSetDsts(u32 dstsMode, vm::ptr dsts) +s32 cellRescSetDsts(u32 dstsMode, vm::ptr dsts) { - cellResc.Log("cellRescSetDsts(dstsMode=%d, CellRescDsts_addr=0x%x)", dstsMode, dsts.addr()); + cellResc.Log("cellRescSetDsts(dstsMode=%d, dsts=*0x%x)", dstsMode, dsts); if (!s_rescInternalInstance->m_bInitialized) { @@ -713,7 +714,7 @@ void SetFlipHandler(vm::ptr handler) } } -int cellRescSetDisplayMode(u32 displayMode) +s32 cellRescSetDisplayMode(PPUThread& CPU, u32 displayMode) { cellResc.Warning("cellRescSetDisplayMode(displayMode=%d)", displayMode); @@ -764,7 +765,7 @@ int cellRescSetDisplayMode(u32 displayMode) else m_pCFragmentShader = m_pCFragmentShaderArray[RESC_SHADER_DEFAULT_BILINEAR]; }*/ - vm::var videocfg; + vm::stackvar videocfg(CPU); videocfg->resolutionId = RescBufferMode2SysutilResolutionId(s_rescInternalInstance->m_dstMode); videocfg->format = RescDstFormat2SysutilFormat(s_rescInternalInstance->m_pRescDsts->format ); videocfg->aspect = CELL_VIDEO_OUT_ASPECT_AUTO; @@ -774,7 +775,7 @@ int cellRescSetDisplayMode(u32 displayMode) if (IsPalInterpolate()) { - //int ret = InitSystemResource(); + //s32 ret = InitSystemResource(); //if (ret) return ret; //InitLabels(); cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); @@ -803,7 +804,7 @@ int cellRescSetDisplayMode(u32 displayMode) return CELL_OK; } -int cellRescAdjustAspectRatio(float horizontal, float vertical) +s32 cellRescAdjustAspectRatio(float horizontal, float vertical) { cellResc.Warning("cellRescAdjustAspectRatio(horizontal=%f, vertical=%f)", horizontal, vertical); @@ -837,7 +838,7 @@ int cellRescAdjustAspectRatio(float horizontal, float vertical) return CELL_OK; } -int cellRescSetPalInterpolateDropFlexRatio(float ratio) +s32 cellRescSetPalInterpolateDropFlexRatio(float ratio) { cellResc.Warning("cellRescSetPalInterpolateDropFlexRatio(ratio=%f)", ratio); @@ -858,10 +859,9 @@ int cellRescSetPalInterpolateDropFlexRatio(float ratio) return CELL_OK; } -int cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) +s32 cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) { - cellResc.Warning("cellRescGetBufferSize(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", - colorBuffers.addr(), vertexArray.addr(), fragmentShader.addr()); + cellResc.Warning("cellRescGetBufferSize(colorBuffers=*0x%x, vertexArray=*0x%x, fragmentShader=*0x%x)", colorBuffers, vertexArray, fragmentShader); if (!s_rescInternalInstance->m_bInitialized) { @@ -902,7 +902,7 @@ int cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, v return CELL_OK; } -int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved) +s32 cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved) { cellResc.Log("cellRescGetNumColorBuffers(dstMode=%d, palTemporalMode=%d, reserved=%d)", dstMode, palTemporalMode, reserved); @@ -923,9 +923,9 @@ int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved) : 2; } -int cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptr rescSrc) +s32 cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptr rescSrc) { - cellResc.Log("cellRescGcmSurface2RescSrc(gcmSurface_addr=0x%x, rescSrc_addr=0x%x)", gcmSurface.addr(), rescSrc.addr()); + cellResc.Log("cellRescGcmSurface2RescSrc(gcmSurface=*0x%x, rescSrc=*0x%x)", gcmSurface, rescSrc); u8 textureFormat = GcmSurfaceFormat2GcmTextureFormat(gcmSurface->colorFormat, gcmSurface->type); s32 xW = 1, xH = 1; @@ -954,9 +954,9 @@ int cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptr src) +s32 cellRescSetSrc(s32 idx, vm::ptr src) { - cellResc.Log("cellRescSetSrc(idx=0x%x, src_addr=0x%x)", idx, src.addr()); + cellResc.Log("cellRescSetSrc(idx=0x%x, src=*0x%x)", idx, src); if(!s_rescInternalInstance->m_bInitialized) { @@ -983,9 +983,9 @@ int cellRescSetSrc(s32 idx, vm::ptr src) return 0; } -int cellRescSetConvertAndFlip(vm::ptr cntxt, s32 idx) +s32 cellRescSetConvertAndFlip(PPUThread& CPU, vm::ptr cntxt, s32 idx) { - cellResc.Log("cellRescSetConvertAndFlip(cntxt_addr=0x%x, indx=0x%x)", cntxt.addr(), idx); + cellResc.Log("cellRescSetConvertAndFlip(cntxt=*0x%x, idx=0x%x)", cntxt, idx); if(!s_rescInternalInstance->m_bInitialized) { @@ -1016,12 +1016,12 @@ int cellRescSetConvertAndFlip(vm::ptr cntxt, s32 idx) //TODO: ? - cellGcmSetPrepareFlip(cntxt, idx); + cellGcmSetPrepareFlip(CPU, cntxt, idx); return CELL_OK; } -int cellRescSetWaitFlip() +s32 cellRescSetWaitFlip() { cellResc.Log("cellRescSetWaitFlip()"); GSLockCurrent lock(GS_LOCK_WAIT_FLIP); @@ -1029,9 +1029,9 @@ int cellRescSetWaitFlip() return CELL_OK; } -int cellRescSetBufferAddress(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) +s32 cellRescSetBufferAddress(PPUThread& CPU, vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) { - cellResc.Warning("cellRescSetBufferAddress(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", colorBuffers.addr(), vertexArray.addr(), fragmentShader.addr()); + cellResc.Warning("cellRescSetBufferAddress(colorBuffers=*0x%x, vertexArray=*0x%x, fragmentShader=*0x%x)", colorBuffers, vertexArray, fragmentShader); if(!s_rescInternalInstance->m_bInitialized) { @@ -1049,17 +1049,17 @@ int cellRescSetBufferAddress(vm::ptr colorBuffers, vm::ptr vertexArray s_rescInternalInstance->m_vertexArrayEA = vertexArray.addr(); s_rescInternalInstance->m_fragmentUcodeEA = fragmentShader.addr(); - vm::var> dstOffset; + vm::stackvar> dstOffset(CPU); cellGcmAddressToOffset(s_rescInternalInstance->m_colorBuffersEA, dstOffset); - for (int i=0; im_dstOffsets[i] = dstOffset.value() + i * s_rescInternalInstance->m_dstBufInterval; } - for (int i=0; im_dstOffsets[i], s_rescInternalInstance->m_dstPitch, s_rescInternalInstance->m_dstWidth, s_rescInternalInstance->m_dstHeight); + s32 ret = cellGcmSetDisplayBuffer(i, s_rescInternalInstance->m_dstOffsets[i], s_rescInternalInstance->m_dstPitch, s_rescInternalInstance->m_dstWidth, s_rescInternalInstance->m_dstHeight); if (ret) return ret; } @@ -1075,7 +1075,7 @@ int cellRescSetBufferAddress(vm::ptr colorBuffers, vm::ptr vertexArray void cellRescSetFlipHandler(vm::ptr handler) { - cellResc.Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler.addr()); + cellResc.Warning("cellRescSetFlipHandler(handler=*0x%x)", handler); Emu.GetGSManager().GetRender().m_flip_handler = handler; } @@ -1087,14 +1087,14 @@ void cellRescResetFlipStatus() Emu.GetGSManager().GetRender().m_flip_status = 1; } -int cellRescGetFlipStatus() +s32 cellRescGetFlipStatus() { cellResc.Log("cellRescGetFlipStatus()"); return Emu.GetGSManager().GetRender().m_flip_status; } -int cellRescGetRegisterCount() +s32 cellRescGetRegisterCount() { UNIMPLEMENTED_FUNC(cellResc); return CELL_OK; @@ -1107,7 +1107,7 @@ u64 cellRescGetLastFlipTime() return Emu.GetGSManager().GetRender().m_last_flip_time; } -int cellRescSetRegisterCount() +s32 cellRescSetRegisterCount() { UNIMPLEMENTED_FUNC(cellResc); return CELL_OK; @@ -1115,7 +1115,7 @@ int cellRescSetRegisterCount() void cellRescSetVBlankHandler(vm::ptr handler) { - cellResc.Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler.addr()); + cellResc.Warning("cellRescSetVBlankHandler(handler=*0x%x)", handler); Emu.GetGSManager().GetRender().m_vblank_handler = handler; } @@ -1162,7 +1162,7 @@ static void blackman(float window[]) window[3] = ((100.f - SEVIRITY) / 100.f + SEVIRITY / 100.f*a3); } -int CreateInterlaceTable(u32 ea_addr, float srcH, float dstH, CellRescTableElement depth, int length) +s32 CreateInterlaceTable(u32 ea_addr, float srcH, float dstH, CellRescTableElement depth, s32 length) { float phi[4], transient[4]; float y_fraction; @@ -1174,7 +1174,7 @@ int CreateInterlaceTable(u32 ea_addr, float srcH, float dstH, CellRescTableEleme blackman(window); - for (int i = 0; im_initConfig.ratioMode != CELL_RESC_LETTERBOX) ? 1.f : (1.f - 2.f * XY_DELTA_LB); float dstH = s_rescInternalInstance->m_dstHeight * ratioModeCoefficient * s_rescInternalInstance->m_ratioAdjY; - if (int retValue = CreateInterlaceTable(ea_addr, srcH, dstH, depth, length) == CELL_OK) + if (s32 retValue = CreateInterlaceTable(ea_addr, srcH, dstH, depth, length)) + { + return retValue; + } + else { s_rescInternalInstance->m_interlaceTableEA = ea_addr; s_rescInternalInstance->m_interlaceElement = depth; s_rescInternalInstance->m_interlaceTableLength = length; return CELL_OK; } - else - { - return retValue; - } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.h b/rpcs3/Emu/SysCalls/Modules/cellResc.h index a2d577a061..6fcb438ec8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.h +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.h @@ -3,6 +3,8 @@ #define roundup(x,a) (((x)+(a)-1)&(~((a)-1))) #define SEVIRITY 80.f +namespace vm { using namespace ps3; } + #include "Emu/RSX/GCM.h" enum diff --git a/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp b/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp index 21e33c2d01..72ff357e02 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp @@ -7,14 +7,14 @@ extern Module cellRtc; -s64 convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, int years) +s64 convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, s32 years) { return (s64)seconds + (s64)minutes * 60 + (s64)hours * 3600 + (s64)days * 86400 + (s64)(years - 70) * 31536000 + (s64)((years - 69) / 4) * 86400 - (s64)((years - 1) / 100) * 86400 + (s64)((years + 299) / 400) * 86400; } -u64 convertToWin32FILETIME(u16 seconds, u16 minutes, u16 hours, u16 days, int years) +u64 convertToWin32FILETIME(u16 seconds, u16 minutes, u16 hours, u16 days, s32 years) { s64 unixtime = convertToUNIXTime(seconds, minutes, hours, days, years); u64 win32time = u64(unixtime) * u64(10000000) + u64(116444736000000000); @@ -22,7 +22,7 @@ u64 convertToWin32FILETIME(u16 seconds, u16 minutes, u16 hours, u16 days, int ye return win32filetime; } -int cellRtcGetCurrentTick(vm::ptr pTick) +s32 cellRtcGetCurrentTick(vm::ptr pTick) { cellRtc.Log("cellRtcGetCurrentTick(pTick=0x%x)", pTick.addr()); @@ -31,7 +31,7 @@ int cellRtcGetCurrentTick(vm::ptr pTick) return CELL_OK; } -int cellRtcGetCurrentClock(vm::ptr pClock, s32 iTimeZone) +s32 cellRtcGetCurrentClock(vm::ptr pClock, s32 iTimeZone) { cellRtc.Log("cellRtcGetCurrentClock(pClock=0x%x, time_zone=%d)", pClock.addr(), iTimeZone); @@ -52,7 +52,7 @@ int cellRtcGetCurrentClock(vm::ptr pClock, s32 iTimeZone) return CELL_OK; } -int cellRtcGetCurrentClockLocalTime(vm::ptr pClock) +s32 cellRtcGetCurrentClockLocalTime(vm::ptr pClock) { cellRtc.Log("cellRtcGetCurrentClockLocalTime(pClock=0x%x)", pClock.addr()); @@ -69,9 +69,9 @@ int cellRtcGetCurrentClockLocalTime(vm::ptr pClock) return CELL_OK; } -int cellRtcFormatRfc2822(vm::ptr pszDateTime, vm::ptr pUtc, s32 iTimeZone) +s32 cellRtcFormatRfc2822(vm::ptr pszDateTime, vm::ptr pUtc, s32 iTimeZone) { - cellRtc.Log("cellRtcFormatRfc2822(pszDateTime_addr=0x%x, pUtc=0x%x, time_zone=%d)", pszDateTime.addr(), pUtc.addr(), iTimeZone); + cellRtc.Log("cellRtcFormatRfc2822(pszDateTime=*0x%x, pUtc=*0x%x, time_zone=%d)", pszDateTime, pUtc, iTimeZone); // Add time_zone as offset in minutes. rTimeSpan tz = rTimeSpan(0, (long) iTimeZone, 0, 0); @@ -87,9 +87,9 @@ int cellRtcFormatRfc2822(vm::ptr pszDateTime, vm::ptr pUtc, s return CELL_OK; } -int cellRtcFormatRfc2822LocalTime(vm::ptr pszDateTime, vm::ptr pUtc) +s32 cellRtcFormatRfc2822LocalTime(vm::ptr pszDateTime, vm::ptr pUtc) { - cellRtc.Log("cellRtcFormatRfc2822LocalTime(pszDateTime_addr=0x%x, pUtc=0x%x)", pszDateTime.addr(), pUtc.addr()); + cellRtc.Log("cellRtcFormatRfc2822LocalTime(pszDateTime=*0x%x, pUtc=*0x%x)", pszDateTime, pUtc); // Get date from ticks. rDateTime date = rDateTime((time_t)pUtc->tick); @@ -101,9 +101,9 @@ int cellRtcFormatRfc2822LocalTime(vm::ptr pszDateTime, vm::ptr pszDateTime, vm::ptr pUtc, s32 iTimeZone) +s32 cellRtcFormatRfc3339(vm::ptr pszDateTime, vm::ptr pUtc, s32 iTimeZone) { - cellRtc.Log("cellRtcFormatRfc3339(pszDateTime_addr=0x%x, pUtc=0x%x, iTimeZone=%d)", pszDateTime.addr(), pUtc.addr(), iTimeZone); + cellRtc.Log("cellRtcFormatRfc3339(pszDateTime=*0x%x, pUtc=*0x%x, iTimeZone=%d)", pszDateTime, pUtc, iTimeZone); // Add time_zone as offset in minutes. rTimeSpan tz = rTimeSpan(0, (long) iTimeZone, 0, 0); @@ -119,9 +119,9 @@ int cellRtcFormatRfc3339(vm::ptr pszDateTime, vm::ptr pUtc, s return CELL_OK; } -int cellRtcFormatRfc3339LocalTime(vm::ptr pszDateTime, vm::ptr pUtc) +s32 cellRtcFormatRfc3339LocalTime(vm::ptr pszDateTime, vm::ptr pUtc) { - cellRtc.Log("cellRtcFormatRfc3339LocalTime(pszDateTime_addr=0x%x, pUtc=0x%x)", pszDateTime.addr(), pUtc.addr()); + cellRtc.Log("cellRtcFormatRfc3339LocalTime(pszDateTime=*0x%x, pUtc=*0x%x)", pszDateTime, pUtc); // Get date from ticks. rDateTime date = rDateTime((time_t) pUtc->tick); @@ -133,9 +133,9 @@ int cellRtcFormatRfc3339LocalTime(vm::ptr pszDateTime, vm::ptr pUtc, vm::ptr pszDateTime) +s32 cellRtcParseDateTime(vm::ptr pUtc, vm::cptr pszDateTime) { - cellRtc.Log("cellRtcParseDateTime(pUtc=0x%x, pszDateTime_addr=0x%x)", pUtc.addr(), pszDateTime.addr()); + cellRtc.Log("cellRtcParseDateTime(pUtc=*0x%x, pszDateTime=*0x%x)", pUtc, pszDateTime); // Get date from formatted string. rDateTime date; @@ -146,9 +146,9 @@ int cellRtcParseDateTime(vm::ptr pUtc, vm::ptr pszDateT return CELL_OK; } -int cellRtcParseRfc3339(vm::ptr pUtc, vm::ptr pszDateTime) +s32 cellRtcParseRfc3339(vm::ptr pUtc, vm::cptr pszDateTime) { - cellRtc.Log("cellRtcParseRfc3339(pUtc=0x%x, pszDateTime_addr=0x%x)", pUtc.addr(), pszDateTime.addr()); + cellRtc.Log("cellRtcParseRfc3339(pUtc=*0x%x, pszDateTime=*0x%x)", pUtc, pszDateTime); // Get date from RFC3339 formatted string. rDateTime date; @@ -159,7 +159,7 @@ int cellRtcParseRfc3339(vm::ptr pUtc, vm::ptr pszDateTi return CELL_OK; } -int cellRtcGetTick(vm::ptr pTime, vm::ptr pTick) +s32 cellRtcGetTick(vm::ptr pTime, vm::ptr pTick) { cellRtc.Log("cellRtcGetTick(pTime=0x%x, pTick=0x%x)", pTime.addr(), pTick.addr()); @@ -169,7 +169,7 @@ int cellRtcGetTick(vm::ptr pTime, vm::ptr pTick) return CELL_OK; } -int cellRtcSetTick(vm::ptr pTime, vm::ptr pTick) +s32 cellRtcSetTick(vm::ptr pTime, vm::ptr pTick) { cellRtc.Log("cellRtcSetTick(pTime=0x%x, pTick=0x%x)", pTime.addr(), pTick.addr()); @@ -186,7 +186,7 @@ int cellRtcSetTick(vm::ptr pTime, vm::ptr pTick) return CELL_OK; } -int cellRtcTickAddTicks(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) +s32 cellRtcTickAddTicks(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { cellRtc.Log("cellRtcTickAddTicks(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); @@ -194,7 +194,7 @@ int cellRtcTickAddTicks(vm::ptr pTick0, vm::ptr pTick1 return CELL_OK; } -int cellRtcTickAddMicroseconds(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) +s32 cellRtcTickAddMicroseconds(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { cellRtc.Log("cellRtcTickAddMicroseconds(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); @@ -206,7 +206,7 @@ int cellRtcTickAddMicroseconds(vm::ptr pTick0, vm::ptr return CELL_OK; } -int cellRtcTickAddSeconds(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) +s32 cellRtcTickAddSeconds(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { cellRtc.Log("cellRtcTickAddSeconds(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); @@ -218,7 +218,7 @@ int cellRtcTickAddSeconds(vm::ptr pTick0, vm::ptr pTic return CELL_OK; } -int cellRtcTickAddMinutes(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) +s32 cellRtcTickAddMinutes(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { cellRtc.Log("cellRtcTickAddMinutes(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); @@ -230,7 +230,7 @@ int cellRtcTickAddMinutes(vm::ptr pTick0, vm::ptr pTic return CELL_OK; } -int cellRtcTickAddHours(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) +s32 cellRtcTickAddHours(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { cellRtc.Log("cellRtcTickAddHours(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); @@ -242,7 +242,7 @@ int cellRtcTickAddHours(vm::ptr pTick0, vm::ptr pTick1 return CELL_OK; } -int cellRtcTickAddDays(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) +s32 cellRtcTickAddDays(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { cellRtc.Log("cellRtcTickAddDays(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); @@ -254,7 +254,7 @@ int cellRtcTickAddDays(vm::ptr pTick0, vm::ptr pTick1, return CELL_OK; } -int cellRtcTickAddWeeks(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) +s32 cellRtcTickAddWeeks(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { cellRtc.Log("cellRtcTickAddWeeks(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); @@ -266,7 +266,7 @@ int cellRtcTickAddWeeks(vm::ptr pTick0, vm::ptr pTick1 return CELL_OK; } -int cellRtcTickAddMonths(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) +s32 cellRtcTickAddMonths(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { cellRtc.Log("cellRtcTickAddMonths(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); @@ -278,7 +278,7 @@ int cellRtcTickAddMonths(vm::ptr pTick0, vm::ptr pTick return CELL_OK; } -int cellRtcTickAddYears(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) +s32 cellRtcTickAddYears(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { cellRtc.Log("cellRtcTickAddYears(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); @@ -290,7 +290,7 @@ int cellRtcTickAddYears(vm::ptr pTick0, vm::ptr pTick1 return CELL_OK; } -int cellRtcConvertUtcToLocalTime(vm::ptr pUtc, vm::ptr pLocalTime) +s32 cellRtcConvertUtcToLocalTime(vm::ptr pUtc, vm::ptr pLocalTime) { cellRtc.Log("cellRtcConvertUtcToLocalTime(pUtc=0x%x, pLocalTime=0x%x)", pUtc.addr(), pLocalTime.addr()); @@ -300,7 +300,7 @@ int cellRtcConvertUtcToLocalTime(vm::ptr pUtc, vm::ptr return CELL_OK; } -int cellRtcConvertLocalTimeToUtc(vm::ptr pLocalTime, vm::ptr pUtc) +s32 cellRtcConvertLocalTimeToUtc(vm::ptr pLocalTime, vm::ptr pUtc) { cellRtc.Log("cellRtcConvertLocalTimeToUtc(pLocalTime=0x%x, pUtc=0x%x)", pLocalTime.addr(), pUtc.addr()); @@ -310,7 +310,7 @@ int cellRtcConvertLocalTimeToUtc(vm::ptr pLocalTime, vm::ptr pDateTime, vm::ptr puiDosTime) +s32 cellRtcGetDosTime(vm::ptr pDateTime, vm::ptr puiDosTime) { cellRtc.Log("cellRtcGetDosTime(pDateTime=0x%x, puiDosTime=0x%x)", pDateTime.addr(), puiDosTime.addr()); @@ -321,7 +321,7 @@ int cellRtcGetDosTime(vm::ptr pDateTime, vm::ptr puiDosTim return CELL_OK; } -int cellRtcGetTime_t(vm::ptr pDateTime, vm::ptr piTime) +s32 cellRtcGetTime_t(vm::ptr pDateTime, vm::ptr piTime) { cellRtc.Log("cellRtcGetTime_t(pDateTime=0x%x, piTime=0x%x)", pDateTime.addr(), piTime.addr()); @@ -333,7 +333,7 @@ int cellRtcGetTime_t(vm::ptr pDateTime, vm::ptr piTime) return CELL_OK; } -int cellRtcGetWin32FileTime(vm::ptr pDateTime, vm::ptr pulWin32FileTime) +s32 cellRtcGetWin32FileTime(vm::ptr pDateTime, vm::ptr pulWin32FileTime) { cellRtc.Log("cellRtcGetWin32FileTime(pDateTime=0x%x, pulWin32FileTime=0x%x)", pDateTime.addr(), pulWin32FileTime.addr()); @@ -345,7 +345,7 @@ int cellRtcGetWin32FileTime(vm::ptr pDateTime, vm::ptr pul return CELL_OK; } -int cellRtcSetDosTime(vm::ptr pDateTime, u32 uiDosTime) +s32 cellRtcSetDosTime(vm::ptr pDateTime, u32 uiDosTime) { cellRtc.Log("cellRtcSetDosTime(pDateTime=0x%x, uiDosTime=0x%x)", pDateTime.addr(), uiDosTime); @@ -363,7 +363,7 @@ int cellRtcSetDosTime(vm::ptr pDateTime, u32 uiDosTime) return CELL_OK; } -int cellRtcSetTime_t(vm::ptr pDateTime, u64 iTime) +s32 cellRtcSetTime_t(vm::ptr pDateTime, u64 iTime) { cellRtc.Log("cellRtcSetTime_t(pDateTime=0x%x, iTime=0x%llx)", pDateTime.addr(), iTime); @@ -380,9 +380,9 @@ int cellRtcSetTime_t(vm::ptr pDateTime, u64 iTime) return CELL_OK; } -int cellRtcSetWin32FileTime(vm::ptr pDateTime, u64 ulWin32FileTime) +s32 cellRtcSetWin32FileTime(vm::ptr pDateTime, u64 ulWin32FileTime) { - cellRtc.Log("cellRtcSetWin32FileTime(pDateTime_addr=0x%x, ulWin32FileTime=0x%llx)", pDateTime.addr(), ulWin32FileTime); + cellRtc.Log("cellRtcSetWin32FileTime(pDateTime=*0x%x, ulWin32FileTime=0x%llx)", pDateTime, ulWin32FileTime); rDateTime date_time = rDateTime((time_t)ulWin32FileTime); @@ -397,7 +397,7 @@ int cellRtcSetWin32FileTime(vm::ptr pDateTime, u64 ulWin32FileT return CELL_OK; } -int cellRtcIsLeapYear(s32 year) +s32 cellRtcIsLeapYear(s32 year) { cellRtc.Log("cellRtcIsLeapYear(year=%d)", year); @@ -405,7 +405,7 @@ int cellRtcIsLeapYear(s32 year) return datetime.IsLeapYear(year, rDateTime::Gregorian); } -int cellRtcGetDaysInMonth(s32 year, s32 month) +s32 cellRtcGetDaysInMonth(s32 year, s32 month) { cellRtc.Log("cellRtcGetDaysInMonth(year=%d, month=%d)", year, month); @@ -413,7 +413,7 @@ int cellRtcGetDaysInMonth(s32 year, s32 month) return datetime.GetNumberOfDays((rDateTime::Month) month, year, rDateTime::Gregorian); } -int cellRtcGetDayOfWeek(s32 year, s32 month, s32 day) +s32 cellRtcGetDayOfWeek(s32 year, s32 month, s32 day) { cellRtc.Log("cellRtcGetDayOfWeek(year=%d, month=%d, day=%d)", year, month, day); @@ -422,7 +422,7 @@ int cellRtcGetDayOfWeek(s32 year, s32 month, s32 day) return datetime.GetWeekDay(); } -int cellRtcCheckValid(vm::ptr pTime) +s32 cellRtcCheckValid(vm::ptr pTime) { cellRtc.Log("cellRtcCheckValid(pTime=0x%x)", pTime.addr()); @@ -436,7 +436,7 @@ int cellRtcCheckValid(vm::ptr pTime) else return CELL_OK; } -int cellRtcCompareTick(vm::ptr pTick0, vm::ptr pTick1) +s32 cellRtcCompareTick(vm::ptr pTick0, vm::ptr pTick1) { cellRtc.Log("cellRtcCompareTick(pTick0=0x%x, pTick1=0x%x)", pTick0.addr(), pTick1.addr()); diff --git a/rpcs3/Emu/SysCalls/Modules/cellRtc.h b/rpcs3/Emu/SysCalls/Modules/cellRtc.h index 3863de0b01..2c51bac05e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRtc.h +++ b/rpcs3/Emu/SysCalls/Modules/cellRtc.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellRudp.h b/rpcs3/Emu/SysCalls/Modules/cellRudp.h index 0a33a58998..9f3e17c70d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRudp.h +++ b/rpcs3/Emu/SysCalls/Modules/cellRudp.h @@ -1,3 +1,7 @@ +#pragma once + +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -42,11 +46,11 @@ enum CELL_RUDP_ERROR_KEEP_ALIVE_FAILURE = 0x80770026, }; -typedef vm::ptr(CellRudpAllocatorFuncAlloc)(u32 size); -typedef u32(CellRudpAllocatorFuncFree)(vm::ptr ptr); +using CellRudpAllocatorFuncAlloc = func_def(u32 size)>; +using CellRudpAllocatorFuncFree = func_def ptr)>; struct CellRudpAllocator { - vm::ptr app_malloc; - vm::ptr app_free; -}; \ No newline at end of file + vm::bptr app_malloc; + vm::bptr app_free; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp index 0ca3f285f6..8c7b302b89 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp @@ -8,7 +8,7 @@ extern Module cellSail; -int cellSailMemAllocatorInitialize(vm::ptr pSelf, vm::ptr pCallbacks) +s32 cellSailMemAllocatorInitialize(vm::ptr pSelf, vm::ptr pCallbacks) { cellSail.Warning("cellSailMemAllocatorInitialize(pSelf_addr=0x%x, pCallbacks_addr=0x%x)", pSelf.addr(), pCallbacks.addr()); @@ -18,61 +18,61 @@ int cellSailMemAllocatorInitialize(vm::ptr pSelf, vm::ptr< return CELL_OK; } -int cellSailFutureInitialize() +s32 cellSailFutureInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailFutureFinalize() +s32 cellSailFutureFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailFutureReset() +s32 cellSailFutureReset() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailFutureSet() +s32 cellSailFutureSet() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailFutureGet() +s32 cellSailFutureGet() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailFutureIsDone() +s32 cellSailFutureIsDone() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorGetStreamType() +s32 cellSailDescriptorGetStreamType() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorGetUri() +s32 cellSailDescriptorGetUri() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorGetMediaInfo() +s32 cellSailDescriptorGetMediaInfo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorSetAutoSelection(vm::ptr pSelf, bool autoSelection) +s32 cellSailDescriptorSetAutoSelection(vm::ptr pSelf, bool autoSelection) { cellSail.Warning("cellSailDescriptorSetAutoSelection(pSelf_addr=0x%x, autoSelection=%s)", pSelf.addr(), autoSelection ? "true" : "false"); @@ -84,7 +84,7 @@ int cellSailDescriptorSetAutoSelection(vm::ptr pSelf, bool a return CELL_OK; } -int cellSailDescriptorIsAutoSelection(vm::ptr pSelf) +s32 cellSailDescriptorIsAutoSelection(vm::ptr pSelf) { cellSail.Warning("cellSailDescriptorIsAutoSelection(pSelf_addr=0x%x)", pSelf.addr()); @@ -94,7 +94,7 @@ int cellSailDescriptorIsAutoSelection(vm::ptr pSelf) return CELL_OK; } -int cellSailDescriptorCreateDatabase(vm::ptr pSelf, vm::ptr pDatabase, u32 size, u64 arg) +s32 cellSailDescriptorCreateDatabase(vm::ptr pSelf, vm::ptr pDatabase, u32 size, u64 arg) { cellSail.Warning("cellSailDescriptorCreateDatabase(pSelf=0x%x, pDatabase=0x%x, size=0x%x, arg=0x%x", pSelf.addr(), pDatabase.addr(), size, arg); @@ -113,409 +113,409 @@ int cellSailDescriptorCreateDatabase(vm::ptr pSelf, vm::ptr< return CELL_OK; } -int cellSailDescriptorDestroyDatabase() +s32 cellSailDescriptorDestroyDatabase() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorOpen() +s32 cellSailDescriptorOpen() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorClose() +s32 cellSailDescriptorClose() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorSetEs() +s32 cellSailDescriptorSetEs() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorClearEs() +s32 cellSailDescriptorClearEs() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorGetCapabilities() +s32 cellSailDescriptorGetCapabilities() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorInquireCapability() +s32 cellSailDescriptorInquireCapability() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailDescriptorSetParameter() +s32 cellSailDescriptorSetParameter() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterInitialize() +s32 cellSailSoundAdapterInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterFinalize() +s32 cellSailSoundAdapterFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterSetPreferredFormat() +s32 cellSailSoundAdapterSetPreferredFormat() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterGetFrame() +s32 cellSailSoundAdapterGetFrame() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterGetFormat() +s32 cellSailSoundAdapterGetFormat() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterUpdateAvSync() +s32 cellSailSoundAdapterUpdateAvSync() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSoundAdapterPtsToTimePosition() +s32 cellSailSoundAdapterPtsToTimePosition() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterInitialize() +s32 cellSailGraphicsAdapterInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterFinalize() +s32 cellSailGraphicsAdapterFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterSetPreferredFormat() +s32 cellSailGraphicsAdapterSetPreferredFormat() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterGetFrame() +s32 cellSailGraphicsAdapterGetFrame() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterGetFrame2() +s32 cellSailGraphicsAdapterGetFrame2() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterGetFormat() +s32 cellSailGraphicsAdapterGetFormat() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterUpdateAvSync() +s32 cellSailGraphicsAdapterUpdateAvSync() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailGraphicsAdapterPtsToTimePosition() +s32 cellSailGraphicsAdapterPtsToTimePosition() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAuReceiverInitialize() +s32 cellSailAuReceiverInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAuReceiverFinalize() +s32 cellSailAuReceiverFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAuReceiverGet() +s32 cellSailAuReceiverGet() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererAudioInitialize() +s32 cellSailRendererAudioInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererAudioFinalize() +s32 cellSailRendererAudioFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererAudioNotifyCallCompleted() +s32 cellSailRendererAudioNotifyCallCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererAudioNotifyFrameDone() +s32 cellSailRendererAudioNotifyFrameDone() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererAudioNotifyOutputEos() +s32 cellSailRendererAudioNotifyOutputEos() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererVideoInitialize() +s32 cellSailRendererVideoInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererVideoFinalize() +s32 cellSailRendererVideoFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererVideoNotifyCallCompleted() +s32 cellSailRendererVideoNotifyCallCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererVideoNotifyFrameDone() +s32 cellSailRendererVideoNotifyFrameDone() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailRendererVideoNotifyOutputEos() +s32 cellSailRendererVideoNotifyOutputEos() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceInitialize() +s32 cellSailSourceInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceFinalize() +s32 cellSailSourceFinalize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyCallCompleted() +s32 cellSailSourceNotifyCallCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyInputEos() +s32 cellSailSourceNotifyInputEos() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyStreamOut() +s32 cellSailSourceNotifyStreamOut() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifySessionError() +s32 cellSailSourceNotifySessionError() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyMediaStateChanged() +s32 cellSailSourceNotifyMediaStateChanged() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceCheck() +s32 cellSailSourceCheck() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyOpenCompleted() +s32 cellSailSourceNotifyOpenCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyStartCompleted() +s32 cellSailSourceNotifyStartCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyStopCompleted() +s32 cellSailSourceNotifyStopCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyReadCompleted() +s32 cellSailSourceNotifyReadCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceSetDiagHandler() +s32 cellSailSourceSetDiagHandler() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailSourceNotifyCloseCompleted() +s32 cellSailSourceNotifyCloseCompleted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4MovieGetBrand() +s32 cellSailMp4MovieGetBrand() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4MovieIsCompatibleBrand() +s32 cellSailMp4MovieIsCompatibleBrand() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4MovieGetMovieInfo() +s32 cellSailMp4MovieGetMovieInfo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4MovieGetTrackByIndex() +s32 cellSailMp4MovieGetTrackByIndex() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4MovieGetTrackById() +s32 cellSailMp4MovieGetTrackById() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4MovieGetTrackByTypeAndIndex() +s32 cellSailMp4MovieGetTrackByTypeAndIndex() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4TrackGetTrackInfo() +s32 cellSailMp4TrackGetTrackInfo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4TrackGetTrackReferenceCount() +s32 cellSailMp4TrackGetTrackReferenceCount() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4TrackGetTrackReference() +s32 cellSailMp4TrackGetTrackReference() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailMp4ConvertTimeScale() +s32 cellSailMp4ConvertTimeScale() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAviMovieGetMovieInfo() +s32 cellSailAviMovieGetMovieInfo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAviMovieGetStreamByIndex() +s32 cellSailAviMovieGetStreamByIndex() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAviMovieGetStreamByTypeAndIndex() +s32 cellSailAviMovieGetStreamByTypeAndIndex() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAviMovieGetHeader() +s32 cellSailAviMovieGetHeader() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAviStreamGetMediaType() +s32 cellSailAviStreamGetMediaType() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailAviStreamGetHeader() +s32 cellSailAviStreamGetHeader() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerInitialize() +s32 cellSailPlayerInitialize() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerInitialize2(vm::ptr pSelf, vm::ptr pAllocator, vm::ptr pCallback, u64 callbackArg, +s32 cellSailPlayerInitialize2(vm::ptr pSelf, vm::ptr pAllocator, vm::ptr pCallback, u64 callbackArg, vm::ptr pAttribute, vm::ptr pResource) { cellSail.Warning("cellSailPlayerInitialize2(pSelf_addr=0x%x, pAllocator_addr=0x%x, pCallback=0x%x, callbackArg=%d, pAttribute_addr=0x%x, pResource=0x%x)", pSelf.addr(), @@ -530,91 +530,91 @@ int cellSailPlayerInitialize2(vm::ptr pSelf, vm::ptr pSelf, vm::ptr pDesc) +s32 cellSailPlayerAddDescriptor(vm::ptr pSelf, vm::ptr pDesc) { cellSail.Warning("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), pDesc.addr()); @@ -632,7 +632,7 @@ int cellSailPlayerAddDescriptor(vm::ptr pSelf, vm::ptr pSelf, s32 streamType, vm::ptr pMediaInfo, vm::ptr pUri, vm::ptr ppDesc) +s32 cellSailPlayerCreateDescriptor(vm::ptr pSelf, s32 streamType, vm::ptr pMediaInfo, vm::cptr pUri, vm::ptr ppDesc) { cellSail.Warning("cellSailPlayerCreateDescriptor(pSelf_addr=0x%x, streamType=%d, pMediaInfo_addr=0x%x, pUri_addr=0x%x, ppDesc_addr=0x%x)", pSelf.addr(), streamType, pMediaInfo.addr(), pUri.addr(), ppDesc.addr()); @@ -657,7 +657,7 @@ int cellSailPlayerCreateDescriptor(vm::ptr pSelf, s32 streamType if (f.Open(path)) { u64 size = f.GetSize(); u32 buf_ = Memory.Alloc(size, 1); - auto bufPtr = vm::ptr::make(buf_); + auto bufPtr = vm::cptr::make(buf_); PamfHeader *buf = const_cast(bufPtr.get_ptr()); assert(f.Read(buf, size) == size); u32 sp_ = Memory.Alloc(sizeof(CellPamfReader), 1); @@ -685,7 +685,7 @@ int cellSailPlayerCreateDescriptor(vm::ptr pSelf, s32 streamType return CELL_OK; } -int cellSailPlayerDestroyDescriptor(vm::ptr pSelf, vm::ptr pDesc) +s32 cellSailPlayerDestroyDescriptor(vm::ptr pSelf, vm::ptr pDesc) { cellSail.Todo("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), pDesc.addr()); @@ -695,7 +695,7 @@ int cellSailPlayerDestroyDescriptor(vm::ptr pSelf, vm::ptr pSelf, vm::ptr ppDesc) +s32 cellSailPlayerRemoveDescriptor(vm::ptr pSelf, vm::ptr ppDesc) { cellSail.Warning("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), ppDesc.addr()); @@ -709,121 +709,121 @@ int cellSailPlayerRemoveDescriptor(vm::ptr pSelf, vm::ptrdescriptors; } -int cellSailPlayerGetDescriptorCount(vm::ptr pSelf) +s32 cellSailPlayerGetDescriptorCount(vm::ptr pSelf) { cellSail.Warning("cellSailPlayerGetDescriptorCount(pSelf_addr=0x%x)", pSelf.addr()); return pSelf->descriptors; } -int cellSailPlayerGetCurrentDescriptor() +s32 cellSailPlayerGetCurrentDescriptor() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerOpenStream() +s32 cellSailPlayerOpenStream() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerCloseStream() +s32 cellSailPlayerCloseStream() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerOpenEsAudio() +s32 cellSailPlayerOpenEsAudio() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerOpenEsVideo() +s32 cellSailPlayerOpenEsVideo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerOpenEsUser() +s32 cellSailPlayerOpenEsUser() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerReopenEsAudio() +s32 cellSailPlayerReopenEsAudio() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerReopenEsVideo() +s32 cellSailPlayerReopenEsVideo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerReopenEsUser() +s32 cellSailPlayerReopenEsUser() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerCloseEsAudio() +s32 cellSailPlayerCloseEsAudio() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerCloseEsVideo() +s32 cellSailPlayerCloseEsVideo() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerCloseEsUser() +s32 cellSailPlayerCloseEsUser() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerStart() +s32 cellSailPlayerStart() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerStop() +s32 cellSailPlayerStop() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerNext() +s32 cellSailPlayerNext() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerCancel() +s32 cellSailPlayerCancel() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerSetPaused(vm::ptr pSelf, bool paused) +s32 cellSailPlayerSetPaused(vm::ptr pSelf, bool paused) { cellSail.Todo("cellSailPlayerSetPaused(pSelf_addr=0x%x, paused=%d)", pSelf.addr(), paused); return CELL_OK; } -int cellSailPlayerIsPaused(vm::ptr pSelf) +s32 cellSailPlayerIsPaused(vm::ptr pSelf) { cellSail.Warning("cellSailPlayerIsPaused(pSelf_addr=0x%x)", pSelf.addr()); return pSelf->paused; } -int cellSailPlayerSetRepeatMode(vm::ptr pSelf, s32 repeatMode, vm::ptr pCommand) +s32 cellSailPlayerSetRepeatMode(vm::ptr pSelf, s32 repeatMode, vm::ptr pCommand) { cellSail.Warning("cellSailPlayerSetRepeatMode(pSelf_addr=0x%x, repeatMode=%d, pCommand_addr=0x%x)", pSelf.addr(), repeatMode, pCommand.addr()); @@ -833,7 +833,7 @@ int cellSailPlayerSetRepeatMode(vm::ptr pSelf, s32 repeatMode, v return pSelf->repeatMode; } -int cellSailPlayerGetRepeatMode(vm::ptr pSelf, vm::ptr pCommand) +s32 cellSailPlayerGetRepeatMode(vm::ptr pSelf, vm::ptr pCommand) { cellSail.Warning("cellSailPlayerGetRepeatMode(pSelf_addr=0x%x, pCommand_addr=0x%x)", pSelf.addr(), pCommand.addr()); @@ -842,37 +842,37 @@ int cellSailPlayerGetRepeatMode(vm::ptr pSelf, vm::ptrrepeatMode; } -int cellSailPlayerSetEsAudioMuted() +s32 cellSailPlayerSetEsAudioMuted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerSetEsVideoMuted() +s32 cellSailPlayerSetEsVideoMuted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerIsEsAudioMuted() +s32 cellSailPlayerIsEsAudioMuted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerIsEsVideoMuted() +s32 cellSailPlayerIsEsVideoMuted() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerDumpImage() +s32 cellSailPlayerDumpImage() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; } -int cellSailPlayerUnregisterSource() +s32 cellSailPlayerUnregisterSource() { UNIMPLEMENTED_FUNC(cellSail); return CELL_OK; @@ -944,7 +944,6 @@ Module cellSail("cellSail", []() REG_FUNC(cellSail, cellSailSourceNotifyStreamOut); REG_FUNC(cellSail, cellSailSourceNotifySessionError); REG_FUNC(cellSail, cellSailSourceNotifyMediaStateChanged); - //cellSail.AddFunc(, cellSailSourceCheck); REG_FUNC(cellSail, cellSailSourceNotifyOpenCompleted); REG_FUNC(cellSail, cellSailSourceNotifyStartCompleted); REG_FUNC(cellSail, cellSailSourceNotifyStopCompleted); @@ -961,7 +960,6 @@ Module cellSail("cellSail", []() REG_FUNC(cellSail, cellSailMp4TrackGetTrackInfo); REG_FUNC(cellSail, cellSailMp4TrackGetTrackReferenceCount); REG_FUNC(cellSail, cellSailMp4TrackGetTrackReference); - //cellSail.AddFunc(, cellSailMp4ConvertTimeScale); REG_FUNC(cellSail, cellSailAviMovieGetMovieInfo); REG_FUNC(cellSail, cellSailAviMovieGetStreamByIndex); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.h b/rpcs3/Emu/SysCalls/Modules/cellSail.h index 3f77c94d98..e8eee799b3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -1041,7 +1043,7 @@ struct CellSailDescriptor be_t internalData[31]; }; -static_assert(sizeof(CellSailDescriptor) == 0x100, "Invalid CellSailDescriptor size"); +CHECK_SIZE(CellSailDescriptor, 0x100); struct CellSailStartCommand { @@ -1108,4 +1110,4 @@ struct CellSailPlayer be_t internalData[26]; }; -static_assert(sizeof(CellSailPlayer) == 0x100, "Invalid CellSailPlayer size"); \ No newline at end of file +CHECK_SIZE(CellSailPlayer, 0x100); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index a585717aff..9556a2da4d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -2,7 +2,6 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" @@ -37,7 +36,7 @@ never_inline s32 savedata_op( PPUThread& CPU, u32 operation, u32 version, - vm::ptr dirName, + vm::cptr dirName, u32 errDialog, vm::ptr setList, vm::ptr setBuf, @@ -329,7 +328,7 @@ never_inline s32 savedata_op( } else { - throw __FUNCTION__; + throw EXCEPTION("Invalid savedata selected"); } } } @@ -555,7 +554,7 @@ never_inline s32 savedata_op( } } - psf.SetInteger("*" + file_path, fileSet->fileType.data() == se32(CELL_SAVEDATA_FILETYPE_SECUREFILE)); + psf.SetInteger("*" + file_path, fileSet->fileType == CELL_SAVEDATA_FILETYPE_SECUREFILE); std::string local_path; @@ -685,7 +684,7 @@ s32 cellSaveDataFixedLoad2( s32 cellSaveDataAutoSave2( PPUThread& CPU, u32 version, - vm::ptr dirName, + vm::cptr dirName, u32 errDialog, vm::ptr setBuf, vm::ptr funcStat, @@ -702,7 +701,7 @@ s32 cellSaveDataAutoSave2( s32 cellSaveDataAutoLoad2( PPUThread& CPU, u32 version, - vm::ptr dirName, + vm::cptr dirName, u32 errDialog, vm::ptr setBuf, vm::ptr funcStat, @@ -850,7 +849,7 @@ s32 cellSaveDataUserAutoSave( PPUThread& CPU, u32 version, u32 userId, - vm::ptr dirName, + vm::cptr dirName, u32 errDialog, vm::ptr setBuf, vm::ptr funcStat, @@ -868,7 +867,7 @@ s32 cellSaveDataUserAutoLoad( PPUThread& CPU, u32 version, u32 userId, - vm::ptr dirName, + vm::cptr dirName, u32 errDialog, vm::ptr setBuf, vm::ptr funcStat, @@ -987,7 +986,7 @@ s32 cellSaveDataListExport( s32 cellSaveDataFixedImport( PPUThread& CPU, - vm::ptr dirName, + vm::cptr dirName, u32 maxSizeKB, vm::ptr funcDone, u32 container, @@ -1000,7 +999,7 @@ s32 cellSaveDataFixedImport( s32 cellSaveDataFixedExport( PPUThread& CPU, - vm::ptr dirName, + vm::cptr dirName, u32 maxSizeKB, vm::ptr funcDone, u32 container, @@ -1012,7 +1011,7 @@ s32 cellSaveDataFixedExport( } s32 cellSaveDataGetListItem( - vm::ptr dirName, + vm::cptr dirName, vm::ptr dir, vm::ptr sysFileParam, vm::ptr bind, @@ -1069,7 +1068,7 @@ s32 cellSaveDataUserListExport( s32 cellSaveDataUserFixedImport( PPUThread& CPU, u32 userId, - vm::ptr dirName, + vm::cptr dirName, u32 maxSizeKB, vm::ptr funcDone, u32 container, @@ -1083,7 +1082,7 @@ s32 cellSaveDataUserFixedImport( s32 cellSaveDataUserFixedExport( PPUThread& CPU, u32 userId, - vm::ptr dirName, + vm::cptr dirName, u32 maxSizeKB, vm::ptr funcDone, u32 container, @@ -1096,7 +1095,7 @@ s32 cellSaveDataUserFixedExport( s32 cellSaveDataUserGetListItem( u32 userId, - vm::ptr dirName, + vm::cptr dirName, vm::ptr dir, vm::ptr sysFileParam, vm::ptr bind, diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.h b/rpcs3/Emu/SysCalls/Modules/cellSaveData.h index 1c9351ca3a..5e7e4e71b5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellScreenshot.h b/rpcs3/Emu/SysCalls/Modules/cellScreenshot.h index 75045278d7..766fd73783 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellScreenshot.h +++ b/rpcs3/Emu/SysCalls/Modules/cellScreenshot.h @@ -1,3 +1,7 @@ +#pragma once + +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -11,7 +15,7 @@ enum struct CellScreenShotSetParam { - const char *photo_title; - const char *game_title; - const char *game_comment; -}; \ No newline at end of file + vm::bcptr photo_title; + vm::bcptr game_title; + vm::bcptr game_comment; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSearch.h b/rpcs3/Emu/SysCalls/Modules/cellSearch.h index 8c61d51018..be910c9be4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSearch.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSearch.h @@ -1,7 +1,10 @@ +#pragma once + +namespace vm { using namespace ps3; } + // Error Codes enum { - CELL_SEARCH_OK = 0, CELL_SEARCH_CANCELED = 1, CELL_SEARCH_ERROR_PARAM = 0x8002C801, CELL_SEARCH_ERROR_BUSY = 0x8002C802, @@ -37,7 +40,7 @@ enum }; // Sort keys -enum +enum : s32 { CELL_SEARCH_SORTKEY_NONE = 0, CELL_SEARCH_SORTKEY_DEFAULT = 1, @@ -53,7 +56,7 @@ enum }; // Sort order -enum +enum : s32 { CELL_SEARCH_SORTORDER_NONE = 0, CELL_SEARCH_SORTORDER_ASCENDING = 1, @@ -61,7 +64,7 @@ enum }; // Content types -enum +enum : s32 { CELL_SEARCH_CONTENTTYPE_NONE = 0, CELL_SEARCH_CONTENTTYPE_MUSIC = 1, @@ -74,7 +77,7 @@ enum }; // Codecs -enum CellSearchCodec +enum CellSearchCodec : s32 { CELL_SEARCH_CODEC_UNKNOWN = 0, CELL_SEARCH_CODEC_MPEG2 = 1, @@ -108,7 +111,7 @@ enum CellSearchCodec }; // Scene types -enum CellSearchSceneType +enum CellSearchSceneType : s32 { CELL_SEARCH_SCENETYPE_NONE = 0, CELL_SEARCH_SCENETYPE_CHAPTER = 1, @@ -117,7 +120,7 @@ enum CellSearchSceneType }; // List types -enum CellSearchListType +enum CellSearchListType : s32 { CELL_SEARCH_LISTTYPE_MUSIC_ALBUM = 1, CELL_SEARCH_LISTTYPE_MUSIC_GENRE = 2, @@ -126,7 +129,7 @@ enum CellSearchListType }; // Content status -enum CellSearchContentStatus +enum CellSearchContentStatus : s32 { CELL_SEARCH_CONTENTSTATUS_AVAILABLE, CELL_SEARCH_CONTENTSTATUS_NOT_SUPPORTED, @@ -134,7 +137,7 @@ enum CellSearchContentStatus }; // Search orientation -enum CellSearchOrientation +enum CellSearchOrientation : s32 { CELL_SEARCH_ORIENTATION_UNKNOWN, CELL_SEARCH_ORIENTATION_TOP_LEFT, @@ -144,13 +147,13 @@ enum CellSearchOrientation }; // Search modes -enum CellSearchMode +enum CellSearchMode : s32 { CELL_SEARCH_MODE_NORMAL = 0, }; // Search events -enum CellSearchEvent +enum CellSearchEvent : s32 { CELL_SEARCH_EVENT_NOTIFICATION = 0, CELL_SEARCH_EVENT_INITIALIZE_RESULT, @@ -162,7 +165,7 @@ enum CellSearchEvent CELL_SEARCH_EVENT_SCENESEARCH_RESULT, }; -typedef void(CellSearchSystemCallback)(CellSearchEvent event, s32 result, vm::ptr param, vm::ptr userData); +using CellSearchSystemCallback = func_def param, vm::ptr userData)>; struct CellSearchContentId { @@ -177,7 +180,7 @@ struct CellSearchResultParam struct CellSearchMusicListInfo { - be_t listType; + be_t listType; // CellSearchListType be_t numOfItems; be_t duration; char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; @@ -188,7 +191,7 @@ struct CellSearchMusicListInfo struct CellSearchPhotoListInfo { - be_t listType; + be_t listType; // CellSearchListType be_t numOfItems; char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; char reserved[3]; @@ -196,7 +199,7 @@ struct CellSearchPhotoListInfo struct CellSearchVideoListInfo { - be_t listType; + be_t listType; // CellSearchListType be_t numOfItems; be_t duration; char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; @@ -216,8 +219,8 @@ struct CellSearchMusicInfo be_t quantizationBitrate; be_t playCount; be_t drmEncrypted; - be_t codec; - be_t status; + be_t codec; // CellSearchCodec + be_t status; // CellSearchContentStatus char diskNumber[8]; char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; char reserved[3]; @@ -236,9 +239,9 @@ struct CellSearchPhotoInfo be_t takenDate; be_t width; be_t height; - be_t orientation; - be_t codec; - be_t status; + be_t orientation; // CellSearchOrientation + be_t codec; // CellSearchCodec + be_t status; // CellSearchContentStatus char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; char reserved[3]; char albumTitle[CELL_SEARCH_TITLE_LEN_MAX + 1]; @@ -255,9 +258,9 @@ struct CellSearchVideoInfo be_t audioBitrate; be_t playCount; be_t drmEncrypted; - be_t videoCodec; - be_t audioCodec; - be_t status; + be_t videoCodec; // CellSearchCodec + be_t audioCodec; // CellSearchCodec + be_t status; // CellSearchContentStatus char title[CELL_SEARCH_TITLE_LEN_MAX + 1]; char reserved[3]; char albumTitle[CELL_SEARCH_TITLE_LEN_MAX + 1]; @@ -266,7 +269,7 @@ struct CellSearchVideoInfo struct CellSearchVideoSceneInfo { - be_t sceneType; + be_t sceneType; // CellSearchSceneType be_t startTime_ms; be_t endTime_ms; CellSearchContentId videoId; @@ -297,4 +300,4 @@ struct CellSearchTimeInfo be_t takenDate; be_t importedDate; be_t modifiedDate; -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 9f96909219..ca22faba25 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -2,11 +2,9 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/IdManager.h" #include "Emu/Event.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/SPUThread.h" #include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" @@ -17,500 +15,1400 @@ #include "Emu/SysCalls/lv2/sys_process.h" #include "Emu/SysCalls/lv2/sys_semaphore.h" #include "Emu/SysCalls/lv2/sys_event.h" -#include "Emu/Cell/SPURSManager.h" #include "sysPrxForUser.h" #include "cellSpurs.h" +//---------------------------------------------------------------------------- +// Externs +//---------------------------------------------------------------------------- + extern Module cellSpurs; +//---------------------------------------------------------------------------- +// Function prototypes +//---------------------------------------------------------------------------- + +// +// SPURS SPU functions +// bool spursKernelEntry(SPUThread & spu); -s32 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id); -s32 _cellSpursSendSignal(vm::ptr taskset, u32 taskID); -s32 spursCreateLv2EventQueue(vm::ptr spurs, u32& queue_id, vm::ptr port, s32 size, u64 name_u64) +// +// SPURS utility functions +// +u32 spursGetSdkVersion(); +bool spursIsLibProfLoaded(); + +// +// SPURS core functions +// +s32 spursCreateLv2EventQueue(PPUThread& CPU, vm::ptr spurs, vm::ptr queueId, vm::ptr port, s32 size, vm::cptr name); +s32 spursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool spursCreated); +s32 spursDetachLv2EventQueue(vm::ptr spurs, u8 spuPort, bool spursCreated); +void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs); +void spursHandlerEntry(PPUThread& CPU); +s32 spursCreateHandler(vm::ptr spurs, u32 ppuPriority); +s32 spursInvokeEventHandlers(PPUThread& CPU, vm::ptr eventPortMux); +s32 spursWakeUpShutdownCompletionWaiter(PPUThread& CPU, vm::ptr spurs, u32 wid); +void spursEventHelperEntry(PPUThread& CPU); +s32 spursCreateSpursEventHelper(PPUThread& CPU, vm::ptr spurs, u32 ppuPriority); +void spursInitialiseEventPortMux(vm::ptr eventPortMux, u8 spuPort, u32 eventPort, u32 unknown); +s32 spursAddDefaultSystemWorkload(vm::ptr spurs, vm::cptr swlPriority, u32 swlMaxSpu, u32 swlIsPreem); +s32 spursFinalizeSpu(vm::ptr spurs); +s32 spursStopEventHelper(PPUThread& CPU, vm::ptr spurs); +s32 spursSignalToHandlerThread(PPUThread& CPU, vm::ptr spurs); +s32 spursJoinHandlerThread(PPUThread& CPU, vm::ptr spurs); +s32 spursInit(PPUThread& CPU, vm::ptr spurs, u32 revision, u32 sdkVersion, s32 nSpus, s32 spuPriority, s32 ppuPriority, u32 flags, + vm::cptr prefix, u32 prefixSize, u32 container, vm::cptr swlPriority, u32 swlMaxSpu, u32 swlIsPreem); +s32 cellSpursInitialize(PPUThread& CPU, vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork); +s32 cellSpursInitializeWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::cptr attr); +s32 cellSpursInitializeWithAttribute2(PPUThread& CPU, vm::ptr spurs, vm::cptr attr); +s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork); +s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container); +s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::cptr prefix, u32 size); +s32 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr attr); +s32 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s32 type); +s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::cptr priority, u32 maxSpu, vm::cptr isPreemptible); +s32 cellSpursFinalize(vm::ptr spurs); +s32 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group); +s32 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads); +s32 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::ptr nThreads); +s32 cellSpursSetMaxContention(vm::ptr spurs, u32 wid, u32 maxContention); +s32 cellSpursSetPriorities(vm::ptr spurs, u32 wid, vm::cptr priorities); +s32 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::cptr isPreemptible); +s32 cellSpursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic); +s32 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port); +s32 cellSpursEnableExceptionEventHandler(vm::ptr spurs, bool flag); +s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, vm::ptr eaHandler, vm::ptr arg); +s32 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr spurs); +s32 cellSpursGetInfo(vm::ptr spurs, vm::ptr info); + +// +// SPURS SPU GUID functions +// +s32 cellSpursGetSpuGuid(); + +// +// SPURS trace functions +// +void spursTraceStatusUpdate(vm::ptr spurs); +s32 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus); +s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode); +s32 cellSpursTraceFinalize(vm::ptr spurs); +s32 spursTraceStart(vm::ptr spurs, u32 updateStatus); +s32 cellSpursTraceStart(vm::ptr spurs); +s32 spursTraceStop(vm::ptr spurs, u32 updateStatus); +s32 cellSpursTraceStop(vm::ptr spurs); + +// +// SPURS policy module functions +// +s32 _cellSpursWorkloadAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, vm::cptr pm, u32 size, u64 data, vm::cptr priority, u32 minCnt, u32 maxCnt); +s32 cellSpursWorkloadAttributeSetName(vm::ptr attr, vm::cptr nameClass, vm::cptr nameInstance); +s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr attr, vm::ptr hook, vm::ptr arg); +s32 spursAddWorkload(vm::ptr spurs, vm::ptr wid, vm::cptr pm, u32 size, u64 data, const u8 priorityTable[], u32 minContention, u32 maxContention, + vm::cptr nameClass, vm::cptr nameInstance, vm::ptr hook, vm::ptr hookArg); +s32 cellSpursAddWorkload(vm::ptr spurs, vm::ptr wid, vm::cptr pm, u32 size, u64 data, vm::cptr priority, u32 minCnt, u32 maxCnt); +s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, vm::ptr wid, vm::cptr attr); +s32 cellSpursShutdownWorkload(); +s32 cellSpursWaitForWorkloadShutdown(); +s32 cellSpursRemoveWorkload(); +s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs); +s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 wid); +s32 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::pptr flag); +s32 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value); +s32 cellSpursReadyCountSwap(); +s32 cellSpursReadyCountCompareAndSwap(); +s32 cellSpursReadyCountAdd(); +s32 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 wid); +s32 cellSpursGetWorkloadInfo(); +s32 cellSpursSetExceptionEventHandler(); +s32 cellSpursUnsetExceptionEventHandler(); +s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set); +s32 _cellSpursWorkloadFlagReceiver2(); +s32 cellSpursRequestIdleSpu(); + +// +// SPURS taskset functions +// +s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 max_contention, vm::cptr name, u32 size, s32 enable_clear_ls); +s32 cellSpursCreateTasksetWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr); +s32 cellSpursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 maxContention); +s32 cellSpursJoinTaskset(vm::ptr taskset); +s32 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid); +s32 cellSpursShutdownTaskset(vm::ptr taskset); +s32 cellSpursTasksetAttributeSetName(vm::ptr attr, vm::cptr name); +s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size); +s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable); +s32 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision); +s32 cellSpursCreateTaskset2(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr); +s32 cellSpursDestroyTaskset2(); +s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg); +s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset); +s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr spurs, vm::pptr taskset, u32 id); +s32 cellSpursTasksetGetSpursAddress(vm::cptr taskset, vm::ptr spurs); +s32 cellSpursGetTasksetInfo(); +s32 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::cptr priority, u32 max_contention); + +// +// SPURS task functions +// +s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm::cptr elf, vm::cptr context, u32 size, vm::ptr ls_pattern, vm::ptr arg); +s32 spursTaskStart(PPUThread& CPU, vm::ptr taskset, u32 taskId); +s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr taskset, vm::ptr taskId, vm::cptr elf, vm::cptr context, u32 size, vm::ptr lsPattern, vm::ptr argument); +s32 _cellSpursSendSignal(PPUThread& CPU, vm::ptr taskset, u32 taskId); +s32 cellSpursCreateTaskWithAttribute(); +s32 cellSpursTaskExitCodeGet(); +s32 cellSpursTaskExitCodeInitialize(); +s32 cellSpursTaskExitCodeTryGet(); +s32 cellSpursTaskGetLoadableSegmentPattern(); +s32 cellSpursTaskGetReadOnlyAreaPattern(); +s32 cellSpursTaskGenerateLsPattern(); +s32 _cellSpursTaskAttributeInitialize(); +s32 cellSpursTaskAttributeSetExitCodeContainer(); +s32 _cellSpursTaskAttribute2Initialize(vm::ptr attribute, u32 revision); +s32 cellSpursTaskGetContextSaveAreaSize(); +s32 cellSpursCreateTask2(); +s32 cellSpursJoinTask2(); +s32 cellSpursTryJoinTask2(); +s32 cellSpursCreateTask2WithBinInfo(); + +// +// SPURS event flag functions +// +s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr taskset, vm::ptr eventFlag, u32 flagClearMode, u32 flagDirection); +s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits); +s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr eventFlag, u16 bits); +s32 spursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block); +s32 cellSpursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode); +s32 cellSpursEventFlagTryWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode); +s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& CPU, vm::ptr eventFlag); +s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag); +s32 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::ptr direction); +s32 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::ptr clear_mode); +s32 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, vm::pptr taskset); + +// +// SPURS lock free queue functions +// +s32 _cellSpursLFQueueInitialize(); +s32 _cellSpursLFQueuePushBody(); +s32 cellSpursLFQueueDetachLv2EventQueue(); +s32 cellSpursLFQueueAttachLv2EventQueue(); +s32 _cellSpursLFQueuePopBody(); +s32 cellSpursLFQueueGetTasksetAddress(); + +// +// SPURS queue functions +// +s32 _cellSpursQueueInitialize(); +s32 cellSpursQueuePopBody(); +s32 cellSpursQueuePushBody(); +s32 cellSpursQueueAttachLv2EventQueue(); +s32 cellSpursQueueDetachLv2EventQueue(); +s32 cellSpursQueueGetTasksetAddress(); +s32 cellSpursQueueClear(); +s32 cellSpursQueueDepth(); +s32 cellSpursQueueGetEntrySize(); +s32 cellSpursQueueSize(); +s32 cellSpursQueueGetDirection(); + +// +// SPURS barrier functions +// +s32 cellSpursBarrierInitialize(); +s32 cellSpursBarrierGetTasksetAddress(); + +// +// SPURS semaphore functions +// +s32 _cellSpursSemaphoreInitialize(); +s32 cellSpursSemaphoreGetTasksetAddress(); + +// +// SPURS job chain functions +// +s32 cellSpursCreateJobChainWithAttribute(); +s32 cellSpursCreateJobChain(); +s32 cellSpursJoinJobChain(); +s32 cellSpursKickJobChain(); +s32 _cellSpursJobChainAttributeInitialize(); +s32 cellSpursGetJobChainId(); +s32 cellSpursJobChainSetExceptionEventHandler(); +s32 cellSpursJobChainUnsetExceptionEventHandler(); +s32 cellSpursGetJobChainInfo(); +s32 cellSpursJobChainGetSpursAddress(); +s32 cellSpursJobGuardInitialize(); +s32 cellSpursJobChainAttributeSetName(); +s32 cellSpursShutdownJobChain(); +s32 cellSpursJobChainAttributeSetHaltOnError(); +s32 cellSpursJobChainAttributeSetJobTypeMemoryCheck(); +s32 cellSpursJobGuardNotify(); +s32 cellSpursJobGuardReset(); +s32 cellSpursRunJobChain(); +s32 cellSpursJobChainGetError(); +s32 cellSpursGetJobPipelineInfo(); +s32 cellSpursJobSetMaxGrab(); +s32 cellSpursJobHeaderSetJobbin2Param(); +s32 cellSpursAddUrgentCommand(); +s32 cellSpursAddUrgentCall(); + +//---------------------------------------------------------------------------- +// SPURS utility functions +//---------------------------------------------------------------------------- + +/// Get the version of SDK used by this process +u32 spursGetSdkVersion() { - auto queue = Emu.GetEventManager().MakeEventQueue(SYS_SYNC_FIFO, SYS_PPU_QUEUE, name_u64, 0, size); + s32 version; - if (!queue) // rough + if (s32 rc = process_get_sdk_version(process_getpid(), version)) { - return CELL_EAGAIN; + throw EXCEPTION("process_get_sdk_version() failed (0x%x)", rc); } - queue_id = Emu.GetIdManager().add(std::move(queue)); + return version == -1 ? 0x465000 : version; +} - if (s32 res = spursAttachLv2EventQueue(spurs, queue_id, port, 1, true)) +/// Check whether libprof is loaded +bool spursIsLibProfLoaded() +{ + return false; +} + +//---------------------------------------------------------------------------- +// SPURS core functions +//---------------------------------------------------------------------------- + +/// Create an LV2 event queue and attach it to the SPURS instance +s32 spursCreateLv2EventQueue(PPUThread& CPU, vm::ptr spurs, vm::ptr queueId, vm::ptr port, s32 size, vm::cptr name) +{ + vm::stackvar attr(CPU); + + auto sys_event_queue_attribute_initialize = [](vm::ptr attr) { - assert(!"spursAttachLv2EventQueue() failed"); + attr->protocol = SYS_SYNC_PRIORITY; + attr->type = SYS_PPU_QUEUE; + attr->name[0] = '\0'; + }; + + sys_event_queue_attribute_initialize(attr); + std::memcpy(attr->name, name.get_ptr(), sizeof(attr->name)); + if (s32 rc = sys_event_queue_create(queueId, attr, SYS_EVENT_QUEUE_LOCAL, size)) + { + return rc; + } + + vm::stackvar _port(CPU); + if (s32 rc = spursAttachLv2EventQueue(CPU, spurs, *queueId, _port, 1 /*isDynamic*/, true /*spursCreated*/)) + { + sys_event_queue_destroy(*queueId, SYS_EVENT_QUEUE_DESTROY_FORCE); + } + + *port = _port; + return CELL_OK; +} + +/// Attach an LV2 event queue to the SPURS instance +s32 spursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool spursCreated) +{ + if (!spurs || !port) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (spurs->exception.data()) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + s32 sdkVer = spursGetSdkVersion(); + u8 _port = 0x3f; + u64 portMask = 0; + + if (isDynamic == 0) + { + _port = *port; + if (_port > 0x3f) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + + if (sdkVer >= 0x180000 && _port > 0xf) + { + return CELL_SPURS_CORE_ERROR_PERM; + } + } + + for (u32 i = isDynamic ? 0x10 : _port; i <= _port; i++) + { + portMask |= 1ull << (i); + } + + vm::stackvar connectedPort(CPU); + if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->spuTG, queue, portMask, connectedPort)) + { + if (res == CELL_EISCONN) + { + return CELL_SPURS_CORE_ERROR_BUSY; + } + + return res; + } + + *port = connectedPort; + if (!spursCreated) + { + spurs->spuPortBits |= 1ull << connectedPort; } return CELL_OK; } -s32 spursInit( - vm::ptr spurs, - const u32 revision, - const u32 sdkVersion, - const s32 nSpus, - const s32 spuPriority, - const s32 ppuPriority, - u32 flags, // SpursAttrFlags - const char prefix[], - const u32 prefixSize, - const u32 container, - const u8 swlPriority[], - const u32 swlMaxSpu, - const u32 swlIsPreem) +/// Detach an LV2 event queue from the SPURS instance +s32 spursDetachLv2EventQueue(vm::ptr spurs, u8 spuPort, bool spursCreated) { - // SPURS initialization (asserts should actually rollback and return the error instead) + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (!spursCreated && spurs->exception.data()) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + if (spuPort > 0x3F) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + + auto sdkVer = spursGetSdkVersion(); + if (!spursCreated) + { + auto mask = 1ull << spuPort; + if (sdkVer >= 0x180000) + { + if ((spurs->spuPortBits.load() & mask) == 0) + { + return CELL_SPURS_CORE_ERROR_SRCH; + } + } + + spurs->spuPortBits &= ~mask; + } + + return CELL_OK; +} + +/// Wait until a workload in the SPURS instance becomes ready +void spursHandlerWaitReady(PPUThread& CPU, vm::ptr spurs) +{ + if (s32 rc = sys_lwmutex_lock(CPU, spurs.of(&CellSpurs::mutex), 0)) + { + throw EXCEPTION("sys_lwmutex_lock() failed (0x%x)", rc); + } + + while (true) + { + CHECK_EMU_STATUS; + + if (spurs->handlerExiting.load()) + { + extern u32 g_ppu_func_index__sys_lwmutex_unlock; // test + + if (s32 rc = CALL_FUNC(CPU, sys_lwmutex_unlock, CPU, spurs.of(&CellSpurs::mutex))) + { + throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc); + } + + sys_ppu_thread_exit(CPU, 0); + } + + // Find a runnable workload + spurs->handlerDirty.store(0); + if (spurs->exception == 0) + { + bool foundRunnableWorkload = false; + for (u32 i = 0; i < 16; i++) + { + if (spurs->wklState1[i].load() == SPURS_WKL_STATE_RUNNABLE && + *((u64*)spurs->wklInfo1[i].priority) != 0 && + spurs->wklMaxContention[i].load() & 0x0F) + { + if (spurs->wklReadyCount1[i].load() || + spurs->wklSignal1.load() & (0x8000u >> i) || + (spurs->wklFlag.flag.load() == 0 && + spurs->wklFlagReceiver.load() == (u8)i)) + { + foundRunnableWorkload = true; + break; + } + } + } + + if (spurs->flags1 & SF1_32_WORKLOADS) + { + for (u32 i = 0; i < 16; i++) + { + if (spurs->wklState2[i].load() == SPURS_WKL_STATE_RUNNABLE && + *((u64*)spurs->wklInfo2[i].priority) != 0 && + spurs->wklMaxContention[i].load() & 0xF0) + { + if (spurs->wklIdleSpuCountOrReadyCount2[i].load() || + spurs->wklSignal2.load() & (0x8000u >> i) || + (spurs->wklFlag.flag.load() == 0 && + spurs->wklFlagReceiver.load() == (u8)i + 0x10)) + { + foundRunnableWorkload = true; + break; + } + } + } + } + + if (foundRunnableWorkload) { + break; + } + } + + // If we reach it means there are no runnable workloads in this SPURS instance. + // Wait until some workload becomes ready. + spurs->handlerWaiting.store(1); + if (spurs->handlerDirty.load() == 0) + { + if (s32 rc = sys_lwcond_wait(CPU, spurs.of(&CellSpurs::cond), 0)) + { + throw EXCEPTION("sys_lwcond_wait() failed (0x%x)", rc); + } + } + + spurs->handlerWaiting.store(0); + } + + // If we reach here then a runnable workload was found + if (s32 rc = sys_lwmutex_unlock(CPU, spurs.of(&CellSpurs::mutex))) + { + throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc); + } +} + +/// Entry point of the SPURS handler thread. This thread is responsible for starting the SPURS SPU thread group. +void spursHandlerEntry(PPUThread& CPU) +{ + auto spurs = vm::ptr::make(VM_CAST(CPU.GPR[3])); + + if (spurs->flags & SAF_UNKNOWN_FLAG_30) + { + sys_ppu_thread_exit(CPU, 0); + } + + while (true) + { + CHECK_EMU_STATUS; + + if (spurs->flags1 & SF1_EXIT_IF_NO_WORK) + { + spursHandlerWaitReady(CPU, spurs); + } + + if (s32 rc = sys_spu_thread_group_start(spurs->spuTG)) + { + throw EXCEPTION("sys_spu_thread_group_start() failed (0x%x)", rc); + } + + if (s32 rc = sys_spu_thread_group_join(spurs->spuTG, vm::null, vm::null)) + { + if (rc == CELL_ESTAT) + { + sys_ppu_thread_exit(CPU, 0); + } + + throw EXCEPTION("sys_spu_thread_group_join() failed (0x%x)", rc); + } + + if ((spurs->flags1 & SF1_EXIT_IF_NO_WORK) == 0) + { + if (spurs->handlerExiting.load() != 1) + { + throw EXCEPTION("Unexpected handlerExiting value (false)"); + } + + sys_ppu_thread_exit(CPU, 0); + } + } +} + +/// Create the SPURS handler thread +s32 spursCreateHandler(vm::ptr spurs, u32 ppuPriority) +{ + // create joinable thread with stackSize = 0x4000 and custom task + spurs->ppu0 = ppu_thread_create(0, spurs.addr(), ppuPriority, 0x4000, true, false, std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr0", spursHandlerEntry); + return CELL_OK; +} + +/// Invoke event handlers +s32 spursInvokeEventHandlers(PPUThread& CPU, vm::ptr eventPortMux) +{ + if (eventPortMux->reqPending.exchange(0).data()) + { + const vm::ptr handlerList = eventPortMux->handlerList.exchange(vm::null); + + for (auto node = handlerList; node; node = node->next) + { + node->handler(CPU, eventPortMux, node->data); + } + } + + return CELL_OK; +} + +// Invoke workload shutdown completion callbacks +s32 spursWakeUpShutdownCompletionWaiter(PPUThread& CPU, vm::ptr spurs, u32 wid) +{ + if (!spurs) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (wid >= (u32)(spurs->flags1 & SF1_32_WORKLOADS ? CELL_SPURS_MAX_WORKLOAD2 : CELL_SPURS_MAX_WORKLOAD)) + { + return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; + } + + const u8 wklState = wid < CELL_SPURS_MAX_WORKLOAD ? spurs->wklState1[wid].load() : spurs->wklState2[wid & 0x0F].load(); + + if (wklState != SPURS_WKL_STATE_REMOVABLE) + { + return CELL_SPURS_POLICY_MODULE_ERROR_STAT; + } + + auto& wklF = wid < CELL_SPURS_MAX_WORKLOAD ? spurs->wklF1[wid] : spurs->wklF2[wid & 0x0F]; + auto& wklEvent = wid < CELL_SPURS_MAX_WORKLOAD ? spurs->wklEvent1[wid] : spurs->wklEvent2[wid & 0x0F]; + + if (wklF.hook) + { + wklF.hook(CPU, spurs, wid, wklF.hookArg); + + assert(wklEvent.load() & 0x01); + assert(wklEvent.load() & 0x02); + assert((wklEvent.load() & 0x20) == 0); + wklEvent |= 0x20; + } + + s32 rc = CELL_OK; + if (!wklF.hook || wklEvent.load() & 0x10) + { + assert(wklF.x28 == 2); + rc = sys_semaphore_post((u32)wklF.sem, 1); + } + + return rc; +} + +/// Entry point of the SPURS event helper thread +void spursEventHelperEntry(PPUThread& CPU) +{ + const auto spurs = vm::ptr::make(VM_CAST(CPU.GPR[3])); + + bool terminate = false; + + vm::stackvar eventArray(CPU, sizeof32(sys_event_t) * 8); + vm::stackvar> count(CPU); + + vm::ptr events = eventArray; + + while (!terminate) + { + if (s32 rc = sys_event_queue_receive(CPU, spurs->eventQueue, vm::null, 0 /*timeout*/)) + { + throw EXCEPTION("sys_event_queue_receive() failed (0x%x)", rc); + } + + const u64 event_src = CPU.GPR[4]; + const u64 event_data1 = CPU.GPR[5]; + const u64 event_data2 = CPU.GPR[6]; + const u64 event_data3 = CPU.GPR[7]; + + if (event_src == SYS_SPU_THREAD_EVENT_EXCEPTION_KEY) + { + spurs->exception = 1; + + events[0].source = event_src; + events[0].data1 = event_data1; + events[0].data2 = event_data2; + events[0].data3 = event_data3; + + if (sys_event_queue_tryreceive(spurs->eventQueue, events + 1, 7, count) != CELL_OK) + { + continue; + } + + // TODO: Examine LS and dump exception details + + for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) + { + sys_semaphore_post((u32)spurs->wklF1[i].sem, 1); + if (spurs->flags1 & SF1_32_WORKLOADS) + { + sys_semaphore_post((u32)spurs->wklF2[i].sem, 1); + } + } + } + else + { + const u32 data0 = event_data2 & 0x00FFFFFF; + + if (data0 == 1) + { + terminate = true; + } + else if (data0 < 1) + { + const u32 shutdownMask = (u32)event_data3; + + for (auto wid = 0; wid < CELL_SPURS_MAX_WORKLOAD; wid++) + { + if (shutdownMask & (0x80000000u >> wid)) + { + if (s32 rc = spursWakeUpShutdownCompletionWaiter(CPU, spurs, wid)) + { + throw EXCEPTION("spursWakeUpShutdownCompletionWaiter() failed (0x%x)", rc); + } + } + + if ((spurs->flags1 & SF1_32_WORKLOADS) && (shutdownMask & (0x8000 >> wid))) + { + if (s32 rc = spursWakeUpShutdownCompletionWaiter(CPU, spurs, wid + 0x10)) + { + throw EXCEPTION("spursWakeUpShutdownCompletionWaiter() failed (0x%x)", rc); + } + } + } + } + else if (data0 == 2) + { + if (s32 rc = sys_semaphore_post((u32)spurs->semPrv, 1)) + { + throw EXCEPTION("sys_semaphore_post() failed (0x%x)", rc); + } + } + else if (data0 == 3) + { + if (s32 rc = spursInvokeEventHandlers(CPU, spurs.of(&CellSpurs::eventPortMux))) + { + throw EXCEPTION("spursInvokeEventHandlers() failed (0x%x)", rc); + } + } + else + { + throw EXCEPTION("Unexpected value (data0=0x%x)", data0); + } + } + } +} + +/// Create the SPURS event helper thread +s32 spursCreateSpursEventHelper(PPUThread& CPU, vm::ptr spurs, u32 ppuPriority) +{ + vm::stackvar evqName(CPU, 8); + memcpy(evqName.get_ptr(), "_spuPrv", 8); + + if (s32 rc = spursCreateLv2EventQueue(CPU, spurs, spurs.of(&CellSpurs::eventQueue), spurs.of(&CellSpurs::spuPort), 0x2A /*size*/, evqName)) + { + return rc; + } + + if (s32 rc = sys_event_port_create(spurs.of(&CellSpurs::eventPort), SYS_EVENT_PORT_LOCAL, SYS_EVENT_PORT_NO_NAME)) + { + if (s32 rc2 = spursDetachLv2EventQueue(spurs, spurs->spuPort, true /*spursCreated*/)) + { + return CELL_SPURS_CORE_ERROR_AGAIN; + } + + sys_event_queue_destroy(spurs->eventQueue, SYS_EVENT_QUEUE_DESTROY_FORCE); + return CELL_SPURS_CORE_ERROR_AGAIN; + } + + if (s32 rc = sys_event_port_connect_local(spurs->eventPort, spurs->eventQueue)) + { + sys_event_port_destroy(spurs->eventPort); + + if (s32 rc2 = spursDetachLv2EventQueue(spurs, spurs->spuPort, true /*spursCreated*/)) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + sys_event_queue_destroy(spurs->eventQueue, SYS_EVENT_QUEUE_DESTROY_FORCE); + return CELL_SPURS_CORE_ERROR_STAT; + } + + // create joinable thread with stackSize = 0x8000 and custom task + const u32 tid = ppu_thread_create(0, spurs.addr(), ppuPriority, 0x8000, true, false, std::string(spurs->prefix, spurs->prefixSize) + "SpursHdlr1", spursEventHelperEntry); + + // cannot happen in current implementation + if (tid == 0) + { + sys_event_port_disconnect(spurs->eventPort); + sys_event_port_destroy(spurs->eventPort); + + if (s32 rc = spursDetachLv2EventQueue(spurs, spurs->spuPort, true /*spursCreated*/)) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + sys_event_queue_destroy(spurs->eventQueue, SYS_EVENT_QUEUE_DESTROY_FORCE); + return CELL_SPURS_CORE_ERROR_STAT; + } + + spurs->ppu1 = tid; + return CELL_OK; +} + +/// Initialise the event port multiplexor structure +void spursInitialiseEventPortMux(vm::ptr eventPortMux, u8 spuPort, u32 eventPort, u32 unknown) +{ + memset(eventPortMux.get_ptr(), 0, sizeof(CellSpurs::EventPortMux)); + eventPortMux->spuPort = spuPort; + eventPortMux->eventPort = eventPort; + eventPortMux->x08 = unknown; +} + +/// Enable the system workload +s32 spursAddDefaultSystemWorkload(vm::ptr spurs, vm::ptr swlPriority, u32 swlMaxSpu, u32 swlIsPreem) +{ + // TODO: Implement this + return CELL_OK; +} + +/// Destroy the SPURS SPU threads and thread group +s32 spursFinalizeSpu(vm::ptr spurs) +{ + if (spurs->flags & SAF_UNKNOWN_FLAG_7 || spurs->flags & SAF_UNKNOWN_FLAG_8) + { + while (true) + { + if (s32 rc = sys_spu_thread_group_join(spurs->spuTG, vm::null, vm::null)) + { + throw EXCEPTION("sys_spu_thread_group_join() failed (0x%x)", rc); + } + + if (s32 rc = sys_spu_thread_group_destroy(spurs->spuTG)) + { + if (rc != CELL_EBUSY) + { + throw EXCEPTION("sys_spu_thread_group_destroy() failed (0x%x)", rc); + } + + continue; + } + + break; + } + } + else + { + if (s32 rc = sys_spu_thread_group_destroy(spurs->spuTG)) + { + return rc; + } + } + + if (s32 rc = sys_spu_image_close(spurs.of(&CellSpurs::spuImg))) + { + throw EXCEPTION("sys_spu_image_close() failed (0x%x)", rc); + } + + return CELL_OK; +} + +/// Stop the event helper thread +s32 spursStopEventHelper(PPUThread& CPU, vm::ptr spurs) +{ + if (spurs->ppu1 == 0xFFFFFFFF) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + if (sys_event_port_send(spurs->eventPort, 0, 1, 0) != CELL_OK) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + if (sys_ppu_thread_join(CPU, (u32)spurs->ppu1, vm::stackvar>(CPU)) != CELL_OK) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + spurs->ppu1 = 0xFFFFFFFF; + + if (s32 rc = sys_event_port_disconnect(spurs->eventPort)) + { + throw EXCEPTION("sys_event_port_disconnect() failed (0x%x)", rc); + } + + if (s32 rc = sys_event_port_destroy(spurs->eventPort)) + { + throw EXCEPTION("sys_event_port_destroy() failed (0x%x)", rc); + } + + if (s32 rc = spursDetachLv2EventQueue(spurs, spurs->spuPort, true /*spursCreated*/)) + { + throw EXCEPTION("spursDetachLv2EventQueue() failed (0x%x)", rc); + } + + if (s32 rc = sys_event_queue_destroy(spurs->eventQueue, SYS_EVENT_QUEUE_DESTROY_FORCE)) + { + throw EXCEPTION("sys_event_queue_destroy() failed (0x%x)", rc); + } + + return CELL_OK; +} + +/// Signal to the SPURS handler thread +s32 spursSignalToHandlerThread(PPUThread& CPU, vm::ptr spurs) +{ + if (s32 rc = sys_lwmutex_lock(CPU, spurs.of(&CellSpurs::mutex), 0 /* forever */)) + { + throw EXCEPTION("sys_lwmutex_lock() failed (0x%x)", rc); + } + + if (s32 rc = sys_lwcond_signal(CPU, spurs.of(&CellSpurs::cond))) + { + throw EXCEPTION("sys_lwcond_signal() failed (0x%x)", rc); + } + + if (s32 rc = sys_lwmutex_unlock(CPU, spurs.of(&CellSpurs::mutex))) + { + throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc); + } + + return CELL_OK; +} + +/// Join the SPURS handler thread +s32 spursJoinHandlerThread(PPUThread& CPU, vm::ptr spurs) +{ + if (spurs->ppu0 == 0xFFFFFFFF) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + if (s32 rc = sys_ppu_thread_join(CPU, (u32)spurs->ppu0, vm::stackvar>(CPU))) + { + throw EXCEPTION("sys_ppu_thread_join() failed (0x%x)", rc); + } + + spurs->ppu0 = 0xFFFFFFFF; + return CELL_OK; +} + +/// Initialise SPURS +s32 spursInit( + PPUThread& CPU, + vm::ptr spurs, + u32 revision, + u32 sdkVersion, + s32 nSpus, + s32 spuPriority, + s32 ppuPriority, + u32 flags, // SpursAttrFlags + vm::cptr prefix, + u32 prefixSize, + u32 container, + vm::cptr swlPriority, + u32 swlMaxSpu, + u32 swlIsPreem) +{ + vm::stackvar> sem(CPU); + vm::stackvar semAttr(CPU); + vm::stackvar lwCondAttr(CPU); + vm::stackvar lwMutexAttr(CPU); + vm::stackvar> spuTgId(CPU); + vm::stackvar spuTgName(CPU, 128); + vm::stackvar spuTgAttr(CPU); + vm::stackvar spuThArgs(CPU); + vm::stackvar> spuThreadId(CPU); + vm::stackvar spuThAttr(CPU); + vm::stackvar spuThName(CPU, 128); if (!spurs) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } + if (prefixSize > CELL_SPURS_NAME_MAX_LENGTH) { return CELL_SPURS_CORE_ERROR_INVAL; } - if (process_is_spu_lock_line_reservation_address(spurs.addr(), SYS_MEMORY_ACCESS_RIGHT_SPU_THR) != CELL_OK) + + if (sys_process_is_spu_lock_line_reservation_address(spurs.addr(), SYS_MEMORY_ACCESS_RIGHT_SPU_THR) != CELL_OK) { return CELL_SPURS_CORE_ERROR_PERM; } + // Intialise SPURS context const bool isSecond = (flags & SAF_SECOND_VERSION) != 0; - memset(spurs.get_ptr(), 0, CellSpurs::size1 + isSecond * CellSpurs::size2); - spurs->m.revision = revision; - spurs->m.sdkVersion = sdkVersion; - spurs->m.ppu0 = 0xffffffffull; - spurs->m.ppu1 = 0xffffffffull; - spurs->m.flags = flags; - memcpy(spurs->m.prefix, prefix, prefixSize); - spurs->m.prefixSize = (u8)prefixSize; - std::string name(prefix, prefixSize); // initialize name string + auto rollback = [=] + { + if (spurs->semPrv) + { + sys_semaphore_destroy((u32)spurs->semPrv); + } + + for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) + { + if (spurs->wklF1[i].sem) + { + sys_semaphore_destroy((u32)spurs->wklF1[i].sem); + } + + if (isSecond) + { + if (spurs->wklF2[i].sem) + { + sys_semaphore_destroy((u32)spurs->wklF2[i].sem); + } + } + } + }; + + memset(spurs.get_ptr(), 0, isSecond ? CELL_SPURS_SIZE2 : CELL_SPURS_SIZE); + spurs->revision = revision; + spurs->sdkVersion = sdkVersion; + spurs->ppu0 = 0xffffffffull; + spurs->ppu1 = 0xffffffffull; + spurs->flags = flags; + spurs->prefixSize = (u8)prefixSize; + memcpy(spurs->prefix, prefix.get_ptr(), prefixSize); if (!isSecond) { - spurs->m.wklMskA.write_relaxed(be_t::make(0xffff)); + spurs->wklEnabled.store(0xffff); } - spurs->m.xCC = 0; - spurs->m.xCD = 0; - spurs->m.sysSrvMsgUpdateTrace = 0; + + // Initialise trace + spurs->sysSrvTrace = {}; + for (u32 i = 0; i < 8; i++) { - spurs->m.sysSrvWorkload[i] = -1; + spurs->sysSrvPreemptWklId[i] = -1; } - // default or system workload: - spurs->m.wklInfoSysSrv.addr.set(be_t::make(SPURS_IMG_ADDR_SYS_SRV_WORKLOAD)); - spurs->m.wklInfoSysSrv.arg = 0; - spurs->m.wklInfoSysSrv.uniqueId.write_relaxed(0xff); - u32 sem; - for (u32 i = 0; i < 0x10; i++) + // Import default system workload + spurs->wklInfoSysSrv.addr.set(SPURS_IMG_ADDR_SYS_SRV_WORKLOAD); + spurs->wklInfoSysSrv.size = 0x2200; + spurs->wklInfoSysSrv.arg = 0; + spurs->wklInfoSysSrv.uniqueId.store(0xff); + + auto sys_semaphore_attribute_initialize = [](vm::ptr attr) { - sem = Emu.GetIdManager().make(0, 1, SYS_SYNC_PRIORITY, *(u64*)"_spuWkl"); - assert(sem && ~sem); // should rollback if semaphore creation failed and return the error - spurs->m.wklF1[i].sem = sem; - } - if (isSecond) + attr->protocol = SYS_SYNC_PRIORITY; + attr->pshared = SYS_SYNC_NOT_PROCESS_SHARED; + attr->ipc_key = 0; + attr->flags = 0; + attr->name[0] = '\0'; + }; + + // Create semaphores for each workload + // TODO: Find out why these semaphores are needed + sys_semaphore_attribute_initialize(semAttr); + memcpy(semAttr->name, "_spuWkl", 8); + for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - for (u32 i = 0; i < 0x10; i++) + if (s32 rc = sys_semaphore_create(sem, semAttr, 0, 1)) // Emu.GetIdManager().make(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuWkl", 0) { - sem = Emu.GetIdManager().make(0, 1, SYS_SYNC_PRIORITY, *(u64*)"_spuWkl"); - assert(sem && ~sem); - spurs->m.wklF2[i].sem = sem; + return rollback(), rc; + } + + spurs->wklF1[i].sem = sem.value(); + + if (isSecond) + { + if (s32 rc = sys_semaphore_create(sem, semAttr, 0, 1)) // Emu.GetIdManager().make(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuWkl", 0) + { + return rollback(), rc; + } + + spurs->wklF2[i].sem = sem.value(); } } - sem = Emu.GetIdManager().make(0, 1, SYS_SYNC_PRIORITY, *(u64*)"_spuPrv"); - assert(sem && ~sem); - spurs->m.semPrv = sem; - spurs->m.unk11 = -1; - spurs->m.unk12 = -1; - spurs->m.unk13 = 0; - spurs->m.nSpus = nSpus; - spurs->m.spuPriority = spuPriority; - spurs->m.spuImg.addr = Memory.MainMem.AllocAlign(0x40000, 4096); - spurs->m.spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; - - s32 tgt = SYS_SPU_THREAD_GROUP_TYPE_NORMAL; - if (flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) + // Create semaphore + // TODO: Figure out why this semaphore is needed + memcpy(semAttr->name, "_spuPrv", 8); + if (s32 rc = sys_semaphore_create(sem, semAttr, 0, 1)) // Emu.GetIdManager().make(SYS_SYNC_PRIORITY, 1, *(u64*)"_spuPrv", 0); { - tgt = SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT; + return rollback(), rc; } - else if (flags & SAF_UNKNOWN_FLAG_0) - { - tgt = 0xC02; - } - if (flags & SAF_SPU_MEMORY_CONTAINER_SET) tgt |= SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER; - if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) tgt |= SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM; - if (flags & SAF_UNKNOWN_FLAG_7) tgt |= 0x102; - if (flags & SAF_UNKNOWN_FLAG_8) tgt |= 0xC02; - if (flags & SAF_UNKNOWN_FLAG_9) tgt |= 0x800; - spurs->m.spuTG = spu_thread_group_create(name + "CellSpursKernelGroup", nSpus, spuPriority, tgt, container); - assert(spurs->m.spuTG.data()); - name += "CellSpursKernel0"; - for (s32 num = 0; num < nSpus; num++, name[name.size() - 1]++) + spurs->semPrv = sem.value(); + + spurs->unk11 = -1; + spurs->unk12 = -1; + spurs->unk13 = 0; + spurs->nSpus = nSpus; + spurs->spuPriority = spuPriority; + + // Import SPURS kernel + spurs->spuImg.type = SYS_SPU_IMAGE_TYPE_USER; + spurs->spuImg.addr = (u32)Memory.Alloc(0x40000, 4096); + spurs->spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; + spurs->spuImg.nsegs = 1; + + // Create a thread group for this SPURS context + memcpy(spuTgName.get_ptr(), spurs->prefix, spurs->prefixSize); + spuTgName[spurs->prefixSize] = '\0'; + strcat(spuTgName.get_ptr(), "CellSpursKernelGroup"); + + auto sys_spu_thread_group_attribute_initialize = [](vm::ptr attr) { - spurs->m.spus[num] = spu_thread_initialize(spurs->m.spuTG, num, vm::ptr::make(spurs.addr() + offsetof(CellSpurs, m.spuImg)), - name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, (u64)num << 32, spurs.addr(), 0, 0, [spurs](SPUThread& SPU) + attr->name = vm::null; + attr->nsize = 0; + attr->type = SYS_SPU_THREAD_GROUP_TYPE_NORMAL; + }; + + sys_spu_thread_group_attribute_initialize(spuTgAttr); + spuTgAttr->name = spuTgName; + spuTgAttr->nsize = (u32)strlen(spuTgAttr->name.get_ptr()) + 1; + + if (spurs->flags & SAF_UNKNOWN_FLAG_0) + { + spuTgAttr->type = 0x0C00 | SYS_SPU_THREAD_GROUP_TYPE_SYSTEM; + } + else if (flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) + { + spuTgAttr->type = SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT; + } + else + { + spuTgAttr->type = SYS_SPU_THREAD_GROUP_TYPE_NORMAL; + } + + if (spurs->flags & SAF_SPU_MEMORY_CONTAINER_SET) + { + spuTgAttr->type |= SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER; + spuTgAttr->ct = container; + } + + if (flags & SAF_UNKNOWN_FLAG_7) spuTgAttr->type |= 0x0100 | SYS_SPU_THREAD_GROUP_TYPE_SYSTEM; + if (flags & SAF_UNKNOWN_FLAG_8) spuTgAttr->type |= 0x0C00 | SYS_SPU_THREAD_GROUP_TYPE_SYSTEM; + if (flags & SAF_UNKNOWN_FLAG_9) spuTgAttr->type |= 0x0800; + if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) spuTgAttr->type |= SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM; + + if (s32 rc = sys_spu_thread_group_create(spuTgId, nSpus, spuPriority, spuTgAttr)) + { + sys_spu_image_close(spurs.of(&CellSpurs::spuImg)); + return rollback(), rc; + } + + spurs->spuTG = spuTgId.value(); + + // Initialise all SPUs in the SPU thread group + memcpy(spuThName.get_ptr(), spurs->prefix, spurs->prefixSize); + spuThName[spurs->prefixSize] = '\0'; + strcat(spuThName.get_ptr(), "CellSpursKernel"); + + spuThAttr->name = spuThName; + spuThAttr->name_len = (u32)strlen(spuThName.get_ptr()) + 2; + spuThAttr->option = SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE; + spuThName[spuThAttr->name_len - 1] = '\0'; + + for (s32 num = 0; num < nSpus; num++) + { + spuThName[spuThAttr->name_len - 2] = '0' + num; + spuThArgs->arg1 = (u64)num << 32; + spuThArgs->arg2 = (u64)spurs.addr(); + + if (s32 rc = sys_spu_thread_initialize(spuThreadId, spurs->spuTG, num, spurs.of(&CellSpurs::spuImg), spuThAttr, spuThArgs)) { - SPU.RegisterHleFunction(spurs->m.spuImg.entry_point, spursKernelEntry); - SPU.FastCall(spurs->m.spuImg.entry_point); - }); + sys_spu_thread_group_destroy(spurs->spuTG); + sys_spu_image_close(spurs.of(&CellSpurs::spuImg)); + return rollback(), rc; + } + + const auto spuThread = Emu.GetIdManager().get(spurs->spus[num] = spuThreadId.value()); + + // entry point cannot be initialized immediately because SPU LS will be rewritten by sys_spu_thread_group_start() + spuThread->m_custom_task = [spurs](SPUThread& SPU) + { + SPU.RegisterHleFunction(spurs->spuImg.entry_point, spursKernelEntry); + SPU.FastCall(spurs->spuImg.entry_point); + }; } + // Start the SPU printf server if required if (flags & SAF_SPU_PRINTF_ENABLED) { // spu_printf: attach group - if (!spu_printf_agcb || spu_printf_agcb(spurs->m.spuTG) != CELL_OK) + if (!spu_printf_agcb || spu_printf_agcb(CPU, spurs->spuTG) != CELL_OK) { // remove flag if failed - spurs->m.flags &= ~SAF_SPU_PRINTF_ENABLED; + spurs->flags &= ~SAF_SPU_PRINTF_ENABLED; } } - lwmutex_create(spurs->m.mutex, false, SYS_SYNC_PRIORITY, *(u64*)"_spuPrv"); - lwcond_create(spurs->m.cond, spurs->m.mutex, *(u64*)"_spuPrv"); + const auto lwMutex = spurs.of(&CellSpurs::mutex); + const auto lwCond = spurs.of(&CellSpurs::cond); - spurs->m.flags1 = (flags & SAF_EXIT_IF_NO_WORK ? SF1_EXIT_IF_NO_WORK : 0) | (isSecond ? SF1_32_WORKLOADS : 0); - spurs->m.wklFlagReceiver.write_relaxed(0xff); - spurs->m.wklFlag.flag.write_relaxed(be_t::make(-1)); - spurs->_u8[0xD64] = 0; - spurs->_u8[0xD65] = 0; - spurs->_u8[0xD66] = 0; - spurs->m.ppuPriority = ppuPriority; - - u32 queue; - if (s32 res = spursCreateLv2EventQueue(spurs, queue, vm::ptr::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv")) + auto sys_lwmutex_attribute_initialize = [](vm::ptr attr) { - assert(!"spursCreateLv2EventQueue() failed"); - } - spurs->m.queue = queue; + attr->protocol = SYS_SYNC_PRIORITY; + attr->recursive = SYS_SYNC_NOT_RECURSIVE; + attr->name[0] = '\0'; + }; - u32 port = Emu.GetIdManager().make(SYS_EVENT_PORT_LOCAL, 0); - assert(port && ~port); - spurs->m.port = port; - - if (s32 res = sys_event_port_connect_local(port, queue)) + // Create a mutex to protect access to SPURS handler thread data + sys_lwmutex_attribute_initialize(lwMutexAttr); + memcpy(lwMutexAttr->name, "_spuPrv", 8); + if (s32 rc = sys_lwmutex_create(lwMutex, lwMutexAttr)) { - assert(!"sys_event_port_connect_local() failed"); + spursFinalizeSpu(spurs); + return rollback(), rc; } - name = std::string(prefix, prefixSize); - - spurs->m.ppu0 = ppu_thread_create(0, 0, ppuPriority, 0x4000, true, false, name + "SpursHdlr0", [spurs](PPUThread& CPU) + // Create condition variable to signal the SPURS handler thread + memcpy(lwCondAttr->name, "_spuPrv", 8); + if (s32 rc = sys_lwcond_create(lwCond, lwMutex, lwCondAttr)) { - if (spurs->m.flags & SAF_UNKNOWN_FLAG_30) + sys_lwmutex_destroy(CPU, lwMutex); + spursFinalizeSpu(spurs); + return rollback(), rc; + } + + spurs->flags1 = (flags & SAF_EXIT_IF_NO_WORK ? SF1_EXIT_IF_NO_WORK : 0) | (isSecond ? SF1_32_WORKLOADS : 0); + spurs->wklFlagReceiver.store(0xff); + spurs->wklFlag.flag.store(-1); + spurs->handlerDirty.store(0); + spurs->handlerWaiting.store(0); + spurs->handlerExiting.store(0); + spurs->ppuPriority = ppuPriority; + + // Create the SPURS event helper thread + if (s32 rc = spursCreateSpursEventHelper(CPU, spurs, ppuPriority)) + { + sys_lwcond_destroy(lwCond); + sys_lwmutex_destroy(CPU, lwMutex); + spursFinalizeSpu(spurs); + return rollback(), rc; + } + + // Create the SPURS handler thread + if (s32 rc = spursCreateHandler(spurs, ppuPriority)) + { + spursStopEventHelper(CPU, spurs); + sys_lwcond_destroy(lwCond); + sys_lwmutex_destroy(CPU, lwMutex); + spursFinalizeSpu(spurs); + return rollback(), rc; + } + + // Enable SPURS exception handler + if (s32 rc = cellSpursEnableExceptionEventHandler(spurs, true /*enable*/)) + { + spursSignalToHandlerThread(CPU, spurs); + spursJoinHandlerThread(CPU, spurs); + spursStopEventHelper(CPU, spurs); + sys_lwcond_destroy(lwCond); + sys_lwmutex_destroy(CPU, lwMutex); + spursFinalizeSpu(spurs); + return rollback(), rc; + } + + spurs->traceBuffer = vm::null; + // TODO: Register libprof for user trace + + // Initialise the event port multiplexor + spursInitialiseEventPortMux(spurs.of(&CellSpurs::eventPortMux), spurs->spuPort, spurs->eventPort, 3); + + // Enable the default system workload if required + if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) + { + if (s32 rc = spursAddDefaultSystemWorkload(spurs, swlPriority, swlMaxSpu, swlIsPreem)) { - return; - } - - while (true) - { - if (Emu.IsStopped()) - { - cellSpurs.Warning("SPURS Handler Thread 0 aborted"); - return; - } - - if (spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) - { - if (s32 res = sys_lwmutex_lock(CPU, spurs->get_lwmutex(), 0)) - { - assert(!"sys_lwmutex_lock() failed"); - } - if (spurs->m.xD66.read_relaxed()) - { - if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex())) - { - assert(!"sys_lwmutex_unlock() failed"); - } - return; - } - else while (true) - { - if (Emu.IsStopped()) break; - - spurs->m.xD64.exchange(0); - if (spurs->m.exception.data() == 0) - { - bool do_break = false; - for (u32 i = 0; i < 16; i++) - { - if (spurs->m.wklState1[i].read_relaxed() == 2 && - *((u64 *)spurs->m.wklInfo1[i].priority) != 0 && - spurs->m.wklMaxContention[i].read_relaxed() & 0xf - ) - { - if (spurs->m.wklReadyCount1[i].read_relaxed() || - spurs->m.wklSignal1.read_relaxed() & (0x8000u >> i) || - (spurs->m.wklFlag.flag.read_relaxed() == 0 && - spurs->m.wklFlagReceiver.read_relaxed() == (u8)i - )) - { - do_break = true; - break; - } - } - } - if (spurs->m.flags1 & SF1_32_WORKLOADS) for (u32 i = 0; i < 16; i++) - { - if (spurs->m.wklState2[i].read_relaxed() == 2 && - *((u64 *)spurs->m.wklInfo2[i].priority) != 0 && - spurs->m.wklMaxContention[i].read_relaxed() & 0xf0 - ) - { - if (spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed() || - spurs->m.wklSignal2.read_relaxed() & (0x8000u >> i) || - (spurs->m.wklFlag.flag.read_relaxed() == 0 && - spurs->m.wklFlagReceiver.read_relaxed() == (u8)i + 0x10 - )) - { - do_break = true; - break; - } - } - } - if (do_break) break; // from while - } - - spurs->m.xD65.exchange(1); - if (spurs->m.xD64.read_relaxed() == 0) - { - if (s32 res = sys_lwcond_wait(CPU, spurs->get_lwcond(), 0)) - { - assert(!"sys_lwcond_wait() failed"); - } - } - spurs->m.xD65.exchange(0); - if (spurs->m.xD66.read_relaxed()) - { - if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex())) - { - assert(!"sys_lwmutex_unlock() failed"); - } - return; - } - } - - if (Emu.IsStopped()) continue; - - if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex())) - { - assert(!"sys_lwmutex_unlock() failed"); - } - } - - if (Emu.IsStopped()) continue; - - if (s32 res = sys_spu_thread_group_start(spurs->m.spuTG)) - { - assert(!"sys_spu_thread_group_start() failed"); - } - if (s32 res = sys_spu_thread_group_join(spurs->m.spuTG, vm::null, vm::null)) - { - if (res == CELL_ESTAT) - { - return; - } - assert(!"sys_spu_thread_group_join() failed"); - } - - if (Emu.IsStopped()) continue; - - if ((spurs->m.flags1 & SF1_EXIT_IF_NO_WORK) == 0) - { - assert(spurs->m.xD66.read_relaxed() == 1 || Emu.IsStopped()); - return; - } - } - }); - - spurs->m.ppu1 = ppu_thread_create(0, 0, ppuPriority, 0x8000, true, false, name + "SpursHdlr1", [spurs](PPUThread& CPU) - { - // TODO - - }); - - // enable exception event handler - if (spurs->m.enableEH.compare_and_swap_test(be_t::make(0), be_t::make(1))) - { - if (s32 res = sys_spu_thread_group_connect_event(spurs->m.spuTG, spurs->m.queue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION)) - { - assert(!"sys_spu_thread_group_connect_event() failed"); + throw EXCEPTION("spursAddDefaultSystemWorkload() failed (0x%x)", rc); } + + return CELL_OK; } - - spurs->m.traceBuffer.set(0); - // can also use cellLibprof if available (omitted) - - // some unknown subroutine - spurs->m.sub3.unk1 = spurs.addr() + 0xc9; - spurs->m.sub3.unk2 = 3; // unknown const - spurs->m.sub3.port = (u64)spurs->m.port; - - if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) // initialize system workload (disabled) + else if (flags & SAF_EXIT_IF_NO_WORK) { - s32 res = CELL_OK; - // TODO - assert(res == CELL_OK); - } - else if (flags & SAF_EXIT_IF_NO_WORK) // wakeup - { - return spursWakeUp(GetCurrentPPUThread(), spurs); + return cellSpursWakeUp(CPU, spurs); } - return CELL_OK; + return CELL_OK; } -s32 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) +/// Initialise SPURS +s32 cellSpursInitialize(PPUThread& CPU, vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { - cellSpurs.Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", - spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0); + cellSpurs.Warning("cellSpursInitialize(spurs=*0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs, nSpus, spuPriority, ppuPriority, exitIfNoWork); - return spursInit( - spurs, - 0, - 0, - nSpus, - spuPriority, - ppuPriority, - exitIfNoWork ? SAF_EXIT_IF_NO_WORK : SAF_NONE, - nullptr, - 0, - 0, - nullptr, - 0, - 0); + return spursInit(CPU, spurs, 0, 0, nSpus, spuPriority, ppuPriority, exitIfNoWork ? SAF_EXIT_IF_NO_WORK : SAF_NONE, vm::null, 0, 0, vm::null, 0, 0); } -s32 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptr attr) +/// Initialise SPURS +s32 cellSpursInitializeWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::cptr attr) { - cellSpurs.Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); + cellSpurs.Warning("cellSpursInitializeWithAttribute(spurs=*0x%x, attr=*0x%x)", spurs, attr); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (attr->m.revision > 2) + + if (attr->revision > 2) { return CELL_SPURS_CORE_ERROR_INVAL; } - + return spursInit( + CPU, spurs, - attr->m.revision, - attr->m.sdkVersion, - attr->m.nSpus, - attr->m.spuPriority, - attr->m.ppuPriority, - attr->m.flags | (attr->m.exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0), - attr->m.prefix, - attr->m.prefixSize, - attr->m.container, - attr->m.swlPriority, - attr->m.swlMaxSpu, - attr->m.swlIsPreem); + attr->revision, + attr->sdkVersion, + attr->nSpus, + attr->spuPriority, + attr->ppuPriority, + attr->flags | (attr->exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0), + attr.of(&CellSpursAttribute::prefix, 0), + attr->prefixSize, + attr->container, + attr.of(&CellSpursAttribute::swlPriority, 0), + attr->swlMaxSpu, + attr->swlIsPreem); } -s32 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptr attr) +/// Initialise SPURS +s32 cellSpursInitializeWithAttribute2(PPUThread& CPU, vm::ptr spurs, vm::cptr attr) { - cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); + cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs=*0x%x, attr=*0x%x)", spurs, attr); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (attr->m.revision > 2) + + if (attr->revision > 2) { return CELL_SPURS_CORE_ERROR_INVAL; } return spursInit( + CPU, spurs, - attr->m.revision, - attr->m.sdkVersion, - attr->m.nSpus, - attr->m.spuPriority, - attr->m.ppuPriority, - attr->m.flags | (attr->m.exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0) | SAF_SECOND_VERSION, - attr->m.prefix, - attr->m.prefixSize, - attr->m.container, - attr->m.swlPriority, - attr->m.swlMaxSpu, - attr->m.swlIsPreem); + attr->revision, + attr->sdkVersion, + attr->nSpus, + attr->spuPriority, + attr->ppuPriority, + attr->flags | (attr->exitIfNoWork ? SAF_EXIT_IF_NO_WORK : 0) | SAF_SECOND_VERSION, + attr.of(&CellSpursAttribute::prefix, 0), + attr->prefixSize, + attr->container, + attr.of(&CellSpursAttribute::swlPriority, 0), + attr->swlMaxSpu, + attr->swlIsPreem); } +/// Initialise SPURS attribute s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { - cellSpurs.Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", - attr.addr(), revision, sdkVersion, nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0); + cellSpurs.Warning("_cellSpursAttributeInitialize(attr=*0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", + attr, revision, sdkVersion, nSpus, spuPriority, ppuPriority, exitIfNoWork); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - memset(attr.get_ptr(), 0, attr->size); - attr->m.revision = revision; - attr->m.sdkVersion = sdkVersion; - attr->m.nSpus = nSpus; - attr->m.spuPriority = spuPriority; - attr->m.ppuPriority = ppuPriority; - attr->m.exitIfNoWork = exitIfNoWork; + memset(attr.get_ptr(), 0, sizeof(CellSpursAttribute)); + attr->revision = revision; + attr->sdkVersion = sdkVersion; + attr->nSpus = nSpus; + attr->spuPriority = spuPriority; + attr->ppuPriority = ppuPriority; + attr->exitIfNoWork = exitIfNoWork; return CELL_OK; } +/// Set memory container ID for creating the SPU thread group s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container) { - cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", attr.addr(), container); + cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr=*0x%x, container=0x%x)", attr, container); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (attr->m.flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) + if (attr->flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) { return CELL_SPURS_CORE_ERROR_STAT; } - attr->m.container = container; - attr->m.flags |= SAF_SPU_MEMORY_CONTAINER_SET; + attr->container = container; + attr->flags |= SAF_SPU_MEMORY_CONTAINER_SET; return CELL_OK; } -s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr prefix, u32 size) +/// Set the prefix for SPURS +s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::cptr prefix, u32 size) { - cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=%d)", attr.addr(), prefix.addr(), size); + cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr=*0x%x, prefix=*0x%x, size=%d)", attr, prefix, size); if (!attr || !prefix) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } @@ -520,79 +1418,87 @@ s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptrm.prefix, prefix.get_ptr(), size); - attr->m.prefixSize = size; + memcpy(attr->prefix, prefix.get_ptr(), size); + attr->prefixSize = size; return CELL_OK; } +/// Enable spu_printf() s32 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr attr) { - cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.addr()); + cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr=*0x%x)", attr); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - attr->m.flags |= SAF_SPU_PRINTF_ENABLED; + attr->flags |= SAF_SPU_PRINTF_ENABLED; return CELL_OK; } +/// Set the type of SPU thread group s32 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s32 type) { - cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.addr(), type); + cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr=*0x%x, type=%d)", attr, type); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } if (type == SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT) { - if (attr->m.flags & SAF_SPU_MEMORY_CONTAINER_SET) + if (attr->flags & SAF_SPU_MEMORY_CONTAINER_SET) { return CELL_SPURS_CORE_ERROR_STAT; } - attr->m.flags |= SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // set + attr->flags |= SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // set } else if (type == SYS_SPU_THREAD_GROUP_TYPE_NORMAL) { - attr->m.flags &= ~SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // clear + attr->flags &= ~SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT; // clear } else { return CELL_SPURS_CORE_ERROR_INVAL; } + return CELL_OK; } -s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::ptr priority, u32 maxSpu, vm::ptr isPreemptible) +/// Enable the system workload +s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::cptr priority, u32 maxSpu, vm::cptr isPreemptible) { - cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)", - attr.addr(), priority.addr(), maxSpu, isPreemptible.addr()); + cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr=*0x%x, priority=*0x%x, maxSpu=%d, isPreemptible=*0x%x)", attr, priority, maxSpu, isPreemptible); if (!attr) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) + + if (!attr.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - const u32 nSpus = attr->_u32[2]; + const u32 nSpus = attr->nSpus; + if (!nSpus) { return CELL_SPURS_CORE_ERROR_INVAL; } + for (u32 i = 0; i < nSpus; i++) { if ((*priority)[i] == 1) @@ -601,17 +1507,19 @@ s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: { return CELL_SPURS_CORE_ERROR_INVAL; } - if (nSpus == 1 || attr->m.exitIfNoWork) + + if (nSpus == 1 || attr->exitIfNoWork) { return CELL_SPURS_CORE_ERROR_PERM; } - if (attr->m.flags & SAF_SYSTEM_WORKLOAD_ENABLED) + + if (attr->flags & SAF_SYSTEM_WORKLOAD_ENABLED) { return CELL_SPURS_CORE_ERROR_BUSY; } - attr->m.flags |= SAF_SYSTEM_WORKLOAD_ENABLED; // set flag - *(u64*)attr->m.swlPriority = *(u64*)*priority; // copy system workload priorities + attr->flags |= SAF_SYSTEM_WORKLOAD_ENABLED; // set flag + *(u64*)attr->swlPriority = *(u64*)*priority; // copy system workload priorities u32 isPreem = 0; // generate mask from isPreemptible values for (u32 j = 0; j < nSpus; j++) @@ -621,266 +1529,641 @@ s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: isPreem |= (1 << j); } } - attr->m.swlMaxSpu = maxSpu; // write max spu for system workload - attr->m.swlIsPreem = isPreem; // write isPreemptible mask + + attr->swlMaxSpu = maxSpu; // write max spu for system workload + attr->swlIsPreem = isPreem; // write isPreemptible mask return CELL_OK; } } + return CELL_SPURS_CORE_ERROR_INVAL; } +/// Release resources allocated for SPURS s32 cellSpursFinalize(vm::ptr spurs) { - cellSpurs.Todo("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr()); + cellSpurs.Todo("cellSpursFinalize(spurs=*0x%x)", spurs); if (!spurs) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - if (spurs->m.xD66.read_relaxed()) + + if (spurs->handlerExiting.load()) { return CELL_SPURS_CORE_ERROR_STAT; } - // TODO + u32 wklEnabled = spurs->wklEnabled.load(); + if (spurs->flags1 & SF1_32_WORKLOADS) + { + wklEnabled &= 0xFFFF0000; + } + + if (spurs->flags & SAF_SYSTEM_WORKLOAD_ENABLED) + { + } + + // TODO: Implement the rest of this function return CELL_OK; } -s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated) -{ - if (!spurs || !port) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - if (spurs.addr() % 128) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - if (spurs->m.exception.data()) - { - return CELL_SPURS_CORE_ERROR_STAT; - } - - s32 sdk_ver; - if (s32 res = process_get_sdk_version(process_getpid(), sdk_ver)) - { - assert(!"process_get_sdk_version() failed"); - } - if (sdk_ver == -1) sdk_ver = 0x460000; - - u8 _port = 0x3f; - u64 port_mask = 0; - - if (isDynamic == 0) - { - _port = *port; - if (_port > 0x3f) - { - return CELL_SPURS_CORE_ERROR_INVAL; - } - if (sdk_ver > 0x17ffff && _port > 0xf) - { - return CELL_SPURS_CORE_ERROR_PERM; - } - } - - for (u32 i = isDynamic ? 0x10 : _port; i <= _port; i++) - { - port_mask |= 1ull << (i); - } - - assert(port_mask); // zero mask will return CELL_EINVAL - if (s32 res = sys_spu_thread_group_connect_event_all_threads(spurs->m.spuTG, queue, port_mask, port)) - { - if (res == CELL_EISCONN) - { - return CELL_SPURS_CORE_ERROR_BUSY; - } - return res; - } - - if (!wasCreated) - { - spurs->m.spups |= be_t::make(1ull << *port); // atomic bitwise or - } - return CELL_OK; -} - -s32 cellSpursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) -{ - cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%d)", - spurs.addr(), queue, port.addr(), isDynamic); - - return spursAttachLv2EventQueue(spurs, queue, port, isDynamic, false); -} - -s32 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port) -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursGetSpuGuid() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - +/// Get the SPU thread group ID s32 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) { - cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.addr(), group.addr()); + cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs=*0x%x, group=*0x%x)", spurs, group); if (!spurs || !group) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - *group = spurs->m.spuTG; + *group = spurs->spuTG; return CELL_OK; } +// Get the number of SPU threads s32 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) { - cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), nThreads.addr()); + cellSpurs.Warning("cellSpursGetNumSpuThread(spurs=*0x%x, nThreads=*0x%x)", spurs, nThreads); if (!spurs || !nThreads) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - *nThreads = (u32)spurs->m.nSpus; + *nThreads = spurs->nSpus; return CELL_OK; } +/// Get SPU thread ids s32 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::ptr nThreads) { - cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), thread.addr(), nThreads.addr()); + cellSpurs.Warning("cellSpursGetSpuThreadId(spurs=*0x%x, thread=*0x%x, nThreads=*0x%x)", spurs, thread, nThreads); if (!spurs || !thread || !nThreads) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + + if (!spurs.aligned()) { return CELL_SPURS_CORE_ERROR_ALIGN; } - const u32 count = std::min(*nThreads, spurs->m.nSpus); + const u32 count = std::min(*nThreads, spurs->nSpus); + for (u32 i = 0; i < count; i++) { - thread[i] = spurs->m.spus[i]; + thread[i] = spurs->spus[i]; } + *nThreads = count; return CELL_OK; } -s32 cellSpursSetMaxContention(vm::ptr spurs, u32 workloadId, u32 maxContention) +/// Set the maximum contention for a workload +s32 cellSpursSetMaxContention(vm::ptr spurs, u32 wid, u32 maxContention) +{ + cellSpurs.Warning("cellSpursSetMaxContention(spurs=*0x%x, wid=%d, maxContention=%d)", spurs, wid, maxContention); + + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? CELL_SPURS_MAX_WORKLOAD2 : CELL_SPURS_MAX_WORKLOAD)) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_CORE_ERROR_SRCH; + } + + if (spurs->exception.data()) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + if (maxContention > CELL_SPURS_MAX_SPU) + { + maxContention = CELL_SPURS_MAX_SPU; + } + + spurs->wklMaxContention[wid % CELL_SPURS_MAX_WORKLOAD].atomic_op([spurs, wid, maxContention](u8& value) + { + value &= wid < CELL_SPURS_MAX_WORKLOAD ? 0xF0 : 0x0F; + value |= wid < CELL_SPURS_MAX_WORKLOAD ? maxContention : maxContention << 4; + }); + + return CELL_OK; +} + +/// Set the priority of a workload on each SPU +s32 cellSpursSetPriorities(vm::ptr spurs, u32 wid, vm::cptr priorities) +{ + cellSpurs.Warning("cellSpursSetPriorities(spurs=*0x%x, wid=%d, priorities=*0x%x)", spurs, wid, priorities); + + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? CELL_SPURS_MAX_WORKLOAD2 : CELL_SPURS_MAX_WORKLOAD)) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_CORE_ERROR_SRCH; + } + + if (spurs->exception.data()) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + if (spurs->flags & SAF_SYSTEM_WORKLOAD_ENABLED) + { + // TODO: Implement this + } + + u64 prio = 0; + for (s32 i = 0; i < CELL_SPURS_MAX_SPU; i++) + { + if (priorities[i] >= CELL_SPURS_MAX_PRIORITY) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + + prio |= priorities[i]; + prio <<= 8; + } + + auto& wklInfo = wid < CELL_SPURS_MAX_WORKLOAD ? spurs->wklInfo1[wid] : spurs->wklInfo2[wid]; + *((be_t*)wklInfo.priority) = prio; + + spurs->sysSrvMsgUpdateWorkload.store(0xFF); + spurs->sysSrvMessage.store(0xFF); + return CELL_OK; +} + +/// Set preemption victim SPU +s32 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::cptr isPreemptible) { UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; } -s32 cellSpursSetPriorities(vm::ptr spurs, u32 workloadId, vm::ptr priorities) +/// Attach an LV2 event queue to a SPURS instance +s32 cellSpursAttachLv2EventQueue(PPUThread& CPU, vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) { - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; + cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs=*0x%x, queue=0x%x, port=*0x%x, isDynamic=%d)", spurs, queue, port, isDynamic); + + return spursAttachLv2EventQueue(CPU, spurs, queue, port, isDynamic, false /*spursCreated*/); } -s32 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::ptr isPreemptible) +/// Detach an LV2 event queue from a SPURS instance +s32 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port) { - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; + cellSpurs.Warning("cellSpursDetachLv2EventQueue(spurs=*0x%x, port=%d)", spurs, port); + + return spursDetachLv2EventQueue(spurs, port, false /*spursCreated*/); } +/// Enable the SPU exception event handler s32 cellSpursEnableExceptionEventHandler(vm::ptr spurs, bool flag) { - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; + cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs=*0x%x, flag=%d)", spurs, flag); + + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + s32 rc = CELL_OK; + auto oldEnableEH = spurs->enableEH.exchange(flag ? 1u : 0u); + if (flag) + { + if (oldEnableEH == 0) + { + rc = sys_spu_thread_group_connect_event(spurs->spuTG, spurs->eventQueue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION); + } + } + else + { + if (oldEnableEH == 1) + { + rc = sys_spu_thread_group_disconnect_event(spurs->eventQueue, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION); + } + } + + return rc; } -s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, u32 eaHandler_addr, u32 arg_addr) +/// Set the global SPU exception event handler +s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, vm::ptr eaHandler, vm::ptr arg) { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs.Warning("cellSpursSetGlobalExceptionEventHandler(spurs=*0x%x, eaHandler=*0x%x, arg=*0x%x)", spurs, eaHandler, arg); + + if (!spurs || !eaHandler) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (spurs->exception.data()) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + auto handler = spurs->globalSpuExceptionHandler.compare_and_swap(0, 1); + if (handler) + { + return CELL_SPURS_CORE_ERROR_BUSY; + } + + spurs->globalSpuExceptionHandlerArgs = arg.addr(); + spurs->globalSpuExceptionHandler.exchange(eaHandler.addr()); return CELL_OK; } + +/// Remove the global SPU exception event handler s32 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr spurs) { - UNIMPLEMENTED_FUNC(cellSpurs); + cellSpurs.Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs=*0x%x)", spurs); + + spurs->globalSpuExceptionHandlerArgs = 0; + spurs->globalSpuExceptionHandler.exchange(0); return CELL_OK; } +/// Get internal information of a SPURS instance s32 cellSpursGetInfo(vm::ptr spurs, vm::ptr info) { UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; } -s32 spursWakeUp(PPUThread& CPU, vm::ptr spurs) -{ - if (!spurs) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (spurs.addr() % 128) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - if (spurs->m.exception.data()) - { - return CELL_SPURS_POLICY_MODULE_ERROR_STAT; - } +//---------------------------------------------------------------------------- +// SPURS SPU GUID functions +//---------------------------------------------------------------------------- - spurs->m.xD64.exchange(1); - if (spurs->m.xD65.read_sync()) - { - if (s32 res = sys_lwmutex_lock(CPU, spurs->get_lwmutex(), 0)) - { - assert(!"sys_lwmutex_lock() failed"); - } - if (s32 res = sys_lwcond_signal(CPU, spurs->get_lwcond())) - { - assert(!"sys_lwcond_signal() failed"); - } - if (s32 res = sys_lwmutex_unlock(CPU, spurs->get_lwmutex())) - { - assert(!"sys_lwmutex_unlock() failed"); - } - } +/// Get the SPU GUID from a .SpuGUID section +s32 cellSpursGetSpuGuid() +{ + UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; } -s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) -{ - cellSpurs.Warning("%s(spurs_addr=0x%x)", __FUNCTION__, spurs.addr()); +//---------------------------------------------------------------------------- +// SPURS trace functions +//---------------------------------------------------------------------------- - return spursWakeUp(CPU, spurs); +/// Signal SPUs to update trace status +void spursTraceStatusUpdate(vm::ptr spurs) +{ + u8 init; + + spurs->sysSrvTrace.atomic_op([spurs, &init](CellSpurs::SrvTraceSyncVar& data) + { + if ((init = data.sysSrvTraceInitialised)) + { + data.sysSrvNotifyUpdateTraceComplete = 1; + data.sysSrvMsgUpdateTrace = (1 << spurs->nSpus) - 1; + } + }); + + if (init) + { + spurs->sysSrvMessage.store(0xFF); + + if (s32 rc = sys_semaphore_wait((u32)spurs->semPrv, 0)) + { + throw EXCEPTION("sys_semaphore_wait() failed (0x%x)", rc); + } + } } +/// Initialize SPURS trace +s32 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus) +{ + if (!spurs || !buffer) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned() || !buffer.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (size < sizeof32(CellSpursTraceInfo) || mode & ~(CELL_SPURS_TRACE_MODE_FLAG_MASK)) + { + return CELL_SPURS_CORE_ERROR_INVAL; + } + + if (spurs->traceBuffer) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + spurs->traceDataSize = size - sizeof32(CellSpursTraceInfo); + for (u32 i = 0; i < 8; i++) + { + buffer->spuThread[i] = spurs->spus[i]; + buffer->count[i] = 0; + } + + buffer->spuThreadGroup = spurs->spuTG; + buffer->numSpus = spurs->nSpus; + spurs->traceBuffer.set(buffer.addr() | (mode & CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER ? 1 : 0)); + spurs->traceMode = mode; + + u32 spuTraceDataCount = (u32)((spurs->traceDataSize / sizeof32(CellSpursTracePacket)) / spurs->nSpus); + for (u32 i = 0, j = 8; i < 6; i++) + { + spurs->traceStartIndex[i] = j; + j += spuTraceDataCount; + } + + spurs->sysSrvTraceControl = 0; + if (updateStatus) + { + spursTraceStatusUpdate(spurs); + } + + return CELL_OK; +} + +/// Initialize SPURS trace +s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode) +{ + cellSpurs.Warning("cellSpursTraceInitialize(spurs=*0x%x, buffer=*0x%x, size=0x%x, mode=0x%x)", spurs, buffer, size, mode); + + if (spursIsLibProfLoaded()) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + return spursTraceInitialize(spurs, buffer, size, mode, 1); +} + +/// Finalize SPURS trace +s32 cellSpursTraceFinalize(vm::ptr spurs) +{ + cellSpurs.Warning("cellSpursTraceFinalize(spurs=*0x%x)", spurs); + + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (!spurs->traceBuffer) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + spurs->sysSrvTraceControl = 0; + spurs->traceMode = 0; + spurs->traceBuffer = vm::null; + spursTraceStatusUpdate(spurs); + return CELL_OK; +} + +/// Start SPURS trace +s32 spursTraceStart(vm::ptr spurs, u32 updateStatus) +{ + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (!spurs->traceBuffer) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + spurs->sysSrvTraceControl = 1; + if (updateStatus) + { + spursTraceStatusUpdate(spurs); + } + + return CELL_OK; +} + +/// Start SPURS trace +s32 cellSpursTraceStart(vm::ptr spurs) +{ + cellSpurs.Warning("cellSpursTraceStart(spurs=*0x%x)", spurs); + + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + return spursTraceStart(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); +} + +/// Stop SPURS trace +s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) +{ + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + if (!spurs->traceBuffer) + { + return CELL_SPURS_CORE_ERROR_STAT; + } + + spurs->sysSrvTraceControl = 2; + if (updateStatus) + { + spursTraceStatusUpdate(spurs); + } + + return CELL_OK; +} + +/// Stop SPURS trace +s32 cellSpursTraceStop(vm::ptr spurs) +{ + cellSpurs.Warning("cellSpursTraceStop(spurs=*0x%x)", spurs); + + if (!spurs) + { + return CELL_SPURS_CORE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_CORE_ERROR_ALIGN; + } + + return spursTraceStop(spurs, spurs->traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); +} + +//---------------------------------------------------------------------------- +// SPURS policy module functions +//---------------------------------------------------------------------------- + +/// Initialize attributes of a workload +s32 _cellSpursWorkloadAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, vm::cptr pm, u32 size, u64 data, vm::cptr priority, u32 minCnt, u32 maxCnt) +{ + cellSpurs.Warning("_cellSpursWorkloadAttributeInitialize(attr=*0x%x, revision=%d, sdkVersion=0x%x, pm=*0x%x, size=0x%x, data=0x%llx, priority=*0x%x, minCnt=0x%x, maxCnt=0x%x)", + attr, revision, sdkVersion, pm, size, data, priority, minCnt, maxCnt); + + if (!attr) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (!pm) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (pm % 16) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (minCnt == 0 || *(u64*)*priority & 0xf0f0f0f0f0f0f0f0ull) // check if some priority > 15 + { + return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; + } + + memset(attr.get_ptr(), 0, sizeof(CellSpursWorkloadAttribute)); + attr->revision = revision; + attr->sdkVersion = sdkVersion; + attr->pm = pm; + attr->size = size; + attr->data = data; + *(u64*)attr->priority = *(u64*)*priority; + attr->minContention = minCnt; + attr->maxContention = maxCnt; + return CELL_OK; +} + +/// Set the name of a workload +s32 cellSpursWorkloadAttributeSetName(vm::ptr attr, vm::cptr nameClass, vm::cptr nameInstance) +{ + cellSpurs.Warning("cellSpursWorkloadAttributeSetName(attr=*0x%x, nameClass=*0x%x, nameInstance=*0x%x)", attr, nameClass, nameInstance); + + if (!attr) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + attr->nameClass = nameClass; + attr->nameInstance = nameInstance; + return CELL_OK; +} + +/// Set a hook function for shutdown completion event of a workload +s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr attr, vm::ptr hook, vm::ptr arg) +{ + cellSpurs.Warning("cellSpursWorkloadAttributeSetShutdownCompletionEventHook(attr=*0x%x, hook=*0x%x, arg=*0x%x)", attr, hook, arg); + + if (!attr || !hook) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + attr->hook = hook; + attr->hookArg = arg; + return CELL_OK; +} + +/// Add workload s32 spursAddWorkload( vm::ptr spurs, vm::ptr wid, - vm::ptr pm, + vm::cptr pm, u32 size, u64 data, const u8 priorityTable[], u32 minContention, u32 maxContention, - vm::ptr nameClass, - vm::ptr nameInstance, + vm::cptr nameClass, + vm::cptr nameInstance, vm::ptr hook, vm::ptr hookArg) { @@ -888,22 +2171,25 @@ s32 spursAddWorkload( { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128 || pm.addr() % 16) + + if (!spurs.aligned() || pm % 16) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } + if (minContention == 0 || *(u64*)priorityTable & 0xf0f0f0f0f0f0f0f0ull) // check if some priority > 15 { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - if (spurs->m.exception.data()) + + if (spurs->exception.data()) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } u32 wnum; - const u32 wmax = spurs->m.flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u; // TODO: check if can be changed - spurs->m.wklMskA.atomic_op([spurs, wmax, &wnum](be_t& value) + const u32 wmax = spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u; // TODO: check if can be changed + spurs->wklEnabled.atomic_op([spurs, wmax, &wnum](be_t& value) { wnum = cntlz32(~(u32)value); // found empty position if (wnum < wmax) @@ -921,86 +2207,95 @@ s32 spursAddWorkload( u32 index = wnum & 0xf; if (wnum <= 15) { - assert((spurs->m.wklCurrentContention[wnum] & 0xf) == 0); - assert((spurs->m.wklPendingContention[wnum] & 0xf) == 0); - spurs->m.wklState1[wnum].write_relaxed(1); - spurs->m.wklStatus1[wnum] = 0; - spurs->m.wklEvent1[wnum] = 0; - spurs->m.wklInfo1[wnum].addr = pm; - spurs->m.wklInfo1[wnum].arg = data; - spurs->m.wklInfo1[wnum].size = size; + assert((spurs->wklCurrentContention[wnum] & 0xf) == 0); + assert((spurs->wklPendingContention[wnum] & 0xf) == 0); + spurs->wklState1[wnum].store(1); + spurs->wklStatus1[wnum] = 0; + spurs->wklEvent1[wnum].store(0); + spurs->wklInfo1[wnum].addr = pm; + spurs->wklInfo1[wnum].arg = data; + spurs->wklInfo1[wnum].size = size; + for (u32 i = 0; i < 8; i++) { - spurs->m.wklInfo1[wnum].priority[i] = priorityTable[i]; + spurs->wklInfo1[wnum].priority[i] = priorityTable[i]; } - spurs->m.wklH1[wnum].nameClass = nameClass; - spurs->m.wklH1[wnum].nameInstance = nameInstance; - memset(spurs->m.wklF1[wnum].unk0, 0, 0x20); // clear struct preserving semaphore id - memset(spurs->m.wklF1[wnum].unk1, 0, 0x58); + + spurs->wklH1[wnum].nameClass = nameClass; + spurs->wklH1[wnum].nameInstance = nameInstance; + memset(spurs->wklF1[wnum].unk0, 0, 0x20); // clear struct preserving semaphore id + memset(&spurs->wklF1[wnum].x28, 0, 0x58); + if (hook) { - spurs->m.wklF1[wnum].hook = hook; - spurs->m.wklF1[wnum].hookArg = hookArg; - spurs->m.wklEvent1[wnum] |= 2; + spurs->wklF1[wnum].hook = hook; + spurs->wklF1[wnum].hookArg = hookArg; + spurs->wklEvent1[wnum] |= 2; } - if ((spurs->m.flags1 & SF1_32_WORKLOADS) == 0) + + if ((spurs->flags1 & SF1_32_WORKLOADS) == 0) { - spurs->m.wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0); - spurs->m.wklMinContention[wnum] = minContention > 8 ? 8 : minContention; + spurs->wklIdleSpuCountOrReadyCount2[wnum].store(0); + spurs->wklMinContention[wnum] = minContention > 8 ? 8 : minContention; } - spurs->m.wklReadyCount1[wnum].write_relaxed(0); + + spurs->wklReadyCount1[wnum].store(0); } else { - assert((spurs->m.wklCurrentContention[index] & 0xf0) == 0); - assert((spurs->m.wklPendingContention[index] & 0xf0) == 0); - spurs->m.wklState2[index].write_relaxed(1); - spurs->m.wklStatus2[index] = 0; - spurs->m.wklEvent2[index] = 0; - spurs->m.wklInfo2[index].addr = pm; - spurs->m.wklInfo2[index].arg = data; - spurs->m.wklInfo2[index].size = size; + assert((spurs->wklCurrentContention[index] & 0xf0) == 0); + assert((spurs->wklPendingContention[index] & 0xf0) == 0); + spurs->wklState2[index].store(1); + spurs->wklStatus2[index] = 0; + spurs->wklEvent2[index].store(0); + spurs->wklInfo2[index].addr = pm; + spurs->wklInfo2[index].arg = data; + spurs->wklInfo2[index].size = size; + for (u32 i = 0; i < 8; i++) { - spurs->m.wklInfo2[index].priority[i] = priorityTable[i]; + spurs->wklInfo2[index].priority[i] = priorityTable[i]; } - spurs->m.wklH2[index].nameClass = nameClass; - spurs->m.wklH2[index].nameInstance = nameInstance; - memset(spurs->m.wklF2[index].unk0, 0, 0x20); // clear struct preserving semaphore id - memset(spurs->m.wklF2[index].unk1, 0, 0x58); + + spurs->wklH2[index].nameClass = nameClass; + spurs->wklH2[index].nameInstance = nameInstance; + memset(spurs->wklF2[index].unk0, 0, 0x20); // clear struct preserving semaphore id + memset(&spurs->wklF2[index].x28, 0, 0x58); + if (hook) { - spurs->m.wklF2[index].hook = hook; - spurs->m.wklF2[index].hookArg = hookArg; - spurs->m.wklEvent2[index] |= 2; + spurs->wklF2[index].hook = hook; + spurs->wklF2[index].hookArg = hookArg; + spurs->wklEvent2[index] |= 2; } - spurs->m.wklIdleSpuCountOrReadyCount2[wnum].write_relaxed(0); + + spurs->wklIdleSpuCountOrReadyCount2[wnum].store(0); } if (wnum <= 15) { - spurs->m.wklMaxContention[wnum].atomic_op([maxContention](u8& v) + spurs->wklMaxContention[wnum].atomic_op([maxContention](u8& v) { v &= ~0xf; v |= (maxContention > 8 ? 8 : maxContention); }); - spurs->m.wklSignal1._and_not({ be_t::make(0x8000 >> index) }); // clear bit in wklFlag1 + spurs->wklSignal1._and_not(0x8000 >> index); // clear bit in wklFlag1 } else { - spurs->m.wklMaxContention[index].atomic_op([maxContention](u8& v) + spurs->wklMaxContention[index].atomic_op([maxContention](u8& v) { v &= ~0xf0; v |= (maxContention > 8 ? 8 : maxContention) << 4; }); - spurs->m.wklSignal2._and_not({ be_t::make(0x8000 >> index) }); // clear bit in wklFlag2 + spurs->wklSignal2._and_not(0x8000 >> index); // clear bit in wklFlag2 } - spurs->m.wklFlagReceiver.compare_and_swap(wnum, 0xff); + spurs->wklFlagReceiver.compare_and_swap(wnum, 0xff); u32 res_wkl; - CellSpurs::WorkloadInfo& wkl = wnum <= 15 ? spurs->m.wklInfo1[wnum] : spurs->m.wklInfo2[wnum & 0xf]; - spurs->m.wklMskB.atomic_op_sync([spurs, &wkl, wnum, &res_wkl](be_t& v) + CellSpurs::WorkloadInfo& wkl = wnum <= 15 ? spurs->wklInfo1[wnum] : spurs->wklInfo2[wnum & 0xf]; + spurs->wklMskB.atomic_op([spurs, &wkl, wnum, &res_wkl](be_t& v) { const u32 mask = v & ~(0x80000000u >> wnum); res_wkl = 0; @@ -1009,16 +2304,16 @@ s32 spursAddWorkload( { if (mask & m) { - CellSpurs::WorkloadInfo& current = i <= 15 ? spurs->m.wklInfo1[i] : spurs->m.wklInfo2[i & 0xf]; - if (current.addr.addr() == wkl.addr.addr()) + CellSpurs::WorkloadInfo& current = i <= 15 ? spurs->wklInfo1[i] : spurs->wklInfo2[i & 0xf]; + if (current.addr == wkl.addr) { // if a workload with identical policy module found - res_wkl = current.uniqueId.read_relaxed(); + res_wkl = current.uniqueId.load(); break; } else { - k |= 0x80000000 >> current.uniqueId.read_relaxed(); + k |= 0x80000000 >> current.uniqueId.load(); res_wkl = cntlz32(~k); } } @@ -1030,208 +2325,330 @@ s32 spursAddWorkload( assert(res_wkl <= 31); spurs->wklState(wnum).exchange(2); - spurs->m.sysSrvMsgUpdateWorkload.exchange(0xff); - spurs->m.sysSrvMessage.exchange(0xff); + spurs->sysSrvMsgUpdateWorkload.exchange(0xff); + spurs->sysSrvMessage.exchange(0xff); return CELL_OK; } -s32 cellSpursAddWorkload( - vm::ptr spurs, - vm::ptr wid, - vm::ptr pm, - u32 size, - u64 data, - vm::ptr priorityTable, - u32 minContention, - u32 maxContention) +/// Add workload +s32 cellSpursAddWorkload(vm::ptr spurs, vm::ptr wid, vm::cptr pm, u32 size, u64 data, vm::cptr priority, u32 minCnt, u32 maxCnt) { - cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", - __FUNCTION__, spurs.addr(), wid.addr(), pm.addr(), size, data, priorityTable.addr(), minContention, maxContention); + cellSpurs.Warning("cellSpursAddWorkload(spurs=*0x%x, wid=*0x%x, pm=*0x%x, size=0x%x, data=0x%llx, priority=*0x%x, minCnt=0x%x, maxCnt=0x%x)", + spurs, wid, pm, size, data, priority, minCnt, maxCnt); - return spursAddWorkload( - spurs, - wid, - pm, - size, - data, - *priorityTable, - minContention, - maxContention, - vm::null, - vm::null, - vm::null, - vm::null); + return spursAddWorkload(spurs, wid, pm, size, data, *priority, minCnt, maxCnt, vm::null, vm::null, vm::null, vm::null); } -s32 _cellSpursWorkloadAttributeInitialize( - vm::ptr attr, - u32 revision, - u32 sdkVersion, - vm::ptr pm, - u32 size, - u64 data, - vm::ptr priorityTable, - u32 minContention, - u32 maxContention) +/// Add workload +s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, vm::ptr wid, vm::cptr attr) { - cellSpurs.Warning("%s(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", - __FUNCTION__, attr.addr(), revision, sdkVersion, pm.addr(), size, data, priorityTable.addr(), minContention, maxContention); + cellSpurs.Warning("cellSpursAddWorkloadWithAttribute(spurs=*0x%x, wid=*0x%x, attr=*0x%x)", spurs, wid, attr); if (!attr) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (attr.addr() % 8) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - if (!pm) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (pm.addr() % 16) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - if (minContention == 0 || *(u64*)*priorityTable & 0xf0f0f0f0f0f0f0f0ull) // check if some priority > 15 - { - return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; - } - - memset(attr.get_ptr(), 0, CellSpursWorkloadAttribute::size); - attr->m.revision = revision; - attr->m.sdkVersion = sdkVersion; - attr->m.pm = pm; - attr->m.size = size; - attr->m.data = data; - *(u64*)attr->m.priority = *(u64*)*priorityTable; - attr->m.minContention = minContention; - attr->m.maxContention = maxContention; - return CELL_OK; -} -s32 cellSpursWorkloadAttributeSetName(vm::ptr attr, vm::ptr nameClass, vm::ptr nameInstance) -{ - cellSpurs.Warning("%s(attr_addr=0x%x, nameClass_addr=0x%x, nameInstance_addr=0x%x)", __FUNCTION__, attr.addr(), nameClass.addr(), nameInstance.addr()); - - if (!attr) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (attr.addr() % 8) + if (!attr.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - attr->m.nameClass = nameClass; - attr->m.nameInstance = nameInstance; - return CELL_OK; -} - -s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr attr, vm::ptr hook, vm::ptr arg) -{ - cellSpurs.Warning("%s(attr_addr=0x%x, hook_addr=0x%x, arg=0x%x)", __FUNCTION__, attr.addr(), hook.addr(), arg.addr()); - - if (!attr || !hook) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (attr.addr() % 8) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - - attr->m.hook = hook; - attr->m.hookArg = arg; - return CELL_OK; -} - -s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptr wid, vm::ptr attr) -{ - cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, attr_addr=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), attr.addr()); - - if (!attr) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (attr.addr() % 8) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - if (attr->m.revision != be_t::make(1)) + if (attr->revision != 1) { return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; } - return spursAddWorkload( - spurs, - wid, - attr->m.pm, - attr->m.size, - attr->m.data, - attr->m.priority, - attr->m.minContention, - attr->m.maxContention, - attr->m.nameClass, - attr->m.nameInstance, - attr->m.hook, - attr->m.hookArg); -} - -s32 cellSpursRemoveWorkload() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursWaitForWorkloadShutdown() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; + return spursAddWorkload(spurs, wid, attr->pm, attr->size, attr->data, attr->priority, attr->minContention, attr->maxContention, attr->nameClass, attr->nameInstance, attr->hook, attr->hookArg); } +/// Request workload shutdown s32 cellSpursShutdownWorkload() { UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; } -s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set) +/// Wait for workload shutdown +s32 cellSpursWaitForWorkloadShutdown() { - cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, is_set=%d)", __FUNCTION__, spurs.addr(), wid, is_set); + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Remove workload +s32 cellSpursRemoveWorkload() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Activate the SPURS kernel +s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) +{ + cellSpurs.Warning("cellSpursWakeUp(spurs=*0x%x)", spurs); if (!spurs) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; } - if (spurs.addr() % 128) + + if (!spurs.aligned()) { return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; } - if (wid >= (spurs->m.flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u)) - { - return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; - } - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0) - { - return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; - } - if (spurs->m.exception.data()) + + if (spurs->exception.data()) { return CELL_SPURS_POLICY_MODULE_ERROR_STAT; } - if (s32 res = spurs->m.wklFlag.flag.atomic_op_sync(0, [spurs, wid, is_set](be_t& flag) -> s32 + + spurs->handlerDirty.exchange(1); + + if (spurs->handlerWaiting.load()) + { + spursSignalToHandlerThread(CPU, spurs); + } + + return CELL_OK; +} + +/// Send a workload signal +s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 wid) +{ + cellSpurs.Warning("cellSpursSendWorkloadSignal(spurs=*0x%x, wid=%d)", spurs, wid); + + if (!spurs) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (wid >= CELL_SPURS_MAX_WORKLOAD2 || (wid >= CELL_SPURS_MAX_WORKLOAD && (spurs->flags1 & SF1_32_WORKLOADS) == 0)) + { + return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; + } + + if (spurs->exception) + { + return CELL_SPURS_POLICY_MODULE_ERROR_STAT; + } + + if (spurs->wklState(wid).load() != SPURS_WKL_STATE_RUNNABLE) + { + return CELL_SPURS_POLICY_MODULE_ERROR_STAT; + } + + if (wid >= CELL_SPURS_MAX_WORKLOAD) + { + spurs->wklSignal2 |= 0x8000 >> (wid & 0x0F); + } + else + { + spurs->wklSignal1 |= 0x8000 >> wid; + } + + return CELL_OK; +} + +/// Get the address of the workload flag +s32 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::pptr flag) +{ + cellSpurs.Warning("cellSpursGetWorkloadFlag(spurs=*0x%x, flag=**0x%x)", spurs, flag); + + if (!spurs || !flag) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + *flag = spurs.of(&CellSpurs::wklFlag); + return CELL_OK; +} + +/// Set ready count +s32 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) +{ + cellSpurs.Warning("cellSpursReadyCountStore(spurs=*0x%x, wid=%d, value=0x%x)", spurs, wid, value); + + if (!spurs) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u) || value > 0xff) + { + return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; + } + + if (spurs->exception.data() || spurs->wklState(wid).load() != 2) + { + return CELL_SPURS_POLICY_MODULE_ERROR_STAT; + } + + if (wid < CELL_SPURS_MAX_WORKLOAD) + { + spurs->wklReadyCount1[wid].exchange((u8)value); + } + else + { + spurs->wklIdleSpuCountOrReadyCount2[wid].exchange((u8)value); + } + + return CELL_OK; +} + +/// Swap ready count +s32 cellSpursReadyCountSwap() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Compare and swap ready count +s32 cellSpursReadyCountCompareAndSwap() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Increase or decrease ready count +s32 cellSpursReadyCountAdd() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Get workload's data to be passed to policy module +s32 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 wid) +{ + cellSpurs.Warning("cellSpursGetWorkloadData(spurs=*0x%x, data=*0x%x, wid=%d)", spurs, data, wid); + + if (!spurs || !data) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (wid >= CELL_SPURS_MAX_WORKLOAD2 || (wid >= CELL_SPURS_MAX_WORKLOAD && (spurs->flags1 & SF1_32_WORKLOADS) == 0)) + { + return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; + } + + if (spurs->exception) + { + return CELL_SPURS_POLICY_MODULE_ERROR_STAT; + } + + if (wid >= CELL_SPURS_MAX_WORKLOAD) + { + *data = spurs->wklInfo2[wid & 0x0F].arg; + } + else + { + *data = spurs->wklInfo1[wid].arg; + } + + return CELL_OK; +} + +/// Get workload information +s32 cellSpursGetWorkloadInfo() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Set the SPU exception event handler +s32 cellSpursSetExceptionEventHandler() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Disable the SPU exception event handler +s32 cellSpursUnsetExceptionEventHandler() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +/// Set/unset the recipient of the workload flag +s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set) +{ + cellSpurs.Warning("_cellSpursWorkloadFlagReceiver(spurs=*0x%x, wid=%d, is_set=%d)", spurs, wid, is_set); + + if (!spurs) + { + return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; + } + + if (!spurs.aligned()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; + } + + if (wid >= (spurs->flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u)) + { + return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; + } + + if ((spurs->wklEnabled.load() & (0x80000000u >> wid)) == 0) + { + return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; + } + + if (spurs->exception.data()) + { + return CELL_SPURS_POLICY_MODULE_ERROR_STAT; + } + + _mm_mfence(); + + if (s32 res = spurs->wklFlag.flag.atomic_op([spurs, wid, is_set](be_t& flag) -> s32 { if (is_set) { - if (spurs->m.wklFlagReceiver.read_relaxed() != 0xff) + if (spurs->wklFlagReceiver.load() != 0xff) { return CELL_SPURS_POLICY_MODULE_ERROR_BUSY; } } else { - if (spurs->m.wklFlagReceiver.read_relaxed() != wid) + if (spurs->wklFlagReceiver.load() != wid) { return CELL_SPURS_POLICY_MODULE_ERROR_PERM; } @@ -1243,7 +2660,7 @@ s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set return res; } - spurs->m.wklFlagReceiver.atomic_op([wid, is_set](u8& FR) + spurs->wklFlagReceiver.atomic_op([wid, is_set](u8& FR) { if (is_set) { @@ -1263,225 +2680,40 @@ s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set return CELL_OK; } -s32 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::pptr flag) -{ - cellSpurs.Warning("%s(spurs_addr=0x%x, flag_addr=0x%x)", __FUNCTION__, spurs.addr(), flag.addr()); - - if (!spurs || !flag) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (spurs.addr() % 128) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - - flag->set(vm::get_addr(&spurs->m.wklFlag)); - return CELL_OK; -} - -s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) -{ - cellSpurs.Warning("%s(spurs=0x%x, workloadId=0x%x)", __FUNCTION__, spurs.addr(), workloadId); - - if (spurs.addr() == 0) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - - if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->m.flags1 & SF1_32_WORKLOADS) == 0)) - { - return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; - } - - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0) - { - return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; - } - - if (spurs->m.exception) - { - return CELL_SPURS_POLICY_MODULE_ERROR_STAT; - } - - u8 state; - if (workloadId >= CELL_SPURS_MAX_WORKLOAD) - { - state = spurs->m.wklState2[workloadId & 0x0F].read_relaxed(); - } - else - { - state = spurs->m.wklState1[workloadId].read_relaxed(); - } - - if (state != SPURS_WKL_STATE_RUNNABLE) - { - return CELL_SPURS_POLICY_MODULE_ERROR_STAT; - } - - if (workloadId >= CELL_SPURS_MAX_WORKLOAD) - { - spurs->m.wklSignal2 |= be_t::make(0x8000 >> (workloadId & 0x0F)); - } - else - { - spurs->m.wklSignal1 |= be_t::make(0x8000 >> workloadId); - } - - return CELL_OK; -} - -s32 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 workloadId) -{ - cellSpurs.Warning("%s(spurs_addr=0x%x, data=0x%x, workloadId=%d)", __FUNCTION__, spurs.addr(), data.addr(), workloadId); - - if (spurs.addr() == 0 || data.addr() == 0) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - - if (workloadId >= CELL_SPURS_MAX_WORKLOAD2 || (workloadId >= CELL_SPURS_MAX_WORKLOAD && (spurs->m.flags1 & SF1_32_WORKLOADS) == 0)) - { - return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; - } - - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> workloadId)) == 0) - { - return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; - } - - if (spurs->m.exception) - { - return CELL_SPURS_POLICY_MODULE_ERROR_STAT; - } - - if (workloadId >= CELL_SPURS_MAX_WORKLOAD) - { - *data = spurs->m.wklInfo2[workloadId & 0x0F].arg; - } - else - { - *data = spurs->m.wklInfo1[workloadId].arg; - } - - return CELL_OK; -} - -s32 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) -{ - cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, value=0x%x)", __FUNCTION__, spurs.addr(), wid, value); - - if (!spurs) - { - return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; - } - if (spurs.addr() % 128) - { - return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN; - } - if (wid >= (spurs->m.flags1 & SF1_32_WORKLOADS ? 0x20u : 0x10u) || value > 0xff) - { - return CELL_SPURS_POLICY_MODULE_ERROR_INVAL; - } - if ((spurs->m.wklMskA.read_relaxed() & (0x80000000u >> wid)) == 0) - { - return CELL_SPURS_POLICY_MODULE_ERROR_SRCH; - } - if (spurs->m.exception.data() || spurs->wklState(wid).read_relaxed() != 2) - { - return CELL_SPURS_POLICY_MODULE_ERROR_STAT; - } - - if (wid < CELL_SPURS_MAX_WORKLOAD) - { - spurs->m.wklReadyCount1[wid].exchange((u8)value); - } - else - { - spurs->m.wklIdleSpuCountOrReadyCount2[wid].exchange((u8)value); - } - return CELL_OK; -} - -s32 cellSpursReadyCountAdd() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursReadyCountCompareAndSwap() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursReadyCountSwap() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursRequestIdleSpu() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursGetWorkloadInfo() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - +/// Set/unset the recipient of the workload flag s32 _cellSpursWorkloadFlagReceiver2() { UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; } -s32 cellSpursSetExceptionEventHandler() +/// Request assignment of idle SPUs +s32 cellSpursRequestIdleSpu() { UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; } -s32 cellSpursUnsetExceptionEventHandler() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} +//---------------------------------------------------------------------------- +// SPURS event flag functions +//---------------------------------------------------------------------------- +/// Initialize a SPURS event flag s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr taskset, vm::ptr eventFlag, u32 flagClearMode, u32 flagDirection) { - cellSpurs.Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%d, flagDirection=%d)", - spurs.addr(), taskset.addr(), eventFlag.addr(), flagClearMode, flagDirection); + cellSpurs.Warning("_cellSpursEventFlagInitialize(spurs=*0x%x, taskset=*0x%x, eventFlag=*0x%x, flagClearMode=%d, flagDirection=%d)", spurs, taskset, eventFlag, flagClearMode, flagDirection); - if (taskset.addr() == 0 && spurs.addr() == 0) + if ((!taskset && !spurs) || !eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() == 0) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align || taskset.addr() % CellSpursTaskset::align || eventFlag.addr() % CellSpursEventFlag::align) + if (!spurs.aligned() || !taskset.aligned() || !eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - if (taskset.addr() && taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD2) + if (taskset && taskset->wid >= CELL_SPURS_MAX_WORKLOAD2) { return CELL_SPURS_TASK_ERROR_INVAL; } @@ -1491,174 +2723,186 @@ s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptrm.direction = flagDirection; - eventFlag->m.clearMode = flagClearMode; - eventFlag->m.spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; + memset(eventFlag.get_ptr(), 0, sizeof(CellSpursEventFlag)); + eventFlag->direction = flagDirection; + eventFlag->clearMode = flagClearMode; + eventFlag->spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; - if (taskset.addr()) + if (taskset) { - eventFlag->m.addr = taskset.addr(); + eventFlag->addr = taskset.addr(); } else { - eventFlag->m.isIwl = 1; - eventFlag->m.addr = spurs.addr(); + eventFlag->isIwl = 1; + eventFlag->addr = spurs.addr(); } return CELL_OK; } -s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr eventFlag) +/// Reset a SPURS event flag +s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) { - cellSpurs.Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); + cellSpurs.Warning("cellSpursEventFlagClear(eventFlag=*0x%x, bits=0x%x)", eventFlag, bits); if (!eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { - return CELL_SPURS_TASK_ERROR_AGAIN; + return CELL_SPURS_TASK_ERROR_ALIGN; } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + eventFlag->events &= ~bits; + return CELL_OK; +} + +/// Set a SPURS event flag +s32 cellSpursEventFlagSet(PPUThread& CPU, vm::ptr eventFlag, u16 bits) +{ + cellSpurs.Warning("cellSpursEventFlagSet(eventFlag=*0x%x, bits=0x%x)", eventFlag, bits); + + if (!eventFlag) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!eventFlag.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } - if (eventFlag->m.spuPort != CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) + bool send; + u8 ppuWaitSlot; + u16 ppuEvents; + u16 pendingRecv; + u16 pendingRecvTaskEvents[16]; + eventFlag->ctrl.atomic_op([eventFlag, bits, &send, &ppuWaitSlot, &ppuEvents, &pendingRecv, &pendingRecvTaskEvents](CellSpursEventFlag::ControlSyncVar& ctrl) { - return CELL_SPURS_TASK_ERROR_STAT; - } + send = false; + ppuWaitSlot = 0; + ppuEvents = 0; + pendingRecv = 0; - vm::ptr spurs; - if (eventFlag->m.isIwl == 1) - { - spurs.set((u32)eventFlag->m.addr); - } - else - { - auto taskset = vm::ptr::make((u32)eventFlag->m.addr); - spurs.set((u32)taskset->m.spurs.addr()); - } + u16 eventsToClear = 0; - u32 eventQueueId; - vm::var port; - auto rc = spursCreateLv2EventQueue(spurs, eventQueueId, port, 1, *((u64 *)"_spuEvF")); - if (rc != CELL_OK) - { - // Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code - return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF)); - } - - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) - { - vm::var> eventPortId; - rc = sys_event_port_create(vm::ptr::make(eventPortId.addr()), SYS_EVENT_PORT_LOCAL, 0); - if (rc == CELL_OK) + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY && ctrl.ppuWaitMask) { - rc = sys_event_port_connect_local(eventPortId.value(), eventQueueId); - if (rc == CELL_OK) - { - eventFlag->m.eventPortId = eventPortId; - goto success; - } + u16 ppuRelevantEvents = (ctrl.events | bits) & ctrl.ppuWaitMask; - sys_event_port_destroy(eventPortId.value()); + // Unblock the waiting PPU thread if either all the bits being waited by the thread have been set or + // if the wait mode of the thread is OR and atleast one bit the thread is waiting on has been set + if ((ctrl.ppuWaitMask & ~ppuRelevantEvents) == 0 || + ((ctrl.ppuWaitSlotAndMode & 0x0F) == CELL_SPURS_EVENT_FLAG_OR && ppuRelevantEvents != 0)) + { + ctrl.ppuPendingRecv = 1; + ctrl.ppuWaitMask = 0; + ppuEvents = ppuRelevantEvents; + eventsToClear = ppuRelevantEvents; + ppuWaitSlot = ctrl.ppuWaitSlotAndMode >> 4; + send = true; + } } - // TODO: Implement the following - // if (spursDetachLv2EventQueue(spurs, port, 1) == CELL_OK) - // { - // sys_event_queue_destroy(eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE); - // } + s32 i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1; + s32 j = 0; + u16 relevantWaitSlots = eventFlag->spuTaskUsedWaitSlots & ~ctrl.spuTaskPendingRecv; + while (relevantWaitSlots) + { + if (relevantWaitSlots & 0x0001) + { + u16 spuTaskRelevantEvents = (ctrl.events | bits) & eventFlag->spuTaskWaitMask[i]; - // Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code - return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF)); + // Unblock the waiting SPU task if either all the bits being waited by the task have been set or + // if the wait mode of the task is OR and atleast one bit the thread is waiting on has been set + if ((eventFlag->spuTaskWaitMask[i] & ~spuTaskRelevantEvents) == 0 || + (((eventFlag->spuTaskWaitMode >> j) & 0x0001) == CELL_SPURS_EVENT_FLAG_OR && spuTaskRelevantEvents != 0)) + { + eventsToClear |= spuTaskRelevantEvents; + pendingRecv |= 1 << j; + pendingRecvTaskEvents[j] = spuTaskRelevantEvents; + } + } + + relevantWaitSlots >>= 1; + i--; + j++; + } + + ctrl.events |= bits; + ctrl.spuTaskPendingRecv |= pendingRecv; + + // If the clear flag is AUTO then clear the bits comnsumed by all tasks marked to be unblocked + if (eventFlag->clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) + { + ctrl.events &= ~eventsToClear; + } + + //eventFlagControl = ((u64)events << 48) | ((u64)spuTaskPendingRecv << 32) | ((u64)ppuWaitMask << 16) | ((u64)ppuWaitSlotAndMode << 8) | (u64)ppuPendingRecv; + }); + + if (send) + { + // Signal the PPU thread to be woken up + eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEvents; + if (s32 rc = sys_event_port_send(eventFlag->eventPortId, 0, 0, 0)) + { + throw EXCEPTION("sys_event_port_send() failed (0x%x)", rc); + } } -success: - eventFlag->m.eventQueueId = eventQueueId; - eventFlag->m.spuPort = port; - return CELL_OK; -} - -s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) -{ - cellSpurs.Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); - - if (!eventFlag) + if (pendingRecv) { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } + // Signal each SPU task whose conditions have been met to be woken up + for (s32 i = 0; i < CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS; i++) + { + if (pendingRecv & (0x8000 >> i)) + { + eventFlag->pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i]; + vm::stackvar> taskset(CPU); + if (eventFlag->isIwl) + { + cellSpursLookUpTasksetAddress(CPU, vm::ptr::make((u32)eventFlag->addr), taskset, eventFlag->waitingTaskWklId[i]); + } + else + { + taskset->set((u32)eventFlag->addr); + } - if (eventFlag.addr() % CellSpursEventFlag::align) - { - return CELL_SPURS_TASK_ERROR_AGAIN; - } + auto rc = _cellSpursSendSignal(CPU, taskset.value(), eventFlag->waitingTaskId[i]); + if (rc == CELL_SPURS_TASK_ERROR_INVAL || rc == CELL_SPURS_TASK_ERROR_STAT) + { + return CELL_SPURS_TASK_ERROR_FATAL; + } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) - { - return CELL_SPURS_TASK_ERROR_PERM; - } - - if (eventFlag->m.spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) - { - return CELL_SPURS_TASK_ERROR_STAT; - } - - if (eventFlag->m.ppuWaitMask || eventFlag->m.ppuPendingRecv) - { - return CELL_SPURS_TASK_ERROR_BUSY; - } - - auto port = eventFlag->m.spuPort; - eventFlag->m.spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; - - vm::ptr spurs; - if (eventFlag->m.isIwl == 1) - { - spurs.set((u32)eventFlag->m.addr); - } - else - { - auto taskset = vm::ptr::make((u32)eventFlag->m.addr); - spurs.set((u32)taskset->m.spurs.addr()); - } - - if(eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) - { - sys_event_port_disconnect(eventFlag->m.eventPortId); - sys_event_port_destroy(eventFlag->m.eventPortId); - } - - s32 rc = CELL_OK; - // TODO: Implement the following - // auto rc = spursDetachLv2EventQueue(spurs, port, 1); - // if (rc == CELL_OK) - // { - // rc = sys_event_queue_destroy(eventFlag->m.eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE); - // } - - if (rc != CELL_OK) - { - // Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code - return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF)); + if (rc != CELL_OK) + { + throw EXCEPTION(""); + } + } + } } return CELL_OK; } -s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) +/// Wait for SPURS event flag +s32 spursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) { - if (eventFlag.addr() == 0 || mask.addr() == 0) + if (!eventFlag || !mask) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } @@ -1668,337 +2912,363 @@ s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr return CELL_SPURS_TASK_ERROR_INVAL; } - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } - if (block && eventFlag->m.spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) + if (block && eventFlag->spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) { return CELL_SPURS_TASK_ERROR_STAT; } - if (eventFlag->m.ppuWaitMask || eventFlag->m.ppuPendingRecv) + if (eventFlag->ctrl.data.ppuWaitMask || eventFlag->ctrl.data.ppuPendingRecv) { return CELL_SPURS_TASK_ERROR_BUSY; } - u16 relevantEvents = eventFlag->m.events & *mask; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) - { - // Make sure the wait mask and mode specified does not conflict with that of the already waiting tasks. - // Conflict scenarios: - // OR vs OR - A conflict never occurs - // OR vs AND - A conflict occurs if the masks for the two tasks overlap - // AND vs AND - A conflict occurs if the masks for the two tasks are not the same - - // Determine the set of all already waiting tasks whose wait mode/mask can possibly conflict with the specified wait mode/mask. - // This set is equal to 'set of all tasks waiting' - 'set of all tasks whose wait conditions have been met'. - // If the wait mode is OR, we prune the set of all tasks that are waiting in OR mode from the set since a conflict cannot occur - // with an already waiting task in OR mode. - u16 relevantWaitSlots = eventFlag->m.spuTaskUsedWaitSlots & ~eventFlag->m.spuTaskPendingRecv; - if (mode == CELL_SPURS_EVENT_FLAG_OR) - { - relevantWaitSlots &= eventFlag->m.spuTaskWaitMode; - } - - int i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1; - while (relevantWaitSlots) - { - if (relevantWaitSlots & 0x0001) - { - if (eventFlag->m.spuTaskWaitMask[i] & *mask && eventFlag->m.spuTaskWaitMask[i] != *mask) - { - return CELL_SPURS_TASK_ERROR_AGAIN; - } - } - - relevantWaitSlots >>= 1; - i--; - } - } - - // There is no need to block if all bits required by the wait operation have already been set or - // if the wait mode is OR and atleast one of the bits required by the wait operation has been set. bool recv; - if ((*mask & ~relevantEvents) == 0 || (mode == CELL_SPURS_EVENT_FLAG_OR && relevantEvents)) + s32 rc; + u16 receivedEvents; + eventFlag->ctrl.atomic_op([eventFlag, mask, mode, block, &recv, &rc, &receivedEvents](CellSpursEventFlag::ControlSyncVar& ctrl) { - // If the clear flag is AUTO then clear the bits comnsumed by this thread - if (eventFlag->m.clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) + u16 relevantEvents = ctrl.events & *mask; + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { - eventFlag->m.events &= ~relevantEvents; - } + // Make sure the wait mask and mode specified does not conflict with that of the already waiting tasks. + // Conflict scenarios: + // OR vs OR - A conflict never occurs + // OR vs AND - A conflict occurs if the masks for the two tasks overlap + // AND vs AND - A conflict occurs if the masks for the two tasks are not the same - recv = false; - } - else - { - // If we reach here it means that the conditions for this thread have not been met. - // If this is a try wait operation then do not block but return an error code. - if (block == 0) - { - return CELL_SPURS_TASK_ERROR_BUSY; - } - - eventFlag->m.ppuWaitSlotAndMode = 0; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) - { - // Find an unsed wait slot - int i = 0; - u16 spuTaskUsedWaitSlots = eventFlag->m.spuTaskUsedWaitSlots; - while (spuTaskUsedWaitSlots & 0x0001) + // Determine the set of all already waiting tasks whose wait mode/mask can possibly conflict with the specified wait mode/mask. + // This set is equal to 'set of all tasks waiting' - 'set of all tasks whose wait conditions have been met'. + // If the wait mode is OR, we prune the set of all tasks that are waiting in OR mode from the set since a conflict cannot occur + // with an already waiting task in OR mode. + u16 relevantWaitSlots = eventFlag->spuTaskUsedWaitSlots & ~ctrl.spuTaskPendingRecv; + if (mode == CELL_SPURS_EVENT_FLAG_OR) { - spuTaskUsedWaitSlots >>= 1; - i++; + relevantWaitSlots &= eventFlag->spuTaskWaitMode; } - if (i == CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS) + s32 i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1; + while (relevantWaitSlots) { - // Event flag has no empty wait slots - return CELL_SPURS_TASK_ERROR_BUSY; - } + if (relevantWaitSlots & 0x0001) + { + if (eventFlag->spuTaskWaitMask[i] & *mask && eventFlag->spuTaskWaitMask[i] != *mask) + { + rc = CELL_SPURS_TASK_ERROR_AGAIN; + return; + } + } - // Mark the found wait slot as used by this thread - eventFlag->m.ppuWaitSlotAndMode = (CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1 - i) << 4; + relevantWaitSlots >>= 1; + i--; + } } - // Save the wait mask and mode for this thread - eventFlag->m.ppuWaitSlotAndMode |= mode; - eventFlag->m.ppuWaitMask = *mask; - recv = true; + // There is no need to block if all bits required by the wait operation have already been set or + // if the wait mode is OR and atleast one of the bits required by the wait operation has been set. + if ((*mask & ~relevantEvents) == 0 || (mode == CELL_SPURS_EVENT_FLAG_OR && relevantEvents)) + { + // If the clear flag is AUTO then clear the bits comnsumed by this thread + if (eventFlag->clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) + { + ctrl.events &= ~relevantEvents; + } + + recv = false; + receivedEvents = relevantEvents; + } + else + { + // If we reach here it means that the conditions for this thread have not been met. + // If this is a try wait operation then do not block but return an error code. + if (block == 0) + { + rc = CELL_SPURS_TASK_ERROR_BUSY; + return; + } + + ctrl.ppuWaitSlotAndMode = 0; + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + { + // Find an unsed wait slot + s32 i = 0; + u16 spuTaskUsedWaitSlots = eventFlag->spuTaskUsedWaitSlots; + while (spuTaskUsedWaitSlots & 0x0001) + { + spuTaskUsedWaitSlots >>= 1; + i++; + } + + if (i == CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS) + { + // Event flag has no empty wait slots + rc = CELL_SPURS_TASK_ERROR_BUSY; + return; + } + + // Mark the found wait slot as used by this thread + ctrl.ppuWaitSlotAndMode = (CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1 - i) << 4; + } + + // Save the wait mask and mode for this thread + ctrl.ppuWaitSlotAndMode |= mode; + ctrl.ppuWaitMask = *mask; + + recv = true; + } + + //eventFlagControl = ((u64)events << 48) | ((u64)spuTaskPendingRecv << 32) | ((u64)ppuWaitMask << 16) | ((u64)ppuWaitSlotAndMode << 8) | (u64)ppuPendingRecv; + rc = CELL_OK; + }); + + if (rc != CELL_OK) + { + return rc; } - u16 receivedEventFlag; - if (recv) { + if (recv) + { // Block till something happens - vm::var data; - auto rc = sys_event_queue_receive(GetCurrentPPUThread(), eventFlag->m.eventQueueId, data, 0); - if (rc != CELL_OK) + if (s32 rc = sys_event_queue_receive(CPU, eventFlag->eventQueueId, vm::null, 0)) { - assert(0); + throw EXCEPTION("sys_event_queue_receive() failed (0x%x)", rc); } - int i = 0; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + s32 i = 0; + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) { - i = eventFlag->m.ppuWaitSlotAndMode >> 4; + i = eventFlag->ctrl.data.ppuWaitSlotAndMode >> 4; } - receivedEventFlag = eventFlag->m.pendingRecvTaskEvents[i]; - eventFlag->m.ppuPendingRecv = 0; + *mask = eventFlag->pendingRecvTaskEvents[i]; + eventFlag->ctrl.data.ppuPendingRecv = 0; } - *mask = receivedEventFlag; + *mask = receivedEvents; return CELL_OK; } -s32 cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) +/// Wait for SPURS event flag +s32 cellSpursEventFlagWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode) { - cellSpurs.Warning("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%d)", eventFlag.addr(), mask.addr(), mode); + cellSpurs.Warning("cellSpursEventFlagWait(eventFlag=*0x%x, mask=*0x%x, mode=%d)", eventFlag, mask, mode); - return _cellSpursEventFlagWait(eventFlag, mask, mode, 1/*block*/); + return spursEventFlagWait(CPU, eventFlag, mask, mode, 1 /*block*/); } -s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) +/// Check SPURS event flag +s32 cellSpursEventFlagTryWait(PPUThread& CPU, vm::ptr eventFlag, vm::ptr mask, u32 mode) { - cellSpurs.Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); + cellSpurs.Warning("cellSpursEventFlagTryWait(eventFlag=*0x%x, mask=*0x%x, mode=0x%x)", eventFlag, mask, mode); - if (eventFlag.addr() == 0) + return spursEventFlagWait(CPU, eventFlag, mask, mode, 0 /*block*/); +} + +/// Attach an LV2 event queue to a SPURS event flag +s32 cellSpursEventFlagAttachLv2EventQueue(PPUThread& CPU, vm::ptr eventFlag) +{ + cellSpurs.Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag=*0x%x)", eventFlag); + + if (!eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { - return CELL_SPURS_TASK_ERROR_ALIGN; + return CELL_SPURS_TASK_ERROR_AGAIN; } - eventFlag->m.events &= ~bits; - return CELL_OK; -} - -s32 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) -{ - cellSpurs.Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); - - if (eventFlag.addr() == 0) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (eventFlag.addr() % CellSpursEventFlag::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_PPU2SPU && eventFlag->m.direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) { return CELL_SPURS_TASK_ERROR_PERM; } - u16 ppuEventFlag = 0; - bool send = false; - int ppuWaitSlot = 0; - u16 eventsToClear = 0; - if (eventFlag->m.direction == CELL_SPURS_EVENT_FLAG_ANY2ANY && eventFlag->m.ppuWaitMask) + if (eventFlag->spuPort != CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) { - u16 ppuRelevantEvents = (eventFlag->m.events | bits) & eventFlag->m.ppuWaitMask; - - // Unblock the waiting PPU thread if either all the bits being waited by the thread have been set or - // if the wait mode of the thread is OR and atleast one bit the thread is waiting on has been set - if ((eventFlag->m.ppuWaitMask & ~ppuRelevantEvents) == 0 || - ((eventFlag->m.ppuWaitSlotAndMode & 0x0F) == CELL_SPURS_EVENT_FLAG_OR && ppuRelevantEvents != 0)) - { - eventFlag->m.ppuPendingRecv = 1; - eventFlag->m.ppuWaitMask = 0; - ppuEventFlag = ppuRelevantEvents; - eventsToClear = ppuRelevantEvents; - ppuWaitSlot = eventFlag->m.ppuWaitSlotAndMode >> 4; - send = true; - } + return CELL_SPURS_TASK_ERROR_STAT; } - int i = CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS - 1; - int j = 0; - u16 relevantWaitSlots = eventFlag->m.spuTaskUsedWaitSlots & ~eventFlag->m.spuTaskPendingRecv; - u16 spuTaskPendingRecv = 0; - u16 pendingRecvTaskEvents[16]; - while (relevantWaitSlots) + vm::ptr spurs; + if (eventFlag->isIwl == 1) { - if (relevantWaitSlots & 0x0001) - { - u16 spuTaskRelevantEvents = (eventFlag->m.events | bits) & eventFlag->m.spuTaskWaitMask[i]; + spurs.set((u32)eventFlag->addr); + } + else + { + auto taskset = vm::ptr::make((u32)eventFlag->addr); + spurs = taskset->spurs; + } - // Unblock the waiting SPU task if either all the bits being waited by the task have been set or - // if the wait mode of the task is OR and atleast one bit the thread is waiting on has been set - if ((eventFlag->m.spuTaskWaitMask[i] & ~spuTaskRelevantEvents) == 0 || - (((eventFlag->m.spuTaskWaitMode >> j) & 0x0001) == CELL_SPURS_EVENT_FLAG_OR && spuTaskRelevantEvents != 0)) + vm::stackvar> eventQueueId(CPU); + vm::stackvar port(CPU); + vm::stackvar evqName(CPU, 8); + memcpy(evqName.get_ptr(), "_spuEvF", 8); + + auto failure = [](s32 rc) -> s32 + { + // Return rc if its an error code from SPURS otherwise convert the error code to a SPURS task error code + return (rc & 0x0FFF0000) == 0x00410000 ? rc : (0x80410900 | (rc & 0xFF)); + }; + + if (s32 rc = spursCreateLv2EventQueue(CPU, spurs, eventQueueId, port, 1, evqName)) + { + return failure(rc); + } + + auto success = [&] + { + eventFlag->eventQueueId = eventQueueId; + eventFlag->spuPort = port; + }; + + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + { + vm::stackvar> eventPortId(CPU); + + s32 rc = sys_event_port_create(eventPortId, SYS_EVENT_PORT_LOCAL, 0); + if (rc == CELL_OK) + { + rc = sys_event_port_connect_local(eventPortId.value(), eventQueueId.value()); + if (rc == CELL_OK) { - eventsToClear |= spuTaskRelevantEvents; - spuTaskPendingRecv |= 1 << j; - pendingRecvTaskEvents[j] = spuTaskRelevantEvents; + eventFlag->eventPortId = eventPortId; + return success(), CELL_OK; } + + sys_event_port_destroy(eventPortId.value()); } - relevantWaitSlots >>= 1; - i--; - j++; - } - - eventFlag->m.events |= bits; - eventFlag->m.spuTaskPendingRecv |= spuTaskPendingRecv; - - // If the clear flag is AUTO then clear the bits comnsumed by all tasks marked to be unblocked - if (eventFlag->m.clearMode == CELL_SPURS_EVENT_FLAG_CLEAR_AUTO) - { - eventFlag->m.events &= ~eventsToClear; - } - - if (send) - { - // Signal the PPU thread to be woken up - eventFlag->m.pendingRecvTaskEvents[ppuWaitSlot] = ppuEventFlag; - if (sys_event_port_send(eventFlag->m.eventPortId, 0, 0, 0) != CELL_OK) + if (spursDetachLv2EventQueue(spurs, port, true /*spursCreated*/) == CELL_OK) { - assert(0); + sys_event_queue_destroy(eventQueueId.value(), SYS_EVENT_QUEUE_DESTROY_FORCE); } + + return failure(rc); } - if (spuTaskPendingRecv) + return success(), CELL_OK; +} + +/// Detach an LV2 event queue from SPURS event flag +s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) +{ + cellSpurs.Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag=*0x%x)", eventFlag); + + if (!eventFlag) { - // Signal each SPU task whose conditions have been met to be woken up - for (int i = 0; i < CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS; i++) - { - if (spuTaskPendingRecv & (0x8000 >> i)) - { - eventFlag->m.pendingRecvTaskEvents[i] = pendingRecvTaskEvents[i]; - vm::var taskset; - if (eventFlag->m.isIwl) - { - cellSpursLookUpTasksetAddress(vm::ptr::make((u32)eventFlag->m.addr), - vm::ptr::make(taskset.addr()), - eventFlag->m.waitingTaskWklId[i]); - } - else - { - taskset.value() = (u32)eventFlag->m.addr; - } + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } - auto rc = _cellSpursSendSignal(vm::ptr::make(taskset.addr()), eventFlag->m.waitingTaskId[i]); - if (rc == CELL_SPURS_TASK_ERROR_INVAL || rc == CELL_SPURS_TASK_ERROR_STAT) - { - return CELL_SPURS_TASK_ERROR_FATAL; - } + if (!eventFlag.aligned()) + { + return CELL_SPURS_TASK_ERROR_AGAIN; + } - if (rc != CELL_OK) - { - assert(0); - } - } - } + if (eventFlag->direction != CELL_SPURS_EVENT_FLAG_SPU2PPU && eventFlag->direction != CELL_SPURS_EVENT_FLAG_ANY2ANY) + { + return CELL_SPURS_TASK_ERROR_PERM; + } + + if (eventFlag->spuPort == CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT) + { + return CELL_SPURS_TASK_ERROR_STAT; + } + + if (eventFlag->ctrl.data.ppuWaitMask || eventFlag->ctrl.data.ppuPendingRecv) + { + return CELL_SPURS_TASK_ERROR_BUSY; + } + + const u8 port = eventFlag->spuPort; + + eventFlag->spuPort = CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT; + + vm::ptr spurs; + if (eventFlag->isIwl == 1) + { + spurs.set((u32)eventFlag->addr); + } + else + { + auto taskset = vm::ptr::make((u32)eventFlag->addr); + spurs = taskset->spurs; + } + + if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) + { + sys_event_port_disconnect(eventFlag->eventPortId); + sys_event_port_destroy(eventFlag->eventPortId); + } + + auto rc = spursDetachLv2EventQueue(spurs, port, true /*spursCreated*/); + + if (rc == CELL_OK) + { + rc = sys_event_queue_destroy(eventFlag->eventQueueId, SYS_EVENT_QUEUE_DESTROY_FORCE); } return CELL_OK; } -s32 cellSpursEventFlagTryWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) -{ - cellSpurs.Warning("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=0x%x)", eventFlag.addr(), mask.addr(), mode); - - return _cellSpursEventFlagWait(eventFlag, mask, mode, 0/*block*/); -} - +/// Get send-receive direction of the SPURS event flag s32 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::ptr direction) { - cellSpurs.Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.addr(), direction.addr()); + cellSpurs.Warning("cellSpursEventFlagGetDirection(eventFlag=*0x%x, direction=*0x%x)", eventFlag, direction); - if (eventFlag.addr() == 0 || direction.addr() == 0) + if (!eventFlag || !direction) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - *direction = eventFlag->m.direction; + *direction = eventFlag->direction; return CELL_OK; } +/// Get clearing mode of SPURS event flag s32 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::ptr clear_mode) { - cellSpurs.Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.addr(), clear_mode.addr()); + cellSpurs.Warning("cellSpursEventFlagGetClearMode(eventFlag=*0x%x, clear_mode=*0x%x)", eventFlag, clear_mode); - if (eventFlag.addr() == 0 || clear_mode.addr() == 0) + if (!eventFlag || !clear_mode) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - *clear_mode = eventFlag->m.clearMode; + *clear_mode = eventFlag->clearMode; return CELL_OK; } -s32 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, vm::ptr taskset) +/// Get address of taskset to which the SPURS event flag belongs +s32 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, vm::pptr taskset) { - cellSpurs.Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.addr(), taskset.addr()); + cellSpurs.Warning("cellSpursEventFlagGetTasksetAddress(eventFlag=*0x%x, taskset=**0x%x)", eventFlag, taskset); - if (eventFlag.addr() == 0 || taskset.addr() == 0) + if (!eventFlag || !taskset) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; } - if (eventFlag.addr() % CellSpursEventFlag::align) + if (!eventFlag.aligned()) { return CELL_SPURS_TASK_ERROR_ALIGN; } - taskset.set(eventFlag->m.isIwl ? 0 : eventFlag->m.addr); + taskset->set(eventFlag->isIwl ? 0u : VM_CAST(eventFlag->addr)); return CELL_OK; } @@ -2104,6 +3374,670 @@ s32 cellSpursQueueGetDirection() return CELL_OK; } +s32 spursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 max_contention, vm::cptr name, u32 size, s32 enable_clear_ls) +{ + if (!spurs || !taskset) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!spurs.aligned() || !taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + memset(taskset.get_ptr(), 0, size); + + taskset->spurs = spurs; + taskset->args = args; + taskset->enable_clear_ls = enable_clear_ls > 0 ? 1 : 0; + taskset->size = size; + + vm::stackvar wkl_attr(CPU); + _cellSpursWorkloadAttributeInitialize(wkl_attr, 1 /*revision*/, 0x33 /*sdk_version*/, vm::cptr::make(SPURS_IMG_ADDR_TASKSET_PM), 0x1E40 /*pm_size*/, + taskset.addr(), priority, 8 /*min_contention*/, max_contention); + // TODO: Check return code + + cellSpursWorkloadAttributeSetName(wkl_attr, vm::null, name); + // TODO: Check return code + + // TODO: cellSpursWorkloadAttributeSetShutdownCompletionEventHook(wkl_attr, hook, taskset); + // TODO: Check return code + + vm::stackvar> wid(CPU); + cellSpursAddWorkloadWithAttribute(spurs, wid, wkl_attr); + // TODO: Check return code + + taskset->wkl_flag_wait_task = 0x80; + taskset->wid = wid.value(); + // TODO: cellSpursSetExceptionEventHandler(spurs, wid, hook, taskset); + // TODO: Check return code + + return CELL_OK; +} + +s32 cellSpursCreateTasksetWithAttribute(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr) +{ + cellSpurs.Warning("cellSpursCreateTasksetWithAttribute(spurs=*0x%x, taskset=*0x%x, attr=*0x%x)", spurs, taskset, attr); + + if (!attr) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (attr->revision != CELL_SPURS_TASKSET_ATTRIBUTE_REVISION) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + auto rc = spursCreateTaskset(CPU, spurs, taskset, attr->args, attr.of(&CellSpursTasksetAttribute::priority), attr->max_contention, attr->name, attr->taskset_size, attr->enable_clear_ls); + + if (attr->taskset_size >= sizeof32(CellSpursTaskset2)) + { + // TODO: Implement this + } + + return rc; +} + +s32 cellSpursCreateTaskset(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, u64 args, vm::cptr priority, u32 maxContention) +{ + cellSpurs.Warning("cellSpursCreateTaskset(spurs=*0x%x, taskset=*0x%x, args=0x%llx, priority=*0x%x, maxContention=%d)", spurs, taskset, args, priority, maxContention); + + return spursCreateTaskset(CPU, spurs, taskset, args, priority, maxContention, vm::null, sizeof32(CellSpursTaskset), 0); +} + +s32 cellSpursJoinTaskset(vm::ptr taskset) +{ + cellSpurs.Warning("cellSpursJoinTaskset(taskset=*0x%x)", taskset); + + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) +{ + cellSpurs.Warning("cellSpursGetTasksetId(taskset=*0x%x, wid=*0x%x)", taskset, wid); + + if (!taskset || !wid) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + *wid = taskset->wid; + return CELL_OK; +} + +s32 cellSpursShutdownTaskset(vm::ptr taskset) +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm::cptr elf, vm::cptr context, u32 size, vm::ptr ls_pattern, vm::ptr arg) +{ + if (!taskset || !elf) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (elf % 16) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (spursGetSdkVersion() < 0x27FFFF) + { + if (context % 16) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + } + else + { + if (context % 128) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + } + + u32 alloc_ls_blocks = 0; + + if (context) + { + if (size < CELL_SPURS_TASK_EXECUTION_CONTEXT_SIZE) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + alloc_ls_blocks = size > 0x3D400 ? 0x7A : ((size - 0x400) >> 11); + if (ls_pattern) + { + u128 ls_pattern_128 = u128::from64r(ls_pattern->_u64[0], ls_pattern->_u64[1]); + u32 ls_blocks = 0; + for (auto i = 0; i < 128; i++) + { + if (ls_pattern_128._bit[i]) + { + ls_blocks++; + } + } + + if (ls_blocks > alloc_ls_blocks) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + u128 _0 = u128::from32(0); + if ((ls_pattern_128 & u128::from32r(0xFC000000)) != _0) + { + // Prevent save/restore to SPURS management area + return CELL_SPURS_TASK_ERROR_INVAL; + } + } + } + else + { + alloc_ls_blocks = 0; + } + + // TODO: Verify the ELF header is proper and all its load segments are at address >= 0x3000 + + u32 tmp_task_id; + for (tmp_task_id = 0; tmp_task_id < CELL_SPURS_MAX_TASK; tmp_task_id++) + { + if (!taskset->enabled.value()._bit[tmp_task_id]) + { + auto enabled = taskset->enabled.value(); + enabled._bit[tmp_task_id] = true; + taskset->enabled = enabled; + break; + } + } + + if (tmp_task_id >= CELL_SPURS_MAX_TASK) + { + return CELL_SPURS_TASK_ERROR_AGAIN; + } + + taskset->task_info[tmp_task_id].elf = elf; + taskset->task_info[tmp_task_id].context_save_storage_and_alloc_ls_blocks = (context.addr() | alloc_ls_blocks); + taskset->task_info[tmp_task_id].args = *arg; + if (ls_pattern) + { + taskset->task_info[tmp_task_id].ls_pattern = *ls_pattern; + } + + *task_id = tmp_task_id; + return CELL_OK; +} + +s32 spursTaskStart(PPUThread& CPU, vm::ptr taskset, u32 taskId) +{ + auto pendingReady = taskset->pending_ready.value(); + pendingReady._bit[taskId] = true; + taskset->pending_ready = pendingReady; + + cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid); + + if (s32 rc = cellSpursWakeUp(CPU, taskset->spurs)) + { + if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) + { + rc = CELL_SPURS_TASK_ERROR_STAT; + } + else + { + throw EXCEPTION("cellSpursWakeUp() failed (0x%x)", rc); + } + } + + return CELL_OK; +} + +s32 cellSpursCreateTask(PPUThread& CPU, vm::ptr taskset, vm::ptr taskId, vm::cptr elf, vm::cptr context, u32 size, vm::ptr lsPattern, vm::ptr argument) +{ + cellSpurs.Warning("cellSpursCreateTask(taskset=*0x%x, taskID=*0x%x, elf=*0x%x, context=*0x%x, size=0x%x, lsPattern=*0x%x, argument=*0x%x)", taskset, taskId, elf, context, size, lsPattern, argument); + + if (!taskset) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + vm::stackvar> tmpTaskId(CPU); + auto rc = spursCreateTask(taskset, tmpTaskId, elf, context, size, lsPattern, argument); + if (rc != CELL_OK) + { + return rc; + } + + rc = spursTaskStart(CPU, taskset, tmpTaskId.value()); + if (rc != CELL_OK) + { + return rc; + } + + *taskId = tmpTaskId; + return CELL_OK; +} + +s32 _cellSpursSendSignal(PPUThread& CPU, vm::ptr taskset, u32 taskId) +{ + if (!taskset) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (taskId >= CELL_SPURS_MAX_TASK || taskset->wid >= CELL_SPURS_MAX_WORKLOAD2) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + be_t _0(u128::from32(0)); + bool disabled = taskset->enabled.value()._bit[taskId]; + auto invalid = (taskset->ready & taskset->pending_ready) != _0 || (taskset->running & taskset->waiting) != _0 || disabled || + ((taskset->running | taskset->ready | taskset->pending_ready | taskset->waiting | taskset->signalled) & ~taskset->enabled) != _0; + + if (invalid) + { + return CELL_SPURS_TASK_ERROR_SRCH; + } + + auto shouldSignal = ((taskset->waiting & ~taskset->signalled) & be_t(u128::fromBit(taskId))) != _0 ? true : false; + auto signalled = taskset->signalled.value(); + signalled._bit[taskId] = true; + taskset->signalled = signalled; + if (shouldSignal) + { + cellSpursSendWorkloadSignal(taskset->spurs, taskset->wid); + auto rc = cellSpursWakeUp(CPU, taskset->spurs); + if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) + { + return CELL_SPURS_TASK_ERROR_STAT; + } + + if (rc != CELL_OK) + { + assert(0); + } + } + + return CELL_OK; +} + +s32 cellSpursCreateTaskWithAttribute() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTasksetAttributeSetName(vm::ptr attr, vm::cptr name) +{ + cellSpurs.Warning("cellSpursTasksetAttributeSetName(attr=*0x%x, name=*0x%x)", attr, name); + + if (!attr || !name) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + attr->name = name; + return CELL_OK; +} + +s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size) +{ + cellSpurs.Warning("cellSpursTasksetAttributeSetTasksetSize(attr=*0x%x, size=0x%x)", attr, size); + + if (!attr) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (size != sizeof32(CellSpursTaskset) && size != sizeof32(CellSpursTaskset2)) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + attr->taskset_size = size; + return CELL_OK; +} + +s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable) +{ + cellSpurs.Warning("cellSpursTasksetAttributeEnableClearLS(attr=*0x%x, enable=%d)", attr, enable); + + if (!attr) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!attr.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + attr->enable_clear_ls = enable ? 1 : 0; + return CELL_OK; +} + +s32 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision) +{ + cellSpurs.Warning("_cellSpursTasksetAttribute2Initialize(attribute=*0x%x, revision=%d)", attribute, revision); + + memset(attribute.get_ptr(), 0, sizeof(CellSpursTasksetAttribute2)); + attribute->revision = revision; + attribute->name = vm::null; + attribute->args = 0; + + for (s32 i = 0; i < 8; i++) + { + attribute->priority[i] = 1; + } + + attribute->max_contention = 8; + attribute->enable_clear_ls = 0; + attribute->task_name_buffer.set(0); + return CELL_OK; +} + +s32 cellSpursTaskExitCodeGet() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTaskExitCodeInitialize() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTaskExitCodeTryGet() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTaskGetLoadableSegmentPattern() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTaskGetReadOnlyAreaPattern() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTaskGenerateLsPattern() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 _cellSpursTaskAttributeInitialize() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTaskAttributeSetExitCodeContainer() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 _cellSpursTaskAttribute2Initialize(vm::ptr attribute, u32 revision) +{ + cellSpurs.Warning("_cellSpursTaskAttribute2Initialize(attribute=*0x%x, revision=%d)", attribute, revision); + + attribute->revision = revision; + attribute->sizeContext = 0; + attribute->eaContext = 0; + + for (s32 c = 0; c < 4; c++) + { + attribute->lsPattern._u32[c] = 0; + } + + attribute->name = vm::null; + + return CELL_OK; +} + +s32 cellSpursTaskGetContextSaveAreaSize() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursCreateTaskset2(PPUThread& CPU, vm::ptr spurs, vm::ptr taskset, vm::ptr attr) +{ + cellSpurs.Warning("cellSpursCreateTaskset2(spurs=*0x%x, taskset=*0x%x, attr=*0x%x)", spurs, taskset, attr); + + vm::stackvar tmp_attr(CPU); + + if (!attr) + { + attr = tmp_attr; + _cellSpursTasksetAttribute2Initialize(attr, 0); + } + + if (s32 rc = spursCreateTaskset(CPU, spurs, taskset, attr->args, attr.of(&CellSpursTasksetAttribute2::priority), attr->max_contention, attr->name, sizeof32(CellSpursTaskset2), attr->enable_clear_ls)) + { + return rc; + } + + if (!attr->task_name_buffer.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + // TODO: Implement rest of the function + return CELL_OK; +} + +s32 cellSpursCreateTask2() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursJoinTask2() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTryJoinTask2() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursDestroyTaskset2() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursCreateTask2WithBinInfo() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg) +{ + cellSpurs.Warning("cellSpursTasksetSetExceptionEventHandler(taskset=*0x%x, handler=*0x%x, arg=*0x%x)", taskset, handler, arg); + + if (!taskset || !handler) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + if (taskset->exception_handler) + { + return CELL_SPURS_TASK_ERROR_BUSY; + } + + taskset->exception_handler = handler; + taskset->exception_handler_arg = arg; + return CELL_OK; +} + +s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset) +{ + cellSpurs.Warning("cellSpursTasksetUnsetExceptionEventHandler(taskset=*0x%x)", taskset); + + if (!taskset) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + taskset->exception_handler.set(0); + taskset->exception_handler_arg.set(0); + return CELL_OK; +} + +s32 cellSpursLookUpTasksetAddress(PPUThread& CPU, vm::ptr spurs, vm::pptr taskset, u32 id) +{ + cellSpurs.Warning("cellSpursLookUpTasksetAddress(spurs=*0x%x, taskset=**0x%x, id=0x%x)", spurs, taskset, id); + + if (!taskset) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + vm::stackvar> data(CPU); + if (s32 rc = cellSpursGetWorkloadData(spurs, data, id)) + { + // Convert policy module error code to a task error code + return rc ^ 0x100; + } + + taskset->set((u32)data.value()); + return CELL_OK; +} + +s32 cellSpursTasksetGetSpursAddress(vm::cptr taskset, vm::ptr spurs) +{ + cellSpurs.Warning("cellSpursTasksetGetSpursAddress(taskset=*0x%x, spurs=**0x%x)", taskset, spurs); + + if (!taskset || !spurs) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!taskset.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + if (taskset->wid >= CELL_SPURS_MAX_WORKLOAD) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + + *spurs = (u32)taskset->spurs.addr(); + return CELL_OK; +} + +s32 cellSpursGetTasksetInfo() +{ + UNIMPLEMENTED_FUNC(cellSpurs); + return CELL_OK; +} + +s32 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::cptr priority, u32 max_contention) +{ + cellSpurs.Warning("_cellSpursTasksetAttributeInitialize(attribute=*0x%x, revision=%d, skd_version=0x%x, args=0x%llx, priority=*0x%x, max_contention=%d)", + attribute, revision, sdk_version, args, priority, max_contention); + + if (!attribute) + { + return CELL_SPURS_TASK_ERROR_NULL_POINTER; + } + + if (!attribute.aligned()) + { + return CELL_SPURS_TASK_ERROR_ALIGN; + } + + for (u32 i = 0; i < 8; i++) + { + if (priority[i] > 0xF) + { + return CELL_SPURS_TASK_ERROR_INVAL; + } + } + + memset(attribute.get_ptr(), 0, sizeof(CellSpursTasksetAttribute)); + attribute->revision = revision; + attribute->sdk_version = sdk_version; + attribute->args = args; + memcpy(attribute->priority, priority.get_ptr(), 8); + attribute->taskset_size = 6400/*CellSpursTaskset::size*/; + attribute->max_contention = max_contention; + return CELL_OK; +} + s32 cellSpursCreateJobChainWithAttribute() { UNIMPLEMENTED_FUNC(cellSpurs); @@ -2164,695 +4098,6 @@ s32 cellSpursJobChainGetSpursAddress() return CELL_OK; } -s32 spursCreateTaskset(vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, - u32 max_contention, vm::ptr name, u32 size, s32 enable_clear_ls) -{ - if (!spurs || !taskset) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align || taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - memset(taskset.get_ptr(), 0, size); - - taskset->m.spurs = spurs; - taskset->m.args = args; - taskset->m.enable_clear_ls = enable_clear_ls > 0 ? 1 : 0; - taskset->m.size = size; - - vm::var wkl_attr; - _cellSpursWorkloadAttributeInitialize(wkl_attr, 1 /*revision*/, 0x33 /*sdk_version*/, vm::ptr::make(SPURS_IMG_ADDR_TASKSET_PM), 0x1E40 /*pm_size*/, - taskset.addr(), priority, 8 /*min_contention*/, max_contention); - // TODO: Check return code - - cellSpursWorkloadAttributeSetName(wkl_attr, vm::null, name); - // TODO: Check return code - - // TODO: cellSpursWorkloadAttributeSetShutdownCompletionEventHook(wkl_attr, hook, taskset); - // TODO: Check return code - - vm::var> wid; - cellSpursAddWorkloadWithAttribute(spurs, vm::ptr::make(wid.addr()), wkl_attr); - // TODO: Check return code - - taskset->m.wkl_flag_wait_task = 0x80; - taskset->m.wid = wid.value(); - // TODO: cellSpursSetExceptionEventHandler(spurs, wid, hook, taskset); - // TODO: Check return code - - return CELL_OK; -} - -s32 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) -{ - cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); - - if (!attr) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (attr.addr() % CellSpursTasksetAttribute::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (attr->m.revision != CELL_SPURS_TASKSET_ATTRIBUTE_REVISION) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - auto rc = spursCreateTaskset(spurs, taskset, attr->m.args, vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, m.priority)), - attr->m.max_contention, vm::ptr::make(attr->m.name.addr()), attr->m.taskset_size, attr->m.enable_clear_ls); - - if (attr->m.taskset_size >= CellSpursTaskset2::size) - { - // TODO: Implement this - } - - return rc; -} - -s32 cellSpursCreateTaskset(vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, u32 maxContention) -{ - cellSpurs.Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)", - spurs.addr(), taskset.addr(), args, priority.addr(), maxContention); - - return spursCreateTaskset(spurs, taskset, args, priority, maxContention, vm::null, 6400/*CellSpursTaskset::size*/, 0); -} - -s32 cellSpursJoinTaskset(vm::ptr taskset) -{ - cellSpurs.Warning("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.addr()); - - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) -{ - cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, wid=0x%x)", taskset.addr(), wid.addr()); - - if (!taskset || !wid) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - *wid = taskset->m.wid; - return CELL_OK; -} - -s32 cellSpursShutdownTaskset(vm::ptr taskset) -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -u32 _cellSpursGetSdkVersion() -{ - // Commenting this out for now since process_get_sdk_version does not return - // the correct SDK version and instead returns a version too high for the game - // and causes SPURS to fail. - //s32 sdk_version; - - //if (process_get_sdk_version(process_getpid(), sdk_version) != CELL_OK) - //{ - // throw __FUNCTION__; - //} - - //return sdk_version; - return 1; -} - -s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm::ptr elf_addr, vm::ptr context_addr, u32 context_size, vm::ptr ls_pattern, vm::ptr arg) -{ - if (!taskset || !elf_addr) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (elf_addr.addr() % 16) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - auto sdk_version = _cellSpursGetSdkVersion(); - if (sdk_version < 0x27FFFF) - { - if (context_addr.addr() % 16) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - } - else - { - if (context_addr.addr() % 128) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - } - - u32 alloc_ls_blocks = 0; - if (context_addr.addr() != 0) - { - if (context_size < CELL_SPURS_TASK_EXECUTION_CONTEXT_SIZE) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - alloc_ls_blocks = context_size > 0x3D400 ? 0x7A : ((context_size - 0x400) >> 11); - if (ls_pattern.addr() != 0) - { - u128 ls_pattern_128 = u128::from64r(ls_pattern->_u64[0], ls_pattern->_u64[1]); - u32 ls_blocks = 0; - for (auto i = 0; i < 128; i++) - { - if (ls_pattern_128._bit[i]) - { - ls_blocks++; - } - } - - if (ls_blocks > alloc_ls_blocks) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - u128 _0 = u128::from32(0); - if ((ls_pattern_128 & u128::from32r(0xFC000000)) != _0) - { - // Prevent save/restore to SPURS management area - return CELL_SPURS_TASK_ERROR_INVAL; - } - } - } - else - { - alloc_ls_blocks = 0; - } - - // TODO: Verify the ELF header is proper and all its load segments are at address >= 0x3000 - - u32 tmp_task_id; - for (tmp_task_id = 0; tmp_task_id < CELL_SPURS_MAX_TASK; tmp_task_id++) - { - if (!taskset->m.enabled.value()._bit[tmp_task_id]) - { - auto enabled = taskset->m.enabled.value(); - enabled._bit[tmp_task_id] = true; - taskset->m.enabled = enabled; - break; - } - } - - if (tmp_task_id >= CELL_SPURS_MAX_TASK) - { - return CELL_SPURS_TASK_ERROR_AGAIN; - } - - taskset->m.task_info[tmp_task_id].elf_addr.set(elf_addr.addr()); - taskset->m.task_info[tmp_task_id].context_save_storage_and_alloc_ls_blocks = (context_addr.addr() | alloc_ls_blocks); - taskset->m.task_info[tmp_task_id].args = *arg; - if (ls_pattern.addr()) - { - taskset->m.task_info[tmp_task_id].ls_pattern = *ls_pattern; - } - - *task_id = tmp_task_id; - return CELL_OK; -} - -s32 spursTaskStart(vm::ptr taskset, u32 taskId) -{ - auto pendingReady = taskset->m.pending_ready.value(); - pendingReady._bit[taskId] = true; - taskset->m.pending_ready = pendingReady; - - cellSpursSendWorkloadSignal(taskset->m.spurs, taskset->m.wid); - auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->m.spurs); - if (rc != CELL_OK) - { - if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) - { - rc = CELL_SPURS_TASK_ERROR_STAT; - } - else - { - assert(0); - } - } - - return rc; -} - -s32 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, u32 elf_addr, u32 context_addr, u32 context_size, vm::ptr lsPattern, - vm::ptr argument) -{ - 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.addr(), taskId.addr(), elf_addr, context_addr, context_size, lsPattern.addr(), argument.addr()); - - if (!taskset) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - vm::var> tmpTaskId; - auto rc = spursCreateTask(taskset, tmpTaskId, vm::ptr::make(elf_addr), vm::ptr::make(context_addr), context_size, lsPattern, argument); - if (rc != CELL_OK) - { - return rc; - } - - rc = spursTaskStart(taskset, tmpTaskId->value()); - if (rc != CELL_OK) - { - return rc; - } - - *taskId = tmpTaskId; - return CELL_OK; -} - -s32 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) -{ - if (!taskset) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (taskId >= CELL_SPURS_MAX_TASK || taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD2) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - auto _0 = be_t::make(u128::from32(0)); - auto disabled = taskset->m.enabled.value()._bit[taskId] ? false : true; - auto invalid = (taskset->m.ready & taskset->m.pending_ready) != _0 || (taskset->m.running & taskset->m.waiting) != _0 || disabled || - ((taskset->m.running | taskset->m.ready | taskset->m.pending_ready | taskset->m.waiting | taskset->m.signalled) & be_t::make(~taskset->m.enabled.value())) != _0; - - if (invalid) - { - return CELL_SPURS_TASK_ERROR_SRCH; - } - - auto shouldSignal = (taskset->m.waiting & be_t::make(~taskset->m.signalled.value()) & be_t::make(u128::fromBit(taskId))) != _0 ? true : false; - auto signalled = taskset->m.signalled.value(); - signalled._bit[taskId] = true; - taskset->m.signalled = signalled; - if (shouldSignal) - { - cellSpursSendWorkloadSignal(taskset->m.spurs, taskset->m.wid); - auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->m.spurs); - if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) - { - return CELL_SPURS_TASK_ERROR_STAT; - } - - if (rc != CELL_OK) - { - assert(0); - } - } - - return CELL_OK; -} - -s32 cellSpursCreateTaskWithAttribute() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTasksetAttributeSetName(vm::ptr attr, vm::ptr name) -{ - cellSpurs.Warning("%s(attr=0x%x, name=0x%x)", __FUNCTION__, attr.addr(), name.addr()); - - if (!attr || !name) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (attr.addr() % CellSpursTasksetAttribute::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - attr->m.name = name; - return CELL_OK; -} - -s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size) -{ - cellSpurs.Warning("%s(attr=0x%x, size=0x%x)", __FUNCTION__, attr.addr(), size); - - if (!attr) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (attr.addr() % CellSpursTasksetAttribute::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (size != 6400/*CellSpursTaskset::size*/ && size != CellSpursTaskset2::size) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - attr->m.taskset_size = size; - return CELL_OK; -} - -s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable) -{ - cellSpurs.Warning("%s(attr=0x%x, enable=%d)", __FUNCTION__, attr.addr(), enable); - - if (!attr) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (attr.addr() % CellSpursTasksetAttribute::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - attr->m.enable_clear_ls = enable ? 1 : 0; - return CELL_OK; -} - -s32 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision) -{ - cellSpurs.Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); - - memset(attribute.get_ptr(), 0, CellSpursTasksetAttribute2::size); - attribute->m.revision = revision; - attribute->m.name = vm::null; - attribute->m.args = 0; - - for (s32 i = 0; i < 8; i++) - { - attribute->m.priority[i] = 1; - } - - attribute->m.max_contention = 8; - attribute->m.enable_clear_ls = 0; - attribute->m.task_name_buffer.set(0); - return CELL_OK; -} - -s32 cellSpursTaskExitCodeGet() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTaskExitCodeInitialize() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTaskExitCodeTryGet() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTaskGetLoadableSegmentPattern() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTaskGetReadOnlyAreaPattern() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTaskGenerateLsPattern() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 _cellSpursTaskAttributeInitialize() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTaskAttributeSetExitCodeContainer() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 _cellSpursTaskAttribute2Initialize(vm::ptr attribute, u32 revision) -{ - cellSpurs.Warning("_cellSpursTaskAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); - - attribute->revision = revision; - attribute->sizeContext = 0; - attribute->eaContext = 0; - - for (s32 c = 0; c < 4; c++) - { - attribute->lsPattern._u32[c] = 0; - } - - attribute->name_addr = 0; - - return CELL_OK; -} - -s32 cellSpursTaskGetContextSaveAreaSize() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) -{ - cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); - - vm::ptr tmp_attr; - - if (!attr) - { - attr.set(tmp_attr.addr()); - _cellSpursTasksetAttribute2Initialize(attr, 0); - } - - auto rc = spursCreateTaskset(spurs, vm::ptr::make(taskset.addr()), attr->m.args, - vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, m.priority)), - attr->m.max_contention, attr->m.name, CellSpursTaskset2::size, (u8)attr->m.enable_clear_ls); - if (rc != CELL_OK) - { - return rc; - } - - if (attr->m.task_name_buffer.addr() % CellSpursTaskNameBuffer::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - // TODO: Implement rest of the function - return CELL_OK; -} - -s32 cellSpursCreateTask2() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursJoinTask2() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTryJoinTask2() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursDestroyTaskset2() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursCreateTask2WithBinInfo() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg) -{ - cellSpurs.Warning("%s(taskset=0x5x, handler=0x%x, arg=0x%x)", __FUNCTION__, taskset.addr(), handler.addr(), arg.addr()); - - if (!taskset || !handler) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - if (taskset->m.exception_handler) - { - return CELL_SPURS_TASK_ERROR_BUSY; - } - - taskset->m.exception_handler = handler; - taskset->m.exception_handler_arg = arg; - return CELL_OK; -} - -s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset) -{ - cellSpurs.Warning("%s(taskset=0x%x)", __FUNCTION__, taskset.addr()); - - if (!taskset) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - taskset->m.exception_handler.set(0); - taskset->m.exception_handler_arg.set(0); - return CELL_OK; -} - -s32 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id) -{ - cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, id=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), id); - - if (taskset.addr() == 0) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - vm::var> data; - auto rc = cellSpursGetWorkloadData(spurs, data, id); - if (rc != CELL_OK) - { - // Convert policy module error code to a task error code - return rc ^ 0x100; - } - - taskset.set((u32)data.value()); - return CELL_OK; -} - -s32 cellSpursTasksetGetSpursAddress(vm::ptr taskset, vm::ptr spurs) -{ - cellSpurs.Warning("%s(taskset=0x%x, spurs=0x%x)", __FUNCTION__, taskset.addr(), spurs.addr()); - - if (!taskset || !spurs) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (taskset.addr() % CellSpursTaskset::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - if (taskset->m.wid >= CELL_SPURS_MAX_WORKLOAD) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - - *spurs = (u32)taskset->m.spurs.addr(); - return CELL_OK; -} - -s32 cellSpursGetTasksetInfo() -{ - UNIMPLEMENTED_FUNC(cellSpurs); - return CELL_OK; -} - -s32 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::ptr priority, u32 max_contention) -{ - cellSpurs.Warning("%s(attribute=0x%x, revision=%d, skd_version=%d, args=0x%llx, priority=0x%x, max_contention=%d)", - __FUNCTION__, attribute.addr(), revision, sdk_version, args, priority.addr(), max_contention); - - if (!attribute) - { - return CELL_SPURS_TASK_ERROR_NULL_POINTER; - } - - if (attribute.addr() % CellSpursTasksetAttribute::align) - { - return CELL_SPURS_TASK_ERROR_ALIGN; - } - - for (u32 i = 0; i < 8; i++) - { - if (priority[i] > 0xF) - { - return CELL_SPURS_TASK_ERROR_INVAL; - } - } - - memset(attribute.get_ptr(), 0, CellSpursTasksetAttribute::size); - attribute->m.revision = revision; - attribute->m.sdk_version = sdk_version; - attribute->m.args = args; - memcpy(attribute->m.priority, priority.get_ptr(), 8); - attribute->m.taskset_size = 6400/*CellSpursTaskset::size*/; - attribute->m.max_contention = max_contention; - return CELL_OK; -} - s32 cellSpursJobGuardInitialize() { UNIMPLEMENTED_FUNC(cellSpurs); @@ -2961,190 +4206,6 @@ s32 cellSpursSemaphoreGetTasksetAddress() return CELL_OK; } -bool spursIsLibProfLoaded() -{ - return false; -} - -void spursTraceStatusUpdate(vm::ptr spurs) -{ - LV2_LOCK; - - if (spurs->m.xCC != 0) - { - spurs->m.xCD = 1; - spurs->m.sysSrvMsgUpdateTrace = (1 << spurs->m.nSpus) - 1; - spurs->m.sysSrvMessage.write_relaxed(0xFF); - sys_semaphore_wait((u32)spurs->m.semPrv, 0); - } -} - -s32 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus) -{ - if (!spurs || !buffer) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align || buffer.addr() % CellSpursTraceInfo::align) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - if (size < CellSpursTraceInfo::size || mode & ~(CELL_SPURS_TRACE_MODE_FLAG_MASK)) - { - return CELL_SPURS_CORE_ERROR_INVAL; - } - - if (spurs->m.traceBuffer) - { - return CELL_SPURS_CORE_ERROR_STAT; - } - - spurs->m.traceDataSize = size - CellSpursTraceInfo::size; - for (u32 i = 0; i < 8; i++) - { - buffer->spu_thread[i] = spurs->m.spus[i]; - buffer->count[i] = 0; - } - - buffer->spu_thread_grp = spurs->m.spuTG; - buffer->nspu = spurs->m.nSpus; - spurs->m.traceBuffer.set(buffer.addr() | (mode & CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER ? 1 : 0)); - spurs->m.traceMode = mode; - - u32 spuTraceDataCount = (u32)((spurs->m.traceDataSize / CellSpursTracePacket::size) / spurs->m.nSpus); - for (u32 i = 0, j = 8; i < 6; i++) - { - spurs->m.traceStartIndex[i] = j; - j += spuTraceDataCount; - } - - spurs->m.sysSrvTraceControl = 0; - if (updateStatus) - { - spursTraceStatusUpdate(spurs); - } - - return CELL_OK; -} - -s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode) -{ - if (spursIsLibProfLoaded()) - { - return CELL_SPURS_CORE_ERROR_STAT; - } - - return spursTraceInitialize(spurs, buffer, size, mode, 1); -} - -s32 spursTraceStart(vm::ptr spurs, u32 updateStatus) -{ - if (!spurs) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - if (!spurs->m.traceBuffer) - { - return CELL_SPURS_CORE_ERROR_STAT; - } - - spurs->m.sysSrvTraceControl = 1; - if (updateStatus) - { - spursTraceStatusUpdate(spurs); - } - - return CELL_OK; -} - -s32 cellSpursTraceStart(vm::ptr spurs) -{ - if (!spurs) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - return spursTraceStart(spurs, spurs->m.traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); -} - -s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) -{ - if (!spurs) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - if (!spurs->m.traceBuffer) - { - return CELL_SPURS_CORE_ERROR_STAT; - } - - spurs->m.sysSrvTraceControl = 2; - if (updateStatus) - { - spursTraceStatusUpdate(spurs); - } - - return CELL_OK; -} - -s32 cellSpursTraceStop(vm::ptr spurs) -{ - if (!spurs) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - return spursTraceStop(spurs, spurs->m.traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); -} - -s32 cellSpursTraceFinalize(vm::ptr spurs) -{ - if (!spurs) - { - return CELL_SPURS_CORE_ERROR_NULL_POINTER; - } - - if (spurs.addr() % CellSpurs::align) - { - return CELL_SPURS_CORE_ERROR_ALIGN; - } - - if (!spurs->m.traceBuffer) - { - return CELL_SPURS_CORE_ERROR_STAT; - } - - spurs->m.sysSrvTraceControl = 0; - spurs->m.traceMode = 0; - spurs->m.traceBuffer.set(0); - spursTraceStatusUpdate(spurs); - return CELL_OK; -} - Module cellSpurs("cellSpurs", []() { // Core diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index 8a049fc7cf..ad05f23f9c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -1,5 +1,10 @@ #pragma once +namespace vm { using namespace ps3; } + +struct CellSpurs; +struct CellSpursTaskset; + // Core return codes. enum { @@ -87,45 +92,40 @@ enum }; // SPURS defines. -enum SPURSKernelInterfaces +enum SPURSKernelInterfaces : u32 { - CELL_SPURS_MAX_SPU = 8, - CELL_SPURS_MAX_WORKLOAD = 16, - CELL_SPURS_MAX_WORKLOAD2 = 32, - CELL_SPURS_SYS_SERVICE_WORKLOAD_ID = 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, - CELL_SPURS_KERNEL1_ENTRY_ADDR = 0x818, - CELL_SPURS_KERNEL2_ENTRY_ADDR = 0x848, - CELL_SPURS_KERNEL1_EXIT_ADDR = 0x808, - CELL_SPURS_KERNEL2_EXIT_ADDR = 0x838, + CELL_SPURS_MAX_SPU = 8, + CELL_SPURS_MAX_WORKLOAD = 16, + CELL_SPURS_MAX_WORKLOAD2 = 32, + CELL_SPURS_SYS_SERVICE_WORKLOAD_ID = 32, + CELL_SPURS_MAX_PRIORITY = 16, + CELL_SPURS_NAME_MAX_LENGTH = 15, + CELL_SPURS_SIZE = 4096, + CELL_SPURS_SIZE2 = 8192, + CELL_SPURS_INTERRUPT_VECTOR = 0x0, + CELL_SPURS_LOCK_LINE = 0x80, + CELL_SPURS_KERNEL_DMA_TAG_ID = 31, + CELL_SPURS_KERNEL1_ENTRY_ADDR = 0x818, + CELL_SPURS_KERNEL2_ENTRY_ADDR = 0x848, + CELL_SPURS_KERNEL1_EXIT_ADDR = 0x808, + CELL_SPURS_KERNEL2_EXIT_ADDR = 0x838, CELL_SPURS_KERNEL1_SELECT_WORKLOAD_ADDR = 0x290, CELL_SPURS_KERNEL2_SELECT_WORKLOAD_ADDR = 0x290, }; enum RangeofEventQueuePortNumbers { - CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15, - CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16, + CELL_SPURS_STATIC_PORT_RANGE_BOTTOM = 15, + CELL_SPURS_DYNAMIC_PORT_RANGE_TOP = 16, CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63, }; enum SpursAttrFlags : u32 { - SAF_NONE = 0x0, - - SAF_EXIT_IF_NO_WORK = 0x1, - SAF_UNKNOWN_FLAG_30 = 0x2, - SAF_SECOND_VERSION = 0x4, - + SAF_NONE = 0x00000000, + SAF_EXIT_IF_NO_WORK = 0x00000001, + SAF_UNKNOWN_FLAG_30 = 0x00000002, + SAF_SECOND_VERSION = 0x00000004, SAF_UNKNOWN_FLAG_9 = 0x00400000, SAF_UNKNOWN_FLAG_8 = 0x00800000, SAF_UNKNOWN_FLAG_7 = 0x01000000, @@ -138,13 +138,12 @@ enum SpursAttrFlags : u32 enum SpursFlags1 : u8 { - SF1_NONE = 0x0, - + SF1_NONE = 0x00, SF1_32_WORKLOADS = 0x40, SF1_EXIT_IF_NO_WORK = 0x80, }; -enum SpursWorkloadConstants : u64 +enum SpursWorkloadConstants : u32 { // Workload states SPURS_WKL_STATE_NON_EXISTENT = 0, @@ -154,15 +153,18 @@ enum SpursWorkloadConstants : u64 SPURS_WKL_STATE_REMOVABLE = 4, SPURS_WKL_STATE_INVALID = 5, - // GUID - SPURS_GUID_SYS_WKL = 0x1BB841BF38F89D33ull, - SPURS_GUID_TASKSET_PM = 0x836E915B2E654143ull, - // Image addresses SPURS_IMG_ADDR_SYS_SRV_WORKLOAD = 0x100, SPURS_IMG_ADDR_TASKSET_PM = 0x200, }; +enum SpursWorkloadGUIDs : u64 +{ + // GUID + SPURS_GUID_SYS_WKL = 0x1BB841BF38F89D33ull, + SPURS_GUID_TASKSET_PM = 0x836E915B2E654143ull, +}; + enum CellSpursModulePollStatus { CELL_SPURS_MODULE_POLL_STATUS_READYCOUNT = 1, @@ -257,369 +259,387 @@ enum SpursEventFlagConstants CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT = 0xFF, }; -class SPURSManager; -class SPURSManagerEventFlag; -class SPURSManagerTaskset; -struct CellSpurs; - -struct CellSpursAttribute -{ - static const uint align = 8; - static const uint size = 512; - - union - { - // raw data - u8 _u8[size]; - struct { be_t _u32[size / sizeof(u32)]; }; - - // real data - struct - { - be_t revision; // 0x0 - be_t sdkVersion; // 0x4 - be_t nSpus; // 0x8 - be_t spuPriority; // 0xC - be_t ppuPriority; // 0x10 - bool exitIfNoWork; // 0x14 - char prefix[15]; // 0x15 (not a NTS) - be_t prefixSize; // 0x24 - be_t flags; // 0x28 (SpursAttrFlags) - be_t container; // 0x2C - be_t unk0; // 0x30 - be_t unk1; // 0x34 - u8 swlPriority[8]; // 0x38 - be_t swlMaxSpu; // 0x40 - be_t swlIsPreem; // 0x44 - } m; - - // alternative implementation - struct - { - } c; - }; -}; - -struct CellSpursWorkloadFlag +struct set_alignment(16) CellSpursWorkloadFlag { be_t unused0; be_t unused1; atomic_be_t flag; }; -typedef void(CellSpursShutdownCompletionEventHook)(vm::ptr, u32 wid, vm::ptr arg); +CHECK_SIZE_ALIGN(CellSpursWorkloadFlag, 16, 16); -struct CellSpursTraceInfo +struct CellSpursInfo { - static const u32 size = 0x80; - static const u32 align = 16; - - be_t spu_thread[8]; // 0x00 - be_t count[8]; // 0x20 - be_t spu_thread_grp; // 0x40 - be_t nspu; // 0x44 - //u8 padding[]; + be_t nSpus; + be_t spuThreadGroupPriority; + be_t ppuThreadPriority; + bool exitIfNoWork; + bool spurs2; + u8 padding24[2]; + vm::bptr traceBuffer; + be_t padding32; + be_t traceBufferSize; + be_t traceMode; + be_t spuThreadGroup; + be_t spuThreads[8]; + be_t spursHandlerThread0; + be_t spursHandlerThread1; + char namePrefix[16]; + be_t namePrefixLength; + be_t deadlineMissCounter; + be_t deadlineMeetCounter; + u8 padding[164]; }; -struct CellSpursTracePacket -{ - static const u32 size = 16; +CHECK_SIZE(CellSpursInfo, 280); - struct - { - u8 tag; - u8 length; - u8 spu; - u8 workload; - be_t time; - } header; +struct set_alignment(8) CellSpursAttribute +{ + be_t revision; // 0x0 + be_t sdkVersion; // 0x4 + be_t nSpus; // 0x8 + be_t spuPriority; // 0xC + be_t ppuPriority; // 0x10 + bool exitIfNoWork; // 0x14 + char prefix[15]; // 0x15 (not a NTS) + be_t prefixSize; // 0x24 + be_t flags; // 0x28 (SpursAttrFlags) + be_t container; // 0x2C + be_t unk0; // 0x30 + be_t unk1; // 0x34 + u8 swlPriority[8]; // 0x38 + be_t swlMaxSpu; // 0x40 + be_t swlIsPreem; // 0x44 + u8 padding[440]; +}; + +CHECK_SIZE_ALIGN(CellSpursAttribute, 512, 8); + +using CellSpursShutdownCompletionEventHook = func_def spurs, u32 wid, vm::ptr arg)>; + +struct set_alignment(16) CellSpursTraceInfo +{ + be_t spuThread[8]; // 0x00 + be_t count[8]; // 0x20 + be_t spuThreadGroup; // 0x40 + be_t numSpus; // 0x44 + u8 padding[56]; +}; + +CHECK_SIZE_ALIGN(CellSpursTraceInfo, 128, 16); + +struct CellSpursTraceHeader +{ + u8 tag; + u8 length; + u8 spu; + u8 workload; + be_t time; +}; + +struct CellSpursTraceControlData +{ + be_t incident; + be_t reserved; +}; + +struct CellSpursTraceServiceData +{ + be_t incident; + be_t reserved; +}; + +struct CellSpursTraceTaskData +{ + be_t incident; + be_t taskId; +}; + +struct CellSpursTraceJobData +{ + u8 reserved[3]; + u8 binLSAhigh8; + be_t jobDescriptor; +}; + +struct CellSpursTraceLoadData +{ + be_t ea; + be_t ls; + be_t size; +}; + +struct CellSpursTraceMapData +{ + be_t offset; + be_t ls; + be_t size; +}; + +struct CellSpursTraceStartData +{ + char module[4]; + be_t level; + be_t ls; +}; + +struct set_alignment(16) CellSpursTracePacket +{ + CellSpursTraceHeader header; union { - struct - { - be_t incident; - be_t reserved; - } service; + CellSpursTraceControlData control; + CellSpursTraceServiceData service; + CellSpursTraceTaskData task; + CellSpursTraceJobData job; - struct - { - be_t ea; - be_t ls; - be_t size; - } load; - - struct - { - be_t offset; - be_t ls; - be_t size; - } map; - - struct - { - s8 module[4]; - be_t level; - be_t ls; - } start; - - struct - { - be_t incident; - be_t taskId; - } task; + CellSpursTraceLoadData load; + CellSpursTraceMapData map; + CellSpursTraceStartData start; + be_t stop; be_t user; be_t guid; - be_t stop; - } data; + be_t raw; + } + data; }; -// Core CellSpurs structures -struct CellSpurs -{ - static const uint align = 128; - static const uint size = 0x2000; // size of CellSpurs2 - static const uint size1 = 0x1000; // size of CellSpurs - static const uint size2 = 0x1000; +CHECK_SIZE_ALIGN(CellSpursTracePacket, 16, 16); +// Core CellSpurs structures +struct set_alignment(128) CellSpurs +{ struct _sub_str1 { - u8 unk0[0x20]; // 0x00 - SPU exceptionh handler 0x08 - SPU exception handler args + u8 unk0[0x20]; // 0x00 - SPU exception handler 0x08 - SPU exception handler args be_t sem; // 0x20 - u8 unk1[0x8]; + be_t x28; // 0x28 + be_t x2C; // 0x2C vm::bptr hook; // 0x30 vm::bptr hookArg; // 0x38 u8 unk2[0x40]; }; - static_assert(sizeof(_sub_str1) == 0x80, "Wrong _sub_str1 size"); + CHECK_SIZE(_sub_str1, 128); - struct _sub_str2 // Event port multiplexer + struct EventPortMux; + + using EventHandlerCallback = func_def, u64 data)>; + + struct EventHandlerListNode { - be_t unk0; // 0x00 Outstanding requests - be_t unk1; // 0x04 - be_t unk2; // 0x08 - be_t unk3; // 0x0C - be_t port; // 0x10 - u8 unk_[0x68]; // 0x18 - The first u64 seems to be the start of a linked list. The linked list struct seems to be {u64 next; u64 data; u64 handler} + vm::bptr next; + be_t data; + vm::bptr handler; }; - static_assert(sizeof(_sub_str2) == 0x80, "Wrong _sub_str2 size"); + struct EventPortMux + { + atomic_be_t reqPending; // 0x00 + be_t spuPort; // 0x04 + be_t x08; // 0x08 + be_t x0C; // 0x0C + be_t eventPort; // 0x10 + atomic_be_t> handlerList; // 0x18 + u8 x20[0x80 - 0x20]; // 0x20 + }; + + CHECK_SIZE(EventPortMux, 128); struct WorkloadInfo { - vm::bptr addr; // Address of the executable - be_t arg; // spu argument - be_t size; - atomic_be_t uniqueId; // The unique id is the same for all workloads with the same addr + vm::bcptr addr; // 0x00 Address of the executable + be_t arg; // 0x08 Argument + be_t size; // 0x10 Size of the executable + atomic_be_t uniqueId; // 0x14 Unique id of the workload. It is the same for all workloads with the same addr. u8 pad[3]; - u8 priority[8]; + u8 priority[8]; // 0x18 Priority of the workload on each SPU }; - static_assert(sizeof(WorkloadInfo) == 0x20, "Wrong WorkloadInfo size"); + CHECK_SIZE(WorkloadInfo, 32); struct _sub_str4 { - static const uint size = 0x10; - - vm::bptr nameClass; - vm::bptr nameInstance; + vm::bcptr nameClass; + vm::bcptr nameInstance; }; - union + atomic_be_t wklReadyCount1[0x10]; // 0x00 Number of SPUs requested by each workload (0..15 wids). + atomic_be_t wklIdleSpuCountOrReadyCount2[0x10]; // 0x10 SPURS1: Number of idle SPUs requested by each workload (0..15 wids). SPURS2: Number of SPUs requested by each workload (16..31 wids). + u8 wklCurrentContention[0x10]; // 0x20 Number of SPUs used by each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. + u8 wklPendingContention[0x10]; // 0x30 Number of SPUs that are pending to context switch to the workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. + u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused. + atomic_be_t wklMaxContention[0x10]; // 0x50 Max SPUs that may be allocated to each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. + CellSpursWorkloadFlag wklFlag; // 0x60 + atomic_be_t wklSignal1; // 0x70 Bitset for 0..15 wids + atomic_be_t sysSrvMessage; // 0x72 + u8 spuIdling; // 0x73 + u8 flags1; // 0x74 Type is SpursFlags1 + u8 sysSrvTraceControl; // 0x75 + u8 nSpus; // 0x76 + atomic_be_t wklFlagReceiver; // 0x77 + atomic_be_t wklSignal2; // 0x78 Bitset for 16..32 wids + u8 x7A[6]; // 0x7A + atomic_be_t wklState1[0x10]; // 0x80 SPURS_WKL_STATE_* + u8 wklStatus1[0x10]; // 0x90 + atomic_be_t wklEvent1[0x10]; // 0xA0 + atomic_be_t wklEnabled; // 0xB0 + atomic_be_t wklMskB; // 0xB4 - System service - Available module id + u32 xB8; // 0xB8 + u8 sysSrvExitBarrier; // 0xBC + atomic_be_t sysSrvMsgUpdateWorkload; // 0xBD + u8 xBE; // 0xBE + u8 sysSrvMsgTerminate; // 0xBF + u8 sysSrvPreemptWklId[8]; // 0xC0 Id of the workload that was preempted by the system workload on each SPU + u8 sysSrvOnSpu; // 0xC8 + u8 spuPort; // 0xC9 + u8 xCA; // 0xCA + u8 xCB; // 0xCB + + struct SrvTraceSyncVar { - // raw data - u8 _u8[size]; - std::array, size / sizeof(u32)> _u32; - - // real data - struct - { - atomic_be_t wklReadyCount1[0x10]; // 0x00 Number of SPUs requested by each workload (0..15 wids). - atomic_be_t wklIdleSpuCountOrReadyCount2[0x10]; // 0x10 SPURS1: Number of idle SPUs requested by each workload (0..15 wids). SPURS2: Number of SPUs requested by each workload (16..31 wids). - u8 wklCurrentContention[0x10]; // 0x20 Number of SPUs used by each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. - u8 wklPendingContention[0x10]; // 0x30 Number of SPUs that are pending to context switch to the workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. - u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused. - atomic_be_t wklMaxContention[0x10]; // 0x50 Max SPUs that may be allocated to each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16. - CellSpursWorkloadFlag wklFlag; // 0x60 - atomic_be_t wklSignal1; // 0x70 (bitset for 0..15 wids) - atomic_be_t sysSrvMessage; // 0x72 - u8 spuIdling; // 0x73 - u8 flags1; // 0x74 Type is SpursFlags1 - u8 sysSrvTraceControl; // 0x75 - u8 nSpus; // 0x76 - atomic_be_t wklFlagReceiver; // 0x77 - atomic_be_t wklSignal2; // 0x78 (bitset for 16..32 wids) - u8 x7A[6]; // 0x7A - atomic_be_t wklState1[0x10]; // 0x80 SPURS_WKL_STATE_* - u8 wklStatus1[0x10]; // 0x90 - u8 wklEvent1[0x10]; // 0xA0 - atomic_be_t wklMskA; // 0xB0 - System service - Available workloads (32*u1) - atomic_be_t wklMskB; // 0xB4 - System service - Available module id - u32 xB8; // 0xB8 - u8 sysSrvExitBarrier; // 0xBC - atomic_be_t sysSrvMsgUpdateWorkload; // 0xBD - u8 xBE; // 0xBE - u8 sysSrvMsgTerminate; // 0xBF - u8 sysSrvWorkload[8]; // 0xC0 - u8 sysSrvOnSpu; // 0xC8 - u8 spuPort; // 0xC9 - u8 xCA; // 0xCA - u8 xCB; // 0xCB - u8 xCC; // 0xCC - u8 xCD; // 0xCD - u8 sysSrvMsgUpdateTrace; // 0xCE - u8 xCF; // 0xCF - atomic_be_t wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_* - u8 wklStatus2[0x10]; // 0xE0 - u8 wklEvent2[0x10]; // 0xF0 - _sub_str1 wklF1[0x10]; // 0x100 - vm::bptr traceBuffer; // 0x900 - be_t traceStartIndex[6]; // 0x908 - u8 unknown7[0x948 - 0x920]; // 0x920 - be_t traceDataSize; // 0x948 - be_t traceMode; // 0x950 - u8 unknown8[0x980 - 0x954]; // 0x954 - be_t semPrv; // 0x980 - be_t unk11; // 0x988 - be_t unk12; // 0x98C - be_t unk13; // 0x990 - u8 unknown4[0xB00 - 0x998]; - WorkloadInfo wklInfo1[0x10]; // 0xB00 - WorkloadInfo wklInfoSysSrv; // 0xD00 - be_t ppu0; // 0xD20 - be_t ppu1; // 0xD28 - be_t spuTG; // 0xD30 - SPU thread group - be_t spus[8]; // 0xD34 - u8 unknown3[0xD5C - 0xD54]; - be_t queue; // 0xD5C - Event queue - be_t port; // 0xD60 - Event port - atomic_be_t xD64; // 0xD64 - SPURS handler dirty - atomic_be_t xD65; // 0xD65 - SPURS handler waiting - atomic_be_t xD66; // 0xD66 - SPURS handler exiting - atomic_be_t enableEH; // 0xD68 - be_t exception; // 0xD6C - sys_spu_image spuImg; // 0xD70 - be_t flags; // 0xD80 - be_t spuPriority; // 0xD84 - be_t ppuPriority; // 0xD88 - char prefix[0x0f]; // 0xD8C - u8 prefixSize; // 0xD9B - be_t unk5; // 0xD9C - be_t revision; // 0xDA0 - be_t sdkVersion; // 0xDA4 - atomic_be_t spups; // 0xDA8 - SPU port bits - sys_lwmutex_t mutex; // 0xDB0 - sys_lwcond_t cond; // 0xDC8 - u8 unknown9[0xE00 - 0xDD0]; - _sub_str4 wklH1[0x10]; // 0xE00 - _sub_str2 sub3; // 0xF00 - u8 unknown6[0x1000 - 0xF80]; // 0xF80 - Gloabl SPU exception handler 0xF88 - Gloabl SPU exception handlers args - WorkloadInfo wklInfo2[0x10]; // 0x1000 - _sub_str1 wklF2[0x10]; // 0x1200 - _sub_str4 wklH2[0x10]; // 0x1A00 - } m; - - // alternative implementation - struct - { - SPURSManager *spurs; - } c; + u8 sysSrvTraceInitialised; // 0xCC + u8 sysSrvNotifyUpdateTraceComplete; // 0xCD + u8 sysSrvMsgUpdateTrace; // 0xCE + u8 xCF; }; + atomic_be_t sysSrvTrace; // 0xCC + + atomic_be_t wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_* + u8 wklStatus2[0x10]; // 0xE0 + atomic_be_t wklEvent2[0x10]; // 0xF0 + _sub_str1 wklF1[0x10]; // 0x100 + vm::bptr traceBuffer; // 0x900 + be_t traceStartIndex[6]; // 0x908 + u8 unknown7[0x948 - 0x920]; // 0x920 + be_t traceDataSize; // 0x948 + be_t traceMode; // 0x950 + u8 unknown8[0x980 - 0x954]; // 0x954 + be_t semPrv; // 0x980 + be_t unk11; // 0x988 + be_t unk12; // 0x98C + be_t unk13; // 0x990 + u8 unknown4[0xB00 - 0x998]; + WorkloadInfo wklInfo1[0x10]; // 0xB00 + WorkloadInfo wklInfoSysSrv; // 0xD00 + be_t ppu0; // 0xD20 Handler thread + be_t ppu1; // 0xD28 + be_t spuTG; // 0xD30 SPU thread group + be_t spus[8]; // 0xD34 + u8 unknown3[0xD5C - 0xD54]; + be_t eventQueue; // 0xD5C + be_t eventPort; // 0xD60 + atomic_be_t handlerDirty; // 0xD64 + atomic_be_t handlerWaiting; // 0xD65 + atomic_be_t handlerExiting; // 0xD66 + atomic_be_t enableEH; // 0xD68 + be_t exception; // 0xD6C + sys_spu_image spuImg; // 0xD70 + be_t flags; // 0xD80 + be_t spuPriority; // 0xD84 + be_t ppuPriority; // 0xD88 + char prefix[0x0f]; // 0xD8C + u8 prefixSize; // 0xD9B + be_t unk5; // 0xD9C + be_t revision; // 0xDA0 + be_t sdkVersion; // 0xDA4 + atomic_be_t spuPortBits; // 0xDA8 + sys_lwmutex_t mutex; // 0xDB0 + sys_lwcond_t cond; // 0xDC8 + u8 unknown9[0xE00 - 0xDD0]; + _sub_str4 wklH1[0x10]; // 0xE00 + EventPortMux eventPortMux; // 0xF00 + atomic_be_t globalSpuExceptionHandler; // 0xF80 + be_t globalSpuExceptionHandlerArgs; // 0xF88 + u8 unknown6[0x1000 - 0xF90]; + WorkloadInfo wklInfo2[0x10]; // 0x1000 + _sub_str1 wklF2[0x10]; // 0x1200 + _sub_str4 wklH2[0x10]; // 0x1A00 + u8 unknown_[0x2000 - 0x1B00]; + force_inline atomic_be_t& wklState(const u32 wid) { if (wid & 0x10) { - return m.wklState2[wid & 0xf]; + return wklState2[wid & 0xf]; } else { - return m.wklState1[wid & 0xf]; + return wklState1[wid & 0xf]; } } - - force_inline vm::ptr get_lwmutex() - { - return vm::ptr::make(vm::get_addr(&m.mutex)); - } - - force_inline vm::ptr get_lwcond() - { - return vm::ptr::make(vm::get_addr(&m.cond)); - } }; -typedef CellSpurs CellSpurs2; +CHECK_SIZE_ALIGN(CellSpurs, 0x2000, 128); + +using CellSpurs2 = CellSpurs; + +struct CellSpursExceptionInfo +{ + be_t spu_thread; + be_t spu_npc; + be_t cause; + be_t option; +}; + +// Exception handler +using CellSpursGlobalExceptionEventHandler = func_def spurs, vm::cptr info, u32 id, vm::ptr arg)>; struct CellSpursWorkloadAttribute { - static const uint align = 8; - static const uint size = 512; - - union - { - // raw data - u8 _u8[size]; - - // real data - struct - { - be_t revision; - be_t sdkVersion; - vm::bptr pm; - be_t size; - be_t data; - u8 priority[8]; - be_t minContention; - be_t maxContention; - vm::bptr nameClass; - vm::bptr nameInstance; - vm::bptr hook; - vm::bptr hookArg; - } m; - }; + be_t revision; + be_t sdkVersion; + vm::bcptr pm; + be_t size; + be_t data; + u8 priority[8]; + be_t minContention; + be_t maxContention; + vm::bcptr nameClass; + vm::bcptr nameInstance; + vm::bptr hook; + vm::bptr hookArg; + u8 padding[456]; }; -struct CellSpursEventFlag +CHECK_SIZE_ALIGN(CellSpursWorkloadAttribute, 512, 8); + +struct set_alignment(128) CellSpursEventFlag { - static const u32 align = 128; - static const u32 size = 128; + struct ControlSyncVar + { + be_t events; // 0x00 Event bits + be_t spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks + be_t ppuWaitMask; // 0x04 Wait mask for blocked PPU thread + u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread + u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked + }; union { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t events; // 0x00 Event bits - be_t spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks - be_t ppuWaitMask; // 0x04 Wait mask for blocked PPU thread - u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread - u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked - be_t spuTaskUsedWaitSlots; // 0x08 A bit is set to 1 if the wait slot corresponding to the bit is used by an SPU task and 0 otherwise - be_t spuTaskWaitMode; // 0x0A A bit is set to 1 if the wait mode for the SPU task corresponding to the bit is AND and 0 otherwise - u8 spuPort; // 0x0C - u8 isIwl; // 0x0D - u8 direction; // 0x0E - u8 clearMode; // 0x0F - be_t spuTaskWaitMask[16]; // 0x10 Wait mask for blocked SPU tasks - be_t pendingRecvTaskEvents[16]; // 0x30 The value of event flag when the wait condition for the thread/task was met - u8 waitingTaskId[16]; // 0x50 Task id of waiting SPU threads - u8 waitingTaskWklId[16]; // 0x60 Workload id of waiting SPU threads - be_t addr; // 0x70 - be_t eventPortId; // 0x78 - be_t eventQueueId; // 0x7C - } m; - - SPURSManagerEventFlag *eventFlag; + atomic_be_t ctrl; // 0x00 + atomic_be_t events; // 0x00 }; + + be_t spuTaskUsedWaitSlots; // 0x08 A bit is set to 1 if the wait slot corresponding to the bit is used by an SPU task and 0 otherwise + be_t spuTaskWaitMode; // 0x0A A bit is set to 1 if the wait mode for the SPU task corresponding to the bit is AND and 0 otherwise + u8 spuPort; // 0x0C + u8 isIwl; // 0x0D + u8 direction; // 0x0E + u8 clearMode; // 0x0F + be_t spuTaskWaitMask[16]; // 0x10 Wait mask for blocked SPU tasks + be_t pendingRecvTaskEvents[16]; // 0x30 The value of event flag when the wait condition for the thread/task was met + u8 waitingTaskId[16]; // 0x50 Task id of waiting SPU threads + u8 waitingTaskWklId[16]; // 0x60 Workload id of waiting SPU threads + be_t addr; // 0x70 + be_t eventPortId; // 0x78 + be_t eventQueueId; // 0x7C }; -static_assert(sizeof(CellSpursEventFlag) == CellSpursEventFlag::size, "Wrong CellSpursEventFlag size"); +CHECK_SIZE_ALIGN(CellSpursEventFlag, 128, 128); union CellSpursTaskArgument { @@ -633,120 +653,123 @@ union CellSpursTaskLsPattern be_t _u64[2]; }; -struct CellSpursTaskset +struct set_alignment(16) CellSpursTaskAttribute { - static const u32 align = 128; - static const u32 size = 6400; + u8 reserved[256]; +}; +CHECK_SIZE_ALIGN(CellSpursTaskAttribute, 256, 16); + +struct set_alignment(16) CellSpursTaskAttribute2 +{ + be_t revision; + be_t sizeContext; + be_t eaContext; + CellSpursTaskLsPattern lsPattern; + vm::bcptr name; + + u8 reserved[220]; +}; + +CHECK_SIZE_ALIGN(CellSpursTaskAttribute2, 256, 16); + +// Exception handler +using CellSpursTasksetExceptionEventHandler = func_def spurs, vm::ptr taskset, u32 idTask, vm::cptr info, vm::ptr arg)>; + +struct set_alignment(128) CellSpursTaskExitCode +{ + u8 skip[128]; +}; + +CHECK_SIZE_ALIGN(CellSpursTaskExitCode, 128, 128); + +struct CellSpursTaskInfo +{ + CellSpursTaskLsPattern lsPattern; + CellSpursTaskArgument argument; + vm::bptr eaElf; + vm::bptr eaContext; + be_t sizeContext; + u8 state; + u8 hasSignal; + u8 padding[2]; + vm::bcptr eaTaskExitCode; + u8 guid[8]; + u8 reserved[12]; +}; + +CHECK_SIZE(CellSpursTaskInfo, 72); + +struct CellSpursTasksetInfo +{ + CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; + be_t argument; + be_t idWorkload; + be_t idLastScheduledTask; + vm::bcptr name; + vm::bptr exceptionEventHandler; + vm::bptr exceptionEventHandlerArgument; + be_t sizeTaskset; + u8 reserved[112]; +}; + +CHECK_SIZE(CellSpursTasksetInfo, 9360); + +struct set_alignment(8) CellSpursTasksetAttribute +{ + be_t revision; // 0x00 + be_t sdk_version; // 0x04 + be_t args; // 0x08 + u8 priority[8]; // 0x10 + be_t max_contention; // 0x18 + vm::bcptr name; // 0x1C + be_t taskset_size; // 0x20 + be_t enable_clear_ls; // 0x24 + u8 reserved[472]; +}; + +CHECK_SIZE_ALIGN(CellSpursTasksetAttribute, 512, 8); + +struct set_alignment(128) CellSpursTaskset +{ struct TaskInfo { CellSpursTaskArgument args; // 0x00 - vm::bptr elf_addr; // 0x10 + vm::bcptr elf; // 0x10 be_t context_save_storage_and_alloc_ls_blocks; // 0x18 This is (context_save_storage_addr | allocated_ls_blocks) CellSpursTaskLsPattern ls_pattern; // 0x20 }; - static_assert(sizeof(TaskInfo) == 0x30, "Wrong TaskInfo size"); + CHECK_SIZE(TaskInfo, 48); - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t running; // 0x00 - be_t ready; // 0x10 - be_t pending_ready; // 0x20 - be_t enabled; // 0x30 - be_t signalled; // 0x40 - be_t waiting; // 0x50 - vm::bptr spurs; // 0x60 - be_t args; // 0x68 - u8 enable_clear_ls; // 0x70 - u8 x71; // 0x71 - u8 wkl_flag_wait_task; // 0x72 - u8 last_scheduled_task; // 0x73 - be_t wid; // 0x74 - be_t x78; // 0x78 - TaskInfo task_info[128]; // 0x80 - vm::bptr exception_handler; // 0x1880 - vm::bptr exception_handler_arg; // 0x1888 - be_t size; // 0x1890 - u32 unk2; // 0x1894 - u32 event_flag_id1; // 0x1898 - u32 event_flag_id2; // 0x189C - u8 unk3[0x60]; // 0x18A0 - } m; - - SPURSManagerTaskset *taskset; - }; + be_t running; // 0x00 + be_t ready; // 0x10 + be_t pending_ready; // 0x20 + be_t enabled; // 0x30 + be_t signalled; // 0x40 + be_t waiting; // 0x50 + vm::bptr spurs; // 0x60 + be_t args; // 0x68 + u8 enable_clear_ls; // 0x70 + u8 x71; // 0x71 + u8 wkl_flag_wait_task; // 0x72 + u8 last_scheduled_task; // 0x73 + be_t wid; // 0x74 + be_t x78; // 0x78 + TaskInfo task_info[128]; // 0x80 + vm::bptr exception_handler; // 0x1880 + vm::bptr exception_handler_arg; // 0x1888 + be_t size; // 0x1890 + u32 unk2; // 0x1894 + u32 event_flag_id1; // 0x1898 + u32 event_flag_id2; // 0x189C + u8 unk3[0x60]; // 0x18A0 }; -static_assert(sizeof(CellSpursTaskset) == CellSpursTaskset::size, "Wrong CellSpursTaskset size"); +CHECK_SIZE_ALIGN(CellSpursTaskset, 128 * 50, 128); -struct CellSpursInfo +struct set_alignment(128) CellSpursTaskset2 { - be_t nSpus; - be_t spuThreadGroupPriority; - be_t ppuThreadPriority; - bool exitIfNoWork; - bool spurs2; - be_t traceBuffer_addr; //void *traceBuffer; - be_t traceBufferSize; - be_t traceMode; - be_t spuThreadGroup; //typedef u32 sys_spu_thread_group_t; - be_t spuThreads[8]; //typedef u32 sys_spu_thread_t; - be_t spursHandlerThread0; - be_t spursHandlerThread1; - s8 namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1]; - be_t namePrefixLength; - be_t deadlineMissCounter; - be_t deadlineMeetCounter; - //u8 padding[]; -}; - -struct CellSpursExceptionInfo -{ - be_t spu_thread; - be_t spu_npc; - be_t cause; - be_t option; -}; - -// Exception handlers. -//typedef void (*CellSpursGlobalExceptionEventHandler)(vm::ptr spurs, vm::ptr info, -// u32 id, vm::ptr arg); -// -//typedef void (*CellSpursTasksetExceptionEventHandler)(vm::ptr spurs, vm::ptr taskset, -// u32 idTask, vm::ptr info, vm::ptr arg); - -struct CellSpursTaskNameBuffer -{ - static const u32 align = 16; - - char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; -}; - -struct CellSpursTasksetInfo -{ - //CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; - be_t argument; - be_t idWorkload; - be_t idLastScheduledTask; //typedef unsigned CellSpursTaskId - be_t name_addr; - be_t exceptionEventHandler_addr; - be_t exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument - be_t sizeTaskset; - //be_t reserved[]; -}; - -struct CellSpursTaskset2 -{ - static const u32 align = 128; - static const u32 size = 10496; - struct TaskInfo { CellSpursTaskArgument args; @@ -755,135 +778,60 @@ struct CellSpursTaskset2 CellSpursTaskLsPattern ls_pattern; }; - static_assert(sizeof(TaskInfo) == 0x30, "Wrong TaskInfo size"); + CHECK_SIZE(TaskInfo, 48); - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t running_set[4]; // 0x00 - be_t ready_set[4]; // 0x10 - be_t ready2_set[4]; // 0x20 - TODO: Find out what this is - be_t enabled_set[4]; // 0x30 - be_t signal_received_set[4]; // 0x40 - be_t waiting_set[4]; // 0x50 - vm::bptr spurs; // 0x60 - be_t args; // 0x68 - u8 enable_clear_ls; // 0x70 - u8 x71; // 0x71 - u8 x72; // 0x72 - u8 last_scheduled_task; // 0x73 - be_t wid; // 0x74 - be_t x78; // 0x78 - TaskInfo task_info[128]; // 0x80 - vm::bptr exception_handler; // 0x1880 - vm::bptr exception_handler_arg; // 0x1888 - be_t size; // 0x1890 - u32 unk2; // 0x1894 - u32 event_flag_id1; // 0x1898 - u32 event_flag_id2; // 0x189C - u8 unk3[0x1980 - 0x18A0]; // 0x18A0 - be_t task_exit_code[128]; // 0x1980 - u8 unk4[0x2900 - 0x2180]; // 0x2180 - } m; - }; + be_t running_set[4]; // 0x00 + be_t ready_set[4]; // 0x10 + be_t ready2_set[4]; // 0x20 - TODO: Find out what this is + be_t enabled_set[4]; // 0x30 + be_t signal_received_set[4]; // 0x40 + be_t waiting_set[4]; // 0x50 + vm::bptr spurs; // 0x60 + be_t args; // 0x68 + u8 enable_clear_ls; // 0x70 + u8 x71; // 0x71 + u8 x72; // 0x72 + u8 last_scheduled_task; // 0x73 + be_t wid; // 0x74 + be_t x78; // 0x78 + TaskInfo task_info[128]; // 0x80 + vm::bptr exception_handler; // 0x1880 + vm::bptr exception_handler_arg; // 0x1888 + be_t size; // 0x1890 + u32 unk2; // 0x1894 + u32 event_flag_id1; // 0x1898 + u32 event_flag_id2; // 0x189C + u8 unk3[0x1980 - 0x18A0]; // 0x18A0 + be_t task_exit_code[128]; // 0x1980 + u8 unk4[0x2900 - 0x2180]; // 0x2180 }; -static_assert(sizeof(CellSpursTaskset2) == CellSpursTaskset2::size, "Wrong CellSpursTaskset2 size"); +CHECK_SIZE_ALIGN(CellSpursTaskset2, 128 * 82, 128); -struct CellSpursTasksetAttribute +struct set_alignment(16) CellSpursTaskNameBuffer { - static const u32 align = 8; - static const u32 size = 512; - - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t revision; // 0x00 - be_t sdk_version; // 0x04 - be_t args; // 0x08 - u8 priority[8]; // 0x10 - be_t max_contention; // 0x18 - vm::bptr name; // 0x1C - be_t taskset_size; // 0x20 - be_t enable_clear_ls; // 0x24 - } m; - }; + char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; }; -struct CellSpursTasksetAttribute2 +struct set_alignment(8) CellSpursTasksetAttribute2 { - static const u32 align = 8; - static const u32 size = 512; - - union - { - // Raw data - u8 _u8[size]; - - // Real data - struct - { - be_t revision; // 0x00 - vm::bptr name; // 0x04 - be_t args; // 0x08 - u8 priority[8]; // 0x10 - be_t max_contention; // 0x18 - be_t enable_clear_ls; // 0x1C - vm::bptr task_name_buffer; // 0x20 - } m; - }; + be_t revision; // 0x00 + vm::bcptr name; // 0x04 + be_t args; // 0x08 + u8 priority[8]; // 0x10 + be_t max_contention; // 0x18 + be_t enable_clear_ls; // 0x1C + vm::bptr task_name_buffer; // 0x20 + u8 reserved[472]; }; -struct CellSpursTraceTaskData -{ - be_t incident; - be_t task; -}; +CHECK_SIZE_ALIGN(CellSpursTasksetAttribute2, 512, 8); -struct CellSpursTaskAttribute2 -{ - be_t revision; - be_t sizeContext; - be_t eaContext; - CellSpursTaskLsPattern lsPattern; - be_t name_addr; - //be_t __reserved__[]; -}; - -struct CellSpursTaskExitCode -{ - unsigned char skip[128]; -}; - -struct CellSpursTaskInfo -{ - CellSpursTaskLsPattern lsPattern; - CellSpursTaskArgument argument; - const be_t eaElf_addr; //void *eaElf - const be_t eaContext_addr; //void *eaContext - be_t sizeContext; - u8 state; - u8 hasSignal; - const be_t CellSpursTaskExitCode_addr; - u8 guid[8]; - //be_t reserved[]; -}; - -struct CellSpursTaskBinInfo +struct set_alignment(16) CellSpursTaskBinInfo { be_t eaElf; be_t sizeContext; - be_t __reserved__; + be_t reserved; CellSpursTaskLsPattern lsPattern; }; @@ -898,7 +846,7 @@ struct SpursKernelContext vm::bptr spurs; // 0x1C0 be_t spuNum; // 0x1C8 be_t dmaTagId; // 0x1CC - vm::bptr wklCurrentAddr; // 0x1D0 + vm::bcptr wklCurrentAddr; // 0x1D0 be_t wklCurrentUniqueId; // 0x1D8 be_t wklCurrentId; // 0x1DC be_t exitToKernelAddr; // 0x1E0 @@ -924,7 +872,7 @@ struct SpursKernelContext be_t guid[4]; // 0x280 }; -static_assert(sizeof(SpursKernelContext) == 0x190, "Incorrect size for SpursKernelContext"); +CHECK_SIZE(SpursKernelContext, 0x190); // The SPURS taskset policy module context. This resides at 0x2700 of the LS. struct SpursTasksetContext @@ -957,7 +905,8 @@ struct SpursTasksetContext u8 x2FD8[0x3000 - 0x2FD8]; // 0x2FD8 }; -static_assert(sizeof(SpursTasksetContext) == 0x900, "Incorrect size for SpursTasksetContext"); +CHECK_SIZE(SpursTasksetContext, 0x900); -s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated); -s32 spursWakeUp(PPUThread& CPU, vm::ptr spurs); +class SpursModuleExit +{ +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.h b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.h index 3f59c932d3..8744312ca5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.h @@ -1,2 +1,3 @@ #pragma once +namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index cae4a7bb7e..2bb4690821 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -11,67 +11,75 @@ #include "Loader/ELF32.h" #include "Emu/FS/vfsStreamMemory.h" -// -// SPURS utility functions -// -void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId); -u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status); -void cellSpursModuleExit(SPUThread & spu); - -bool spursDma(SPUThread & spu, u32 cmd, u64 ea, u32 lsa, u32 size, u32 tag); -u32 spursDmaGetCompletionStatus(SPUThread & spu, u32 tagMask); -u32 spursDmaWaitForCompletion(SPUThread & spu, u32 tagMask, bool waitForAll = true); -void spursHalt(SPUThread & spu); - -// -// SPURS Kernel functions -// -bool spursKernel1SelectWorkload(SPUThread & spu); -bool spursKernel2SelectWorkload(SPUThread & spu); -void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus); -bool spursKernelWorkloadExit(SPUThread & spu); -bool spursKernelEntry(SPUThread & spu); - -// -// SPURS System Service functions -// -bool spursSysServiceEntry(SPUThread & spu); -// TODO: Exit -void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt); -void spursSysServiceMain(SPUThread & spu, u32 pollStatus); -void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt); -void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt); -// TODO: Deactivate workload -void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelContext * ctxt, u32 wklShutdownBitSet); -void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt); -void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 arg4); -// TODO: Deactivate trace -// TODO: System workload entry -void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelContext * ctxt); - -// -// SPURS Taskset Policy Module functions -// -bool spursTasksetEntry(SPUThread & spu); -bool spursTasksetSyscallEntry(SPUThread & spu); -void spursTasksetResumeTask(SPUThread & spu); -void spursTasksetStartTask(SPUThread & spu, CellSpursTaskArgument & taskArgs); -s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * isWaiting); -void spursTasksetProcessPollStatus(SPUThread & spu, u32 pollStatus); -bool spursTasksetPollStatus(SPUThread & spu); -void spursTasksetExit(SPUThread & spu); -void spursTasksetOnTaskExit(SPUThread & spu, u64 addr, u32 taskId, s32 exitCode, u64 args); -s32 spursTasketSaveTaskContext(SPUThread & spu); -void spursTasksetDispatch(SPUThread & spu); -s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args); -void spursTasksetInit(SPUThread & spu, u32 pollStatus); -s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, u64 elfAddr, bool skipWriteableSegments); +//---------------------------------------------------------------------------- +// Externs +//---------------------------------------------------------------------------- extern Module cellSpurs; -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- +// Function prototypes +//---------------------------------------------------------------------------- + +// // SPURS utility functions -////////////////////////////////////////////////////////////////////////////// +// +static void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId); +static u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status); +static void cellSpursModuleExit(SPUThread & spu); + +static bool spursDma(SPUThread & spu, u32 cmd, u64 ea, u32 lsa, u32 size, u32 tag); +static u32 spursDmaGetCompletionStatus(SPUThread & spu, u32 tagMask); +static u32 spursDmaWaitForCompletion(SPUThread & spu, u32 tagMask, bool waitForAll = true); +static void spursHalt(SPUThread & spu); + +// +// SPURS kernel functions +// +static bool spursKernel1SelectWorkload(SPUThread & spu); +static bool spursKernel2SelectWorkload(SPUThread & spu); +static void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus); +static bool spursKernelWorkloadExit(SPUThread & spu); +bool spursKernelEntry(SPUThread & spu); + +// +// SPURS system workload functions +// +static bool spursSysServiceEntry(SPUThread & spu); +// TODO: Exit +static void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt); +static void spursSysServiceMain(SPUThread & spu, u32 pollStatus); +static void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt); +static void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt); +// TODO: Deactivate workload +static void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelContext * ctxt, u32 wklShutdownBitSet); +static void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt); +static void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 forceNotify); +// TODO: Deactivate trace +// TODO: System workload entry +static void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelContext * ctxt); + +// +// SPURS taskset policy module functions +// +static bool spursTasksetEntry(SPUThread & spu); +static bool spursTasksetSyscallEntry(SPUThread & spu); +static void spursTasksetResumeTask(SPUThread & spu); +static void spursTasksetStartTask(SPUThread & spu, CellSpursTaskArgument & taskArgs); +static s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * isWaiting); +static void spursTasksetProcessPollStatus(SPUThread & spu, u32 pollStatus); +static bool spursTasksetPollStatus(SPUThread & spu); +static void spursTasksetExit(SPUThread & spu); +static void spursTasksetOnTaskExit(SPUThread & spu, u64 addr, u32 taskId, s32 exitCode, u64 args); +static s32 spursTasketSaveTaskContext(SPUThread & spu); +static void spursTasksetDispatch(SPUThread & spu); +static s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args); +static void spursTasksetInit(SPUThread & spu, u32 pollStatus); +static s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, u64 elfAddr, bool skipWriteableSegments); + +//---------------------------------------------------------------------------- +// SPURS utility functions +//---------------------------------------------------------------------------- /// Output trace information void cellSpursModulePutTrace(CellSpursTracePacket * packet, u32 dmaTagId) { @@ -83,7 +91,7 @@ u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status) { auto ctxt = vm::get_ptr(spu.offset + 0x100); spu.GPR[3]._u32[3] = 1; - if (ctxt->spurs->m.flags1 & SF1_32_WORKLOADS) { + if (ctxt->spurs->flags1 & SF1_32_WORKLOADS) { spursKernel2SelectWorkload(spu); } else { spursKernel1SelectWorkload(spu); @@ -101,7 +109,8 @@ u32 cellSpursModulePollStatus(SPUThread & spu, u32 * status) { /// Exit current workload void cellSpursModuleExit(SPUThread & spu) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - spu.SetBranch(ctxt->exitToKernelAddr); + spu.PC = ctxt->exitToKernelAddr - 4; + throw SpursModuleExit(); } /// Execute a DMA operation @@ -129,24 +138,24 @@ bool spursDma(SPUThread & spu, u32 cmd, u64 ea, u32 lsa, u32 size, u32 tag) { u32 spursDmaGetCompletionStatus(SPUThread & spu, u32 tagMask) { spu.set_ch_value(MFC_WrTagMask, tagMask); spu.set_ch_value(MFC_WrTagUpdate, MFC_TAG_UPDATE_IMMEDIATE); - return spu.get_ch_value(MFC_RdTagStat); + return spu.get_ch_value(MFC_RdTagStat); } /// Wait for DMA operations to complete u32 spursDmaWaitForCompletion(SPUThread & spu, u32 tagMask, bool waitForAll) { spu.set_ch_value(MFC_WrTagMask, tagMask); spu.set_ch_value(MFC_WrTagUpdate, waitForAll ? MFC_TAG_UPDATE_ALL : MFC_TAG_UPDATE_ANY); - return spu.get_ch_value(MFC_RdTagStat); + return spu.get_ch_value(MFC_RdTagStat); } /// Halt the SPU void spursHalt(SPUThread & spu) { - spu.halt(); + spu.halt(); } -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- // SPURS kernel functions -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- /// Select a workload to run bool spursKernel1SelectWorkload(SPUThread & spu) { @@ -160,7 +169,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { u32 wklSelectedId; u32 pollStatus; - vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr()), 128, [&]() { // lock the first 0x80 bytes of spurs auto spurs = ctxt->spurs.priv_ptr(); @@ -168,12 +177,12 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { u8 contention[CELL_SPURS_MAX_WORKLOAD]; u8 pendingContention[CELL_SPURS_MAX_WORKLOAD]; for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - contention[i] = spurs->m.wklCurrentContention[i] - ctxt->wklLocContention[i]; + contention[i] = spurs->wklCurrentContention[i] - ctxt->wklLocContention[i]; // If this is a poll request then the number of SPUs pending to context switch is also added to the contention presumably // to prevent unnecessary jumps to the kernel if (isPoll) { - pendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + pendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; if (i != ctxt->wklCurrentId) { contention[i] += pendingContention[i]; } @@ -185,21 +194,21 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { // The system service has the highest priority. Select the system service if // the system service message bit for this SPU is set. - if (spurs->m.sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMessage.load() & (1 << ctxt->spuNum)) { ctxt->spuIdling = 0; if (!isPoll || ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID) { // Clear the message bit - spurs->m.sysSrvMessage.write_relaxed(spurs->m.sysSrvMessage.read_relaxed() & ~(1 << ctxt->spuNum)); + spurs->sysSrvMessage.store(spurs->sysSrvMessage.load() & ~(1 << ctxt->spuNum)); } } else { // Caclulate the scheduling weight for each workload u16 maxWeight = 0; for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { u16 runnable = ctxt->wklRunnable1 & (0x8000 >> i); - u16 wklSignal = spurs->m.wklSignal1.read_relaxed() & (0x8000 >> i); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = spurs->m.wklReadyCount1[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklReadyCount1[i].read_relaxed(); - u8 idleSpuCount = spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed(); + u16 wklSignal = spurs->wklSignal1.load() & (0x8000 >> i); + u8 wklFlag = spurs->wklFlag.flag.load() == 0 ? spurs->wklFlagReceiver.load() == i ? 1 : 0 : 0; + u8 readyCount = spurs->wklReadyCount1[i].load() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklReadyCount1[i].load(); + u8 idleSpuCount = spurs->wklIdleSpuCountOrReadyCount2[i].load() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklIdleSpuCountOrReadyCount2[i].load(); u8 requestCount = readyCount + idleSpuCount; // For a workload to be considered for scheduling: @@ -209,7 +218,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { // 4. The number of SPUs allocated to it must be less than the number of SPUs requested (i.e. readyCount) // OR the workload must be signalled // OR the workload flag is 0 and the workload is configured as the wokload flag receiver - if (runnable && ctxt->priority[i] != 0 && spurs->m.wklMaxContention[i].read_relaxed() > contention[i]) { + if (runnable && ctxt->priority[i] != 0 && spurs->wklMaxContention[i].load() > contention[i]) { if (wklFlag || wklSignal || (readyCount != 0 && requestCount > contention[i])) { // The scheduling weight of the workload is formed from the following parameters in decreasing order of priority: // 1. Wokload signal set or workload flag or ready count > contention @@ -222,7 +231,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { u16 weight = (wklFlag || wklSignal || (readyCount > contention[i])) ? 0x8000 : 0; weight |= (u16)(ctxt->priority[i] & 0x7F) << 16; weight |= i == ctxt->wklCurrentId ? 0x80 : 0x00; - weight |= (contention[i] > 0 && spurs->m.wklMinContention[i] > contention[i]) ? 0x40 : 0x00; + weight |= (contention[i] > 0 && spurs->wklMinContention[i] > contention[i]) ? 0x40 : 0x00; weight |= ((CELL_SPURS_MAX_SPU - contention[i]) & 0x0F) << 2; weight |= ctxt->wklUniqueId[i] == ctxt->wklCurrentId ? 0x02 : 0x00; weight |= 0x01; @@ -244,12 +253,12 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { if (!isPoll || wklSelectedId == ctxt->wklCurrentId) { // Clear workload signal for the selected workload - spurs->m.wklSignal1.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x8000 >> wklSelectedId))); - spurs->m.wklSignal2.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x80000000u >> wklSelectedId))); + spurs->wklSignal1.store(spurs->wklSignal1.load() & ~(0x8000 >> wklSelectedId)); + spurs->wklSignal2.store(spurs->wklSignal1.load() & ~(0x80000000u >> wklSelectedId)); // If the selected workload is the wklFlag workload then pull the wklFlag to all 1s - if (wklSelectedId == spurs->m.wklFlagReceiver.read_relaxed()) { - spurs->m.wklFlag.flag.write_relaxed(be_t::make(0xFFFFFFFF)); + if (wklSelectedId == spurs->wklFlagReceiver.load()) { + spurs->wklFlag.flag.store(0xFFFFFFFF); } } } @@ -262,8 +271,8 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklCurrentContention[i] = contention[i]; - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklCurrentContention[i] = contention[i]; + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocContention[i] = 0; ctxt->wklLocPendingContention[i] = 0; } @@ -281,7 +290,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklPendingContention[i] = pendingContention[i]; + spurs->wklPendingContention[i] = pendingContention[i]; ctxt->wklLocPendingContention[i] = 0; } @@ -291,7 +300,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { } else { // Not called by kernel and no context switch is required for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocPendingContention[i] = 0; } } @@ -317,7 +326,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { u32 wklSelectedId; u32 pollStatus; - vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr()), 128, [&]() { // lock the first 0x80 bytes of spurs auto spurs = ctxt->spurs.priv_ptr(); @@ -325,13 +334,13 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { u8 contention[CELL_SPURS_MAX_WORKLOAD2]; u8 pendingContention[CELL_SPURS_MAX_WORKLOAD2]; for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD2; i++) { - contention[i] = spurs->m.wklCurrentContention[i & 0x0F] - ctxt->wklLocContention[i & 0x0F]; + contention[i] = spurs->wklCurrentContention[i & 0x0F] - ctxt->wklLocContention[i & 0x0F]; contention[i] = i < CELL_SPURS_MAX_WORKLOAD ? contention[i] & 0x0F : contention[i] >> 4; // If this is a poll request then the number of SPUs pending to context switch is also added to the contention presumably // to prevent unnecessary jumps to the kernel if (isPoll) { - pendingContention[i] = spurs->m.wklPendingContention[i & 0x0F] - ctxt->wklLocPendingContention[i & 0x0F]; + pendingContention[i] = spurs->wklPendingContention[i & 0x0F] - ctxt->wklLocPendingContention[i & 0x0F]; pendingContention[i] = i < CELL_SPURS_MAX_WORKLOAD ? pendingContention[i] & 0x0F : pendingContention[i] >> 4; if (i != ctxt->wklCurrentId) { contention[i] += pendingContention[i]; @@ -344,12 +353,12 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { // The system service has the highest priority. Select the system service if // the system service message bit for this SPU is set. - if (spurs->m.sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMessage.load() & (1 << ctxt->spuNum)) { // Not sure what this does. Possibly Mark the SPU as in use. ctxt->spuIdling = 0; if (!isPoll || ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID) { // Clear the message bit - spurs->m.sysSrvMessage.write_relaxed(spurs->m.sysSrvMessage.read_relaxed() & ~(1 << ctxt->spuNum)); + spurs->sysSrvMessage.store(spurs->sysSrvMessage.load() & ~(1 << ctxt->spuNum)); } } else { // Caclulate the scheduling weight for each workload @@ -358,10 +367,10 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { auto j = i & 0x0F; u16 runnable = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->wklRunnable1 & (0x8000 >> j) : ctxt->wklRunnable2 & (0x8000 >> j); u8 priority = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->priority[j] & 0x0F : ctxt->priority[j] >> 4; - u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklMaxContention[j].read_relaxed() & 0x0F : spurs->m.wklMaxContention[j].read_relaxed() >> 4; - u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklSignal1.read_relaxed() & (0x8000 >> j) : spurs->m.wklSignal2.read_relaxed() & (0x8000 >> j); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[j].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[j].read_relaxed(); + u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklMaxContention[j].load() & 0x0F : spurs->wklMaxContention[j].load() >> 4; + u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklSignal1.load() & (0x8000 >> j) : spurs->wklSignal2.load() & (0x8000 >> j); + u8 wklFlag = spurs->wklFlag.flag.load() == 0 ? spurs->wklFlagReceiver.load() == i ? 1 : 0 : 0; + u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklReadyCount1[j].load() : spurs->wklIdleSpuCountOrReadyCount2[j].load(); // For a workload to be considered for scheduling: // 1. Its priority must be greater than 0 @@ -396,12 +405,12 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { if (!isPoll || wklSelectedId == ctxt->wklCurrentId) { // Clear workload signal for the selected workload - spurs->m.wklSignal1.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x8000 >> wklSelectedId))); - spurs->m.wklSignal2.write_relaxed(be_t::make(spurs->m.wklSignal1.read_relaxed() & ~(0x80000000u >> wklSelectedId))); + spurs->wklSignal1.store(spurs->wklSignal1.load() & ~(0x8000 >> wklSelectedId)); + spurs->wklSignal2.store(spurs->wklSignal1.load() & ~(0x80000000u >> wklSelectedId)); // If the selected workload is the wklFlag workload then pull the wklFlag to all 1s - if (wklSelectedId == spurs->m.wklFlagReceiver.read_relaxed()) { - spurs->m.wklFlag.flag.write_relaxed(be_t::make(0xFFFFFFFF)); + if (wklSelectedId == spurs->wklFlagReceiver.load()) { + spurs->wklFlag.flag.store(0xFFFFFFFF); } } } @@ -414,8 +423,8 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < (CELL_SPURS_MAX_WORKLOAD2 >> 1); i++) { - spurs->m.wklCurrentContention[i] = contention[i] | (contention[i + 0x10] << 4); - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklCurrentContention[i] = contention[i] | (contention[i + 0x10] << 4); + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocContention[i] = 0; ctxt->wklLocPendingContention[i] = 0; } @@ -430,7 +439,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { } for (auto i = 0; i < (CELL_SPURS_MAX_WORKLOAD2 >> 1); i++) { - spurs->m.wklPendingContention[i] = pendingContention[i] | (pendingContention[i + 0x10] << 4); + spurs->wklPendingContention[i] = pendingContention[i] | (pendingContention[i + 0x10] << 4); ctxt->wklLocPendingContention[i] = 0; } @@ -438,7 +447,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { } else { // Not called by kernel and no context switch is required for (auto i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { - spurs->m.wklPendingContention[i] = spurs->m.wklPendingContention[i] - ctxt->wklLocPendingContention[i]; + spurs->wklPendingContention[i] = spurs->wklPendingContention[i] - ctxt->wklLocPendingContention[i]; ctxt->wklLocPendingContention[i] = 0; } } @@ -455,15 +464,15 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { /// SPURS kernel dispatch workload void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - auto isKernel2 = ctxt->spurs->m.flags1 & SF1_32_WORKLOADS ? true : false; + auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; auto pollStatus = (u32)widAndPollStatus; auto wid = (u32)(widAndPollStatus >> 32); // DMA in the workload info for the selected workload - auto wklInfoOffset = wid < CELL_SPURS_MAX_WORKLOAD ? &ctxt->spurs->m.wklInfo1[wid] : - wid < CELL_SPURS_MAX_WORKLOAD2 && isKernel2 ? &ctxt->spurs->m.wklInfo2[wid & 0xf] : - &ctxt->spurs->m.wklInfoSysSrv; + auto wklInfoOffset = wid < CELL_SPURS_MAX_WORKLOAD ? &ctxt->spurs->wklInfo1[wid] : + wid < CELL_SPURS_MAX_WORKLOAD2 && isKernel2 ? &ctxt->spurs->wklInfo2[wid & 0xf] : + &ctxt->spurs->wklInfoSysSrv; memcpy(vm::get_ptr(spu.offset + 0x3FFE0), wklInfoOffset, 0x20); @@ -483,7 +492,7 @@ void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus) { } ctxt->wklCurrentAddr = wklInfo->addr; - ctxt->wklCurrentUniqueId = wklInfo->uniqueId.read_relaxed(); + ctxt->wklCurrentUniqueId = wklInfo->uniqueId.load(); } if (!isKernel2) { @@ -497,13 +506,13 @@ void spursKernelDispatchWorkload(SPUThread & spu, u64 widAndPollStatus) { spu.GPR[3]._u32[3] = 0x100; spu.GPR[4]._u64[1] = wklInfo->arg; spu.GPR[5]._u32[3] = pollStatus; - spu.SetBranch(0xA00); + spu.PC = 0xA00 - 4; } /// SPURS kernel workload exit bool spursKernelWorkloadExit(SPUThread & spu) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - auto isKernel2 = ctxt->spurs->m.flags1 & SF1_32_WORKLOADS ? true : false; + auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; // Select next workload to run spu.GPR[3].clear(); @@ -521,9 +530,7 @@ bool spursKernelWorkloadExit(SPUThread & spu) { bool spursKernelEntry(SPUThread & spu) { while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (Emu.IsStopped()) { - return false; - } + CHECK_EMU_STATUS; } auto ctxt = vm::get_ptr(spu.offset + 0x100); @@ -533,7 +540,7 @@ bool spursKernelEntry(SPUThread & spu) { ctxt->spuNum = spu.GPR[3]._u32[3]; ctxt->spurs.set(spu.GPR[4]._u64[1]); - auto isKernel2 = ctxt->spurs->m.flags1 & SF1_32_WORKLOADS ? true : false; + auto isKernel2 = ctxt->spurs->flags1 & SF1_32_WORKLOADS ? true : false; // Initialise the SPURS context to its initial values ctxt->dmaTagId = CELL_SPURS_KERNEL_DMA_TAG_ID; @@ -566,9 +573,9 @@ bool spursKernelEntry(SPUThread & spu) { return false; } -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- // SPURS system workload functions -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- /// Entry point of the system service bool spursSysServiceEntry(SPUThread & spu) { @@ -576,14 +583,20 @@ bool spursSysServiceEntry(SPUThread & spu) { auto arg = spu.GPR[4]._u64[1]; auto pollStatus = spu.GPR[5]._u32[3]; - if (ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID) { - spursSysServiceMain(spu, pollStatus); - } else { - // TODO: If we reach here it means the current workload was preempted to start the - // system workload. Need to implement this. + try { + if (ctxt->wklCurrentId == CELL_SPURS_SYS_SERVICE_WORKLOAD_ID) { + spursSysServiceMain(spu, pollStatus); + } else { + // TODO: If we reach here it means the current workload was preempted to start the + // system workload. Need to implement this. + } + + cellSpursModuleExit(spu); } - - cellSpursModuleExit(spu); + + catch (SpursModuleExit) { + } + return false; } @@ -591,37 +604,39 @@ bool spursSysServiceEntry(SPUThread & spu) { void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { bool shouldExit; + std::unique_lock lock(spu.mutex, std::defer_lock); + while (true) { - vm::reservation_acquire(vm::get_ptr(spu.offset + 0x100), vm::cast(ctxt->spurs.addr()), 128, [&spu](){ spu.Notify(); }); + vm::reservation_acquire(vm::get_ptr(spu.offset + 0x100), VM_CAST(ctxt->spurs.addr()), 128, [&spu](){ spu.cv.notify_one(); }); auto spurs = vm::get_ptr(spu.offset + 0x100); // Find the number of SPUs that are idling in this SPURS instance u32 nIdlingSpus = 0; for (u32 i = 0; i < 8; i++) { - if (spurs->m.spuIdling & (1 << i)) { + if (spurs->spuIdling & (1 << i)) { nIdlingSpus++; } } - bool allSpusIdle = nIdlingSpus == spurs->m.nSpus ? true: false; - bool exitIfNoWork = spurs->m.flags1 & SF1_EXIT_IF_NO_WORK ? true : false; + bool allSpusIdle = nIdlingSpus == spurs->nSpus ? true: false; + bool exitIfNoWork = spurs->flags1 & SF1_EXIT_IF_NO_WORK ? true : false; shouldExit = allSpusIdle && exitIfNoWork; // Check if any workloads can be scheduled bool foundReadyWorkload = false; - if (spurs->m.sysSrvMessage.read_relaxed() & (1 << ctxt->spuNum)) { + if (spurs->sysSrvMessage.load() & (1 << ctxt->spuNum)) { foundReadyWorkload = true; } else { - if (spurs->m.flags1 & SF1_32_WORKLOADS) { + if (spurs->flags1 & SF1_32_WORKLOADS) { for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD2; i++) { u32 j = i & 0x0F; u16 runnable = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->wklRunnable1 & (0x8000 >> j) : ctxt->wklRunnable2 & (0x8000 >> j); u8 priority = i < CELL_SPURS_MAX_WORKLOAD ? ctxt->priority[j] & 0x0F : ctxt->priority[j] >> 4; - u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklMaxContention[j].read_relaxed() & 0x0F : spurs->m.wklMaxContention[j].read_relaxed() >> 4; - u8 contention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklCurrentContention[j] & 0x0F : spurs->m.wklCurrentContention[j] >> 4; - u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklSignal1.read_relaxed() & (0x8000 >> j) : spurs->m.wklSignal2.read_relaxed() & (0x8000 >> j); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[j].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[j].read_relaxed(); + u8 maxContention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklMaxContention[j].load() & 0x0F : spurs->wklMaxContention[j].load() >> 4; + u8 contention = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklCurrentContention[j] & 0x0F : spurs->wklCurrentContention[j] >> 4; + u16 wklSignal = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklSignal1.load() & (0x8000 >> j) : spurs->wklSignal2.load() & (0x8000 >> j); + u8 wklFlag = spurs->wklFlag.flag.load() == 0 ? spurs->wklFlagReceiver.load() == i ? 1 : 0 : 0; + u8 readyCount = i < CELL_SPURS_MAX_WORKLOAD ? spurs->wklReadyCount1[j].load() : spurs->wklIdleSpuCountOrReadyCount2[j].load(); if (runnable && priority > 0 && maxContention > contention) { if (wklFlag || wklSignal || readyCount > contention) { @@ -633,14 +648,14 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { } else { for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { u16 runnable = ctxt->wklRunnable1 & (0x8000 >> i); - u16 wklSignal = spurs->m.wklSignal1.read_relaxed() & (0x8000 >> i); - u8 wklFlag = spurs->m.wklFlag.flag.read_relaxed() == 0 ? spurs->m.wklFlagReceiver.read_relaxed() == i ? 1 : 0 : 0; - u8 readyCount = spurs->m.wklReadyCount1[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklReadyCount1[i].read_relaxed(); - u8 idleSpuCount = spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->m.wklIdleSpuCountOrReadyCount2[i].read_relaxed(); + u16 wklSignal = spurs->wklSignal1.load() & (0x8000 >> i); + u8 wklFlag = spurs->wklFlag.flag.load() == 0 ? spurs->wklFlagReceiver.load() == i ? 1 : 0 : 0; + u8 readyCount = spurs->wklReadyCount1[i].load() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklReadyCount1[i].load(); + u8 idleSpuCount = spurs->wklIdleSpuCountOrReadyCount2[i].load() > CELL_SPURS_MAX_SPU ? CELL_SPURS_MAX_SPU : spurs->wklIdleSpuCountOrReadyCount2[i].load(); u8 requestCount = readyCount + idleSpuCount; - if (runnable && ctxt->priority[i] != 0 && spurs->m.wklMaxContention[i].read_relaxed() > spurs->m.wklCurrentContention[i]) { - if (wklFlag || wklSignal || (readyCount != 0 && requestCount > spurs->m.wklCurrentContention[i])) { + if (runnable && ctxt->priority[i] != 0 && spurs->wklMaxContention[i].load() > spurs->wklCurrentContention[i]) { + if (wklFlag || wklSignal || (readyCount != 0 && requestCount > spurs->wklCurrentContention[i])) { foundReadyWorkload = true; break; } @@ -649,21 +664,23 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { } } - bool spuIdling = spurs->m.spuIdling & (1 << ctxt->spuNum) ? true : false; + bool spuIdling = spurs->spuIdling & (1 << ctxt->spuNum) ? true : false; if (foundReadyWorkload && shouldExit == false) { - spurs->m.spuIdling &= ~(1 << ctxt->spuNum); + spurs->spuIdling &= ~(1 << ctxt->spuNum); } else { - spurs->m.spuIdling |= 1 << ctxt->spuNum; + spurs->spuIdling |= 1 << ctxt->spuNum; } // If all SPUs are idling and the exit_if_no_work flag is set then the SPU thread group must exit. Otherwise wait for external events. if (spuIdling && shouldExit == false && foundReadyWorkload == false) { // The system service blocks by making a reservation and waiting on the lock line reservation lost event. - spu.WaitForAnySignal(1); - if (Emu.IsStopped()) return; + CHECK_EMU_STATUS; + if (!lock) lock.lock(); + spu.cv.wait_for(lock, std::chrono::milliseconds(1)); + continue; } - if (vm::reservation_update(vm::cast(ctxt->spurs.addr()), vm::get_ptr(spu.offset + 0x100), 128) && (shouldExit || foundReadyWorkload)) { + if (vm::reservation_update(VM_CAST(ctxt->spurs.addr()), vm::get_ptr(spu.offset + 0x100), 128) && (shouldExit || foundReadyWorkload)) { break; } } @@ -677,31 +694,29 @@ void spursSysServiceIdleHandler(SPUThread & spu, SpursKernelContext * ctxt) { void spursSysServiceMain(SPUThread & spu, u32 pollStatus) { auto ctxt = vm::get_ptr(spu.offset + 0x100); - if (ctxt->spurs.addr() % CellSpurs::align) { + if (!ctxt->spurs.aligned()) { assert(!"spursSysServiceMain(): invalid spurs alignment"); - //spursHalt(spu); - //return; + spursHalt(spu); } // Initialise the system service if this is the first time its being started on this SPU if (ctxt->sysSrvInitialised == 0) { ctxt->sysSrvInitialised = 1; - vm::reservation_acquire(vm::get_ptr(spu.offset + 0x100), vm::cast(ctxt->spurs.addr()), 128); + vm::reservation_acquire(vm::get_ptr(spu.offset + 0x100), VM_CAST(ctxt->spurs.addr()), 128); - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); // Halt if already initialised - if (spurs->m.sysSrvOnSpu & (1 << ctxt->spuNum)) { + if (spurs->sysSrvOnSpu & (1 << ctxt->spuNum)) { assert(!"spursSysServiceMain(): already initialized"); - //spursHalt(spu); - //return; + spursHalt(spu); } - spurs->m.sysSrvOnSpu |= 1 << ctxt->spuNum; + spurs->sysSrvOnSpu |= 1 << ctxt->spuNum; - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); ctxt->traceBuffer = 0; @@ -727,6 +742,7 @@ void spursSysServiceMain(SPUThread & spu, u32 pollStatus) { cellSpursModulePutTrace(&pkt, ctxt->dmaTagId); while (true) { + CHECK_EMU_STATUS; // Process requests for the system service spursSysServiceProcessRequests(spu, ctxt); @@ -767,7 +783,7 @@ poll: cellSpursModulePutTrace(&pkt, ctxt->dmaTagId); spursSysServiceIdleHandler(spu, ctxt); - if (Emu.IsStopped()) return; + CHECK_EMU_STATUS; goto poll; } @@ -779,27 +795,27 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt) bool updateWorkload = false; bool terminate = false; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); // Terminate request - if (spurs->m.sysSrvMsgTerminate & (1 << ctxt->spuNum)) { - spurs->m.sysSrvOnSpu &= ~(1 << ctxt->spuNum); + if (spurs->sysSrvMsgTerminate & (1 << ctxt->spuNum)) { + spurs->sysSrvOnSpu &= ~(1 << ctxt->spuNum); terminate = true; } // Update workload message - if (spurs->m.sysSrvMsgUpdateWorkload.read_relaxed() & (1 << ctxt->spuNum)) { - spurs->m.sysSrvMsgUpdateWorkload &= ~(1 << ctxt->spuNum); + if (spurs->sysSrvMsgUpdateWorkload.load() & (1 << ctxt->spuNum)) { + spurs->sysSrvMsgUpdateWorkload &= ~(1 << ctxt->spuNum); updateWorkload = true; } // Update trace message - if (spurs->m.sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) { + if (spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) { updateTrace = true; } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); // Process update workload message @@ -821,9 +837,9 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt) /// Activate a workload void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) { auto spurs = vm::get_ptr(spu.offset + 0x100); - memcpy(vm::get_ptr(spu.offset + 0x30000), vm::get_ptr(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklInfo1))), 0x200); - if (spurs->m.flags1 & SF1_32_WORKLOADS) { - memcpy(vm::get_ptr(spu.offset + 0x30200), vm::get_ptr(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklInfo2))), 0x200); + memcpy(vm::get_ptr(spu.offset + 0x30000), vm::get_ptr(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklInfo1))), 0x200); + if (spurs->flags1 & SF1_32_WORKLOADS) { + memcpy(vm::get_ptr(spu.offset + 0x30200), vm::get_ptr(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklInfo2))), 0x200); } u32 wklShutdownBitSet = 0; @@ -834,9 +850,9 @@ void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) // Copy the priority of the workload for this SPU and its unique id to the LS ctxt->priority[i] = wklInfo1[i].priority[ctxt->spuNum] == 0 ? 0 : 0x10 - wklInfo1[i].priority[ctxt->spuNum]; - ctxt->wklUniqueId[i] = wklInfo1[i].uniqueId.read_relaxed(); + ctxt->wklUniqueId[i] = wklInfo1[i].uniqueId.load(); - if (spurs->m.flags1 & SF1_32_WORKLOADS) { + if (spurs->flags1 & SF1_32_WORKLOADS) { auto wklInfo2 = vm::get_ptr(spu.offset + 0x30200); // Copy the priority of the workload for this SPU to the LS @@ -846,50 +862,50 @@ void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) } } - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { // Update workload status and runnable flag based on the workload state - auto wklStatus = spurs->m.wklStatus1[i]; - if (spurs->m.wklState1[i].read_relaxed() == SPURS_WKL_STATE_RUNNABLE) { - spurs->m.wklStatus1[i] |= 1 << ctxt->spuNum; + auto wklStatus = spurs->wklStatus1[i]; + if (spurs->wklState1[i].load() == SPURS_WKL_STATE_RUNNABLE) { + spurs->wklStatus1[i] |= 1 << ctxt->spuNum; ctxt->wklRunnable1 |= 0x8000 >> i; } else { - spurs->m.wklStatus1[i] &= ~(1 << ctxt->spuNum); + spurs->wklStatus1[i] &= ~(1 << ctxt->spuNum); } // If the workload is shutting down and if this is the last SPU from which it is being removed then // add it to the shutdown bit set - if (spurs->m.wklState1[i].read_relaxed() == SPURS_WKL_STATE_SHUTTING_DOWN) { - if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->m.wklStatus1[i] == 0)) { - spurs->m.wklState1[i].write_relaxed(SPURS_WKL_STATE_REMOVABLE); + if (spurs->wklState1[i].load() == SPURS_WKL_STATE_SHUTTING_DOWN) { + if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->wklStatus1[i] == 0)) { + spurs->wklState1[i].store(SPURS_WKL_STATE_REMOVABLE); wklShutdownBitSet |= 0x80000000u >> i; } } - if (spurs->m.flags1 & SF1_32_WORKLOADS) { + if (spurs->flags1 & SF1_32_WORKLOADS) { // Update workload status and runnable flag based on the workload state - wklStatus = spurs->m.wklStatus2[i]; - if (spurs->m.wklState2[i].read_relaxed() == SPURS_WKL_STATE_RUNNABLE) { - spurs->m.wklStatus2[i] |= 1 << ctxt->spuNum; + wklStatus = spurs->wklStatus2[i]; + if (spurs->wklState2[i].load() == SPURS_WKL_STATE_RUNNABLE) { + spurs->wklStatus2[i] |= 1 << ctxt->spuNum; ctxt->wklRunnable2 |= 0x8000 >> i; } else { - spurs->m.wklStatus2[i] &= ~(1 << ctxt->spuNum); + spurs->wklStatus2[i] &= ~(1 << ctxt->spuNum); } // If the workload is shutting down and if this is the last SPU from which it is being removed then // add it to the shutdown bit set - if (spurs->m.wklState2[i].read_relaxed() == SPURS_WKL_STATE_SHUTTING_DOWN) { - if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->m.wklStatus2[i] == 0)) { - spurs->m.wklState2[i].write_relaxed(SPURS_WKL_STATE_REMOVABLE); + if (spurs->wklState2[i].load() == SPURS_WKL_STATE_SHUTTING_DOWN) { + if (((wklStatus & (1 << ctxt->spuNum)) != 0) && (spurs->wklStatus2[i] == 0)) { + spurs->wklState2[i].store(SPURS_WKL_STATE_REMOVABLE); wklShutdownBitSet |= 0x8000 >> i; } } } } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); if (wklShutdownBitSet) { @@ -903,28 +919,28 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC // workloads that have a shutdown completion hook registered u32 wklNotifyBitSet; u8 spuPort; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); wklNotifyBitSet = 0; - spuPort = spurs->m.spuPort;; + spuPort = spurs->spuPort;; for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { if (wklShutdownBitSet & (0x80000000u >> i)) { - spurs->m.wklEvent1[i] |= 0x01; - if (spurs->m.wklEvent1[i] & 0x02 || spurs->m.wklEvent1[i] & 0x10) { + spurs->wklEvent1[i] |= 0x01; + if (spurs->wklEvent1[i].load() & 0x02 || spurs->wklEvent1[i].load() & 0x10) { wklNotifyBitSet |= 0x80000000u >> i; } } if (wklShutdownBitSet & (0x8000 >> i)) { - spurs->m.wklEvent2[i] |= 0x01; - if (spurs->m.wklEvent2[i] & 0x02 || spurs->m.wklEvent2[i] & 0x10) { + spurs->wklEvent2[i] |= 0x01; + if (spurs->wklEvent2[i].load() & 0x02 || spurs->wklEvent2[i].load() & 0x10) { wklNotifyBitSet |= 0x8000 >> i; } } } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); if (wklNotifyBitSet) { @@ -935,61 +951,61 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC /// Update the trace count for this SPU void spursSysServiceTraceSaveCount(SPUThread & spu, SpursKernelContext * ctxt) { if (ctxt->traceBuffer) { - auto traceInfo = vm::ptr::make((u32)(ctxt->traceBuffer - (ctxt->spurs->m.traceStartIndex[ctxt->spuNum] << 4))); + auto traceInfo = vm::ptr::make((u32)(ctxt->traceBuffer - (ctxt->spurs->traceStartIndex[ctxt->spuNum] << 4))); traceInfo->count[ctxt->spuNum] = ctxt->traceMsgCount; } } /// Update trace control -void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 arg4) { +void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 arg2, u32 arg3, u32 forceNotify) { bool notify; u8 sysSrvMsgUpdateTrace; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); - sysSrvMsgUpdateTrace = spurs->m.sysSrvMsgUpdateTrace; - spurs->m.sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum); - spurs->m.xCC &= ~(1 << ctxt->spuNum); - spurs->m.xCC |= arg2 << ctxt->spuNum; + sysSrvMsgUpdateTrace = spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace; + spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum); + spurs->sysSrvTrace.data.sysSrvTraceInitialised &= ~(1 << ctxt->spuNum); + spurs->sysSrvTrace.data.sysSrvTraceInitialised |= arg2 << ctxt->spuNum; notify = false; - if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) && (spurs->m.sysSrvMsgUpdateTrace == 0) && (spurs->m.xCD != 0)) { - spurs->m.xCD = 0; - notify = true; + if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) && (spurs->sysSrvTrace.data.sysSrvMsgUpdateTrace == 0) && (spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete != 0)) { + spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete = 0; + notify = true; } - if (arg4 && spurs->m.xCD != 0) { - spurs->m.xCD = 0; - notify = true; + if (forceNotify && spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete != 0) { + spurs->sysSrvTrace.data.sysSrvNotifyUpdateTraceComplete = 0; + notify = true; } - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); // Get trace parameters from CellSpurs and store them in the LS if (((sysSrvMsgUpdateTrace & (1 << ctxt->spuNum)) != 0) || (arg3 != 0)) { - vm::reservation_acquire(vm::get_ptr(spu.offset + 0x80), vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.traceBuffer)), 128); - auto spurs = vm::get_ptr(spu.offset + 0x80 - offsetof(CellSpurs, m.traceBuffer)); + vm::reservation_acquire(vm::get_ptr(spu.offset + 0x80), VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, traceBuffer)), 128); + auto spurs = vm::get_ptr(spu.offset + 0x80 - offsetof(CellSpurs, traceBuffer)); - if (ctxt->traceMsgCount != 0xFF || spurs->m.traceBuffer.addr() == 0) { + if (ctxt->traceMsgCount != 0xFF || spurs->traceBuffer.addr() == 0) { spursSysServiceTraceSaveCount(spu, ctxt); } else { - memcpy(vm::get_ptr(spu.offset + 0x2C00), vm::get_ptr(spurs->m.traceBuffer.addr() & -0x4), 0x80); + memcpy(vm::get_ptr(spu.offset + 0x2C00), vm::get_ptr(spurs->traceBuffer.addr() & -0x4), 0x80); auto traceBuffer = vm::get_ptr(spu.offset + 0x2C00); ctxt->traceMsgCount = traceBuffer->count[ctxt->spuNum]; } - ctxt->traceBuffer = spurs->m.traceBuffer.addr() + (spurs->m.traceStartIndex[ctxt->spuNum] << 4); - ctxt->traceMaxCount = spurs->m.traceStartIndex[1] - spurs->m.traceStartIndex[0]; + ctxt->traceBuffer = spurs->traceBuffer.addr() + (spurs->traceStartIndex[ctxt->spuNum] << 4); + ctxt->traceMaxCount = spurs->traceStartIndex[1] - spurs->traceStartIndex[0]; if (ctxt->traceBuffer == 0) { ctxt->traceMsgCount = 0; } } if (notify) { - auto spurs = vm::get_ptr(spu.offset + 0x2D80 - offsetof(CellSpurs, m.wklState1)); - sys_spu_thread_send_event(spu, spurs->m.spuPort, 2, 0); + auto spurs = vm::get_ptr(spu.offset + 0x2D80 - offsetof(CellSpurs, wklState1)); + sys_spu_thread_send_event(spu, spurs->spuPort, 2, 0); } } @@ -999,33 +1015,33 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte bool do_return = false; - vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr() + offsetof(CellSpurs, wklState1)), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); - if (spurs->m.sysSrvWorkload[ctxt->spuNum] == 0xFF) { + if (spurs->sysSrvPreemptWklId[ctxt->spuNum] == 0xFF) { do_return = true; return; } - wklId = spurs->m.sysSrvWorkload[ctxt->spuNum]; - spurs->m.sysSrvWorkload[ctxt->spuNum] = 0xFF; + wklId = spurs->sysSrvPreemptWklId[ctxt->spuNum]; + spurs->sysSrvPreemptWklId[ctxt->spuNum] = 0xFF; - memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->m.wklState1, 128); + memcpy(vm::get_ptr(spu.offset + 0x2D80), spurs->wklState1, 128); }); if (do_return) return; spursSysServiceActivateWorkload(spu, ctxt); - vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->spurs.addr()), 128, [&]() { auto spurs = ctxt->spurs.priv_ptr(); if (wklId >= CELL_SPURS_MAX_WORKLOAD) { - spurs->m.wklCurrentContention[wklId & 0x0F] -= 0x10; - spurs->m.wklReadyCount1[wklId & 0x0F].write_relaxed(spurs->m.wklReadyCount1[wklId & 0x0F].read_relaxed() - 1); + spurs->wklCurrentContention[wklId & 0x0F] -= 0x10; + spurs->wklReadyCount1[wklId & 0x0F].store(spurs->wklReadyCount1[wklId & 0x0F].load() - 1); } else { - spurs->m.wklCurrentContention[wklId & 0x0F] -= 0x01; - spurs->m.wklIdleSpuCountOrReadyCount2[wklId & 0x0F].write_relaxed(spurs->m.wklIdleSpuCountOrReadyCount2[wklId & 0x0F].read_relaxed() - 1); + spurs->wklCurrentContention[wklId & 0x0F] -= 0x01; + spurs->wklIdleSpuCountOrReadyCount2[wklId & 0x0F].store(spurs->wklIdleSpuCountOrReadyCount2[wklId & 0x0F].load() - 1); } memcpy(vm::get_ptr(spu.offset + 0x100), spurs, 128); @@ -1046,9 +1062,9 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte ctxt->wklCurrentId = wklIdSaved; } -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- // SPURS taskset policy module functions -////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- enum SpursTasksetRequest { SPURS_TASKSET_REQUEST_POLL_SIGNAL = -1, @@ -1084,11 +1100,17 @@ bool spursTasksetEntry(SPUThread & spu) { spu.RegisterHleFunction(CELL_SPURS_TASKSET_PM_ENTRY_ADDR, spursTasksetEntry); spu.RegisterHleFunction(ctxt->syscallAddr, spursTasksetSyscallEntry); - // Initialise the taskset policy module - spursTasksetInit(spu, pollStatus); + try { + // Initialise the taskset policy module + spursTasksetInit(spu, pollStatus); + + // Dispatch + spursTasksetDispatch(spu); + } + + catch (SpursModuleExit) { + } - // Dispatch - spursTasksetDispatch(spu); return false; } @@ -1096,19 +1118,25 @@ bool spursTasksetEntry(SPUThread & spu) { bool spursTasksetSyscallEntry(SPUThread & spu) { auto ctxt = vm::get_ptr(spu.offset + 0x2700); - // Save task context - ctxt->savedContextLr = spu.GPR[0]; - ctxt->savedContextSp = spu.GPR[1]; - for (auto i = 0; i < 48; i++) { - ctxt->savedContextR80ToR127[i] = spu.GPR[80 + i]; + try { + // Save task context + ctxt->savedContextLr = spu.GPR[0]; + ctxt->savedContextSp = spu.GPR[1]; + for (auto i = 0; i < 48; i++) { + ctxt->savedContextR80ToR127[i] = spu.GPR[80 + i]; + } + + // Handle the syscall + spu.GPR[3]._u32[3] = spursTasksetProcessSyscall(spu, spu.GPR[3]._u32[3], spu.GPR[4]._u32[3]); + + // Resume the previously executing task if the syscall did not cause a context switch + throw EXCEPTION("Broken (TODO)"); + //if (spu.m_is_branch == false) { + // spursTasksetResumeTask(spu); + //} } - // Handle the syscall - spu.GPR[3]._u32[3] = spursTasksetProcessSyscall(spu, spu.GPR[3]._u32[3], spu.GPR[4]._u32[3]); - - // Resume the previously executing task if the syscall did not cause a context switch - if (spu.m_is_branch == false) { - spursTasksetResumeTask(spu); + catch (SpursModuleExit) { } return false; @@ -1125,7 +1153,7 @@ void spursTasksetResumeTask(SPUThread & spu) { spu.GPR[80 + i] = ctxt->savedContextR80ToR127[i]; } - spu.SetBranch(spu.GPR[0]._u32[3]); + spu.PC = spu.GPR[0]._u32[3] - 4; } /// Start a task @@ -1135,13 +1163,13 @@ void spursTasksetStartTask(SPUThread & spu, CellSpursTaskArgument & taskArgs) { spu.GPR[2].clear(); spu.GPR[3] = u128::from64r(taskArgs._u64[0], taskArgs._u64[1]); - spu.GPR[4]._u64[1] = taskset->m.args; - spu.GPR[4]._u64[0] = taskset->m.spurs.addr(); + spu.GPR[4]._u64[1] = taskset->args; + spu.GPR[4]._u64[0] = taskset->spurs.addr(); for (auto i = 5; i < 128; i++) { spu.GPR[i].clear(); } - spu.SetBranch(ctxt->savedContextLr.value()._u32[3]); + spu.PC = ctxt->savedContextLr.value()._u32[3] - 4; } /// Process a request and update the state of the taskset @@ -1151,20 +1179,19 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * s32 rc = CELL_OK; s32 numNewlyReadyTasks; - vm::reservation_op(vm::cast(ctxt->taskset.addr()), 128, [&]() { + vm::reservation_op(VM_CAST(ctxt->taskset.addr()), 128, [&]() { auto taskset = ctxt->taskset.priv_ptr(); // Verify taskset state is valid - auto _0 = be_t::make(u128::from32(0)); - if ((taskset->m.waiting & taskset->m.running) != _0 || (taskset->m.ready & taskset->m.pending_ready) != _0 || - ((taskset->m.running | taskset->m.ready | taskset->m.pending_ready | taskset->m.signalled | taskset->m.waiting) & be_t::make(~taskset->m.enabled.value())) != _0) { + be_t _0(u128::from32(0)); + if ((taskset->waiting & taskset->running) != _0 || (taskset->ready & taskset->pending_ready) != _0 || + ((taskset->running | taskset->ready | taskset->pending_ready | taskset->signalled | taskset->waiting) & ~taskset->enabled) != _0) { assert(!"Invalid taskset state"); - //spursHalt(spu); - //return CELL_OK; + spursHalt(spu); } // Find the number of tasks that have become ready since the last iteration - auto newlyReadyTasks = (taskset->m.signalled | taskset->m.pending_ready).value() & ~taskset->m.ready.value(); + auto newlyReadyTasks = (taskset->signalled | taskset->pending_ready) & ~taskset->ready.value(); numNewlyReadyTasks = 0; for (auto i = 0; i < 128; i++) { if (newlyReadyTasks._bit[i]) { @@ -1174,11 +1201,11 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * u128 readyButNotRunning; u8 selectedTaskId; - auto running = taskset->m.running.value(); - auto waiting = taskset->m.waiting.value(); - auto enabled = taskset->m.enabled.value(); - auto signalled = (taskset->m.signalled & (taskset->m.ready | taskset->m.pending_ready)).value(); - auto ready = (taskset->m.signalled | taskset->m.ready | taskset->m.pending_ready).value(); + u128 running = taskset->running.value(); + u128 waiting = taskset->waiting.value(); + u128 enabled = taskset->enabled.value(); + u128 signalled = (taskset->signalled & (taskset->ready | taskset->pending_ready)); + u128 ready = (taskset->signalled | taskset->ready | taskset->pending_ready); switch (request) { case SPURS_TASKSET_REQUEST_POLL_SIGNAL: @@ -1207,20 +1234,20 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * break; case SPURS_TASKSET_REQUEST_POLL: readyButNotRunning = ready & ~running; - if (taskset->m.wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { - readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->m.wkl_flag_wait_task)); + if (taskset->wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { + readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->wkl_flag_wait_task)); } rc = readyButNotRunning != _0 ? 1 : 0; break; case SPURS_TASKSET_REQUEST_WAIT_WKL_FLAG: - if (taskset->m.wkl_flag_wait_task == 0x81) { + if (taskset->wkl_flag_wait_task == 0x81) { // A workload flag is already pending so consume it - taskset->m.wkl_flag_wait_task = 0x80; + taskset->wkl_flag_wait_task = 0x80; rc = 0; - } else if (taskset->m.wkl_flag_wait_task == 0x80) { + } else if (taskset->wkl_flag_wait_task == 0x80) { // No tasks are waiting for the workload flag. Mark this task as waiting for the workload flag. - taskset->m.wkl_flag_wait_task = ctxt->taskId; + taskset->wkl_flag_wait_task = ctxt->taskId; running._bit[ctxt->taskId] = false; waiting._bit[ctxt->taskId] = true; rc = 1; @@ -1232,25 +1259,25 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * break; case SPURS_TASKSET_REQUEST_SELECT_TASK: readyButNotRunning = ready & ~running; - if (taskset->m.wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { - readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->m.wkl_flag_wait_task)); + if (taskset->wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { + readyButNotRunning = readyButNotRunning & ~(u128::fromBit(taskset->wkl_flag_wait_task)); } // Select a task from the readyButNotRunning set to run. Start from the task after the last scheduled task to ensure fairness. - for (selectedTaskId = taskset->m.last_scheduled_task + 1; selectedTaskId < 128; selectedTaskId++) { + for (selectedTaskId = taskset->last_scheduled_task + 1; selectedTaskId < 128; selectedTaskId++) { if (readyButNotRunning._bit[selectedTaskId]) { break; } } if (selectedTaskId == 128) { - for (selectedTaskId = 0; selectedTaskId < taskset->m.last_scheduled_task + 1; selectedTaskId++) { + for (selectedTaskId = 0; selectedTaskId < taskset->last_scheduled_task + 1; selectedTaskId++) { if (readyButNotRunning._bit[selectedTaskId]) { break; } } - if (selectedTaskId == taskset->m.last_scheduled_task + 1) { + if (selectedTaskId == taskset->last_scheduled_task + 1) { selectedTaskId = CELL_SPURS_MAX_TASK; } } @@ -1258,51 +1285,50 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * *taskId = selectedTaskId; *isWaiting = waiting._bit[selectedTaskId < CELL_SPURS_MAX_TASK ? selectedTaskId : 0] ? 1 : 0; if (selectedTaskId != CELL_SPURS_MAX_TASK) { - taskset->m.last_scheduled_task = selectedTaskId; + taskset->last_scheduled_task = selectedTaskId; running._bit[selectedTaskId] = true; waiting._bit[selectedTaskId] = false; } break; case SPURS_TASKSET_REQUEST_RECV_WKL_FLAG: - if (taskset->m.wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { + if (taskset->wkl_flag_wait_task < CELL_SPURS_MAX_TASK) { // There is a task waiting for the workload flag - taskset->m.wkl_flag_wait_task = 0x80; + taskset->wkl_flag_wait_task = 0x80; rc = 1; numNewlyReadyTasks++; } else { // No tasks are waiting for the workload flag - taskset->m.wkl_flag_wait_task = 0x81; + taskset->wkl_flag_wait_task = 0x81; rc = 0; } break; default: assert(!"Unknown taskset request"); - //spursHalt(spu); - //return CELL_OK; + spursHalt(spu); } - taskset->m.pending_ready = _0; - taskset->m.running = running; - taskset->m.waiting = waiting; - taskset->m.enabled = enabled; - taskset->m.signalled = signalled; - taskset->m.ready = ready; + taskset->pending_ready = _0; + taskset->running = running; + taskset->waiting = waiting; + taskset->enabled = enabled; + taskset->signalled = signalled; + taskset->ready = ready; memcpy(vm::get_ptr(spu.offset + 0x2700), taskset, 128); }); // Increment the ready count of the workload by the number of tasks that have become ready - vm::reservation_op(vm::cast(kernelCtxt->spurs.addr()), 128, [&]() { + vm::reservation_op(VM_CAST(kernelCtxt->spurs.addr()), 128, [&]() { auto spurs = kernelCtxt->spurs.priv_ptr(); - s32 readyCount = kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[kernelCtxt->wklCurrentId].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].read_relaxed(); + s32 readyCount = kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD ? spurs->wklReadyCount1[kernelCtxt->wklCurrentId].load() : spurs->wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].load(); readyCount += numNewlyReadyTasks; readyCount = readyCount < 0 ? 0 : readyCount > 0xFF ? 0xFF : readyCount; if (kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD) { - spurs->m.wklReadyCount1[kernelCtxt->wklCurrentId].write_relaxed(readyCount); + spurs->wklReadyCount1[kernelCtxt->wklCurrentId].store(readyCount); } else { - spurs->m.wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].write_relaxed(readyCount); + spurs->wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].store(readyCount); } memcpy(vm::get_ptr(spu.offset + 0x100), spurs, 128); @@ -1398,11 +1424,11 @@ s32 spursTasketSaveTaskContext(SPUThread & spu) { u128 r; spu.FPSCR.Read(r); ctxt->savedContextFpscr = r; - ctxt->savedSpuWriteEventMask = spu.get_ch_value(SPU_RdEventMask); - ctxt->savedWriteTagGroupQueryMask = spu.get_ch_value(MFC_RdTagMask); + ctxt->savedSpuWriteEventMask = spu.get_ch_value(SPU_RdEventMask); + ctxt->savedWriteTagGroupQueryMask = spu.get_ch_value(MFC_RdTagMask); // Store the processor context - const u32 contextSaveStorage = vm::cast(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80); + const u32 contextSaveStorage = VM_CAST(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80); memcpy(vm::get_ptr(contextSaveStorage), vm::get_ptr(spu.offset + 0x2C80), 0x380); // Save LS context @@ -1433,10 +1459,10 @@ void spursTasksetDispatch(SPUThread & spu) { ctxt->taskId = taskId; // DMA in the task info for the selected task - memcpy(vm::get_ptr(spu.offset + 0x2780), &ctxt->taskset->m.task_info[taskId], sizeof(CellSpursTaskset::TaskInfo)); + memcpy(vm::get_ptr(spu.offset + 0x2780), &ctxt->taskset->task_info[taskId], sizeof(CellSpursTaskset::TaskInfo)); auto taskInfo = vm::get_ptr(spu.offset + 0x2780); - auto elfAddr = taskInfo->elf_addr.addr().value(); - taskInfo->elf_addr.set(taskInfo->elf_addr.addr() & 0xFFFFFFFFFFFFFFF8ull); + auto elfAddr = taskInfo->elf.addr().value(); + taskInfo->elf.set(taskInfo->elf.addr() & 0xFFFFFFFFFFFFFFF8ull); // Trace - Task: Incident=dispatch CellSpursTracePacket pkt; @@ -1453,10 +1479,9 @@ void spursTasksetDispatch(SPUThread & spu) { u32 entryPoint; u32 lowestLoadAddr; - if (spursTasksetLoadElf(spu, &entryPoint, &lowestLoadAddr, taskInfo->elf_addr.addr(), false) != CELL_OK) { + if (spursTasksetLoadElf(spu, &entryPoint, &lowestLoadAddr, taskInfo->elf.addr(), false) != CELL_OK) { assert(!"spursTaskLoadElf() failed"); - //spursHalt(spu); - //return; + spursHalt(spu); } //spursDmaWaitForCompletion(spu, 1 << ctxt->dmaTagId); @@ -1469,7 +1494,7 @@ void spursTasksetDispatch(SPUThread & spu) { ctxt->x2FD4 = elfAddr & 5; // TODO: Figure this out if ((elfAddr & 5) == 1) { - memcpy(vm::get_ptr(spu.offset + 0x2FC0), &((CellSpursTaskset2*)(ctxt->taskset.get_ptr()))->m.task_exit_code[taskId], 0x10); + memcpy(vm::get_ptr(spu.offset + 0x2FC0), &((CellSpursTaskset2*)(ctxt->taskset.get_ptr()))->task_exit_code[taskId], 0x10); } // Trace - GUID @@ -1486,7 +1511,7 @@ void spursTasksetDispatch(SPUThread & spu) { spursTasksetStartTask(spu, taskInfo->args); } else { - if (taskset->m.enable_clear_ls) { + if (taskset->enable_clear_ls) { memset(vm::get_ptr(spu.offset + CELL_SPURS_TASK_TOP), 0, CELL_SPURS_TASK_BOTTOM - CELL_SPURS_TASK_TOP); } @@ -1495,15 +1520,14 @@ void spursTasksetDispatch(SPUThread & spu) { if (ls_pattern != u128::from64r(0x03FFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull)) { // Load the ELF u32 entryPoint; - if (spursTasksetLoadElf(spu, &entryPoint, nullptr, taskInfo->elf_addr.addr(), true) != CELL_OK) { + if (spursTasksetLoadElf(spu, &entryPoint, nullptr, taskInfo->elf.addr(), true) != CELL_OK) { assert(!"spursTasksetLoadElf() failed"); - //spursHalt(spu); - //return; + spursHalt(spu); } } // Load saved context from main memory to LS - const u32 contextSaveStorage = vm::cast(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80); + const u32 contextSaveStorage = VM_CAST(taskInfo->context_save_storage_and_alloc_ls_blocks & -0x80); memcpy(vm::get_ptr(spu.offset + 0x2C80), vm::get_ptr(contextSaveStorage), 0x380); for (auto i = 6; i < 128; i++) { if (ls_pattern._bit[i]) { @@ -1557,8 +1581,8 @@ s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args) { spursTasksetProcessRequest(spu, SPURS_TASKSET_REQUEST_DESTROY_TASK, nullptr, nullptr); } - auto addr = ctxt->x2FD4 == 4 ? taskset->m.x78 : ctxt->x2FC0; - auto args = ctxt->x2FD4 == 4 ? 0 : ctxt->x2FC8; + const u64 addr = ctxt->x2FD4 == 4 ? taskset->x78 : ctxt->x2FC0; + const u64 args = ctxt->x2FD4 == 4 ? 0 : ctxt->x2FC8.value(); spursTasksetOnTaskExit(spu, addr, ctxt->taskId, ctxt->taskExitCode, args); } @@ -1655,7 +1679,7 @@ s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, return CELL_SPURS_TASK_ERROR_INVAL; } - vfsStreamMemory stream(vm::cast(elfAddr)); + vfsStreamMemory stream(VM_CAST(elfAddr)); loader::handlers::elf32 loader; auto rc = loader.init(stream); if (rc != loader::handler::ok) { @@ -1675,7 +1699,7 @@ s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, return CELL_SPURS_TASK_ERROR_FAULT; } - _lowestLoadAddr = _lowestLoadAddr > phdr.data_be.p_vaddr ? phdr.data_be.p_vaddr : _lowestLoadAddr; + _lowestLoadAddr > phdr.data_be.p_vaddr ? _lowestLoadAddr = phdr.data_be.p_vaddr : _lowestLoadAddr; } } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp index 5e642a01b5..569fca2bf7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp @@ -6,21 +6,21 @@ extern Module cellSubdisplay; -int cellSubDisplayInit() +s32 cellSubDisplayInit() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayEnd() +s32 cellSubDisplayEnd() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayGetRequiredMemory(vm::ptr pParam) +s32 cellSubDisplayGetRequiredMemory(vm::ptr pParam) { - cellSubdisplay.Warning("cellSubDisplayGetRequiredMemory(pParam_addr=0x%x)", pParam.addr()); + cellSubdisplay.Warning("cellSubDisplayGetRequiredMemory(pParam=*0x%x)", pParam); if (pParam->version == CELL_SUBDISPLAY_VERSION_0002) { @@ -32,43 +32,43 @@ int cellSubDisplayGetRequiredMemory(vm::ptr pParam) } } -int cellSubDisplayStart() +s32 cellSubDisplayStart() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayStop() +s32 cellSubDisplayStop() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayGetVideoBuffer() +s32 cellSubDisplayGetVideoBuffer() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayAudioOutBlocking() +s32 cellSubDisplayAudioOutBlocking() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayAudioOutNonBlocking() +s32 cellSubDisplayAudioOutNonBlocking() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayGetPeerNum() +s32 cellSubDisplayGetPeerNum() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; } -int cellSubDisplayGetPeerList() +s32 cellSubDisplayGetPeerList() { UNIMPLEMENTED_FUNC(cellSubdisplay); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.h b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.h index 8321a606c0..590a6aa41b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -58,8 +60,8 @@ struct CellSubDisplayParam be_t mode; be_t nGroup; be_t nPeer; - vm::ptr videoParam; - vm::ptr audioParam; + vm::bptr videoParam; + vm::bptr audioParam; }; struct CellSubDisplayPSPId @@ -80,4 +82,4 @@ struct CellSubDisplayPeerInfo CellSubDisplayNickname pspNickname; }; -typedef void(*CellSubDisplayHandler)(s32 cbMsg, u64 cbParam, u32 *userdata); \ No newline at end of file +using CellSubDisplayHandler = func_def userdata)>; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index db6ec1be46..0e04566a8d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -2,7 +2,6 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_event.h" @@ -19,30 +18,25 @@ waiter_map_t g_sync_rwm_read_wm("sync_rwm_read_wm"); waiter_map_t g_sync_rwm_write_wm("sync_rwm_write_wm"); waiter_map_t g_sync_queue_wm("sync_queue_wm"); -s32 syncMutexInitialize(vm::ptr mutex) +s32 cellSyncMutexInitialize(vm::ptr mutex) { + cellSync.Log("cellSyncMutexInitialize(mutex=*0x%x)", mutex); + if (!mutex) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - mutex->sync_var.exchange({}); + mutex->exchange({}); return CELL_OK; } -s32 cellSyncMutexInitialize(vm::ptr mutex) -{ - cellSync.Log("cellSyncMutexInitialize(mutex=*0x%x)", mutex); - - return syncMutexInitialize(mutex); -} - s32 cellSyncMutexLock(vm::ptr mutex) { cellSync.Log("cellSyncMutexLock(mutex=*0x%x)", mutex); @@ -52,21 +46,18 @@ s32 cellSyncMutexLock(vm::ptr mutex) return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - // prx: increase acquire_count and remember its old value - const auto order = mutex->acquire_count++; + // increase acq value and remember its old value + const auto order = mutex->atomic_op(&sync_mutex_t::acquire); - // prx: wait until release_count is equal to old acquire_count - g_sync_mutex_wm.wait_op(mutex.addr(), [mutex, order]() - { - return order == mutex->release_count.read_relaxed(); - }); + // wait until rel value is equal to old acq value + g_sync_mutex_wm.wait_op(mutex.addr(), WRAP_EXPR(mutex->load().rel == order)); - mutex->sync_var.read_sync(); + _mm_mfence(); return CELL_OK; } @@ -80,16 +71,17 @@ s32 cellSyncMutexTryLock(vm::ptr mutex) return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - // prx: lock only if acquire_count and release_count are equal - return mutex->sync_var.atomic_op(CELL_OK, [](CellSyncMutex::sync_t& mutex) -> s32 + if (!mutex->atomic_op(&sync_mutex_t::try_lock)) { - return (mutex.acquire_count++ != mutex.release_count) ? CELL_SYNC_ERROR_BUSY : CELL_OK; - }); + return CELL_SYNC_ERROR_BUSY; + } + + return CELL_OK; } s32 cellSyncMutexUnlock(vm::ptr mutex) @@ -100,66 +92,43 @@ s32 cellSyncMutexUnlock(vm::ptr mutex) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (mutex.addr() % 4) + + if (!mutex.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - // prx: increase release count - mutex->release_count++; + mutex->atomic_op(&sync_mutex_t::unlock); g_sync_mutex_wm.notify(mutex.addr()); return CELL_OK; } -s32 syncBarrierInitialize(vm::ptr barrier, u16 total_count) -{ - if (!barrier) - { - return CELL_SYNC_ERROR_NULL_POINTER; - } - if (barrier.addr() % 4) - { - return CELL_SYNC_ERROR_ALIGN; - } - if (!total_count || total_count > 32767) - { - return CELL_SYNC_ERROR_INVAL; - } - - // prx: zeroize first u16, write total_count in second u16 and sync - barrier->data.exchange({ be_t::make(0), be_t::make(total_count) }); - - return CELL_OK; -} - s32 cellSyncBarrierInitialize(vm::ptr barrier, u16 total_count) { cellSync.Log("cellSyncBarrierInitialize(barrier=*0x%x, total_count=%d)", barrier, total_count); - return syncBarrierInitialize(barrier, total_count); -} - -s32 syncBarrierTryNotifyOp(CellSyncBarrier::data_t& barrier) -{ - // prx: extract m_value (repeat if < 0), increase, compare with second s16, set sign bit if equal, insert it back - s16 value = barrier.m_value; - - if (value < 0) + if (!barrier) { - return CELL_SYNC_ERROR_BUSY; + return CELL_SYNC_ERROR_NULL_POINTER; } - if (++value == barrier.m_count) + if (!barrier.aligned()) { - value |= 0x8000; + return CELL_SYNC_ERROR_ALIGN; } - barrier.m_value = value; + if (!total_count || total_count > 32767) + { + return CELL_SYNC_ERROR_INVAL; + } + + // clear current value, write total_count and sync + barrier->exchange({ 0, total_count }); return CELL_OK; -}; +} s32 cellSyncBarrierNotify(vm::ptr barrier) { @@ -169,15 +138,13 @@ s32 cellSyncBarrierNotify(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - g_sync_barrier_notify_wm.wait_op(barrier.addr(), [barrier]() - { - return barrier->data.atomic_op_sync(CELL_OK, syncBarrierTryNotifyOp) == CELL_OK; - }); + g_sync_barrier_notify_wm.wait_op(barrier.addr(), WRAP_EXPR(barrier->atomic_op(&sync_barrier_t::try_notify))); g_sync_barrier_wait_wm.notify(barrier.addr()); @@ -192,37 +159,20 @@ s32 cellSyncBarrierTryNotify(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - if (s32 res = barrier->data.atomic_op_sync(CELL_OK, syncBarrierTryNotifyOp)) - { - return res; - } + _mm_mfence(); - g_sync_barrier_wait_wm.notify(barrier.addr()); - - return CELL_OK; -} - -s32 syncBarrierTryWaitOp(CellSyncBarrier::data_t& barrier) -{ - // prx: extract m_value (repeat if >= 0), decrease it, set 0 if == 0x8000, insert it back - s16 value = barrier.m_value; - - if (value >= 0) + if (!barrier->atomic_op(&sync_barrier_t::try_notify)) { return CELL_SYNC_ERROR_BUSY; } - if (--value == -0x8000) - { - value = 0; - } - - barrier.m_value = value; + g_sync_barrier_wait_wm.notify(barrier.addr()); return CELL_OK; } @@ -235,15 +185,15 @@ s32 cellSyncBarrierWait(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - g_sync_barrier_wait_wm.wait_op(barrier.addr(), [barrier]() - { - return barrier->data.atomic_op_sync(CELL_OK, syncBarrierTryWaitOp) == CELL_OK; - }); + _mm_mfence(); + + g_sync_barrier_wait_wm.wait_op(barrier.addr(), WRAP_EXPR(barrier->atomic_op(&sync_barrier_t::try_wait))); g_sync_barrier_notify_wm.notify(barrier.addr()); @@ -258,14 +208,17 @@ s32 cellSyncBarrierTryWait(vm::ptr barrier) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (barrier.addr() % 4) + + if (!barrier.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - if (s32 res = barrier->data.atomic_op_sync(CELL_OK, syncBarrierTryWaitOp)) + _mm_mfence(); + + if (!barrier->atomic_op(&sync_barrier_t::try_wait)) { - return res; + return CELL_SYNC_ERROR_BUSY; } g_sync_barrier_notify_wm.notify(barrier.addr()); @@ -273,56 +226,31 @@ s32 cellSyncBarrierTryWait(vm::ptr barrier) return CELL_OK; } -s32 syncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer_size) -{ - if (!rwm || !buffer) - { - return CELL_SYNC_ERROR_NULL_POINTER; - } - if (rwm.addr() % 16 || buffer.addr() % 128) - { - return CELL_SYNC_ERROR_ALIGN; - } - if (buffer_size % 128 || buffer_size > 0x4000) - { - return CELL_SYNC_ERROR_INVAL; - } - - // prx: zeroize first u16 and second u16, write buffer_size in second u32, write buffer_addr in second u64 and sync - rwm->m_size = buffer_size; - rwm->m_buffer = buffer; - rwm->data.exchange({}); - - return CELL_OK; -} - s32 cellSyncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer_size) { cellSync.Log("cellSyncRwmInitialize(rwm=*0x%x, buffer=*0x%x, buffer_size=0x%x)", rwm, buffer, buffer_size); - return syncRwmInitialize(rwm, buffer, buffer_size); -} - -s32 syncRwmTryReadBeginOp(CellSyncRwm::data_t& rwm) -{ - if (rwm.m_writers.data()) + if (!rwm || !buffer) { - return CELL_SYNC_ERROR_BUSY; + return CELL_SYNC_ERROR_NULL_POINTER; } - rwm.m_readers++; - - return CELL_OK; -} - -s32 syncRwmReadEndOp(CellSyncRwm::data_t& rwm) -{ - if (!rwm.m_readers.data()) + if (!rwm.aligned() || buffer % 128) { - return CELL_SYNC_ERROR_ABORT; + return CELL_SYNC_ERROR_ALIGN; } - rwm.m_readers--; + if (buffer_size % 128 || buffer_size > 0x4000) + { + return CELL_SYNC_ERROR_INVAL; + } + + // clear readers and writers, write buffer_size, buffer addr and sync + rwm->ctrl.store({}); + rwm->size = buffer_size; + rwm->buffer = buffer; + + _mm_mfence(); return CELL_OK; } @@ -335,25 +263,22 @@ s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - // prx: increase m_readers, wait until m_writers is zero - g_sync_rwm_read_wm.wait_op(rwm.addr(), [rwm]() - { - return rwm->data.atomic_op(CELL_OK, syncRwmTryReadBeginOp) == CELL_OK; - }); + // wait until `writers` is zero, increase `readers` + g_sync_rwm_read_wm.wait_op(rwm.addr(), WRAP_EXPR(rwm->ctrl.atomic_op(&sync_rwm_t::try_read_begin))); - // copy data to buffer_addr - memcpy(buffer.get_ptr(), rwm->m_buffer.get_ptr(), rwm->m_size); + // copy data to buffer + std::memcpy(buffer.get_ptr(), rwm->buffer.get_ptr(), rwm->size); - // prx: decrease m_readers (return 0x8041010C if already zero) - if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmReadEndOp)) + // decrease `readers`, return error if already zero + if (!rwm->ctrl.atomic_op(&sync_rwm_t::try_read_end)) { - cellSync.Error("syncRwmReadEndOp(rwm=0x%x) failed: m_readers == 0", rwm); - return res; + return CELL_SYNC_ERROR_ABORT; } g_sync_rwm_write_wm.notify(rwm.addr()); @@ -369,21 +294,25 @@ s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmTryReadBeginOp)) + // increase `readers` if `writers` is zero + if (!rwm->ctrl.atomic_op(&sync_rwm_t::try_read_begin)) { - return res; + return CELL_SYNC_ERROR_BUSY; } - memcpy(buffer.get_ptr(), rwm->m_buffer.get_ptr(), rwm->m_size); + // copy data to buffer + std::memcpy(buffer.get_ptr(), rwm->buffer.get_ptr(), rwm->size); - if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmReadEndOp)) + // decrease `readers`, return error if already zero + if (!rwm->ctrl.atomic_op(&sync_rwm_t::try_read_end)) { - return res; + return CELL_SYNC_ERROR_ABORT; } g_sync_rwm_write_wm.notify(rwm.addr()); @@ -391,19 +320,7 @@ s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) return CELL_OK; } -s32 syncRwmTryWriteBeginOp(CellSyncRwm::data_t& rwm) -{ - if (rwm.m_writers.data()) - { - return CELL_SYNC_ERROR_BUSY; - } - - rwm.m_writers = 1; - - return CELL_OK; -} - -s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) +s32 cellSyncRwmWrite(vm::ptr rwm, vm::cptr buffer) { cellSync.Log("cellSyncRwmWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); @@ -411,34 +328,30 @@ s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - g_sync_rwm_read_wm.wait_op(rwm.addr(), [rwm]() - { - return rwm->data.atomic_op(CELL_OK, syncRwmTryWriteBeginOp) == CELL_OK; - }); + // wait until `writers` is zero, set to 1 + g_sync_rwm_read_wm.wait_op(rwm.addr(), WRAP_EXPR(rwm->ctrl.atomic_op(&sync_rwm_t::try_write_begin))); - // prx: wait until m_readers == 0 - g_sync_rwm_write_wm.wait_op(rwm.addr(), [rwm]() - { - return rwm->data.read_relaxed().m_readers.data() == 0; - }); + // wait until `readers` is zero + g_sync_rwm_write_wm.wait_op(rwm.addr(), WRAP_EXPR(!rwm->ctrl.load().readers.data())); - // prx: copy data from buffer_addr - memcpy(rwm->m_buffer.get_ptr(), buffer.get_ptr(), rwm->m_size); + // copy data from buffer + std::memcpy(rwm->buffer.get_ptr(), buffer.get_ptr(), rwm->size); - // prx: sync and zeroize m_readers and m_writers - rwm->data.exchange({}); + // sync and clear `readers` and `writers` + rwm->ctrl.exchange({}); g_sync_rwm_read_wm.notify(rwm.addr()); return CELL_OK; } -s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::ptr buffer) +s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::cptr buffer) { cellSync.Log("cellSyncRwmTryWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); @@ -446,86 +359,65 @@ s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (rwm.addr() % 16) + + if (!rwm.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - // prx: compare m_readers | m_writers with 0, return if not zero, set m_writers to 1 - if (!rwm->data.compare_and_swap_test({}, { be_t::make(0), be_t::make(1) })) + // set `writers` to 1 if `readers` and `writers` are zero + if (!rwm->ctrl.compare_and_swap_test({ 0, 0 }, { 0, 1 })) { return CELL_SYNC_ERROR_BUSY; } - // prx: copy data from buffer_addr - memcpy(rwm->m_buffer.get_ptr(), buffer.get_ptr(), rwm->m_size); + // copy data from buffer + std::memcpy(rwm->buffer.get_ptr(), buffer.get_ptr(), rwm->size); - // prx: sync and zeroize m_readers and m_writers - rwm->data.exchange({}); + // sync and clear `readers` and `writers` + rwm->ctrl.exchange({}); g_sync_rwm_read_wm.notify(rwm.addr()); return CELL_OK; } -s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth) -{ - if (!queue) - { - return CELL_SYNC_ERROR_NULL_POINTER; - } - if (size && !buffer) - { - return CELL_SYNC_ERROR_NULL_POINTER; - } - if (queue.addr() % 32 || buffer.addr() % 16) - { - return CELL_SYNC_ERROR_ALIGN; - } - if (!depth || size % 16) - { - return CELL_SYNC_ERROR_INVAL; - } - - // prx: zeroize first u64, write size in third u32, write depth in fourth u32, write address in third u64 and sync - queue->m_size = size; - queue->m_depth = depth; - queue->m_buffer = buffer; - queue->data.exchange({}); - - return CELL_OK; -} - s32 cellSyncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth) { cellSync.Log("cellSyncQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x)", queue, buffer, size, depth); - return syncQueueInitialize(queue, buffer, size, depth); -} - -s32 syncQueueTryPushOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) -{ - const u32 v1 = queue.m_v1; - const u32 v2 = queue.m_v2; - - // prx: compare 5th u8 with zero (break if not zero) - // prx: compare (second u32 (u24) + first u8) with depth (break if greater or equal) - if ((v2 >> 24) || ((v2 & 0xffffff) + (v1 >> 24)) >= depth) + if (!queue) { - return CELL_SYNC_ERROR_BUSY; + return CELL_SYNC_ERROR_NULL_POINTER; } - // prx: extract first u32 (u24) (-> position), calculate (position + 1) % depth, insert it back - // prx: insert 1 in 5th u8 - // prx: extract second u32 (u24), increase it, insert it back - position = (v1 & 0xffffff); - queue.m_v1 = (v1 & 0xff000000) | ((position + 1) % depth); - queue.m_v2 = (1 << 24) | ((v2 & 0xffffff) + 1); + if (size && !buffer) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + + if (!queue.aligned() || buffer % 16) + { + return CELL_SYNC_ERROR_ALIGN; + } + + if (!depth || size % 16) + { + return CELL_SYNC_ERROR_INVAL; + } + + // clear sync var, write size, depth, buffer addr and sync + queue->ctrl.store({}); + queue->size = size; + queue->depth = depth; + queue->buffer = buffer; + + _mm_mfence(); return CELL_OK; } -s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) +s32 cellSyncQueuePush(vm::ptr queue, vm::cptr buffer) { cellSync.Log("cellSyncQueuePush(queue=*0x%x, buffer=*0x%x)", queue, buffer); @@ -533,37 +425,30 @@ s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 size = queue->m_size; - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + const u32 depth = queue->check_depth(); u32 position; - g_sync_queue_wm.wait_op(queue.addr(), [queue, depth, &position]() - { - return CELL_OK == queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 - { - return syncQueueTryPushOp(queue, depth, position); - }); - }); - // prx: memcpy(position * m_size + m_addr, buffer_addr, m_size), sync - memcpy(&queue->m_buffer[position * size], buffer.get_ptr(), size); + g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_push_begin, depth, position))); - // prx: atomically insert 0 in 5th u8 - queue->data &= { be_t::make(~0), be_t::make(0xffffff) }; + // copy data from the buffer at the position + std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size); + + // clear 5th byte + queue->ctrl &= { 0xffffffff, 0x00ffffff }; g_sync_queue_wm.notify(queue.addr()); return CELL_OK; } -s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffer) +s32 cellSyncQueueTryPush(vm::ptr queue, vm::cptr buffer) { cellSync.Log("cellSyncQueueTryPush(queue=*0x%x, buffer=*0x%x)", queue, buffer); @@ -571,53 +456,28 @@ s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffe { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 size = queue->m_size; - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + const u32 depth = queue->check_depth(); u32 position; - s32 res = queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 - { - return syncQueueTryPushOp(queue, depth, position); - }); - if (res) - { - return res; - } - memcpy(&queue->m_buffer[position * size], buffer.get_ptr(), size); - - queue->data &= { be_t::make(~0), be_t::make(0xffffff) }; - - g_sync_queue_wm.notify(queue.addr()); - - return CELL_OK; -} - -s32 syncQueueTryPopOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) -{ - const u32 v1 = queue.m_v1; - const u32 v2 = queue.m_v2; - - // prx: extract first u8, repeat if not zero - // prx: extract second u32 (u24), subtract 5th u8, compare with zero, repeat if less or equal - if ((v1 >> 24) || ((v2 & 0xffffff) <= (v2 >> 24))) + if (!queue->ctrl.atomic_op(&sync_queue_t::try_push_begin, depth, position)) { return CELL_SYNC_ERROR_BUSY; } - // prx: insert 1 in first u8 - // prx: extract first u32 (u24), add depth, subtract second u32 (u24), calculate (% depth), save to position - // prx: extract second u32 (u24), decrease it, insert it back - queue.m_v1 = 0x1000000 | v1; - position = ((v1 & 0xffffff) + depth - (v2 & 0xffffff)) % depth; - queue.m_v2 = (v2 & 0xff000000) | ((v2 & 0xffffff) - 1); + // copy data from the buffer at the position + std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size); + + // clear 5th byte + queue->ctrl &= { 0xffffffff, 0x00ffffff }; + + g_sync_queue_wm.notify(queue.addr()); return CELL_OK; } @@ -630,30 +490,23 @@ s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 size = queue->m_size; - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + const u32 depth = queue->check_depth(); u32 position; - g_sync_queue_wm.wait_op(queue.addr(), [queue, depth, &position]() - { - return CELL_OK == queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 - { - return syncQueueTryPopOp(queue, depth, position); - }); - }); - // prx: (sync), memcpy(buffer_addr, position * m_size + m_addr, m_size) - memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); + g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_pop_begin, depth, position))); - // prx: atomically insert 0 in first u8 - queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + // copy data at the position to the buffer + std::memcpy(buffer.get_ptr(), &queue->buffer[position * queue->size], queue->size); + + // clear first byte + queue->ctrl &= { 0x00ffffff, 0xffffffffu }; g_sync_queue_wm.notify(queue.addr()); @@ -668,47 +521,28 @@ s32 cellSyncQueueTryPop(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 size = queue->m_size; - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + const u32 depth = queue->check_depth(); u32 position; - s32 res = queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 - { - return syncQueueTryPopOp(queue, depth, position); - }); - if (res) - { - return res; - } - - memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); - - queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; - - g_sync_queue_wm.notify(queue.addr()); - - return CELL_OK; -} - -s32 syncQueueTryPeekOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) -{ - const u32 v1 = queue.m_v1; - const u32 v2 = queue.m_v2; - - if ((v1 >> 24) || ((v2 & 0xffffff) <= (v2 >> 24))) + + if (!queue->ctrl.atomic_op(&sync_queue_t::try_pop_begin, depth, position)) { return CELL_SYNC_ERROR_BUSY; } - queue.m_v1 = 0x1000000 | v1; - position = ((v1 & 0xffffff) + depth - (v2 & 0xffffff)) % depth; + // copy data at the position to the buffer + std::memcpy(buffer.get_ptr(), &queue->buffer[position * queue->size], queue->size); + + // clear first byte + queue->ctrl &= { 0x00ffffff, 0xffffffffu }; + + g_sync_queue_wm.notify(queue.addr()); return CELL_OK; } @@ -721,28 +555,23 @@ s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 size = queue->m_size; - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + const u32 depth = queue->check_depth(); u32 position; - g_sync_queue_wm.wait_op(queue.addr(), [queue, depth, &position]() - { - return CELL_OK == queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 - { - return syncQueueTryPeekOp(queue, depth, position); - }); - }); - memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); + g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_peek_begin, depth, position))); - queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + // copy data at the position to the buffer + std::memcpy(buffer.get_ptr(), &queue->buffer[position * queue->size], queue->size); + + // clear first byte + queue->ctrl &= { 0x00ffffff, 0xffffffffu }; g_sync_queue_wm.notify(queue.addr()); @@ -757,29 +586,26 @@ s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 size = queue->m_size; - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + const u32 depth = queue->check_depth(); u32 position; - s32 res = queue->data.atomic_op(CELL_OK, [depth, &position](CellSyncQueue::data_t& queue) -> s32 + + if (!queue->ctrl.atomic_op(&sync_queue_t::try_peek_begin, depth, position)) { - return syncQueueTryPeekOp(queue, depth, position); - }); - if (res) - { - return res; + return CELL_SYNC_ERROR_BUSY; } - memcpy(buffer.get_ptr(), &queue->m_buffer[position * size], size); + // copy data at the position to the buffer + std::memcpy(buffer.get_ptr(), &queue->buffer[position * queue->size], queue->size); - queue->data &= { be_t::make(0xffffff), be_t::make(~0) }; + // clear first byte + queue->ctrl &= { 0x00ffffff, 0xffffffffu }; g_sync_queue_wm.notify(queue.addr()); @@ -794,17 +620,15 @@ s32 cellSyncQueueSize(vm::ptr queue) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const auto data = queue->data.read_relaxed(); - const u32 count = data.m_v2 & 0xffffff; - const u32 depth = queue->m_depth; - assert((data.m_v1 & 0xffffff) <= depth && count <= depth); + queue->check_depth(); - return count; + return queue->ctrl.load().m_v2 & 0xffffff; } s32 cellSyncQueueClear(vm::ptr queue) @@ -815,53 +639,19 @@ s32 cellSyncQueueClear(vm::ptr queue) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 32) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } - const u32 depth = queue->m_depth; - const auto data = queue->data.read_relaxed(); - assert((data.m_v1 & 0xffffff) <= depth && (data.m_v2 & 0xffffff) <= depth); + queue->check_depth(); - // TODO: optimize if possible - g_sync_queue_wm.wait_op(queue.addr(), [queue, depth]() - { - return CELL_OK == queue->data.atomic_op(CELL_OK, [depth](CellSyncQueue::data_t& queue) -> s32 - { - const u32 v1 = queue.m_v1; + g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_clear_begin_1))); - // prx: extract first u8, repeat if not zero, insert 1 - if (v1 >> 24) - { - return CELL_SYNC_ERROR_BUSY; - } + g_sync_queue_wm.wait_op(queue.addr(), WRAP_EXPR(queue->ctrl.atomic_op(&sync_queue_t::try_clear_begin_2))); - queue.m_v1 = v1 | 0x1000000; - - return CELL_OK; - }); - }); - - g_sync_queue_wm.wait_op(queue.addr(), [queue, depth]() - { - return CELL_OK == queue->data.atomic_op(CELL_OK, [depth](CellSyncQueue::data_t& queue) -> s32 - { - const u32 v2 = queue.m_v2; - - // prx: extract 5th u8, repeat if not zero, insert 1 - if (v2 >> 24) - { - return CELL_SYNC_ERROR_BUSY; - } - - queue.m_v2 = v2 | 0x1000000; - - return CELL_OK; - }); - }); - - queue->data.exchange({}); + queue->ctrl.exchange({}); g_sync_queue_wm.notify(queue.addr()); @@ -870,7 +660,7 @@ s32 cellSyncQueueClear(vm::ptr queue) // LFQueue functions -void syncLFQueueInit(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) +void syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { queue->m_size = size; queue->m_depth = depth; @@ -890,13 +680,13 @@ void syncLFQueueInit(vm::ptr queue, vm::ptr buffer, u32 siz //m_bs[2] //m_bs[3] queue->m_v1 = -1; - queue->push2 = { { be_t::make(-1) } }; - queue->pop2 = { { be_t::make(-1) } }; + queue->push2 = { { 0xffff } }; + queue->pop2 = { { 0xffff } }; } else { - queue->pop1 = { { be_t::make(0), be_t::make(0), queue->pop1.read_relaxed().m_h3, be_t::make(0) } }; - queue->push1 = { { be_t::make(0), be_t::make(0), queue->push1.read_relaxed().m_h7, be_t::make(0) } }; + queue->pop1 = { { 0, 0, queue->pop1.load().m_h3, 0 } }; + queue->push1 = { { 0, 0, queue->push1.load().m_h7, 0 } }; queue->m_bs[0] = -1; // written as u32 queue->m_bs[1] = -1; queue->m_bs[2] = -1; @@ -910,49 +700,57 @@ void syncLFQueueInit(vm::ptr queue, vm::ptr buffer, u32 siz queue->m_eq_id = 0; } -s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) +s32 cellSyncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { + cellSync.Warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal); + if (!queue) { return CELL_SYNC_ERROR_NULL_POINTER; } + if (size) { if (!buffer) { return CELL_SYNC_ERROR_NULL_POINTER; } + if (size > 0x4000 || size % 16) { return CELL_SYNC_ERROR_INVAL; } } + if (!depth || (depth >> 15) || direction > 3) { return CELL_SYNC_ERROR_INVAL; } - if (queue.addr() % 128 || buffer.addr() % 16) + + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } - // prx: get sdk version of current process, return non-zero result of sys_process_get_sdk_version + // get sdk version of current process s32 sdk_ver; - s32 ret = process_get_sdk_version(process_getpid(), sdk_ver); - if (ret != CELL_OK) + + if (s32 ret = process_get_sdk_version(process_getpid(), sdk_ver)) { return ret; } + if (sdk_ver == -1) { sdk_ver = 0x460000; } - // prx: reserve u32 at 0x2c offset + // reserve `init` u32 old_value; + while (true) { - const auto old = queue->init.read_relaxed(); + const auto old = queue->init.load(); auto init = old; if (old.data()) @@ -961,6 +759,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 { return CELL_SYNC_ERROR_STAT; } + old_value = old; } else @@ -968,6 +767,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 if (sdk_ver > 0x17ffff) { auto data = vm::get_ptr(queue.addr()); + for (u32 i = 0; i < sizeof(CellSyncLFQueue) / sizeof(u64); i++) { if (data[i]) @@ -976,6 +776,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 } } } + init = 1; old_value = 1; } @@ -989,37 +790,31 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 { return CELL_SYNC_ERROR_INVAL; } + if (sdk_ver > 0x17ffff) { - if (queue->m_eaSignal.addr() != eaSignal.addr() || queue->m_direction != direction) + if (queue->m_eaSignal != eaSignal || queue->m_direction != direction) { return CELL_SYNC_ERROR_INVAL; } } + + _mm_mfence(); } else { - // prx: call internal function with same arguments - syncLFQueueInit(queue, buffer, size, depth, direction, eaSignal); + syncLFQueueInitialize(queue, buffer, size, depth, direction, eaSignal); - // prx: sync, zeroize u32 at 0x2c offset queue->init.exchange({}); } - // prx: sync - queue->init.read_sync(); return CELL_OK; } -s32 cellSyncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) +s32 _cellSyncLFQueueGetPushPointer(PPUThread& CPU, vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { - cellSync.Warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal); + cellSync.Warning("_cellSyncLFQueueGetPushPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); - return syncLFQueueInitialize(queue, buffer, size, depth, direction, eaSignal); -} - -s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue) -{ if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU) { return CELL_SYNC_ERROR_PERM; @@ -1033,12 +828,9 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 { while (true) { - if (Emu.IsStopped()) - { - return -1; - } + CHECK_EMU_STATUS; - const auto old = queue->push1.read_sync(); + const auto old = queue->push1.load_sync(); auto push = old; if (var1) @@ -1058,7 +850,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } else { - var2 -= (s32)(u16)queue->pop1.read_relaxed().m_h1; + var2 -= (s32)(u16)queue->pop1.load().m_h1; if (var2 < 0) { var2 += depth * 2; @@ -1066,8 +858,9 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 if (var2 < depth) { - pointer = (s16)push.m_h8; - if (pointer + 1 >= depth * 2) + const s32 _pointer = (s16)push.m_h8; + *pointer = _pointer; + if (_pointer + 1 >= depth * 2) { push.m_h8 = 0; } @@ -1106,46 +899,26 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } } - if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::null, 0)) + if (s32 res = sys_event_queue_receive(CPU, queue->m_eq_id, vm::null, 0)) { - assert(!"sys_event_queue_receive() failed"); + throw EXCEPTION(""); } var1 = 1; } } -s32 _cellSyncLFQueueGetPushPointer(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) -{ - cellSync.Warning("_cellSyncLFQueueGetPushPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); - - s32 pointer_value; - s32 result = syncLFQueueGetPushPointer(queue, pointer_value, isBlocking, useEventQueue); - - *pointer = pointer_value; - - return result; -} - -s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue) -{ - throw __FUNCTION__; -} - -s32 _cellSyncLFQueueGetPushPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) +s32 _cellSyncLFQueueGetPushPointer2(PPUThread& CPU, vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { // arguments copied from _cellSyncLFQueueGetPushPointer cellSync.Todo("_cellSyncLFQueueGetPushPointer2(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); - s32 pointer_value; - s32 result = syncLFQueueGetPushPointer2(queue, pointer_value, isBlocking, useEventQueue); - - *pointer = pointer_value; - - return result; + throw EXCEPTION(""); } -s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal) +s32 _cellSyncLFQueueCompletePushPointer(PPUThread& CPU, vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) { + cellSync.Warning("_cellSyncLFQueueCompletePushPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal); + if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU) { return CELL_SYNC_ERROR_PERM; @@ -1155,10 +928,10 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, while (true) { - const auto old = queue->push2.read_sync(); + const auto old = queue->push2.load_sync(); auto push2 = old; - const auto old2 = queue->push3.read_relaxed(); + const auto old2 = queue->push3.load(); auto push3 = old2; s32 var1 = pointer - (u16)push3.m_h5; @@ -1167,7 +940,7 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, var1 += depth * 2; } - s32 var2 = (s32)(s16)queue->pop1.read_relaxed().m_h4 - (s32)(u16)queue->pop1.read_relaxed().m_h1; + s32 var2 = (s32)(s16)queue->pop1.load().m_h4 - (s32)(u16)queue->pop1.load().m_h1; if (var2 < 0) { var2 += depth * 2; @@ -1184,7 +957,7 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, var9_ = 1 << var9_; } s32 var9 = cntlz32((u32)(u16)~(var9_ | (u16)push3.m_h6)) - 16; // count leading zeros in u16 - + s32 var5 = (s32)(u16)push3.m_h6 | var9_; if (var9 & 0x30) { @@ -1260,12 +1033,12 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, if (exch) { assert(fpSendSignal); - return fpSendSignal((u32)queue->m_eaSignal.addr(), var6); + return fpSendSignal(CPU, (u32)queue->m_eaSignal.addr(), var6); } } else { - pack = queue->push2.read_relaxed().pack; + pack = queue->push2.load().pack; if ((pack & 0x1f) == ((pack >> 10) & 0x1f)) { if (queue->push3.compare_and_swap_test(old2, push3)) @@ -1278,27 +1051,15 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, } } -s32 _cellSyncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) -{ - cellSync.Warning("_cellSyncLFQueueCompletePushPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal); - - return syncLFQueueCompletePushPointer(queue, pointer, fpSendSignal); -} - -s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal) -{ - throw __FUNCTION__; -} - -s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) +s32 _cellSyncLFQueueCompletePushPointer2(PPUThread& CPU, vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) { // arguments copied from _cellSyncLFQueueCompletePushPointer cellSync.Todo("_cellSyncLFQueueCompletePushPointer2(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal); - return syncLFQueueCompletePushPointer2(queue, pointer, fpSendSignal); + throw EXCEPTION(""); } -s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) +s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm::cptr buffer, u32 isBlocking) { // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 cellSync.Warning("_cellSyncLFQueuePushBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); @@ -1307,65 +1068,59 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128 || buffer.addr() % 16) + + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } - s32 position; + vm::stackvar> position(CPU); while (true) { + CHECK_EMU_STATUS; + s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { - res = syncLFQueueGetPushPointer(queue, position, isBlocking, 0); + res = _cellSyncLFQueueGetPushPointer(CPU, queue, position, isBlocking, 0); } else { - res = syncLFQueueGetPushPointer2(queue, position, isBlocking, 0); + res = _cellSyncLFQueueGetPushPointer2(CPU, queue, position, isBlocking, 0); } if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) { - if (res) - { - return res; - } + if (res) return res; + break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - - if (Emu.IsStopped()) - { - cellSync.Warning("_cellSyncLFQueuePushBody(queue=*0x%x) aborted", queue); - return CELL_OK; - } } const s32 depth = queue->m_depth; const s32 size = queue->m_size; - const u32 addr = vm::cast((queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)); - memcpy(vm::get_ptr(addr), buffer.get_ptr(), size); - - s32 res; + const s32 pos = position.value(); + const u32 addr = VM_CAST((u64)((queue->m_buffer.addr() & ~1ull) + size * (pos >= depth ? pos - depth : pos))); + std::memcpy(vm::get_ptr(addr), buffer.get_ptr(), size); if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { - res = syncLFQueueCompletePushPointer(queue, position, nullptr); + return _cellSyncLFQueueCompletePushPointer(CPU, queue, pos, vm::null); } else { - res = syncLFQueueCompletePushPointer2(queue, position, nullptr); + return _cellSyncLFQueueCompletePushPointer2(CPU, queue, pos, vm::null); } - - return res; } -s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue) +s32 _cellSyncLFQueueGetPopPointer(PPUThread& CPU, vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 arg4, u32 useEventQueue) { + cellSync.Warning("_cellSyncLFQueueGetPopPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue, pointer, isBlocking, arg4, useEventQueue); + if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU) { return CELL_SYNC_ERROR_PERM; @@ -1379,12 +1134,9 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i { while (true) { - if (Emu.IsStopped()) - { - return -1; - } + CHECK_EMU_STATUS; - const auto old = queue->pop1.read_sync(); + const auto old = queue->pop1.load_sync(); auto pop = old; if (var1) @@ -1404,7 +1156,7 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i } else { - var2 = (s32)(u16)queue->push1.read_relaxed().m_h5 - var2; + var2 = (s32)(u16)queue->push1.load().m_h5 - var2; if (var2 < 0) { var2 += depth * 2; @@ -1412,8 +1164,9 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i if (var2 > 0) { - pointer = (s16)pop.m_h4; - if (pointer + 1 >= depth * 2) + const s32 _pointer = (s16)pop.m_h4; + *pointer = _pointer; + if (_pointer + 1 >= depth * 2) { pop.m_h4 = 0; } @@ -1452,46 +1205,27 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i } } - if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::null, 0)) + if (s32 res = sys_event_queue_receive(CPU, queue->m_eq_id, vm::null, 0)) { - assert(!"sys_event_queue_receive() failed"); + throw EXCEPTION(""); } var1 = 1; } } -s32 _cellSyncLFQueueGetPopPointer(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 arg4, u32 useEventQueue) -{ - cellSync.Warning("_cellSyncLFQueueGetPopPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue, pointer, isBlocking, arg4, useEventQueue); - - s32 pointer_value; - s32 result = syncLFQueueGetPopPointer(queue, pointer_value, isBlocking, arg4, useEventQueue); - - *pointer = pointer_value; - - return result; -} - -s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue) -{ - throw __FUNCTION__; -} - -s32 _cellSyncLFQueueGetPopPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) +s32 _cellSyncLFQueueGetPopPointer2(PPUThread& CPU, vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { // arguments copied from _cellSyncLFQueueGetPopPointer cellSync.Todo("_cellSyncLFQueueGetPopPointer2(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); - s32 pointer_value; - s32 result = syncLFQueueGetPopPointer2(queue, pointer_value, isBlocking, useEventQueue); - - *pointer = pointer_value; - - return result; + throw EXCEPTION(""); } -s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) +s32 _cellSyncLFQueueCompletePopPointer(PPUThread& CPU, vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) { + // arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer) + cellSync.Warning("_cellSyncLFQueueCompletePopPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull); + if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU) { return CELL_SYNC_ERROR_PERM; @@ -1501,10 +1235,10 @@ s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, c while (true) { - const auto old = queue->pop2.read_sync(); + const auto old = queue->pop2.load_sync(); auto pop2 = old; - const auto old2 = queue->pop3.read_relaxed(); + const auto old2 = queue->pop3.load(); auto pop3 = old2; s32 var1 = pointer - (u16)pop3.m_h1; @@ -1513,7 +1247,7 @@ s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, c var1 += depth * 2; } - s32 var2 = (s32)(s16)queue->push1.read_relaxed().m_h8 - (s32)(u16)queue->push1.read_relaxed().m_h5; + s32 var2 = (s32)(s16)queue->push1.load().m_h8 - (s32)(u16)queue->push1.load().m_h5; if (var2 < 0) { var2 += depth * 2; @@ -1605,12 +1339,12 @@ s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, c if (exch) { assert(fpSendSignal); - return fpSendSignal((u32)queue->m_eaSignal.addr(), var6); + return fpSendSignal(CPU, (u32)queue->m_eaSignal.addr(), var6); } } else { - pack = queue->pop2.read_relaxed().pack; + pack = queue->pop2.load().pack; if ((pack & 0x1f) == ((pack >> 10) & 0x1f)) { if (queue->pop3.compare_and_swap_test(old2, pop3)) @@ -1623,25 +1357,12 @@ s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, c } } -s32 _cellSyncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) -{ - // arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer) - cellSync.Warning("_cellSyncLFQueueCompletePopPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull); - - return syncLFQueueCompletePopPointer(queue, pointer, fpSendSignal, noQueueFull); -} - -s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) -{ - throw __FUNCTION__; -} - -s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) +s32 _cellSyncLFQueueCompletePopPointer2(PPUThread& CPU, vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) { // arguments copied from _cellSyncLFQueueCompletePopPointer cellSync.Todo("_cellSyncLFQueueCompletePopPointer2(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull); - return syncLFQueueCompletePopPointer2(queue, pointer, fpSendSignal, noQueueFull); + throw EXCEPTION(""); } s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) @@ -1653,60 +1374,53 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128 || buffer.addr() % 16) + + if (!queue.aligned() || buffer % 16) { return CELL_SYNC_ERROR_ALIGN; } - s32 position; + vm::stackvar> position(CPU); while (true) { + CHECK_EMU_STATUS; + s32 res; + if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { - res = syncLFQueueGetPopPointer(queue, position, isBlocking, 0, 0); + res = _cellSyncLFQueueGetPopPointer(CPU, queue, position, isBlocking, 0, 0); } else { - res = syncLFQueueGetPopPointer2(queue, position, isBlocking, 0); + res = _cellSyncLFQueueGetPopPointer2(CPU, queue, position, isBlocking, 0); } if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) { - if (res) - { - return res; - } + if (res) return res; + break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - - if (Emu.IsStopped()) - { - cellSync.Warning("_cellSyncLFQueuePopBody(queue=*0x%x) aborted", queue); - return CELL_OK; - } } const s32 depth = queue->m_depth; const s32 size = queue->m_size; - const u32 addr = vm::cast((queue->m_buffer.addr() & ~1) + size * (position >= depth ? position - depth : position)); - memcpy(buffer.get_ptr(), vm::get_ptr(addr), size); - - s32 res; + const s32 pos = position.value(); + const u32 addr = VM_CAST((u64)((queue->m_buffer.addr() & ~1) + size * (pos >= depth ? pos - depth : pos))); + std::memcpy(buffer.get_ptr(), vm::get_ptr(addr), size); if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { - res = syncLFQueueCompletePopPointer(queue, position, nullptr, 0); + return _cellSyncLFQueueCompletePopPointer(CPU, queue, pos, vm::null, 0); } else { - res = syncLFQueueCompletePopPointer2(queue, position, nullptr, 0); + return _cellSyncLFQueueCompletePopPointer2(CPU, queue, pos, vm::null, 0); } - - return res; } s32 cellSyncLFQueueClear(vm::ptr queue) @@ -1717,22 +1431,23 @@ s32 cellSyncLFQueueClear(vm::ptr queue) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } while (true) { - const auto old = queue->pop1.read_sync(); + const auto old = queue->pop1.load_sync(); auto pop = old; - const auto push = queue->push1.read_relaxed(); + const auto push = queue->push1.load(); s32 var1, var2; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { - var1 = var2 = (u16)queue->pop2.read_relaxed().pack; + var1 = var2 = (u16)queue->pop2.load().pack; } else { @@ -1767,17 +1482,18 @@ s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } while (true) { - const auto old = queue->pop3.read_sync(); + const auto old = queue->pop3.load_sync(); - u32 var1 = (u16)queue->pop1.read_relaxed().m_h1; - u32 var2 = (u16)queue->push1.read_relaxed().m_h5; + u32 var1 = (u16)queue->pop1.load().m_h1; + u32 var2 = (u16)queue->push1.load().m_h5; if (queue->pop3.compare_and_swap_test(old, old)) { @@ -1789,6 +1505,7 @@ s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) { *size = var2 - var1 + (u32)queue->m_depth * 2; } + return CELL_OK; } } @@ -1802,16 +1519,18 @@ s32 cellSyncLFQueueDepth(vm::ptr queue, vm::ptr depth) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } *depth = queue->m_depth; + return CELL_OK; } -s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::pptr ppSignal) +s32 _cellSyncLFQueueGetSignalAddress(vm::cptr queue, vm::pptr ppSignal) { cellSync.Log("_cellSyncLFQueueGetSignalAddress(queue=*0x%x, ppSignal=**0x%x)", queue, ppSignal); @@ -1819,7 +1538,8 @@ s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::p { return CELL_SYNC_ERROR_NULL_POINTER; } - if (queue.addr() % 128) + + if (!queue.aligned()) { return CELL_SYNC_ERROR_ALIGN; } @@ -1829,7 +1549,7 @@ s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::p return CELL_OK; } -s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptr direction) +s32 cellSyncLFQueueGetDirection(vm::cptr queue, vm::ptr direction) { cellSync.Log("cellSyncLFQueueGetDirection(queue=*0x%x, direction=*0x%x)", queue, direction); @@ -1837,16 +1557,18 @@ s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptrm_direction; + return CELL_OK; } -s32 cellSyncLFQueueGetEntrySize(vm::ptr queue, vm::ptr entry_size) +s32 cellSyncLFQueueGetEntrySize(vm::cptr queue, vm::ptr entry_size) { cellSync.Log("cellSyncLFQueueGetEntrySize(queue=*0x%x, entry_size=*0x%x)", queue, entry_size); @@ -1854,37 +1576,29 @@ s32 cellSyncLFQueueGetEntrySize(vm::ptr queue, vm::ptrm_size; - return CELL_OK; -} -s32 syncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue) -{ - throw __FUNCTION__; + return CELL_OK; } s32 _cellSyncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue) { cellSync.Todo("_cellSyncLFQueueAttachLv2EventQueue(spus=*0x%x, num=%d, queue=*0x%x)", spus, num, queue); - return syncLFQueueAttachLv2EventQueue(spus, num, queue); -} - -s32 syncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue) -{ - throw __FUNCTION__; + throw EXCEPTION(""); } s32 _cellSyncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue) { cellSync.Todo("_cellSyncLFQueueDetachLv2EventQueue(spus=*0x%x, num=%d, queue=*0x%x)", spus, num, queue); - return syncLFQueueDetachLv2EventQueue(spus, num, queue); + throw EXCEPTION(""); } Module cellSync("cellSync", []() diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.h b/rpcs3/Emu/SysCalls/Modules/cellSync.h index d5c9430752..a4b1cd11b5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -29,69 +31,243 @@ enum CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114, // ??? }; -union CellSyncMutex +struct set_alignment(4) sync_mutex_t // CellSyncMutex sync var { - struct sync_t - { - be_t release_count; // increased when mutex is unlocked - be_t acquire_count; // increased when mutex is locked - }; + be_t rel; + be_t acq; - struct + be_t acquire() { - atomic_be_t release_count; - atomic_be_t acquire_count; - }; + return acq++; + } - atomic_be_t sync_var; + bool try_lock() + { + return acq++ == rel; + } + + void unlock() + { + rel++; + } }; -static_assert(sizeof(CellSyncMutex) == 4, "CellSyncMutex: wrong size"); +using CellSyncMutex = atomic_be_t; -struct CellSyncBarrier +CHECK_SIZE_ALIGN(CellSyncMutex, 4, 4); + +struct set_alignment(4) sync_barrier_t // CellSyncBarrier sync var { - struct data_t + be_t value; + be_t count; + + bool try_notify() { - be_t m_value; - be_t m_count; + // extract m_value (repeat if < 0), increase, compare with second s16, set sign bit if equal, insert it back + s16 v = value; + + if (v < 0) + { + return false; + } + + if (++v == count) + { + v |= 0x8000; + } + + value = v; + + return true; }; - atomic_be_t data; + bool try_wait() + { + // extract m_value (repeat if >= 0), decrease it, set 0 if == 0x8000, insert it back + s16 v = value; + + if (v >= 0) + { + return false; + } + + if (--v == -0x8000) + { + v = 0; + } + + value = v; + + return true; + } }; -static_assert(sizeof(CellSyncBarrier) == 4, "CellSyncBarrier: wrong size"); +using CellSyncBarrier = atomic_be_t; -struct CellSyncRwm +CHECK_SIZE_ALIGN(CellSyncBarrier, 4, 4); + +struct sync_rwm_t // CellSyncRwm sync var { - struct data_t - { - be_t m_readers; - be_t m_writers; - }; + be_t readers; + be_t writers; - atomic_be_t data; - be_t m_size; - vm::bptr m_buffer; + bool try_read_begin() + { + if (writers.data()) + { + return false; + } + + readers++; + return true; + } + + bool try_read_end() + { + if (!readers.data()) + { + return false; + } + + readers--; + return true; + } + + bool try_write_begin() + { + if (writers.data()) + { + return false; + } + + writers = 1; + return true; + } }; -static_assert(sizeof(CellSyncRwm) == 16, "CellSyncRwm: wrong size"); - -struct CellSyncQueue +struct set_alignment(16) CellSyncRwm { - struct data_t - { - be_t m_v1; - be_t m_v2; - }; + atomic_be_t ctrl; // sync var - atomic_be_t data; - be_t m_size; - be_t m_depth; - vm::bptr m_buffer; + be_t size; + vm::bptr buffer; +}; + +CHECK_SIZE_ALIGN(CellSyncRwm, 16, 16); + +struct sync_queue_t // CellSyncQueue sync var +{ + be_t m_v1; + be_t m_v2; + + bool try_push_begin(u32 depth, u32& position) + { + const u32 v1 = m_v1; + const u32 v2 = m_v2; + + // compare 5th byte with zero (break if not zero) + // compare (second u32 (u24) + first byte) with depth (break if greater or equal) + if ((v2 >> 24) || ((v2 & 0xffffff) + (v1 >> 24)) >= depth) + { + return false; + } + + // extract first u32 (u24) (-> position), calculate (position + 1) % depth, insert it back + // insert 1 in 5th u8 + // extract second u32 (u24), increase it, insert it back + position = (v1 & 0xffffff); + m_v1 = (v1 & 0xff000000) | ((position + 1) % depth); + m_v2 = (1 << 24) | ((v2 & 0xffffff) + 1); + + return true; + } + + bool try_pop_begin(u32 depth, u32& position) + { + const u32 v1 = m_v1; + const u32 v2 = m_v2; + + // extract first u8, repeat if not zero + // extract second u32 (u24), subtract 5th u8, compare with zero, repeat if less or equal + if ((v1 >> 24) || ((v2 & 0xffffff) <= (v2 >> 24))) + { + return false; + } + + // insert 1 in first u8 + // extract first u32 (u24), add depth, subtract second u32 (u24), calculate (% depth), save to position + // extract second u32 (u24), decrease it, insert it back + m_v1 = 0x1000000 | v1; + position = ((v1 & 0xffffff) + depth - (v2 & 0xffffff)) % depth; + m_v2 = (v2 & 0xff000000) | ((v2 & 0xffffff) - 1); + + return true; + } + + bool try_peek_begin(u32 depth, u32& position) + { + const u32 v1 = m_v1; + const u32 v2 = m_v2; + + if ((v1 >> 24) || ((v2 & 0xffffff) <= (v2 >> 24))) + { + return false; + } + + m_v1 = 0x1000000 | v1; + position = ((v1 & 0xffffff) + depth - (v2 & 0xffffff)) % depth; + + return true; + } + + bool try_clear_begin_1() + { + if (m_v1 & 0xff000000) + { + return false; + } + + m_v1 |= 0x1000000; + + return true; + } + + bool try_clear_begin_2() + { + if (m_v2 & 0xff000000) + { + return false; + } + + m_v2 |= 0x1000000; + + return true; + } +}; + +struct set_alignment(32) CellSyncQueue +{ + atomic_be_t ctrl; + + be_t size; + be_t depth; + vm::bptr buffer; be_t reserved; + + u32 check_depth() + { + const auto data = ctrl.load(); + + if ((data.m_v1 & 0xffffff) > depth || (data.m_v2 & 0xffffff) > depth) + { + throw EXCEPTION("Invalid queue pointers"); + } + + return depth; + } }; -static_assert(sizeof(CellSyncQueue) == 32, "CellSyncQueue: wrong size"); +CHECK_SIZE_ALIGN(CellSyncQueue, 32, 32); enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection { @@ -101,7 +277,7 @@ enum CellSyncQueueDirection : u32 // CellSyncLFQueueDirection CELL_SYNC_QUEUE_ANY2ANY = 3, // SPU/PPU to SPU/PPU }; -struct CellSyncLFQueue +struct set_alignment(128) CellSyncLFQueue { struct pop1_t { @@ -155,11 +331,11 @@ struct CellSyncLFQueue be_t m_size; // 0x10 be_t m_depth; // 0x14 - vm::bptr m_buffer; // 0x18 + vm::bptr m_buffer; // 0x18 u8 m_bs[4]; // 0x20 - be_t m_direction; // 0x24 + be_t m_direction; // 0x24 CellSyncQueueDirection be_t m_v1; // 0x28 - atomic_be_t init; // 0x2C + atomic_be_t init; // 0x2C atomic_be_t push2; // 0x30 be_t m_hs1[15]; // 0x32 atomic_be_t pop2; // 0x50 @@ -186,24 +362,4 @@ struct CellSyncLFQueue } }; -static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size"); - -s32 syncMutexInitialize(vm::ptr mutex); - -s32 syncBarrierInitialize(vm::ptr barrier, u16 total_count); - -s32 syncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer_size); - -s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth); - -s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal); -s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue); -s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue); -s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal); -s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal); -s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 isBlocking, u32, u32 useEventQueue); -s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue); -s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull); -s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull); -s32 syncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue); -s32 syncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue); +CHECK_SIZE_ALIGN(CellSyncLFQueue, 128, 128); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp index 3b7daeaa0a..b1406ea74e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp @@ -9,7 +9,7 @@ extern Module cellSync2; s32 _cellSync2MutexAttributeInitialize(vm::ptr attr, u32 sdkVersion) { - cellSync2.Warning("_cellSync2MutexAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2MutexAttributeInitialize(attr=*0x%x, sdkVersion=0x%x)", attr, sdkVersion); attr->sdkVersion = sdkVersion; attr->threadTypes = CELL_SYNC2_THREAD_TYPE_PPU_THREAD | CELL_SYNC2_THREAD_TYPE_PPU_FIBER | @@ -22,9 +22,9 @@ s32 _cellSync2MutexAttributeInitialize(vm::ptr attr, u3 return CELL_OK; } -s32 cellSync2MutexEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2MutexEstimateBufferSize(vm::cptr attr, vm::ptr bufferSize) { - cellSync2.Todo("cellSync2MutexEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2MutexEstimateBufferSize(attr=*0x%x, bufferSize=*0x%x)", attr, bufferSize); if (attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; @@ -64,7 +64,7 @@ s32 cellSync2MutexUnlock() s32 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 sdkVersion) { - cellSync2.Warning("_cellSync2CondAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2CondAttributeInitialize(attr=*0x%x, sdkVersion=0x%x)", attr, sdkVersion); attr->sdkVersion = sdkVersion; attr->maxWaiters = 15; @@ -73,9 +73,9 @@ s32 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 return CELL_OK; } -s32 cellSync2CondEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2CondEstimateBufferSize(vm::cptr attr, vm::ptr bufferSize) { - cellSync2.Todo("cellSync2CondEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2CondEstimateBufferSize(attr=*0x%x, bufferSize=*0x%x)", attr, bufferSize); if (attr->maxWaiters == 0 || attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; @@ -115,7 +115,7 @@ s32 cellSync2CondSignalAll() s32 _cellSync2SemaphoreAttributeInitialize(vm::ptr attr, u32 sdkVersion) { - cellSync2.Warning("_cellSync2SemaphoreAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2SemaphoreAttributeInitialize(attr=*0x%x, sdkVersion=0x%x)", attr, sdkVersion); attr->sdkVersion = sdkVersion; attr->threadTypes = CELL_SYNC2_THREAD_TYPE_PPU_THREAD | CELL_SYNC2_THREAD_TYPE_PPU_FIBER | @@ -127,9 +127,9 @@ s32 _cellSync2SemaphoreAttributeInitialize(vm::ptr return CELL_OK; } -s32 cellSync2SemaphoreEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2SemaphoreEstimateBufferSize(vm::cptr attr, vm::ptr bufferSize) { - cellSync2.Todo("cellSync2SemaphoreEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2SemaphoreEstimateBufferSize(attr=*0x%x, bufferSize=*0x%x)", attr, bufferSize); if (attr->maxWaiters == 0 || attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; @@ -175,7 +175,7 @@ s32 cellSync2SemaphoreGetCount() s32 _cellSync2QueueAttributeInitialize(vm::ptr attr, u32 sdkVersion) { - cellSync2.Warning("_cellSync2QueueAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2QueueAttributeInitialize(attr=*0x%x, sdkVersion=0x%x)", attr, sdkVersion); attr->sdkVersion = sdkVersion; attr->threadTypes = CELL_SYNC2_THREAD_TYPE_PPU_THREAD | CELL_SYNC2_THREAD_TYPE_PPU_FIBER | @@ -190,9 +190,9 @@ s32 _cellSync2QueueAttributeInitialize(vm::ptr attr, u3 return CELL_OK; } -s32 cellSync2QueueEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2QueueEstimateBufferSize(vm::cptr attr, vm::ptr bufferSize) { - cellSync2.Todo("cellSync2QueueEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2QueueEstimateBufferSize(attr=*0x%x, bufferSize=*0x%x)", attr, bufferSize); if (attr->elementSize == 0 || attr->elementSize > 16384 || attr->elementSize % 16 || attr->depth == 0 || attr->depth > 4294967292 || attr->maxPushWaiters > 32768 || attr->maxPopWaiters > 32768) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync2.h b/rpcs3/Emu/SysCalls/Modules/cellSync2.h index b18c3d69a2..557562b8d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync2.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync2.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -39,7 +41,7 @@ struct CellSync2MutexAttribute u8 reserved[86]; }; -static_assert(sizeof(CellSync2MutexAttribute) == 128, "Wrong CellSync2MutexAttribute size"); +CHECK_SIZE(CellSync2MutexAttribute, 128); struct CellSync2CondAttribute { @@ -49,7 +51,7 @@ struct CellSync2CondAttribute u8 reserved[90]; }; -static_assert(sizeof(CellSync2CondAttribute) == 128, "Wrong CellSync2CondAttribute size"); +CHECK_SIZE(CellSync2CondAttribute, 128); struct CellSync2SemaphoreAttribute { @@ -60,7 +62,7 @@ struct CellSync2SemaphoreAttribute u8 reserved[88]; }; -static_assert(sizeof(CellSync2SemaphoreAttribute) == 128, "Wrong CellSync2SemaphoreAttribute size"); +CHECK_SIZE(CellSync2SemaphoreAttribute, 128); struct CellSync2QueueAttribute { @@ -74,4 +76,4 @@ struct CellSync2QueueAttribute u8 reserved[76]; }; -static_assert(sizeof(CellSync2QueueAttribute) == 128, "Wrong CellSync2QueueAttribute size"); +CHECK_SIZE(CellSync2QueueAttribute, 128); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp index 2324e48ffc..3a51927a28 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp @@ -4,6 +4,8 @@ #include "Emu/SysCalls/ModuleManager.h" #include "Emu/SysCalls/Modules.h" +namespace vm { using namespace ps3; } + extern Module cellSysmodule; enum diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 74c23480c6..159bfdd3bf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -4,100 +4,110 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Callback.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/DbgCommand.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 "Emu/RSX/GSManager.h" #include "Emu/Audio/AudioManager.h" #include "Emu/FS/VFS.h" #include "cellMsgDialog.h" +#include "cellAudioIn.h" +#include "cellAudioOut.h" #include "cellSysutil.h" extern Module cellSysutil; -int cellSysutilGetSystemParamInt(int id, vm::ptr value) +const char* get_systemparam_id_name(s32 id) { - cellSysutil.Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.addr()); + switch (id) + { + case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: return "ID_DATE_FORMAT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: return "ID_TIME_FORMAT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: return "ID_TIMEZONE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: return "ID_SUMMERTIME"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: return "ID_GAME_PARENTAL_LEVEL"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: return "ID_GAME_PARENTAL_LEVEL0_RESTRICT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: return "ID_CURRENT_USER_HAS_NP_ACCOUNT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: return "ID_CAMERA_PLFREQ"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: return "ID_PAD_RUMBLE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: return "ID_KEYBOARD_TYPE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: return "ID_JAPANESE_KEYBOARD_ENTRY_METHOD"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: return "ID_CHINESE_KEYBOARD_ENTRY_METHOD"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: return "ID_PAD_AUTOOFF"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: return "ID_NICKNAME"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME"; + default: return "???"; + } +} + +s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr value) +{ + cellSysutil.Warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, get_systemparam_id_name(id), value); switch(id) { case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_LANG"); *value = Ini.SysLanguage.GetValue(); break; case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN"); *value = CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CROSS; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT"); *value = CELL_SYSUTIL_DATE_FMT_DDMMYYYY; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT"); *value = CELL_SYSUTIL_TIME_FMT_CLOCK24; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE"); - *value = 3; + *value = 180; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME"); - *value = 1; + *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL"); *value = CELL_SYSUTIL_GAME_PARENTAL_OFF; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT"); *value = CELL_SYSUTIL_GAME_PARENTAL_LEVEL0_RESTRICT_OFF; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ"); *value = CELL_SYSUTIL_CAMERA_PLFREQ_DISABLED; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE"); *value = CELL_SYSUTIL_PAD_RUMBLE_OFF; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: - cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF"); *value = 0; break; @@ -108,21 +118,19 @@ int cellSysutilGetSystemParamInt(int id, vm::ptr value) return CELL_OK; } -int cellSysutilGetSystemParamString(s32 id, vm::ptr buf, u32 bufsize) +s32 cellSysutilGetSystemParamString(s32 id, vm::ptr buf, u32 bufsize) { - cellSysutil.Log("cellSysutilGetSystemParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.addr(), bufsize); + cellSysutil.Log("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, get_systemparam_id_name(id), buf, bufsize); memset(buf.get_ptr(), 0, bufsize); switch(id) { case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: - cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME"); memcpy(buf.get_ptr(), "Unknown", 8); // for example break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: - cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME"); memcpy(buf.get_ptr(), "Unknown", 8); break; @@ -133,9 +141,9 @@ int cellSysutilGetSystemParamString(s32 id, vm::ptr buf, u32 bufsize) return CELL_OK; } -int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr state) +s32 cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr state) { - cellSysutil.Log("cellVideoOutGetState(videoOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", videoOut, deviceIndex, state.addr()); + cellSysutil.Log("cellVideoOutGetState(videoOut=%d, deviceIndex=%d, state=*0x%x)", videoOut, deviceIndex, state); if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND; @@ -159,10 +167,9 @@ int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr resolution) +s32 cellVideoOutGetResolution(u32 resolutionId, vm::ptr resolution) { - cellSysutil.Log("cellVideoOutGetResolution(resolutionId=%d, resolution_addr=0x%x)", - resolutionId, resolution.addr()); + cellSysutil.Log("cellVideoOutGetResolution(resolutionId=%d, resolution=*0x%x)", resolutionId, resolution); u32 num = ResolutionIdToNum(resolutionId); if(!num) @@ -176,8 +183,7 @@ int cellVideoOutGetResolution(u32 resolutionId, vm::ptr s32 cellVideoOutConfigure(u32 videoOut, vm::ptr config, vm::ptr option, u32 waitForEvent) { - cellSysutil.Warning("cellVideoOutConfigure(videoOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=0x%x)", - videoOut, config.addr(), option.addr(), waitForEvent); + cellSysutil.Warning("cellVideoOutConfigure(videoOut=%d, config=*0x%x, option=*0x%x, waitForEvent=0x%x)", videoOut, config, option, waitForEvent); switch(videoOut) { @@ -208,10 +214,9 @@ s32 cellVideoOutConfigure(u32 videoOut, vm::ptr confi return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT; } -int cellVideoOutGetConfiguration(u32 videoOut, vm::ptr config, vm::ptr option) +s32 cellVideoOutGetConfiguration(u32 videoOut, vm::ptr config, vm::ptr option) { - cellSysutil.Warning("cellVideoOutGetConfiguration(videoOut=%d, config_addr=0x%x, option_addr=0x%x)", - videoOut, config.addr(), option.addr()); + cellSysutil.Warning("cellVideoOutGetConfiguration(videoOut=%d, config=*0x%x, option=*0x%x)", videoOut, config, option); if (option) *option = {}; *config = {}; @@ -234,10 +239,9 @@ int cellVideoOutGetConfiguration(u32 videoOut, vm::ptr info) +s32 cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr info) { - cellSysutil.Warning("cellVideoOutGetDeviceInfo(videoOut=%d, deviceIndex=%d, info_addr=0x%x)", - videoOut, deviceIndex, info.addr()); + cellSysutil.Warning("cellVideoOutGetDeviceInfo(videoOut=%d, deviceIndex=%d, info=*0x%x)", videoOut, deviceIndex, info); if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND; @@ -266,7 +270,7 @@ int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr func; vm::ptr arg; - -} g_sys_callback[4]; +} +g_sys_callback[4]; void sysutilSendSystemCommand(u64 status, u64 param) { @@ -311,9 +315,9 @@ void sysutilSendSystemCommand(u64 status, u64 param) { if (cb.func) { - Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32 + Emu.GetCallbackManager().Register([=](CPUThread& CPU) -> s32 { - cb.func(PPU, status, param, cb.arg); + cb.func(static_cast(CPU), status, param, cb.arg); return CELL_OK; }); } @@ -324,36 +328,22 @@ s32 cellSysutilCheckCallback(PPUThread& CPU) { cellSysutil.Log("cellSysutilCheckCallback()"); - s32 res; - u32 count = 0; - - while (Emu.GetCallbackManager().Check(CPU, res)) + while (auto func = Emu.GetCallbackManager().Check()) { - count++; + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - cellSysutil.Warning("cellSysutilCheckCallback() aborted"); - return CELL_OK; - } - - if (res) + if (s32 res = func(CPU)) { return res; } } - if (!count && !g_sys_callback[0].func && !g_sys_callback[1].func && !g_sys_callback[2].func && !g_sys_callback[3].func) - { - LOG_WARNING(TTY, "System warning: no callback registered\n"); - } - return CELL_OK; } s32 cellSysutilRegisterCallback(s32 slot, vm::ptr func, vm::ptr userdata) { - cellSysutil.Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%x, userdata=0x%x)", slot, func.addr(), userdata.addr()); + cellSysutil.Warning("cellSysutilRegisterCallback(slot=%d, func=*0x%x, userdata=*0x%x)", slot, func, userdata); if ((u32)slot > 3) { @@ -379,14 +369,13 @@ s32 cellSysutilUnregisterCallback(s32 slot) return CELL_OK; } -int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) +s32 cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) { - cellSysutil.Warning("cellAudioOutGetSoundAvailability(audioOut=%d, type=%d, fs=0x%x, option=%d)", - audioOut, type, fs, option); + cellSysutil.Warning("cellAudioOutGetSoundAvailability(audioOut=%d, type=%d, fs=0x%x, option=%d)", audioOut, type, fs, option); option = 0; - int available = 8; // should be at least 2 + s32 available = 8; // should be at least 2 switch(fs) { @@ -420,14 +409,13 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; } -int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u32 option) +s32 cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u32 option) { - cellSysutil.Warning("cellAudioOutGetSoundAvailability2(audioOut=%d, type=%d, fs=0x%x, ch=%d, option=%d)", - audioOut, type, fs, ch, option); + cellSysutil.Warning("cellAudioOutGetSoundAvailability2(audioOut=%d, type=%d, fs=0x%x, ch=%d, option=%d)", audioOut, type, fs, ch, option); option = 0; - int available = 8; // should be at least 2 + s32 available = 8; // should be at least 2 switch(fs) { @@ -470,67 +458,66 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; } -int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr state) +s32 cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr state) { - cellSysutil.Warning("cellAudioOutGetState(audioOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", audioOut, deviceIndex, state.addr()); + cellSysutil.Warning("cellAudioOutGetState(audioOut=0x%x, deviceIndex=0x%x, state=*0x%x)", audioOut, deviceIndex, state); *state = {}; switch(audioOut) { case CELL_AUDIO_OUT_PRIMARY: - state->state = Emu.GetAudioManager().GetState(); - state->encoder = Emu.GetAudioManager().GetInfo().mode.encoder; - state->downMixer = Emu.GetAudioManager().GetInfo().mode.downMixer; - state->soundMode.type = Emu.GetAudioManager().GetInfo().mode.type; - state->soundMode.channel = Emu.GetAudioManager().GetInfo().mode.channel; - state->soundMode.fs = Emu.GetAudioManager().GetInfo().mode.fs; + state->state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED; + state->encoder = CELL_AUDIO_OUT_CODING_TYPE_LPCM; + state->downMixer = CELL_AUDIO_OUT_DOWNMIXER_NONE; + state->soundMode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM; + state->soundMode.channel = CELL_AUDIO_OUT_CHNUM_8; + state->soundMode.fs = CELL_AUDIO_OUT_FS_48KHZ; state->soundMode.reserved = 0; - state->soundMode.layout = Emu.GetAudioManager().GetInfo().mode.layout; + state->soundMode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy; - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; case CELL_AUDIO_OUT_SECONDARY: state->state = CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED; - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; } return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; } -int cellAudioOutConfigure(u32 audioOut, vm::ptr config, vm::ptr option, u32 waitForEvent) +s32 cellAudioOutConfigure(u32 audioOut, vm::ptr config, vm::ptr option, u32 waitForEvent) { - cellSysutil.Warning("cellAudioOutConfigure(audioOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=%d)", - audioOut, config.addr(), option.addr(), waitForEvent); + cellSysutil.Warning("cellAudioOutConfigure(audioOut=%d, config=*0x%x, option=*0x%x, waitForEvent=%d)", audioOut, config, option, waitForEvent); switch(audioOut) { case CELL_AUDIO_OUT_PRIMARY: if (config->channel) { - Emu.GetAudioManager().GetInfo().mode.channel = config->channel; + //Emu.GetAudioManager().GetInfo().mode.channel = config->channel; } - Emu.GetAudioManager().GetInfo().mode.encoder = config->encoder; + //Emu.GetAudioManager().GetInfo().mode.encoder = config->encoder; if(config->downMixer) { - Emu.GetAudioManager().GetInfo().mode.downMixer = config->downMixer; + //Emu.GetAudioManager().GetInfo().mode.downMixer = config->downMixer; } - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; case CELL_AUDIO_OUT_SECONDARY: - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; } return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; } -int cellAudioOutGetConfiguration(u32 audioOut, vm::ptr config, vm::ptr option) +s32 cellAudioOutGetConfiguration(u32 audioOut, vm::ptr config, vm::ptr option) { - cellSysutil.Warning("cellAudioOutGetConfiguration(audioOut=%d, config_addr=0x%x, option_addr=0x%x)", audioOut, config.addr(), option.addr()); + cellSysutil.Warning("cellAudioOutGetConfiguration(audioOut=%d, config=*0x%x, option=*0x%x)", audioOut, config, option); if (option) *option = {}; *config = {}; @@ -538,21 +525,21 @@ int cellAudioOutGetConfiguration(u32 audioOut, vm::ptrchannel = Emu.GetAudioManager().GetInfo().mode.channel; - config->encoder = Emu.GetAudioManager().GetInfo().mode.encoder; - config->downMixer = Emu.GetAudioManager().GetInfo().mode.downMixer; + config->channel = CELL_AUDIO_OUT_CHNUM_8; + config->encoder = CELL_AUDIO_OUT_CODING_TYPE_LPCM; + config->downMixer = CELL_AUDIO_OUT_DOWNMIXER_NONE; - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; case CELL_AUDIO_OUT_SECONDARY: - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; } return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; } -int cellAudioOutGetNumberOfDevice(u32 audioOut) +s32 cellAudioOutGetNumberOfDevice(u32 audioOut) { cellSysutil.Warning("cellAudioOutGetNumberOfDevice(audioOut=%d)", audioOut); @@ -565,9 +552,9 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut) return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; } -int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr info) +s32 cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr info) { - cellSysutil.Todo("cellAudioOutGetDeviceInfo(audioOut=%d, deviceIndex=%d, info_addr=0x%x)", audioOut, deviceIndex, info.addr()); + cellSysutil.Todo("cellAudioOutGetDeviceInfo(audioOut=%d, deviceIndex=%d, info=*0x%x)", audioOut, deviceIndex, info); if(deviceIndex) return CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND; @@ -580,12 +567,12 @@ int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptravailableModes[0].fs = CELL_AUDIO_OUT_FS_48KHZ; info->availableModes[0].layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy; - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; } -int cellAudioOutSetCopyControl(u32 audioOut, u32 control) +s32 cellAudioOutSetCopyControl(u32 audioOut, u32 control) { - cellSysutil.Warning("cellAudioOutSetCopyControl(audioOut=%d,control=%d)",audioOut,control); + cellSysutil.Warning("cellAudioOutSetCopyControl(audioOut=%d, control=%d)", audioOut, control); switch(audioOut) { @@ -606,74 +593,32 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control) default: return CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER; } - return CELL_AUDIO_OUT_SUCCEEDED; + return CELL_OK; } - - - -typedef struct{ +struct CellSysCacheParam +{ char cacheId[CELL_SYSCACHE_ID_SIZE]; char getCachePath[CELL_SYSCACHE_PATH_MAX]; vm::ptr reserved; -} CellSysCacheParam; +}; - -//class WxDirDeleteTraverser : public wxDirTraverser -//{ -//public: -// virtual wxDirTraverseResult OnFile(const wxString& filename) -// { -// if (!wxRemoveFile(filename)){ -// cellSysutil.Error("Couldn't delete File: %s", fmt::ToUTF8(filename).c_str()); -// } -// return wxDIR_CONTINUE; -// } -// virtual wxDirTraverseResult OnDir(const wxString& dirname) -// { -// wxDir dir(dirname); -// dir.Traverse(*this); -// if (!wxRmDir(dirname)){ -// //this get triggered a few times while clearing folders -// //but if this gets reimplented we should probably warn -// //if directories can't be removed -// } -// return wxDIR_CONTINUE; -// } -//}; - -int cellSysCacheClear(void) +s32 cellSysCacheClear(void) { - cellSysutil.Warning("cellSysCacheClear()"); + cellSysutil.Todo("cellSysCacheClear()"); //if some software expects CELL_SYSCACHE_ERROR_NOTMOUNTED we need to check whether //it was mounted before, for that we would need to save the state which I don't know //where to put std::string localPath; Emu.GetVFS().GetDevice(std::string("/dev_hdd1/cache/"), localPath); - - //TODO: implement - //if (rIsDir(localPath)){ - // WxDirDeleteTraverser deleter; - // wxString f = wxFindFirstFile(fmt::FromUTF8(localPath+"\\*"),wxDIR); - // while (!f.empty()) - // { - // wxDir dir(f); - // dir.Traverse(deleter); - // f = wxFindNextFile(); - // } - // return CELL_SYSCACHE_RET_OK_CLEARED; - //} - //else{ - // return CELL_SYSCACHE_ERROR_ACCESS_ERROR; - //} return CELL_SYSCACHE_RET_OK_CLEARED; } -int cellSysCacheMount(vm::ptr param) +s32 cellSysCacheMount(vm::ptr param) { - cellSysutil.Warning("cellSysCacheMount(param_addr=0x%x)", param.addr()); + cellSysutil.Warning("cellSysCacheMount(param=*0x%x)", param); //TODO: implement char id[CELL_SYSCACHE_ID_SIZE]; @@ -685,55 +630,55 @@ int cellSysCacheMount(vm::ptr param) return CELL_SYSCACHE_RET_OK_RELAYED; } -bool bgm_playback_enabled = true; +bool g_bgm_playback_enabled = true; -int cellSysutilEnableBgmPlayback() +s32 cellSysutilEnableBgmPlayback() { cellSysutil.Warning("cellSysutilEnableBgmPlayback()"); // TODO - bgm_playback_enabled = true; + g_bgm_playback_enabled = true; return CELL_OK; } -int cellSysutilEnableBgmPlaybackEx(vm::ptr param) +s32 cellSysutilEnableBgmPlaybackEx(vm::ptr param) { - cellSysutil.Warning("cellSysutilEnableBgmPlaybackEx(param_addr=0x%x)", param.addr()); + cellSysutil.Warning("cellSysutilEnableBgmPlaybackEx(param=*0x%x)", param); // TODO - bgm_playback_enabled = true; + g_bgm_playback_enabled = true; return CELL_OK; } -int cellSysutilDisableBgmPlayback() +s32 cellSysutilDisableBgmPlayback() { cellSysutil.Warning("cellSysutilDisableBgmPlayback()"); // TODO - bgm_playback_enabled = false; + g_bgm_playback_enabled = false; return CELL_OK; } -int cellSysutilDisableBgmPlaybackEx(vm::ptr param) +s32 cellSysutilDisableBgmPlaybackEx(vm::ptr param) { - cellSysutil.Warning("cellSysutilDisableBgmPlaybackEx(param_addr=0x%x)", param.addr()); + cellSysutil.Warning("cellSysutilDisableBgmPlaybackEx(param=*0x%x)", param); // TODO - bgm_playback_enabled = false; + g_bgm_playback_enabled = false; return CELL_OK; } -int cellSysutilGetBgmPlaybackStatus(vm::ptr status) +s32 cellSysutilGetBgmPlaybackStatus(vm::ptr status) { - cellSysutil.Log("cellSysutilGetBgmPlaybackStatus(status_addr=0x%x)", status.addr()); + cellSysutil.Log("cellSysutilGetBgmPlaybackStatus(status=*0x%x)", status); // TODO status->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP; - status->enableState = bgm_playback_enabled ? CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE : CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE; + status->enableState = g_bgm_playback_enabled ? CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE : CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE; status->currentFadeRatio = 0; // current volume ratio (0%) memset(status->contentId, 0, sizeof(status->contentId)); memset(status->reserved, 0, sizeof(status->reserved)); @@ -741,9 +686,9 @@ int cellSysutilGetBgmPlaybackStatus(vm::ptr status return CELL_OK; } -int cellSysutilGetBgmPlaybackStatus2(vm::ptr status2) +s32 cellSysutilGetBgmPlaybackStatus2(vm::ptr status2) { - cellSysutil.Log("cellSysutilGetBgmPlaybackStatus2(status2_addr=0x%x)", status2.addr()); + cellSysutil.Log("cellSysutilGetBgmPlaybackStatus2(status2=*0x%x)", status2); // TODO status2->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP; @@ -752,9 +697,9 @@ int cellSysutilGetBgmPlaybackStatus2(vm::ptr stat return CELL_OK; } -int cellWebBrowserEstimate2(const vm::ptr config, vm::ptr memSize) +s32 cellWebBrowserEstimate2(vm::cptr config, vm::ptr memSize) { - cellSysutil.Warning("cellWebBrowserEstimate2(config_addr=0x%x, memSize_addr=0x%x)", config.addr(), memSize.addr()); + cellSysutil.Warning("cellWebBrowserEstimate2(config=*0x%x, memSize=*0x%x)", config, memSize); // TODO: When cellWebBrowser stuff is implemented, change this to some real // needed memory buffer size. diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h index 2c8fd2245c..8cfdbfeef6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum { CELL_SYSUTIL_ERROR_TYPE = 0x8002b101, @@ -32,8 +34,8 @@ enum CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF = 0x0156, // Strings - CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME = 0x113, - CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME = 0x131, + CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME = 0x0113, + CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME = 0x0131, }; enum @@ -78,7 +80,7 @@ enum CELL_SYSUTIL_SYSCHAT_VOICE_STREAMING_PAUSED = 0x0164, }; -typedef void(CellSysutilCallback)(u64 status, u64 param, vm::ptr userdata); +using CellSysutilCallback = func_def userdata)>; void sysutilSendSystemCommand(u64 status, u64 param); @@ -152,22 +154,20 @@ enum CELL_SYSCACHE_ERROR_NOTMOUNTED = 0x8002bc04, // We don't really need to simulate the mounting, so this is probably useless }; -typedef s32 CellWebBrowserId; -typedef vm::ptr CellWebBrowserClientSession; -typedef void(CellWebBrowserCallback)(s32 cb_type, CellWebBrowserClientSession, vm::ptr usrdata); -typedef void(CellWebComponentCallback)(CellWebBrowserId, s32 cb_type, CellWebBrowserClientSession, vm::ptr usrdata); -typedef void(CellWebBrowserSystemCallback)(s32 cb_type, vm::ptr usrdata); +using CellWebBrowserCallback = func_def client_session, vm::ptr usrdata)>; +using CellWebComponentCallback = func_def client_session, vm::ptr usrdata)>; +using CellWebBrowserSystemCallback = func_def usrdata)>; -typedef void(CellWebBrowserMIMETypeCallback)(vm::ptr mimetype, vm::ptr url, vm::ptr usrdata); -typedef void(CellWebBrowserErrorCallback)(s32 err_type, vm::ptr usrdata); -typedef void(CellWebBrowserStatusCallback)(s32 err_type, vm::ptr usrdata); -typedef void(CellWebBrowserNotify)(vm::ptr message, vm::ptr usrdata); -typedef void(CellWebBrowserUsrdata)(vm::ptr usrdata); +using CellWebBrowserMIMETypeCallback = func_def mimetype, vm::cptr url, vm::ptr usrdata)>; +using CellWebBrowserErrorCallback = func_def usrdata)>; +using CellWebBrowserStatusCallback = func_def usrdata)>; +using CellWebBrowserNotify = func_def message, vm::ptr usrdata)>; +using CellWebBrowserUsrdata = func_def usrdata)>; struct CellWebBrowserMimeSet { - const vm::bptr type; - const vm::bptr directory; + vm::bcptr type; + vm::bcptr directory; }; struct CellWebBrowserPos @@ -192,7 +192,7 @@ struct CellWebBrowserConfig { be_t version; be_t heap_size; - vm::bptr mimesets; + vm::bcptr mimesets; be_t mimeset_num; be_t functions; be_t tab_count; @@ -218,3 +218,39 @@ struct CellWebBrowserConfig2 be_t resolution_factor; be_t magic_number_; }; + +enum CellSysutilBgmPlaybackStatusState +{ + CELL_SYSUTIL_BGMPLAYBACK_STATUS_PLAY = 0, + CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP = 1 +}; + +enum CellSysutilBgmPlaybackStatusEnabled +{ + CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE = 0, + CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE = 1 +}; + +struct CellSysutilBgmPlaybackStatus +{ + u8 playerState; + u8 enableState; + char contentId[16]; + u8 currentFadeRatio; + char reserved[13]; +}; + +struct CellSysutilBgmPlaybackStatus2 +{ + u8 playerState; + char reserved[7]; +}; + +struct CellSysutilBgmPlaybackExtraParam +{ + be_t systemBgmFadeInTime; + be_t systemBgmFadeOutTime; + be_t gameBgmFadeInTime; + be_t gameBgmFadeOutTime; + char reserved[8]; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp index 915a469dbd..396c6a6093 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp @@ -2,6 +2,8 @@ #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" +namespace vm { using namespace ps3; } + extern Module cellSysutilAp; // Return Codes @@ -23,13 +25,13 @@ s32 cellSysutilApGetRequiredMemSize() return 1024*1024; // Return 1 MB as required size } -int cellSysutilApOn() +s32 cellSysutilApOn() { UNIMPLEMENTED_FUNC(cellSysutilAp); return CELL_OK; } -int cellSysutilApOff() +s32 cellSysutilApOff() { UNIMPLEMENTED_FUNC(cellSysutilAp); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellUsbd.h b/rpcs3/Emu/SysCalls/Modules/cellUsbd.h index 6259bd9978..56f08c0210 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUsbd.h +++ b/rpcs3/Emu/SysCalls/Modules/cellUsbd.h @@ -1,3 +1,7 @@ +#pragma once + +namespace vm { using namespace ps3; } + // Return Codes enum { @@ -36,4 +40,4 @@ enum USBD_HC_CC_XACT = 0x2, USBD_HC_CC_BABBLE = 0x4, USBD_HC_CC_DATABUF = 0x8, -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp index dd67c39aa5..6a741b7c98 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp @@ -9,9 +9,9 @@ extern Module cellUserInfo; -int cellUserInfoGetStat(u32 id, vm::ptr stat) +s32 cellUserInfoGetStat(u32 id, vm::ptr stat) { - cellUserInfo.Warning("cellUserInfoGetStat(id=%d, stat_addr=0x%x)", id, stat.addr()); + cellUserInfo.Warning("cellUserInfoGetStat(id=%d, stat=*0x%x)", id, stat); if (id > CELL_USERINFO_USER_MAX) return CELL_USERINFO_ERROR_NOUSER; @@ -37,28 +37,27 @@ int cellUserInfoGetStat(u32 id, vm::ptr stat) return CELL_OK; } -int cellUserInfoSelectUser_ListType() +s32 cellUserInfoSelectUser_ListType() { UNIMPLEMENTED_FUNC(cellUserInfo); return CELL_OK; } -int cellUserInfoSelectUser_SetList() +s32 cellUserInfoSelectUser_SetList() { UNIMPLEMENTED_FUNC(cellUserInfo); return CELL_OK; } -int cellUserInfoEnableOverlay() +s32 cellUserInfoEnableOverlay() { UNIMPLEMENTED_FUNC(cellUserInfo); return CELL_OK; } -int cellUserInfoGetList(vm::ptr listNum, vm::ptr listBuf, vm::ptr currentUserId) +s32 cellUserInfoGetList(vm::ptr listNum, vm::ptr listBuf, vm::ptr currentUserId) { - cellUserInfo.Warning("cellUserInfoGetList(listNum_addr=0x%x, listBuf_addr=0x%x, currentUserId_addr=0x%x)", - listNum.addr(), listBuf.addr(), currentUserId.addr()); + cellUserInfo.Warning("cellUserInfoGetList(listNum=*0x%x, listBuf=*0x%x, currentUserId=*0x%x)", listNum, listBuf, currentUserId); // If only listNum is NULL, an error will be returned if (listBuf && !listNum) diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h index 5edd525cb6..33192f4f2b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index 8315babc45..b28068ee79 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -3,7 +3,6 @@ #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" std::mutex g_mutex_avcodec_open2; @@ -15,7 +14,6 @@ extern "C" #include "libswscale/swscale.h" } -#include "Emu/CPU/CPUThreadManager.h" #include "cellPamf.h" #include "cellVdec.h" @@ -23,7 +21,7 @@ extern Module cellVdec; #define VDEC_ERROR(...) { cellVdec.Error(__VA_ARGS__); Emu.Pause(); return; } // only for decoder thread -VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, vm::ptr func, u32 arg) +VideoDecoder::VideoDecoder(s32 type, u32 profile, u32 addr, u32 size, vm::ptr func, u32 arg) : type(type) , profile(profile) , memAddr(addr) @@ -39,7 +37,6 @@ VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 si , codec(nullptr) , input_format(nullptr) , ctx(nullptr) - , vdecCb(nullptr) { av_register_all(); avcodec_register_all(); @@ -189,7 +186,7 @@ next: } } -u32 vdecQueryAttr(CellVdecCodecType type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr attr) +u32 vdecQueryAttr(s32 type, u32 profile, u32 spec_addr /* may be 0 */, vm::ptr attr) { switch (type) // TODO: check profile levels { @@ -215,16 +212,10 @@ void vdecOpen(u32 vdec_id) // TODO: call from the constructor vdec.id = vdec_id; - vdec.vdecCb = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_PPU).get()); - vdec.vdecCb->SetName(fmt::format("VideoDecoder[0x%x] Callback", vdec_id)); - vdec.vdecCb->SetEntry(0); - vdec.vdecCb->SetPrio(1001); - vdec.vdecCb->SetStackSize(0x10000); - vdec.vdecCb->InitStack(); - vdec.vdecCb->InitRegs(); - vdec.vdecCb->DoRun(); - - thread_t t(fmt::format("VideoDecoder[0x%x] Thread", vdec_id), [sptr]() + vdec.vdecCb = Emu.GetIdManager().make_ptr(fmt::format("VideoDecoder[0x%x] Thread", vdec_id)); + vdec.vdecCb->prio = 1001; + vdec.vdecCb->stack_size = 0x10000; + vdec.vdecCb->custom_task = [sptr](PPUThread& CPU) { VideoDecoder& vdec = *sptr; VdecTask& task = vdec.task; @@ -547,24 +538,27 @@ void vdecOpen(u32 vdec_id) // TODO: call from the constructor } vdec.is_finished = true; - }); + }; + + vdec.vdecCb->Run(); + vdec.vdecCb->Exec(); } -s32 cellVdecQueryAttr(vm::ptr type, vm::ptr attr) +s32 cellVdecQueryAttr(vm::cptr type, vm::ptr attr) { cellVdec.Warning("cellVdecQueryAttr(type=*0x%x, attr=*0x%x)", type, attr); return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr); } -s32 cellVdecQueryAttrEx(vm::ptr type, vm::ptr attr) +s32 cellVdecQueryAttrEx(vm::cptr type, vm::ptr attr) { cellVdec.Warning("cellVdecQueryAttrEx(type=*0x%x, attr=*0x%x)", type, attr); return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr); } -s32 cellVdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellVdecOpen(vm::cptr type, vm::cptr res, vm::cptr cb, vm::ptr handle) { cellVdec.Warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); @@ -573,7 +567,7 @@ s32 cellVdecOpen(vm::ptr type, vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellVdecOpenEx(vm::cptr type, vm::cptr res, vm::cptr cb, vm::ptr handle) { cellVdec.Warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); @@ -598,15 +592,12 @@ s32 cellVdecClose(u32 handle) while (!vdec->is_finished) { - if (Emu.IsStopped()) - { - cellVdec.Warning("cellVdecClose(%d) aborted", handle); - break; - } + CHECK_EMU_STATUS; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - if (vdec->vdecCb) Emu.GetCPU().RemoveThread(vdec->vdecCb->GetId()); + Emu.GetIdManager().remove(vdec->vdecCb->GetId()); Emu.GetIdManager().remove(handle); return CELL_OK; } @@ -641,7 +632,7 @@ s32 cellVdecEndSeq(u32 handle) return CELL_OK; } -s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr auInfo) +s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::cptr auInfo) { cellVdec.Log("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, mode, auInfo); @@ -654,7 +645,7 @@ s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr format, vm::ptr outBuff) +s32 cellVdecGetPicture(u32 handle, vm::cptr format, vm::ptr outBuff) { cellVdec.Log("cellVdecGetPicture(handle=0x%x, format=*0x%x, outBuff=*0x%x)", handle, format, outBuff); @@ -720,13 +711,13 @@ s32 cellVdecGetPicture(u32 handle, vm::ptr format, vm:: default: { - cellVdec.Fatal("cellVdecGetPicture: unknown formatType(%d)", type); + throw EXCEPTION("Unknown formatType(%d)", type); } } if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709) { - cellVdec.Fatal("cellVdecGetPicture: unknown colorMatrixType(%d)", format->colorMatrixType); + throw EXCEPTION("Unknown colorMatrixType(%d)", format->colorMatrixType); } if (alpha_plane) @@ -742,7 +733,7 @@ s32 cellVdecGetPicture(u32 handle, vm::ptr format, vm:: default: { - cellVdec.Fatal("cellVdecGetPicture: unknown pix_fmt(%d)", f); + throw EXCEPTION("Unknown pix_fmt(%d)", f); } } @@ -778,13 +769,13 @@ s32 cellVdecGetPicture(u32 handle, vm::ptr format, vm:: return CELL_OK; } -s32 _nid_a21aa896(PPUThread& CPU, u32 handle, vm::ptr format2, vm::ptr outBuff, u32 arg4) +s32 _nid_a21aa896(PPUThread& CPU, u32 handle, vm::cptr format2, vm::ptr outBuff, u32 arg4) { cellVdec.Warning("_nid_a21aa896(handle=0x%x, format2=*0x%x, outBuff=*0x%x, arg4=*0x%x)", handle, format2, outBuff, arg4); if (arg4 || format2->unk0 || format2->unk1) { - cellVdec.Fatal("_nid_a21aa896(): unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format2->unk0, format2->unk1); + throw EXCEPTION("Unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format2->unk0, format2->unk1); } vm::stackvar format(CPU); @@ -827,23 +818,23 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr picItem) info->startAddr = 0x00000123; // invalid value (no address for picture) info->size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128); info->auNum = 1; - info->auPts[0].lower = (u32)vf.pts; - info->auPts[0].upper = vf.pts >> 32; + info->auPts[0].lower = (u32)(vf.pts); + info->auPts[0].upper = (u32)(vf.pts >> 32); info->auPts[1].lower = (u32)CODEC_TS_INVALID; info->auPts[1].upper = (u32)CODEC_TS_INVALID; - info->auDts[0].lower = (u32)vf.dts; - info->auDts[0].upper = vf.dts >> 32; + info->auDts[0].lower = (u32)(vf.dts); + info->auDts[0].upper = (u32)(vf.dts >> 32); info->auDts[1].lower = (u32)CODEC_TS_INVALID; info->auDts[1].upper = (u32)CODEC_TS_INVALID; info->auUserData[0] = vf.userdata; info->auUserData[1] = 0; info->status = CELL_OK; info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL; - info->picInfo_addr = info.addr() + sizeof(CellVdecPicItem); + info->picInfo_addr = info.addr() + sizeof32(CellVdecPicItem); if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC) { - auto avc = vm::ptr::make(info.addr() + sizeof(CellVdecPicItem)); + auto avc = vm::ptr::make(info.addr() + sizeof32(CellVdecPicItem)); avc->horizontalSize = frame.width; avc->verticalSize = frame.height; @@ -897,7 +888,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr picItem) } else if (vdec->type == CELL_VDEC_CODEC_TYPE_DIVX) { - auto dvx = vm::ptr::make(info.addr() + sizeof(CellVdecPicItem)); + auto dvx = vm::ptr::make(info.addr() + sizeof32(CellVdecPicItem)); switch (frame.pict_type) { @@ -931,9 +922,9 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr picItem) } else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG2) { - auto mp2 = vm::ptr::make(info.addr() + sizeof(CellVdecPicItem)); + auto mp2 = vm::ptr::make(info.addr() + sizeof32(CellVdecPicItem)); - cellVdec.Fatal("cellVdecGetPicItem(MPEG2)"); + throw EXCEPTION("MPEG2"); } *picItem = info; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 66de0968fe..8afb573ffa 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -12,15 +14,15 @@ enum CELL_VDEC_ERROR_FATAL = 0x80610180, }; -enum CellVdecCodecType : u32 +enum CellVdecCodecType : s32 { - CELL_VDEC_CODEC_TYPE_MPEG2 = 0x00000000, - CELL_VDEC_CODEC_TYPE_AVC = 0x00000001, - CELL_VDEC_CODEC_TYPE_DIVX = 0x00000005, + CELL_VDEC_CODEC_TYPE_MPEG2 = 0, + CELL_VDEC_CODEC_TYPE_AVC = 1, + CELL_VDEC_CODEC_TYPE_DIVX = 5, }; // Callback Messages -enum CellVdecMsgType : u32 +enum CellVdecMsgType : s32 { CELL_VDEC_MSG_TYPE_AUDONE, // decoding finished CELL_VDEC_MSG_TYPE_PICOUT, // picture done @@ -29,7 +31,7 @@ enum CellVdecMsgType : u32 }; // Decoder Operation Mode -enum CellVdecDecodeMode : u32 +enum CellVdecDecodeMode : s32 { CELL_VDEC_DEC_MODE_NORMAL, CELL_VDEC_DEC_MODE_B_SKIP, @@ -37,7 +39,7 @@ enum CellVdecDecodeMode : u32 }; // Output Picture Format Type -enum CellVdecPicFormatType : u32 +enum CellVdecPicFormatType : s32 { CELL_VDEC_PICFMT_ARGB32_ILV, CELL_VDEC_PICFMT_RGBA32_ILV, @@ -46,13 +48,13 @@ enum CellVdecPicFormatType : u32 }; // Output Color Matrix Coef -enum CellVdecColorMatrixType : u32 +enum CellVdecColorMatrixType : s32 { CELL_VDEC_COLOR_MATRIX_TYPE_BT601, CELL_VDEC_COLOR_MATRIX_TYPE_BT709, }; -enum CellVdecPicAttr : u32 +enum CellVdecPicAttr : s32 { CELL_VDEC_PICITEM_ATTR_NORMAL, CELL_VDEC_PICITEM_ATTR_SKIPPED, @@ -74,14 +76,14 @@ enum CellVdecFrameRate : u8 // Codec Type Information struct CellVdecType { - be_t codecType; + be_t codecType; // CellVdecCodecType be_t profileLevel; }; // Extended Codec Type Information struct CellVdecTypeEx { - be_t codecType; + be_t codecType; // CellVdecCodecType be_t profileLevel; be_t codecSpecificInfo_addr; }; @@ -126,9 +128,6 @@ struct CellVdecResourceEx be_t spursResource_addr; }; -// Presentation Time Stamp -typedef CellCodecTimeStamp CellVdecTimeStamp; - // Access Unit Information struct CellVdecAuInfo { @@ -143,7 +142,7 @@ struct CellVdecAuInfo // Output Picture Information struct CellVdecPicItem { - be_t codecType; + be_t codecType; // CellVdecCodecType be_t startAddr; be_t size; u8 auNum; @@ -151,28 +150,28 @@ struct CellVdecPicItem CellCodecTimeStamp auDts[2]; be_t auUserData[2]; be_t status; - be_t attr; + be_t attr; // CellVdecPicAttr be_t picInfo_addr; }; // Output Picture Format struct CellVdecPicFormat { - be_t formatType; - be_t colorMatrixType; + be_t formatType; // CellVdecPicFormatType + be_t colorMatrixType; // CellVdecColorMatrixType u8 alpha; }; struct CellVdecPicFormat2 { - be_t formatType; - be_t colorMatrixType; + be_t formatType; // CellVdecPicFormatType + be_t colorMatrixType; // CellVdecColorMatrixType be_t unk0; u8 alpha; be_t unk1; }; -typedef u32(CellVdecCbMsg)(u32 handle, CellVdecMsgType msgType, s32 msgData, u32 cbArg); +using CellVdecCbMsg = func_def; // Callback Function Information struct CellVdecCb @@ -468,7 +467,7 @@ struct CellVdecDivxInfo DIVX_transferCharacteristics transferCharacteristics; DIVX_matrixCoefficients matrixCoefficients; DIVX_pictureStruct pictureStruct; - be_t frameRateCode; + be_t frameRateCode; // DIVX_frameRateCode }; enum MPEG2_level @@ -638,8 +637,8 @@ struct CellVdecMpeg2Info u8 number_of_frame_centre_offsets[2]; be_t frame_centre_horizontal_offset[2][3]; be_t frame_centre_vertical_offset[2][3]; - be_t headerPresentFlags; - be_t headerRetentionFlags; + be_t headerPresentFlags; // MPEG2_headerFlags + be_t headerRetentionFlags; // MPEG2_headerFlags bool mpeg1Flag; u8 ccDataLength[2]; u8 ccData[2][128]; @@ -717,7 +716,7 @@ public: squeue_t frames; - const CellVdecCodecType type; + const s32 type; const u32 profile; const u32 memAddr; const u32 memSize; @@ -730,9 +729,9 @@ public: u32 frc_set; // frame rate overwriting AVRational rfr, afr; - PPUThread* vdecCb; + std::shared_ptr vdecCb; - VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, vm::ptr func, u32 arg); + VideoDecoder(s32 type, u32 profile, u32 addr, u32 size, vm::ptr func, u32 arg); ~VideoDecoder(); }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp b/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp index e9ed1f9da1..3ffa9c52ad 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVoice.cpp @@ -3,6 +3,8 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +namespace vm { using namespace ps3; } + extern Module cellVoice; // Error Codes diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp index dab1201638..a4a109f178 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp @@ -13,7 +13,7 @@ extern "C" extern Module cellVpost; -s32 cellVpostQueryAttr(vm::ptr cfgParam, vm::ptr attr) +s32 cellVpostQueryAttr(vm::cptr cfgParam, vm::ptr attr) { cellVpost.Warning("cellVpostQueryAttr(cfgParam=*0x%x, attr=*0x%x)", cfgParam, attr); @@ -27,7 +27,7 @@ s32 cellVpostQueryAttr(vm::ptr cfgParam, vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) +s32 cellVpostOpen(vm::cptr cfgParam, vm::cptr resource, vm::ptr handle) { cellVpost.Warning("cellVpostOpen(cfgParam=*0x%x, resource=*0x%x, handle=*0x%x)", cfgParam, resource, handle); @@ -36,7 +36,7 @@ s32 cellVpostOpen(vm::ptr cfgParam, vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) +s32 cellVpostOpenEx(vm::cptr cfgParam, vm::cptr resource, vm::ptr handle) { cellVpost.Warning("cellVpostOpenEx(cfgParam=*0x%x, resource=*0x%x, handle=*0x%x)", cfgParam, resource, handle); @@ -60,7 +60,7 @@ s32 cellVpostClose(u32 handle) return CELL_OK; } -s32 cellVpostExec(u32 handle, vm::ptr inPicBuff, vm::ptr ctrlParam, vm::ptr outPicBuff, vm::ptr picInfo) +s32 cellVpostExec(u32 handle, vm::cptr inPicBuff, vm::cptr ctrlParam, vm::ptr outPicBuff, vm::ptr picInfo) { cellVpost.Log("cellVpostExec(handle=0x%x, inPicBuff=*0x%x, ctrlParam=*0x%x, outPicBuff=*0x%x, picInfo=*0x%x)", handle, inPicBuff, ctrlParam, outPicBuff, picInfo); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.h b/rpcs3/Emu/SysCalls/Modules/cellVpost.h index e69cf9e09a..eab6d8a3b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { @@ -137,23 +139,23 @@ enum CELL_VPOST_CSC_ERROR_E_FATAL_SPUCORE_FAIL = 0x806184c2, }; -enum CellVpostPictureDepth +enum CellVpostPictureDepth : s32 { CELL_VPOST_PIC_DEPTH_8, }; -enum CellVpostPictureFormatIn +enum CellVpostPictureFormatIn : s32 { CELL_VPOST_PIC_FMT_IN_YUV420_PLANAR, }; -enum CellVpostPictureFormatOut +enum CellVpostPictureFormatOut : s32 { CELL_VPOST_PIC_FMT_OUT_RGBA_ILV, CELL_VPOST_PIC_FMT_OUT_YUV420_PLANAR, }; -enum CellVpostPictureStructure +enum CellVpostPictureStructure : s32 { CELL_VPOST_PIC_STRUCT_PFRM, CELL_VPOST_PIC_STRUCT_IFRM, @@ -161,7 +163,7 @@ enum CellVpostPictureStructure CELL_VPOST_PIC_STRUCT_IBTM, }; -enum CellVpostExecType +enum CellVpostExecType : s32 { CELL_VPOST_EXEC_TYPE_PFRM_PFRM, CELL_VPOST_EXEC_TYPE_PTOP_ITOP, @@ -173,31 +175,31 @@ enum CellVpostExecType CELL_VPOST_EXEC_TYPE_IBTM_IBTM, }; -enum CellVpostChromaPositionType +enum CellVpostChromaPositionType : s32 { CELL_VPOST_CHROMA_POS_TYPE_A, CELL_VPOST_CHROMA_POS_TYPE_B, }; -enum CellVpostScanType +enum CellVpostScanType : s32 { CELL_VPOST_SCAN_TYPE_P, CELL_VPOST_SCAN_TYPE_I, }; -enum CellVpostQuantRange +enum CellVpostQuantRange : s32 { CELL_VPOST_QUANT_RANGE_FULL, CELL_VPOST_QUANT_RANGE_BROADCAST, }; -enum CellVpostColorMatrix +enum CellVpostColorMatrix : s32 { CELL_VPOST_COLOR_MATRIX_BT601, CELL_VPOST_COLOR_MATRIX_BT709, }; -enum CellVpostScalerType +enum CellVpostScalerType : s32 { CELL_VPOST_SCALER_TYPE_BILINEAR, CELL_VPOST_SCALER_TYPE_LINEAR_SHARP, @@ -205,7 +207,7 @@ enum CellVpostScalerType CELL_VPOST_SCALER_TYPE_8X4TAP, }; -enum CellVpostIpcType +enum CellVpostIpcType : s32 { CELL_VPOST_IPC_TYPE_DOUBLING, CELL_VPOST_IPC_TYPE_LINEAR, @@ -216,13 +218,13 @@ struct CellVpostCfgParam { be_t inMaxWidth; be_t inMaxHeight; - be_t inDepth; - be_t inPicFmt; + be_t inDepth; // CellVpostPictureDepth + be_t inPicFmt; // CellVpostPictureFormatIn be_t outMaxWidth; be_t outMaxHeight; - be_t outDepth; - be_t outPicFmt; + be_t outDepth; // CellVpostPictureDepth + be_t outPicFmt; // CellVpostPictureFormatOut be_t reserved1; be_t reserved2; @@ -265,16 +267,16 @@ struct CellVpostWindow struct CellVpostCtrlParam { - be_t execType; + be_t execType; // CellVpostExecType - be_t scalerType; - be_t ipcType; + be_t scalerType; // CellVpostScalerType + be_t ipcType; // CellVpostIpcType be_t inWidth; be_t inHeight; - be_t inChromaPosType; - be_t inQuantRange; - be_t inColorMatrix; + be_t inChromaPosType; // CellVpostChromaPositionType + be_t inQuantRange; // CellVpostQuantRange + be_t inColorMatrix; // CellVpostColorMatrix CellVpostWindow inWindow; be_t outWidth; @@ -292,23 +294,23 @@ struct CellVpostPictureInfo { be_t inWidth; be_t inHeight; - be_t inDepth; - be_t inScanType; - be_t inPicFmt; - be_t inChromaPosType; - be_t inPicStruct; - be_t inQuantRange; - be_t inColorMatrix; + be_t inDepth; // CellVpostPictureDepth + be_t inScanType; // CellVpostScanType + be_t inPicFmt; // CellVpostPictureFormatIn + be_t inChromaPosType; // CellVpostChromaPositionType + be_t inPicStruct; // CellVpostPictureStructure + be_t inQuantRange; // CellVpostQuantRange + be_t inColorMatrix; // CellVpostColorMatrix be_t outWidth; be_t outHeight; - be_t outDepth; - be_t outScanType; - be_t outPicFmt; - be_t outChromaPosType; - be_t outPicStruct; - be_t outQuantRange; - be_t outColorMatrix; + be_t outDepth; // CellVpostPictureDepth + be_t outScanType; // CellVpostScanType + be_t outPicFmt; // CellVpostPictureFormatOut + be_t outChromaPosType; // CellVpostChromaPositionType + be_t outPicStruct; // CellVpostPictureStructure + be_t outQuantRange; // CellVpostQuantRange + be_t outColorMatrix; // CellVpostColorMatrix be_t userData; @@ -325,4 +327,4 @@ public: : to_rgba(rgba) { } -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 69eb7ea158..9221b4cdb1 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -2,11 +2,10 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/Cell/PPUInstrTable.h" -#include "Emu/CPU/CPUThreadManager.h" #include "cellAudio.h" #include "libmixer.h" @@ -21,9 +20,9 @@ u64 mixcount; std::vector ssp; -int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr, u32 samples) +s32 cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr, u32 samples) { - libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr_addr=0x%x, samples=%d)", aan_handle, aan_port, offset, addr.addr(), samples); + libmixer.Log("cellAANAddData(aan_handle=0x%x, aan_port=0x%x, offset=0x%x, addr=*0x%x, samples=%d)", aan_handle, aan_port, offset, addr, samples); u32 type = aan_port >> 16; u32 port = aan_port & 0xffff; @@ -44,7 +43,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0) { - libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr_addr=0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr.addr(), samples); + libmixer.Error("cellAANAddData(aan_handle=0x%x, aan_port=0x%x, offset=0x%x, addr=*0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr, samples); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -102,7 +101,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr return CELL_OK; } -int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) +s32 cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { libmixer.Warning("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); @@ -120,7 +119,7 @@ int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) return CELL_OK; } -int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) +s32 cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { libmixer.Warning("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); @@ -138,15 +137,13 @@ int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePort return CELL_OK; } -int cellSSPlayerCreate(vm::ptr handle, vm::ptr config) +s32 cellSSPlayerCreate(vm::ptr handle, vm::ptr config) { - libmixer.Warning("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)", - handle.addr(), config.addr()); + libmixer.Warning("cellSSPlayerCreate(handle=*0x%x, config=*0x%x)", handle, config); if (config->outputMode != 0 || config->channels - 1 >= 2) { - libmixer.Error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters", - (u32)config->outputMode, (u32)config->channels); + libmixer.Error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters", config->outputMode, config->channels); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -163,7 +160,7 @@ int cellSSPlayerCreate(vm::ptr handle, vm::ptr config) return CELL_OK; } -int cellSSPlayerRemove(u32 handle) +s32 cellSSPlayerRemove(u32 handle) { libmixer.Warning("cellSSPlayerRemove(handle=0x%x)", handle); @@ -182,10 +179,9 @@ int cellSSPlayerRemove(u32 handle) return CELL_OK; } -int cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm::ptr commonInfo) +s32 cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm::ptr commonInfo) { - libmixer.Warning("cellSSPlayerSetWave(handle=0x%x, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", - handle, waveInfo.addr(), commonInfo.addr()); + libmixer.Warning("cellSSPlayerSetWave(handle=0x%x, waveInfo=*0x%x, commonInfo=*0x%x)", handle, waveInfo, commonInfo); std::lock_guard lock(mixer_mutex); @@ -206,9 +202,9 @@ int cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm: return CELL_OK; } -int cellSSPlayerPlay(u32 handle, vm::ptr info) +s32 cellSSPlayerPlay(u32 handle, vm::ptr info) { - libmixer.Warning("cellSSPlayerPlay(handle=0x%x, info_addr=0x%x)", handle, info.addr()); + libmixer.Warning("cellSSPlayerPlay(handle=0x%x, info=*0x%x)", handle, info); std::lock_guard lock(mixer_mutex); @@ -230,7 +226,7 @@ int cellSSPlayerPlay(u32 handle, vm::ptr info) return CELL_OK; } -int cellSSPlayerStop(u32 handle, u32 mode) +s32 cellSSPlayerStop(u32 handle, u32 mode) { libmixer.Warning("cellSSPlayerStop(handle=0x%x, mode=0x%x)", handle, mode); @@ -249,9 +245,9 @@ int cellSSPlayerStop(u32 handle, u32 mode) return CELL_OK; } -int cellSSPlayerSetParam(u32 handle, vm::ptr info) +s32 cellSSPlayerSetParam(u32 handle, vm::ptr info) { - libmixer.Warning("cellSSPlayerSetParam(handle=0x%x, info_addr=0x%x)", handle, info.addr()); + libmixer.Warning("cellSSPlayerSetParam(handle=0x%x, info=*0x%x)", handle, info); std::lock_guard lock(mixer_mutex); @@ -272,7 +268,7 @@ int cellSSPlayerSetParam(u32 handle, vm::ptr info) return CELL_OK; } -int cellSSPlayerGetState(u32 handle) +s32 cellSSPlayerGetState(u32 handle) { libmixer.Warning("cellSSPlayerGetState(handle=0x%x)", handle); @@ -292,9 +288,9 @@ int cellSSPlayerGetState(u32 handle) return CELL_SSPLAYER_STATE_OFF; } -int cellSurMixerCreate(vm::ptr config) +s32 cellSurMixerCreate(vm::cptr config) { - libmixer.Warning("cellSurMixerCreate(config_addr=0x%x)", config.addr()); + libmixer.Warning("cellSurMixerCreate(config=*0x%x)", config); g_surmx.audio_port = g_audio.open_port(); @@ -328,22 +324,14 @@ int cellSurMixerCreate(vm::ptr config) libmixer.Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); - thread_t t("Surmixer Thread", []() + auto ppu = Emu.GetIdManager().make_ptr("Surmixer Thread"); + ppu->prio = 1001; + ppu->stack_size = 0x10000; + ppu->custom_task = [](PPUThread& CPU) { AudioPortConfig& port = g_audio.ports[g_surmx.audio_port]; - auto cb_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - - auto& ppu = static_cast(*cb_thread); - ppu.SetName("Surmixer Callback Thread"); - ppu.SetEntry(0); - ppu.SetPrio(1001); - ppu.SetStackSize(0x10000); - ppu.InitStack(); - ppu.InitRegs(); - ppu.DoRun(); - - while (port.state.read_relaxed() != AUDIO_PORT_STATE_CLOSED && !Emu.IsStopped()) + while (port.state.load() != AUDIO_PORT_STATE_CLOSED && !Emu.IsStopped()) { if (mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack) { @@ -351,14 +339,14 @@ int cellSurMixerCreate(vm::ptr config) continue; } - if (port.state.read_relaxed() == AUDIO_PORT_STATE_STARTED) + if (port.state.load() == AUDIO_PORT_STATE_STARTED) { //u64 stamp0 = get_system_time(); memset(mixdata, 0, sizeof(mixdata)); if (surMixerCb) { - surMixerCb(ppu, surMixerCbArg, (u32)mixcount, 256); + surMixerCb(CPU, surMixerCbArg, (u32)mixcount, 256); } //u64 stamp1 = get_system_time(); @@ -373,10 +361,10 @@ int cellSurMixerCreate(vm::ptr config) float right = 0.0f; float speed = fabs(p.m_speed); float fpos = 0.0f; - for (int i = 0; i < 256; i++) if (p.m_active) + for (s32 i = 0; i < 256; i++) if (p.m_active) { u32 pos = p.m_position; - int pos_inc = 0; + s32 pos_inc = 0; if (p.m_speed > 0.0f) // select direction { pos_inc = 1; @@ -385,7 +373,7 @@ int cellSurMixerCreate(vm::ptr config) { pos_inc = -1; } - int shift = i - (int)fpos; // change playback speed (simple and rough) + s32 shift = i - (int)fpos; // change playback speed (simple and rough) if (shift > 0) { // slow playback @@ -463,56 +451,65 @@ int cellSurMixerCreate(vm::ptr config) ssp.clear(); } - Emu.GetCPU().RemoveThread(ppu.GetId()); surMixerCb.set(0); - }); + + const u32 id = CPU.GetId(); + + CallAfter([id]() + { + Emu.GetIdManager().remove(id); + }); + }; return CELL_OK; } -int cellSurMixerGetAANHandle(vm::ptr handle) +s32 cellSurMixerGetAANHandle(vm::ptr handle) { - libmixer.Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> %d", handle.addr(), 0x11111111); + libmixer.Warning("cellSurMixerGetAANHandle(handle=*0x%x) -> %d", handle, 0x11111111); *handle = 0x11111111; return CELL_OK; } -int cellSurMixerChStripGetAANPortNo(vm::ptr port, u32 type, u32 index) +s32 cellSurMixerChStripGetAANPortNo(vm::ptr port, u32 type, u32 index) { - libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0x%x", port.addr(), type, index, (type << 16) | index); + libmixer.Warning("cellSurMixerChStripGetAANPortNo(port=*0x%x, type=0x%x, index=0x%x) -> 0x%x", port, type, index, (type << 16) | index); *port = (type << 16) | index; return CELL_OK; } -int cellSurMixerSetNotifyCallback(vm::ptr func, vm::ptr arg) +s32 cellSurMixerSetNotifyCallback(vm::ptr func, vm::ptr arg) { - libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func.addr(), arg.addr()); + libmixer.Warning("cellSurMixerSetNotifyCallback(func=*0x%x, arg=*0x%x)", func, arg); if (surMixerCb) { - libmixer.Error("cellSurMixerSetNotifyCallback: surMixerCb already set (addr=0x%x)", surMixerCb.addr()); + libmixer.Error("cellSurMixerSetNotifyCallback: surMixerCb already set (*0x%x)", surMixerCb); } + surMixerCb = func; surMixerCbArg = arg; + return CELL_OK; } -int cellSurMixerRemoveNotifyCallback(vm::ptr func) +s32 cellSurMixerRemoveNotifyCallback(vm::ptr func) { - libmixer.Warning("cellSurMixerRemoveNotifyCallback(func_addr=0x%x)", func.addr()); + libmixer.Warning("cellSurMixerRemoveNotifyCallback(func=*0x%x)", func); - if (surMixerCb.addr() != func.addr()) + if (surMixerCb != func) { - libmixer.Error("cellSurMixerRemoveNotifyCallback: surMixerCb had different value (addr=0x%x)", surMixerCb.addr()); + libmixer.Error("cellSurMixerRemoveNotifyCallback: surMixerCb had different value (*0x%x)", surMixerCb); } else { - surMixerCb.set(0); + surMixerCb = vm::null; } + return CELL_OK; } -int cellSurMixerStart() +s32 cellSurMixerStart() { libmixer.Warning("cellSurMixerStart()"); @@ -526,13 +523,13 @@ int cellSurMixerStart() return CELL_OK; } -int cellSurMixerSetParameter(u32 param, float value) +s32 cellSurMixerSetParameter(u32 param, float value) { libmixer.Todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); return CELL_OK; } -int cellSurMixerFinalize() +s32 cellSurMixerFinalize() { libmixer.Warning("cellSurMixerFinalize()"); @@ -546,7 +543,7 @@ int cellSurMixerFinalize() return CELL_OK; } -int cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 samples) +s32 cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 samples) { if (busNo < 8 && samples == 256 && offset == 0) { @@ -569,13 +566,13 @@ int cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 sa return CELL_OK; } -int cellSurMixerChStripSetParameter(u32 type, u32 index, vm::ptr param) +s32 cellSurMixerChStripSetParameter(u32 type, u32 index, vm::ptr param) { - libmixer.Todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param_addr=0x%x)", type, index, param.addr()); + libmixer.Todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param=*0x%x)", type, index, param); return CELL_OK; } -int cellSurMixerPause(u32 type) +s32 cellSurMixerPause(u32 type) { libmixer.Warning("cellSurMixerPause(type=%d)", type); @@ -589,17 +586,17 @@ int cellSurMixerPause(u32 type) return CELL_OK; } -int cellSurMixerGetCurrentBlockTag(vm::ptr tag) +s32 cellSurMixerGetCurrentBlockTag(vm::ptr tag) { - libmixer.Log("cellSurMixerGetCurrentBlockTag(tag_addr=0x%x)", tag.addr()); + libmixer.Log("cellSurMixerGetCurrentBlockTag(tag=*0x%x)", tag); *tag = mixcount; return CELL_OK; } -int cellSurMixerGetTimestamp(u64 tag, vm::ptr stamp) +s32 cellSurMixerGetTimestamp(u64 tag, vm::ptr stamp) { - libmixer.Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.addr()); + libmixer.Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp=*0x%x)", tag, stamp); *stamp = g_audio.start_time + (tag) * 256000000 / 48000; // ??? return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h index b2f0a19dcd..0ad5f6832e 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.h +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error Codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index 8c30d2951e..a02614fc34 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -32,7 +32,7 @@ struct sceNpInternal sceNpInternal sceNpInstance; -int sceNpInit(u32 mem_size, u32 mem_addr) +s32 sceNpInit(u32 mem_size, u32 mem_addr) { sceNp.Warning("sceNpInit(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr); @@ -44,7 +44,7 @@ int sceNpInit(u32 mem_size, u32 mem_addr) return CELL_OK; } -int sceNp2Init(u32 mem_size, u32 mem_addr) +s32 sceNp2Init(u32 mem_size, u32 mem_addr) { sceNp.Warning("sceNp2Init(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr); @@ -56,7 +56,7 @@ int sceNp2Init(u32 mem_size, u32 mem_addr) return CELL_OK; } -int sceNpTerm() +s32 sceNpTerm() { sceNp.Warning("sceNpTerm()"); @@ -68,7 +68,7 @@ int sceNpTerm() return CELL_OK; } -int sceNp2Term() +s32 sceNp2Term() { sceNp.Warning("sceNp2Term()"); @@ -80,7 +80,7 @@ int sceNp2Term() return CELL_OK; } -int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) +s32 npDrmIsAvailable(u32 k_licensee_addr, vm::cptr drm_path) { if (!Emu.GetVFS().ExistsFile(drm_path.get_ptr())) { @@ -93,7 +93,7 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) if (k_licensee_addr) { - for (int i = 0; i < 0x10; i++) + for (s32 i = 0; i < 0x10; i++) { k_licensee[i] = vm::read8(k_licensee_addr + i); k_licensee_str += fmt::Format("%02x", k_licensee[i]); @@ -146,41 +146,41 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) return CELL_OK; } -int sceNpDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) +s32 sceNpDrmIsAvailable(u32 k_licensee_addr, vm::cptr drm_path) { sceNp.Warning("sceNpDrmIsAvailable(k_licensee_addr=0x%x, drm_path_addr=0x%x('%s'))", k_licensee_addr, drm_path.addr(), drm_path.get_ptr()); return npDrmIsAvailable(k_licensee_addr, drm_path); } -int sceNpDrmIsAvailable2(u32 k_licensee_addr, vm::ptr drm_path) +s32 sceNpDrmIsAvailable2(u32 k_licensee_addr, vm::cptr drm_path) { sceNp.Warning("sceNpDrmIsAvailable2(k_licensee_addr=0x%x, drm_path_addr=0x%x('%s'))", k_licensee_addr, drm_path.addr(), drm_path.get_ptr()); return npDrmIsAvailable(k_licensee_addr, drm_path); } -int sceNpDrmVerifyUpgradeLicense(vm::ptr content_id) +s32 sceNpDrmVerifyUpgradeLicense(vm::cptr content_id) { sceNp.Todo("sceNpDrmVerifyUpgradeLicense(content_id_addr=0x%x)", content_id.addr()); return CELL_OK; } -int sceNpDrmVerifyUpgradeLicense2(vm::ptr content_id) +s32 sceNpDrmVerifyUpgradeLicense2(vm::cptr content_id) { sceNp.Todo("sceNpDrmVerifyUpgradeLicense2(content_id_addr=0x%x)", content_id.addr()); return CELL_OK; } -int sceNpDrmExecuteGamePurchase() +s32 sceNpDrmExecuteGamePurchase() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpDrmGetTimelimit(vm::ptr path, vm::ptr time_remain) +s32 sceNpDrmGetTimelimit(vm::ptr path, vm::ptr time_remain) { sceNp.Warning("sceNpDrmGetTimelimit(path_addr=0x%x, time_remain=0x%x)", path.addr(), time_remain.addr()); @@ -189,7 +189,7 @@ int sceNpDrmGetTimelimit(vm::ptr path, vm::ptr time_remain) return CELL_OK; } -int sceNpDrmProcessExitSpawn(vm::ptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) +s32 sceNpDrmProcessExitSpawn(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { sceNp.Warning("sceNpDrmProcessExitSpawn()"); sceNp.Warning("path: %s", path.get_ptr()); @@ -205,7 +205,7 @@ int sceNpDrmProcessExitSpawn(vm::ptr path, u32 argv_addr, u32 envp_a return CELL_OK; } -int sceNpDrmProcessExitSpawn2(vm::ptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) +s32 sceNpDrmProcessExitSpawn2(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { sceNp.Warning("sceNpDrmProcessExitSpawn2()"); sceNp.Warning("path: %s", path.get_ptr()); @@ -221,97 +221,97 @@ int sceNpDrmProcessExitSpawn2(vm::ptr path, u32 argv_addr, u32 envp_ return CELL_OK; } -int sceNpBasicRegisterHandler() +s32 sceNpBasicRegisterHandler() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicRegisterContextSensitiveHandler() +s32 sceNpBasicRegisterContextSensitiveHandler() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicUnregisterHandler() +s32 sceNpBasicUnregisterHandler() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicSetPresence() +s32 sceNpBasicSetPresence() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicSetPresenceDetails() +s32 sceNpBasicSetPresenceDetails() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicSetPresenceDetails2() +s32 sceNpBasicSetPresenceDetails2() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicSendMessage() +s32 sceNpBasicSendMessage() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicSendMessageGui() +s32 sceNpBasicSendMessageGui() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicSendMessageAttachment() +s32 sceNpBasicSendMessageAttachment() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicRecvMessageAttachment() +s32 sceNpBasicRecvMessageAttachment() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicRecvMessageAttachmentLoad() +s32 sceNpBasicRecvMessageAttachmentLoad() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicRecvMessageCustom() +s32 sceNpBasicRecvMessageCustom() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicMarkMessageAsUsed() +s32 sceNpBasicMarkMessageAsUsed() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicAbortGui() +s32 sceNpBasicAbortGui() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicAddFriend() +s32 sceNpBasicAddFriend() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetFriendListEntryCount(vm::ptr count) +s32 sceNpBasicGetFriendListEntryCount(vm::ptr count) { sceNp.Warning("sceNpBasicGetFriendListEntryCount(count_addr=0x%x)", count.addr()); @@ -324,49 +324,49 @@ int sceNpBasicGetFriendListEntryCount(vm::ptr count) return CELL_OK; } -int sceNpBasicGetFriendListEntry() +s32 sceNpBasicGetFriendListEntry() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetFriendPresenceByIndex() +s32 sceNpBasicGetFriendPresenceByIndex() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetFriendPresenceByIndex2() +s32 sceNpBasicGetFriendPresenceByIndex2() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetFriendPresenceByNpId() +s32 sceNpBasicGetFriendPresenceByNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetFriendPresenceByNpId2() +s32 sceNpBasicGetFriendPresenceByNpId2() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicAddPlayersHistory() +s32 sceNpBasicAddPlayersHistory() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicAddPlayersHistoryAsync() +s32 sceNpBasicAddPlayersHistoryAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetPlayersHistoryEntryCount(u32 options, vm::ptr count) +s32 sceNpBasicGetPlayersHistoryEntryCount(u32 options, vm::ptr count) { sceNp.Todo("sceNpBasicGetPlayersHistoryEntryCount(options=%d, count_addr=0x%x)", options, count.addr()); @@ -376,19 +376,19 @@ int sceNpBasicGetPlayersHistoryEntryCount(u32 options, vm::ptr count) return CELL_OK; } -int sceNpBasicGetPlayersHistoryEntry() +s32 sceNpBasicGetPlayersHistoryEntry() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicAddBlockListEntry() +s32 sceNpBasicAddBlockListEntry() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetBlockListEntryCount(u32 count) +s32 sceNpBasicGetBlockListEntryCount(u32 count) { sceNp.Todo("sceNpBasicGetBlockListEntryCount(count=%d)", count); @@ -398,13 +398,13 @@ int sceNpBasicGetBlockListEntryCount(u32 count) return CELL_OK; } -int sceNpBasicGetBlockListEntry() +s32 sceNpBasicGetBlockListEntry() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetMessageAttachmentEntryCount(vm::ptr count) +s32 sceNpBasicGetMessageAttachmentEntryCount(vm::ptr count) { sceNp.Todo("sceNpBasicGetMessageAttachmentEntryCount(count_addr=0x%x)", count.addr()); @@ -414,7 +414,7 @@ int sceNpBasicGetMessageAttachmentEntryCount(vm::ptr count) return CELL_OK; } -int sceNpBasicGetMessageAttachmentEntry(u32 index, vm::ptr from) +s32 sceNpBasicGetMessageAttachmentEntry(u32 index, vm::ptr from) { sceNp.Todo("sceNpBasicGetMessageAttachmentEntry(index=%d, from_addr=0x%x)", index, from.addr()); @@ -424,19 +424,19 @@ int sceNpBasicGetMessageAttachmentEntry(u32 index, vm::ptr from) return CELL_OK; } -int sceNpBasicGetCustomInvitationEntryCount() +s32 sceNpBasicGetCustomInvitationEntryCount() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetCustomInvitationEntry() +s32 sceNpBasicGetCustomInvitationEntry() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpBasicGetMatchingInvitationEntryCount(vm::ptr count) +s32 sceNpBasicGetMatchingInvitationEntryCount(vm::ptr count) { sceNp.Todo("sceNpBasicGetMatchingInvitationEntryCount(count_addr=0x%x)", count.addr()); @@ -446,7 +446,7 @@ int sceNpBasicGetMatchingInvitationEntryCount(vm::ptr count) return CELL_OK; } -int sceNpBasicGetMatchingInvitationEntry(u32 index, vm::ptr from) +s32 sceNpBasicGetMatchingInvitationEntry(u32 index, vm::ptr from) { sceNp.Todo("sceNpBasicGetMatchingInvitationEntry(index=%d, from_addr=0x%x)", index, from.addr()); @@ -456,7 +456,7 @@ int sceNpBasicGetMatchingInvitationEntry(u32 index, vm::ptr from) return CELL_OK; } -int sceNpBasicGetClanMessageEntryCount(vm::ptr count) +s32 sceNpBasicGetClanMessageEntryCount(vm::ptr count) { sceNp.Todo("sceNpBasicGetClanMessageEntryCount(count_addr=0x%x)", count.addr()); @@ -466,7 +466,7 @@ int sceNpBasicGetClanMessageEntryCount(vm::ptr count) return CELL_OK; } -int sceNpBasicGetClanMessageEntry(u32 index, vm::ptr from) +s32 sceNpBasicGetClanMessageEntry(u32 index, vm::ptr from) { sceNp.Todo("sceNpBasicGetClanMessageEntry(index=%d, from_addr=0x%x)", index, from.addr()); @@ -476,7 +476,7 @@ int sceNpBasicGetClanMessageEntry(u32 index, vm::ptr from) return CELL_OK; } -int sceNpBasicGetMessageEntryCount(u32 type, vm::ptr count) +s32 sceNpBasicGetMessageEntryCount(u32 type, vm::ptr count) { sceNp.Warning("sceNpBasicGetMessageEntryCount(type=%d, count_addr=0x%x)", type, count.addr()); @@ -489,7 +489,7 @@ int sceNpBasicGetMessageEntryCount(u32 type, vm::ptr count) return CELL_OK; } -int sceNpBasicGetMessageEntry(u32 type, u32 index, vm::ptr from) +s32 sceNpBasicGetMessageEntry(u32 type, u32 index, vm::ptr from) { sceNp.Todo("sceNpBasicGetMessageEntry(type=%d, index=%d, from_addr=0x%x)", type, index, from.addr()); @@ -499,7 +499,7 @@ int sceNpBasicGetMessageEntry(u32 type, u32 index, vm::ptr from) return CELL_OK; } -int sceNpBasicGetEvent(vm::ptr event, vm::ptr from, vm::ptr data, vm::ptr size) +s32 sceNpBasicGetEvent(vm::ptr event, vm::ptr from, vm::ptr data, vm::ptr size) { sceNp.Warning("sceNpBasicGetEvent(event_addr=0x%x, from_addr=0x%x, data_addr=0x%x, size_addr=0x%x)", event.addr(), from.addr(), data.addr(), size.addr()); @@ -512,259 +512,259 @@ int sceNpBasicGetEvent(vm::ptr event, vm::ptr from, vm::ptr< return CELL_OK; } -int sceNpCommerceCreateCtx() +s32 sceNpCommerceCreateCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceDestroyCtx() +s32 sceNpCommerceDestroyCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceInitProductCategory() +s32 sceNpCommerceInitProductCategory() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceDestroyProductCategory() +s32 sceNpCommerceDestroyProductCategory() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetProductCategoryStart() +s32 sceNpCommerceGetProductCategoryStart() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetProductCategoryFinish() +s32 sceNpCommerceGetProductCategoryFinish() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetProductCategoryResult() +s32 sceNpCommerceGetProductCategoryResult() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetProductCategoryAbort() +s32 sceNpCommerceGetProductCategoryAbort() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetProductId() +s32 sceNpCommerceGetProductId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetProductName() +s32 sceNpCommerceGetProductName() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCategoryDescription() +s32 sceNpCommerceGetCategoryDescription() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCategoryId() +s32 sceNpCommerceGetCategoryId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCategoryImageURL() +s32 sceNpCommerceGetCategoryImageURL() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCategoryInfo() +s32 sceNpCommerceGetCategoryInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCategoryName() +s32 sceNpCommerceGetCategoryName() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCurrencyCode() +s32 sceNpCommerceGetCurrencyCode() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCurrencyDecimals() +s32 sceNpCommerceGetCurrencyDecimals() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetCurrencyInfo() +s32 sceNpCommerceGetCurrencyInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetNumOfChildCategory() +s32 sceNpCommerceGetNumOfChildCategory() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetNumOfChildProductSku() +s32 sceNpCommerceGetNumOfChildProductSku() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetSkuDescription() +s32 sceNpCommerceGetSkuDescription() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetSkuId() +s32 sceNpCommerceGetSkuId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetSkuImageURL() +s32 sceNpCommerceGetSkuImageURL() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetSkuName() +s32 sceNpCommerceGetSkuName() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetSkuPrice() +s32 sceNpCommerceGetSkuPrice() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetSkuUserData() +s32 sceNpCommerceGetSkuUserData() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceSetDataFlagStart() +s32 sceNpCommerceSetDataFlagStart() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetDataFlagStart() +s32 sceNpCommerceGetDataFlagStart() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceSetDataFlagFinish() +s32 sceNpCommerceSetDataFlagFinish() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetDataFlagFinish() +s32 sceNpCommerceGetDataFlagFinish() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetDataFlagState() +s32 sceNpCommerceGetDataFlagState() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetDataFlagAbort() +s32 sceNpCommerceGetDataFlagAbort() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetChildCategoryInfo() +s32 sceNpCommerceGetChildCategoryInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceGetChildProductSkuInfo() +s32 sceNpCommerceGetChildProductSkuInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceDoCheckoutStartAsync() +s32 sceNpCommerceDoCheckoutStartAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCommerceDoCheckoutFinishAsync() +s32 sceNpCommerceDoCheckoutFinishAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCustomMenuRegisterActions() +s32 sceNpCustomMenuRegisterActions() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCustomMenuActionSetActivation() +s32 sceNpCustomMenuActionSetActivation() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpCustomMenuRegisterExceptionList() +s32 sceNpCustomMenuRegisterExceptionList() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpFriendlist() +s32 sceNpFriendlist() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpFriendlistCustom() +s32 sceNpFriendlistCustom() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpFriendlistAbortGui() +s32 sceNpFriendlistAbortGui() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupInit() +s32 sceNpLookupInit() { sceNp.Warning("sceNpLookupInit()"); @@ -778,7 +778,7 @@ int sceNpLookupInit() return CELL_OK; } -int sceNpLookupTerm() +s32 sceNpLookupTerm() { sceNp.Warning("sceNpLookupTerm()"); @@ -790,140 +790,140 @@ int sceNpLookupTerm() return CELL_OK; } -int sceNpLookupCreateTitleCtx() +s32 sceNpLookupCreateTitleCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupDestroyTitleCtx() +s32 sceNpLookupDestroyTitleCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupCreateTransactionCtx() +s32 sceNpLookupCreateTransactionCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupDestroyTransactionCtx() +s32 sceNpLookupDestroyTransactionCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupSetTimeout() +s32 sceNpLookupSetTimeout() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupAbortTransaction() +s32 sceNpLookupAbortTransaction() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupWaitAsync() +s32 sceNpLookupWaitAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupPollAsync() +s32 sceNpLookupPollAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupNpId() +s32 sceNpLookupNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupNpIdAsync() +s32 sceNpLookupNpIdAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupUserProfile() +s32 sceNpLookupUserProfile() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupUserProfileAsync() +s32 sceNpLookupUserProfileAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupUserProfileWithAvatarSize() +s32 sceNpLookupUserProfileWithAvatarSize() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupUserProfileWithAvatarSizeAsync() +s32 sceNpLookupUserProfileWithAvatarSizeAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupAvatarImage() +s32 sceNpLookupAvatarImage() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupAvatarImageAsync() +s32 sceNpLookupAvatarImageAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupTitleStorage() +s32 sceNpLookupTitleStorage() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupTitleStorageAsync() +s32 sceNpLookupTitleStorageAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupTitleSmallStorage() +s32 sceNpLookupTitleSmallStorage() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpLookupTitleSmallStorageAsync() +s32 sceNpLookupTitleSmallStorageAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerRegisterCallback() +s32 sceNpManagerRegisterCallback() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerUnregisterCallback() +s32 sceNpManagerUnregisterCallback() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetStatus(vm::ptr status) +s32 sceNpManagerGetStatus(vm::ptr status) { sceNp.Log("sceNpManagerGetStatus(status_addr=0x%x)", status.addr()); @@ -936,55 +936,55 @@ int sceNpManagerGetStatus(vm::ptr status) return CELL_OK; } -int sceNpManagerGetNetworkTime() +s32 sceNpManagerGetNetworkTime() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetOnlineId() +s32 sceNpManagerGetOnlineId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetNpId() +s32 sceNpManagerGetNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetOnlineName() +s32 sceNpManagerGetOnlineName() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetAvatarUrl() +s32 sceNpManagerGetAvatarUrl() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetMyLanguages() +s32 sceNpManagerGetMyLanguages() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetAccountRegion() +s32 sceNpManagerGetAccountRegion() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetAccountAge() +s32 sceNpManagerGetAccountAge() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetContentRatingFlag(vm::ptr isRestricted, vm::ptr age) +s32 sceNpManagerGetContentRatingFlag(vm::ptr isRestricted, vm::ptr age) { sceNp.Warning("sceNpManagerGetContentRatingFlag(isRestricted_addr=0x%x, age_addr=0x%x)", isRestricted.addr(), age.addr()); @@ -998,223 +998,223 @@ int sceNpManagerGetContentRatingFlag(vm::ptr isRestricted, vm::ptr age return CELL_OK; } -int sceNpManagerGetChatRestrictionFlag() +s32 sceNpManagerGetChatRestrictionFlag() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetCachedInfo() +s32 sceNpManagerGetCachedInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetPsHandle() +s32 sceNpManagerGetPsHandle() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerRequestTicket() +s32 sceNpManagerRequestTicket() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerRequestTicket2() +s32 sceNpManagerRequestTicket2() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetTicket() +s32 sceNpManagerGetTicket() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetTicketParam() +s32 sceNpManagerGetTicketParam() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetEntitlementIdList() +s32 sceNpManagerGetEntitlementIdList() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerGetEntitlementById() +s32 sceNpManagerGetEntitlementById() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerSubSignin() +s32 sceNpManagerSubSignin() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerSubSigninAbortGui() +s32 sceNpManagerSubSigninAbortGui() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpManagerSubSignout() +s32 sceNpManagerSubSignout() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingCreateCtx() +s32 sceNpMatchingCreateCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingDestroyCtx() +s32 sceNpMatchingDestroyCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetResult() +s32 sceNpMatchingGetResult() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetResultGUI() +s32 sceNpMatchingGetResultGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingSetRoomInfo() +s32 sceNpMatchingSetRoomInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingSetRoomInfoNoLimit() +s32 sceNpMatchingSetRoomInfoNoLimit() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetRoomInfo() +s32 sceNpMatchingGetRoomInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetRoomInfoNoLimit() +s32 sceNpMatchingGetRoomInfoNoLimit() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingSetRoomSearchFlag() +s32 sceNpMatchingSetRoomSearchFlag() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetRoomSearchFlag() +s32 sceNpMatchingGetRoomSearchFlag() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetRoomMemberListLocal() +s32 sceNpMatchingGetRoomMemberListLocal() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGetRoomListLimitGUI() +s32 sceNpMatchingGetRoomListLimitGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingKickRoomMember() +s32 sceNpMatchingKickRoomMember() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingKickRoomMemberWithOpt() +s32 sceNpMatchingKickRoomMemberWithOpt() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingQuickMatchGUI() +s32 sceNpMatchingQuickMatchGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingSendInvitationGUI() +s32 sceNpMatchingSendInvitationGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingAcceptInvitationGUI() +s32 sceNpMatchingAcceptInvitationGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingCreateRoomGUI() +s32 sceNpMatchingCreateRoomGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingJoinRoomGUI() +s32 sceNpMatchingJoinRoomGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingLeaveRoom() +s32 sceNpMatchingLeaveRoom() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingSearchJoinRoomGUI() +s32 sceNpMatchingSearchJoinRoomGUI() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpMatchingGrantOwnership() +s32 sceNpMatchingGrantOwnership() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpProfileCallGui() +s32 sceNpProfileCallGui() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpProfileAbortGui() +s32 sceNpProfileAbortGui() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreInit() +s32 sceNpScoreInit() { sceNp.Warning("sceNpScoreInit()"); @@ -1226,7 +1226,7 @@ int sceNpScoreInit() return CELL_OK; } -int sceNpScoreTerm() +s32 sceNpScoreTerm() { sceNp.Warning("sceNpScoreTerm()"); @@ -1238,349 +1238,349 @@ int sceNpScoreTerm() return CELL_OK; } -int sceNpScoreCreateTitleCtx() +s32 sceNpScoreCreateTitleCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreDestroyTitleCtx() +s32 sceNpScoreDestroyTitleCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreCreateTransactionCtx() +s32 sceNpScoreCreateTransactionCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreDestroyTransactionCtx() +s32 sceNpScoreDestroyTransactionCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreSetTimeout() +s32 sceNpScoreSetTimeout() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreSetPlayerCharacterId() +s32 sceNpScoreSetPlayerCharacterId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreWaitAsync() +s32 sceNpScoreWaitAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScorePollAsync() +s32 sceNpScorePollAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetBoardInfo() +s32 sceNpScoreGetBoardInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetBoardInfoAsync() +s32 sceNpScoreGetBoardInfoAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreRecordScore() +s32 sceNpScoreRecordScore() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreRecordScoreAsync() +s32 sceNpScoreRecordScoreAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreRecordGameData() +s32 sceNpScoreRecordGameData() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreRecordGameDataAsync() +s32 sceNpScoreRecordGameDataAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetGameData() +s32 sceNpScoreGetGameData() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetGameDataAsync() +s32 sceNpScoreGetGameDataAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetRankingByNpId() +s32 sceNpScoreGetRankingByNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetRankingByNpIdAsync() +s32 sceNpScoreGetRankingByNpIdAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetRankingByRange() +s32 sceNpScoreGetRankingByRange() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetRankingByRangeAsync() +s32 sceNpScoreGetRankingByRangeAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreCensorComment() +s32 sceNpScoreCensorComment() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreCensorCommentAsync() +s32 sceNpScoreCensorCommentAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreSanitizeComment() +s32 sceNpScoreSanitizeComment() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreSanitizeCommentAsync() +s32 sceNpScoreSanitizeCommentAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetRankingByNpIdPcId() +s32 sceNpScoreGetRankingByNpIdPcId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetRankingByNpIdPcIdAsync() +s32 sceNpScoreGetRankingByNpIdPcIdAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreAbortTransaction() +s32 sceNpScoreAbortTransaction() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansMembersRankingByNpId() +s32 sceNpScoreGetClansMembersRankingByNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansMembersRankingByNpIdAsync() +s32 sceNpScoreGetClansMembersRankingByNpIdAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansMembersRankingByNpIdPcId() +s32 sceNpScoreGetClansMembersRankingByNpIdPcId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansMembersRankingByNpIdPcIdAsync() +s32 sceNpScoreGetClansMembersRankingByNpIdPcIdAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansRankingByRange() +s32 sceNpScoreGetClansRankingByRange() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansRankingByRangeAsync() +s32 sceNpScoreGetClansRankingByRangeAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClanMemberGameData() +s32 sceNpScoreGetClanMemberGameData() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClanMemberGameDataAsync() +s32 sceNpScoreGetClanMemberGameDataAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansRankingByClanId() +s32 sceNpScoreGetClansRankingByClanId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansRankingByClanIdAsync() +s32 sceNpScoreGetClansRankingByClanIdAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansMembersRankingByRange() +s32 sceNpScoreGetClansMembersRankingByRange() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpScoreGetClansMembersRankingByRangeAsync() +s32 sceNpScoreGetClansMembersRankingByRangeAsync() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingCreateCtx() +s32 sceNpSignalingCreateCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingDestroyCtx() +s32 sceNpSignalingDestroyCtx() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingAddExtendedHandler() +s32 sceNpSignalingAddExtendedHandler() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingSetCtxOpt() +s32 sceNpSignalingSetCtxOpt() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetCtxOpt() +s32 sceNpSignalingGetCtxOpt() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingActivateConnection() +s32 sceNpSignalingActivateConnection() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingDeactivateConnection() +s32 sceNpSignalingDeactivateConnection() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingTerminateConnection() +s32 sceNpSignalingTerminateConnection() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetConnectionStatus() +s32 sceNpSignalingGetConnectionStatus() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetConnectionInfo() +s32 sceNpSignalingGetConnectionInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetConnectionFromNpId() +s32 sceNpSignalingGetConnectionFromNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetConnectionFromPeerAddress() +s32 sceNpSignalingGetConnectionFromPeerAddress() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetLocalNetInfo() +s32 sceNpSignalingGetLocalNetInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetPeerNetInfo() +s32 sceNpSignalingGetPeerNetInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingCancelPeerNetInfo() +s32 sceNpSignalingCancelPeerNetInfo() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpSignalingGetPeerNetInfoResult() +s32 sceNpSignalingGetPeerNetInfoResult() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpUtilCmpNpId() +s32 sceNpUtilCmpNpId() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpUtilCmpNpIdInOrder() +s32 sceNpUtilCmpNpIdInOrder() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int sceNpUtilBandwidthTestInitStart(u32 prio, size_t stack) +s32 sceNpUtilBandwidthTestInitStart(u32 prio, size_t stack) { UNIMPLEMENTED_FUNC(sceNp); @@ -1592,7 +1592,7 @@ int sceNpUtilBandwidthTestInitStart(u32 prio, size_t stack) return CELL_OK; } -int sceNpUtilBandwidthTestGetStatus() +s32 sceNpUtilBandwidthTestGetStatus() { UNIMPLEMENTED_FUNC(sceNp); @@ -1602,7 +1602,7 @@ int sceNpUtilBandwidthTestGetStatus() return CELL_OK; } -int sceNpUtilBandwidthTestShutdown() +s32 sceNpUtilBandwidthTestShutdown() { UNIMPLEMENTED_FUNC(sceNp); @@ -1614,7 +1614,7 @@ int sceNpUtilBandwidthTestShutdown() return CELL_OK; } -int sceNpUtilBandwidthTestAbort() +s32 sceNpUtilBandwidthTestAbort() { UNIMPLEMENTED_FUNC(sceNp); @@ -1624,13 +1624,13 @@ int sceNpUtilBandwidthTestAbort() return CELL_OK; } -int _sceNpSysutilClientMalloc() +s32 _sceNpSysutilClientMalloc() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; } -int _sceNpSysutilClientFree() +s32 _sceNpSysutilClientFree() { UNIMPLEMENTED_FUNC(sceNp); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.h b/rpcs3/Emu/SysCalls/Modules/sceNp.h index 35be94177a..b86f1fc805 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.h @@ -1,4 +1,7 @@ #pragma once + +namespace vm { using namespace ps3; } + #include "cellRtc.h" // Error Codes @@ -96,7 +99,7 @@ enum SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID = 0x8002a1b1, }; -typedef int(*SceNpBasicEventHandler)(s32 event, s32 retCode, u32 reqId, vm::ptr arg); +using SceNpBasicEventHandler = func_def arg)>; // NP Manager Utility statuses enum @@ -689,41 +692,41 @@ enum // NP communication ID structure struct SceNpCommunicationId { - s8 data[9]; - s8 term; + char data[9]; + char term; u8 num; - //s8 dummy; + char dummy; }; // OnlineId structure struct SceNpOnlineId { - s8 data[16]; - s8 term; - //s8 dummy[3]; + char data[16]; + char term; + char dummy[3]; }; // NP ID structure struct SceNpId { SceNpOnlineId handle; - //u8 opt[8]; - //u8 reserved[8]; + u8 opt[8]; + u8 reserved[8]; }; // Online Name structure struct SceNpOnlineName { - s8 data[48]; - s8 term; - s8 padding[3]; + char data[48]; + char term; + char padding[3]; }; // Avatar structure struct SceNpAvatarUrl { - s8 data[127]; - s8 term; + char data[127]; + char term; }; // Avatar image structure @@ -731,14 +734,14 @@ struct SceNpAvatarImage { u8 data[SCE_NET_NP_AVATAR_IMAGE_MAX_SIZE]; be_t size; - //u8 reserved[12]; + u8 reserved[12]; }; // Self introduction structure struct SceNpAboutMe { - s8 data[SCE_NET_NP_ABOUT_ME_MAX_LENGTH]; - s8 term; + char data[SCE_NET_NP_ABOUT_ME_MAX_LENGTH]; + char term; }; // User information structure @@ -749,12 +752,12 @@ struct SceNpUserInfo SceNpAvatarUrl icon; }; -// User information structure (pointer version) +// User information structure struct SceNpUserInfo2 { SceNpId npId; - SceNpOnlineName onlineName; - SceNpAvatarUrl avatarUrl; + vm::bptr onlineName; + vm::bptr avatarUrl; }; // Often used languages structure @@ -781,6 +784,7 @@ struct SceNpCommunicationSignature // NP cache information structure struct SceNpManagerCacheParam { + be_t size; SceNpOnlineId onlineId; SceNpId npId; SceNpOnlineName onlineName; @@ -790,7 +794,7 @@ struct SceNpManagerCacheParam // Message attachment data struct SceNpBasicAttachmentData { - be_t id; + be_t id; // SceNpBasicAttachmentDataId be_t size; }; @@ -1063,10 +1067,13 @@ struct SceNpMatching2LobbyDataInternal union SceNpMatching2LobbyMessageDestination { be_t unicastTarget; - struct multicastTarget { - be_t *memberId; + + struct + { + vm::bptr memberId; be_t memberIdNum; - }; + } + multicastTarget; }; // Group label @@ -1969,7 +1976,8 @@ struct SceNpScoreClanIdRankData }; // Union for connection information -union SceNpSignalingConnectionInfo { +union SceNpSignalingConnectionInfo +{ be_t rtt; be_t bandwidth; SceNpId npId; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp index 3ea66374d1..77cf742b1a 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp @@ -20,9 +20,9 @@ struct sceNpClansInternal sceNpClansInternal sceNpClansInstance; -int sceNpClansInit(vm::ptr commId, vm::ptr passphrase, vm::ptr pool, vm::ptr poolSize, u32 flags) +s32 sceNpClansInit(vm::ptr commId, vm::ptr passphrase, vm::ptr pool, vm::ptr poolSize, u32 flags) { - sceNpClans.Warning("sceNpClansInit(commId_addr=0x%x, passphrase_addr=0x%x, pool_addr=0x%x,poolSize_addr=0x%x, flags=%d)", commId.addr(), passphrase.addr(), pool.addr(), poolSize.addr(), flags); + sceNpClans.Warning("sceNpClansInit(commId=*0x%x, passphrase=*0x%x, pool=*0x%x, poolSize=*0x%x, flags=0x%x)", commId, passphrase, pool, poolSize, flags); if (sceNpClansInstance.m_bSceNpClansInitialized) return SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED; @@ -35,7 +35,7 @@ int sceNpClansInit(vm::ptr commId, vm::ptr handle,u64 flags) +s32 sceNpClansCreateRequest(vm::ptr handle, u64 flags) { - sceNpClans.Todo("sceNpClansCreateRequest(handle_addr=0x%x, flags=0x%llx)", handle.addr(), flags); + sceNpClans.Todo("sceNpClansCreateRequest(handle=*0x%x, flags=0x%llx)", handle, flags); if (!sceNpClansInstance.m_bSceNpClansInitialized) return SCE_NP_CLANS_ERROR_NOT_INITIALIZED; @@ -60,7 +60,7 @@ int sceNpClansCreateRequest(vm::ptr handle,u64 flags) return CELL_OK; } -int sceNpClansDestroyRequest(vm::ptr handle) +s32 sceNpClansDestroyRequest(vm::ptr handle) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -70,7 +70,7 @@ int sceNpClansDestroyRequest(vm::ptr handle) return CELL_OK; } -int sceNpClansAbortRequest(vm::ptr handle) +s32 sceNpClansAbortRequest(vm::ptr handle) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -80,7 +80,7 @@ int sceNpClansAbortRequest(vm::ptr handle) return CELL_OK; } -int sceNpClansCreateClan(vm::ptr handle, vm::ptr name, vm::ptr tag, vm::ptr clanId) +s32 sceNpClansCreateClan(vm::ptr handle, vm::cptr name, vm::cptr tag, vm::ptr clanId) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -90,7 +90,7 @@ int sceNpClansCreateClan(vm::ptr handle, vm::ptr handle, u32 clanId) +s32 sceNpClansDisbandClan(vm::ptr handle, u32 clanId) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -100,7 +100,7 @@ int sceNpClansDisbandClan(vm::ptr handle, u32 clanId) return CELL_OK; } -int sceNpClansGetClanList(vm::ptr handle, vm::ptr paging, vm::ptr clanList, vm::ptr pageResult) +s32 sceNpClansGetClanList(vm::ptr handle, vm::cptr paging, vm::ptr clanList, vm::ptr pageResult) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -110,7 +110,7 @@ int sceNpClansGetClanList(vm::ptr handle, vm::ptr handle, u32 clanId, vm::ptr npid, vm::ptr message) +s32 sceNpClansKickMember(vm::ptr handle, u32 clanId, vm::ptr npid, vm::ptr message) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -250,7 +250,7 @@ int sceNpClansKickMember(vm::ptr handle, u32 clanId, vm return CELL_OK; } -int sceNpClansSendInvitation(vm::ptr handle, u32 clanId, vm::ptr npid, vm::ptr message) +s32 sceNpClansSendInvitation(vm::ptr handle, u32 clanId, vm::ptr npid, vm::ptr message) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -260,7 +260,7 @@ int sceNpClansSendInvitation(vm::ptr handle, u32 clanId return CELL_OK; } -int sceNpClansCancelInvitation() +s32 sceNpClansCancelInvitation() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -270,7 +270,7 @@ int sceNpClansCancelInvitation() return CELL_OK; } -int sceNpClansSendInvitationResponse(vm::ptr handle, u32 clanId, vm::ptr message, bool accept) +s32 sceNpClansSendInvitationResponse(vm::ptr handle, u32 clanId, vm::ptr message, bool accept) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -280,7 +280,7 @@ int sceNpClansSendInvitationResponse(vm::ptr handle, u3 return CELL_OK; } -int sceNpClansSendMembershipRequest(vm::ptr handle, u32 clanId, vm::ptr message) +s32 sceNpClansSendMembershipRequest(vm::ptr handle, u32 clanId, vm::ptr message) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -290,7 +290,7 @@ int sceNpClansSendMembershipRequest(vm::ptr handle, u32 return CELL_OK; } -int sceNpClansCancelMembershipRequest() +s32 sceNpClansCancelMembershipRequest() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -300,7 +300,7 @@ int sceNpClansCancelMembershipRequest() return CELL_OK; } -int sceNpClansSendMembershipResponse() +s32 sceNpClansSendMembershipResponse() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -310,7 +310,7 @@ int sceNpClansSendMembershipResponse() return CELL_OK; } -int sceNpClansGetBlacklist() +s32 sceNpClansGetBlacklist() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -320,7 +320,7 @@ int sceNpClansGetBlacklist() return CELL_OK; } -int sceNpClansAddBlacklistEntry() +s32 sceNpClansAddBlacklistEntry() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -330,7 +330,7 @@ int sceNpClansAddBlacklistEntry() return CELL_OK; } -int sceNpClansRemoveBlacklistEntry() +s32 sceNpClansRemoveBlacklistEntry() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -340,7 +340,7 @@ int sceNpClansRemoveBlacklistEntry() return CELL_OK; } -int sceNpClansRetrieveAnnouncements() +s32 sceNpClansRetrieveAnnouncements() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -350,7 +350,7 @@ int sceNpClansRetrieveAnnouncements() return CELL_OK; } -int sceNpClansPostAnnouncement() +s32 sceNpClansPostAnnouncement() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -360,7 +360,7 @@ int sceNpClansPostAnnouncement() return CELL_OK; } -int sceNpClansRemoveAnnouncement() +s32 sceNpClansRemoveAnnouncement() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -370,7 +370,7 @@ int sceNpClansRemoveAnnouncement() return CELL_OK; } -int sceNpClansPostChallenge(vm::ptr handle, u32 clanId, u32 targetClan, vm::ptr message, vm::ptr data, u32 duration, vm::ptr mId) +s32 sceNpClansPostChallenge(vm::ptr handle, u32 clanId, u32 targetClan, vm::ptr message, vm::ptr data, u32 duration, vm::ptr mId) { UNIMPLEMENTED_FUNC(sceNpClans); @@ -385,7 +385,7 @@ int sceNpClansPostChallenge(vm::ptr handle, u32 clanId, return CELL_OK; } -int sceNpClansRetrievePostedChallenges() +s32 sceNpClansRetrievePostedChallenges() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -397,7 +397,7 @@ int sceNpClansRetrievePostedChallenges() return CELL_OK; } -int sceNpClansRemovePostedChallenge() +s32 sceNpClansRemovePostedChallenge() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -407,7 +407,7 @@ int sceNpClansRemovePostedChallenge() return CELL_OK; } -int sceNpClansRetrieveChallenges() +s32 sceNpClansRetrieveChallenges() { UNIMPLEMENTED_FUNC(sceNpClans); @@ -417,7 +417,7 @@ int sceNpClansRetrieveChallenges() return CELL_OK; } -int sceNpClansRemoveChallenge() +s32 sceNpClansRemoveChallenge() { UNIMPLEMENTED_FUNC(sceNpClans); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpClans.h b/rpcs3/Emu/SysCalls/Modules/sceNpClans.h index 838458c071..90728adce4 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpClans.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpClans.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return codes enum { diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp index c7379c7821..3fde2fc928 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp @@ -18,19 +18,19 @@ struct sceNpCommerce2Internal sceNpCommerce2Internal sceNpCommerce2Instance; -int sceNpCommerce2ExecuteStoreBrowse() +s32 sceNpCommerce2ExecuteStoreBrowse() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetStoreBrowseUserdata() +s32 sceNpCommerce2GetStoreBrowseUserdata() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2Init() +s32 sceNpCommerce2Init() { sceNpCommerce2.Warning("sceNpCommerce2Init()"); @@ -42,7 +42,7 @@ int sceNpCommerce2Init() return CELL_OK; } -int sceNpCommerce2Term() +s32 sceNpCommerce2Term() { sceNpCommerce2.Warning("sceNpCommerce2Term()"); @@ -54,259 +54,259 @@ int sceNpCommerce2Term() return CELL_OK; } -int sceNpCommerce2CreateCtx() +s32 sceNpCommerce2CreateCtx() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DestroyCtx() +s32 sceNpCommerce2DestroyCtx() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2CreateSessionStart() +s32 sceNpCommerce2CreateSessionStart() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2CreateSessionAbort() +s32 sceNpCommerce2CreateSessionAbort() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2CreateSessionFinish() +s32 sceNpCommerce2CreateSessionFinish() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetCategoryContentsCreateReq() +s32 sceNpCommerce2GetCategoryContentsCreateReq() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetCategoryContentsStart() +s32 sceNpCommerce2GetCategoryContentsStart() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetCategoryContentsGetResult() +s32 sceNpCommerce2GetCategoryContentsGetResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2InitGetCategoryContentsResult() +s32 sceNpCommerce2InitGetCategoryContentsResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetCategoryInfo() +s32 sceNpCommerce2GetCategoryInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetContentInfo() +s32 sceNpCommerce2GetContentInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetCategoryInfoFromContentInfo() +s32 sceNpCommerce2GetCategoryInfoFromContentInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetGameProductInfoFromContentInfo() +s32 sceNpCommerce2GetGameProductInfoFromContentInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DestroyGetCategoryContentsResult() +s32 sceNpCommerce2DestroyGetCategoryContentsResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetProductInfoCreateReq() +s32 sceNpCommerce2GetProductInfoCreateReq() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetProductInfoStart() +s32 sceNpCommerce2GetProductInfoStart() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetProductInfoGetResult() +s32 sceNpCommerce2GetProductInfoGetResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2InitGetProductInfoResult() +s32 sceNpCommerce2InitGetProductInfoResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetGameProductInfo() +s32 sceNpCommerce2GetGameProductInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DestroyGetProductInfoResult() +s32 sceNpCommerce2DestroyGetProductInfoResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetProductInfoListCreateReq() +s32 sceNpCommerce2GetProductInfoListCreateReq() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetProductInfoListStart() +s32 sceNpCommerce2GetProductInfoListStart() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetProductInfoListGetResult() +s32 sceNpCommerce2GetProductInfoListGetResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2InitGetProductInfoListResult() +s32 sceNpCommerce2InitGetProductInfoListResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetGameProductInfoFromGetProductInfoListResult() +s32 sceNpCommerce2GetGameProductInfoFromGetProductInfoListResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DestroyGetProductInfoListResult() +s32 sceNpCommerce2DestroyGetProductInfoListResult() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetContentRatingInfoFromGameProductInfo() +s32 sceNpCommerce2GetContentRatingInfoFromGameProductInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetContentRatingInfoFromCategoryInfo() +s32 sceNpCommerce2GetContentRatingInfoFromCategoryInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetContentRatingDescriptor() +s32 sceNpCommerce2GetContentRatingDescriptor() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetGameSkuInfoFromGameProductInfo() +s32 sceNpCommerce2GetGameSkuInfoFromGameProductInfo() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetPrice() +s32 sceNpCommerce2GetPrice() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoCheckoutStartAsync() +s32 sceNpCommerce2DoCheckoutStartAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoCheckoutFinishAsync() +s32 sceNpCommerce2DoCheckoutFinishAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoProductBrowseStartAsync() +s32 sceNpCommerce2DoProductBrowseStartAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoProductBrowseFinishAsync() +s32 sceNpCommerce2DoProductBrowseFinishAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoDlListStartAsync() +s32 sceNpCommerce2DoDlListStartAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoDlListFinishAsync() +s32 sceNpCommerce2DoDlListFinishAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoProductCodeStartAsync() +s32 sceNpCommerce2DoProductCodeStartAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DoProductCodeFinishAsync() +s32 sceNpCommerce2DoProductCodeFinishAsync() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2GetBGDLAvailability() +s32 sceNpCommerce2GetBGDLAvailability() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2SetBGDLAvailability() +s32 sceNpCommerce2SetBGDLAvailability() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2AbortReq() +s32 sceNpCommerce2AbortReq() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; } -int sceNpCommerce2DestroyReq() +s32 sceNpCommerce2DestroyReq() { UNIMPLEMENTED_FUNC(sceNpCommerce2); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h index 90e30569d7..804e7d84a7 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h @@ -1,4 +1,7 @@ #pragma once + +namespace vm { using namespace ps3; } + #include "cellRtc.h" // Return codes diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpSns.h b/rpcs3/Emu/SysCalls/Modules/sceNpSns.h index 874ea96be1..8c498eb641 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpSns.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpSns.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return codes enum { @@ -35,4 +37,4 @@ struct SceNpSnsFbInitParams { be_t pool; be_t poolSize; -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index 4c941ebf70..be1a709d89 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "rpcs3/Ini.h" #include "Utilities/rXml.h" @@ -11,163 +11,163 @@ #include "Emu/FS/VFS.h" #include "Emu/FS/vfsDir.h" #include "Emu/FS/vfsFileBase.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include "sceNp.h" #include "sceNpTrophy.h" extern Module sceNpTrophy; // Internal Structs -struct sceNpTrophyInternalContext +struct trophy_context_t { - // TODO + const u32 id; + std::string trp_name; std::unique_ptr trp_stream; - std::unique_ptr tropusr; -// TODO: remove the following code when Visual C++ no longer generates -// compiler errors for it. All of this should be auto-generated -#if defined(_MSC_VER) && _MSC_VER <= 1800 - sceNpTrophyInternalContext() - : trp_stream(), - tropusr() + trophy_context_t() + : id(Emu.GetIdManager().get_current_id()) { } - - sceNpTrophyInternalContext(sceNpTrophyInternalContext&& other) - { - std::swap(trp_stream,other.trp_stream); - std::swap(tropusr, other.tropusr); - std::swap(trp_name, other.trp_name); - } - - sceNpTrophyInternalContext& operator =(sceNpTrophyInternalContext&& other) - { - std::swap(trp_stream, other.trp_stream); - std::swap(tropusr, other.tropusr); - std::swap(trp_name, other.trp_name); - return *this; - } - - sceNpTrophyInternalContext(sceNpTrophyInternalContext& other) = delete; - sceNpTrophyInternalContext& operator =(sceNpTrophyInternalContext& other) = delete; -#endif - }; -struct sceNpTrophyInternal +struct trophy_handle_t { - bool m_bInitialized; - std::vector contexts; + const u32 id; - sceNpTrophyInternal() - : m_bInitialized(false) + trophy_handle_t() + : id(Emu.GetIdManager().get_current_id()) { } }; -sceNpTrophyInternal sceNpTrophyInstance; - -static sceNpTrophyInternalContext& getContext(u32 context) { - // The invalid context is 0, so remap contexts 1... to indices 0... - if (context == 0) - throw "getContext: context == 0"; - return sceNpTrophyInstance.contexts[context - 1]; -} - // Functions -int sceNpTrophyInit(u32 pool_addr, u32 poolSize, u32 containerId, u64 options) +s32 sceNpTrophyInit(vm::ptr pool, u32 poolSize, u32 containerId, u64 options) { - sceNpTrophy.Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=0x%x, options=0x%llx)", pool_addr, poolSize, containerId, options); - - if (sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED; - if (options) - return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; - - sceNpTrophyInstance.m_bInitialized = true; + sceNpTrophy.Warning("sceNpTrophyInit(pool=*0x%x, poolSize=0x%x, containerId=0x%x, options=0x%llx)", pool, poolSize, containerId, options); return CELL_OK; } -int sceNpTrophyCreateContext(vm::ptr context, vm::ptr commID, vm::ptr commSign, u64 options) +s32 sceNpTrophyTerm() { - sceNpTrophy.Warning("sceNpTrophyCreateContext(context=*0x%x, commID=*0x%x, commSign=*0x%x, options=0x%llx)", context, commID, commSign, options); + sceNpTrophy.Warning("sceNpTrophyTerm()"); - if (!sceNpTrophyInstance.m_bInitialized) + return CELL_OK; +} + +s32 sceNpTrophyCreateHandle(vm::ptr handle) +{ + sceNpTrophy.Warning("sceNpTrophyCreateHandle(handle=*0x%x)", handle); + + if (!handle) { - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT; } - if (options & ~1) - { - return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; - } - // TODO: There are other possible errors + *handle = Emu.GetIdManager().make(); - // TODO: Is the TROPHY.TRP file necessarily located in this path? - if (!Emu.GetVFS().ExistsDir("/app_home/../TROPDIR/")) + return CELL_OK; +} + +s32 sceNpTrophyDestroyHandle(u32 handle) +{ + sceNpTrophy.Warning("sceNpTrophyDestroyHandle(handle=0x%x)", handle); + + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } + + Emu.GetIdManager().remove(handle); + + return CELL_OK; +} + +s32 sceNpTrophyAbortHandle(u32 handle) +{ + sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=0x%x)", handle); + + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } + + return CELL_OK; +} + +s32 sceNpTrophyCreateContext(vm::ptr context, vm::cptr commId, vm::cptr commSign, u64 options) +{ + sceNpTrophy.Warning("sceNpTrophyCreateContext(context=*0x%x, commId=*0x%x, commSign=*0x%x, options=0x%llx)", context, commId, commSign, options); + + // rough checks for further fmt::format call + if (commId->term || commId->num > 99) + { + return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID; + } + + // generate trophy context name + std::string name = fmt::format("%s_%02d", commId->data, commId->num); + + // open trophy pack file + std::unique_ptr stream(Emu.GetVFS().OpenFile("/app_home/../TROPDIR/" + name + "/TROPHY.TRP", vfsRead)); + + // check if exists and opened + if (!stream || !stream->IsOpened()) { return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; } - // TODO: Following method will retrieve the TROPHY.TRP of the first folder that contains such file - for (const auto entry : vfsDir("/app_home/../TROPDIR/")) - { - if (entry->flags & DirEntry_TypeDir) - { - vfsStream* stream = Emu.GetVFS().OpenFile("/app_home/../TROPDIR/" + entry->name + "/TROPHY.TRP", vfsRead); + // create trophy context + const auto ctxt = Emu.GetIdManager().make_ptr(); - if (stream && stream->IsOpened()) - { - sceNpTrophyInstance.contexts.emplace_back(); - sceNpTrophyInternalContext& ctxt = sceNpTrophyInstance.contexts.back(); - ctxt.trp_stream.reset(stream); - ctxt.trp_name = entry->name; - stream = nullptr; - *context = sceNpTrophyInstance.contexts.size(); // contexts start from 1 - return CELL_OK; - } - } - } - - return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; -} - -int sceNpTrophyCreateHandle(vm::ptr handle) -{ - sceNpTrophy.Todo("sceNpTrophyCreateHandle(handle_addr=0x%x)", handle.addr()); - - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - // TODO: There are other possible errors - - // TODO: ? + // set trophy context parameters (could be passed to constructor through make_ptr call) + ctxt->trp_name = std::move(name); + ctxt->trp_stream = std::move(stream); + *context = ctxt->id; return CELL_OK; } -int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptr statusCb, u32 arg_addr, u64 options) +s32 sceNpTrophyDestroyContext(u32 context) { - sceNpTrophy.Warning("sceNpTrophyRegisterContext(context=0x%x, handle=0x%x, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)", - context, handle, statusCb.addr(), arg_addr, options); + sceNpTrophy.Warning("sceNpTrophyDestroyContext(context=0x%x)", context); - if (!(sceNpTrophyInstance.m_bInitialized)) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - if (options & (~(u64)1)) - return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED; - if (context == 0 || context > sceNpTrophyInstance.contexts.size()) { - sceNpTrophy.Warning("sceNpTrophyRegisterContext: invalid context (%d)", context); + const auto ctxt = Emu.GetIdManager().get(context); + + if (!ctxt) + { return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } - // TODO: There are other possible errors - sceNpTrophyInternalContext& ctxt = getContext(context); - if (!ctxt.trp_stream) - return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; + Emu.GetIdManager().remove(context); - TRPLoader trp(*(ctxt.trp_stream)); + return CELL_OK; +} + +s32 sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr statusCb, vm::ptr arg, u64 options) +{ + sceNpTrophy.Error("sceNpTrophyRegisterContext(context=0x%x, handle=0x%x, statusCb=*0x%x, arg=*0x%x, options=0x%llx)", context, handle, statusCb, arg, options); + + const auto ctxt = Emu.GetIdManager().get(context); + + if (!ctxt) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; + } + + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } + + TRPLoader trp(*ctxt->trp_stream); if (!trp.LoadHeader()) return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE; @@ -191,14 +191,14 @@ int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptrtrp_name; if (!trp.Install(trophyPath)) return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE; @@ -206,79 +206,67 @@ int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptrLoad(trophyUsrPath, trophyConfPath); - ctxt.tropusr.reset(tropusr); + ctxt->tropusr.reset(tropusr); // TODO: Callbacks - statusCb(context, SCE_NP_TROPHY_STATUS_INSTALLED, 100, 100, arg_addr); - statusCb(context, SCE_NP_TROPHY_STATUS_PROCESSING_COMPLETE, 100, 100, arg_addr); + statusCb(CPU, context, SCE_NP_TROPHY_STATUS_INSTALLED, 100, 100, arg); + statusCb(CPU, context, SCE_NP_TROPHY_STATUS_PROCESSING_COMPLETE, 100, 100, arg); return CELL_OK; } -int sceNpTrophyGetGameProgress() +s32 sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr reqspace, u64 options) { - UNIMPLEMENTED_FUNC(sceNpTrophy); - return CELL_OK; -} + sceNpTrophy.Error("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace*=0x%x, options=0x%llx)", context, handle, reqspace, options); -int sceNpTrophySetSoundLevel() -{ - UNIMPLEMENTED_FUNC(sceNpTrophy); - return CELL_OK; -} + const auto ctxt = Emu.GetIdManager().get(context); -int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr reqspace, u64 options) -{ - sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace_addr=0x%x, options=0x%llx)", - context, handle, reqspace.addr(), options); - - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - if (context == 0 || context > sceNpTrophyInstance.contexts.size()) { - sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace: invalid context (%d)", context); + if (!ctxt) + { return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } - // TODO: There are other possible errors - const sceNpTrophyInternalContext& ctxt = getContext(context); - if (!ctxt.trp_stream) - return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; + const auto hndl = Emu.GetIdManager().get(handle); - *reqspace = ctxt.trp_stream->GetSize(); // TODO: This is not accurate. It's just an approximation of the real value - return CELL_OK; -} + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } -int sceNpTrophyDestroyContext() -{ - UNIMPLEMENTED_FUNC(sceNpTrophy); - return CELL_OK; -} - -int sceNpTrophyAbortHandle(u32 handle) -{ - sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=0x%x)", handle); - - // TODO: ? - - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + // TODO: This is not accurate. It's just an approximation of the real value + *reqspace = ctxt->trp_stream->GetSize(); return CELL_OK; } -int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr details, vm::ptr data) +s32 sceNpTrophySetSoundLevel(u32 context, u32 handle, u32 level, u64 options) { - sceNpTrophy.Warning("sceNpTrophyGetGameInfo(context=0x%x, handle=0x%x, details_addr=0x%x, data_addr=0x%x)", - context, handle, details.addr(), data.addr()); + sceNpTrophy.Todo("sceNpTrophySetSoundLevel(context=0x%x, handle=0x%x, level=%d, options=0x%llx)", context, handle, level, options); - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - // TODO: There are other possible errors + return CELL_OK; +} + +s32 sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr details, vm::ptr data) +{ + sceNpTrophy.Error("sceNpTrophyGetGameInfo(context=0x%x, handle=0x%x, details=*0x%x, data=*0x%x)", context, handle, details, data); + + const auto ctxt = Emu.GetIdManager().get(context); + + if (!ctxt) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; + } + + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } std::string path; rXmlDocument doc; - const sceNpTrophyInternalContext& ctxt = getContext(context); - Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user + Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user doc.Load(path); std::string titleName; @@ -300,7 +288,7 @@ int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptrnumPlatinum++; break; } - if (ctxt.tropusr->GetTrophyUnlockState(trophy_id)) + if (ctxt->tropusr->GetTrophyUnlockState(trophy_id)) { data->unlockedTrophies++; switch (n->GetAttribute("ttype")[0]) { @@ -313,77 +301,69 @@ int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptrtitle, titleName.c_str(), std::min((size_t) SCE_NP_TROPHY_NAME_MAX_SIZE, titleName.length() + 1)); - memcpy(details->description, titleDetail.c_str(), std::min((size_t) SCE_NP_TROPHY_DESCR_MAX_SIZE, titleDetail.length() + 1)); + strcpy_trunc(details->title, titleName); + strcpy_trunc(details->description, titleDetail); return CELL_OK; } -int sceNpTrophyDestroyHandle() +s32 sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr platinumId) { - UNIMPLEMENTED_FUNC(sceNpTrophy); - return CELL_OK; -} + sceNpTrophy.Error("sceNpTrophyUnlockTrophy(context=0x%x, handle=0x%x, trophyId=%d, platinumId=*0x%x)", context, handle, trophyId, platinumId); -int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr platinumId) -{ - sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=0x%x, handle=0x%x, trophyId=%d, platinumId_addr=0x%x)", - context, handle, trophyId, platinumId.addr()); - - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - // TODO: There are other possible errors + const auto ctxt = Emu.GetIdManager().get(context); - sceNpTrophyInternalContext& ctxt = getContext(context); - if (trophyId >= (s32)ctxt.tropusr->GetTrophiesCount()) + if (!ctxt) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; + } + + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } + + if (trophyId >= (s32)ctxt->tropusr->GetTrophiesCount()) return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID; - if (ctxt.tropusr->GetTrophyUnlockState(trophyId)) + if (ctxt->tropusr->GetTrophyUnlockState(trophyId)) return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED; - u64 timestamp1 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong - u64 timestamp2 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong - ctxt.tropusr->UnlockTrophy(trophyId, timestamp1, timestamp2); - std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPUSR.DAT"; - ctxt.tropusr->Save(trophyPath); + ctxt->tropusr->UnlockTrophy(trophyId, 0, 0); // TODO + std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT"; + ctxt->tropusr->Save(trophyPath); *platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO return CELL_OK; } -int sceNpTrophyTerm() +s32 sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr flags, vm::ptr count) { - sceNpTrophy.Warning("sceNpTrophyTerm()"); + sceNpTrophy.Error("sceNpTrophyGetTrophyUnlockState(context=0x%x, handle=0x%x, flags=*0x%x, count=*0x%x)", context, handle, flags, count); - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; + const auto ctxt = Emu.GetIdManager().get(context); - sceNpTrophyInstance.m_bInitialized = false; - - return CELL_OK; -} - -int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr flags, vm::ptr count) -{ - sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState(context=0x%x, handle=0x%x, flags_addr=0x%x, count_addr=0x%x)", - context, handle, flags.addr(), count.addr()); - - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - if (context == 0 || context > sceNpTrophyInstance.contexts.size()) { - sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState: invalid context (%d)", context); + if (!ctxt) + { return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } - // TODO: There are other possible errors - const sceNpTrophyInternalContext& ctxt = getContext(context); - u32 count_ = ctxt.tropusr->GetTrophiesCount(); + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } + + u32 count_ = ctxt->tropusr->GetTrophiesCount(); *count = count_; if (count_ > 128) - sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!"); + sceNpTrophy.Error("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!"); // Pack up to 128 bools in u32 flag_bits[4] for (u32 id = 0; id < count_; id++) { - if (ctxt.tropusr->GetTrophyUnlockState(id)) + if (ctxt->tropusr->GetTrophyUnlockState(id)) flags->flag_bits[id/32] |= 1<<(id%32); else flags->flag_bits[id/32] &= ~(1<<(id%32)); @@ -392,25 +372,27 @@ int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr details, vm::ptr data) { - UNIMPLEMENTED_FUNC(sceNpTrophy); - return CELL_OK; -} + sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details=*0x%x, data=*0x%x)", context, handle, trophyId, details, data); -int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr details, vm::ptr data) -{ - sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details_addr=0x%x, data_addr=0x%x)", - context, handle, trophyId, details.addr(), data.addr()); + const auto ctxt = Emu.GetIdManager().get(context); - if (!sceNpTrophyInstance.m_bInitialized) - return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; - // TODO: There are other possible errors + if (!ctxt) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; + } + + const auto hndl = Emu.GetIdManager().get(handle); + + if (!hndl) + { + return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; + } std::string path; rXmlDocument doc; - const sceNpTrophyInternalContext& ctxt = getContext(context); - Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user + Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user doc.Load(path); std::string name; @@ -437,8 +419,8 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptrtrophyId = trophyId; - data->unlocked = ctxt.tropusr->GetTrophyUnlockState(trophyId) ? true : false; // ??? - data->timestamp.tick = ctxt.tropusr->GetTrophyTimestamp(trophyId); + data->unlocked = ctxt->tropusr->GetTrophyUnlockState(trophyId) != 0; // ??? + data->timestamp = ctxt->tropusr->GetTrophyTimestamp(trophyId); } } @@ -447,16 +429,30 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr percentage) { - UNIMPLEMENTED_FUNC(sceNpTrophy); + sceNpTrophy.Todo("sceNpTrophyGetGameProgress(context=0x%x, handle=0x%x, percentage=*0x%x)", context, handle, percentage); + return CELL_OK; } +s32 sceNpTrophyGetGameIcon(u32 context, u32 handle, vm::ptr buffer, vm::ptr size) +{ + sceNpTrophy.Todo("sceNpTrophyGetGameIcon(context=0x%x, handle=0x%x, buffer=*0x%x, size=*0x%x)", context, handle, buffer, size); + + return CELL_OK; +} + +s32 sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::ptr buffer, vm::ptr size) +{ + sceNpTrophy.Todo("sceNpTrophyGetTrophyIcon(context=0x%x, handle=0x%x, trophyId=%d, buffer=*0x%x, size=*0x%x)", context, handle, trophyId, buffer, size); + + return CELL_OK; +} + + Module sceNpTrophy("sceNpTrophy", []() { - sceNpTrophyInstance.m_bInitialized = false; - REG_FUNC(sceNpTrophy, sceNpTrophyGetGameProgress); REG_FUNC(sceNpTrophy, sceNpTrophyRegisterContext); REG_FUNC(sceNpTrophy, sceNpTrophyCreateHandle); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h index bcb857cc04..f61f8d7bab 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Error codes enum { @@ -80,8 +82,8 @@ struct SceNpTrophyGameDetails be_t numGold; be_t numSilver; be_t numBronze; - u8 title[SCE_NP_TROPHY_TITLE_MAX_SIZE]; - u8 description[SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE]; + char title[SCE_NP_TROPHY_TITLE_MAX_SIZE]; + char description[SCE_NP_TROPHY_GAME_DESCR_MAX_SIZE]; u8 reserved[4]; }; @@ -98,17 +100,17 @@ struct SceNpTrophyDetails { be_t trophyId; // SceNpTrophyId be_t trophyGrade; // SceNpTrophyGrade - u8 name[SCE_NP_TROPHY_NAME_MAX_SIZE]; - u8 description[SCE_NP_TROPHY_DESCR_MAX_SIZE]; - bool hidden; + char name[SCE_NP_TROPHY_NAME_MAX_SIZE]; + char description[SCE_NP_TROPHY_DESCR_MAX_SIZE]; + b8 hidden; u8 reserved[3]; }; struct SceNpTrophyData { - CellRtcTick timestamp; + be_t timestamp; // CellRtcTick be_t trophyId; // SceNpTrophyId - bool unlocked; + b8 unlocked; u8 reserved[3]; }; @@ -134,4 +136,4 @@ enum SCE_NP_TROPHY_STATUS_CHANGES_DETECTED = 9, }; -typedef s32 (SceNpTrophyStatusCallback)(u32 context, u32 status, s32 completed, s32 total, u32 arg_addr); +using SceNpTrophyStatusCallback = func_def arg)>; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp index f9055f71d4..ef09c3718c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp @@ -19,7 +19,7 @@ struct sceNpTusInternal sceNpTusInternal sceNpTusInstance; -int sceNpTusInit() +s32 sceNpTusInit() { sceNpTus.Warning("sceNpTusInit()"); @@ -31,7 +31,7 @@ int sceNpTusInit() return CELL_OK; } -int sceNpTusTerm() +s32 sceNpTusTerm() { sceNpTus.Warning("sceNpTusTerm()"); @@ -43,7 +43,7 @@ int sceNpTusTerm() return CELL_OK; } -int sceNpTusCreateTitleCtx() +s32 sceNpTusCreateTitleCtx() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -53,7 +53,7 @@ int sceNpTusCreateTitleCtx() return CELL_OK; } -int sceNpTusDestroyTitleCtx() +s32 sceNpTusDestroyTitleCtx() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -63,7 +63,7 @@ int sceNpTusDestroyTitleCtx() return CELL_OK; } -int sceNpTusCreateTransactionCtx() +s32 sceNpTusCreateTransactionCtx() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -73,7 +73,7 @@ int sceNpTusCreateTransactionCtx() return CELL_OK; } -int sceNpTusDestroyTransactionCtx() +s32 sceNpTusDestroyTransactionCtx() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -83,7 +83,7 @@ int sceNpTusDestroyTransactionCtx() return CELL_OK; } -int sceNpTusSetTimeout() +s32 sceNpTusSetTimeout() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -93,7 +93,7 @@ int sceNpTusSetTimeout() return CELL_OK; } -int sceNpTusAbortTransaction() +s32 sceNpTusAbortTransaction() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -103,7 +103,7 @@ int sceNpTusAbortTransaction() return CELL_OK; } -int sceNpTusWaitAsync() +s32 sceNpTusWaitAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -113,7 +113,7 @@ int sceNpTusWaitAsync() return CELL_OK; } -int sceNpTusPollAsync() +s32 sceNpTusPollAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -123,7 +123,7 @@ int sceNpTusPollAsync() return CELL_OK; } -int sceNpTusSetMultiSlotVariable() +s32 sceNpTusSetMultiSlotVariable() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -133,7 +133,7 @@ int sceNpTusSetMultiSlotVariable() return CELL_OK; } -int sceNpTusSetMultiSlotVariableVUser() +s32 sceNpTusSetMultiSlotVariableVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -143,7 +143,7 @@ int sceNpTusSetMultiSlotVariableVUser() return CELL_OK; } -int sceNpTusSetMultiSlotVariableAsync() +s32 sceNpTusSetMultiSlotVariableAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -153,7 +153,7 @@ int sceNpTusSetMultiSlotVariableAsync() return CELL_OK; } -int sceNpTusSetMultiSlotVariableVUserAsync() +s32 sceNpTusSetMultiSlotVariableVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -163,7 +163,7 @@ int sceNpTusSetMultiSlotVariableVUserAsync() return CELL_OK; } -int sceNpTusGetMultiSlotVariable() +s32 sceNpTusGetMultiSlotVariable() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -173,7 +173,7 @@ int sceNpTusGetMultiSlotVariable() return CELL_OK; } -int sceNpTusGetMultiSlotVariableVUser() +s32 sceNpTusGetMultiSlotVariableVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -183,7 +183,7 @@ int sceNpTusGetMultiSlotVariableVUser() return CELL_OK; } -int sceNpTusGetMultiSlotVariableAsync() +s32 sceNpTusGetMultiSlotVariableAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -193,7 +193,7 @@ int sceNpTusGetMultiSlotVariableAsync() return CELL_OK; } -int sceNpTusGetMultiSlotVariableVUserAsync() +s32 sceNpTusGetMultiSlotVariableVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -203,7 +203,7 @@ int sceNpTusGetMultiSlotVariableVUserAsync() return CELL_OK; } -int sceNpTusGetMultiUserVariable() +s32 sceNpTusGetMultiUserVariable() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -213,7 +213,7 @@ int sceNpTusGetMultiUserVariable() return CELL_OK; } -int sceNpTusGetMultiUserVariableVUser() +s32 sceNpTusGetMultiUserVariableVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -223,7 +223,7 @@ int sceNpTusGetMultiUserVariableVUser() return CELL_OK; } -int sceNpTusGetMultiUserVariableAsync() +s32 sceNpTusGetMultiUserVariableAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -233,7 +233,7 @@ int sceNpTusGetMultiUserVariableAsync() return CELL_OK; } -int sceNpTusGetMultiUserVariableVUserAsync() +s32 sceNpTusGetMultiUserVariableVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -243,7 +243,7 @@ int sceNpTusGetMultiUserVariableVUserAsync() return CELL_OK; } -int sceNpTusAddAndGetVariable() +s32 sceNpTusAddAndGetVariable() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -253,7 +253,7 @@ int sceNpTusAddAndGetVariable() return CELL_OK; } -int sceNpTusAddAndGetVariableVUser() +s32 sceNpTusAddAndGetVariableVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -263,7 +263,7 @@ int sceNpTusAddAndGetVariableVUser() return CELL_OK; } -int sceNpTusAddAndGetVariableAsync() +s32 sceNpTusAddAndGetVariableAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -273,7 +273,7 @@ int sceNpTusAddAndGetVariableAsync() return CELL_OK; } -int sceNpTusAddAndGetVariableVUserAsync() +s32 sceNpTusAddAndGetVariableVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -283,7 +283,7 @@ int sceNpTusAddAndGetVariableVUserAsync() return CELL_OK; } -int sceNpTusTryAndSetVariable() +s32 sceNpTusTryAndSetVariable() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -293,7 +293,7 @@ int sceNpTusTryAndSetVariable() return CELL_OK; } -int sceNpTusTryAndSetVariableVUser() +s32 sceNpTusTryAndSetVariableVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -303,7 +303,7 @@ int sceNpTusTryAndSetVariableVUser() return CELL_OK; } -int sceNpTusTryAndSetVariableAsync() +s32 sceNpTusTryAndSetVariableAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -313,7 +313,7 @@ int sceNpTusTryAndSetVariableAsync() return CELL_OK; } -int sceNpTusTryAndSetVariableVUserAsync() +s32 sceNpTusTryAndSetVariableVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -323,7 +323,7 @@ int sceNpTusTryAndSetVariableVUserAsync() return CELL_OK; } -int sceNpTusDeleteMultiSlotVariable() +s32 sceNpTusDeleteMultiSlotVariable() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -333,7 +333,7 @@ int sceNpTusDeleteMultiSlotVariable() return CELL_OK; } -int sceNpTusDeleteMultiSlotVariableVUser() +s32 sceNpTusDeleteMultiSlotVariableVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -343,7 +343,7 @@ int sceNpTusDeleteMultiSlotVariableVUser() return CELL_OK; } -int sceNpTusDeleteMultiSlotVariableAsync() +s32 sceNpTusDeleteMultiSlotVariableAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -353,7 +353,7 @@ int sceNpTusDeleteMultiSlotVariableAsync() return CELL_OK; } -int sceNpTusDeleteMultiSlotVariableVUserAsync() +s32 sceNpTusDeleteMultiSlotVariableVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -363,7 +363,7 @@ int sceNpTusDeleteMultiSlotVariableVUserAsync() return CELL_OK; } -int sceNpTusSetData() +s32 sceNpTusSetData() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -373,7 +373,7 @@ int sceNpTusSetData() return CELL_OK; } -int sceNpTusSetDataVUser() +s32 sceNpTusSetDataVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -383,7 +383,7 @@ int sceNpTusSetDataVUser() return CELL_OK; } -int sceNpTusSetDataAsync() +s32 sceNpTusSetDataAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -393,7 +393,7 @@ int sceNpTusSetDataAsync() return CELL_OK; } -int sceNpTusSetDataVUserAsync() +s32 sceNpTusSetDataVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -403,7 +403,7 @@ int sceNpTusSetDataVUserAsync() return CELL_OK; } -int sceNpTusGetData() +s32 sceNpTusGetData() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -413,7 +413,7 @@ int sceNpTusGetData() return CELL_OK; } -int sceNpTusGetDataVUser() +s32 sceNpTusGetDataVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -423,7 +423,7 @@ int sceNpTusGetDataVUser() return CELL_OK; } -int sceNpTusGetDataAsync() +s32 sceNpTusGetDataAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -433,7 +433,7 @@ int sceNpTusGetDataAsync() return CELL_OK; } -int sceNpTusGetDataVUserAsync() +s32 sceNpTusGetDataVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -443,7 +443,7 @@ int sceNpTusGetDataVUserAsync() return CELL_OK; } -int sceNpTusGetMultiSlotDataStatus() +s32 sceNpTusGetMultiSlotDataStatus() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -453,7 +453,7 @@ int sceNpTusGetMultiSlotDataStatus() return CELL_OK; } -int sceNpTusGetMultiSlotDataStatusVUser() +s32 sceNpTusGetMultiSlotDataStatusVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -463,7 +463,7 @@ int sceNpTusGetMultiSlotDataStatusVUser() return CELL_OK; } -int sceNpTusGetMultiSlotDataStatusAsync() +s32 sceNpTusGetMultiSlotDataStatusAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -473,7 +473,7 @@ int sceNpTusGetMultiSlotDataStatusAsync() return CELL_OK; } -int sceNpTusGetMultiSlotDataStatusVUserAsync() +s32 sceNpTusGetMultiSlotDataStatusVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -483,7 +483,7 @@ int sceNpTusGetMultiSlotDataStatusVUserAsync() return CELL_OK; } -int sceNpTusGetMultiUserDataStatus() +s32 sceNpTusGetMultiUserDataStatus() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -493,7 +493,7 @@ int sceNpTusGetMultiUserDataStatus() return CELL_OK; } -int sceNpTusGetMultiUserDataStatusVUser() +s32 sceNpTusGetMultiUserDataStatusVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -503,7 +503,7 @@ int sceNpTusGetMultiUserDataStatusVUser() return CELL_OK; } -int sceNpTusGetMultiUserDataStatusAsync() +s32 sceNpTusGetMultiUserDataStatusAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -513,7 +513,7 @@ int sceNpTusGetMultiUserDataStatusAsync() return CELL_OK; } -int sceNpTusGetMultiUserDataStatusVUserAsync() +s32 sceNpTusGetMultiUserDataStatusVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -523,7 +523,7 @@ int sceNpTusGetMultiUserDataStatusVUserAsync() return CELL_OK; } -int sceNpTusDeleteMultiSlotData() +s32 sceNpTusDeleteMultiSlotData() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -533,7 +533,7 @@ int sceNpTusDeleteMultiSlotData() return CELL_OK; } -int sceNpTusDeleteMultiSlotDataVUser() +s32 sceNpTusDeleteMultiSlotDataVUser() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -543,7 +543,7 @@ int sceNpTusDeleteMultiSlotDataVUser() return CELL_OK; } -int sceNpTusDeleteMultiSlotDataAsync() +s32 sceNpTusDeleteMultiSlotDataAsync() { UNIMPLEMENTED_FUNC(sceNpTus); @@ -553,7 +553,7 @@ int sceNpTusDeleteMultiSlotDataAsync() return CELL_OK; } -int sceNpTusDeleteMultiSlotDataVUserAsync() +s32 sceNpTusDeleteMultiSlotDataVUserAsync() { UNIMPLEMENTED_FUNC(sceNpTus); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTus.h b/rpcs3/Emu/SysCalls/Modules/sceNpTus.h index 865a725e78..a03e985379 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTus.h +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTus.h @@ -1,4 +1,7 @@ #pragma once + +namespace vm { using namespace ps3; } + #include "cellRtc.h" // Constants for TUS functions and structures diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index b916a50550..4b4d4dc9c0 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -4,7 +4,6 @@ #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/CB_FUNC.h" #include "Emu/FS/vfsFile.h" #include "Emu/SysCalls/lv2/sleep_queue.h" @@ -14,7 +13,6 @@ #include "Emu/SysCalls/lv2/sys_prx.h" #include "Emu/SysCalls/lv2/sys_ppu_thread.h" #include "Emu/SysCalls/lv2/sys_process.h" -#include "Emu/SysCalls/lv2/sys_time.h" #include "Emu/SysCalls/lv2/sys_mmapper.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" #include "Loader/ELF32.h" @@ -24,6 +22,8 @@ extern Module sysPrxForUser; +extern u64 get_system_time(); + #define TLS_MAX 128 #define TLS_SYS 0x30 @@ -75,7 +75,7 @@ u32 ppu_get_tls(u32 thread) } } - throw "Out of TLS memory"; + throw EXCEPTION("Out of TLS memory"); } void ppu_free_tls(u32 thread) @@ -94,9 +94,9 @@ s32 sys_lwmutex_create(vm::ptr lwmutex, vm::ptrrecursive.data() == se32(SYS_SYNC_RECURSIVE); + const bool recursive = attr->recursive == SYS_SYNC_RECURSIVE; - if (!recursive && attr->recursive.data() != se32(SYS_SYNC_NOT_RECURSIVE)) + if (!recursive && attr->recursive != SYS_SYNC_NOT_RECURSIVE) { sysPrxForUser.Error("sys_lwmutex_create(): invalid recursive attribute (0x%x)", attr->recursive); return CELL_EINVAL; @@ -112,7 +112,7 @@ s32 sys_lwmutex_create(vm::ptr lwmutex, vm::ptrlock_var = { { lwmutex::free, lwmutex::zero } }; + lwmutex->lock_var = { { lwmutex_free, 0 } }; lwmutex->attribute = attr->recursive | attr->protocol; lwmutex->recursive_count = 0; lwmutex->sleep_queue = Emu.GetIdManager().make(protocol, attr->name_u64); @@ -125,7 +125,7 @@ s32 sys_lwmutex_destroy(PPUThread& CPU, vm::ptr lwmutex) sysPrxForUser.Log("sys_lwmutex_destroy(lwmutex=*0x%x)", lwmutex); // check to prevent recursive locking in the next call - if (lwmutex->owner.read_relaxed() == CPU.GetId()) + if (lwmutex->vars.owner.load() == CPU.GetId()) { return CELL_EBUSY; } @@ -146,7 +146,7 @@ s32 sys_lwmutex_destroy(PPUThread& CPU, vm::ptr lwmutex) } // deleting succeeded - lwmutex->owner.exchange(lwmutex::dead); + lwmutex->vars.owner.exchange(lwmutex_dead); return CELL_OK; } @@ -155,12 +155,12 @@ s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout { sysPrxForUser.Log("sys_lwmutex_lock(lwmutex=*0x%x, timeout=0x%llx)", lwmutex, timeout); - const be_t tid = be_t::make(CPU.GetId()); + const be_t tid = CPU.GetId(); // try to lock lightweight mutex - const be_t old_owner = lwmutex->owner.compare_and_swap(lwmutex::free, tid); + const be_t old_owner = lwmutex->vars.owner.compare_and_swap(lwmutex_free, tid); - if (old_owner.data() == se32(lwmutex_free)) + if (old_owner == lwmutex_free) { // locking succeeded return CELL_OK; @@ -170,7 +170,7 @@ s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout { // recursive locking - if ((lwmutex->attribute.data() & se32(SYS_SYNC_RECURSIVE)) == 0) + if ((lwmutex->attribute & SYS_SYNC_RECURSIVE) == 0) { // if not recursive return CELL_EDEADLK; @@ -184,12 +184,12 @@ s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout // recursive locking succeeded lwmutex->recursive_count++; - lwmutex->lock_var.read_sync(); + _mm_mfence(); return CELL_OK; } - if (old_owner.data() == se32(lwmutex_dead)) + if (old_owner == lwmutex_dead) { // invalid or deleted mutex return CELL_EINVAL; @@ -197,9 +197,9 @@ s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout for (u32 i = 0; i < 300; i++) { - if (lwmutex->owner.read_relaxed().data() == se32(lwmutex_free)) + if (lwmutex->vars.owner.load() == lwmutex_free) { - if (lwmutex->owner.compare_and_swap_test(lwmutex::free, tid)) + if (lwmutex->vars.owner.compare_and_swap_test(lwmutex_free, tid)) { // locking succeeded return CELL_OK; @@ -210,7 +210,7 @@ s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout // atomically increment waiter value using 64 bit op lwmutex->all_info++; - if (lwmutex->owner.compare_and_swap_test(lwmutex::free, tid)) + if (lwmutex->vars.owner.compare_and_swap_test(lwmutex_free, tid)) { // locking succeeded lwmutex->all_info--; @@ -226,20 +226,20 @@ s32 sys_lwmutex_lock(PPUThread& CPU, vm::ptr lwmutex, u64 timeout if (res == CELL_OK) { // locking succeeded - auto old = lwmutex->owner.exchange(tid); + auto old = lwmutex->vars.owner.exchange(tid); - if (old.data() != se32(lwmutex_reserved) && !Emu.IsStopped()) + if (old != lwmutex_reserved) { - sysPrxForUser.Fatal("sys_lwmutex_lock(lwmutex=*0x%x): locking failed (owner=0x%x)", lwmutex, old); + throw EXCEPTION("Locking failed (lwmutex=*0x%x, owner=0x%x)", lwmutex, old); } return CELL_OK; } - if (res == CELL_EBUSY && lwmutex->attribute.data() & se32(SYS_SYNC_RETRY)) + if (res == CELL_EBUSY && lwmutex->attribute & SYS_SYNC_RETRY) { // TODO (protocol is ignored in current implementation) - throw __FUNCTION__; + throw EXCEPTION(""); } return res; @@ -249,12 +249,12 @@ s32 sys_lwmutex_trylock(PPUThread& CPU, vm::ptr lwmutex) { sysPrxForUser.Log("sys_lwmutex_trylock(lwmutex=*0x%x)", lwmutex); - const be_t tid = be_t::make(CPU.GetId()); + const be_t tid = CPU.GetId(); // try to lock lightweight mutex - const be_t old_owner = lwmutex->owner.compare_and_swap(lwmutex::free, tid); + const be_t old_owner = lwmutex->vars.owner.compare_and_swap(lwmutex_free, tid); - if (old_owner.data() == se32(lwmutex_free)) + if (old_owner == lwmutex_free) { // locking succeeded return CELL_OK; @@ -264,7 +264,7 @@ s32 sys_lwmutex_trylock(PPUThread& CPU, vm::ptr lwmutex) { // recursive locking - if ((lwmutex->attribute.data() & se32(SYS_SYNC_RECURSIVE)) == 0) + if ((lwmutex->attribute & SYS_SYNC_RECURSIVE) == 0) { // if not recursive return CELL_EDEADLK; @@ -278,18 +278,18 @@ s32 sys_lwmutex_trylock(PPUThread& CPU, vm::ptr lwmutex) // recursive locking succeeded lwmutex->recursive_count++; - lwmutex->lock_var.read_sync(); + _mm_mfence(); return CELL_OK; } - if (old_owner.data() == se32(lwmutex_dead)) + if (old_owner == lwmutex_dead) { // invalid or deleted mutex return CELL_EINVAL; } - if (old_owner.data() == se32(lwmutex_reserved)) + if (old_owner == lwmutex_reserved) { // should be locked by the syscall const s32 res = _sys_lwmutex_trylock(lwmutex->sleep_queue); @@ -297,11 +297,11 @@ s32 sys_lwmutex_trylock(PPUThread& CPU, vm::ptr lwmutex) if (res == CELL_OK) { // locking succeeded - auto old = lwmutex->owner.exchange(tid); + auto old = lwmutex->vars.owner.exchange(tid); - if (old.data() != se32(lwmutex_reserved) && !Emu.IsStopped()) + if (old != lwmutex_reserved) { - sysPrxForUser.Fatal("sys_lwmutex_trylock(lwmutex=*0x%x): locking failed (owner=0x%x)", lwmutex, old); + throw EXCEPTION("Locking failed (lwmutex=*0x%x, owner=0x%x)", lwmutex, old); } } @@ -316,10 +316,10 @@ s32 sys_lwmutex_unlock(PPUThread& CPU, vm::ptr lwmutex) { sysPrxForUser.Log("sys_lwmutex_unlock(lwmutex=*0x%x)", lwmutex); - const be_t tid = be_t::make(CPU.GetId()); + const be_t tid = CPU.GetId(); // check owner - if (lwmutex->owner.read_relaxed() != tid) + if (lwmutex->vars.owner.load() != tid) { return CELL_EPERM; } @@ -333,19 +333,19 @@ s32 sys_lwmutex_unlock(PPUThread& CPU, vm::ptr lwmutex) } // ensure that waiter is zero - if (lwmutex->lock_var.compare_and_swap_test({ tid, lwmutex::zero }, { lwmutex::free, lwmutex::zero })) + if (lwmutex->lock_var.compare_and_swap_test({ tid, 0 }, { lwmutex_free, 0 })) { // unlocking succeeded return CELL_OK; } - if (lwmutex->attribute.data() & se32(SYS_SYNC_RETRY)) + if (lwmutex->attribute & SYS_SYNC_RETRY) { // TODO (protocol is ignored in current implementation) } // set special value - lwmutex->owner.exchange(lwmutex::reserved); + lwmutex->vars.owner.exchange(lwmutex_reserved); // call the syscall if (_sys_lwmutex_unlock(lwmutex->sleep_queue) == CELL_ESRCH) @@ -386,13 +386,13 @@ s32 sys_lwcond_signal(PPUThread& CPU, vm::ptr lwcond) const vm::ptr lwmutex = lwcond->lwmutex; - if ((lwmutex->attribute.data() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) == se32(SYS_SYNC_RETRY)) + if ((lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_RETRY) { // TODO (protocol ignored) //return _sys_lwcond_signal(lwcond->lwcond_queue, 0, -1, 2); } - if (lwmutex->owner.read_relaxed() == CPU.GetId()) + if (lwmutex->vars.owner.load() == CPU.GetId()) { // if owns the mutex lwmutex->all_info++; @@ -444,13 +444,13 @@ s32 sys_lwcond_signal_all(PPUThread& CPU, vm::ptr lwcond) const vm::ptr lwmutex = lwcond->lwmutex; - if ((lwmutex->attribute.data() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) == se32(SYS_SYNC_RETRY)) + if ((lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_RETRY) { // TODO (protocol ignored) //return _sys_lwcond_signal_all(lwcond->lwcond_queue, lwmutex->sleep_queue, 2); } - if (lwmutex->owner.read_relaxed() == CPU.GetId()) + if (lwmutex->vars.owner.load() == CPU.GetId()) { // if owns the mutex, call the syscall const s32 res = _sys_lwcond_signal_all(lwcond->lwcond_queue, lwmutex->sleep_queue, 1); @@ -501,13 +501,13 @@ s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr lwcond, u32 ppu_t const vm::ptr lwmutex = lwcond->lwmutex; - if ((lwmutex->attribute.data() & se32(SYS_SYNC_ATTR_PROTOCOL_MASK)) == se32(SYS_SYNC_RETRY)) + if ((lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_RETRY) { // TODO (protocol ignored) //return _sys_lwcond_signal(lwcond->lwcond_queue, 0, ppu_thread_id, 2); } - if (lwmutex->owner.read_relaxed() == CPU.GetId()) + if (lwmutex->vars.owner.load() == CPU.GetId()) { // if owns the mutex lwmutex->all_info++; @@ -557,11 +557,11 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout) { sysPrxForUser.Log("sys_lwcond_wait(lwcond=*0x%x, timeout=0x%llx)", lwcond, timeout); - const be_t tid = be_t::make(CPU.GetId()); + const be_t tid = CPU.GetId(); const vm::ptr lwmutex = lwcond->lwmutex; - if (lwmutex->owner.read_relaxed() != tid) + if (lwmutex->vars.owner.load() != tid) { // if not owner of the mutex return CELL_EPERM; @@ -571,7 +571,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout) const be_t recursive_value = lwmutex->recursive_count; // set special value - lwmutex->owner = { lwmutex::reserved }; + lwmutex->vars.owner = { lwmutex_reserved }; lwmutex->recursive_count = 0; // call the syscall @@ -585,12 +585,12 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout) } // restore owner and recursive value - const auto old = lwmutex->owner.exchange(tid); + const auto old = lwmutex->vars.owner.exchange(tid); lwmutex->recursive_count = recursive_value; - if (old.data() != se32(lwmutex_reserved) && !Emu.IsStopped()) + if (old != lwmutex_reserved) { - sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): locking failed (lwmutex->owner=0x%x)", lwcond, old); + throw EXCEPTION("Locking failed (lwmutex=*0x%x, owner=0x%x)", lwmutex, old); } return res; @@ -614,22 +614,28 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout) if (res == CELL_EDEADLK) { // restore owner and recursive value - const auto old = lwmutex->owner.exchange(tid); + const auto old = lwmutex->vars.owner.exchange(tid); lwmutex->recursive_count = recursive_value; - if (old.data() != se32(lwmutex_reserved) && !Emu.IsStopped()) + if (old != lwmutex_reserved) { - sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): locking failed after timeout (lwmutex->owner=0x%x)", lwcond, old); + throw EXCEPTION("Locking failed (lwmutex=*0x%x, owner=0x%x)", lwmutex, old); } return CELL_ETIMEDOUT; } - sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): unexpected syscall result (0x%x)", lwcond, res); - return res; + throw EXCEPTION("Unexpected syscall result (lwcond=*0x%x, result=0x%x)", lwcond, res); } -std::string ps3_fmt(PPUThread& context, vm::ptr fmt, u32 g_count, u32 f_count, u32 v_count) +s64 sys_time_get_system_time() +{ + sysPrxForUser.Log("sys_time_get_system_time()"); + + return get_system_time(); +} + +std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_count, u32 v_count) { std::string result; @@ -743,7 +749,7 @@ std::string ps3_fmt(PPUThread& context, vm::ptr fmt, u32 g_count, u3 case 's': { // string - auto string = vm::ptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); + auto string = vm::cptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; @@ -752,7 +758,7 @@ std::string ps3_fmt(PPUThread& context, vm::ptr fmt, u32 g_count, u3 } } - throw fmt::format("ps3_fmt(): unknown formatting: '%s'", start.get_ptr()); + throw EXCEPTION("Unknown formatting: '%s'", start.get_ptr()); } } @@ -762,7 +768,7 @@ std::string ps3_fmt(PPUThread& context, vm::ptr fmt, u32 g_count, u3 return result; } -u32 _sys_heap_create_heap(vm::ptr name, u32 arg2, u32 arg3, u32 arg4) +u32 _sys_heap_create_heap(vm::cptr name, u32 arg2, u32 arg3, u32 arg4) { sysPrxForUser.Warning("_sys_heap_create_heap(name=*0x%x, arg2=0x%x, arg3=0x%x, arg4=0x%x)", name, arg2, arg3, arg4); @@ -860,7 +866,7 @@ s32 sys_spu_image_close(vm::ptr img) return CELL_OK; } -s32 sys_raw_spu_load(s32 id, vm::ptr path, vm::ptr entry) +s32 sys_raw_spu_load(s32 id, vm::cptr path, vm::ptr entry) { sysPrxForUser.Warning("sys_raw_spu_load(id=%d, path=*0x%x, entry=*0x%x)", id, path, entry); sysPrxForUser.Warning("*** path = '%s'", path.get_ptr()); @@ -892,7 +898,7 @@ s32 sys_raw_spu_load(s32 id, vm::ptr path, vm::ptr entry) return CELL_OK; } -s32 sys_raw_spu_image_load(s32 id, vm::ptr img) +s32 sys_raw_spu_image_load(PPUThread& CPU, s32 id, vm::ptr img) { sysPrxForUser.Warning("sys_raw_spu_image_load(id=%d, img=*0x%x)", id, img); @@ -904,7 +910,7 @@ s32 sys_raw_spu_image_load(s32 id, vm::ptr img) const auto stamp1 = get_system_time(); - vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point | be_t::make(1)); + vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point | 1); const auto stamp2 = get_system_time(); @@ -938,7 +944,7 @@ vm::ptr _sys_memset(vm::ptr dst, s32 value, u32 size) return dst; } -vm::ptr _sys_memcpy(vm::ptr dst, vm::ptr src, u32 size) +vm::ptr _sys_memcpy(vm::ptr dst, vm::cptr src, u32 size) { sysPrxForUser.Log("_sys_memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); @@ -947,78 +953,78 @@ vm::ptr _sys_memcpy(vm::ptr dst, vm::ptr src, u32 size) return dst; } -s32 _sys_memcmp(vm::ptr buf1, vm::ptr buf2, u32 size) +s32 _sys_memcmp(vm::cptr buf1, vm::cptr buf2, u32 size) { sysPrxForUser.Log("_sys_memcmp(buf1=*0x%x, buf2=*0x%x, size=%d)", buf1, buf2, size); return memcmp(buf1.get_ptr(), buf2.get_ptr(), size); } -s64 _sys_strlen(vm::ptr str) +s64 _sys_strlen(vm::cptr str) { sysPrxForUser.Log("_sys_strlen(str=*0x%x)", str); return strlen(str.get_ptr()); } -s32 _sys_strcmp(vm::ptr str1, vm::ptr str2) +s32 _sys_strcmp(vm::cptr str1, vm::cptr str2) { sysPrxForUser.Log("_sys_strcmp(str1=*0x%x, str2=*0x%x)", str1, str2); return strcmp(str1.get_ptr(), str2.get_ptr()); } -s32 _sys_strncmp(vm::ptr str1, vm::ptr str2, s32 max) +s32 _sys_strncmp(vm::cptr str1, vm::cptr str2, s32 max) { sysPrxForUser.Log("_sys_strncmp(str1=*0x%x, str2=*0x%x, max=%d)", str1, str2, max); return strncmp(str1.get_ptr(), str2.get_ptr(), max); } -vm::ptr _sys_strcat(vm::ptr dest, vm::ptr source) +vm::ptr _sys_strcat(vm::ptr dest, vm::cptr source) { sysPrxForUser.Log("_sys_strcat(dest=*0x%x, source=*0x%x)", dest, source); if (strcat(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) { - throw "_sys_strcat() failed: unexpected strcat() result"; + throw EXCEPTION("Unexpected strcat() result"); } return dest; } -vm::ptr _sys_strchr(vm::ptr str, s32 ch) +vm::cptr _sys_strchr(vm::cptr str, s32 ch) { sysPrxForUser.Log("_sys_strchr(str=*0x%x, ch=0x%x)", str, ch); - return vm::ptr::make(vm::get_addr(strchr(str.get_ptr(), ch))); + return vm::cptr::make(vm::get_addr(strchr(str.get_ptr(), ch))); } -vm::ptr _sys_strncat(vm::ptr dest, vm::ptr source, u32 len) +vm::ptr _sys_strncat(vm::ptr dest, vm::cptr source, u32 len) { sysPrxForUser.Log("_sys_strncat(dest=*0x%x, source=*0x%x, len=%d)", dest, source, len); if (strncat(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) { - throw "_sys_strncat() failed: unexpected strncat() result"; + throw EXCEPTION("Unexpected strncat() result"); } return dest; } -vm::ptr _sys_strcpy(vm::ptr dest, vm::ptr source) +vm::ptr _sys_strcpy(vm::ptr dest, vm::cptr source) { sysPrxForUser.Log("_sys_strcpy(dest=*0x%x, source=*0x%x)", dest, source); if (strcpy(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) { - throw "_sys_strcpy() failed: unexpected strcpy() result"; + throw EXCEPTION("Unexpected strcpy() result"); } return dest; } -vm::ptr _sys_strncpy(vm::ptr dest, vm::ptr source, u32 len) +vm::ptr _sys_strncpy(vm::ptr dest, vm::cptr source, u32 len) { sysPrxForUser.Log("_sys_strncpy(dest=*0x%x, source=*0x%x, len=%d)", dest, source, len); @@ -1029,7 +1035,7 @@ vm::ptr _sys_strncpy(vm::ptr dest, vm::ptr source, u32 l if (strncpy(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) { - throw "_sys_strncpy() failed: unexpected strncpy() result"; + throw EXCEPTION("Unexpected strncpy() result"); } return dest; @@ -1134,11 +1140,11 @@ s32 _sys_free(u32 addr) return CELL_OK; } -s32 _sys_snprintf(PPUThread& CPU, vm::ptr dst, u32 count, vm::ptr fmt) // va_args... +s32 _sys_snprintf(PPUThread& CPU, vm::ptr dst, u32 count, vm::cptr fmt, ppu_va_args_t va_args) { sysPrxForUser.Warning("_sys_snprintf(dst=*0x%x, count=%d, fmt=*0x%x, ...)", dst, count, fmt); - std::string result = ps3_fmt(CPU, fmt, 3, 0, 0); + std::string result = ps3_fmt(CPU, fmt, va_args.g_count, va_args.f_count, va_args.v_count); sysPrxForUser.Warning("*** '%s' -> '%s'", fmt.get_ptr(), result); @@ -1156,14 +1162,12 @@ s32 _sys_snprintf(PPUThread& CPU, vm::ptr dst, u32 count, vm::ptr fmt) // va_args... +s32 _sys_printf(vm::cptr fmt, ppu_va_args_t va_args) { sysPrxForUser.Todo("_sys_printf(fmt=*0x%x, ...)", fmt); // probably, assertion failed - sysPrxForUser.Fatal("_sys_printf: \n%s", fmt.get_ptr()); - Emu.Pause(); - return CELL_OK; + throw EXCEPTION("%s", fmt.get_ptr()); } s32 sys_process_get_paramsfo(vm::ptr buffer) @@ -1179,7 +1183,7 @@ void sys_spinlock_initialize(vm::ptr> lock) sysPrxForUser.Log("sys_spinlock_initialize(lock=*0x%x)", lock); // prx: set 0 and sync - lock->exchange(be_t::make(0)); + lock->exchange(0); } void sys_spinlock_lock(vm::ptr> lock) @@ -1187,15 +1191,11 @@ void sys_spinlock_lock(vm::ptr> lock) sysPrxForUser.Log("sys_spinlock_lock(lock=*0x%x)", lock); // prx: exchange with 0xabadcafe, repeat until exchanged with 0 - while (lock->exchange(be_t::make(0xabadcafe)).data()) + while (lock->exchange(0xabadcafe).data()) { - g_sys_spinlock_wm.wait_op(lock.addr(), [lock](){ return lock->read_relaxed().data() == 0; }); + g_sys_spinlock_wm.wait_op(lock.addr(), WRAP_EXPR(!lock->load().data())); - if (Emu.IsStopped()) - { - sysPrxForUser.Warning("sys_spinlock_lock(lock=*0x%x) aborted", lock); - break; - } + CHECK_EMU_STATUS; } } @@ -1204,7 +1204,7 @@ s32 sys_spinlock_trylock(vm::ptr> lock) sysPrxForUser.Log("sys_spinlock_trylock(lock=*0x%x)", lock); // prx: exchange with 0xabadcafe, translate exchanged value - if (lock->exchange(be_t::make(0xabadcafe)).data()) + if (lock->exchange(0xabadcafe).data()) { return CELL_EBUSY; } @@ -1217,12 +1217,12 @@ void sys_spinlock_unlock(vm::ptr> lock) sysPrxForUser.Log("sys_spinlock_unlock(lock=*0x%x)", lock); // prx: sync and set 0 - lock->exchange(be_t::make(0)); + lock->exchange(0); g_sys_spinlock_wm.notify(lock.addr()); } -s32 sys_ppu_thread_create(PPUThread& CPU, vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) +s32 sys_ppu_thread_create(PPUThread& CPU, vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr threadname) { sysPrxForUser.Warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, entry, arg, prio, stacksize, flags, threadname); @@ -1274,13 +1274,15 @@ void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm std::lock_guard lock(g_once_mutex); - if (once_ctrl->compare_and_swap_test(be_t::make(SYS_PPU_THREAD_ONCE_INIT), be_t::make(SYS_PPU_THREAD_DONE_INIT))) + if (once_ctrl->compare_and_swap_test(SYS_PPU_THREAD_ONCE_INIT, SYS_PPU_THREAD_DONE_INIT)) { // call init function using current thread context init(CPU); } } +u32 g_ppu_func_index__sys_lwmutex_unlock; // test + Module sysPrxForUser("sysPrxForUser", []() { g_tls_start = 0; @@ -1303,7 +1305,7 @@ Module sysPrxForUser("sysPrxForUser", []() REG_FUNC(sysPrxForUser, sys_lwmutex_destroy); REG_FUNC(sysPrxForUser, sys_lwmutex_lock); REG_FUNC(sysPrxForUser, sys_lwmutex_trylock); - REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); + g_ppu_func_index__sys_lwmutex_unlock = REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); // test REG_FUNC(sysPrxForUser, sys_lwcond_create); REG_FUNC(sysPrxForUser, sys_lwcond_destroy); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h index 41aa474d9f..f491f38465 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct HeapInfo { const std::string name; @@ -39,3 +41,5 @@ s32 sys_lwcond_signal(PPUThread& CPU, vm::ptr lwcond); s32 sys_lwcond_signal_all(PPUThread& CPU, vm::ptr lwcond); s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr lwcond, u32 ppu_thread_id); s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout); + +void sys_ppu_thread_exit(PPUThread& CPU, u64 val); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp b/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp index 858263109e..7f824b27ff 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp @@ -4,13 +4,15 @@ #include "Emu/SysCalls/Modules.h" #include "Emu/Cell/PPUInstrTable.h" +namespace vm { using namespace ps3; } + extern Module sys_libc; namespace sys_libc_func { - void memcpy(vm::ptr dst, vm::ptr src, u32 size) + void memcpy(vm::ptr dst, vm::cptr src, u32 size) { - sys_libc.Log("memcpy(dst=0x%x, src=0x%x, size=0x%x)", dst, src, size); + sys_libc.Log("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); ::memcpy(dst.get_ptr(), src.get_ptr(), size); } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.cpp b/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.cpp new file mode 100644 index 0000000000..708d4e913f --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.cpp @@ -0,0 +1,230 @@ +#include "stdafx.h" +#include "Emu/Memory/Memory.h" +#include "Emu/System.h" +#include "Emu/IdManager.h" +#include "Emu/SysCalls/Modules.h" + +#include "sys_lv2dbg.h" + +extern Module sys_lv2dbg; + +s32 sys_dbg_read_ppu_thread_context(u64 id, vm::ptr ppu_context) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_read_spu_thread_context(u32 id, vm::ptr spu_context) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_read_spu_thread_context2(u32 id, vm::ptr spu_context) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_set_stacksize_ppu_exception_handler(u32 stacksize) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_initialize_ppu_exception_handler(s32 prio) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_finalize_ppu_exception_handler() +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_register_ppu_exception_handler(vm::ptr callback, u64 ctrl_flags) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_unregister_ppu_exception_handler() +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_signal_to_ppu_exception_handler(u64 flags) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_mutex_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_cond_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_rwlock_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_event_queue_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_semaphore_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_lwmutex_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_lwcond_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_event_flag_information(u32 id, vm::ptr info) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_ppu_thread_ids(vm::ptr ids, vm::ptr ids_num, vm::ptr all_ids_num) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_spu_thread_group_ids(vm::ptr ids, vm::ptr ids_num, vm::ptr all_ids_num) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_spu_thread_ids(u32 group_id, vm::ptr ids, vm::ptr ids_num, vm::ptr all_ids_num) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_ppu_thread_name(u64 id, vm::ptr name) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_spu_thread_name(u32 id, vm::ptr name) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_spu_thread_group_name(u32 id, vm::ptr name) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_get_ppu_thread_status(u64 id, vm::ptr status) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_spu_thread_group_status(u32 id, vm::ptr status) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_enable_floating_point_enabled_exception(u64 id, u64 flags, u64 opt1, u64 opt2) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_disable_floating_point_enabled_exception(u64 id, u64 flags, u64 opt1, u64 opt2) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_vm_get_page_information(u32 addr, u32 num, vm::ptr pageinfo) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_set_address_to_dabr(u64 addr, u64 ctrl_flag) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_get_address_from_dabr(vm::ptr addr, vm::ptr ctrl_flag) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_signal_to_coredump_handler(u64 data1, u64 data2, u64 data3) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_mat_set_condition(u32 addr, u64 cond) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_mat_get_condition(u32 addr, vm::ptr condp) +{ + throw EXCEPTION(""); +} + + +s32 sys_dbg_get_coredump_params(vm::ptr param) +{ + throw EXCEPTION(""); +} + +s32 sys_dbg_set_mask_to_ppu_exception_handler(u64 mask, u64 flags) +{ + throw EXCEPTION(""); +} + +Module sys_lv2dbg("sys_lv2dbg", [] +{ + REG_FUNC(sys_lv2dbg, sys_dbg_read_ppu_thread_context); + REG_FUNC(sys_lv2dbg, sys_dbg_read_spu_thread_context); + REG_FUNC(sys_lv2dbg, sys_dbg_read_spu_thread_context2); + REG_FUNC(sys_lv2dbg, sys_dbg_set_stacksize_ppu_exception_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_initialize_ppu_exception_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_finalize_ppu_exception_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_register_ppu_exception_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_unregister_ppu_exception_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_signal_to_ppu_exception_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_get_mutex_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_cond_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_rwlock_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_event_queue_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_semaphore_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_lwmutex_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_lwcond_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_event_flag_information); + REG_FUNC(sys_lv2dbg, sys_dbg_get_ppu_thread_ids); + REG_FUNC(sys_lv2dbg, sys_dbg_get_spu_thread_group_ids); + REG_FUNC(sys_lv2dbg, sys_dbg_get_spu_thread_ids); + REG_FUNC(sys_lv2dbg, sys_dbg_get_ppu_thread_name); + REG_FUNC(sys_lv2dbg, sys_dbg_get_spu_thread_name); + REG_FUNC(sys_lv2dbg, sys_dbg_get_spu_thread_group_name); + REG_FUNC(sys_lv2dbg, sys_dbg_get_ppu_thread_status); + REG_FUNC(sys_lv2dbg, sys_dbg_get_spu_thread_group_status); + REG_FUNC(sys_lv2dbg, sys_dbg_enable_floating_point_enabled_exception); + REG_FUNC(sys_lv2dbg, sys_dbg_disable_floating_point_enabled_exception); + REG_FUNC(sys_lv2dbg, sys_dbg_vm_get_page_information); + REG_FUNC(sys_lv2dbg, sys_dbg_set_address_to_dabr); + REG_FUNC(sys_lv2dbg, sys_dbg_get_address_from_dabr); + REG_FUNC(sys_lv2dbg, sys_dbg_signal_to_coredump_handler); + REG_FUNC(sys_lv2dbg, sys_dbg_mat_set_condition); + REG_FUNC(sys_lv2dbg, sys_dbg_mat_get_condition); + REG_FUNC(sys_lv2dbg, sys_dbg_get_coredump_params); + REG_FUNC(sys_lv2dbg, sys_dbg_set_mask_to_ppu_exception_handler); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.h b/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.h new file mode 100644 index 0000000000..04a786d0dd --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.h @@ -0,0 +1,290 @@ +#pragma once + +#include "Emu/SysCalls/lv2/sys_mutex.h" +#include "Emu/SysCalls/lv2/sys_cond.h" +#include "Emu/SysCalls/lv2/sys_rwlock.h" +#include "Emu/SysCalls/lv2/sys_event.h" +#include "Emu/SysCalls/lv2/sys_semaphore.h" +#include "Emu/SysCalls/lv2/sys_lwmutex.h" +#include "Emu/SysCalls/lv2/sys_lwcond.h" +#include "Emu/SysCalls/lv2/sys_event_flag.h" + +namespace vm { using namespace ps3; } + +// Error Codes +enum +{ + CELL_LV2DBG_ERROR_DEINVALIDPROCESSID = 0x80010401, + CELL_LV2DBG_ERROR_DEINVALIDTHREADID = 0x80010402, + CELL_LV2DBG_ERROR_DEILLEGALREGISTERTYPE = 0x80010403, + CELL_LV2DBG_ERROR_DEILLEGALREGISTERNUMBER = 0x80010404, + CELL_LV2DBG_ERROR_DEILLEGALTHREADSTATE = 0x80010405, + CELL_LV2DBG_ERROR_DEINVALIDEFFECTIVEADDRESS = 0x80010406, + CELL_LV2DBG_ERROR_DENOTFOUNDPROCESSID = 0x80010407, + CELL_LV2DBG_ERROR_DENOMEM = 0x80010408, + CELL_LV2DBG_ERROR_DEINVALIDARGUMENTS = 0x80010409, + CELL_LV2DBG_ERROR_DENOTFOUNDFILE = 0x8001040a, + CELL_LV2DBG_ERROR_DEINVALIDFILETYPE = 0x8001040b, + CELL_LV2DBG_ERROR_DENOTFOUNDTHREADID = 0x8001040c, + CELL_LV2DBG_ERROR_DEINVALIDTHREADSTATUS = 0x8001040d, + CELL_LV2DBG_ERROR_DENOAVAILABLEPROCESSID = 0x8001040e, + CELL_LV2DBG_ERROR_DENOTFOUNDEVENTHANDLER = 0x8001040f, + CELL_LV2DBG_ERROR_DESPNOROOM = 0x80010410, + CELL_LV2DBG_ERROR_DESPNOTFOUND = 0x80010411, + CELL_LV2DBG_ERROR_DESPINPROCESS = 0x80010412, + CELL_LV2DBG_ERROR_DEINVALIDPRIMARYSPUTHREADID = 0x80010413, + CELL_LV2DBG_ERROR_DETHREADSTATEISNOTSTOPPED = 0x80010414, + CELL_LV2DBG_ERROR_DEINVALIDTHREADTYPE = 0x80010415, + CELL_LV2DBG_ERROR_DECONTINUEFAILED = 0x80010416, + CELL_LV2DBG_ERROR_DESTOPFAILED = 0x80010417, + CELL_LV2DBG_ERROR_DENOEXCEPTION = 0x80010418, + CELL_LV2DBG_ERROR_DENOMOREEVENTQUE = 0x80010419, + CELL_LV2DBG_ERROR_DEEVENTQUENOTCREATED = 0x8001041a, + CELL_LV2DBG_ERROR_DEEVENTQUEOVERFLOWED = 0x8001041b, + CELL_LV2DBG_ERROR_DENOTIMPLEMENTED = 0x8001041c, + CELL_LV2DBG_ERROR_DEQUENOTREGISTERED = 0x8001041d, + CELL_LV2DBG_ERROR_DENOMOREEVENTPROCESS = 0x8001041e, + CELL_LV2DBG_ERROR_DEPROCESSNOTREGISTERED = 0x8001041f, + CELL_LV2DBG_ERROR_DEEVENTDISCARDED = 0x80010420, + CELL_LV2DBG_ERROR_DENOMORESYNCID = 0x80010421, + CELL_LV2DBG_ERROR_DESYNCIDALREADYADDED = 0x80010422, + CELL_LV2DBG_ERROR_DESYNCIDNOTFOUND = 0x80010423, + CELL_LV2DBG_ERROR_DESYNCIDNOTACQUIRED = 0x80010424, + CELL_LV2DBG_ERROR_DEPROCESSALREADYREGISTERED = 0x80010425, + CELL_LV2DBG_ERROR_DEINVALIDLSADDRESS = 0x80010426, + CELL_LV2DBG_ERROR_DEINVALIDOPERATION = 0x80010427, + CELL_LV2DBG_ERROR_DEINVALIDMODULEID = 0x80010428, + CELL_LV2DBG_ERROR_DEHANDLERALREADYREGISTERED = 0x80010429, + CELL_LV2DBG_ERROR_DEINVALIDHANDLER = 0x8001042a, + CELL_LV2DBG_ERROR_DEHANDLENOTREGISTERED = 0x8001042b, + CELL_LV2DBG_ERROR_DEOPERATIONDENIED = 0x8001042c, + CELL_LV2DBG_ERROR_DEHANDLERNOTINITIALIZED = 0x8001042d, + CELL_LV2DBG_ERROR_DEHANDLERALREADYINITIALIZED = 0x8001042e, + CELL_LV2DBG_ERROR_DEILLEGALCOREDUMPPARAMETER = 0x8001042f, +}; + +enum : u64 +{ + SYS_DBG_PPU_THREAD_STOP = 0x0000000000000001ull, + SYS_DBG_SPU_THREAD_GROUP_STOP = 0x0000000000000002ull, + SYS_DBG_SYSTEM_PPU_THREAD_NOT_STOP = 0x0000000000000004ull, + SYS_DBG_SYSTEM_SPU_THREAD_GROUP_NOT_STOP = 0x0000000000000008ull, + SYS_DBG_NOT_EXE_CTRL_BY_COREDUMP_EVENT = 0x0000000000000010ull, +}; + +enum : u64 +{ + SYS_DBG_PPU_EXCEPTION_TRAP = 0x0000000001000000ull, + SYS_DBG_PPU_EXCEPTION_PREV_INST = 0x0000000002000000ull, + SYS_DBG_PPU_EXCEPTION_ILL_INST = 0x0000000004000000ull, + SYS_DBG_PPU_EXCEPTION_TEXT_HTAB_MISS = 0x0000000008000000ull, + SYS_DBG_PPU_EXCEPTION_TEXT_SLB_MISS = 0x0000000010000000ull, + SYS_DBG_PPU_EXCEPTION_DATA_HTAB_MISS = 0x0000000020000000ull, + SYS_DBG_PPU_EXCEPTION_DATA_SLB_MISS = 0x0000000040000000ull, + SYS_DBG_PPU_EXCEPTION_FLOAT = 0x0000000080000000ull, + SYS_DBG_PPU_EXCEPTION_DABR_MATCH = 0x0000000100000000ull, + SYS_DBG_PPU_EXCEPTION_ALIGNMENT = 0x0000000200000000ull, + SYS_DBG_PPU_EXCEPTION_DATA_MAT = 0x0000002000000000ull, +}; + +enum : u64 +{ + SYS_DBG_EVENT_CORE_DUMPED = 0x0000000000001000ull, + SYS_DBG_EVENT_PPU_EXCEPTION_HANDLER_SIGNALED = 0x0000000000002000ull, +}; + +union sys_dbg_vr_t +{ + u8 byte[16]; + be_t halfword[8]; + be_t word[8]; + be_t dw[2]; +}; + +struct sys_dbg_ppu_thread_context_t +{ + be_t gpr[32]; + be_t cr; + be_t xer; + be_t lr; + be_t ctr; + be_t pc; + be_t fpr[32]; + be_t fpscr; + sys_dbg_vr_t vr[32]; + sys_dbg_vr_t vscr; +}; + +union sys_dbg_spu_gpr_t +{ + u8 byte[16]; + be_t halfword[8]; + be_t word[4]; + be_t dw[2]; +}; + +union sys_dbg_spu_fpscr_t +{ + u8 byte[16]; + be_t halfword[8]; + be_t word[4]; + be_t dw[2]; +}; + +struct sys_dbg_spu_thread_context_t +{ + sys_dbg_spu_gpr_t gpr[128]; + be_t npc; + be_t fpscr; + be_t srr0; + be_t spu_status; + be_t spu_cfg; + be_t mb_stat; + be_t ppu_mb; + be_t spu_mb[4]; + be_t decrementer; + be_t mfc_cq_sr[96]; +}; + +struct sys_dbg_spu_thread_context2_t +{ + sys_dbg_spu_gpr_t gpr[128]; + be_t npc; + sys_dbg_spu_fpscr_t fpscr; + be_t srr0; + be_t spu_status; + be_t spu_cfg; + be_t mb_stat; + be_t ppu_mb; + be_t spu_mb[4]; + be_t decrementer; + be_t mfc_cq_sr[96]; +}; + +struct sys_dbg_mutex_information_t +{ + sys_mutex_attribute_t attr; + be_t owner; + be_t lock_counter; + be_t cond_ref_counter; + be_t cond_id; // zero + vm::bptr wait_id_list; + be_t wait_threads_num; + be_t wait_all_threads_num; +}; + +struct sys_dbg_cond_information_t +{ + sys_cond_attribute_t attr; + be_t mutex_id; + vm::bptr wait_id_list; + be_t wait_threads_num; + be_t wait_all_threads_num; +}; + +struct sys_dbg_rwlock_information_t +{ + sys_rwlock_attribute_t attr; + be_t owner; + vm::bptr r_wait_id_list; + be_t r_wait_threads_num; + be_t r_wait_all_threads_num; + vm::bptr w_wait_id_list; + be_t w_wait_threads_num; + be_t w_wait_all_threads_num; +}; + +struct sys_dbg_event_queue_information_t +{ + sys_event_queue_attribute_t attr; + be_t event_queue_key; + be_t queue_size; + vm::bptr wait_id_list; + be_t wait_threads_num; + be_t wait_all_threads_num; + vm::bptr equeue_list; + be_t readable_equeue_num; + be_t readable_all_equeue_num; +}; + +struct sys_dbg_semaphore_information_t +{ + sys_semaphore_attribute_t attr; + be_t max_val; + be_t cur_val; + vm::bptr wait_id_list; + be_t wait_threads_num; + be_t wait_all_threads_num; +}; + +struct sys_dbg_lwmutex_information_t +{ + sys_lwmutex_attribute_t attr; + be_t owner; + be_t lock_counter; + vm::bptr wait_id_list; + be_t wait_threads_num; + be_t wait_all_threads_num; +}; + +struct sys_dbg_lwcond_information_t +{ + sys_lwcond_attribute_t attr; + vm::bptr lwmutex; + vm::bptr wait_id_list; + be_t wait_threads_num; + be_t wait_all_threads_num; +}; + +struct sys_dbg_event_flag_wait_information_t +{ + be_t bitptn; + be_t mode; +}; + +struct sys_dbg_event_flag_information_t +{ + sys_event_flag_attribute_t attr; + be_t cur_bitptn; + vm::bptr wait_id_list; + vm::bptr wait_info_list; + be_t wait_threads_num; + be_t wait_all_threads_num; +}; + +using dbg_exception_handler_t = func_def; + +enum : u64 +{ + SYS_VM_STATE_LOCKED = 0x0008ull, + SYS_VM_STATE_DIRTY = 0x0010ull, +}; + +struct sys_vm_page_information_t +{ + be_t state; +}; + +enum : u64 +{ + SYS_DBG_DABR_CTRL_READ = 0x0000000000000005ull, + SYS_DBG_DABR_CTRL_WRITE = 0x0000000000000006ull, + SYS_DBG_DABR_CTRL_CLEAR = 0x0000000000000000ull, +}; + +enum +{ + SYS_DBG_MAT_TRANSPARENT = 1, + SYS_DBG_MAT_WRITE = 2, + SYS_DBG_MAT_READ_WRITE = 4, + SYS_MAT_GRANULARITY = 4096, +}; + +enum sys_dbg_coredump_parameter_t : s32 +{ + SYS_DBG_COREDUMP_OFF, + SYS_DBG_COREDUMP_ON_SAVE_TO_APP_HOME, + SYS_DBG_COREDUMP_ON_SAVE_TO_DEV_MS, + SYS_DBG_COREDUMP_ON_SAVE_TO_DEV_USB, + SYS_DBG_COREDUMP_ON_SAVE_TO_DEV_HDD0, +}; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 4dcfe97863..e20bf4c0b6 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -97,7 +97,7 @@ namespace sys_net_func // Functions s32 accept(s32 s, vm::ptr addr, vm::ptr paddrlen) { - sys_net.Warning("accept(s=%d, family_addr=0x%x, paddrlen=0x%x)", s, addr.addr(), paddrlen.addr()); + sys_net.Warning("accept(s=%d, family=*0x%x, paddrlen=*0x%x)", s, addr, paddrlen); if (!addr) { int ret = ::accept(s, nullptr, nullptr); *g_lastError = getLastError(); @@ -117,7 +117,7 @@ namespace sys_net_func s32 bind(s32 s, vm::ptr addr, u32 addrlen) { - sys_net.Warning("bind(s=%d, family_addr=0x%x, addrlen=%d)", s, addr.addr(), addrlen); + sys_net.Warning("bind(s=%d, family=*0x%x, addrlen=%d)", s, addr, addrlen); sockaddr_in saddr; memcpy(&saddr, addr.get_ptr(), sizeof(sockaddr_in)); saddr.sin_family = addr->sin_family; @@ -130,7 +130,7 @@ namespace sys_net_func s32 connect(s32 s, vm::ptr addr, u32 addrlen) { - sys_net.Warning("connect(s=%d, family_addr=0x%x, addrlen=%d)", s, addr.addr(), addrlen); + sys_net.Warning("connect(s=%d, family=*0x%x, addrlen=%d)", s, addr, addrlen); sockaddr_in saddr; memcpy(&saddr, addr.get_ptr(), sizeof(sockaddr_in)); saddr.sin_family = addr->sin_family; @@ -171,9 +171,9 @@ namespace sys_net_func return CELL_OK; } - s32 inet_addr(vm::ptr cp) + s32 inet_addr(vm::cptr cp) { - sys_net.Warning("inet_addr(cp_addr=0x%x['%s'])", cp.addr(), cp.get_ptr()); + sys_net.Warning("inet_addr(cp=*0x%x)", cp.addr()); return htonl(::inet_addr(cp.get_ptr())); // return a big-endian IP address (WTF? function should return LITTLE-ENDIAN value) } @@ -219,9 +219,9 @@ namespace sys_net_func return CELL_OK; } - s32 inet_pton(s32 af, vm::ptr src, vm::ptr dst) + s32 inet_pton(s32 af, vm::cptr src, vm::ptr dst) { - sys_net.Warning("inet_pton(af=%d, src_addr=0x%x, dst_addr=0x%x)", af, src.addr(), dst.addr()); + sys_net.Warning("inet_pton(af=%d, src=*0x%x, dst=*0x%x)", af, src, dst); return ::inet_pton(af, src.get_ptr(), dst.get_ptr()); } @@ -236,7 +236,7 @@ namespace sys_net_func s32 recv(s32 s, vm::ptr buf, u32 len, s32 flags) { - sys_net.Warning("recv(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf.addr(), len, flags); + sys_net.Warning("recv(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags); int ret = ::recv(s, buf.get_ptr(), len, flags); *g_lastError = getLastError(); @@ -245,8 +245,7 @@ namespace sys_net_func s32 recvfrom(s32 s, vm::ptr buf, u32 len, s32 flags, vm::ptr addr, vm::ptr paddrlen) { - sys_net.Warning("recvfrom(s=%d, buf_addr=0x%x, len=%d, flags=0x%x, addr_addr=0x%x, paddrlen=0x%x)", - s, buf.addr(), len, flags, addr.addr(), paddrlen.addr()); + sys_net.Warning("recvfrom(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, paddrlen=*0x%x)", s, buf, len, flags, addr, paddrlen); sockaddr _addr; memcpy(&_addr, addr.get_ptr(), sizeof(sockaddr)); @@ -264,9 +263,9 @@ namespace sys_net_func return CELL_OK; } - s32 send(s32 s, vm::ptr buf, u32 len, s32 flags) + s32 send(s32 s, vm::cptr buf, u32 len, s32 flags) { - sys_net.Warning("send(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf.addr(), len, flags); + sys_net.Warning("send(s=%d, buf=*0x%x, len=%d, flags=0x%x)", s, buf, len, flags); int ret = ::send(s, buf.get_ptr(), len, flags); *g_lastError = getLastError(); @@ -279,10 +278,9 @@ namespace sys_net_func return CELL_OK; } - s32 sendto(s32 s, vm::ptr buf, u32 len, s32 flags, vm::ptr addr, u32 addrlen) + s32 sendto(s32 s, vm::cptr buf, u32 len, s32 flags, vm::ptr addr, u32 addrlen) { - sys_net.Warning("sendto(s=%d, buf_addr=0x%x, len=%d, flags=0x%x, addr=0x%x, addrlen=%d)", - s, buf.addr(), len, flags, addr.addr(), addrlen); + sys_net.Warning("sendto(s=%d, buf=*0x%x, len=%d, flags=0x%x, addr=*0x%x, addrlen=%d)", s, buf, len, flags, addr, addrlen); sockaddr _addr; memcpy(&_addr, addr.get_ptr(), sizeof(sockaddr)); @@ -292,9 +290,9 @@ namespace sys_net_func return ret; } - s32 setsockopt(s32 s, s32 level, s32 optname, vm::ptr optval, u32 optlen) + s32 setsockopt(s32 s, s32 level, s32 optname, vm::cptr optval, u32 optlen) { - sys_net.Warning("socket(s=%d, level=%d, optname=%d, optval_addr=0x%x, optlen=%d)", s, level, optname, optval.addr(), optlen); + sys_net.Warning("socket(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen); int ret = ::setsockopt(s, level, optname, optval.get_ptr(), optlen); *g_lastError = getLastError(); @@ -344,7 +342,7 @@ namespace sys_net_func s32 sys_net_initialize_network_ex(vm::ptr param) { - sys_net.Warning("sys_net_initialize_network_ex(param_addr=0x%x)", param.addr()); + sys_net.Warning("sys_net_initialize_network_ex(param=*0x%x)", param); g_lastError = vm::ptr::make((u32)Memory.Alloc(4, 1)); #ifdef _WIN32 WSADATA wsaData; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.h b/rpcs3/Emu/SysCalls/Modules/sys_net.h index 37b04d05eb..939ec86227 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.h +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct sys_net_initialize_parameter { be_t memory_addr; diff --git a/rpcs3/Emu/Audio/sysutil_audio.h b/rpcs3/Emu/SysCalls/Modules/sysutil_audio.h similarity index 99% rename from rpcs3/Emu/Audio/sysutil_audio.h rename to rpcs3/Emu/SysCalls/Modules/sysutil_audio.h index 2fd567461f..ca09ee29d1 100644 --- a/rpcs3/Emu/Audio/sysutil_audio.h +++ b/rpcs3/Emu/SysCalls/Modules/sysutil_audio.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + //error codes enum AudioErrorCode { diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 7ffde175f1..ac7690d807 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -1,24 +1,36 @@ #pragma once + #include "Emu/Cell/PPUThread.h" using ppu_func_caller = void(*)(PPUThread&); +struct ppu_va_args_t +{ + u32 g_count; + u32 f_count; + u32 v_count; +}; + namespace ppu_func_detail { - enum arg_class : u8 + // argument type classification + enum arg_class : u32 { - ARG_GENERAL, - ARG_FLOAT, - ARG_VECTOR, - ARG_STACK, + ARG_GENERAL, // argument is stored in GPR registers (from r3 to r10) + ARG_FLOAT, // argument is stored in FPR registers (from f1 to f13) + ARG_VECTOR, // argument is stored in VPR registers (from v2 to v13) + ARG_STACK, // argument is stored on the stack + ARG_CONTEXT, // PPUThread& passed, doesn't affect g/f/v_count + ARG_VARIADIC, // information about arg counts already passed, doesn't affect g/f/v_count + ARG_UNKNOWN, }; - template - struct bind_arg; - - template - struct bind_arg + template + struct bind_arg { + static_assert(type == ARG_GENERAL, "Unknown function argument type"); + static_assert(!std::is_pointer::value, "Invalid function argument type (pointer)"); + static_assert(!std::is_reference::value, "Invalid function argument type (reference)"); static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_GENERAL"); static force_inline T get_arg(PPUThread& CPU) @@ -27,7 +39,7 @@ namespace ppu_func_detail } }; - template + template struct bind_arg { static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT"); @@ -38,10 +50,10 @@ namespace ppu_func_detail } }; - template + template struct bind_arg { - static_assert(std::is_same::value, "Invalid function argument type for ARG_VECTOR"); + static_assert(std::is_same, u128>::value, "Invalid function argument type for ARG_VECTOR"); static force_inline T get_arg(PPUThread& CPU) { @@ -49,7 +61,7 @@ namespace ppu_func_detail } }; - template + template struct bind_arg { static_assert(f_count <= 13, "TODO: Unsupported stack argument type (float)"); @@ -59,15 +71,37 @@ namespace ppu_func_detail static force_inline T get_arg(PPUThread& CPU) { // TODO: check stack argument displacement - const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 13, 0) + std::max(v_count - 12, 0)); + const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 13, 0) + std::max(v_count - 12, 0)); return cast_from_ppu_gpr(res); } }; + template + struct bind_arg + { + static_assert(std::is_same::value, "Invalid function argument type for ARG_CONTEXT"); + + static force_inline PPUThread& get_arg(PPUThread& CPU) + { + return CPU; + } + }; + + template + struct bind_arg + { + static_assert(std::is_same::value, "Invalid function argument type for ARG_VARIADIC"); + + static force_inline ppu_va_args_t get_arg(PPUThread& CPU) + { + return{ g_count, f_count, v_count }; + } + }; + template struct bind_result { - static_assert(type == ARG_GENERAL, "Wrong use of bind_result template"); + static_assert(type == ARG_GENERAL, "Unknown function result type"); static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_GENERAL"); static force_inline void put_result(PPUThread& CPU, const T& result) @@ -90,7 +124,7 @@ namespace ppu_func_detail template struct bind_result { - static_assert(std::is_same::value, "Invalid function result type for ARG_VECTOR"); + static_assert(std::is_same, u128>::value, "Invalid function result type for ARG_VECTOR"); static force_inline void put_result(PPUThread& CPU, const T& result) { @@ -98,116 +132,111 @@ namespace ppu_func_detail } }; - struct arg_type_pack + // wrapper for variadic argument info list, each value contains packed argument type and counts of GENERAL, FLOAT and VECTOR arguments + template struct arg_info_pack_t; + + template struct arg_info_pack_t { - arg_class type; - u8 g_count; - u8 f_count; - u8 v_count; + static const u32 last_value = arg_info_pack_t::last_value; }; - template - struct bind_arg_packed + template struct arg_info_pack_t + { + static const u32 last_value = First; + }; + + template<> struct arg_info_pack_t<> + { + static const u32 last_value = 0; + }; + + // argument type + g/f/v_count unpacker + template struct bind_arg_packed { static force_inline T get_arg(PPUThread& CPU) { - return bind_arg> 8), (type_pack >> 16), (type_pack >> 24)>::get_arg(CPU); + return bind_arg(type_pack & 0xff), (type_pack >> 8) & 0xff, (type_pack >> 16) & 0xff, (type_pack >> 24)>::get_arg(CPU); } }; - template - struct call_impl + template + force_inline RT call(PPUThread& CPU, RT(*func)(Args...), arg_info_pack_t) { - static force_inline RT call(F f, Tuple && t) - { - return call_impl::call(f, std::forward(t)); - } - }; - - template - struct call_impl - { - static force_inline RT call(F f, Tuple && t) - { - return f(std::get(std::forward(t))...); - } - }; - - template - force_inline RT call(F f, Tuple && t) - { - using ttype = std::decay_t; - return ppu_func_detail::call_impl::value, std::tuple_size::value>::call(f, std::forward(t)); + // do the actual function call when all arguments are prepared (simultaneous unpacking of Args... and Info...) + return func(bind_arg_packed::get_arg(CPU)...); } - template - force_inline std::tuple<> iterate(PPUThread& CPU) + template + force_inline RT call(PPUThread& CPU, RT(*func)(Args...), arg_info_pack_t info) { - // terminator - return std::tuple<>(); - } + // unpack previous type counts (0/0/0 for the first time) + const u32 g_count = (info.last_value >> 8) & 0xff; + const u32 f_count = (info.last_value >> 16) & 0xff; + const u32 v_count = (info.last_value >> 24); - template - force_inline std::tuple iterate(PPUThread& CPU) - { - static_assert(!std::is_pointer::value, "Invalid function argument type (pointer)"); - static_assert(!std::is_reference::value, "Invalid function argument type (reference)"); // TODO: check calculations const bool is_float = std::is_floating_point::value; - const bool is_vector = std::is_same::value; - const arg_class t = is_float - ? ((f_count >= 13) ? ARG_STACK : ARG_FLOAT) - : (is_vector ? ((v_count >= 12) ? ARG_STACK : ARG_VECTOR) : ((g_count >= 8) ? ARG_STACK : ARG_GENERAL)); - const u32 g = g_count + (is_float || is_vector ? 0 : 1); - const u32 f = f_count + (is_float ? 1 : 0); - const u32 v = v_count + (is_vector ? 1 : 0); + const bool is_vector = std::is_same, u128>::value; + const bool is_context = std::is_same::value; + const bool is_variadic = std::is_same, ppu_va_args_t>::value; + const bool is_general = !is_float && !is_vector && !is_context && !is_variadic; - return std::tuple_cat(std::tuple(bind_arg::get_arg(CPU)), iterate(CPU)); + const arg_class t = + is_general ? (g_count >= 8 ? ARG_STACK : ARG_GENERAL) : + is_float ? (f_count >= 13 ? ARG_STACK : ARG_FLOAT) : + is_vector ? (v_count >= 12 ? ARG_STACK : ARG_VECTOR) : + is_context ? ARG_CONTEXT : + is_variadic ? ARG_VARIADIC : + ARG_UNKNOWN; + + const u32 g = g_count + is_general; + const u32 f = f_count + is_float; + const u32 v = v_count + is_vector; + + return call(CPU, func, arg_info_pack_t{}); } - template - struct result_type + template struct result_type { static_assert(!std::is_pointer::value, "Invalid function result type (pointer)"); static_assert(!std::is_reference::value, "Invalid function result type (reference)"); static const bool is_float = std::is_floating_point::value; - static const bool is_vector = std::is_same::value; + static const bool is_vector = std::is_same, u128>::value; static const arg_class value = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL); }; - template - struct func_binder; - - template - struct func_binder - { - using func_t = void(*)(PPUThread&, T...); - - static void do_call(PPUThread& CPU, func_t func) - { - call(func, std::tuple_cat(std::tuple(CPU), iterate<0, 0, 0, T...>(CPU))); - } - }; + template struct func_binder; template struct func_binder { using func_t = void(*)(T...); - static void do_call(PPUThread& CPU, func_t func) + static force_inline void do_call(PPUThread& CPU, func_t func) { - call(func, iterate<0, 0, 0, T...>(CPU)); + call(CPU, func, arg_info_pack_t<>{}); } }; - template - struct func_binder + template<> + struct func_binder // redundant specialization to bypass internal compiler error in MSVC { - using func_t = RT(*)(PPUThread&, T...); + using func_t = void(*)(); - static void do_call(PPUThread& CPU, func_t func) + static force_inline void do_call(PPUThread& CPU, func_t func) { - bind_result::value>::put_result(CPU, call(func, std::tuple_cat(std::tuple(CPU), iterate<0, 0, 0, T...>(CPU)))); + func(); + } + }; + + template + struct func_binder // redundant specialization to bypass internal compiler error in MSVC + { + using func_t = RT(*)(); + + static force_inline void do_call(PPUThread& CPU, func_t func) + { + bind_result::value>::put_result(CPU, func()); } }; @@ -216,9 +245,9 @@ namespace ppu_func_detail { using func_t = RT(*)(T...); - static void do_call(PPUThread& CPU, func_t func) + static force_inline void do_call(PPUThread& CPU, func_t func) { - bind_result::value>::put_result(CPU, call(func, iterate<0, 0, 0, T...>(CPU))); + bind_result::value>::put_result(CPU, call(CPU, func, arg_info_pack_t<>{})); } }; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index fc3652a1f8..954068371f 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -4,7 +4,7 @@ #include "Utilities/AutoPause.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "ModuleManager.h" +#include "Modules.h" #include "lv2/sleep_queue.h" #include "lv2/sys_lwmutex.h" @@ -29,19 +29,25 @@ #include "lv2/sys_tty.h" #include "lv2/sys_vm.h" #include "lv2/sys_fs.h" +#include "lv2/sys_dbg.h" #include "Emu/SysCalls/Modules/cellGcmSys.h" #include "SysCalls.h" -void null_func(PPUThread& CPU); +void null_func(PPUThread& ppu) +{ + const auto code = ppu.GPR[11]; + LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); + ppu.GPR[3] = 0; +} // UNS = Unused // ROOT = Root // DBG = Debug // PM = Product Mode // AuthID = Authentication ID -const ppu_func_caller sc_table[1024] = +const ppu_func_caller g_sc_table[1024] = { null_func, bind_func(sys_process_getpid), //1 (0x001) @@ -182,7 +188,7 @@ const ppu_func_caller sc_table[1024] = bind_func(sys_time_get_current_time), //145 (0x091) null_func,//bind_func(sys_time_get_system_time), //146 (0x092) ROOT bind_func(sys_time_get_timebase_frequency), //147 (0x093) - null_func,//bind_func(sys_rwlock_trywlock) //148 (0x094) + null_func,//bind_func(_sys_rwlock_trywlock) //148 (0x094) null_func, //149 (0x095) UNS bind_func(sys_raw_spu_create_interrupt_tag), //150 (0x096) bind_func(sys_raw_spu_set_int_mask), //151 (0x097) @@ -886,35 +892,27 @@ const ppu_func_caller sc_table[1024] = null_func, null_func, null_func, bind_func(cellGcmCallback), //1023 UNS }; -void null_func(PPUThread& CPU) -{ - const auto code = CPU.GPR[11]; - LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); - CPU.GPR[3] = 0; -} - void SysCalls::DoSyscall(PPUThread& CPU, u64 code) { if (code >= 1024) { - CPU.m_last_syscall = code; - throw "Invalid syscall number"; + throw EXCEPTION("Invalid syscall number (0x%llx)", code); } - auto old_last_syscall = CPU.m_last_syscall; - CPU.m_last_syscall = ~code; + auto last_code = CPU.hle_code; + CPU.hle_code = ~code; if (Ini.HLELogging.GetValue()) { LOG_NOTICE(PPU, "Syscall %lld called: %s", code, SysCalls::GetFuncName(~code)); } - sc_table[code](CPU); + g_sc_table[code](CPU); if (Ini.HLELogging.GetValue()) { LOG_NOTICE(PPU, "Syscall %lld finished: %s -> 0x%llx", code, SysCalls::GetFuncName(~code), CPU.GPR[3]); } - CPU.m_last_syscall = old_last_syscall; + CPU.hle_code = last_code; } diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp b/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp index ba938fe3b2..f6895edd71 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp @@ -2,257 +2,46 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/IdManager.h" -#include "Emu/CPU/CPUThreadManager.h" -#include "Emu/Cell/PPUThread.h" +#include "Emu/CPU/CPUThread.h" #include "sleep_queue.h" -sleep_queue_t::~sleep_queue_t() +sleep_queue_entry_t::sleep_queue_entry_t(CPUThread& cpu, sleep_queue_t& queue) + : m_queue(queue) + , m_thread(cpu) { - for (auto& tid : m_waiting) - { - LOG_NOTICE(HLE, "~sleep_queue_t['%s']: m_waiting[%lld]=%d", m_name.c_str(), &tid - m_waiting.data(), tid); - } - for (auto& tid : m_signaled) - { - LOG_NOTICE(HLE, "~sleep_queue_t['%s']: m_signaled[%lld]=%d", m_name.c_str(), &tid - m_signaled.data(), tid); - } + m_queue.emplace_back(std::move(cpu.shared_from_this())); + + m_thread.Sleep(); } -void sleep_queue_t::push(u32 tid, u32 protocol) +sleep_queue_entry_t::~sleep_queue_entry_t() noexcept(false) { - assert(tid); + m_thread.Awake(); - switch (protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) + if (m_queue.front().get() == &m_thread) { - case SYS_SYNC_FIFO: - case SYS_SYNC_PRIORITY: - { - std::lock_guard lock(m_mutex); - - for (auto& v : m_waiting) - { - if (v == tid) - { - LOG_ERROR(HLE, "sleep_queue_t['%s']::push() failed: thread already waiting (%d)", m_name.c_str(), tid); - Emu.Pause(); - return; - } - } - - for (auto& v : m_signaled) - { - if (v == tid) - { - LOG_ERROR(HLE, "sleep_queue_t['%s']::push() failed: thread already signaled (%d)", m_name.c_str(), tid); - Emu.Pause(); - return; - } - } - - m_waiting.push_back(tid); + m_queue.pop_front(); return; } - case SYS_SYNC_RETRY: + + if (m_queue.back().get() == &m_thread) { + m_queue.pop_back(); return; } + + for (auto it = m_queue.begin(); it != m_queue.end(); it++) + { + if (it->get() == &m_thread) + { + m_queue.erase(it); + return; + } } - LOG_ERROR(HLE, "sleep_queue_t['%s']::push() failed: unsupported protocol (0x%x)", m_name.c_str(), protocol); - Emu.Pause(); -} - -bool sleep_queue_t::pop(u32 tid, u32 protocol) -{ - assert(tid); - - switch (protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) - { - case SYS_SYNC_FIFO: - case SYS_SYNC_PRIORITY: - { - std::lock_guard lock(m_mutex); - - if (m_signaled.size() && m_signaled[0] == tid) - { - m_signaled.erase(m_signaled.begin()); - return true; - } - - for (auto& v : m_signaled) - { - if (v == tid) - { - return false; - } - } - - for (auto& v : m_waiting) - { - if (v == tid) - { - return false; - } - } - - LOG_ERROR(HLE, "sleep_queue_t['%s']::pop() failed: thread not found (%d)", m_name.c_str(), tid); - Emu.Pause(); - return true; // ??? - } - //case SYS_SYNC_RETRY: // ??? - //{ - // return true; // ??? - //} - } - - LOG_ERROR(HLE, "sleep_queue_t['%s']::pop() failed: unsupported protocol (0x%x)", m_name.c_str(), protocol); - Emu.Pause(); - return false; // ??? -} - -u32 sleep_queue_t::signal(u32 protocol) -{ - u32 res = ~0; - - switch (protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) - { - case SYS_SYNC_FIFO: - { - std::lock_guard lock(m_mutex); - - if (m_waiting.size()) - { - res = m_waiting[0]; - if (!Emu.GetIdManager().check_id(res)) - { - LOG_ERROR(HLE, "sleep_queue_t['%s']::signal(SYS_SYNC_FIFO) failed: invalid thread (%d)", m_name.c_str(), res); - Emu.Pause(); - } - - m_waiting.erase(m_waiting.begin()); - m_signaled.push_back(res); - } - else - { - res = 0; - } - - return res; - } - case SYS_SYNC_PRIORITY: - { - std::lock_guard lock(m_mutex); - - u64 highest_prio = ~0ull; - u64 sel = ~0ull; - for (auto& v : m_waiting) - { - if (const auto t = Emu.GetCPU().GetThread(v)) - { - const u64 prio = t->GetPrio(); - if (prio < highest_prio) - { - highest_prio = prio; - sel = &v - m_waiting.data(); - } - } - else - { - LOG_ERROR(HLE, "sleep_queue_t['%s']::signal(SYS_SYNC_PRIORITY) failed: invalid thread (%d)", m_name.c_str(), v); - Emu.Pause(); - } - } - - if (~sel) - { - res = m_waiting[sel]; - m_waiting.erase(m_waiting.begin() + sel); - m_signaled.push_back(res); - return res; - } - // fallthrough - } - case SYS_SYNC_RETRY: - { - return 0; - } - } - - LOG_ERROR(HLE, "sleep_queue_t['%s']::signal(): unsupported protocol (0x%x)", m_name.c_str(), protocol); - Emu.Pause(); - return 0; -} - -bool sleep_queue_t::invalidate(u32 tid, u32 protocol) -{ - assert(tid); - - switch (protocol & SYS_SYNC_ATTR_PROTOCOL_MASK) - { - case SYS_SYNC_FIFO: - case SYS_SYNC_PRIORITY: - { - std::lock_guard lock(m_mutex); - - for (auto& v : m_waiting) - { - if (v == tid) - { - m_waiting.erase(m_waiting.begin() + (&v - m_waiting.data())); - return true; - } - } - - for (auto& v : m_signaled) - { - if (v == tid) - { - if (&v == m_signaled.data()) - { - return false; // if the thread is signaled, pop() should be used - } - m_signaled.erase(m_signaled.begin() + (&v - m_signaled.data())); - return true; - } - } - - return false; - } - case SYS_SYNC_RETRY: - { - return true; - } - } - - LOG_ERROR(HLE, "sleep_queue_t['%s']::invalidate(): unsupported protocol (0x%x)", m_name.c_str(), protocol); - Emu.Pause(); - return 0; -} - -bool sleep_queue_t::signal_selected(u32 tid) -{ - assert(tid); - - std::lock_guard lock(m_mutex); - - for (auto& v : m_waiting) - { - if (v == tid) - { - m_waiting.erase(m_waiting.begin() + (&v - m_waiting.data())); - m_signaled.push_back(tid); - return true; - } - } - - return false; -} - -u32 sleep_queue_t::count() -{ - std::lock_guard lock(m_mutex); - - return (u32)m_waiting.size() + (u32)m_signaled.size(); + if (!std::uncaught_exception()) + { + throw EXCEPTION("Thread not found"); + } } diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue.h b/rpcs3/Emu/SysCalls/lv2/sleep_queue.h index 4b3a157888..47a04853fc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue.h +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // attr_protocol (waiting scheduling policy) enum { @@ -26,30 +28,31 @@ enum SYS_SYNC_ATTR_RECURSIVE_MASK = 0xF0, //??? }; -class sleep_queue_t +// attr_pshared +enum { - std::vector m_waiting; - std::vector m_signaled; - std::mutex m_mutex; - std::string m_name; + SYS_SYNC_NOT_PROCESS_SHARED = 0x200, +}; + +// attr_adaptive +enum +{ + SYS_SYNC_ADAPTIVE = 0x1000, + SYS_SYNC_NOT_ADAPTIVE = 0x2000, +}; + +using sleep_queue_t = std::deque>; + +// automatic object handling adding threads to the sleep queue +class sleep_queue_entry_t final +{ + CPUThread& m_thread; + sleep_queue_t& m_queue; public: - const u64 name; + // adds specified thread to the sleep queue + sleep_queue_entry_t(CPUThread& cpu, sleep_queue_t& queue); - sleep_queue_t(u64 name = 0) - : name(name) - { - } - - ~sleep_queue_t(); - - void set_full_name(const std::string& name) { m_name = name; } - const std::string& get_full_name() { return m_name; } - - void push(u32 tid, u32 protocol); - bool pop(u32 tid, u32 protocol); - u32 signal(u32 protocol); - bool signal_selected(u32 tid); - bool invalidate(u32 tid, u32 protocol); - u32 count(); + // removes specified thread from the sleep queue + ~sleep_queue_entry_t() noexcept(false); }; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 2d22b1cb6e..142bfcc88c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -4,15 +4,14 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" -#include "sleep_queue.h" -#include "sys_time.h" #include "sys_mutex.h" #include "sys_cond.h" SysCallBase sys_cond("sys_cond"); +extern u64 get_system_time(); + s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr attr) { sys_cond.Warning("sys_cond_create(cond_id=*0x%x, mutex_id=0x%x, attr=*0x%x)", cond_id, mutex_id, attr); @@ -26,7 +25,7 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptrpshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data()) + if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data()) { sys_cond.Error("sys_cond_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags); return CELL_EINVAL; @@ -34,7 +33,7 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptrcond_count) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected cond_count"); } *cond_id = Emu.GetIdManager().make(mutex, attr->name_u64); @@ -55,14 +54,14 @@ s32 sys_cond_destroy(u32 cond_id) return CELL_ESRCH; } - if (!cond->waiters.empty() || cond->signaled) + if (!cond->sq.empty()) { return CELL_EBUSY; } if (!cond->mutex->cond_count--) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected cond_count"); } Emu.GetIdManager().remove(cond_id); @@ -83,11 +82,13 @@ s32 sys_cond_signal(u32 cond_id) return CELL_ESRCH; } - if (!cond->waiters.empty()) + for (auto& thread : cond->sq) { - cond->signaled++; - cond->waiters.erase(cond->waiters.begin()); - cond->cv.notify_one(); + // signal one waiting thread; protocol is ignored in current implementation + if (thread->Signal()) + { + return CELL_OK; + } } return CELL_OK; @@ -106,11 +107,13 @@ s32 sys_cond_signal_all(u32 cond_id) return CELL_ESRCH; } - if (const u32 count = cond->waiters.size()) + for (auto& thread : cond->sq) { - cond->signaled += count; - cond->waiters.clear(); - cond->cv.notify_all(); + // signal all waiting threads; protocol is ignored in current implementation + if (thread->Signal()) + { + ; + } } return CELL_OK; @@ -129,26 +132,21 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) return CELL_ESRCH; } - if (!Emu.GetIdManager().check_id(thread_id)) + // TODO: check if CELL_ESRCH is returned if thread_id is invalid + + for (auto& thread : cond->sq) { - return CELL_ESRCH; + // signal specified thread + if (thread->GetId() == thread_id && thread->Signal()) + { + return CELL_OK; + } } - const auto found = cond->waiters.find(thread_id); - - if (found == cond->waiters.end()) - { - return CELL_EPERM; - } - - cond->signaled++; - cond->waiters.erase(found); - cond->cv.notify_one(); - - return CELL_OK; + return CELL_EPERM; } -s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) +s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout) { sys_cond.Log("sys_cond_wait(cond_id=0x%x, timeout=%lld)", cond_id, timeout); @@ -163,60 +161,85 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) return CELL_ESRCH; } - const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); - - if (cond->mutex->owner.owner_before(thread) || thread.owner_before(cond->mutex->owner)) // check equality + // check current ownership + if (cond->mutex->owner.get() != &ppu) { return CELL_EPERM; } - // add waiter; protocol is ignored in current implementation - cond->waiters.emplace(CPU.GetId()); - // unlock mutex cond->mutex->owner.reset(); - if (cond->mutex->waiters) - { - cond->mutex->cv.notify_one(); - } - // save recursive value const u32 recursive_value = cond->mutex->recursive_count.exchange(0); - while (!cond->mutex->owner.expired() || !cond->signaled || cond->waiters.count(CPU.GetId())) + if (cond->mutex->sq.size()) { - const bool is_timedout = timeout && get_system_time() - start_time > timeout; + // pick another owner; protocol is ignored in current implementation + cond->mutex->owner = cond->mutex->sq.front(); - // check timeout - if (is_timedout && cond->mutex->owner.expired()) + if (!cond->mutex->owner->Signal()) { - // cancel waiting if the mutex is free, restore its owner and recursive value - cond->mutex->owner = thread; - cond->mutex->recursive_count = recursive_value; - - if (!cond->waiters.erase(CPU.GetId())) - { - throw __FUNCTION__; - } - - return CELL_ETIMEDOUT; + throw EXCEPTION("Mutex owner not signaled"); } - - if (Emu.IsStopped()) - { - sys_cond.Warning("sys_cond_wait(id=0x%x) aborted", cond_id); - return CELL_OK; - } - - // wait on appropriate condition variable - (cond->signaled || is_timedout ? cond->mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1)); } - // reown the mutex and restore its recursive value - cond->mutex->owner = thread; + { + // add waiter; protocol is ignored in current implementation + sleep_queue_entry_t waiter(ppu, cond->sq); + + while (!ppu.Signaled()) + { + if (timeout) + { + const u64 passed = get_system_time() - start_time; + + if (passed >= timeout || ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed)) == std::cv_status::timeout) + { + break; + } + } + else + { + ppu.cv.wait(lv2_lock); + } + + CHECK_EMU_STATUS; + } + } + + // reown the mutex (could be set when notified) + if (!cond->mutex->owner) + { + cond->mutex->owner = std::move(ppu.shared_from_this()); + } + + if (cond->mutex->owner.get() != &ppu) + { + // add waiter; protocol is ignored in current implementation + sleep_queue_entry_t waiter(ppu, cond->mutex->sq); + + while (!ppu.Signaled()) + { + ppu.cv.wait(lv2_lock); + + CHECK_EMU_STATUS; + } + + if (cond->mutex->owner.get() != &ppu) + { + throw EXCEPTION("Unexpected mutex owner"); + } + } + + // restore the recursive value cond->mutex->recursive_count = recursive_value; - cond->signaled--; + + // check timeout + if (timeout && get_system_time() - start_time > timeout) + { + return CELL_ETIMEDOUT; + } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.h b/rpcs3/Emu/SysCalls/lv2/sys_cond.h index ee61ee9912..6fbe55e7f2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.h @@ -1,5 +1,9 @@ #pragma once +#include "sleep_queue.h" + +namespace vm { using namespace ps3; } + struct lv2_mutex_t; struct sys_cond_attribute_t @@ -20,17 +24,11 @@ struct lv2_cond_t const u64 name; const std::shared_ptr mutex; // associated mutex - std::atomic signaled; - - // TODO: use sleep queue, possibly remove condition variable - std::condition_variable cv; - std::unordered_set waiters; + sleep_queue_t sq; lv2_cond_t(const std::shared_ptr& mutex, u64 name) : mutex(mutex) , name(name) - , signaled(0) - //, waiters(0) { } }; @@ -42,7 +40,7 @@ class PPUThread; // SysCalls s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr attr); s32 sys_cond_destroy(u32 cond_id); -s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout); +s32 sys_cond_wait(PPUThread& ppu, u32 cond_id, u64 timeout); s32 sys_cond_signal(u32 cond_id); s32 sys_cond_signal_all(u32 cond_id); s32 sys_cond_signal_to(u32 cond_id, u32 thread_id); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_dbg.cpp b/rpcs3/Emu/SysCalls/lv2/sys_dbg.cpp new file mode 100644 index 0000000000..bfa9445bb0 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/sys_dbg.cpp @@ -0,0 +1,9 @@ +#include "stdafx.h" +#include "Emu/Memory/Memory.h" +#include "Emu/System.h" +#include "Emu/IdManager.h" +#include "Emu/SysCalls/SysCalls.h" + +#include "sys_dbg.h" + +SysCallBase sys_dbg("sys_dbg"); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_dbg.h b/rpcs3/Emu/SysCalls/lv2/sys_dbg.h new file mode 100644 index 0000000000..8744312ca5 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/sys_dbg.h @@ -0,0 +1,3 @@ +#pragma once + +namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index ab64c03805..2aaa833447 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -7,13 +7,26 @@ #include "Emu/Cell/PPUThread.h" #include "Emu/Event.h" #include "sleep_queue.h" -#include "sys_time.h" #include "sys_process.h" #include "sys_event.h" SysCallBase sys_event("sys_event"); -s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr attr, u64 event_queue_key, s32 size) +extern u64 get_system_time(); + +lv2_event_queue_t::lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size) + : id(Emu.GetIdManager().get_current_id()) + , protocol(protocol) + , type(type) + , name(name) + , key(key) + , size(size) + , cancelled(false) + , waiters(0) +{ +} + +s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr attr, u64 event_queue_key, s32 size) { sys_event.Warning("sys_event_queue_create(equeue_id=*0x%x, attr=*0x%x, event_queue_key=0x%llx, size=%d)", equeue_id, attr, event_queue_key, size); @@ -40,14 +53,14 @@ s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr default: sys_event.Error("sys_event_queue_create(): unknown type (0x%x)", type); return CELL_EINVAL; } - auto queue = Emu.GetEventManager().MakeEventQueue(protocol, type, attr->name_u64, event_queue_key, size); + const auto queue = Emu.GetEventManager().MakeEventQueue(event_queue_key, protocol, type, attr->name_u64, event_queue_key, size); if (!queue) { return CELL_EEXIST; } - *equeue_id = Emu.GetIdManager().add(std::move(queue)); + *equeue_id = queue->id; return CELL_OK; } @@ -77,7 +90,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) if (queue->cancelled.exchange(true)) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected value"); } if (queue->waiters) @@ -106,7 +119,7 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, if (size < 0) { - throw __FUNCTION__; + throw EXCEPTION("Negative size"); } if (queue->type != SYS_PPU_QUEUE) @@ -118,8 +131,13 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, while (!queue->waiters && count < size && queue->events.size()) { + auto& dest = event_array[count++]; + auto& event = queue->events.front(); - event_array[count++] = { be_t::make(event.source), be_t::make(event.data1), be_t::make(event.data2), be_t::make(event.data3) }; + dest.source = event.source; + dest.data1 = event.data1; + dest.data2 = event.data2; + dest.data3 = event.data3; queue->events.pop_front(); } @@ -154,9 +172,10 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr while (queue->events.empty()) { + CHECK_EMU_STATUS; + if (queue->cancelled) { - queue->waiters--; return CELL_ECANCELED; } @@ -166,12 +185,6 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_event.Warning("sys_event_queue_receive(equeue_id=0x%x) aborted", equeue_id); - return CELL_OK; - } - queue->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.h b/rpcs3/Emu/SysCalls/lv2/sys_event.h index 8d10f379b3..902d45cfc7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Event Queue Type enum : u32 { @@ -13,12 +15,24 @@ enum : s32 SYS_EVENT_QUEUE_DESTROY_FORCE = 1, }; +// Event Queue Ipc Key +enum : u64 +{ + SYS_EVENT_QUEUE_LOCAL = 0x00, +}; + // Event Port Type enum : s32 { SYS_EVENT_PORT_LOCAL = 1, }; +// Event Port Name +enum : u64 +{ + SYS_EVENT_PORT_NO_NAME = 0, +}; + // Event Source Type enum : u32 { @@ -29,11 +43,12 @@ enum : u32 // Event Source Key enum : u64 { - SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501, - SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502, // ??? + SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501ull, + SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502ull, + SYS_SPU_THREAD_EVENT_EXCEPTION_KEY = 0xFFFFFFFF53505503ull, }; -struct sys_event_queue_attr +struct sys_event_queue_attribute_t { be_t protocol; // SYS_SYNC_PRIORITY or SYS_SYNC_FIFO be_t type; // SYS_PPU_QUEUE or SYS_SPU_QUEUE @@ -71,6 +86,7 @@ struct event_t struct lv2_event_queue_t { + const u32 id; const u32 protocol; const s32 type; const u64 name; @@ -84,16 +100,7 @@ struct lv2_event_queue_t std::condition_variable cv; std::atomic waiters; - lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size) - : protocol(protocol) - , type(type) - , name(name) - , key(key) - , size(size) - , cancelled(false) - , waiters(0) - { - } + lv2_event_queue_t(u32 protocol, s32 type, u64 name, u64 key, s32 size); void push(lv2_lock_type& lv2_lock, u64 source, u64 data1, u64 data2, u64 data3) { @@ -128,7 +135,7 @@ REG_ID_TYPE(lv2_event_port_t, 0x0E); // SYS_EVENT_PORT_OBJECT class PPUThread; // SysCalls -s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr attr, u64 event_queue_key, s32 size); +s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr attr, u64 event_queue_key, s32 size); s32 sys_event_queue_destroy(u32 equeue_id, s32 mode); s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr dummy_event, u64 timeout); s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, s32 size, vm::ptr number); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index 14e512ca94..a834cfa630 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -4,15 +4,15 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" #include "sleep_queue.h" -#include "sys_time.h" #include "sys_event_flag.h" SysCallBase sys_event_flag("sys_event_flag"); -s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u64 init) +extern u64 get_system_time(); + +s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u64 init) { sys_event_flag.Warning("sys_event_flag_create(id=*0x%x, attr=*0x%x, init=0x%llx)", id, attr, init); @@ -32,7 +32,7 @@ s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u6 default: sys_event_flag.Error("sys_event_flag_create(): unknown protocol (0x%x)", attr->protocol); return CELL_EINVAL; } - if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data()) + if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data()) { sys_event_flag.Error("sys_event_flag_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags); return CELL_EINVAL; @@ -141,6 +141,8 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t break; } + CHECK_EMU_STATUS; + if (ef->cancelled) { if (!--ef->cancelled) @@ -157,12 +159,6 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_event_flag.Warning("sys_event_flag_wait(id=0x%x) aborted", id); - return CELL_OK; - } - ef->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.h index 348d5c736c..b9218cf684 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 +namespace vm { using namespace ps3; } + enum { SYS_SYNC_WAITER_SINGLE = 0x10000, @@ -12,7 +14,7 @@ enum SYS_EVENT_FLAG_WAIT_CLEAR_ALL = 0x20, }; -struct sys_event_flag_attr +struct sys_event_flag_attribute_t { be_t protocol; be_t pshared; @@ -53,7 +55,7 @@ struct lv2_event_flag_t REG_ID_TYPE(lv2_event_flag_t, 0x98); // SYS_EVENT_FLAG_OBJECT -s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u64 init); +s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u64 init); s32 sys_event_flag_destroy(u32 id); s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 timeout); s32 sys_event_flag_trywait(u32 id, u64 bitptn, u32 mode, vm::ptr result); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index fad6fe9c17..76213f1c3d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -20,7 +20,7 @@ s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr a return CELL_OK; } -s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, vm::ptr arg, u64 size) +s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::cptr arg, u64 size) { sys_fs.Warning("sys_fs_open(path=*0x%x, flags=%#o, fd=*0x%x, mode=%#o, arg=*0x%x, size=0x%llx)", path, flags, fd, mode, arg, size); sys_fs.Warning("*** path = '%s'", path.get_ptr()); @@ -68,6 +68,11 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, open_mode |= o_trunc; } + if (flags & CELL_FS_O_APPEND) + { + open_mode |= o_append; + } + if (flags & CELL_FS_O_EXCL) { if (flags & CELL_FS_O_CREAT) @@ -80,7 +85,7 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, } } - if (flags & ~(CELL_FS_O_ACCMODE | CELL_FS_O_CREAT | CELL_FS_O_TRUNC | CELL_FS_O_EXCL)) + if (flags & ~(CELL_FS_O_ACCMODE | CELL_FS_O_CREAT | CELL_FS_O_TRUNC | CELL_FS_O_APPEND | CELL_FS_O_EXCL)) { open_mode = 0; // error } @@ -92,7 +97,7 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, if (!open_mode) { - sys_fs.Fatal("sys_fs_open('%s'): invalid or unimplemented flags (%#o)", path.get_ptr(), flags); + throw EXCEPTION("Invalid or unimplemented flags (%#o): '%s'", flags, path.get_ptr()); } std::shared_ptr file(Emu.GetVFS().OpenFile(path.get_ptr(), open_mode)); @@ -109,7 +114,7 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, return CELL_FS_ENOENT; } - *fd = Emu.GetIdManager().make(file, mode, flags); + *fd = Emu.GetIdManager().make(std::move(file), mode, flags); return CELL_OK; } @@ -132,7 +137,7 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) return CELL_OK; } -s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite) +s32 sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwrite) { sys_fs.Log("sys_fs_write(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); @@ -170,20 +175,20 @@ s32 sys_fs_close(u32 fd) return CELL_OK; } -s32 sys_fs_opendir(vm::ptr path, vm::ptr fd) +s32 sys_fs_opendir(vm::cptr path, vm::ptr fd) { sys_fs.Warning("sys_fs_opendir(path=*0x%x, fd=*0x%x)", path, fd); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - std::shared_ptr directory(Emu.GetVFS().OpenDir(path.get_ptr())); + std::shared_ptr dir(Emu.GetVFS().OpenDir(path.get_ptr())); - if (!directory || !directory->IsOpened()) + if (!dir || !dir->IsOpened()) { sys_fs.Error("sys_fs_opendir('%s'): failed to open directory", path.get_ptr()); return CELL_FS_ENOENT; } - *fd = Emu.GetIdManager().add(std::move(directory)); + *fd = Emu.GetIdManager().make(std::move(dir)); return CELL_OK; } @@ -199,7 +204,7 @@ s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) return CELL_FS_EBADF; } - const DirEntryInfo* info = directory->Read(); + const DirEntryInfo* info = directory->dir->Read(); if (info) { @@ -232,7 +237,7 @@ s32 sys_fs_closedir(u32 fd) return CELL_OK; } -s32 sys_fs_stat(vm::ptr path, vm::ptr sb) +s32 sys_fs_stat(vm::cptr path, vm::ptr sb) { sys_fs.Warning("sys_fs_stat(path=*0x%x, sb=*0x%x)", path, sb); sys_fs.Warning("*** path = '%s'", path.get_ptr()); @@ -305,7 +310,7 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) return CELL_OK; } -s32 sys_fs_mkdir(vm::ptr path, s32 mode) +s32 sys_fs_mkdir(vm::cptr path, s32 mode) { sys_fs.Warning("sys_fs_mkdir(path=*0x%x, mode=%#o)", path, mode); sys_fs.Warning("*** path = '%s'", path.get_ptr()); @@ -326,7 +331,7 @@ s32 sys_fs_mkdir(vm::ptr path, s32 mode) return CELL_OK; } -s32 sys_fs_rename(vm::ptr from, vm::ptr to) +s32 sys_fs_rename(vm::cptr from, vm::cptr to) { sys_fs.Warning("sys_fs_rename(from=*0x%x, to=*0x%x)", from, to); sys_fs.Warning("*** from = '%s'", from.get_ptr()); @@ -359,7 +364,7 @@ s32 sys_fs_rename(vm::ptr from, vm::ptr to) return CELL_FS_ENOENT; } -s32 sys_fs_rmdir(vm::ptr path) +s32 sys_fs_rmdir(vm::cptr path) { sys_fs.Warning("sys_fs_rmdir(path=*0x%x)", path); sys_fs.Warning("*** path = '%s'", path.get_ptr()); @@ -380,7 +385,7 @@ s32 sys_fs_rmdir(vm::ptr path) return CELL_OK; } -s32 sys_fs_unlink(vm::ptr path) +s32 sys_fs_unlink(vm::cptr path) { sys_fs.Warning("sys_fs_unlink(path=*0x%x)", path); sys_fs.Warning("*** path = '%s'", path.get_ptr()); @@ -449,7 +454,7 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_ return CELL_OK; } -s32 sys_fs_get_block_size(vm::ptr path, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4) +s32 sys_fs_get_block_size(vm::cptr path, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4) { sys_fs.Todo("sys_fs_get_block_size(path=*0x%x, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", path, sector_size, block_size, arg4); sys_fs.Todo("*** path = '%s'", path.get_ptr()); @@ -460,7 +465,7 @@ s32 sys_fs_get_block_size(vm::ptr path, vm::ptr sector_size, vm return CELL_OK; } -s32 sys_fs_truncate(vm::ptr path, u64 size) +s32 sys_fs_truncate(vm::cptr path, u64 size) { sys_fs.Warning("sys_fs_truncate(path=*0x%x, size=0x%llx)", path, size); sys_fs.Warning("*** path = '%s'", path.get_ptr()); @@ -509,7 +514,7 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) return CELL_OK; } -s32 sys_fs_chmod(vm::ptr path, s32 mode) +s32 sys_fs_chmod(vm::cptr path, s32 mode) { sys_fs.Todo("sys_fs_chmod(path=*0x%x, mode=%#o) -> CELL_OK", path, mode); sys_fs.Todo("*** path = '%s'", path.get_ptr()); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.h b/rpcs3/Emu/SysCalls/lv2/sys_fs.h index bc53cbd904..8d282f13e6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.h @@ -1,6 +1,9 @@ #pragma once + #include "Utilities/Thread.h" +namespace vm { using namespace ps3; } + #pragma pack(push, 4) // Error Codes @@ -174,7 +177,7 @@ struct lv2_file_t std::mutex mutex; std::condition_variable cv; - atomic st_status; + atomic_t st_status; u64 st_ringbuf_size; u64 st_block_size; @@ -188,10 +191,10 @@ struct lv2_file_t std::atomic st_total_read; std::atomic st_copied; - atomic st_callback; + atomic_t st_callback; - lv2_file_t(const std::shared_ptr& file, s32 mode, s32 flags) - : file(file) + lv2_file_t(std::shared_ptr file, s32 mode, s32 flags) + : file(std::move(file)) , mode(mode) , flags(flags) , st_status({ SSS_NOT_INITIALIZED }) @@ -204,29 +207,37 @@ REG_ID_TYPE(lv2_file_t, 0x73); // SYS_FS_FD_OBJECT class vfsDirBase; -using lv2_dir_t = vfsDirBase; +struct lv2_dir_t +{ + const std::shared_ptr dir; + + lv2_dir_t(std::shared_ptr dir) + : dir(std::move(dir)) + { + } +}; REG_ID_TYPE(lv2_dir_t, 0x73); // SYS_FS_FD_OBJECT // SysCalls s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr arg3, u32 arg4, vm::ptr arg5, u32 arg6); -s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, vm::ptr arg, u64 size); +s32 sys_fs_open(vm::cptr path, s32 flags, vm::ptr fd, s32 mode, vm::cptr arg, u64 size); s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread); -s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite); +s32 sys_fs_write(u32 fd, vm::cptr buf, u64 nbytes, vm::ptr nwrite); s32 sys_fs_close(u32 fd); -s32 sys_fs_opendir(vm::ptr path, vm::ptr fd); +s32 sys_fs_opendir(vm::cptr path, vm::ptr fd); s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread); s32 sys_fs_closedir(u32 fd); -s32 sys_fs_stat(vm::ptr path, vm::ptr sb); +s32 sys_fs_stat(vm::cptr path, vm::ptr sb); s32 sys_fs_fstat(u32 fd, vm::ptr sb); -s32 sys_fs_mkdir(vm::ptr path, s32 mode); -s32 sys_fs_rename(vm::ptr from, vm::ptr to); -s32 sys_fs_rmdir(vm::ptr path); -s32 sys_fs_unlink(vm::ptr path); +s32 sys_fs_mkdir(vm::cptr path, s32 mode); +s32 sys_fs_rename(vm::cptr from, vm::cptr to); +s32 sys_fs_rmdir(vm::cptr path); +s32 sys_fs_unlink(vm::cptr path); s32 sys_fs_fcntl(u32 fd, s32 flags, u32 addr, u32 arg4, u32 arg5, u32 arg6); s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos); s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4, vm::ptr arg5); -s32 sys_fs_get_block_size(vm::ptr path, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4); -s32 sys_fs_truncate(vm::ptr path, u64 size); +s32 sys_fs_get_block_size(vm::cptr path, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4); +s32 sys_fs_truncate(vm::cptr path, u64 size); s32 sys_fs_ftruncate(u32 fd, u64 size); -s32 sys_fs_chmod(vm::ptr path, s32 mode); +s32 sys_fs_chmod(vm::cptr path, s32 mode); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index 7ce6a93aef..6792fcbc30 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -23,16 +23,14 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) return CELL_ESRCH; } - const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); + const auto thread = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); - if (!t) + if (!thread) { return CELL_ESRCH; } - RawSPUThread& spu = static_cast(*t); - - auto& tag = class_id ? spu.int2 : spu.int0; + auto& tag = class_id ? thread->int2 : thread->int0; if (s32 old = tag.assigned.compare_and_swap(0, -1)) { @@ -47,9 +45,9 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) return CELL_OK; } -s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, u64 arg) +s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread, u64 arg) { - sys_interrupt.Warning("sys_interrupt_thread_establish(ih=*0x%x, intrtag=0x%x, intrthread=%lld, arg=0x%llx)", ih, intrtag, intrthread, arg); + sys_interrupt.Warning("sys_interrupt_thread_establish(ih=*0x%x, intrtag=0x%x, intrthread=0x%x, arg=0x%llx)", ih, intrtag, intrthread, arg); const u32 class_id = intrtag >> 8; @@ -58,37 +56,33 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, return CELL_ESRCH; } - const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); + const auto thread = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); - if (!t) + if (!thread) { return CELL_ESRCH; } - RawSPUThread& spu = static_cast(*t); - - auto& tag = class_id ? spu.int2 : spu.int0; + auto& tag = class_id ? thread->int2 : thread->int0; // CELL_ESTAT is not returned (can't detect exact condition) - const auto it = Emu.GetCPU().GetThread((u32)intrthread); + const auto it = Emu.GetIdManager().get(intrthread); if (!it) { return CELL_ESRCH; } - PPUThread& ppu = static_cast(*it); - { LV2_LOCK; - if (ppu.custom_task) + if (it->custom_task) { return CELL_EAGAIN; } - if (s32 res = tag.assigned.atomic_op(CELL_OK, [](s32& value) -> s32 + if (s32 res = tag.assigned.atomic_op([](s32& value) -> s32 { if (value < 0) { @@ -102,31 +96,31 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, return res; } - ppu.custom_task = [t, &tag, arg](PPUThread& CPU) + it->custom_task = [thread, &tag, arg](PPUThread& CPU) { - const auto func = vm::ptr::make(CPU.entry); - const auto pc = vm::read32(func.addr()); - const auto rtoc = vm::read32(func.addr() + 4); + const u32 pc = CPU.PC; + const u32 rtoc = CPU.GPR[2]; - std::unique_lock cond_lock(tag.handler_mutex); + std::unique_lock lock(tag.handler_mutex); - while (!Emu.IsStopped()) + while (!CPU.IsStopped()) { + CHECK_EMU_STATUS; + // call interrupt handler until int status is clear - if (tag.stat.read_relaxed()) + if (tag.stat.load()) { - //func(CPU, arg); CPU.GPR[3] = arg; CPU.FastCall2(pc, rtoc); } - tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1)); + tag.cond.wait_for(lock, std::chrono::milliseconds(1)); } }; } *ih = Emu.GetIdManager().make(it); - ppu.Exec(); + it->Exec(); return CELL_OK; } @@ -142,11 +136,9 @@ s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr r13) return CELL_ESRCH; } - PPUThread& ppu = static_cast(*handler->handler); - // TODO: wait for sys_interrupt_thread_eoi() and destroy interrupt thread - *r13 = ppu.GPR[13]; + *r13 = handler->thread->GPR[13]; return CELL_OK; } @@ -155,8 +147,9 @@ void sys_interrupt_thread_eoi(PPUThread& CPU) { sys_interrupt.Log("sys_interrupt_thread_eoi()"); - // TODO: maybe it should actually unwind the stack (ensure that all the automatic objects are finalized)? - CPU.GPR[1] = align(CPU.GetStackAddr() + CPU.GetStackSize(), 0x200) - 0x200; // supercrutch (just to hide error messages) + // TODO: maybe it should actually unwind the stack of PPU thread? + + CPU.GPR[1] = align(CPU.stack_addr + CPU.stack_size, 0x200) - 0x200; // supercrutch to bypass stack check CPU.FastStop(); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.h b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.h index 4420ee78f5..2a34aa42fd 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.h @@ -1,13 +1,15 @@ #pragma once +namespace vm { using namespace ps3; } + class PPUThread; struct lv2_int_handler_t { - std::shared_ptr handler; + const std::shared_ptr thread; - lv2_int_handler_t(const std::shared_ptr& handler) - : handler(handler) + lv2_int_handler_t(const std::shared_ptr& thread) + : thread(thread) { } }; @@ -16,6 +18,6 @@ REG_ID_TYPE(lv2_int_handler_t, 0x0B); // SYS_INTR_SERVICE_HANDLE_OBJECT // SysCalls s32 sys_interrupt_tag_destroy(u32 intrtag); -s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, u64 arg); +s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u32 intrthread, u64 arg); s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr r13); void sys_interrupt_thread_eoi(PPUThread& CPU); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index d86f786cda..d9cbbfdf46 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -7,17 +7,12 @@ #include "Emu/Cell/PPUThread.h" #include "Emu/SysCalls/Modules/sysPrxForUser.h" #include "sleep_queue.h" -#include "sys_time.h" #include "sys_lwmutex.h" #include "sys_lwcond.h" SysCallBase sys_lwcond("sys_lwcond"); -void lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name) -{ - lwcond.lwmutex.set(vm::get_addr(&lwmutex)); - lwcond.lwcond_queue = Emu.GetIdManager().make(name); -} +extern u64 get_system_time(); s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr control, u64 name, u32 arg5) { @@ -131,7 +126,7 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) sys_lwcond.Error("_sys_lwcond_signal_all(%d): invalid mode (%d)", lwcond_id, mode); } - const u32 count = cond->waiters.size(); + const u32 count = (u32)cond->waiters.size(); if (count) { @@ -186,6 +181,8 @@ s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 ti while ((!(cond->signaled1 && mutex->signaled) && !cond->signaled2) || cond->waiters.count(CPU.GetId())) { + CHECK_EMU_STATUS; + const bool is_timedout = timeout && get_system_time() - start_time > timeout; // check timeout @@ -200,7 +197,7 @@ s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 ti } else { - throw __FUNCTION__; + throw EXCEPTION("Unexpected values"); } } @@ -216,12 +213,6 @@ s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 ti } } - if (Emu.IsStopped()) - { - sys_lwcond.Warning("_sys_lwcond_queue_wait(lwcond_id=0x%x) aborted", lwcond_id); - return CELL_OK; - } - (cond->signaled1 ? mutex->cv : cond->cv).wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h index 52a822adc7..22943ccc05 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct sys_lwmutex_t; struct sys_lwcond_attribute_t @@ -40,8 +42,6 @@ struct lv2_lwcond_t REG_ID_TYPE(lv2_lwcond_t, 0x97); // SYS_LWCOND_OBJECT // Aux -void lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name); - class PPUThread; // SysCalls diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp index 2dd2fe39f2..606f738426 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.cpp @@ -4,21 +4,13 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" #include "sleep_queue.h" -#include "sys_time.h" #include "sys_lwmutex.h" SysCallBase sys_lwmutex("sys_lwmutex"); -void lwmutex_create(sys_lwmutex_t& lwmutex, bool recursive, u32 protocol, u64 name) -{ - lwmutex.lock_var = { { lwmutex::free, lwmutex::zero } }; - lwmutex.attribute = protocol | (recursive ? SYS_SYNC_RECURSIVE : SYS_SYNC_NOT_RECURSIVE); - lwmutex.recursive_count = 0; - lwmutex.sleep_queue = Emu.GetIdManager().make(protocol, name); -} +extern u64 get_system_time(); s32 _sys_lwmutex_create(vm::ptr lwmutex_id, u32 protocol, vm::ptr control, u32 arg4, u64 name, u32 arg6) { @@ -85,18 +77,14 @@ s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout) while (!mutex->signaled) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { mutex->waiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_lwmutex.Warning("_sys_lwmutex_lock(lwmutex_id=0x%x) aborted", lwmutex_id); - return CELL_OK; - } - mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } @@ -145,7 +133,7 @@ s32 _sys_lwmutex_unlock(u32 lwmutex_id) if (mutex->signaled) { - sys_lwmutex.Fatal("_sys_lwmutex_unlock(lwmutex_id=0x%x): already signaled", lwmutex_id); + throw EXCEPTION("Already signaled (lwmutex_id=0x%x)", lwmutex_id); } mutex->signaled++; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h index 0543b24cb6..7412ee65af 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwmutex.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct sys_lwmutex_attribute_t { be_t protocol; @@ -14,29 +16,11 @@ struct sys_lwmutex_attribute_t enum : u32 { - lwmutex_zero = 0u, - lwmutex_free = 0u - 1u, - lwmutex_dead = 0u - 2u, - lwmutex_reserved = 0u - 3u, + lwmutex_free = 0xffffffffu, + lwmutex_dead = 0xfffffffeu, + lwmutex_reserved = 0xfffffffdu, }; -namespace lwmutex -{ - template - struct const_be_u32_t - { - operator const be_t() const - { - return be_t::make(_value); - } - }; - - static const_be_u32_t zero; - static const_be_u32_t free; - static const_be_u32_t dead; - static const_be_u32_t reserved; -} - struct sys_lwmutex_t { struct sync_var_t @@ -53,7 +37,8 @@ struct sys_lwmutex_t { atomic_be_t owner; atomic_be_t waiter; - }; + } + vars; atomic_be_t all_info; }; @@ -87,11 +72,6 @@ struct lv2_lwmutex_t REG_ID_TYPE(lv2_lwmutex_t, 0x95); // SYS_LWMUTEX_OBJECT -// Aux -void lwmutex_create(sys_lwmutex_t& lwmutex, bool recursive, u32 protocol, u64 name); - -class PPUThread; - // SysCalls s32 _sys_lwmutex_create(vm::ptr lwmutex_id, u32 protocol, vm::ptr control, u32 arg4, u64 name, u32 arg6); s32 _sys_lwmutex_destroy(u32 lwmutex_id); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp index bfdcd3a4a4..e680fb1372 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp @@ -5,95 +5,196 @@ #include "Emu/SysCalls/SysCalls.h" #include "sys_memory.h" -#include SysCallBase sys_memory("sys_memory"); -s32 sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr) +lv2_memory_container_t::lv2_memory_container_t(u32 size) + : size(size) + , id(Emu.GetIdManager().get_current_id()) { - sys_memory.Log("sys_memory_allocate(size=0x%x, flags=0x%x)", size, flags); - - // Check page size. - u32 addr; +} + +s32 sys_memory_allocate(u32 size, u64 flags, vm::ptr alloc_addr) +{ + sys_memory.Warning("sys_memory_allocate(size=0x%x, flags=0x%llx, alloc_addr=*0x%x)", size, flags, alloc_addr); + + LV2_LOCK; + + // Check allocation size switch(flags) { case SYS_MEMORY_PAGE_SIZE_1M: - if(size & 0xfffff) return CELL_EALIGN; - addr = (u32)Memory.Alloc(size, 0x100000); - break; + { + if (size % 0x100000) + { + return CELL_EALIGN; + } + break; + } + case SYS_MEMORY_PAGE_SIZE_64K: - if(size & 0xffff) return CELL_EALIGN; - addr = (u32)Memory.Alloc(size, 0x10000); - break; + { + if (size % 0x10000) + { + return CELL_EALIGN; + } - default: return CELL_EINVAL; + break; } - if (!addr) + default: + { + return CELL_EINVAL; + } + } + + // Available memory reserved for containers + u32 available = 0; + + // Check all containers + for (auto& ct : Emu.GetIdManager().get_all()) + { + available += ct->size - ct->taken; + } + + // Check available memory + if (Memory.GetUserMemAvailSize() < available + size) + { return CELL_ENOMEM; + } + + // Allocate memory + const u32 addr = + flags == SYS_MEMORY_PAGE_SIZE_1M ? Memory.Alloc(size, 0x100000) : + flags == SYS_MEMORY_PAGE_SIZE_64K ? Memory.Alloc(size, 0x10000) : + throw EXCEPTION("Unexpected flags"); + + if (!addr) + { + return CELL_ENOMEM; + } - // Write back the start address of the allocated area. - sys_memory.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", addr, size); - vm::write32(alloc_addr_addr, addr); + // Write back the start address of the allocated area + *alloc_addr = addr; return CELL_OK; } -s32 sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_addr_addr) +s32 sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::ptr alloc_addr) { - sys_memory.Log("sys_memory_allocate_from_container(size=0x%x, cid=0x%x, flags=0x%x)", size, cid, flags); + sys_memory.Warning("sys_memory_allocate_from_container(size=0x%x, cid=0x%x, flags=0x%llx, alloc_addr=*0x%x)", size, cid, flags, alloc_addr); - // Check if this container ID is valid. - const auto ct = Emu.GetIdManager().get(cid); + LV2_LOCK; + + // Check if this container ID is valid + const auto ct = Emu.GetIdManager().get(cid); if (!ct) { return CELL_ESRCH; } - // Check page size. - switch(flags) + // Check allocation size + switch (flags) { case SYS_MEMORY_PAGE_SIZE_1M: - if(size & 0xfffff) return CELL_EALIGN; - ct->addr = (u32)Memory.Alloc(size, 0x100000); - break; + { + if (size % 0x100000) + { + return CELL_EALIGN; + } - case SYS_MEMORY_PAGE_SIZE_64K: - if(size & 0xffff) return CELL_EALIGN; - ct->addr = (u32)Memory.Alloc(size, 0x10000); - break; - - default: return CELL_EINVAL; + break; } - // Store the address and size in the container. - if(!ct->addr) + case SYS_MEMORY_PAGE_SIZE_64K: + { + if (size % 0x10000) + { + return CELL_EALIGN; + } + + break; + } + + default: + { + return CELL_EINVAL; + } + } + + if (ct->taken > ct->size) + { + throw EXCEPTION("Unexpected amount of memory taken (0x%x, size=0x%x)", ct->taken.load(), ct->size); + } + + // Check memory availability + if (size > ct->size - ct->taken) + { return CELL_ENOMEM; - ct->size = size; + } + + // Allocate memory + const u32 addr = + flags == SYS_MEMORY_PAGE_SIZE_1M ? Memory.Alloc(size, 0x100000) : + flags == SYS_MEMORY_PAGE_SIZE_64K ? Memory.Alloc(size, 0x10000) : + throw EXCEPTION("Unexpected flags"); + + if (!addr) + { + throw EXCEPTION("Memory not allocated (ct=0x%x, size=0x%x)", cid, size); + } + + // Store the address and size in the container + ct->allocs.emplace(addr, size); + ct->taken += size; // Write back the start address of the allocated area. - sys_memory.Log("Memory allocated! [addr: 0x%x, size: 0x%x]", ct->addr, ct->size); - vm::write32(alloc_addr_addr, ct->addr); + *alloc_addr = addr; return CELL_OK; } -s32 sys_memory_free(u32 start_addr) +s32 sys_memory_free(u32 addr) { - sys_memory.Log("sys_memory_free(start_addr=0x%x)", start_addr); + sys_memory.Warning("sys_memory_free(addr=0x%x)", addr); - // Release the allocated memory. - if(!Memory.Free(start_addr)) + LV2_LOCK; + + // Check all memory containers + for (auto& ct : Emu.GetIdManager().get_all()) + { + auto found = ct->allocs.find(addr); + + if (found != ct->allocs.end()) + { + if (!Memory.Free(addr)) + { + throw EXCEPTION("Memory not deallocated (cid=0x%x, addr=0x%x, size=0x%x)", ct->id, addr, found->second); + } + + // Return memory size + ct->taken -= found->second; + ct->allocs.erase(found); + + return CELL_OK; + } + } + + if (!Memory.Free(addr)) + { return CELL_EINVAL; + } return CELL_OK; } s32 sys_memory_get_page_attribute(u32 addr, vm::ptr attr) { - sys_memory.Warning("sys_memory_get_page_attribute(addr=0x%x, attr_addr=0x%x)", addr, attr.addr()); + sys_memory.Error("sys_memory_get_page_attribute(addr=0x%x, attr=*0x%x)", addr, attr); + + LV2_LOCK; // TODO: Implement per thread page attribute setting. attr->attribute = 0x40000ull; // SYS_MEMORY_PROT_READ_WRITE @@ -105,26 +206,59 @@ s32 sys_memory_get_page_attribute(u32 addr, vm::ptr attr) s32 sys_memory_get_user_memory_size(vm::ptr mem_info) { - sys_memory.Warning("sys_memory_get_user_memory_size(mem_info_addr=0x%x)", mem_info.addr()); + sys_memory.Warning("sys_memory_get_user_memory_size(mem_info=*0x%x)", mem_info); + + LV2_LOCK; + + u32 reserved = 0; + u32 available = 0; + + // Check all memory containers + for (auto& ct : Emu.GetIdManager().get_all()) + { + reserved += ct->size; + available += ct->size - ct->taken; + } - // Fetch the user memory available. - mem_info->total_user_memory = Memory.GetUserMemTotalSize(); - mem_info->available_user_memory = Memory.GetUserMemAvailSize(); + // Fetch the user memory available + mem_info->total_user_memory = Memory.GetUserMemTotalSize() - reserved; + mem_info->available_user_memory = Memory.GetUserMemAvailSize() - available; + return CELL_OK; } -s32 sys_memory_container_create(vm::ptr cid, u32 yield_size) +s32 sys_memory_container_create(vm::ptr cid, u32 size) { - sys_memory.Warning("sys_memory_container_create(cid_addr=0x%x, yield_size=0x%x)", cid.addr(), yield_size); + sys_memory.Warning("sys_memory_container_create(cid=*0x%x, size=0x%x)", cid, size); - yield_size &= ~0xfffff; //round down to 1 MB granularity - u32 addr = (u32)Memory.Alloc(yield_size, 0x100000); //1 MB alignment + LV2_LOCK; - if(!addr) + // Round down to 1 MB granularity + size &= ~0xfffff; + + if (!size) + { return CELL_ENOMEM; + } - // Wrap the allocated memory in a memory container. - *cid = Emu.GetIdManager().make(addr, yield_size); + u32 reserved = 0; + u32 available = 0; + + // Check all memory containers + for (auto& ct : Emu.GetIdManager().get_all()) + { + reserved += ct->size; + available += ct->size - ct->taken; + } + + if (Memory.GetUserMemTotalSize() < reserved + size || + Memory.GetUserMemAvailSize() < available + size) + { + return CELL_ENOMEM; + } + + // Create the memory container + *cid = Emu.GetIdManager().make(size); return CELL_OK; } @@ -133,35 +267,41 @@ s32 sys_memory_container_destroy(u32 cid) { sys_memory.Warning("sys_memory_container_destroy(cid=0x%x)", cid); - // Check if this container ID is valid. - const auto ct = Emu.GetIdManager().get(cid); + LV2_LOCK; + + const auto ct = Emu.GetIdManager().get(cid); if (!ct) { return CELL_ESRCH; } - // Release the allocated memory and remove the ID. - Memory.Free(ct->addr); - Emu.GetIdManager().remove(cid); + // Check if some memory is not deallocated (the container cannot be destroyed in this case) + if (ct->taken) + { + return CELL_EBUSY; + } + + Emu.GetIdManager().remove(cid); return CELL_OK; } s32 sys_memory_container_get_size(vm::ptr mem_info, u32 cid) { - sys_memory.Warning("sys_memory_container_get_size(mem_info_addr=0x%x, cid=0x%x)", mem_info.addr(), cid); + sys_memory.Warning("sys_memory_container_get_size(mem_info=*0x%x, cid=0x%x)", mem_info, cid); - // Check if this container ID is valid. - const auto ct = Emu.GetIdManager().get(cid); + LV2_LOCK; + + const auto ct = Emu.GetIdManager().get(cid); if (!ct) { return CELL_ESRCH; } - // HACK: Return all memory. - mem_info->total_user_memory = ct->size; - mem_info->available_user_memory = ct->size; + mem_info->total_user_memory = ct->size; // total container memory + mem_info->available_user_memory = ct->size - ct->taken; // available container memory + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.h b/rpcs3/Emu/SysCalls/lv2/sys_memory.h index f0cf7e7ac4..8d39e3afb6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_memory.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + enum : u32 { SYS_MEMORY_CONTAINER_ID_INVALID = 0xFFFFFFFF, @@ -18,10 +20,11 @@ enum : u64 SYS_MEMORY_ATTR_READ_WRITE = 0x0000000000040000ULL, }; -enum +enum : u64 { - SYS_MEMORY_PAGE_SIZE_1M = 0x400, - SYS_MEMORY_PAGE_SIZE_64K = 0x200, + SYS_MEMORY_PAGE_SIZE_1M = 0x400ull, + SYS_MEMORY_PAGE_SIZE_64K = 0x200ull, + SYS_MEMORY_PAGE_SIZE_MASK = 0xf00ull, }; struct sys_memory_info_t @@ -39,24 +42,26 @@ struct sys_page_attr_t be_t pad; }; -struct MemoryContainerInfo +struct lv2_memory_container_t { - u32 addr; - u32 size; + const u32 size; // amount of "physical" memory in this container + const u32 id; - MemoryContainerInfo(u32 addr, u32 size) - : addr(addr) - , size(size) - { - } + // amount of memory allocated + std::atomic taken{ 0 }; + + // allocations (addr -> size) + std::map allocs; + + lv2_memory_container_t(u32 size); }; // SysCalls -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); +s32 sys_memory_allocate(u32 size, u64 flags, vm::ptr alloc_addr); +s32 sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::ptr alloc_addr); s32 sys_memory_free(u32 start_addr); s32 sys_memory_get_page_attribute(u32 addr, vm::ptr attr); s32 sys_memory_get_user_memory_size(vm::ptr mem_info); -s32 sys_memory_container_create(vm::ptr cid, u32 yield_size); +s32 sys_memory_container_create(vm::ptr cid, u32 size); s32 sys_memory_container_destroy(u32 cid); s32 sys_memory_container_get_size(vm::ptr mem_info, u32 cid); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp index cbb6f03e1c..072da9908e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp @@ -4,91 +4,133 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#include "sys_memory.h" #include "sys_mmapper.h" -#include SysCallBase sys_mmapper("sys_mmapper"); -std::map mmapper_info_map; -s32 sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr) +lv2_memory_t::lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr ct) + : size(size) + , align(align) + , id(Emu.GetIdManager().get_current_id()) + , flags(flags) + , ct(ct) { - sys_mmapper.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", - size, flags, alignment, alloc_addr); +} - // Check for valid alignment. - if(alignment > 0x80000000) - return CELL_EALIGN; +s32 sys_mmapper_allocate_address(u64 size, u64 flags, u64 alignment, vm::ptr alloc_addr) +{ + sys_mmapper.Error("sys_mmapper_allocate_address(size=0x%llx, flags=0x%llx, alignment=0x%llx, alloc_addr=*0x%x)", size, flags, alignment, alloc_addr); - // Check page size. - u32 addr; - switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K)) + LV2_LOCK; + + if (size % 0x10000000) { - default: - case SYS_MEMORY_PAGE_SIZE_1M: - if(align(size, alignment) & 0xfffff) - return CELL_EALIGN; - addr = (u32)Memory.Alloc(size, 0x100000); - break; - - case SYS_MEMORY_PAGE_SIZE_64K: - if (align(size, alignment) & 0xffff) - return CELL_EALIGN; - addr = (u32)Memory.Alloc(size, 0x10000); - break; + return CELL_EALIGN; } - // Write back the start address of the allocated area. - vm::write32(alloc_addr, addr); + if (size > UINT32_MAX) + { + return CELL_ENOMEM; + } - return CELL_OK; + switch (alignment) + { + case 0x10000000: + case 0x20000000: + case 0x40000000: + case 0x80000000: + { + for (u32 addr = ::align(0x30000000, alignment); addr < 0xC0000000; addr += static_cast(alignment)) + { + if (Memory.Map(addr, static_cast(size))) + { + *alloc_addr = addr; + + return CELL_OK; + } + } + + return CELL_ENOMEM; + } + } + + return CELL_EALIGN; } s32 sys_mmapper_allocate_fixed_address() { - sys_mmapper.Warning("sys_mmapper_allocate_fixed_address"); + sys_mmapper.Error("sys_mmapper_allocate_fixed_address()"); - // Allocate a fixed size from user memory. - if (!Memory.Alloc(SYS_MMAPPER_FIXED_SIZE, 0x100000)) + LV2_LOCK; + + if (!Memory.Map(0xB0000000, 0x10000000)) + { return CELL_EEXIST; + } return CELL_OK; } -s32 sys_mmapper_allocate_memory(u32 size, u64 flags, vm::ptr mem_id) +// Allocate physical memory (create lv2_memory_t object) +s32 sys_mmapper_allocate_memory(u64 size, u64 flags, vm::ptr mem_id) { - sys_mmapper.Warning("sys_mmapper_allocate_memory(size=0x%x, flags=0x%llx, mem_id_addr=0x%x)", size, flags, mem_id.addr()); + sys_mmapper.Warning("sys_mmapper_allocate_memory(size=0x%llx, flags=0x%llx, mem_id=*0x%x)", size, flags, mem_id); - // Check page granularity. - switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K)) + LV2_LOCK; + + // Check page granularity + switch (flags & SYS_MEMORY_PAGE_SIZE_MASK) { case SYS_MEMORY_PAGE_SIZE_1M: - if(size & 0xfffff) + { + if (size % 0x100000) + { return CELL_EALIGN; - break; + } - case SYS_MEMORY_PAGE_SIZE_64K: - if(size & 0xffff) - return CELL_EALIGN; - break; - - default: - return CELL_EINVAL; + break; } - // Generate a new mem ID. - *mem_id = Emu.GetIdManager().make(size, flags); + case SYS_MEMORY_PAGE_SIZE_64K: + { + if (size % 0x10000) + { + return CELL_EALIGN; + } + + break; + } + + default: + { + return CELL_EINVAL; + } + } + + if (size > UINT32_MAX) + { + return CELL_ENOMEM; + } + + const u32 align = + flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : + flags & SYS_MEMORY_PAGE_SIZE_64K ? 0x10000 : + throw EXCEPTION("Unexpected"); + + // Generate a new mem ID + *mem_id = Emu.GetIdManager().make(static_cast(size), align, flags, nullptr); return CELL_OK; } s32 sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, vm::ptr mem_id) { - sys_mmapper.Warning("sys_mmapper_allocate_memory_from_container(size=0x%x, cid=0x%x, flags=0x%llx, mem_id_addr=0x%x)", - size, cid, flags, mem_id.addr()); + sys_mmapper.Error("sys_mmapper_allocate_memory_from_container(size=0x%x, cid=0x%x, flags=0x%llx, mem_id=*0x%x)", size, cid, flags, mem_id); + + LV2_LOCK; // Check if this container ID is valid. - const auto ct = Emu.GetIdManager().get(cid); + const auto ct = Emu.GetIdManager().get(cid); if (!ct) { @@ -96,143 +138,224 @@ s32 sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, vm: } // Check page granularity. - switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K)) + switch (flags & SYS_MEMORY_PAGE_SIZE_MASK) { case SYS_MEMORY_PAGE_SIZE_1M: - if(size & 0xfffff) + { + if (size % 0x100000) + { return CELL_EALIGN; - break; + } + + break; + } case SYS_MEMORY_PAGE_SIZE_64K: - if(size & 0xffff) + { + if (size % 0x10000) + { return CELL_EALIGN; - break; + } + + break; + } default: + { + return CELL_EINVAL; + } + } + + if (ct->size - ct->taken < size) + { + return CELL_ENOMEM; + } + + const u32 align = + flags & SYS_MEMORY_PAGE_SIZE_1M ? 0x100000 : + flags & SYS_MEMORY_PAGE_SIZE_64K ? 0x10000 : + throw EXCEPTION("Unexpected"); + + ct->taken += size; + + // Generate a new mem ID + *mem_id = Emu.GetIdManager().make(size, align, flags, ct); + + return CELL_OK; +} + +s32 sys_mmapper_change_address_access_right(u32 addr, u64 flags) +{ + sys_mmapper.Todo("sys_mmapper_change_address_access_right(addr=0x%x, flags=0x%llx)", addr, flags); + + return CELL_OK; +} + +s32 sys_mmapper_free_address(u32 addr) +{ + sys_mmapper.Error("sys_mmapper_free_address(addr=0x%x)", addr); + + LV2_LOCK; + + const auto area = Memory.Get(addr); + + if (!area) + { return CELL_EINVAL; } - ct->size = size; + if (area->GetUsedSize()) + { + return CELL_EBUSY; + } - // Generate a new mem ID. - *mem_id = Emu.GetIdManager().make(ct->size, flags); + if (Memory.Unmap(addr)) + { + throw EXCEPTION("Unexpected (failed to unmap memory ad 0x%x)", addr); + } return CELL_OK; } -s32 sys_mmapper_change_address_access_right(u32 start_addr, u64 flags) -{ - sys_mmapper.Warning("sys_mmapper_change_address_access_right(start_addr=0x%x, flags=0x%llx)", start_addr, flags); - - // TODO - - return CELL_OK; -} - -s32 sys_mmapper_free_address(u32 start_addr) -{ - sys_mmapper.Warning("sys_mmapper_free_address(start_addr=0x%x)", start_addr); - - // Free the address. - Memory.Free(start_addr); - return CELL_OK; -} - s32 sys_mmapper_free_memory(u32 mem_id) { sys_mmapper.Warning("sys_mmapper_free_memory(mem_id=0x%x)", mem_id); - // Check if this mem ID is valid. - const auto info = Emu.GetIdManager().get(mem_id); + LV2_LOCK; - if (!info) + // Check if this mem ID is valid. + const auto mem = Emu.GetIdManager().get(mem_id); + + if (!mem) { return CELL_ESRCH; } - // Release the allocated memory and remove the ID. - Emu.GetIdManager().remove(mem_id); + if (mem->addr) + { + return CELL_EBUSY; + } + + // Return physical memory to the container if necessary + if (mem->ct) + { + mem->ct->taken -= mem->size; + } + + // Release the allocated memory and remove the ID + Emu.GetIdManager().remove(mem_id); return CELL_OK; } -s32 sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags) +s32 sys_mmapper_map_memory(u32 addr, u32 mem_id, u64 flags) { - sys_mmapper.Warning("sys_mmapper_map_memory(start_addr=0x%x, mem_id=0x%x, flags=0x%llx)", start_addr, mem_id, flags); + sys_mmapper.Error("sys_mmapper_map_memory(addr=0x%x, mem_id=0x%x, flags=0x%llx)", addr, mem_id, flags); - // Check if this mem ID is valid. - const auto info = Emu.GetIdManager().get(mem_id); + LV2_LOCK; - if (!info) + const auto area = Memory.Get(addr & 0xf0000000); + + if (!area || addr < 0x30000000 || addr >= 0xC0000000) + { + return CELL_EINVAL; + } + + const auto mem = Emu.GetIdManager().get(mem_id); + + if (!mem) { return CELL_ESRCH; } - // Map the memory into the process address. - if(!Memory.Map(start_addr, info->size)) - sys_mmapper.Error("sys_mmapper_map_memory failed!"); + if (addr % mem->align) + { + return CELL_EALIGN; + } - // Keep track of mapped addresses. - mmapper_info_map[start_addr] = mem_id; + if (mem->addr) + { + throw EXCEPTION("Already mapped (mem_id=0x%x, addr=0x%x)", mem_id, mem->addr.load()); + } + + if (!area->AllocFixed(addr, mem->size)) + { + return CELL_EBUSY; + } + + mem->addr = addr; return CELL_OK; } -s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, u32 alloc_addr) +s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, vm::ptr alloc_addr) { - sys_mmapper.Warning("sys_mmapper_search_and_map(start_addr=0x%x, mem_id=0x%x, flags=0x%llx, alloc_addr=0x%x)", - start_addr, mem_id, flags, alloc_addr); + sys_mmapper.Error("sys_mmapper_search_and_map(start_addr=0x%x, mem_id=0x%x, flags=0x%llx, alloc_addr=*0x%x)", start_addr, mem_id, flags, alloc_addr); - // Check if this mem ID is valid. - const auto info = Emu.GetIdManager().get(mem_id); + LV2_LOCK; - if (!info) + const auto area = Memory.Get(start_addr); + + if (!area || start_addr < 0x30000000 || start_addr >= 0xC0000000) + { + return CELL_EINVAL; + } + + const auto mem = Emu.GetIdManager().get(mem_id); + + if (!mem) { return CELL_ESRCH; } - - // Search for a mappable address. - u32 addr; - bool found; - for (int i = 0; i < SYS_MMAPPER_FIXED_SIZE; i += 0x100000) + + const u32 addr = area->AllocAlign(mem->size, mem->align); + + if (!addr) { - addr = start_addr + i; - found = Memory.Map(addr, info->size); - if(found) + return CELL_ENOMEM; + } + + *alloc_addr = addr; + + return CELL_ENOMEM; +} + +s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr mem_id) +{ + sys_mmapper.Todo("sys_mmapper_unmap_memory(addr=0x%x, mem_id=*0x%x)", addr, mem_id); + + LV2_LOCK; + + const auto area = Memory.Get(addr); + + if (!area || addr < 0x30000000 || addr >= 0xC0000000) + { + return CELL_EINVAL; + } + + for (auto& mem : Emu.GetIdManager().get_all()) + { + if (mem->addr == addr) { - sys_mmapper.Warning("Found and mapped address 0x%x", addr); - break; + if (!area->Free(addr)) + { + throw EXCEPTION("Not mapped (mem_id=0x%x, addr=0x%x)", mem->id, addr); + } + + mem->addr = 0; + + *mem_id = mem->id; + + return CELL_OK; } } - if (!found) - return CELL_ENOMEM; - - // Write back the start address of the allocated area. - vm::write32(alloc_addr, addr); - - // Keep track of mapped addresses. - mmapper_info_map[addr] = mem_id; - - return CELL_OK; + return CELL_EINVAL; } -s32 sys_mmapper_unmap_memory(u32 start_addr, u32 mem_id_addr) +s32 sys_mmapper_enable_page_fault_notification(u32 addr, u32 eq) { - sys_mmapper.Warning("sys_mmapper_unmap_memory(start_addr=0x%x, mem_id_addr=0x%x)", start_addr, mem_id_addr); - - // Write back the mem ID of the unmapped area. - u32 mem_id = mmapper_info_map.find(start_addr)->second; - vm::write32(mem_id_addr, mem_id); - - return CELL_OK; -} - -s32 sys_mmapper_enable_page_fault_notification(u32 start_addr, u32 q_id) -{ - sys_mmapper.Warning("sys_mmapper_enable_page_fault_notification(start_addr=0x%x, q_id=0x%x)", start_addr, q_id); - - // TODO + sys_mmapper.Todo("sys_mmapper_enable_page_fault_notification(addr=0x%x, eq=0x%x)", addr, eq); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.h b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.h index a32000d347..def4821277 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.h @@ -1,35 +1,33 @@ #pragma once -#define SYS_MMAPPER_FIXED_ADDR 0xB0000000 -#define SYS_MMAPPER_FIXED_SIZE 0x10000000 +#include "sys_memory.h" -struct mmapper_info +namespace vm { using namespace ps3; } + +struct lv2_memory_t { - u32 size; - u64 flags; + const u32 size; // memory size + const u32 align; // required alignment + const u32 id; + const u64 flags; + const std::shared_ptr ct; // memory container the physical memory is taken from - mmapper_info(u32 _size, u64 _flags) - : size(_size) - , flags(_flags) - { - } + std::atomic addr{ 0 }; // actual mapping address - mmapper_info() - { - } + lv2_memory_t(u32 size, u32 align, u64 flags, const std::shared_ptr ct); }; -REG_ID_TYPE(mmapper_info, 0x08); // SYS_MEM_OBJECT +REG_ID_TYPE(lv2_memory_t, 0x08); // SYS_MEM_OBJECT // SysCalls -s32 sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr); +s32 sys_mmapper_allocate_address(u64 size, u64 flags, u64 alignment, vm::ptr alloc_addr); s32 sys_mmapper_allocate_fixed_address(); -s32 sys_mmapper_allocate_memory(u32 size, u64 flags, vm::ptr mem_id); +s32 sys_mmapper_allocate_memory(u64 size, u64 flags, vm::ptr mem_id); s32 sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, vm::ptr mem_id); -s32 sys_mmapper_change_address_access_right(u32 start_addr, u64 flags); -s32 sys_mmapper_free_address(u32 start_addr); +s32 sys_mmapper_change_address_access_right(u32 addr, u64 flags); +s32 sys_mmapper_free_address(u32 addr); s32 sys_mmapper_free_memory(u32 mem_id); -s32 sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags); -s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, u32 alloc_addr); -s32 sys_mmapper_unmap_memory(u32 start_addr, u32 mem_id_addr); -s32 sys_mmapper_enable_page_fault_notification(u32 start_addr, u32 q_id); +s32 sys_mmapper_map_memory(u32 addr, u32 mem_id, u64 flags); +s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, vm::ptr alloc_addr); +s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr mem_id); +s32 sys_mmapper_enable_page_fault_notification(u32 addr, u32 eq); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index 96333a6920..d2908bfa76 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -4,14 +4,31 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" -#include "sleep_queue.h" -#include "sys_time.h" #include "sys_mutex.h" SysCallBase sys_mutex("sys_mutex"); +extern u64 get_system_time(); + +void lv2_mutex_t::unlock(lv2_lock_type& lv2_lock) +{ + CHECK_LV2_LOCK(lv2_lock); + + owner.reset(); + + if (sq.size()) + { + // pick new owner; protocol is ignored in current implementation + owner = sq.front(); + + if (!owner->Signal()) + { + throw EXCEPTION("Mutex owner not signaled"); + } + } +} + s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr) { sys_mutex.Warning("sys_mutex_create(mutex_id=*0x%x, attr=*0x%x)", mutex_id, attr); @@ -31,12 +48,11 @@ s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr) default: sys_mutex.Error("sys_mutex_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } - const bool recursive = attr->recursive.data() == se32(SYS_SYNC_RECURSIVE); + const bool recursive = attr->recursive == SYS_SYNC_RECURSIVE; - if ((!recursive && attr->recursive.data() != se32(SYS_SYNC_NOT_RECURSIVE)) || attr->pshared.data() != se32(0x200) || attr->adaptive.data() != se32(0x2000) || attr->ipc_key.data() || attr->flags.data()) + if ((!recursive && attr->recursive != SYS_SYNC_NOT_RECURSIVE) || attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->adaptive != SYS_SYNC_NOT_ADAPTIVE || attr->ipc_key.data() || attr->flags.data()) { - sys_mutex.Error("sys_mutex_create(): unknown attributes (recursive=0x%x, pshared=0x%x, adaptive=0x%x, ipc_key=0x%llx, flags=0x%x)", - attr->recursive, attr->pshared, attr->adaptive, attr->ipc_key, attr->flags); + sys_mutex.Error("sys_mutex_create(): unknown attributes (recursive=0x%x, pshared=0x%x, adaptive=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->recursive, attr->pshared, attr->adaptive, attr->ipc_key, attr->flags); return CELL_EINVAL; } @@ -59,13 +75,8 @@ s32 sys_mutex_destroy(u32 mutex_id) return CELL_ESRCH; } - if (!mutex->owner.expired()) - { - return CELL_EBUSY; - } - // assuming that the mutex is locked immediately by another waiting thread when unlocked - if (mutex->waiters) + if (!mutex->owner || !mutex->sq.empty()) { return CELL_EBUSY; } @@ -80,7 +91,7 @@ s32 sys_mutex_destroy(u32 mutex_id) return CELL_OK; } -s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) +s32 sys_mutex_lock(PPUThread& ppu, u32 mutex_id, u64 timeout) { sys_mutex.Log("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx)", mutex_id, timeout); @@ -95,9 +106,8 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) return CELL_ESRCH; } - const auto thread = Emu.GetCPU().GetThread(CPU.GetId(), CPU_THREAD_PPU); - - if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality + // check current ownership + if (mutex->owner.get() == &ppu) { if (mutex->recursive) { @@ -114,33 +124,46 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) return CELL_EDEADLK; } - // protocol is ignored in current implementation - mutex->waiters++; - - while (!mutex->owner.expired()) + // lock immediately if not locked + if (!mutex->owner) { - if (timeout && get_system_time() - start_time > timeout) - { - mutex->waiters--; - return CELL_ETIMEDOUT; - } + mutex->owner = std::move(ppu.shared_from_this()); - if (Emu.IsStopped()) - { - sys_mutex.Warning("sys_mutex_lock(mutex_id=0x%x) aborted", mutex_id); - return CELL_OK; - } - - mutex->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + return CELL_OK; } - mutex->owner = thread; - mutex->waiters--; + // add waiter; protocol is ignored in current implementation + sleep_queue_entry_t waiter(ppu, mutex->sq); + + while (!ppu.Signaled()) + { + CHECK_EMU_STATUS; + + if (timeout) + { + const u64 passed = get_system_time() - start_time; + + if (passed >= timeout || ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed)) == std::cv_status::timeout) + { + return CELL_ETIMEDOUT; + } + } + else + { + ppu.cv.wait(lv2_lock); + } + } + + // new owner must be set when unlocked + if (mutex->owner.get() != &ppu) + { + throw EXCEPTION("Unexpected mutex owner"); + } return CELL_OK; } -s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id) +s32 sys_mutex_trylock(PPUThread& ppu, u32 mutex_id) { sys_mutex.Log("sys_mutex_trylock(mutex_id=0x%x)", mutex_id); @@ -153,9 +176,8 @@ s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id) return CELL_ESRCH; } - const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); - - if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality + // check current ownership + if (mutex->owner.get() == &ppu) { if (mutex->recursive) { @@ -172,17 +194,18 @@ s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id) return CELL_EDEADLK; } - if (!mutex->owner.expired()) + if (mutex->owner) { return CELL_EBUSY; } - mutex->owner = thread; + // own the mutex if free + mutex->owner = std::move(ppu.shared_from_this()); return CELL_OK; } -s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id) +s32 sys_mutex_unlock(PPUThread& ppu, u32 mutex_id) { sys_mutex.Log("sys_mutex_unlock(mutex_id=0x%x)", mutex_id); @@ -195,9 +218,8 @@ s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id) return CELL_ESRCH; } - const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); - - if (mutex->owner.owner_before(thread) || thread.owner_before(mutex->owner)) // check inequality + // check current ownership + if (mutex->owner.get() != &ppu) { return CELL_EPERM; } @@ -206,19 +228,14 @@ s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id) { if (!mutex->recursive) { - throw __FUNCTION__; + throw EXCEPTION("Unexpected recursive_count"); } mutex->recursive_count--; } else { - mutex->owner.reset(); - - if (mutex->waiters) - { - mutex->cv.notify_one(); - } + mutex->unlock(lv2_lock); } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h index b111aa4f31..d1d7449102 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.h @@ -1,5 +1,9 @@ #pragma once +#include "sleep_queue.h" + +namespace vm { using namespace ps3; } + struct sys_mutex_attribute_t { be_t protocol; // SYS_SYNC_FIFO, SYS_SYNC_PRIORITY or SYS_SYNC_PRIORITY_INHERIT @@ -23,23 +27,20 @@ struct lv2_mutex_t const u32 protocol; const u64 name; - std::atomic cond_count; // count of condition variables associated - std::atomic recursive_count; - std::weak_ptr owner; + std::atomic cond_count{ 0 }; // count of condition variables associated + std::atomic recursive_count{ 0 }; + std::shared_ptr owner; - // TODO: use sleep queue, possibly remove condition variable - std::condition_variable cv; - std::atomic waiters; + sleep_queue_t sq; lv2_mutex_t(bool recursive, u32 protocol, u64 name) : recursive(recursive) , protocol(protocol) , name(name) - , cond_count(0) - , recursive_count(0) - , waiters(0) { } + + void unlock(lv2_lock_type& lv2_lock); }; REG_ID_TYPE(lv2_mutex_t, 0x85); // SYS_MUTEX_OBJECT @@ -49,6 +50,6 @@ class PPUThread; // SysCalls s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr); s32 sys_mutex_destroy(u32 mutex_id); -s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout); -s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id); -s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id); +s32 sys_mutex_lock(PPUThread& ppu, u32 mutex_id, u64 timeout); +s32 sys_mutex_trylock(PPUThread& ppu, u32 mutex_id); +s32 sys_mutex_unlock(PPUThread& ppu, u32 mutex_id); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index e40550a097..5506df3ad3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -2,61 +2,93 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/SysCalls/CB_FUNC.h" +#include "Emu/IdManager.h" +#include "Emu/DbgCommand.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" +#include "sys_mutex.h" #include "sys_ppu_thread.h" SysCallBase sys_ppu_thread("sys_ppu_thread"); -void _sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode) +void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) { sys_ppu_thread.Log("_sys_ppu_thread_exit(errorcode=0x%llx)", errorcode); - CPU.SetExitStatus(errorcode); - CPU.Stop(); + LV2_LOCK; - if (!CPU.IsJoinable()) + // get all sys_mutex objects + for (auto& mutex : Emu.GetIdManager().get_all()) { - const u32 id = CPU.GetId(); + // unlock mutex if locked by this thread + if (mutex->owner.get() == &ppu) + { + mutex->unlock(lv2_lock); + } + } + + const auto thread = ppu.shared_from_this(); + + if (!ppu.is_joinable) + { + const u32 id = ppu.GetId(); + CallAfter([id]() { - Emu.GetCPU().RemoveThread(id); + Emu.GetIdManager().remove(id); }); } + + ppu.Exit(); } void 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)); // hack + + std::this_thread::yield(); } -s32 sys_ppu_thread_join(u32 thread_id, vm::ptr vptr) +s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr vptr) { sys_ppu_thread.Warning("sys_ppu_thread_join(thread_id=0x%x, vptr=*0x%x)", thread_id, vptr); - const auto t = Emu.GetCPU().GetThread(thread_id); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - while (t->IsAlive()) + if (!thread->is_joinable || thread->is_joining) { - if (Emu.IsStopped()) - { - sys_ppu_thread.Warning("sys_ppu_thread_join(%d) aborted", thread_id); - return CELL_OK; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + return CELL_EINVAL; } - *vptr = t->GetExitStatus(); - Emu.GetCPU().RemoveThread(thread_id); + if (&ppu == thread.get()) + { + return CELL_EDEADLK; + } + + // mark joining + thread->is_joining = true; + + // join thread + while (thread->IsActive()) + { + CHECK_EMU_STATUS; + + ppu.cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + } + + // get exit status from the register + *vptr = thread->GPR[3]; + + // cleanup + Emu.GetIdManager().remove(thread->GetId()); + return CELL_OK; } @@ -64,42 +96,59 @@ s32 sys_ppu_thread_detach(u32 thread_id) { sys_ppu_thread.Warning("sys_ppu_thread_detach(thread_id=0x%x)", thread_id); - const auto t = Emu.GetCPU().GetThread(thread_id); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - if (!t->IsJoinable()) + if (!thread->is_joinable) { return CELL_EINVAL; } - - t->SetJoinable(false); + + if (thread->is_joining) + { + return CELL_EBUSY; + } + + // "detach" + thread->is_joinable = false; return CELL_OK; } -void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable) +void sys_ppu_thread_get_join_state(PPUThread& ppu, vm::ptr isjoinable) { sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable=*0x%x)", isjoinable); - *isjoinable = CPU.IsJoinable(); + LV2_LOCK; + + *isjoinable = ppu.is_joinable; } s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio) { sys_ppu_thread.Log("sys_ppu_thread_set_priority(thread_id=0x%x, prio=%d)", thread_id, prio); - const auto t = Emu.GetCPU().GetThread(thread_id); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - t->SetPrio(prio); + if (prio < 0 || prio > 3071) + { + return CELL_EINVAL; + } + + thread->prio = prio; return CELL_OK; } @@ -108,122 +157,130 @@ s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr priop) { sys_ppu_thread.Log("sys_ppu_thread_get_priority(thread_id=0x%x, priop=*0x%x)", thread_id, priop); - const auto t = Emu.GetCPU().GetThread(thread_id); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - *priop = static_cast(t->GetPrio()); + *priop = thread->prio; return CELL_OK; } -s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr sp) +s32 sys_ppu_thread_get_stack_information(PPUThread& ppu, vm::ptr sp) { sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(sp=*0x%x)", sp); - sp->pst_addr = CPU.GetStackAddr(); - sp->pst_size = CPU.GetStackSize(); + sp->pst_addr = ppu.stack_addr; + sp->pst_size = ppu.stack_size; return CELL_OK; } s32 sys_ppu_thread_stop(u32 thread_id) { - sys_ppu_thread.Error("sys_ppu_thread_stop(thread_id=0x%x)", thread_id); + sys_ppu_thread.Todo("sys_ppu_thread_stop(thread_id=0x%x)", thread_id); - const auto t = Emu.GetCPU().GetThread(thread_id); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - t->Stop(); + //t->Stop(); return CELL_OK; } s32 sys_ppu_thread_restart(u32 thread_id) { - sys_ppu_thread.Error("sys_ppu_thread_restart(thread_id=0x%x)", thread_id); + sys_ppu_thread.Todo("sys_ppu_thread_restart(thread_id=0x%x)", thread_id); - const auto t = Emu.GetCPU().GetThread(thread_id); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - t->Stop(); - t->Run(); + //t->Stop(); + //t->Run(); return CELL_OK; } u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, std::string name, std::function task) { - const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + const auto ppu = Emu.GetIdManager().make_ptr(name); - auto& ppu = static_cast(*new_thread); + ppu->prio = prio; + ppu->stack_size = stacksize < 0x4000 ? 0x4000 : stacksize; // (hack) adjust minimal stack size + ppu->custom_task = task; + ppu->Run(); - ppu.SetEntry(entry); - ppu.SetPrio(prio); - ppu.SetStackSize(stacksize < 0x4000 ? 0x4000 : stacksize); // (hack) adjust minimal stack size - ppu.SetJoinable(is_joinable); - ppu.SetName(name); - ppu.custom_task = task; - ppu.Run(); + if (entry) + { + ppu->PC = vm::read32(entry); + ppu->GPR[2] = vm::read32(entry + 4); // rtoc + } if (!is_interrupt) { - ppu.GPR[3] = arg; - ppu.Exec(); + ppu->GPR[3] = arg; + ppu->Exec(); } - return ppu.GetId(); + return ppu->GetId(); } -s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) +s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::cptr threadname) { sys_ppu_thread.Warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, param, arg, unk, prio, stacksize, flags, threadname); + LV2_LOCK; + if (prio < 0 || prio > 3071) { return CELL_EINVAL; } - const bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE; - const bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT; + const bool is_joinable = (flags & SYS_PPU_THREAD_CREATE_JOINABLE) != 0; + const bool is_interrupt = (flags & SYS_PPU_THREAD_CREATE_INTERRUPT) != 0; if (is_joinable && is_interrupt) { return CELL_EPERM; } - const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + const auto ppu = Emu.GetIdManager().make_ptr(threadname ? threadname.get_ptr() : ""); - auto& ppu = static_cast(*new_thread); + ppu->prio = prio; + ppu->stack_size = stacksize < 0x4000 ? 0x4000 : stacksize; // (hack) adjust minimal stack size + ppu->Run(); - ppu.SetEntry(param->entry); - ppu.SetPrio(prio); - ppu.SetStackSize(stacksize < 0x4000 ? 0x4000 : stacksize); // (hack) adjust minimal stack size - ppu.SetJoinable(is_joinable); - ppu.SetName(threadname ? threadname.get_ptr() : ""); - ppu.Run(); + ppu->PC = vm::read32(param->entry); + ppu->GPR[2] = vm::read32(param->entry + 4); // rtoc + ppu->GPR[3] = arg; + ppu->GPR[4] = unk; // actually unknown - ppu.GPR[3] = arg; - ppu.GPR[4] = unk; // actually unknown + ppu->is_joinable = is_joinable; if (u32 tls = param->tls) // hack { - ppu.GPR[13] = tls; + ppu->GPR[13] = tls; } - *thread_id = ppu.GetId(); + *thread_id = ppu->GetId(); return CELL_OK; } @@ -232,30 +289,32 @@ s32 sys_ppu_thread_start(u32 thread_id) { sys_ppu_thread.Warning("sys_ppu_thread_start(thread_id=0x%x)", thread_id); - const auto t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - t->Exec(); + thread->Exec(); return CELL_OK; } -s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr name) +s32 sys_ppu_thread_rename(u32 thread_id, vm::cptr name) { - sys_ppu_thread.Error("sys_ppu_thread_rename(thread_id=0x%x, name=*0x%x)", thread_id, name); + sys_ppu_thread.Todo("sys_ppu_thread_rename(thread_id=0x%x, name=*0x%x)", thread_id, name); - const auto t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(thread_id); + + if (!thread) { return CELL_ESRCH; } - - t->SetThreadName(name.get_ptr()); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h index 8aeb276359..f0fc157862 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + class PPUThread; enum : u32 @@ -27,20 +29,32 @@ struct ppu_thread_param_t be_t tls; // vm::bptr }; +enum : u32 +{ + PPU_THREAD_STATUS_IDLE, + PPU_THREAD_STATUS_RUNNABLE, + PPU_THREAD_STATUS_ONPROC, + PPU_THREAD_STATUS_SLEEP, + PPU_THREAD_STATUS_STOP, + PPU_THREAD_STATUS_ZOMBIE, + PPU_THREAD_STATUS_DELETED, + PPU_THREAD_STATUS_UNKNOWN, +}; + // Aux u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, std::string name, std::function task = nullptr); // SysCalls -void _sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); +void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode); void sys_ppu_thread_yield(); -s32 sys_ppu_thread_join(u32 thread_id, vm::ptr vptr); +s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr vptr); s32 sys_ppu_thread_detach(u32 thread_id); -void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable); +void sys_ppu_thread_get_join_state(PPUThread& ppu, vm::ptr isjoinable); s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio); s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr priop); -s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr sp); +s32 sys_ppu_thread_get_stack_information(PPUThread& ppu, vm::ptr sp); s32 sys_ppu_thread_stop(u32 thread_id); s32 sys_ppu_thread_restart(u32 thread_id); -s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 arg4, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname); +s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 arg4, s32 prio, u32 stacksize, u64 flags, vm::cptr threadname); s32 sys_ppu_thread_start(u32 thread_id); -s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr name); +s32 sys_ppu_thread_rename(u32 thread_id, vm::cptr name); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index 1effa3cd6c..186c943626 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -36,25 +36,26 @@ s32 sys_process_exit(s32 status) LV2_LOCK; - if (!Emu.IsStopped()) + CHECK_EMU_STATUS; + + sys_process.Success("Process finished"); + + CallAfter([]() { - sys_process.Success("Process finished"); + Emu.Stop(); + }); - CallAfter([]() - { - Emu.Stop(); - }); + while (true) + { + CHECK_EMU_STATUS; - while (!Emu.IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return CELL_OK; } -void sys_game_process_exitspawn(vm::ptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) +void sys_game_process_exitspawn(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { std::string _path = path.get_ptr(); const std::string& from = "//"; @@ -80,7 +81,7 @@ void sys_game_process_exitspawn(vm::ptr path, u32 argv_addr, u32 env if (argv_addr) { - auto argvp = vm::pptr::make(argv_addr); + auto argvp = vm::cpptr::make(argv_addr); while (argvp && *argvp) { argv.push_back(argvp[0].get_ptr()); @@ -94,7 +95,7 @@ void sys_game_process_exitspawn(vm::ptr path, u32 argv_addr, u32 env if (envp_addr) { - auto envp = vm::pptr::make(envp_addr); + auto envp = vm::cpptr::make(envp_addr); while (envp && *envp) { env.push_back(envp[0].get_ptr()); @@ -128,7 +129,7 @@ void sys_game_process_exitspawn(vm::ptr path, u32 argv_addr, u32 env return; } -void sys_game_process_exitspawn2(vm::ptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) +void sys_game_process_exitspawn2(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { std::string _path = path.get_ptr(); const std::string& from = "//"; @@ -154,7 +155,7 @@ void sys_game_process_exitspawn2(vm::ptr path, u32 argv_addr, u32 en if (argv_addr) { - auto argvp = vm::pptr::make(argv_addr); + auto argvp = vm::cpptr::make(argv_addr); while (argvp && *argvp) { argv.push_back(argvp[0].get_ptr()); @@ -169,7 +170,7 @@ void sys_game_process_exitspawn2(vm::ptr path, u32 argv_addr, u32 en if (envp_addr) { - auto envp = vm::pptr::make(envp_addr); + auto envp = vm::cpptr::make(envp_addr); while (envp && *envp) { env.push_back(envp[0].get_ptr()); @@ -229,7 +230,7 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) case SYS_LWCOND_OBJECT: case SYS_EVENT_FLAG_OBJECT: { - *nump = Emu.GetIdManager().get_count_by_type(object); + *nump = Emu.GetIdManager().get_count(object); return CELL_OK; } } @@ -262,7 +263,7 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s case SYS_LWCOND_OBJECT: case SYS_EVENT_FLAG_OBJECT: { - const auto objects = Emu.GetIdManager().get_IDs_by_type(object); + const auto objects = Emu.GetIdManager().get_IDs(object); u32 i = 0; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.h b/rpcs3/Emu/SysCalls/lv2/sys_process.h index b055e452a0..416a49fd72 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Process Local Object Type enum : u32 { @@ -42,7 +44,5 @@ s32 sys_process_kill(u32 pid); s32 sys_process_wait_for_child(u32 pid, vm::ptr status, u64 unk); s32 sys_process_wait_for_child2(u64 unk1, u64 unk2, u64 unk3, u64 unk4, u64 unk5, u64 unk6); s32 sys_process_detach_child(u64 unk); -void sys_game_process_exitspawn(vm::ptr path, u32 argv_addr, u32 envp_addr, - u32 data_addr, u32 data_size, u32 prio, u64 flags); -void sys_game_process_exitspawn2(vm::ptr path, u32 argv_addr, u32 envp_addr, - u32 data_addr, u32 data_size, u32 prio, u64 flags); +void sys_game_process_exitspawn(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags); +void sys_game_process_exitspawn2(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp index 377e40ceff..9f08e5d0b4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp @@ -18,6 +18,11 @@ SysCallBase sys_prx("sys_prx"); extern void fill_ppu_exec_map(u32 addr, u32 size); +lv2_prx_t::lv2_prx_t() + : id(Emu.GetIdManager().get_current_id()) +{ +} + s32 prx_load_module(std::string path, u64 flags, vm::ptr pOpt) { sys_prx.Warning("prx_load_module(path='%s', flags=0x%llx, pOpt=*0x%x)", path.c_str(), flags, pOpt); @@ -34,7 +39,7 @@ s32 prx_load_module(std::string path, u64 flags, vm::ptr(); + auto prx = Emu.GetIdManager().make_ptr(); auto meta = info.modules[""]; prx->start.set(meta.exports[0xBC9A0086]); @@ -97,7 +102,7 @@ s32 prx_load_module(std::string path, u64 flags, vm::ptrid; } -s32 sys_prx_load_module(vm::ptr path, u64 flags, vm::ptr pOpt) +s32 sys_prx_load_module(vm::cptr path, u64 flags, vm::ptr pOpt) { sys_prx.Warning("sys_prx_load_module(path=*0x%x, flags=0x%llx, pOpt=*0x%x)", path, flags, pOpt); return prx_load_module(path.get_ptr(), flags, pOpt); } -s32 sys_prx_load_module_list(s32 count, vm::pptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list) +s32 sys_prx_load_module_list(s32 count, vm::cpptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list) { sys_prx.Warning("sys_prx_load_module_list(count=%d, path_list=*0x%x, flags=0x%llx, pOpt=*0x%x, id_list=*0x%x)", count, path_list, flags, pOpt, id_list); @@ -192,7 +197,7 @@ s32 sys_prx_start_module(s32 id, u64 flags, vm::ptris_started = true; - pOpt->entry_point.set(be_t::make(prx->start ? prx->start.addr() : ~0ull)); + pOpt->entry_point.set(prx->start ? prx->start.addr() : ~0ull); return CELL_OK; } @@ -212,7 +217,7 @@ s32 sys_prx_stop_module(s32 id, u64 flags, vm::ptr // return CELL_PRX_ERROR_ALREADY_STOPPED; //prx->is_started = false; - pOpt->entry_point.set(be_t::make(prx->stop ? prx->stop.addr() : -1)); + pOpt->entry_point.set(prx->stop ? prx->stop.addr() : -1); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.h b/rpcs3/Emu/SysCalls/lv2/sys_prx.h index d0b329cfe6..8702126a41 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // Return codes enum { @@ -28,6 +30,39 @@ enum CELL_PRX_ERROR_ELF_IS_REGISTERED = 0x80011910, // Fixed ELF is already registered }; +struct sys_stub +{ + u8 s_size; // = 0x2c + u8 s_unk0; + be_t s_version; // = 0x1 + be_t s_unk1; // = 0x9 // flags? + be_t s_imports; + be_t s_unk2; // = 0x0 + be_t s_unk3; // = 0x0 + vm::bcptr s_modulename; + vm::bptr s_nid; + vm::bptr s_text; + be_t s_unk4; // = 0x0 + be_t s_unk5; // = 0x0 + be_t s_unk6; // = 0x0 + be_t s_unk7; // = 0x0 +}; + +struct sys_proc_prx_param +{ + be_t size; + be_t magic; + be_t version; + be_t pad0; + be_t libentstart; + be_t libentend; + vm::bptr libstubstart; + vm::bptr libstubend; + be_t ver; + be_t pad1; + be_t pad2; +}; + // Information about imported or exported libraries in PRX modules struct sys_prx_library_info_t { @@ -120,22 +155,22 @@ struct sys_prx_unload_module_option_t // Auxiliary data types struct lv2_prx_t { + const u32 id; + bool is_started = false; vm::ptr argv)> start = vm::null; vm::ptr argv)> stop = vm::null; vm::ptr exit = vm::null; - lv2_prx_t() - { - } + lv2_prx_t(); }; REG_ID_TYPE(lv2_prx_t, 0x23); // SYS_PRX_OBJECT // SysCalls -s32 sys_prx_load_module(vm::ptr path, u64 flags, vm::ptr pOpt); -s32 sys_prx_load_module_list(s32 count, vm::pptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list); +s32 sys_prx_load_module(vm::cptr path, u64 flags, vm::ptr pOpt); +s32 sys_prx_load_module_list(s32 count, vm::cpptr path_list, u64 flags, vm::ptr pOpt, vm::ptr id_list); s32 sys_prx_load_module_on_memcontainer(); s32 sys_prx_load_module_by_fd(); s32 sys_prx_load_module_on_memcontainer_by_fd(); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp index 422a765157..a9fedf808d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp @@ -10,12 +10,14 @@ SysCallBase sys_rsx("sys_rsx"); s32 sys_rsx_device_open() { sys_rsx.Todo("sys_rsx_device_open()"); + return CELL_OK; } s32 sys_rsx_device_close() { sys_rsx.Todo("sys_rsx_device_close()"); + return CELL_OK; } @@ -29,10 +31,10 @@ s32 sys_rsx_device_close() * @param a6 (IN): E.g. Immediate value passed in cellGcmSys is 16. * @param a7 (IN): E.g. Immediate value passed in cellGcmSys is 8. */ -s32 sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7) +s32 sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7) { - sys_rsx.Todo("sys_rsx_memory_allocate(mem_handle_addr=0x%x, local_mem_addr=0x%x, size=0x%x, flags=0x%x, a5=%d, a6=%d, a7=%d)", - mem_handle.addr(), mem_addr.addr(), size, flags, a5, a6, a7); + sys_rsx.Todo("sys_rsx_memory_allocate(mem_handle=*0x%x, mem_addr=*0x%x, size=0x%x, flags=0x%llx, a5=0x%llx, a6=0x%llx, a7=0x%llx)", mem_handle, mem_addr, size, flags, a5, a6, a7); + return CELL_OK; } @@ -42,7 +44,8 @@ s32 sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 */ s32 sys_rsx_memory_free(u32 mem_handle) { - sys_rsx.Todo("sys_rsx_memory_free(mem_handle=%d)", mem_handle); + sys_rsx.Todo("sys_rsx_memory_free(mem_handle=0x%x)", mem_handle); + return CELL_OK; } @@ -57,8 +60,8 @@ s32 sys_rsx_memory_free(u32 mem_handle) */ s32 sys_rsx_context_allocate(vm::ptr context_id, vm::ptr lpar_dma_control, vm::ptr lpar_driver_info, vm::ptr lpar_reports, u64 mem_ctx, u64 system_mode) { - sys_rsx.Todo("sys_rsx_context_allocate(context_id_addr=0x%x, lpar_dma_control_addr=0x%x, lpar_driver_info_addr=0x%x, lpar_reports_addr=0x%x, mem_ctx=0x%x, system_mode=0x%x)", - context_id.addr(), lpar_dma_control.addr(), lpar_driver_info.addr(), lpar_reports.addr(), mem_ctx, system_mode); + sys_rsx.Todo("sys_rsx_context_allocate(context_id=*0x%x, lpar_dma_control=*0x%x, lpar_driver_info=*0x%x, lpar_reports=*0x%x, mem_ctx=0x%llx, system_mode=0x%llx)", + context_id, lpar_dma_control, lpar_driver_info, lpar_reports, mem_ctx, system_mode); return CELL_OK; } @@ -69,7 +72,8 @@ s32 sys_rsx_context_allocate(vm::ptr context_id, vm::ptr lpar_dma_cont */ s32 sys_rsx_context_free(u32 context_id) { - sys_rsx.Todo("sys_rsx_context_free(context_id=%d)", context_id); + sys_rsx.Todo("sys_rsx_context_free(context_id=0x%x)", context_id); + return CELL_OK; } @@ -83,8 +87,8 @@ s32 sys_rsx_context_free(u32 context_id) */ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags) { - sys_rsx.Todo("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", - context_id, io, ea, size, flags); + sys_rsx.Todo("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags); + return CELL_OK; } @@ -97,8 +101,8 @@ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags) */ s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size) { - sys_rsx.Todo("sys_rsx_context_iounmap(context_id=0x%x, a2=0x%x, io_addr=0x%x, size=0x%x)", - context_id, a2, io_addr, size); + sys_rsx.Todo("sys_rsx_context_iounmap(context_id=0x%x, a2=0x%x, io_addr=0x%x, size=0x%x)", context_id, a2, io_addr, size); + return CELL_OK; } @@ -113,8 +117,7 @@ s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size) */ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6) { - sys_rsx.Todo("sys_rsx_context_attribute(context_id=0x%x, package_id=0x%x, a3=0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", - context_id, package_id, a3, a4, a5, a6); + sys_rsx.Todo("sys_rsx_context_attribute(context_id=0x%x, package_id=0x%x, a3=0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", context_id, package_id, a3, a4, a5, a6); switch(package_id) { @@ -170,9 +173,9 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 * @param a2 (OUT): Unused? * @param dev_id (IN): An immediate value and always 8. (cellGcmInitPerfMon uses 11, 10, 9, 7, 12 successively). */ -s32 sys_rsx_device_map(vm::ptr a1, vm::ptr a2, u32 dev_id) +s32 sys_rsx_device_map(vm::ptr addr, vm::ptr a2, u32 dev_id) { - sys_rsx.Todo("sys_rsx_device_map(a1_addr=0x%x, a2_addr=0x%x, a3=%d)", a1.addr(), a2.addr(), dev_id); + sys_rsx.Todo("sys_rsx_device_map(addr=*0x%x, a2=0x%x, dev_id=0x%x)", addr, a2, dev_id); if (dev_id > 15) { // TODO: Throw RSX error @@ -193,12 +196,14 @@ s32 sys_rsx_device_map(vm::ptr a1, vm::ptr a2, u32 dev_id) */ s32 sys_rsx_device_unmap(u32 dev_id) { - sys_rsx.Todo("sys_rsx_device_unmap(a1=%d)", dev_id); + sys_rsx.Todo("sys_rsx_device_unmap(dev_id=0x%x)", dev_id); + return CELL_OK; } -s32 sys_rsx_attribute() +s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5) { - sys_rsx.Todo("sys_rsx_attribute()"); + sys_rsx.Todo("sys_rsx_attribute(a1=0x%x, a2=0x%x, a3=0x%x, a4=0x%x, a5=0x%x)", a1, a2, a3, a4, a5); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h b/rpcs3/Emu/SysCalls/lv2/sys_rsx.h index f44254cef5..8b2b9d0b0a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.h @@ -1,15 +1,17 @@ #pragma once +namespace vm { using namespace ps3; } + // SysCalls s32 sys_rsx_device_open(); s32 sys_rsx_device_close(); -s32 sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7); +s32 sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7); s32 sys_rsx_memory_free(u32 mem_handle); s32 sys_rsx_context_allocate(vm::ptr context_id, vm::ptr lpar_dma_control, vm::ptr lpar_driver_info, vm::ptr lpar_reports, u64 mem_ctx, u64 system_mode); s32 sys_rsx_context_free(u32 context_id); s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags); s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size); s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6); -s32 sys_rsx_device_map(vm::ptr a1, vm::ptr a2, u32 dev_id); +s32 sys_rsx_device_map(vm::ptr addr, vm::ptr a2, u32 dev_id); s32 sys_rsx_device_unmap(u32 dev_id); -s32 sys_rsx_attribute(); +s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index d23d5270dc..fe9b947d9e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -6,11 +6,12 @@ #include "Emu/Cell/PPUThread.h" #include "sleep_queue.h" -#include "sys_time.h" #include "sys_rwlock.h" SysCallBase sys_rwlock("sys_rwlock"); +extern u64 get_system_time(); + s32 sys_rwlock_create(vm::ptr rw_lock_id, vm::ptr attr) { sys_rwlock.Warning("sys_rwlock_create(rw_lock_id=*0x%x, attr=*0x%x)", rw_lock_id, attr); @@ -30,7 +31,7 @@ s32 sys_rwlock_create(vm::ptr rw_lock_id, vm::ptr a default: sys_rwlock.Error("sys_rwlock_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } - if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data()) + if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data()) { sys_rwlock.Error("sys_rwlock_create(): unknown attributes (pshared=0x%x, ipc_key=0x%llx, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags); return CELL_EINVAL; @@ -84,18 +85,14 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) while (rwlock->writer || rwlock->wwaiters) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { rwlock->rwaiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_rwlock.Warning("sys_rwlock_rlock(rw_lock_id=0x%x) aborted", rw_lock_id); - return CELL_OK; - } - rwlock->rcv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } @@ -179,18 +176,14 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) while (rwlock->readers || rwlock->writer) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { rwlock->wwaiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_rwlock.Warning("sys_rwlock_wlock(rw_lock_id=0x%x) aborted", rw_lock_id); - return CELL_OK; - } - rwlock->wcv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h index cb3d73a575..1c0ff707c6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct sys_rwlock_attribute_t { be_t protocol; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index a693d7239a..9884a712a0 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -4,14 +4,14 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#include "Emu/CPU/CPUThreadManager.h" #include "Emu/Cell/PPUThread.h" #include "sleep_queue.h" -#include "sys_time.h" #include "sys_semaphore.h" SysCallBase sys_semaphore("sys_semaphore"); +extern u64 get_system_time(); + s32 sys_semaphore_create(vm::ptr sem, vm::ptr attr, s32 initial_val, s32 max_val) { sys_semaphore.Warning("sys_semaphore_create(sem=*0x%x, attr=*0x%x, initial_val=%d, max_val=%d)", sem, attr, initial_val, max_val); @@ -37,13 +37,13 @@ s32 sys_semaphore_create(vm::ptr sem, vm::ptr at default: sys_semaphore.Error("sys_semaphore_create(): unknown protocol (0x%x)", protocol); return CELL_EINVAL; } - if (attr->pshared.data() != se32(0x200) || attr->ipc_key.data() || attr->flags.data()) + if (attr->pshared != SYS_SYNC_NOT_PROCESS_SHARED || attr->ipc_key.data() || attr->flags.data()) { sys_semaphore.Error("sys_semaphore_create(): unknown attributes (pshared=0x%x, ipc_key=0x%x, flags=0x%x)", attr->pshared, attr->ipc_key, attr->flags); return CELL_EINVAL; } - *sem = Emu.GetIdManager().make(initial_val, max_val, protocol, attr->name_u64); + *sem = Emu.GetIdManager().make(protocol, max_val, attr->name_u64, initial_val); return CELL_OK; } @@ -91,18 +91,14 @@ s32 sys_semaphore_wait(u32 sem, u64 timeout) while (semaphore->value <= 0) { + CHECK_EMU_STATUS; + if (timeout && get_system_time() - start_time > timeout) { semaphore->waiters--; return CELL_ETIMEDOUT; } - if (Emu.IsStopped()) - { - sys_semaphore.Warning("sys_semaphore_wait(%d) aborted", sem); - return CELL_OK; - } - semaphore->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h index a0e98a97ba..25a0071cc0 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + struct sys_semaphore_attribute_t { be_t protocol; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index dd39861734..4a7b53fc8e 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -58,7 +58,7 @@ s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) return CELL_OK; } -s32 sys_spu_image_open(vm::ptr img, vm::ptr path) +s32 sys_spu_image_open(vm::ptr img, vm::cptr path) { sys_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img.addr(), path.addr(), path.get_ptr()); @@ -92,26 +92,21 @@ s32 sys_spu_image_open(vm::ptr img, vm::ptr path) return CELL_OK; } -u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function task) +u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function task = nullptr) { if (option) { - sys_spu.Todo("Unsupported SPU Thread options (0x%x)", option); + sys_spu.Error("Unsupported SPU Thread options (0x%x)", option); } - const auto t = Emu.GetCPU().AddThread(CPU_THREAD_SPU); + const auto spu = Emu.GetIdManager().make_ptr(name, spu_num); - auto& spu = static_cast(*t); - - spu.index = spu_num; - spu.offset = Memory.MainMem.AllocAlign(256 * 1024); - spu.SetName(name); - spu.m_custom_task = task; + spu->m_custom_task = task; const auto group = Emu.GetIdManager().get(group_id); - spu.tg = group; - group->threads[spu_num] = t; + spu->tg = group; + group->threads[spu_num] = spu; group->args[spu_num] = { a1, a2, a3, a4 }; group->images[spu_num] = img; @@ -125,13 +120,17 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, } } - if (count >= group->num) + if (count > group->num) + { + throw EXCEPTION("Unexpected thread count (%d)", count); + } + + if (count == group->num) { - assert(count == group->num); group->state = SPU_THREAD_GROUP_STATUS_INITIALIZED; } - return spu.GetId(); + return spu->GetId(); } s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg) @@ -157,7 +156,7 @@ s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm return CELL_EBUSY; } - *thread = spu_thread_initialize(group_id, spu_num, img, attr->name ? std::string(attr->name.get_ptr(), attr->name_len) : "SPUThread", attr->option, arg->arg1, arg->arg2, arg->arg3, arg->arg4); + *thread = spu_thread_initialize(group_id, spu_num, img, attr->name ? std::string(attr->name.get_ptr(), attr->name_len) : "", attr->option, arg->arg1, arg->arg2, arg->arg3, arg->arg4); return CELL_OK; } @@ -167,23 +166,29 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg) LV2_LOCK; - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto thread = Emu.GetIdManager().get(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + const auto group = thread->tg.lock(); - const auto group = spu.tg.lock(); + if (!group) + { + throw EXCEPTION("Invalid SPU thread group"); + } - assert(spu.index < group->threads.size()); + if (thread->index >= group->threads.size() || group->threads[thread->index] != thread) + { + throw EXCEPTION("Unexpected SPU thread index (%d)", thread->index); + } - group->args[spu.index].arg1 = arg->arg1; - group->args[spu.index].arg2 = arg->arg2; - group->args[spu.index].arg3 = arg->arg3; - group->args[spu.index].arg4 = arg->arg4; + group->args[thread->index].arg1 = arg->arg1; + group->args[thread->index].arg2 = arg->arg2; + group->args[thread->index].arg3 = arg->arg3; + group->args[thread->index].arg4 = arg->arg4; return CELL_OK; } @@ -194,36 +199,20 @@ s32 sys_spu_thread_get_exit_status(u32 id, vm::ptr status) LV2_LOCK; - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto thread = Emu.GetIdManager().get(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + // TODO: check CELL_ESTAT condition - u32 res; - if (!spu.IsStopped() || !spu.ch_out_mbox.pop(res)) // TODO: Is it possible to get the same status twice? If so, we shouldn't use destructive read - { - return CELL_ESTAT; - } - - *status = res; + *status = thread->ch_out_mbox.pop_uncond(); return CELL_OK; } -u32 spu_thread_group_create(const std::string& name, u32 num, s32 prio, s32 type, u32 container) -{ - if (type) - { - sys_spu.Todo("Unsupported SPU Thread Group type (0x%x)", type); - } - - return Emu.GetIdManager().make(name, num, prio, type, container); -} - s32 sys_spu_thread_group_create(vm::ptr id, u32 num, s32 prio, vm::ptr attr) { sys_spu.Warning("sys_spu_thread_group_create(id=*0x%x, num=%d, prio=%d, attr=*0x%x)", id, num, prio, attr); @@ -235,7 +224,13 @@ s32 sys_spu_thread_group_create(vm::ptr id, u32 num, s32 prio, vm::ptrname.get_ptr(), attr->nsize - 1), num, prio, attr->type, attr->ct); + if (attr->type.data()) + { + sys_spu.Todo("Unsupported SPU Thread Group type (0x%x)", attr->type); + } + + *id = Emu.GetIdManager().make(std::string{ attr->name.get_ptr(), attr->nsize - 1 }, num, prio, attr->type, attr->ct); + return CELL_OK; } @@ -262,10 +257,7 @@ s32 sys_spu_thread_group_destroy(u32 id) { if (t) { - auto& spu = static_cast(*t); - - Memory.MainMem.Free(spu.offset); - Emu.GetCPU().RemoveThread(spu.GetId()); + Emu.GetIdManager().remove(t->GetId()); t.reset(); } @@ -304,24 +296,26 @@ s32 sys_spu_thread_group_start(u32 id) { if (t) { - auto& spu = static_cast(*t); + if (t->index >= group->threads.size()) + { + throw EXCEPTION("Unexpected SPU thread index (%d)", t->index); + } - assert(spu.index < group->threads.size()); - auto& args = group->args[spu.index]; - auto& image = group->images[spu.index]; + auto& args = group->args[t->index]; + auto& image = group->images[t->index]; // Copy SPU image: // TODO: use segment info - memcpy(vm::get_ptr(spu.offset), vm::get_ptr(image->addr), 256 * 1024); + std::memcpy(vm::get_ptr(t->offset), vm::get_ptr(image->addr), 256 * 1024); - spu.SetEntry(image->entry_point); - spu.Run(); - spu.GPR[3] = u128::from64(0, args.arg1); - spu.GPR[4] = u128::from64(0, args.arg2); - spu.GPR[5] = u128::from64(0, args.arg3); - spu.GPR[6] = u128::from64(0, args.arg4); + t->PC = image->entry_point; + t->Run(); + t->GPR[3] = u128::from64(0, args.arg1); + t->GPR[4] = u128::from64(0, args.arg2); + t->GPR[5] = u128::from64(0, args.arg3); + t->GPR[6] = u128::from64(0, args.arg4); - spu.status.exchange(SPU_STATUS_RUNNING); + t->status.exchange(SPU_STATUS_RUNNING); } } @@ -331,10 +325,7 @@ s32 sys_spu_thread_group_start(u32 id) for (auto& t : group->threads) { - if (t) - { - t->Exec(); - } + if (t) t->Exec(); } return CELL_OK; @@ -384,12 +375,7 @@ s32 sys_spu_thread_group_suspend(u32 id) for (auto& t : group->threads) { - if (t) - { - auto& spu = static_cast(*t); - - spu.FastStop(); - } + if (t) t->Sleep(); // trigger status check } return CELL_OK; @@ -422,7 +408,6 @@ s32 sys_spu_thread_group_resume(u32 id) else if (group->state == SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED) { group->state = SPU_THREAD_GROUP_STATUS_WAITING; - return CELL_OK; // probably, nothing to do there } else { @@ -431,14 +416,11 @@ s32 sys_spu_thread_group_resume(u32 id) for (auto& t : group->threads) { - if (t) - { - auto& spu = static_cast(*t); - - spu.FastRun(); - } + if (t) t->Awake(); // untrigger status check } + group->cv.notify_all(); + return CELL_OK; } @@ -472,25 +454,16 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) LV2_LOCK; // seems the id can be either SPU Thread Group or SPU Thread - auto thread = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); - auto group = Emu.GetIdManager().get(id); + const auto thread = Emu.GetIdManager().get(id); + const auto group = thread ? thread->tg.lock() : Emu.GetIdManager().get(id); if (!group && !thread) { return CELL_ESRCH; } - auto& spu = static_cast(*thread); - if (thread) { - if (group) - { - throw __FUNCTION__; - } - - group = spu.tg.lock(); - for (auto& t : group->threads) { // find primary (?) thread and compare it with the one specified @@ -508,26 +481,22 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) } } - if ((group->state <= SPU_THREAD_GROUP_STATUS_INITIALIZED) || (group->state == SPU_THREAD_GROUP_STATUS_WAITING)) + if (group->state <= SPU_THREAD_GROUP_STATUS_INITIALIZED || + group->state == SPU_THREAD_GROUP_STATUS_WAITING || + group->state == SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED) { return CELL_ESTAT; } for (auto& t : group->threads) { - if (t) - { - auto& spu = static_cast(*t); - - spu.status.exchange(SPU_STATUS_STOPPED); - spu.FastStop(); - } + if (t) t->Stop(); } group->state = SPU_THREAD_GROUP_STATUS_INITIALIZED; group->exit_status = value; group->join_state |= SPU_TGJSF_TERMINATED; - group->join_cv.notify_one(); + group->cv.notify_one(); return CELL_OK; } @@ -564,9 +533,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) { if (t) { - auto& spu = static_cast(*t); - - if (!(spu.status.read_relaxed() & SPU_STATUS_STOPPED_BY_STOP)) + if ((t->status.load() & SPU_STATUS_STOPPED_BY_STOP) == 0) { stopped = false; break; @@ -579,13 +546,9 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) break; } - if (Emu.IsStopped()) - { - sys_spu.Warning("sys_spu_thread_group_join(id=0x%x) aborted", id); - return CELL_OK; - } + CHECK_EMU_STATUS; - group->join_cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); } switch (group->join_state & ~SPU_TGJSF_IS_JOINING) @@ -605,7 +568,10 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) if (cause) *cause = SYS_SPU_THREAD_GROUP_JOIN_TERMINATED; break; } - default: throw __FUNCTION__; + default: + { + throw EXCEPTION("Unexpected join_state"); + } } if (status) @@ -622,31 +588,38 @@ s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) { sys_spu.Log("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=%d)", id, address, value, type); - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(id); + + if (!thread) { return CELL_ESRCH; } - if (!t->IsRunning()) - { - return CELL_ESTAT; - } - if (address >= 0x40000 || address + type > 0x40000 || address % type) // check range and alignment { return CELL_EINVAL; } - auto& spu = static_cast(*t); + const auto group = thread->tg.lock(); + + if (!group) + { + throw EXCEPTION("Invalid SPU thread group"); + } + + if ((group->state < SPU_THREAD_GROUP_STATUS_WAITING) || (group->state > SPU_THREAD_GROUP_STATUS_RUNNING)) + { + return CELL_ESTAT; + } switch (type) { - case 1: spu.write8(address, (u8)value); break; - case 2: spu.write16(address, (u16)value); break; - case 4: spu.write32(address, (u32)value); break; - case 8: spu.write64(address, value); break; + case 1: thread->write8(address, (u8)value); break; + case 2: thread->write16(address, (u16)value); break; + case 4: thread->write32(address, (u32)value); break; + case 8: thread->write64(address, value); break; default: return CELL_EINVAL; } @@ -657,31 +630,38 @@ s32 sys_spu_thread_read_ls(u32 id, u32 address, vm::ptr value, u32 type) { sys_spu.Log("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value=*0x%x, type=%d)", id, address, value, type); - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(id); + + if (!thread) { return CELL_ESRCH; } - if (!t->IsRunning()) - { - return CELL_ESTAT; - } - if (address >= 0x40000 || address + type > 0x40000 || address % type) // check range and alignment { return CELL_EINVAL; } - auto& spu = static_cast(*t); + const auto group = thread->tg.lock(); + + if (!group) + { + throw EXCEPTION("Invalid SPU thread group"); + } + + if ((group->state < SPU_THREAD_GROUP_STATUS_WAITING) || (group->state > SPU_THREAD_GROUP_STATUS_RUNNING)) + { + return CELL_ESTAT; + } switch (type) { - case 1: *value = spu.read8(address); break; - case 2: *value = spu.read16(address); break; - case 4: *value = spu.read32(address); break; - case 8: *value = spu.read64(address); break; + case 1: *value = thread->read8(address); break; + case 2: *value = thread->read16(address); break; + case 4: *value = thread->read32(address); break; + case 8: *value = thread->read64(address); break; default: return CELL_EINVAL; } @@ -692,16 +672,29 @@ s32 sys_spu_thread_write_spu_mb(u32 id, u32 value) { sys_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value); - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(id); + + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + const auto group = thread->tg.lock(); - spu.ch_in_mbox.push_uncond(value); + if (!group) + { + throw EXCEPTION("Invalid SPU thread group"); + } + + if ((group->state < SPU_THREAD_GROUP_STATUS_WAITING) || (group->state > SPU_THREAD_GROUP_STATUS_RUNNING)) + { + return CELL_ESTAT; + } + + thread->ch_in_mbox.push_uncond(value); + thread->cv.notify_one(); return CELL_OK; } @@ -710,9 +703,11 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) { sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=0x%x, value=0x%x)", id, value); - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(id); + + if (!thread) { return CELL_ESRCH; } @@ -722,9 +717,7 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) return CELL_EINVAL; } - auto& spu = static_cast(*t); - - spu.snr_config = value; + thread->snr_config = value; return CELL_OK; } @@ -733,16 +726,16 @@ s32 sys_spu_thread_get_spu_cfg(u32 id, vm::ptr value) { sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=0x%x, value=*0x%x)", id, value); - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(id); + + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - - *value = spu.snr_config; + *value = thread->snr_config; return CELL_OK; } @@ -751,9 +744,11 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) { sys_spu.Log("sys_spu_thread_write_snr(id=0x%x, number=%d, value=0x%x)", id, number, value); - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + LV2_LOCK; - if (!t) + const auto thread = Emu.GetIdManager().get(id); + + if (!thread) { return CELL_ESRCH; } @@ -763,9 +758,19 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) return CELL_EINVAL; } - auto& spu = static_cast(*t); + const auto group = thread->tg.lock(); - spu.write_snr(number ? true : false, value); + if (!group) + { + throw EXCEPTION("Invalid SPU thread group"); + } + + //if ((group->state < SPU_THREAD_GROUP_STATUS_WAITING) || (group->state > SPU_THREAD_GROUP_STATUS_RUNNING)) // ??? + //{ + // return CELL_ESTAT; + //} + + thread->write_snr(number, value); return CELL_OK; } @@ -895,23 +900,21 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup) LV2_LOCK; - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto thread = Emu.GetIdManager().get(id); const auto queue = Emu.GetIdManager().get(eq); - if (!t || !queue) + if (!thread || !queue) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - if (et != SYS_SPU_THREAD_EVENT_USER || spup > 63 || queue->type != SYS_PPU_QUEUE) { sys_spu.Error("sys_spu_thread_connect_event(): invalid arguments (et=%d, spup=%d, queue->type=%d)", et, spup, queue->type); return CELL_EINVAL; } - auto& port = spu.spup[spup]; + auto& port = thread->spup[spup]; if (!port.expired()) { @@ -929,22 +932,20 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) LV2_LOCK; - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto thread = Emu.GetIdManager().get(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - if (et != SYS_SPU_THREAD_EVENT_USER || spup > 63) { sys_spu.Error("sys_spu_thread_disconnect_event(): invalid arguments (et=%d, spup=%d)", et, spup); return CELL_EINVAL; } - auto& port = spu.spup[spup]; + auto& port = thread->spup[spup]; if (port.expired()) { @@ -962,22 +963,20 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num) LV2_LOCK; - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto thread = Emu.GetIdManager().get(id); const auto queue = Emu.GetIdManager().get(spuq); - if (!t || !queue) + if (!thread || !queue) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - if (queue->type != SYS_SPU_QUEUE) { return CELL_EINVAL; } - for (auto& v : spu.spuq) + for (auto& v : thread->spuq) { if (auto q = v.second.lock()) { @@ -988,7 +987,7 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num) } } - for (auto& v : spu.spuq) + for (auto& v : thread->spuq) { if (v.second.expired()) { @@ -1008,16 +1007,14 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) LV2_LOCK; - const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto thread = Emu.GetIdManager().get(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - - for (auto& v : spu.spuq) + for (auto& v : thread->spuq) { if (v.first == spuq_num && !v.second.expired()) { @@ -1069,9 +1066,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm:: { if (t) { - auto& spu = static_cast(*t); - - if (!spu.spup[port].expired()) + if (!t->spup[port].expired()) { found = false; break; @@ -1094,9 +1089,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm:: { if (t) { - auto& spu = static_cast(*t); - - spu.spup[port] = queue; + t->spup[port] = queue; } } @@ -1127,9 +1120,7 @@ s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) { if (t) { - auto& spu = static_cast(*t); - - spu.spup[spup].reset(); + t->spup[spup].reset(); } } @@ -1142,18 +1133,18 @@ s32 sys_raw_spu_create(vm::ptr id, vm::ptr attr) LV2_LOCK; - const auto t = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); + // TODO: check number set by sys_spu_initialize() - if (!t) + const auto thread = Emu.GetCPU().NewRawSPUThread(); + + if (!thread) { return CELL_EAGAIN; } - Memory.Map(t->offset = RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * t->index, 0x40000); + thread->Run(); - t->Run(); - - *id = t->index; + *id = thread->index; return CELL_OK; } @@ -1164,20 +1155,16 @@ s32 sys_raw_spu_destroy(u32 id) LV2_LOCK; - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - // TODO: check if busy - Memory.Unmap(spu.offset); - - Emu.GetCPU().RemoveThread(t->GetId()); + Emu.GetIdManager().remove(thread->GetId()); return CELL_OK; } @@ -1191,16 +1178,14 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr return CELL_EINVAL; } - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - - auto& tag = class_id ? spu.int2 : spu.int0; + auto& tag = class_id ? thread->int2 : thread->int0; if (!tag.assigned.compare_and_swap_test(-1, 0)) { @@ -1221,16 +1206,16 @@ s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) return CELL_EINVAL; } - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + auto& tag = class_id ? thread->int2 : thread->int0; - (class_id ? spu.int2 : spu.int0).mask.exchange(mask); + tag.mask.exchange(mask); return CELL_OK; } @@ -1244,16 +1229,16 @@ s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, vm::ptr mask) return CELL_EINVAL; } - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + auto& tag = class_id ? thread->int2 : thread->int0; - *mask = (class_id ? spu.int2 : spu.int0).mask.read_sync(); + *mask = tag.mask.load(); return CELL_OK; } @@ -1267,16 +1252,16 @@ s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) return CELL_EINVAL; } - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + auto& tag = class_id ? thread->int2 : thread->int0; - (class_id ? spu.int2 : spu.int0).clear(stat); + tag.clear(stat); return CELL_OK; } @@ -1290,16 +1275,16 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr stat) return CELL_EINVAL; } - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); + auto& tag = class_id ? thread->int2 : thread->int0; - *stat = (class_id ? spu.int2 : spu.int0).stat.read_sync(); + *stat = tag.stat.load(); return CELL_OK; } @@ -1308,16 +1293,14 @@ s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr value) { sys_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value=*0x%x)", id, value); - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - - *value = spu.ch_out_intr_mbox.pop_uncond(); + *value = thread->ch_out_intr_mbox.pop_uncond(); return CELL_OK; } @@ -1328,19 +1311,17 @@ s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value) if (value > 3) { - sys_spu.Fatal("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value); + throw EXCEPTION("Unexpected value (0x%x)", value); } - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - - spu.snr_config = value; + thread->snr_config = value; return CELL_OK; } @@ -1349,16 +1330,14 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr value) { sys_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value=*0x%x)", id, value); - const auto t = Emu.GetCPU().GetRawSPUThread(id); + const auto thread = Emu.GetCPU().GetRawSPUThread(id); - if (!t) + if (!thread) { return CELL_ESRCH; } - auto& spu = static_cast(*t); - - *value = (u32)spu.snr_config; + *value = (u32)thread->snr_config; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index 590d93dead..6d39a1f8e9 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + #include "sys_event.h" enum : s32 @@ -44,7 +46,7 @@ enum : u32 SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED, SPU_THREAD_GROUP_STATUS_RUNNING, SPU_THREAD_GROUP_STATUS_STOPPED, - SPU_THREAD_GROUP_STATUS_UNKNOWN + SPU_THREAD_GROUP_STATUS_UNKNOWN, }; enum : s32 @@ -57,7 +59,7 @@ enum : s32 struct sys_spu_thread_group_attribute { be_t nsize; // name length including NULL terminator - vm::bptr name; + vm::bcptr name; be_t type; be_t ct; // memory container id }; @@ -71,7 +73,7 @@ enum : u32 struct sys_spu_thread_attribute { - vm::bptr name; + vm::bcptr name; be_t name_len; be_t option; }; @@ -97,7 +99,7 @@ struct sys_spu_segment }; }; -static_assert(sizeof(sys_spu_segment) == 0x18, "Wrong sys_spu_segment size"); +CHECK_SIZE(sys_spu_segment, 0x18); enum : u32 { @@ -139,6 +141,8 @@ enum : u32 SPU_TGJSF_GROUP_EXIT = (1 << 2), // set if SPU Thread Group is terminated by sys_spu_thread_group_exit }; +class SPUThread; + struct spu_group_t { const std::string name; @@ -146,16 +150,16 @@ struct spu_group_t const s32 type; // SPU Thread Group Type const u32 ct; // Memory Container Id - std::array, 256> threads; // SPU Threads + std::array, 256> threads; // SPU Threads std::array, 256> images; // SPU Images std::array args; // SPU Thread Arguments s32 prio; // SPU Thread Group Priority - u32 state; // SPU Thread Group State + volatile u32 state; // SPU Thread Group State s32 exit_status; // SPU Thread Group Exit Status std::atomic join_state; // flags used to detect exit cause - std::condition_variable join_cv; // used to signal waiting PPU thread + std::condition_variable cv; // used to signal waiting PPU thread std::weak_ptr ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events std::weak_ptr ep_exception; // TODO: SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION @@ -204,7 +208,6 @@ struct spu_group_t } }; -class SPUThread; struct vfsStream; void LoadSpuImage(vfsStream& stream, u32& spu_ep, u32 addr); @@ -212,12 +215,11 @@ u32 LoadSpuImage(vfsStream& stream, u32& spu_ep); // Aux s32 spu_image_import(sys_spu_image& img, u32 src, u32 type); -u32 spu_thread_group_create(const std::string& name, u32 num, s32 prio, s32 type, u32 container); -u32 spu_thread_initialize(u32 group, u32 spu_num, vm::ptr img, const std::string& name, u32 option, u64 a1, u64 a2, u64 a3, u64 a4, std::function task = nullptr); // SysCalls s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu); -s32 sys_spu_image_open(vm::ptr img, vm::ptr path); +s32 sys_spu_image_open(vm::ptr img, vm::cptr path); +s32 sys_spu_image_close(vm::ptr img); s32 sys_spu_thread_initialize(vm::ptr thread, u32 group, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg); s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg); s32 sys_spu_thread_group_create(vm::ptr id, u32 num, s32 prio, vm::ptr attr); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp index c408931bad..3ed358e199 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp @@ -1,96 +1,155 @@ -/* -* This file contains Nt monotonic counter code, taken from wine which is: -* Copyright 2002 Rex Jolliff (rex@lvcablemodem.com) -* Copyright 1999 Juergen Schmied -* Copyright 2007 Dmitry Timoshkov -* GNU LGPL 2.1 license -* */ #include "stdafx.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" -#ifdef _WIN32 -#include -#endif #include "sys_time.h" +#ifdef _WIN32 + +#include + +struct time_aux_info_t +{ + u64 perf_freq; + u64 start_time; + u64 start_ftime; // time in 100ns units since Epoch +} +const g_time_aux_info = []() -> time_aux_info_t // initialize time-related values (Windows-only) +{ + LARGE_INTEGER freq; + if (!QueryPerformanceFrequency(&freq)) + { + MessageBox(0, L"Your hardware doesn't support a high-resolution performance counter", L"Error", MB_OK | MB_ICONERROR); + return{}; + } + + LARGE_INTEGER start; + QueryPerformanceCounter(&start); // get time in 1/perf_freq units from RDTSC + + FILETIME ftime; + GetSystemTimeAsFileTime(&ftime); // get time in 100ns units since January 1, 1601 (UTC) + + time_aux_info_t result; + result.perf_freq = freq.QuadPart; + result.start_time = start.QuadPart; + result.start_ftime = (ftime.dwLowDateTime | (u64)ftime.dwHighDateTime << 32) - 116444736000000000; + + return result; +}(); + +#else + +#include "errno.h" + +#endif + SysCallBase sys_time("sys_time"); -static const u64 timebase_frequency = /*79800000*/ 80000000; // 80 Mhz -extern int cellSysutilGetSystemParamInt(int id, vm::ptr value); +static const u64 g_timebase_freq = /*79800000*/ 80000000; // 80 Mhz // Auxiliary functions -u64 get_time() +u64 get_timebased_time() { #ifdef _WIN32 - static struct PerformanceFreqHolder + LARGE_INTEGER count; + if (!QueryPerformanceCounter(&count)) { - u64 value; + throw EXCEPTION("System error 0x%x", GetLastError()); + } - PerformanceFreqHolder() - { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - value = freq.QuadPart; - } - } freq; + const u64 time = count.QuadPart; + const u64 freq = g_time_aux_info.perf_freq; - LARGE_INTEGER cycle; - QueryPerformanceCounter(&cycle); - u64 sec = cycle.QuadPart / freq.value; - return sec * timebase_frequency + (cycle.QuadPart % freq.value) * timebase_frequency / freq.value; + return time / freq * g_timebase_freq + time % freq * g_timebase_freq / freq; #else struct timespec ts; - if (!clock_gettime(CLOCK_MONOTONIC, &ts)) - return ts.tv_sec * (s64)timebase_frequency + (s64)ts.tv_nsec * (s64)timebase_frequency / 1000000000; - - // Should never occur. - assert(0); - return 0; + if (::clock_gettime(CLOCK_MONOTONIC, &ts)) + { + throw EXCEPTION("System error %d", errno); + } + + return static_cast(ts.tv_sec) * g_timebase_freq + static_cast(ts.tv_nsec) * g_timebase_freq / 1000000000u; #endif } // Returns some relative time in microseconds, don't change this fact u64 get_system_time() { - return get_time() / (timebase_frequency / MHZ); -} + while (true) + { +#ifdef _WIN32 + LARGE_INTEGER count; + if (!QueryPerformanceCounter(&count)) + { + throw EXCEPTION("System error 0x%x", GetLastError()); + } + const u64 time = count.QuadPart; + const u64 freq = g_time_aux_info.perf_freq; + + const u64 result = time / freq * 1000000u + (time % freq) * 1000000u / freq; +#else + struct timespec ts; + if (::clock_gettime(CLOCK_MONOTONIC, &ts)) + { + throw EXCEPTION("System error %d", errno); + } + + const u64 result = static_cast(ts.tv_sec) * 1000000u + static_cast(ts.tv_nsec) / 1000u; +#endif + + if (result) return result; + } +} // Functions -s32 sys_time_get_timezone(vm::ptr timezone, vm::ptr summertime) +s32 sys_time_get_timezone(vm::ptr timezone, vm::ptr summertime) { - sys_time.Warning("sys_time_get_timezone(timezone_addr=0x%x, summertime_addr=0x%x)", timezone.addr(), summertime.addr()); + sys_time.Warning("sys_time_get_timezone(timezone=*0x%x, summertime=*0x%x)", timezone, summertime); - int ret; - ret = cellSysutilGetSystemParamInt(0x0116, timezone); //0x0116 = CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE - if (ret != CELL_OK) return ret; - ret = cellSysutilGetSystemParamInt(0x0117, summertime); //0x0117 = CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE - if (ret != CELL_OK) return ret; - return CELL_OK; -} - -s32 sys_time_get_current_time(u32 sec_addr, u32 nsec_addr) -{ - sys_time.Log("sys_time_get_current_time(sec_addr=0x%x, nsec_addr=0x%x)", sec_addr, nsec_addr); - - u64 time = get_time(); - - vm::write64(sec_addr, time / timebase_frequency); - vm::write64(nsec_addr, (time % timebase_frequency) * 1000000000 / (s64)(timebase_frequency)); + *timezone = 180; + *summertime = 0; return CELL_OK; } -s64 sys_time_get_system_time() +s32 sys_time_get_current_time(vm::ptr sec, vm::ptr nsec) { - sys_time.Log("sys_time_get_system_time()"); - return get_system_time(); + sys_time.Log("sys_time_get_current_time(sec=*0x%x, nsec=*0x%x)", sec, nsec); + +#ifdef _WIN32 + LARGE_INTEGER count; + if (!QueryPerformanceCounter(&count)) + { + throw EXCEPTION("System error 0x%x", GetLastError()); + } + + // get time difference in nanoseconds + const u64 diff = (count.QuadPart - g_time_aux_info.start_time) * 1000000000u / g_time_aux_info.perf_freq; + + // get time since Epoch in nanoseconds + const u64 time = g_time_aux_info.start_ftime * 100u + diff; + + *sec = time / 1000000000u; + *nsec = time % 1000000000u; +#else + struct timespec ts; + if (::clock_gettime(CLOCK_REALTIME, &ts)) + { + throw EXCEPTION("System error %d", errno); + } + + *sec = ts.tv_sec; + *nsec = ts.tv_nsec; +#endif + + return CELL_OK; } u64 sys_time_get_timebase_frequency() { sys_time.Log("sys_time_get_timebase_frequency()"); - return timebase_frequency; + + return g_timebase_freq; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.h b/rpcs3/Emu/SysCalls/lv2/sys_time.h index dacff931e0..3070196c7f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_time.h @@ -1,16 +1,8 @@ #pragma once -enum : u32 -{ - MHZ = 1000000, -}; - -// Auxiliary functions -u64 get_time(); -u64 get_system_time(); +namespace vm { using namespace ps3; } // SysCalls -s32 sys_time_get_timezone(vm::ptr timezone, vm::ptr summertime); -s32 sys_time_get_current_time(u32 sec_addr, u32 nsec_addr); -s64 sys_time_get_system_time(); +s32 sys_time_get_timezone(vm::ptr timezone, vm::ptr summertime); +s32 sys_time_get_current_time(vm::ptr sec, vm::ptr nsec); u64 sys_time_get_timebase_frequency(); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index 3bc6592e11..bbb4a697b2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -5,53 +5,70 @@ #include "Emu/SysCalls/SysCalls.h" #include "Utilities/Thread.h" -#include "sys_time.h" #include "sys_event.h" #include "sys_process.h" #include "sys_timer.h" SysCallBase sys_timer("sys_timer"); -s32 sys_timer_create(vm::ptr timer_id) +extern u64 get_system_time(); + +lv2_timer_t::lv2_timer_t() + : start(0) + , period(0) + , state(SYS_TIMER_STATE_STOP) { - sys_timer.Warning("sys_timer_create(timer_id=*0x%x)", timer_id); + auto name = fmt::format("Timer[0x%x] Thread", Emu.GetIdManager().get_current_id()); - std::shared_ptr timer(new lv2_timer_t); - - thread_t(fmt::format("Timer[0x%x] Thread", (*timer_id = Emu.GetIdManager().add(timer))), [timer]() // TODO: call from the constructor + thread.start([name]{ return name; }, [this]() { - LV2_LOCK; + std::unique_lock lock(thread.mutex); - while (!timer.unique() && !Emu.IsStopped()) + while (thread.joinable()) { - if (timer->state == SYS_TIMER_STATE_RUN) + CHECK_EMU_STATUS; + + if (state == SYS_TIMER_STATE_RUN) { - if (get_system_time() >= timer->start) + LV2_LOCK; + + if (get_system_time() >= start) { - const auto queue = timer->port.lock(); + const auto queue = port.lock(); if (queue) { - queue->push(lv2_lock, timer->source, timer->data1, timer->data2, timer->start); + queue->push(lv2_lock, source, data1, data2, start); } - if (timer->period && queue) + if (period && queue) { - timer->start += timer->period; // set next expiration time + start += period; // set next expiration time continue; // hack: check again } else { - timer->state = SYS_TIMER_STATE_STOP; // stop if oneshot or the event port was disconnected (TODO: is it correct?) + state = SYS_TIMER_STATE_STOP; // stop if oneshot or the event port was disconnected (TODO: is it correct?) } } } - timer->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + thread.cv.wait_for(lock, std::chrono::milliseconds(1)); } + }); +} - }).detach(); +lv2_timer_t::~lv2_timer_t() +{ + thread.join(); +} + +s32 sys_timer_create(vm::ptr timer_id) +{ + sys_timer.Warning("sys_timer_create(timer_id=*0x%x)", timer_id); + + *timer_id = Emu.GetIdManager().make(); return CELL_OK; } @@ -84,7 +101,7 @@ s32 sys_timer_get_information(u32 timer_id, vm::ptr inf sys_timer.Warning("sys_timer_get_information(timer_id=0x%x, info=*0x%x)", timer_id, info); LV2_LOCK; - + const auto timer = Emu.GetIdManager().get(timer_id); if (!timer) @@ -94,7 +111,7 @@ s32 sys_timer_get_information(u32 timer_id, vm::ptr inf info->next_expiration_time = timer->start; - info->period = timer->period; + info->period = timer->period; info->timer_state = timer->state; return CELL_OK; @@ -146,10 +163,11 @@ s32 _sys_timer_start(u32 timer_id, u64 base_time, u64 period) // sys_timer_start_periodic() will use current time (TODO: is it correct?) - timer->start = base_time ? base_time : start_time + period; + timer->start = base_time ? base_time : start_time + period; timer->period = period; - timer->state = SYS_TIMER_STATE_RUN; - timer->cv.notify_one(); + timer->state = SYS_TIMER_STATE_RUN; + + timer->thread.cv.notify_one(); return CELL_OK; } @@ -191,10 +209,10 @@ s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data return CELL_EISCONN; } - timer->port = queue; // connect event queue + timer->port = queue; // connect event queue timer->source = name ? name : ((u64)process_getpid() << 32) | timer_id; - timer->data1 = data1; - timer->data2 = data2; + timer->data1 = data1; + timer->data2 = data2; return CELL_OK; } @@ -235,13 +253,9 @@ s32 sys_timer_sleep(u32 sleep_time) while (useconds > (passed = get_system_time() - start_time) + 1000) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - sys_timer.Warning("sys_timer_sleep(sleep_time=%d) aborted", sleep_time); - return CELL_OK; - } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } if (useconds > passed) @@ -262,13 +276,9 @@ s32 sys_timer_usleep(u64 sleep_time) while (sleep_time > (passed = get_system_time() - start_time) + 1000) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + CHECK_EMU_STATUS; - if (Emu.IsStopped()) - { - sys_timer.Warning("sys_timer_usleep(sleep_time=0x%llx) aborted", sleep_time); - return CELL_OK; - } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } if (sleep_time > passed) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.h b/rpcs3/Emu/SysCalls/lv2/sys_timer.h index 257d779b3d..0d5c87e227 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.h @@ -1,5 +1,9 @@ #pragma once +#include "Utilities/Thread.h" + +namespace vm { using namespace ps3; } + // Timer State enum : u32 { @@ -15,8 +19,7 @@ struct sys_timer_information_t be_t pad; }; -// "timer_t" conflicts with some definition -struct lv2_timer_t +struct lv2_timer_t final { std::weak_ptr port; // event queue u64 source; // event source @@ -27,14 +30,11 @@ struct lv2_timer_t u64 period; // period (oneshot if 0) std::atomic state; // timer state - std::condition_variable cv; - lv2_timer_t() - : start(0) - , period(0) - , state(SYS_TIMER_STATE_STOP) - { - } + thread_t thread; // timer thread + + lv2_timer_t(); + ~lv2_timer_t(); }; REG_ID_TYPE(lv2_timer_t, 0x11); // SYS_TIMER_OBJECT diff --git a/rpcs3/Emu/SysCalls/lv2/sys_trace.h b/rpcs3/Emu/SysCalls/lv2/sys_trace.h index 5b253893c3..43be75ff47 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_trace.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_trace.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // SysCalls s32 sys_trace_create(); s32 sys_trace_start(); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp b/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp index 0263ac023d..0c63d21500 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_tty.cpp @@ -18,7 +18,7 @@ s32 sys_tty_read(s32 ch, vm::ptr buf, u32 len, vm::ptr preadlen) return CELL_OK; } -s32 sys_tty_write(s32 ch, vm::ptr buf, u32 len, vm::ptr pwritelen) +s32 sys_tty_write(s32 ch, vm::cptr buf, u32 len, vm::ptr pwritelen) { sys_tty.Log("sys_tty_write(ch=%d, buf_addr=0x%x, len=%d, preadlen_addr=0x%x)", ch, buf.addr(), len, pwritelen.addr()); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_tty.h b/rpcs3/Emu/SysCalls/lv2/sys_tty.h index 602acda625..244d4d2d8c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_tty.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_tty.h @@ -1,5 +1,7 @@ #pragma once +namespace vm { using namespace ps3; } + // TTY channels enum { @@ -24,4 +26,4 @@ enum // SysCalls s32 sys_tty_read(s32 ch, vm::ptr buf, u32 len, vm::ptr preadlen); -s32 sys_tty_write(s32 ch, vm::ptr buf, u32 len, vm::ptr pwritelen); +s32 sys_tty_write(s32 ch, vm::cptr buf, u32 len, vm::ptr pwritelen); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp index cb9f9b65ff..df3cce16a5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp @@ -8,55 +8,24 @@ #include "sys_vm.h" SysCallBase sys_vm("sys_vm"); -std::shared_ptr current_ct; -s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr) +s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr) { - sys_vm.Error("sys_vm_memory_map(vsize=0x%x, psize=0x%x, cid=0x%x, flags=0x%llx, policy=0x%llx, addr_addr=0x%x)", - vsize, psize, cid, flag, policy, addr); + sys_vm.Error("sys_vm_memory_map(vsize=0x%x, psize=0x%x, cid=0x%x, flags=0x%llx, policy=0x%llx, addr=*0x%x)", vsize, psize, cid, flag, policy, addr); - // Check virtual size. - if((vsize < (0x100000 * 32)) || (vsize > (0x100000 * 256))) - { - return CELL_EINVAL; - } - - // Check physical size. - if(psize > (0x100000 * 256)) - { - return CELL_ENOMEM; - } + LV2_LOCK; // Use fixed address (TODO: search and use some free address instead) - u32 new_addr = vm::check_addr(0x60000000) ? 0x70000000 : 0x60000000; + const u32 new_addr = vm::check_addr(0x60000000) ? 0x70000000 : 0x60000000; - // If container ID is SYS_MEMORY_CONTAINER_ID_INVALID, allocate directly. - if(cid == SYS_MEMORY_CONTAINER_ID_INVALID) - { - // Create a new MemoryContainerInfo to act as default container with vsize. - current_ct.reset(new MemoryContainerInfo(new_addr, vsize)); - } - else - { - // Check memory container. - const auto ct = Emu.GetIdManager().get(cid); - - if (!ct) - { - return CELL_ESRCH; - } - - current_ct = ct; - } - - // Allocate actual memory using virtual size (physical size is ignored) + // Map memory if (!Memory.Map(new_addr, vsize)) { return CELL_ENOMEM; } // Write a pointer for the allocated memory. - vm::write32(addr, new_addr); + *addr = new_addr; return CELL_OK; } @@ -65,211 +34,99 @@ s32 sys_vm_unmap(u32 addr) { sys_vm.Error("sys_vm_unmap(addr=0x%x)", addr); - // Unmap memory. - assert(addr == 0x60000000 || addr == 0x70000000); - if(!Memory.Unmap(addr)) return CELL_EINVAL; + LV2_LOCK; + + if (!Memory.Unmap(addr)) + { + return CELL_EINVAL; + } return CELL_OK; } s32 sys_vm_append_memory(u32 addr, u32 size) { - sys_vm.Todo("sys_vm_append_memory(addr=0x%x,size=0x%x)", addr, size); - - // Check address and size. - if((current_ct->addr != addr) || (size <= 0)) - { - return CELL_EINVAL; - } - - // Total memory size must not be superior to 256MB. - if((current_ct->size + size) > (0x100000 * 256)) - { - return CELL_ENOMEM; - } - - // The size is added to the virtual size, which should be inferior to the physical size allocated. - current_ct->size += size; + sys_vm.Todo("sys_vm_append_memory(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_return_memory(u32 addr, u32 size) { - sys_vm.Todo("sys_vm_return_memory(addr=0x%x,size=0x%x)", addr, size); - - // Check address and size. - if((current_ct->addr != addr) || (size <= 0)) - { - return CELL_EINVAL; - } - - // The memory size to return should not be superior to the virtual size in use minus 1MB. - if(current_ct->size < (size + 0x100000)) - { - return CELL_EBUSY; - } - - // The size is returned to physical memory and is subtracted to the virtual size. - current_ct->size -= size; + sys_vm.Todo("sys_vm_return_memory(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_lock(u32 addr, u32 size) { - sys_vm.Todo("sys_vm_lock(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("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)) - { - return CELL_EINVAL; - } - - // The memory size to return should not be superior to the virtual size to lock minus 1MB. - if(current_ct->size < (size + 0x100000)) - { - return CELL_EBUSY; - } - - // TODO: The locked memory area keeps allocated and unchanged until sys_vm_unlocked is called. return CELL_OK; } s32 sys_vm_unlock(u32 addr, u32 size) { - sys_vm.Todo("sys_vm_unlock(addr=0x%x,size=0x%x)", addr, size); + sys_vm.Todo("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)) - { - return CELL_EINVAL; - } - - // TODO: Unlock return CELL_OK; } s32 sys_vm_touch(u32 addr, u32 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)) - { - return CELL_EINVAL; - } - - // TODO - // sys_vm_touch allocates physical memory for a virtual memory address. - // This function is asynchronous, so it may not complete immediately. + sys_vm.Todo("sys_vm_touch(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_flush(u32 addr, u32 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)) - { - return CELL_EINVAL; - } - - // TODO - // sys_vm_flush frees physical memory for a virtual memory address and creates a backup if the memory area is dirty. - // This function is asynchronous, so it may not complete immediately. + sys_vm.Todo("sys_vm_flush(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_invalidate(u32 addr, u32 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)) - { - return CELL_EINVAL; - } - - // TODO - // sys_vm_invalidate frees physical memory for a virtual memory address. - // This function is asynchronous, so it may not complete immediately. + sys_vm.Todo("sys_vm_invalidate(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_store(u32 addr, u32 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)) - { - return CELL_EINVAL; - } - - // TODO - // sys_vm_store creates a backup for a dirty virtual memory area and marks it as clean. - // This function is asynchronous, so it may not complete immediately. + sys_vm.Todo("sys_vm_store(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_sync(u32 addr, u32 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)) - { - return CELL_EINVAL; - } - - // TODO - // sys_vm_sync stalls execution until all asynchronous vm calls finish. + sys_vm.Todo("sys_vm_sync(addr=0x%x, size=0x%x)", addr, size); return CELL_OK; } s32 sys_vm_test(u32 addr, u32 size, vm::ptr result) { - sys_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=*0x%x)", addr, size, result); - // Check address and size. - if((current_ct->addr != addr) || (current_ct->size < size) || (size <= 0)) - { - return CELL_EINVAL; - } - - // TODO - // sys_vm_test checks the state of a portion of the virtual memory area. - - // Faking. - *result = SYS_VM_TEST_ALLOCATED; + *result = SYS_VM_STATE_ON_MEMORY; return CELL_OK; } -s32 sys_vm_get_statistics(u32 addr, vm::ptr stat) +s32 sys_vm_get_statistics(u32 addr, vm::ptr stat) { - sys_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=*0x%x)", addr, stat); - // Check address. - if(current_ct->addr != addr) - { - return CELL_EINVAL; - } - - // TODO stat->page_fault_ppu = 0; stat->page_fault_spu = 0; stat->page_in = 0; stat->page_out = 0; - stat->pmem_total = current_ct->size; + stat->pmem_total = 0; stat->pmem_used = 0; stat->timestamp = 0; + return CELL_OK; -} \ No newline at end of file +} diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.h b/rpcs3/Emu/SysCalls/lv2/sys_vm.h index d803063eab..cce3134611 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.h @@ -1,14 +1,16 @@ #pragma once +namespace vm { using namespace ps3; } + enum : u64 { - SYS_VM_TEST_INVALID = 0, - SYS_VM_TEST_UNUSED = 1, - SYS_VM_TEST_ALLOCATED = 2, - SYS_VM_TEST_STORED = 4, + SYS_VM_STATE_INVALID = 0ull, + SYS_VM_STATE_UNUSED = 1ull, + SYS_VM_STATE_ON_MEMORY = 2ull, + SYS_VM_STATE_STORED = 4ull, }; -struct sys_vm_statistics +struct sys_vm_statistics_t { be_t page_fault_ppu; // Number of bad virtual memory accesses from a PPU thread. be_t page_fault_spu; // Number of bad virtual memory accesses from a SPU thread. @@ -20,7 +22,7 @@ struct sys_vm_statistics }; // SysCalls -s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr); +s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr addr); s32 sys_vm_unmap(u32 addr); s32 sys_vm_append_memory(u32 addr, u32 size); s32 sys_vm_return_memory(u32 addr, u32 size); @@ -32,4 +34,4 @@ s32 sys_vm_invalidate(u32 addr, u32 size); s32 sys_vm_store(u32 addr, u32 size); s32 sys_vm_sync(u32 addr, u32 size); s32 sys_vm_test(u32 addr, u32 size, vm::ptr result); -s32 sys_vm_get_statistics(u32 addr, vm::ptr stat); +s32 sys_vm_get_statistics(u32 addr, vm::ptr stat); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 11ef295559..0001013166 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -5,8 +5,6 @@ #include "Emu/System.h" #include "Emu/GameInfo.h" -#include "Emu/ARMv7/PSVFuncList.h" -#include "Emu/ARMv7/PSVObjectList.h" #include "Emu/SysCalls/ModuleManager.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" @@ -39,7 +37,10 @@ static const std::string& BreakPointsDBName = "BreakPoints.dat"; static const u16 bpdb_version = 0x1000; extern std::atomic g_thread_count; +extern u64 get_system_time(); extern void finalize_ppu_exec_map(); +extern void finalize_psv_modules(); +extern void clear_all_psv_objects(); Emulator::Emulator() : m_status(Stopped) @@ -63,17 +64,6 @@ Emulator::Emulator() Emulator::~Emulator() { - delete m_thread_manager; - delete m_pad_manager; - delete m_keyboard_manager; - delete m_mouse_manager; - delete m_id_manager; - delete m_gs_manager; - delete m_audio_manager; - delete m_callback_manager; - delete m_event_manager; - delete m_module_manager; - delete m_vfs; } void Emulator::Init() @@ -96,46 +86,6 @@ void Emulator::SetTitle(const std::string& title) m_title = title; } -void Emulator::CheckStatus() -{ - //auto threads = GetCPU().GetThreads(); - - //if (!threads.size()) - //{ - // Stop(); - // return; - //} - - //bool AllPaused = true; - - //for (auto& t : threads) - //{ - // if (t->IsPaused()) continue; - // AllPaused = false; - // break; - //} - - //if (AllPaused) - //{ - // Pause(); - // return; - //} - - //bool AllStopped = true; - - //for (auto& t : threads) - //{ - // if (t->IsStopped()) continue; - // AllStopped = false; - // break; - //} - - //if (AllStopped) - //{ - // Pause(); - //} -} - bool Emulator::BootGame(const std::string& path, bool direct) { static const char* elf_path[6] = @@ -179,9 +129,15 @@ bool Emulator::BootGame(const std::string& path, bool direct) void Emulator::Load() { + m_status = Ready; + GetModuleManager().Init(); - if (!fs::is_file(m_path)) return; + if (!fs::is_file(m_path)) + { + m_status = Stopped; + return; + } const std::string elf_dir = m_path.substr(0, m_path.find_last_of("/\\", std::string::npos, 2) + 1); @@ -214,12 +170,13 @@ void Emulator::Load() if (!DecryptSelf(m_path, elf_dir + full_name)) { + m_status = Stopped; return; } } LOG_NOTICE(LOADER, "Loading '%s'...", m_path.c_str()); - GetInfo().Reset(); + ResetInfo(); GetVFS().Init(elf_dir); // /dev_bdvd/ mounting @@ -275,20 +232,20 @@ void Emulator::Load() if (!f.IsOpened()) { LOG_ERROR(LOADER, "Opening '%s' failed", m_path.c_str()); + m_status = Stopped; return; } if (!m_loader.load(f)) { LOG_ERROR(LOADER, "Loading '%s' failed", m_path.c_str()); + m_status = Stopped; vm::close(); return; } LoadPoints(BreakPointsDBName); - m_status = Ready; - GetGSManager().Init(); GetCallbackManager().Init(); GetAudioManager().Init(); @@ -315,6 +272,8 @@ void Emulator::Run() SendDbgCommand(DID_START_EMU); + m_pause_start_time = 0; + m_pause_amend_time = 0; m_status = Running; GetCPU().Exec(); @@ -323,47 +282,86 @@ void Emulator::Run() void Emulator::Pause() { - if (!IsRunning()) return; + const u64 start = get_system_time(); + + // try to set Paused status + if (!sync_bool_compare_and_swap(&m_status, Running, Paused)) + { + return; + } + + // update pause start time + if (m_pause_start_time.exchange(start)) + { + LOG_ERROR(GENERAL, "Emulator::Pause() error: concurrent access"); + } + SendDbgCommand(DID_PAUSE_EMU); - if (sync_bool_compare_and_swap((volatile u32*)&m_status, Running, Paused)) + for (auto& t : GetCPU().GetAllThreads()) { - SendDbgCommand(DID_PAUSED_EMU); - - GetCallbackManager().RunPauseCallbacks(true); + t->Sleep(); // trigger status check } + + SendDbgCommand(DID_PAUSED_EMU); } void Emulator::Resume() { - if (!IsPaused()) return; + // get pause start time + const u64 time = m_pause_start_time.exchange(0); + + // try to increment summary pause time + if (time) + { + m_pause_amend_time += get_system_time() - time; + } + + // try to resume + if (!sync_bool_compare_and_swap(&m_status, Paused, Running)) + { + return; + } + + if (!time) + { + LOG_ERROR(GENERAL, "Emulator::Resume() error: concurrent access"); + } + SendDbgCommand(DID_RESUME_EMU); - m_status = Running; - - CheckStatus(); + for (auto& t : GetCPU().GetAllThreads()) + { + t->Awake(); // untrigger status check and signal + } SendDbgCommand(DID_RESUMED_EMU); - - GetCallbackManager().RunPauseCallbacks(false); } extern std::map g_armv7_dump; void Emulator::Stop() { - if(IsStopped()) return; + LOG_NOTICE(GENERAL, "Stopping emulator..."); + + if (sync_lock_test_and_set(&m_status, Stopped) == Stopped) + { + return; + } SendDbgCommand(DID_STOP_EMU); - m_status = Stopped; - { - auto threads = GetCPU().GetThreads(); + LV2_LOCK; - for (auto& t : threads) + // notify all threads + for (auto& t : GetCPU().GetAllThreads()) { - t->AddEvent(CPU_EVENT_STOP); + std::lock_guard lock(t->mutex); + + t->Sleep(); // trigger status check + + t->cv.notify_one(); // signal } } @@ -372,7 +370,7 @@ void Emulator::Stop() std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - LOG_NOTICE(HLE, "All threads stopped..."); + LOG_NOTICE(GENERAL, "All threads stopped..."); finalize_psv_modules(); clear_all_psv_objects(); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 3617b42b61..308790b69d 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -2,7 +2,7 @@ #include "Loader/Loader.h" -enum Status +enum Status : u32 { Running, Paused, @@ -26,38 +26,20 @@ struct VFS; struct EmuInfo { private: - u32 tls_addr; - u32 tls_filesz; - u32 tls_memsz; + friend class Emulator; - sys_process_param_info proc_param; + u32 m_tls_addr = 0; + u32 m_tls_filesz = 0; + u32 m_tls_memsz = 0; + u32 m_sdk_version = 0x360001; + u32 m_malloc_pagesize = 0x100000; + u32 m_primary_stacksize = 0x100000; + s32 m_primary_prio = 0x50; public: - EmuInfo() { Reset(); } - - sys_process_param_info& GetProcParam() { return proc_param; } - - void Reset() + EmuInfo() { - SetTLSData(0, 0, 0); - memset(&proc_param, 0, sizeof(sys_process_param_info)); - - proc_param.malloc_pagesize = be_t::make(0x100000); - proc_param.sdk_version = be_t::make(0x360001); - proc_param.primary_stacksize = be_t::make(0x100000); - proc_param.primary_prio = be_t::make(0x50); } - - void SetTLSData(u32 addr, u32 filesz, u32 memsz) - { - tls_addr = addr; - tls_filesz = filesz; - tls_memsz = memsz; - } - - u32 GetTLSAddr() const { return tls_addr; } - u32 GetTLSFilesz() const { return tls_filesz; } - u32 GetTLSMemsz() const { return tls_memsz; } }; class Emulator @@ -69,9 +51,12 @@ class Emulator Interpreter, }; - volatile uint m_status; + volatile u32 m_status; uint m_mode; + std::atomic m_pause_start_time; // set when paused + std::atomic m_pause_amend_time; // increased when resumed + u32 m_rsx_callback; u32 m_cpu_thr_stop; @@ -80,17 +65,17 @@ class Emulator std::mutex m_core_mutex; - CPUThreadManager* m_thread_manager; - PadManager* m_pad_manager; - KeyboardManager* m_keyboard_manager; - MouseManager* m_mouse_manager; - ID_manager* m_id_manager; - GSManager* m_gs_manager; - AudioManager* m_audio_manager; - CallbackManager* m_callback_manager; - EventManager* m_event_manager; - ModuleManager* m_module_manager; - VFS* m_vfs; + std::unique_ptr m_thread_manager; + std::unique_ptr m_pad_manager; + std::unique_ptr m_keyboard_manager; + std::unique_ptr m_mouse_manager; + std::unique_ptr m_id_manager; + std::unique_ptr m_gs_manager; + std::unique_ptr m_audio_manager; + std::unique_ptr m_callback_manager; + std::unique_ptr m_event_manager; + std::unique_ptr m_module_manager; + std::unique_ptr m_vfs; EmuInfo m_info; loader::loader m_loader; @@ -135,8 +120,12 @@ public: m_emu_path = path; } - std::mutex& GetCoreMutex() { return m_core_mutex; } + u64 GetPauseTime() + { + return m_pause_amend_time; + } + std::mutex& GetCoreMutex() { return m_core_mutex; } CPUThreadManager& GetCPU() { return *m_thread_manager; } PadManager& GetPadManager() { return *m_pad_manager; } KeyboardManager& GetKeyboardManager() { return *m_keyboard_manager; } @@ -151,9 +140,25 @@ public: EventManager& GetEventManager() { return *m_event_manager; } ModuleManager& GetModuleManager() { return *m_module_manager; } + void ResetInfo() + { + m_info.~EmuInfo(); + new (&m_info) EmuInfo(); + } + void SetTLSData(u32 addr, u32 filesz, u32 memsz) { - m_info.SetTLSData(addr, filesz, memsz); + m_info.m_tls_addr = addr; + m_info.m_tls_filesz = filesz; + m_info.m_tls_memsz = memsz; + } + + void SetParams(u32 sdk_ver, u32 malloc_pagesz, u32 stacksz, s32 prio) + { + m_info.m_sdk_version = sdk_ver; + m_info.m_malloc_pagesize = malloc_pagesz; + m_info.m_primary_stacksize = stacksz; + m_info.m_primary_prio = prio; } void SetRSXCallback(u32 addr) @@ -166,19 +171,18 @@ public: m_cpu_thr_stop = addr; } - EmuInfo& GetInfo() { return m_info; } + u32 GetTLSAddr() const { return m_info.m_tls_addr; } + u32 GetTLSFilesz() const { return m_info.m_tls_filesz; } + u32 GetTLSMemsz() const { return m_info.m_tls_memsz; } - u32 GetTLSAddr() const { return m_info.GetTLSAddr(); } - u32 GetTLSFilesz() const { return m_info.GetTLSFilesz(); } - u32 GetTLSMemsz() const { return m_info.GetTLSMemsz(); } - - u32 GetMallocPageSize() { return m_info.GetProcParam().malloc_pagesize; } - u32 GetSDKVersion() { return m_info.GetProcParam().sdk_version; } + u32 GetMallocPageSize() { return m_info.m_malloc_pagesize; } + u32 GetSDKVersion() { return m_info.m_sdk_version; } + u32 GetPrimaryStackSize() { return m_info.m_primary_stacksize; } + s32 GetPrimaryPrio() { return m_info.m_primary_prio; } u32 GetRSXCallback() const { return m_rsx_callback; } u32 GetCPUThreadStop() const { return m_cpu_thr_stop; } - void CheckStatus(); bool BootGame(const std::string& path, bool direct = false); void Load(); @@ -199,7 +203,9 @@ public: using lv2_lock_type = std::unique_lock; #define LV2_LOCK lv2_lock_type lv2_lock(Emu.GetCoreMutex()) -#define CHECK_LV2_LOCK(x) assert((x).owns_lock() && (x).mutex() == &Emu.GetCoreMutex()) +#define LV2_DEFER_LOCK lv2_lock_type lv2_lock +#define CHECK_LV2_LOCK(x) if (!(x).owns_lock() || (x).mutex() != &Emu.GetCoreMutex()) throw EXCEPTION("Invalid LV2_LOCK (locked=%d)", (x).owns_lock()) +#define CHECK_EMU_STATUS if (Emu.IsStopped()) throw EXCEPTION("Aborted (emulation stopped)") extern Emulator Emu; diff --git a/rpcs3/Gui/ConLogFrame.cpp b/rpcs3/Gui/ConLogFrame.cpp index 73260864a6..a7e5a42fcb 100644 --- a/rpcs3/Gui/ConLogFrame.cpp +++ b/rpcs3/Gui/ConLogFrame.cpp @@ -76,16 +76,16 @@ struct wxWriter : Log::LogListener { switch (msg.mServerity) { - case Log::LogSeverityNotice: + case Log::Severity::Notice: llogcon->SetDefaultStyle(m_color_white); break; - case Log::LogSeverityWarning: + case Log::Severity::Warning: llogcon->SetDefaultStyle(m_color_yellow); break; - case Log::LogSeverityError: + case Log::Severity::Error: llogcon->SetDefaultStyle(m_color_red); break; - case Log::LogSeveritySuccess: + case Log::Severity::Success: llogcon->SetDefaultStyle(m_color_green); break; default: diff --git a/rpcs3/Gui/Debugger.cpp b/rpcs3/Gui/Debugger.cpp index 66f85de571..3d1bd7c6a4 100644 --- a/rpcs3/Gui/Debugger.cpp +++ b/rpcs3/Gui/Debugger.cpp @@ -93,10 +93,6 @@ public: case DID_RESUME_EMU: m_btn_run->SetLabel("Pause"); break; - - case DID_EXIT_THR_SYSCALL: - Emu.GetCPU().RemoveThread(((CPUThread*)event.GetClientData())->GetId()); - break; } UpdateUI(); diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index 432f88e43c..899b2de32d 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -1,4 +1,5 @@ #include "stdafx_gui.h" +#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "GLGSFrame.h" diff --git a/rpcs3/Gui/InstructionEditor.h b/rpcs3/Gui/InstructionEditor.h index 75ee526645..e14512dcf3 100644 --- a/rpcs3/Gui/InstructionEditor.h +++ b/rpcs3/Gui/InstructionEditor.h @@ -73,7 +73,7 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUTh s_panel_margin_x->AddSpacer(12); this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview)); - t2_instr->SetValue(wxString::Format("%08x", vm::read32(CPU->offset + pc))); + t2_instr->SetValue(wxString::Format("%08x", vm::ps3::read32(CPU->GetOffset() + pc).value())); this->SetSizerAndFit(s_panel_margin_x); @@ -83,7 +83,7 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUTh if (!t2_instr->GetValue().ToULong(&opcode, 16)) wxMessageBox("This instruction could not be parsed.\nNo changes were made.","Error"); else - vm::write32(CPU->offset + pc, (u32)opcode); + vm::ps3::write32(CPU->GetOffset() + pc, (u32)opcode); } } diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index 3706141606..6b50c6ab7d 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -108,9 +108,8 @@ void InterpreterDisAsmFrame::UpdateUnitList() { m_choice_units->Freeze(); m_choice_units->Clear(); - auto thrs = Emu.GetCPU().GetThreads(); - for (auto& t : thrs) + for (auto& t : Emu.GetCPU().GetAllThreads()) { m_choice_units->Append(t->GetFName(), t.get()); } @@ -248,10 +247,10 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr) } else { - disasm->offset = vm::get_ptr(CPU->offset); + disasm->offset = vm::get_ptr(CPU->GetOffset()); for(uint i=0, count = 4; ioffset + PC, 4)) + if(!vm::check_addr(CPU->GetOffset() + PC, 4)) { m_list->SetItem(i, 0, wxString(IsBreakPoint(PC) ? ">>> " : " ") + wxString::Format("[%08llx] illegal address", PC)); count = 4; @@ -259,7 +258,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr) } disasm->dump_pc = PC; - count = decoder->DecodeMemory(CPU->offset + PC); + count = decoder->DecodeMemory(CPU->GetOffset() + PC); if(IsBreakPoint(PC)) { @@ -272,7 +271,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr) wxColour colour; - if((!CPU->IsRunning() || !Emu.IsRunning()) && PC == CPU->PC) + if(CPU->IsPaused() && PC == CPU->GetPC()) { colour = wxColour("Green"); } @@ -456,11 +455,11 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event)) diag->SetSizerAndFit( s_panel ); - if(CPU) p_pc->SetValue(wxString::Format("%x", CPU->PC)); + if(CPU) p_pc->SetValue(wxString::Format("%x", CPU->GetPC())); if(diag->ShowModal() == wxID_OK) { - unsigned long pc = CPU ? CPU->PC : 0x0; + unsigned long pc = CPU ? CPU->GetPC() : 0x0; p_pc->GetValue().ToULong(&pc, 16); Emu.GetMarkedPoints().push_back(pc); remove_markedPC.push_back(Emu.GetMarkedPoints().size()-1); @@ -470,10 +469,9 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event)) void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event)) { - if(CPU) ShowAddr(CentrePc(CPU->PC)); + if(CPU) ShowAddr(CentrePc(CPU->GetPC())); } -extern bool dump_enable; void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event)) { if(!CPU) return; @@ -496,7 +494,7 @@ void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event)) void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event)) { - if(CPU) CPU->ExecOnce(); + if(CPU) CPU->Step(); } void InterpreterDisAsmFrame::InstrKey(wxListEvent& event) diff --git a/rpcs3/Gui/KernelExplorer.cpp b/rpcs3/Gui/KernelExplorer.cpp index c7bee4f0f7..6351713025 100644 --- a/rpcs3/Gui/KernelExplorer.cpp +++ b/rpcs3/Gui/KernelExplorer.cpp @@ -4,8 +4,9 @@ #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/CPU/CPUThreadManager.h" -#include "Emu/CPU/CPUThread.h" +#include "Emu/Cell/PPUThread.h" +#include "Emu/Cell/SPUThread.h" +#include "Emu/Cell/RawSPUThread.h" #include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_lwmutex.h" #include "Emu/SysCalls/lv2/sys_lwcond.h" @@ -77,11 +78,12 @@ void KernelExplorer::Update() // TODO: FileSystem // Semaphores - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_SEMAPHORE_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_SEMAPHORE_OBJECT)) { sprintf(name, "Semaphores (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_SEMAPHORE_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_SEMAPHORE_OBJECT)) { const auto sem = Emu.GetIdManager().get(id); sprintf(name, "Semaphore: ID = 0x%x '%s', Count = %d, Max Count = %d, Waiters = %d", id, &name64(sem->name), sem->value.load(), sem->max, sem->waiters.load()); @@ -90,11 +92,12 @@ void KernelExplorer::Update() } // Mutexes - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_MUTEX_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_MUTEX_OBJECT)) { sprintf(name, "Mutexes (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_MUTEX_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_MUTEX_OBJECT)) { const auto mutex = Emu.GetIdManager().get(id); sprintf(name, "Mutex: ID = 0x%x '%s'", id, &name64(mutex->name)); @@ -103,11 +106,12 @@ void KernelExplorer::Update() } // Light Weight Mutexes - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_LWMUTEX_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_LWMUTEX_OBJECT)) { sprintf(name, "Lightweight Mutexes (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_LWMUTEX_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_LWMUTEX_OBJECT)) { const auto lwm = Emu.GetIdManager().get(id); sprintf(name, "Lightweight Mutex: ID = 0x%x '%s'", id, &name64(lwm->name)); @@ -116,11 +120,12 @@ void KernelExplorer::Update() } // Condition Variables - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_COND_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_COND_OBJECT)) { sprintf(name, "Condition Variables (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_COND_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_COND_OBJECT)) { const auto cond = Emu.GetIdManager().get(id); sprintf(name, "Condition Variable: ID = 0x%x '%s'", id, &name64(cond->name)); @@ -129,11 +134,12 @@ void KernelExplorer::Update() } // Light Weight Condition Variables - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_LWCOND_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_LWCOND_OBJECT)) { sprintf(name, "Lightweight Condition Variables (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_LWCOND_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_LWCOND_OBJECT)) { const auto lwc = Emu.GetIdManager().get(id); sprintf(name, "Lightweight Condition Variable: ID = 0x%x '%s'", id, &name64(lwc->name)); @@ -142,11 +148,12 @@ void KernelExplorer::Update() } // Event Queues - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_EVENT_QUEUE_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_EVENT_QUEUE_OBJECT)) { sprintf(name, "Event Queues (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_EVENT_QUEUE_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_EVENT_QUEUE_OBJECT)) { const auto queue = Emu.GetIdManager().get(id); sprintf(name, "Event Queue: ID = 0x%x '%s', Key = %#llx", id, &name64(queue->name), queue->key); @@ -155,11 +162,12 @@ void KernelExplorer::Update() } // Event Ports - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_EVENT_PORT_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_EVENT_PORT_OBJECT)) { sprintf(name, "Event Ports (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto id : Emu.GetIdManager().get_IDs_by_type(SYS_EVENT_PORT_OBJECT)) + + for (const auto id : Emu.GetIdManager().get_IDs(SYS_EVENT_PORT_OBJECT)) { const auto port = Emu.GetIdManager().get(id); sprintf(name, "Event Port: ID = 0x%x, Name = %#llx", id, port->name); @@ -168,13 +176,14 @@ void KernelExplorer::Update() } // Modules - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_PRX_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_PRX_OBJECT)) { sprintf(name, "Modules (%d)", count); const auto& node = m_tree->AppendItem(root, name); //sprintf(name, "Segment List (%l)", 2 * objects.size()); // TODO: Assuming 2 segments per PRX file is not good //m_tree->AppendItem(node, name); - for (const auto& id : Emu.GetIdManager().get_IDs_by_type(SYS_PRX_OBJECT)) + + for (const auto& id : Emu.GetIdManager().get_IDs(SYS_PRX_OBJECT)) { sprintf(name, "PRX: ID = 0x%x", id); m_tree->AppendItem(node, name); @@ -182,11 +191,12 @@ void KernelExplorer::Update() } // Memory Containers - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_MEM_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_MEM_OBJECT)) { sprintf(name, "Memory Containers (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().get_IDs_by_type(SYS_MEM_OBJECT)) + + for (const auto& id : Emu.GetIdManager().get_IDs(SYS_MEM_OBJECT)) { sprintf(name, "Memory Container: ID = 0x%x", id); m_tree->AppendItem(node, name); @@ -194,82 +204,59 @@ void KernelExplorer::Update() } // Event Flags - if (u32 count = Emu.GetIdManager().get_count_by_type(SYS_EVENT_FLAG_OBJECT)) + if (u32 count = Emu.GetIdManager().get_count(SYS_EVENT_FLAG_OBJECT)) { sprintf(name, "Event Flags (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().get_IDs_by_type(SYS_EVENT_FLAG_OBJECT)) + + for (const auto& id : Emu.GetIdManager().get_IDs(SYS_EVENT_FLAG_OBJECT)) { sprintf(name, "Event Flag: ID = 0x%x", id); m_tree->AppendItem(node, name); } } - // PPU / SPU / RawSPU threads + // PPU Threads + if (u32 count = Emu.GetIdManager().get_count()) { - // TODO: add mutexes owners + sprintf(name, "PPU Threads (%d)", count); + const auto& node = m_tree->AppendItem(root, name); - //const auto& objects = Emu.GetCPU().GetThreads(); - u32 ppu_threads_count = 0; - u32 spu_threads_count = 0; - u32 raw_spu_threads_count = 0; - //for (const auto& thread : objects) - //{ - // if (thread->GetType() == CPU_THREAD_PPU) - // ppu_threads_count++; + for (const auto& thread : Emu.GetIdManager().get_all()) + { + sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString()); + m_tree->AppendItem(node, name); + } + } - // if (thread->GetType() == CPU_THREAD_SPU) - // spu_threads_count++; + if (u32 count = Emu.GetIdManager().get_count()) + { + sprintf(name, "SPU Threads (%d)", count); + const auto& node = m_tree->AppendItem(root, name); - // if (thread->GetType() == CPU_THREAD_RAW_SPU) - // raw_spu_threads_count++; - //} + for (const auto& thread : Emu.GetIdManager().get_all()) + { + if (thread->GetType() == CPU_THREAD_SPU) + { + sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString()); + m_tree->AppendItem(node, name); + } + } + } - //if (ppu_threads_count) - //{ - // sprintf(name, "PPU Threads (%d)", ppu_threads_count); - // const auto& node = m_tree->AppendItem(root, name); - - // for (const auto& thread : objects) - // { - // if (thread->GetType() == CPU_THREAD_PPU) - // { - // sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str()); - // m_tree->AppendItem(node, name); - // } - // } - //} - - //if (spu_threads_count) - //{ - // sprintf(name, "SPU Threads (%d)", spu_threads_count); - // const auto& node = m_tree->AppendItem(root, name); - - // for (const auto& thread : objects) - // { - // if (thread->GetType() == CPU_THREAD_SPU) - // { - // sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str()); - // m_tree->AppendItem(node, name); - // } - // } - //} - - //if (raw_spu_threads_count) - //{ - // sprintf(name, "RawSPU Threads (%d)", raw_spu_threads_count); - // const auto& node = m_tree->AppendItem(root, name); - - // for (const auto& thread : objects) - // { - // if (thread->GetType() == CPU_THREAD_RAW_SPU) - // { - // sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString().c_str()); - // m_tree->AppendItem(node, name); - // } - // } - //} + if (u32 count = Emu.GetIdManager().get_count()) + { + sprintf(name, "RawSPU Threads (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto& thread : Emu.GetIdManager().get_all()) + { + if (thread->GetType() == CPU_THREAD_RAW_SPU) + { + sprintf(name, "Thread: ID = 0x%08x '%s', - %s", thread->GetId(), thread->GetName().c_str(), thread->ThreadStatusToString()); + m_tree->AppendItem(node, name); + } + } } m_tree->Expand(root); diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 4fc8cfee4d..79594e8c8f 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -120,7 +120,9 @@ MainFrame::MainFrame() menu_help->Append(id_help_about, "&About..."); SetMenuBar(menubar); +#ifdef _WIN32 SetIcon(wxICON(frame_icon)); +#endif // Panels m_log_frame = new LogFrame(this); @@ -424,7 +426,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) wxCheckBox* chbox_gs_3dmonitor = new wxCheckBox(p_graphics, wxID_ANY, "3D Monitor"); wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file"); wxCheckBox* chbox_audio_conv = new wxCheckBox(p_audio, wxID_ANY, "Convert to 16 bit"); - wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log all SysCalls"); + wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log everything"); wxCheckBox* chbox_rsx_logging = new wxCheckBox(p_hle, wxID_ANY, "RSX Logging"); wxCheckBox* chbox_hle_hook_stfunc = new wxCheckBox(p_hle, wxID_ANY, "Hook static functions"); wxCheckBox* chbox_hle_savetty = new wxCheckBox(p_hle, wxID_ANY, "Save TTY output to file"); diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index aa1487a187..7a34aa581c 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -8,6 +8,7 @@ #include "RSXDebugger.h" #include "Emu/RSX/sysutil_video.h" #include "Emu/RSX/GSManager.h" +#include "Emu/RSX/GSRender.h" //#include "Emu/RSX/GCM.h" #include "MemoryViewer.h" @@ -332,7 +333,7 @@ void RSXDebugger::GoToGet(wxCommandEvent& event) if (!RSXReady()) return; auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().m_ctrlAddress); u32 realAddr; - if (Memory.RSXIOMem.getRealAddr(ctrl->get.read_relaxed(), realAddr)) { + if (Memory.RSXIOMem.getRealAddr(ctrl->get.load(), realAddr)) { m_addr = realAddr; t_addr->SetValue(wxString::Format("%08x", m_addr)); UpdateInformation(); @@ -346,7 +347,7 @@ void RSXDebugger::GoToPut(wxCommandEvent& event) if (!RSXReady()) return; auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().m_ctrlAddress); u32 realAddr; - if (Memory.RSXIOMem.getRealAddr(ctrl->put.read_relaxed(), realAddr)) { + if (Memory.RSXIOMem.getRealAddr(ctrl->put.load(), realAddr)) { m_addr = realAddr; t_addr->SetValue(wxString::Format("%08x", m_addr)); UpdateInformation(); diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 6ef662b641..4c916c4c51 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -36,23 +36,23 @@ namespace loader return bad_file; } - if (m_ehdr.data_le.e_phnum && (m_ehdr.is_le() ? m_ehdr.data_le.e_phentsize : m_ehdr.data_be.e_phentsize) != sizeof(phdr)) + if (m_ehdr.data_le.e_phnum && (m_ehdr.is_le() ? m_ehdr.data_le.e_phentsize != sizeof(phdr) : m_ehdr.data_be.e_phentsize != sizeof(phdr))) { return broken_file; } - if (m_ehdr.data_le.e_shnum && (m_ehdr.is_le() ? m_ehdr.data_le.e_shentsize : m_ehdr.data_be.e_shentsize) != sizeof(shdr)) + if (m_ehdr.data_le.e_shnum && (m_ehdr.is_le() ? m_ehdr.data_le.e_shentsize != sizeof(shdr) : m_ehdr.data_be.e_shentsize != sizeof(shdr))) { return broken_file; } - LOG_WARNING(LOADER, "m_ehdr.e_type = 0x%x", (u16)(m_ehdr.is_le() ? m_ehdr.data_le.e_type : m_ehdr.data_be.e_type)); + LOG_WARNING(LOADER, "m_ehdr.e_type = 0x%x", m_ehdr.is_le() ? m_ehdr.data_le.e_type : m_ehdr.data_be.e_type.value()); if (m_ehdr.data_le.e_phnum) { - m_phdrs.resize(m_ehdr.is_le() ? m_ehdr.data_le.e_phnum : m_ehdr.data_be.e_phnum); - m_stream->Seek(handler::get_stream_offset() + (m_ehdr.is_le() ? m_ehdr.data_le.e_phoff : m_ehdr.data_be.e_phoff)); - size_t size = (m_ehdr.is_le() ? m_ehdr.data_le.e_phnum : m_ehdr.data_be.e_phnum) * sizeof(phdr); + m_phdrs.resize(m_ehdr.is_le() ? m_ehdr.data_le.e_phnum : m_ehdr.data_be.e_phnum.value()); + m_stream->Seek(handler::get_stream_offset() + (m_ehdr.is_le() ? m_ehdr.data_le.e_phoff : m_ehdr.data_be.e_phoff.value())); + size_t size = (m_ehdr.is_le() ? m_ehdr.data_le.e_phnum : m_ehdr.data_be.e_phnum.value()) * sizeof(phdr); if (m_stream->Read(m_phdrs.data(), size) != size) return broken_file; @@ -60,9 +60,9 @@ namespace loader if (m_ehdr.data_le.e_shnum) { - m_shdrs.resize(m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum); - m_stream->Seek(handler::get_stream_offset() + (m_ehdr.is_le() ? m_ehdr.data_le.e_shoff : m_ehdr.data_be.e_shoff)); - size_t size = (m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum) * sizeof(shdr); + m_shdrs.resize(m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum.value()); + m_stream->Seek(handler::get_stream_offset() + (m_ehdr.is_le() ? m_ehdr.data_le.e_shoff : m_ehdr.data_be.e_shoff.value())); + size_t size = (m_ehdr.is_le() ? m_ehdr.data_le.e_shnum : m_ehdr.data_be.e_shnum.value()) * sizeof(shdr); if (m_stream->Read(m_shdrs.data(), size) != size) return broken_file; @@ -74,7 +74,7 @@ namespace loader handler::error_code elf32::load() { Elf_Machine machine; - switch (machine = (Elf_Machine)(u16)(m_ehdr.is_le() ? m_ehdr.data_le.e_machine : m_ehdr.data_be.e_machine)) + switch (machine = (Elf_Machine)(u16)(m_ehdr.is_le() ? m_ehdr.data_le.e_machine : m_ehdr.data_be.e_machine.value())) { case MACHINE_MIPS: vm::psp::init(); break; case MACHINE_ARM: vm::psv::init(); break; @@ -99,16 +99,16 @@ namespace loader u32 size; // 0x0000001c u32 unk1; // 0x00000000 - vm::psv::ptr sceLibcHeapSize; - vm::psv::ptr sceLibcHeapSizeDefault; - vm::psv::ptr sceLibcHeapExtendedAlloc; - vm::psv::ptr sceLibcHeapDelayedAlloc; + vm::lptr sceLibcHeapSize; + vm::lptr sceLibcHeapSizeDefault; + vm::lptr sceLibcHeapExtendedAlloc; + vm::lptr sceLibcHeapDelayedAlloc; u32 unk2; u32 unk3; - vm::psv::ptr __sce_libcmallocreplace; - vm::psv::ptr __sce_libcnewreplace; + vm::lptr __sce_libcmallocreplace; + vm::lptr __sce_libcnewreplace; }; struct psv_process_param_t @@ -118,20 +118,20 @@ namespace loader u32 unk2; // 0x00000005 u32 unk3; - vm::psv::ptr sceUserMainThreadName; - vm::psv::ptr sceUserMainThreadPriority; - vm::psv::ptr sceUserMainThreadStackSize; - vm::psv::ptr sceUserMainThreadAttribute; - vm::psv::ptr sceProcessName; - vm::psv::ptr sce_process_preload_disabled; - vm::psv::ptr sceUserMainThreadCpuAffinityMask; + vm::lcptr sceUserMainThreadName; + vm::lptr sceUserMainThreadPriority; + vm::lptr sceUserMainThreadStackSize; + vm::lptr sceUserMainThreadAttribute; + vm::lcptr sceProcessName; + vm::lptr sce_process_preload_disabled; + vm::lptr sceUserMainThreadCpuAffinityMask; - vm::psv::ptr __sce_libcparam; + vm::lptr __sce_libcparam; }; initialize_psv_modules(); - auto armv7_thr_stop_data = vm::psv::ptr::make(Memory.PSV.RAM.AllocAlign(3 * 4)); + auto armv7_thr_stop_data = vm::ptr::make(Memory.PSV.RAM.AllocAlign(3 * 4)); armv7_thr_stop_data[0] = 0xf870; // HACK instruction (Thumb) armv7_thr_stop_data[1] = SFI_HLE_RETURN; Emu.SetCPUThreadStop(armv7_thr_stop_data.addr()); @@ -143,12 +143,12 @@ namespace loader u32 vnid_addr = 0; std::unordered_map vnid_list; - vm::psv::ptr proc_param = vm::null; + vm::ptr proc_param = vm::null; for (auto& shdr : m_shdrs) { // get secton name - //auto name = vm::psv::ptr::make(sname_base + shdr.data_le.sh_name); + //auto name = vm::cptr::make(sname_base + shdr.data_le.sh_name); m_stream->Seek(handler::get_stream_offset() + m_shdrs[m_ehdr.data_le.e_shstrndx].data_le.sh_offset + shdr.data_le.sh_name); std::string name; @@ -169,8 +169,8 @@ namespace loader { LOG_NOTICE(LOADER, ".sceExport.rodata analysis..."); - auto enid = vm::psv::ptr::make(shdr.data_le.sh_addr); - auto edata = vm::psv::ptr::make(enid.addr() + shdr.data_le.sh_size / 2); + auto enid = vm::cptr::make(shdr.data_le.sh_addr); + auto edata = vm::cptr::make(enid.addr() + shdr.data_le.sh_size / 2); for (u32 j = 0; j < shdr.data_le.sh_size / 8; j++) { @@ -217,8 +217,8 @@ namespace loader continue; } - auto fnid = vm::psv::ptr::make(fnid_addr); - auto fstub = vm::psv::ptr::make(shdr.data_le.sh_addr); + auto fnid = vm::cptr::make(fnid_addr); + auto fstub = vm::cptr::make(shdr.data_le.sh_addr); for (u32 j = 0; j < shdr.data_le.sh_size / 4; j++) { @@ -270,8 +270,8 @@ namespace loader continue; } - auto vnid = vm::psv::ptr::make(vnid_addr); - auto vstub = vm::psv::ptr::make(shdr.data_le.sh_addr); + auto vnid = vm::cptr::make(vnid_addr); + auto vstub = vm::cptr::make(shdr.data_le.sh_addr); for (u32 j = 0; j < shdr.data_le.sh_size / 4; j++) { @@ -299,7 +299,7 @@ namespace loader u32 data = 0; - for (auto code = vm::psv::ptr::make(shdr.data_le.sh_addr); code.addr() < shdr.data_le.sh_addr + shdr.data_le.sh_size; code++) + for (auto code = vm::cptr::make(shdr.data_le.sh_addr); code.addr() < shdr.data_le.sh_addr + shdr.data_le.sh_size; code++) { switch (*code) { @@ -401,13 +401,13 @@ namespace loader armv7_decoder_initialize(code_start, code_end); const std::string& thread_name = proc_param->sceUserMainThreadName ? proc_param->sceUserMainThreadName.get_ptr() : "main_thread"; - const u32 stack_size = proc_param->sceUserMainThreadStackSize ? *proc_param->sceUserMainThreadStackSize : 256 * 1024; - const u32 priority = proc_param->sceUserMainThreadPriority ? *proc_param->sceUserMainThreadPriority : 160; + const u32 stack_size = proc_param->sceUserMainThreadStackSize ? proc_param->sceUserMainThreadStackSize->value() : 256 * 1024; + const u32 priority = proc_param->sceUserMainThreadPriority ? proc_param->sceUserMainThreadPriority->value() : 160; armv7_thread(entry, thread_name, stack_size, priority).args({ Emu.GetPath(), "-emu" }).run(); break; } - case MACHINE_SPU: spu_thread(m_ehdr.is_le() ? m_ehdr.data_le.e_entry : m_ehdr.data_be.e_entry, "main_thread").args({ Emu.GetPath()/*, "-emu"*/ }).run(); break; + case MACHINE_SPU: spu_thread(m_ehdr.is_le() ? m_ehdr.data_le.e_entry : m_ehdr.data_be.e_entry.value(), "main_thread").args({ Emu.GetPath()/*, "-emu"*/ }).run(); break; } return ok; @@ -415,16 +415,16 @@ namespace loader handler::error_code elf32::load_data(u32 offset, bool skip_writeable) { - Elf_Machine machine = (Elf_Machine)(u16)(m_ehdr.is_le() ? m_ehdr.data_le.e_machine : m_ehdr.data_be.e_machine); + Elf_Machine machine = (Elf_Machine)(u16)(m_ehdr.is_le() ? m_ehdr.data_le.e_machine : m_ehdr.data_be.e_machine.value()); for (auto &phdr : m_phdrs) { - u32 memsz = m_ehdr.is_le() ? phdr.data_le.p_memsz : phdr.data_be.p_memsz; - u32 filesz = m_ehdr.is_le() ? phdr.data_le.p_filesz : phdr.data_be.p_filesz; - u32 vaddr = offset + (m_ehdr.is_le() ? phdr.data_le.p_vaddr : phdr.data_be.p_vaddr); - u32 offset = m_ehdr.is_le() ? phdr.data_le.p_offset : phdr.data_be.p_offset; + u32 memsz = m_ehdr.is_le() ? phdr.data_le.p_memsz : phdr.data_be.p_memsz.value(); + u32 filesz = m_ehdr.is_le() ? phdr.data_le.p_filesz : phdr.data_be.p_filesz.value(); + u32 vaddr = offset + (m_ehdr.is_le() ? phdr.data_le.p_vaddr : phdr.data_be.p_vaddr.value()); + u32 offset = m_ehdr.is_le() ? phdr.data_le.p_offset : phdr.data_be.p_offset.value(); - switch (m_ehdr.is_le() ? phdr.data_le.p_type : phdr.data_be.p_type) + switch (m_ehdr.is_le() ? phdr.data_le.p_type : phdr.data_be.p_type.value()) { case 0x00000001: //LOAD if (phdr.data_le.p_memsz) diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 0a25330f96..ab31f086e5 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -6,10 +6,10 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/ModuleManager.h" #include "Emu/SysCalls/lv2/sys_prx.h" #include "Emu/Cell/PPUInstrTable.h" -#include "Emu/CPU/CPUThreadManager.h" #include "ELF64.h" #include "Ini.h" @@ -116,7 +116,7 @@ namespace loader return loading_error; } - segment.initial_addr.set(phdr.p_vaddr.addr()); + segment.initial_addr = phdr.p_vaddr; LOG_WARNING(LOADER, "segment addr=0x%x, initial addr = 0x%x", segment.begin.addr(), segment.initial_addr.addr()); if (phdr.p_filesz) @@ -364,7 +364,7 @@ namespace loader { for (auto &e : m.second.exports) { - auto code = vm::ptr::make(vm::check_addr(e.second, 8) ? vm::read32(e.second) : 0); + auto code = vm::cptr::make(vm::check_addr(e.second, 8) ? vm::read32(e.second).value() : 0); bool is_empty = !code || (code[0] == 0x38600000 && code[1] == BLR()); @@ -416,7 +416,7 @@ namespace loader if (!module) { - LOG_WARNING(LOADER, "Unknown module '%s' in '%s' library", m.first.c_str(), info.name.c_str()); + LOG_ERROR(LOADER, "Unknown module '%s' in '%s' library", m.first.c_str(), info.name.c_str()); } for (auto& f : m.second.exports) @@ -463,7 +463,7 @@ namespace loader if (!func) { - LOG_ERROR(LOADER, "Unimplemented function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); + LOG_ERROR(LOADER, "Unknown function '%s' (0x%x)", SysCalls::GetFuncName(nid), addr); index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); } @@ -606,7 +606,7 @@ namespace loader { m_stream->Seek(handler::get_stream_offset() + phdr.p_offset); m_stream->Read(phdr.p_vaddr.get_ptr(), phdr.p_filesz); - hook_ppu_funcs(vm::ptr::make(phdr.p_vaddr.addr()), phdr.p_filesz / 4); + hook_ppu_funcs(vm::static_ptr_cast>(phdr.p_vaddr), phdr.p_filesz / 4); } } break; @@ -622,29 +622,39 @@ namespace loader { if (phdr.p_filesz) { - const sys_process_param& proc_param = *(sys_process_param*)phdr.p_vaddr.get_ptr(); + struct process_param_t + { + be_t size; + be_t magic; + be_t version; + be_t sdk_version; + be_t primary_prio; + be_t primary_stacksize; + be_t malloc_pagesize; + be_t ppc_seg; + //be_t crash_dump_param_addr; + }; - if (proc_param.size < sizeof(sys_process_param)) + const auto& info = *(process_param_t*)phdr.p_vaddr.get_ptr(); + + if (info.size < sizeof(process_param_t)) { - LOG_WARNING(LOADER, "Bad process_param size! [0x%x : 0x%x]", proc_param.size, sizeof(sys_process_param)); + LOG_WARNING(LOADER, "Bad process_param size! [0x%x : 0x%x]", info.size, sizeof32(process_param_t)); } - if (proc_param.magic != 0x13bcc5f6) + if (info.magic != 0x13bcc5f6) { - LOG_ERROR(LOADER, "Bad process_param magic! [0x%x]", proc_param.magic); + LOG_ERROR(LOADER, "Bad process_param magic! [0x%x]", info.magic); } else { - sys_process_param_info& info = Emu.GetInfo().GetProcParam(); - /* LOG_NOTICE(LOADER, "*** sdk version: 0x%x", info.sdk_version); LOG_NOTICE(LOADER, "*** primary prio: %d", info.primary_prio); LOG_NOTICE(LOADER, "*** primary stacksize: 0x%x", info.primary_stacksize); LOG_NOTICE(LOADER, "*** malloc pagesize: 0x%x", info.malloc_pagesize); LOG_NOTICE(LOADER, "*** ppc seg: 0x%x", info.ppc_seg); //LOG_NOTICE(LOADER, "*** crash dump param addr: 0x%x", info.crash_dump_param_addr); - */ - info = proc_param.info; + Emu.SetParams(info.sdk_version, info.malloc_pagesize, info.primary_stacksize, info.primary_prio); } } break; @@ -670,7 +680,7 @@ namespace loader if (!module) { - LOG_WARNING(LOADER, "Unknown module '%s'", module_name.c_str()); + LOG_ERROR(LOADER, "Unknown module '%s'", module_name.c_str()); } for (u32 i = 0; i < stub->s_imports; ++i) @@ -684,7 +694,7 @@ namespace loader if (!func) { - LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetFuncName(nid), module_name, addr); + LOG_ERROR(LOADER, "Unknown function '%s' in '%s' module (0x%x)", SysCalls::GetFuncName(nid), module_name, addr); index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr)); } @@ -704,6 +714,10 @@ namespace loader } break; } + default: + { + LOG_ERROR(LOADER, "Unknown phdr type (0x%08x)", phdr.p_type); + } } } diff --git a/rpcs3/Loader/ELF64.h b/rpcs3/Loader/ELF64.h index 8580c5be69..bb0120ecd5 100644 --- a/rpcs3/Loader/ELF64.h +++ b/rpcs3/Loader/ELF64.h @@ -32,7 +32,7 @@ namespace loader be_t e_shnum; be_t e_shstrndx; - bool check() const { return e_magic.data() == se32(0x7F454C46); } + bool check() const { return e_magic == 0x7F454C46; } } m_ehdr; struct phdr @@ -40,8 +40,8 @@ namespace loader be_t p_type; be_t p_flags; be_t p_offset; - bptr p_vaddr; - bptr p_paddr; + _ptr_base> p_vaddr; + _ptr_base> p_paddr; be_t p_filesz; be_t p_memsz; be_t p_align; @@ -52,7 +52,7 @@ namespace loader be_t sh_name; be_t sh_type; be_t sh_flags; - bptr sh_addr; + _ptr_base> sh_addr; be_t sh_offset; be_t sh_size; be_t sh_link; @@ -120,10 +120,10 @@ namespace loader struct sprx_segment_info { - vm::ptr begin; + _ptr_base begin; u32 size; u32 size_file; - vm::ptr initial_addr; + _ptr_base initial_addr; std::vector modules; }; @@ -161,4 +161,4 @@ namespace loader std::string sprx_get_module_name() const { return m_sprx_module_info.name; } }; } -} \ No newline at end of file +} diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index 0cafa3554a..0b6834ccbd 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -48,57 +48,6 @@ const std::string Ehdr_MachineToString(const u16 machine); const std::string Phdr_FlagsToString(u32 flags); const std::string Phdr_TypeToString(const u32 type); -struct sys_process_param_info -{ - be_t sdk_version; - be_t primary_prio; - be_t primary_stacksize; - be_t malloc_pagesize; - be_t ppc_seg; - //be_t crash_dump_param_addr; -}; - -struct sys_process_param -{ - be_t size; - be_t magic; - be_t version; - sys_process_param_info info; -}; - -struct sys_stub -{ - u8 s_size; // = 0x2c - u8 s_unk0; - be_t s_version; // = 0x1 - be_t s_unk1; // = 0x9 // flags? - be_t s_imports; - be_t s_unk2; // = 0x0 - be_t s_unk3; // = 0x0 - vm::bptr s_modulename; - vm::bptr s_nid; - vm::bptr s_text; - be_t s_unk4; // = 0x0 - be_t s_unk5; // = 0x0 - be_t s_unk6; // = 0x0 - be_t s_unk7; // = 0x0 -}; - -struct sys_proc_prx_param -{ - be_t size; - be_t magic; - be_t version; - be_t pad0; - be_t libentstart; - be_t libentend; - vm::bptr libstubstart; - vm::bptr libstubend; - be_t ver; - be_t pad1; - be_t pad2; -}; - namespace loader { class handler diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp index d7ba52d755..76e343f24d 100644 --- a/rpcs3/Loader/TROPUSR.cpp +++ b/rpcs3/Loader/TROPUSR.cpp @@ -140,20 +140,8 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con default: trophy_grade = 0; } - TROPUSREntry4 entry4 = { - be_t::make(4), - be_t::make(sizeof(TROPUSREntry4) - 0x10), - be_t::make((u32)m_table4.size()), - be_t::make(0), - be_t::make(trophy_id), - be_t::make(trophy_grade), - be_t::make(0xFFFFFFFF) }; - TROPUSREntry6 entry6 = { - be_t::make(6), - be_t::make(sizeof(TROPUSREntry6) - 0x10), - be_t::make((u32)m_table6.size()), - be_t::make(0), - be_t::make(trophy_id) }; + TROPUSREntry4 entry4 = { 4, sizeof32(TROPUSREntry4) - 0x10, (u32)m_table4.size(), 0, trophy_id, trophy_grade, 0xFFFFFFFF }; + TROPUSREntry6 entry6 = { 6, sizeof32(TROPUSREntry6) - 0x10, (u32)m_table6.size(), 0, trophy_id }; m_table4.push_back(entry4); m_table6.push_back(entry6); @@ -161,19 +149,9 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con } u64 offset = sizeof(TROPUSRHeader) + 2 * sizeof(TROPUSRTableHeader); - TROPUSRTableHeader table4header = { - be_t::make(4), - be_t::make(sizeof(TROPUSREntry4) - 0x10), - be_t::make(1), - be_t::make((u32)m_table4.size()), - be_t::make(offset) }; + TROPUSRTableHeader table4header = { 4, sizeof32(TROPUSREntry4) - 0x10, 1, (u32)m_table4.size(), offset }; offset += m_table4.size() * sizeof(TROPUSREntry4); - TROPUSRTableHeader table6header = { - be_t::make(6), - be_t::make(sizeof(TROPUSREntry6) - 0x10), - be_t::make(1), - be_t::make((u32)m_table6.size()), - be_t::make(offset) }; + TROPUSRTableHeader table6header = { 6, sizeof32(TROPUSREntry6) - 0x10, 1, (u32)m_table6.size(), offset }; offset += m_table6.size() * sizeof(TROPUSREntry6); m_tableHeaders.clear(); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 970570fae7..04e6797157 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -41,6 +41,7 @@ + @@ -143,7 +144,6 @@ - @@ -174,7 +174,6 @@ - @@ -227,7 +226,6 @@ - @@ -278,6 +276,7 @@ + @@ -343,14 +342,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -379,7 +428,6 @@ - @@ -432,7 +480,6 @@ - @@ -448,6 +495,7 @@ + @@ -474,6 +522,8 @@ + + @@ -522,6 +572,7 @@ + @@ -728,4 +779,4 @@ - + \ No newline at end of file diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index aa8ddbdc0e..9c08d40ad2 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -353,9 +353,6 @@ Emu\CPU\Cell - - Emu\CPU\Cell - Emu\CPU\Cell @@ -434,9 +431,6 @@ Emu\SysCalls\currently_unused - - Emu\SysCalls\currently_unused - Emu\SysCalls\currently_unused @@ -575,9 +569,6 @@ Emu\GPU\RSX - - Emu\GPU\RSX - Emu\GPU\RSX @@ -878,6 +869,12 @@ Emu\GPU\RSX\GL + + Emu\SysCalls\lv2 + + + Emu\SysCalls\Modules + @@ -1162,9 +1159,6 @@ Emu\CPU\Cell - - Emu\CPU\Cell - Emu\CPU\Cell @@ -1366,9 +1360,6 @@ Emu\GPU\RSX - - Emu\GPU\RSX - Emu\GPU\RSX @@ -1573,5 +1564,167 @@ Emu\GPU\RSX\GL + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\CPU\ARMv7\Modules + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\Modules + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 506ba9740c..301113ea63 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -88,8 +88,11 @@ true wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;libOpenAL32.dll.a;asmjit.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) - false + true ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib;..\OpenAL\Win64 + 0x200000000 + true + false "$(SolutionDir)\Utilities\git-version-gen.cmd" @@ -115,8 +118,11 @@ true wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;libOpenAL32.dll.a;asmjit.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) - false + true ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib;..\OpenAL\Win64 + 0x200000000 + true + false "$(SolutionDir)\Utilities\git-version-gen.cmd" @@ -153,8 +159,11 @@ %(IgnoreSpecificDefaultLibraries) - false + true ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib;..\OpenAL\Win64 + 0x200000000 + true + false "$(SolutionDir)\Utilities\git-version-gen.cmd" diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 1b730b9109..c1bd53db80 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -13,13 +13,13 @@ #include "define_new_memleakdetect.h" #endif -// This header should be frontend-agnostic, so don't assume wx includes everything -#pragma warning( disable : 4800 ) +#pragma warning( disable : 4351 ) #include #include #include #include +#include #include #include #include @@ -40,43 +40,99 @@ #include "Utilities/GNU.h" -typedef unsigned int uint; +using uint = unsigned int; -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; +using u8 = std::uint8_t; +using u16 = std::uint16_t; +using u32 = std::uint32_t; +using u64 = std::uint64_t; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; +using s8 = std::int8_t; +using s16 = std::int16_t; +using s32 = std::int32_t; +using s64 = std::int64_t; -template force_inline T align(const T addr, int align) +using b8 = std::uint8_t; + +using f32 = float; +using f64 = double; + +template::value>> inline T align(const T& value, u64 align) { - return (addr + (align - 1)) & ~(align - 1); + return static_cast((value + (align - 1)) & ~(align - 1)); } -template struct sizeof32_t +// copy null-terminated string from std::string to char array with truncation +template inline void strcpy_trunc(char(&dst)[N], const std::string& src) { - static const u32 value = static_cast(sizeof(T)); + const std::size_t count = src.size() >= N ? N - 1 : src.size(); + std::memcpy(dst, src.c_str(), count); + dst[count] = '\0'; +} - static_assert(value == sizeof(T), "sizeof32() error: sizeof() is too big"); +// copy null-terminated string from char array to char array with truncation +template inline void strcpy_trunc(char(&dst)[N], const char(&src)[N2]) +{ + const std::size_t count = N2 >= N ? N - 1 : N2; + std::memcpy(dst, src, count); + dst[count] = '\0'; +} + +// bool wrapper for restricting bool result conversions +struct explicit_bool_t +{ + const bool value; + + explicit_bool_t(bool value) + : value(value) + { + } + + explicit operator bool() const + { + return value; + } }; // return 32 bit sizeof() to avoid widening/narrowing conversions with size_t -#define sizeof32(type) sizeof32_t::value +#define sizeof32(type) static_cast(sizeof32_t::value) + +// return 32 bit alignof() to avoid widening/narrowing conversions with size_t +#define alignof32(type) static_cast(alignof32_t<__alignof(type)>::value) + +template struct sizeof32_t +{ + static_assert(Size <= UINT32_MAX, "sizeof32() error: size is too big"); + + enum : u32 { value = static_cast(Size) }; +}; + +template struct alignof32_t +{ + static_assert(Align <= UINT32_MAX, "alignof32() error: alignment is too big"); + + enum : u32 { value = static_cast(Align) }; +}; template using func_def = T; // workaround for MSVC bug: `using X = func_def;` instead of `using X = void();` -#include "Utilities/BEType.h" -#include "Utilities/StrFmt.h" - -#include "Emu/Memory/atomic.h" - template struct ID_type; -#define REG_ID_TYPE(t, id) template<> struct ID_type { static const u32 type = id; } +#define REG_ID_TYPE(t, id) template<> struct ID_type { enum : u32 { type = id }; } + +#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size") +#define CHECK_ALIGN(type, align) static_assert(__alignof(type) == align, "Invalid " #type " type alignment") +#define CHECK_MAX_SIZE(type, size) static_assert(sizeof(type) <= size, #type " type size is too big") +#define CHECK_SIZE_ALIGN(type, size, align) CHECK_SIZE(type, size); CHECK_ALIGN(type, align) + +#define WRAP_EXPR(expr) [&]{ return expr; } +#define COPY_EXPR(expr) [=]{ return expr; } +#define EXCEPTION(text, ...) fmt::exception(__FILE__, __LINE__, __FUNCTION__, text, ##__VA_ARGS__) +#define VM_CAST(value) vm::impl_cast(value, __FILE__, __LINE__, __FUNCTION__) #define _PRGNAME_ "RPCS3" #define _PRGVER_ "0.0.0.5" + +#include "Utilities/BEType.h" +#include "Utilities/StrFmt.h" +#include "Emu/Memory/atomic.h"