sys_time_get_current_time fixed, CALL_FUNC draft

This commit is contained in:
Nekotekina 2015-07-06 02:21:15 +03:00
parent 22e1da5e76
commit 83321c5be7
46 changed files with 385 additions and 351 deletions

View File

@ -37,22 +37,6 @@
#define set_alignment(x) __attribute__((aligned(x)))
#endif
template<size_t size>
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<size_t size, size_t rsize>
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(__GNUG__)
#include <stdlib.h>
@ -93,42 +77,42 @@ int clock_gettime(int foo, struct timespec *ts);
#endif /* __APPLE__ */
template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_val_compare_and_swap(volatile T* dest, T2 comp, T2 exch)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<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<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, bool> sync_bool_compare_and_swap(volatile T* dest, T2 comp, T2 exch)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<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<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_lock_test_and_set(volatile T* dest, T2 value)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_lock_test_and_set(volatile T* dest, T2 value)
{
return __sync_lock_test_and_set(dest, value);
}
template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_add(volatile T* dest, T2 value)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_add(volatile T* dest, T2 value)
{
return __sync_fetch_and_add(dest, value);
}
template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_sub(volatile T* dest, T2 value)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_sub(volatile T* dest, T2 value)
{
return __sync_fetch_and_sub(dest, value);
}
template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_or(volatile T* dest, T2 value)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_or(volatile T* dest, T2 value)
{
return __sync_fetch_and_or(dest, value);
}
template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_and(volatile T* dest, T2 value)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_and(volatile T* dest, T2 value)
{
return __sync_fetch_and_and(dest, value);
}
template<typename T, typename T2> static inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_xor(volatile T* dest, T2 value)
template<typename T, typename T2> inline std::enable_if_t<std::is_arithmetic<T>::value, T> sync_fetch_and_xor(volatile T* dest, T2 value)
{
return __sync_fetch_and_xor(dest, value);
}
@ -139,181 +123,181 @@ template<typename T, typename T2> static inline std::enable_if_t<std::is_arithme
// atomic compare and swap functions
static force_inline uint8_t sync_val_compare_and_swap(volatile uint8_t* dest, uint8_t comp, uint8_t exch)
inline uint8_t sync_val_compare_and_swap(volatile uint8_t* dest, uint8_t comp, uint8_t exch)
{
return _InterlockedCompareExchange8((volatile char*)dest, exch, comp);
}
static force_inline uint16_t sync_val_compare_and_swap(volatile uint16_t* dest, uint16_t comp, uint16_t exch)
inline uint16_t sync_val_compare_and_swap(volatile uint16_t* dest, uint16_t comp, uint16_t exch)
{
return _InterlockedCompareExchange16((volatile short*)dest, exch, comp);
}
static force_inline uint32_t sync_val_compare_and_swap(volatile uint32_t* dest, uint32_t comp, uint32_t exch)
inline uint32_t sync_val_compare_and_swap(volatile uint32_t* dest, uint32_t comp, uint32_t exch)
{
return _InterlockedCompareExchange((volatile long*)dest, exch, comp);
}
static force_inline uint64_t sync_val_compare_and_swap(volatile uint64_t* dest, uint64_t comp, uint64_t exch)
inline uint64_t sync_val_compare_and_swap(volatile uint64_t* dest, uint64_t comp, uint64_t exch)
{
return _InterlockedCompareExchange64((volatile long long*)dest, exch, comp);
}
static force_inline bool sync_bool_compare_and_swap(volatile uint8_t* dest, uint8_t comp, uint8_t exch)
inline bool sync_bool_compare_and_swap(volatile uint8_t* dest, uint8_t comp, uint8_t exch)
{
return (uint8_t)_InterlockedCompareExchange8((volatile char*)dest, exch, comp) == comp;
}
static force_inline bool sync_bool_compare_and_swap(volatile uint16_t* dest, uint16_t comp, uint16_t exch)
inline bool sync_bool_compare_and_swap(volatile uint16_t* dest, uint16_t comp, uint16_t exch)
{
return (uint16_t)_InterlockedCompareExchange16((volatile short*)dest, exch, comp) == comp;
}
static force_inline bool sync_bool_compare_and_swap(volatile uint32_t* dest, uint32_t comp, uint32_t exch)
inline bool sync_bool_compare_and_swap(volatile uint32_t* dest, uint32_t comp, uint32_t exch)
{
return (uint32_t)_InterlockedCompareExchange((volatile long*)dest, exch, comp) == comp;
}
static force_inline bool sync_bool_compare_and_swap(volatile uint64_t* dest, uint64_t comp, uint64_t exch)
inline bool sync_bool_compare_and_swap(volatile uint64_t* dest, uint64_t comp, uint64_t exch)
{
return (uint64_t)_InterlockedCompareExchange64((volatile long long*)dest, exch, comp) == comp;
}
// atomic exchange functions
static force_inline uint8_t sync_lock_test_and_set(volatile uint8_t* dest, uint8_t value)
inline uint8_t sync_lock_test_and_set(volatile uint8_t* dest, uint8_t value)
{
return _InterlockedExchange8((volatile char*)dest, value);
}
static force_inline uint16_t sync_lock_test_and_set(volatile uint16_t* dest, uint16_t value)
inline uint16_t sync_lock_test_and_set(volatile uint16_t* dest, uint16_t value)
{
return _InterlockedExchange16((volatile short*)dest, value);
}
static force_inline uint32_t sync_lock_test_and_set(volatile uint32_t* dest, uint32_t value)
inline uint32_t sync_lock_test_and_set(volatile uint32_t* dest, uint32_t value)
{
return _InterlockedExchange((volatile long*)dest, value);
}
static force_inline uint64_t sync_lock_test_and_set(volatile uint64_t* dest, uint64_t value)
inline uint64_t sync_lock_test_and_set(volatile uint64_t* dest, uint64_t value)
{
return _InterlockedExchange64((volatile long long*)dest, value);
}
// atomic add functions
static force_inline uint8_t sync_fetch_and_add(volatile uint8_t* dest, uint8_t value)
inline uint8_t sync_fetch_and_add(volatile uint8_t* dest, uint8_t value)
{
return _InterlockedExchangeAdd8((volatile char*)dest, value);
}
static force_inline uint16_t sync_fetch_and_add(volatile uint16_t* dest, uint16_t value)
inline uint16_t sync_fetch_and_add(volatile uint16_t* dest, uint16_t value)
{
return _InterlockedExchangeAdd16((volatile short*)dest, value);
}
static force_inline uint32_t sync_fetch_and_add(volatile uint32_t* dest, uint32_t value)
inline uint32_t sync_fetch_and_add(volatile uint32_t* dest, uint32_t value)
{
return _InterlockedExchangeAdd((volatile long*)dest, value);
}
static force_inline uint64_t sync_fetch_and_add(volatile uint64_t* dest, uint64_t value)
inline uint64_t sync_fetch_and_add(volatile uint64_t* dest, uint64_t value)
{
return _InterlockedExchangeAdd64((volatile long long*)dest, value);
}
// atomic sub functions
static force_inline uint8_t sync_fetch_and_sub(volatile uint8_t* dest, uint8_t value)
inline uint8_t sync_fetch_and_sub(volatile uint8_t* dest, uint8_t value)
{
return _InterlockedExchangeAdd8((volatile char*)dest, -(char)value);
}
static force_inline uint16_t sync_fetch_and_sub(volatile uint16_t* dest, uint16_t value)
inline uint16_t sync_fetch_and_sub(volatile uint16_t* dest, uint16_t value)
{
return _InterlockedExchangeAdd16((volatile short*)dest, -(short)value);
}
static force_inline uint32_t sync_fetch_and_sub(volatile uint32_t* dest, uint32_t value)
inline uint32_t sync_fetch_and_sub(volatile uint32_t* dest, uint32_t value)
{
return _InterlockedExchangeAdd((volatile long*)dest, -(long)value);
}
static force_inline uint64_t sync_fetch_and_sub(volatile uint64_t* dest, uint64_t value)
inline uint64_t sync_fetch_and_sub(volatile uint64_t* dest, uint64_t value)
{
return _InterlockedExchangeAdd64((volatile long long*)dest, -(long long)value);
}
// atomic bitwise or functions
// atomic `bitwise or` functions
static force_inline uint8_t sync_fetch_and_or(volatile uint8_t* dest, uint8_t value)
inline uint8_t sync_fetch_and_or(volatile uint8_t* dest, uint8_t value)
{
return _InterlockedOr8((volatile char*)dest, value);
}
static force_inline uint16_t sync_fetch_and_or(volatile uint16_t* dest, uint16_t value)
inline uint16_t sync_fetch_and_or(volatile uint16_t* dest, uint16_t value)
{
return _InterlockedOr16((volatile short*)dest, value);
}
static force_inline uint32_t sync_fetch_and_or(volatile uint32_t* dest, uint32_t value)
inline uint32_t sync_fetch_and_or(volatile uint32_t* dest, uint32_t value)
{
return _InterlockedOr((volatile long*)dest, value);
}
static force_inline uint64_t sync_fetch_and_or(volatile uint64_t* dest, uint64_t value)
inline uint64_t sync_fetch_and_or(volatile uint64_t* dest, uint64_t value)
{
return _InterlockedOr64((volatile long long*)dest, value);
}
// atomic bitwise and functions
// atomic `bitwise and` functions
static force_inline uint8_t sync_fetch_and_and(volatile uint8_t* dest, uint8_t value)
inline uint8_t sync_fetch_and_and(volatile uint8_t* dest, uint8_t value)
{
return _InterlockedAnd8((volatile char*)dest, value);
}
static force_inline uint16_t sync_fetch_and_and(volatile uint16_t* dest, uint16_t value)
inline uint16_t sync_fetch_and_and(volatile uint16_t* dest, uint16_t value)
{
return _InterlockedAnd16((volatile short*)dest, value);
}
static force_inline uint32_t sync_fetch_and_and(volatile uint32_t* dest, uint32_t value)
inline uint32_t sync_fetch_and_and(volatile uint32_t* dest, uint32_t value)
{
return _InterlockedAnd((volatile long*)dest, value);
}
static force_inline uint64_t sync_fetch_and_and(volatile uint64_t* dest, uint64_t value)
inline uint64_t sync_fetch_and_and(volatile uint64_t* dest, uint64_t value)
{
return _InterlockedAnd64((volatile long long*)dest, value);
}
// atomic bitwise xor functions
// atomic `bitwise xor` functions
static force_inline uint8_t sync_fetch_and_xor(volatile uint8_t* dest, uint8_t value)
inline uint8_t sync_fetch_and_xor(volatile uint8_t* dest, uint8_t value)
{
return _InterlockedXor8((volatile char*)dest, value);
}
static force_inline uint16_t sync_fetch_and_xor(volatile uint16_t* dest, uint16_t value)
inline uint16_t sync_fetch_and_xor(volatile uint16_t* dest, uint16_t value)
{
return _InterlockedXor16((volatile short*)dest, value);
}
static force_inline uint32_t sync_fetch_and_xor(volatile uint32_t* dest, uint32_t value)
inline uint32_t sync_fetch_and_xor(volatile uint32_t* dest, uint32_t value)
{
return _InterlockedXor((volatile long*)dest, value);
}
static force_inline uint64_t sync_fetch_and_xor(volatile uint64_t* dest, uint64_t value)
inline uint64_t sync_fetch_and_xor(volatile uint64_t* dest, uint64_t value)
{
return _InterlockedXor64((volatile long long*)dest, value);
}
#endif /* _MSC_VER */
static force_inline uint32_t cntlz32(uint32_t arg)
inline uint32_t cntlz32(uint32_t arg)
{
#if defined(_MSC_VER)
unsigned long res;
@ -337,7 +321,7 @@ static force_inline uint32_t cntlz32(uint32_t arg)
#endif
}
static force_inline uint64_t cntlz64(uint64_t arg)
inline uint64_t cntlz64(uint64_t arg)
{
#if defined(_MSC_VER)
unsigned long res;

View File

@ -11,8 +11,7 @@ namespace vm
}
}
template<typename RT, typename... T>
force_inline RT cb_call(ARMv7Context& context, u32 addr, T... args)
template<typename RT, typename... T> inline RT cb_call(ARMv7Context& context, u32 addr, T... args)
{
return psv_func_detail::func_caller<RT, T...>::call(context, addr, args...);
}

View File

@ -56,7 +56,7 @@ CPUThread::CPUThread(CPUThreadType type, const std::string& name, std::function<
if (!lock) lock.lock();
cv.wait_for(lock, std::chrono::milliseconds(1));
cv.wait(lock);
}
cv.notify_all();

View File

@ -2261,8 +2261,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:
@ -2303,7 +2303,7 @@ 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;

View File

@ -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 <stdint.h>
#ifdef _MSC_VER
@ -18,6 +17,7 @@
#include <fenv.h>
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()
{
@ -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:
@ -2923,7 +2923,7 @@ private:
{
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;

View File

@ -3292,10 +3292,10 @@ void Compiler::MFSPR(u32 rd, u32 spr) {
rd_i64 = GetVrsave();
break;
case 0x10C:
rd_i64 = Call<u64>("get_time", get_time);
rd_i64 = Call<u64>("get_timebased_time", get_timebased_time);
break;
case 0x10D:
rd_i64 = Call<u64>("get_time", get_time);
rd_i64 = Call<u64>("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<u64>("get_time", get_time);
auto tb_i64 = Call<u64>("get_timebased_time", get_timebased_time);
u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
if (n == 0x10D) {

View File

@ -11,7 +11,6 @@
#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 +21,8 @@
#include <cfenv>
extern u64 get_timebased_time();
const g_spu_imm_table_t g_spu_imm;
class spu_inter_func_list_t
@ -179,7 +180,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 = {};
@ -599,7 +600,7 @@ u32 SPUThread::get_ch_value(u32 ch)
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:
@ -965,7 +966,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;
}

View File

@ -7,8 +7,6 @@
#include "Emu/Cell/SPUThread.h"
#include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/SysCalls/lv2/sys_time.h"
#ifdef _WIN32
#include <Windows.h>
#else
@ -139,8 +137,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))
@ -150,16 +146,12 @@ namespace vm
{
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))
@ -170,8 +162,6 @@ namespace vm
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();
@ -197,8 +187,6 @@ namespace vm
bool reservation_acquire(void* data, u32 addr, u32 size, std::function<void()> callback)
{
//const auto stamp0 = get_time();
bool broken = false;
assert(size == 1 || size == 2 || size == 4 || size == 8 || size == 128);

View File

@ -104,7 +104,7 @@ namespace vm
// test address for arbitrary alignment or something
force_inline explicit_bool_t operator %(to_ne_t<AT> right) const
{
return m_addr % right;
return m_addr % right != 0;
}
_ptr_base& operator =(const _ptr_base&) = default;

View File

@ -1,4 +1,5 @@
#pragma once
#include "Emu/Cell/PPUThread.h"
namespace cb_detail
@ -172,15 +173,7 @@ namespace vm
}
}
template<typename RT, typename... T>
force_inline RT cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
template<typename RT, typename... T> inline RT cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
{
return cb_detail::_func_caller<RT, T...>::call(CPU, pc, rtoc, args...);
}
// Something is wrong with it (but cb_call<void, ...>() should work anyway)
//template<typename... T>
//void cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
//{
// cb_detail::_func_caller<void, T...>::call(CPU, pc, rtoc, args...);
//}

View File

@ -20,9 +20,14 @@ void CallbackManager::Async(async_cb_t func)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_cb_thread)
{
throw EXCEPTION("Callback thread not found");
}
m_async_cb.emplace(std::move(func));
m_cv.notify_one();
m_cb_thread->cv.notify_one();
}
CallbackManager::check_cb_t CallbackManager::Check()
@ -45,7 +50,7 @@ void CallbackManager::Init()
{
std::lock_guard<std::mutex> lock(m_mutex);
auto task = [this](CPUThread& CPU)
auto task = [this](CPUThread& cpu)
{
std::unique_lock<std::mutex> lock(m_mutex);
@ -63,12 +68,12 @@ void CallbackManager::Init()
if (lock) lock.unlock();
func(CPU);
func(cpu);
continue;
}
m_cv.wait_for(lock, std::chrono::milliseconds(1));
cpu.cv.wait(lock);
}
};
@ -100,8 +105,8 @@ void CallbackManager::Clear()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_check_cb = {};
m_async_cb = {};
m_check_cb = decltype(m_check_cb){};
m_async_cb = decltype(m_async_cb){};
m_cb_thread.reset();
}

View File

@ -8,7 +8,6 @@ class CallbackManager
using async_cb_t = std::function<void(CPUThread&)>;
std::mutex m_mutex;
std::condition_variable m_cv;
std::queue<check_cb_t> m_check_cb;
std::queue<async_cb_t> m_async_cb;

View File

@ -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";

View File

@ -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"

View File

@ -1,6 +1,7 @@
#pragma once
#include "Emu/SysCalls/SC_FUNC.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "ErrorCodes.h"
#include "LogBase.h"
@ -124,6 +125,38 @@ void hook_ppu_funcs(vm::ptr<u32> base, u32 size);
bool patch_ppu_import(u32 addr, u32 index);
// don't use directly
template<typename RT, typename... T, typename... Args> inline auto _call_ppu(RT(*func)(PPUThread&, T...), PPUThread& CPU, Args&&... args) -> decltype(func(CPU, args...))
{
return func(CPU, args...);
}
// don't use directly
template<typename RT, typename... T, typename... Args> inline auto _call_ppu(RT(*func)(T...), PPUThread& CPU, Args&&... args) -> decltype(func(args...))
{
return func(args...);
}
// call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
template<typename T, typename... Args> inline auto hle_call_func(T func, u32 index, PPUThread& CPU, Args... args) -> decltype(_call_ppu(func, CPU, 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<decltype(_call_ppu(func, CPU, args...)), Args...>(CPU, pc, rtoc, args...);
}
else
{
return _call_ppu(func, CPU, args...);
}
}
#define CALL_FUNC(func, ...) hle_call_func(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)))

View File

@ -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;

View File

@ -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()
@ -151,7 +152,7 @@ s32 cellAudioInit()
// 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;
const u64 expected_time = g_audio.counter * AUDIO_SAMPLES * 1000000 / 48000;
if (expected_time >= time_pos)
{
g_audio.thread.cv.wait_for(lock, std::chrono::milliseconds(1));

View File

@ -3,7 +3,6 @@
#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"

View File

@ -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"

View File

@ -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"

View File

@ -2,7 +2,7 @@
#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"

View File

@ -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<MsgDialogInstance> g_msg_dialog;
MsgDialogInstance::MsgDialogInstance()

View File

@ -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"

View File

@ -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/IdManager.h"
#include "Emu/Event.h"
@ -427,7 +426,9 @@ void spursHandlerWaitReady(PPUThread& CPU, vm::ptr<CellSpurs> spurs)
if (spurs->handlerExiting.load())
{
if (s32 rc = sys_lwmutex_unlock(CPU, spurs.of(&CellSpurs::mutex)))
extern u32 g_ppu_func_index__sys_lwmutex_unlock; // test
if (s32 rc = CALL_FUNC(sys_lwmutex_unlock, CPU, spurs.of(&CellSpurs::mutex)))
{
throw EXCEPTION("sys_lwmutex_unlock() failed (0x%x)", rc);
}
@ -685,7 +686,7 @@ void spursEventHelperEntry(PPUThread& CPU)
}
else if (data0 < 1)
{
const u32 shutdownMask = event_data3;
const u32 shutdownMask = (u32)event_data3;
for (auto wid = 0; wid < CELL_SPURS_MAX_WORKLOAD; wid++)
{
@ -855,7 +856,7 @@ s32 spursStopEventHelper(PPUThread& CPU, vm::ptr<CellSpurs> spurs)
return CELL_SPURS_CORE_ERROR_STAT;
}
if (sys_ppu_thread_join(CPU, spurs->ppu1, vm::stackvar<be_t<u64>>(CPU)) != CELL_OK)
if (sys_ppu_thread_join(CPU, (u32)spurs->ppu1, vm::stackvar<be_t<u64>>(CPU)) != CELL_OK)
{
return CELL_SPURS_CORE_ERROR_STAT;
}
@ -914,7 +915,7 @@ s32 spursJoinHandlerThread(PPUThread& CPU, vm::ptr<CellSpurs> spurs)
return CELL_SPURS_CORE_ERROR_STAT;
}
if (s32 rc = sys_ppu_thread_join(CPU, spurs->ppu0, vm::stackvar<be_t<u64>>(CPU)))
if (s32 rc = sys_ppu_thread_join(CPU, (u32)spurs->ppu0, vm::stackvar<be_t<u64>>(CPU)))
{
throw EXCEPTION("sys_ppu_thread_join() failed (0x%x)", rc);
}

View File

@ -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"

View File

@ -4,7 +4,6 @@
#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"
@ -21,84 +20,94 @@
extern Module cellSysutil;
int cellSysutilGetSystemParamInt(int id, vm::ptr<u32> 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<s32> 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;
@ -109,21 +118,19 @@ int cellSysutilGetSystemParamInt(int id, vm::ptr<u32> value)
return CELL_OK;
}
int cellSysutilGetSystemParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
s32 cellSysutilGetSystemParamString(s32 id, vm::ptr<char> 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;
@ -134,9 +141,9 @@ int cellSysutilGetSystemParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
return CELL_OK;
}
int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutState> state)
s32 cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutState> 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;
@ -160,10 +167,9 @@ int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutStat
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetResolution(u32 resolutionId, vm::ptr<CellVideoOutResolution> resolution)
s32 cellVideoOutGetResolution(u32 resolutionId, vm::ptr<CellVideoOutResolution> 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)
@ -177,8 +183,7 @@ int cellVideoOutGetResolution(u32 resolutionId, vm::ptr<CellVideoOutResolution>
s32 cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> 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)
{
@ -209,10 +214,9 @@ s32 cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration> confi
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> option)
s32 cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> 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 = {};
@ -235,10 +239,9 @@ int cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfiguration
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutDeviceInfo> info)
s32 cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutDeviceInfo> 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;
@ -267,7 +270,7 @@ int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOu
return CELL_OK;
}
int cellVideoOutGetNumberOfDevice(u32 videoOut)
s32 cellVideoOutGetNumberOfDevice(u32 videoOut)
{
cellSysutil.Warning("cellVideoOutGetNumberOfDevice(videoOut=%d)", videoOut);
@ -280,7 +283,7 @@ int cellVideoOutGetNumberOfDevice(u32 videoOut)
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option)
s32 cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option)
{
cellSysutil.Warning("cellVideoOutGetResolutionAvailability(videoOut=%d, resolutionId=0x%x, aspect=%d, option=%d)", videoOut, resolutionId, aspect, option);
@ -340,7 +343,7 @@ s32 cellSysutilCheckCallback(PPUThread& CPU)
s32 cellSysutilRegisterCallback(s32 slot, vm::ptr<CellSysutilCallback> func, vm::ptr<void> 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)
{
@ -366,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)
{
@ -407,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)
{
@ -457,9 +458,9 @@ 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<CellAudioOutState> state)
s32 cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudioOutState> 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 = {};
@ -486,10 +487,9 @@ int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudioOutStat
return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
}
int cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration> config, vm::ptr<CellAudioOutOption> option, u32 waitForEvent)
s32 cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration> config, vm::ptr<CellAudioOutOption> 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)
{
@ -515,9 +515,9 @@ int cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration> confi
return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
}
int cellAudioOutGetConfiguration(u32 audioOut, vm::ptr<CellAudioOutConfiguration> config, vm::ptr<CellAudioOutOption> option)
s32 cellAudioOutGetConfiguration(u32 audioOut, vm::ptr<CellAudioOutConfiguration> config, vm::ptr<CellAudioOutOption> 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 = {};
@ -539,7 +539,7 @@ int cellAudioOutGetConfiguration(u32 audioOut, vm::ptr<CellAudioOutConfiguration
return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
}
int cellAudioOutGetNumberOfDevice(u32 audioOut)
s32 cellAudioOutGetNumberOfDevice(u32 audioOut)
{
cellSysutil.Warning("cellAudioOutGetNumberOfDevice(audioOut=%d)", audioOut);
@ -552,9 +552,9 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut)
return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT;
}
int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudioOutDeviceInfo> info)
s32 cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudioOutDeviceInfo> 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;
@ -570,9 +570,9 @@ int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudioOu
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)
{
@ -596,71 +596,29 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control)
return CELL_OK;
}
typedef struct{
struct CellSysCacheParam
{
char cacheId[CELL_SYSCACHE_ID_SIZE];
char getCachePath[CELL_SYSCACHE_PATH_MAX];
vm::ptr<void> 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<CellSysCacheParam> param)
s32 cellSysCacheMount(vm::ptr<CellSysCacheParam> 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];
@ -672,55 +630,55 @@ int cellSysCacheMount(vm::ptr<CellSysCacheParam> 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<CellSysutilBgmPlaybackExtraParam> param)
s32 cellSysutilEnableBgmPlaybackEx(vm::ptr<CellSysutilBgmPlaybackExtraParam> 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<CellSysutilBgmPlaybackExtraParam> param)
s32 cellSysutilDisableBgmPlaybackEx(vm::ptr<CellSysutilBgmPlaybackExtraParam> 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<CellSysutilBgmPlaybackStatus> status)
s32 cellSysutilGetBgmPlaybackStatus(vm::ptr<CellSysutilBgmPlaybackStatus> 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));
@ -728,9 +686,9 @@ int cellSysutilGetBgmPlaybackStatus(vm::ptr<CellSysutilBgmPlaybackStatus> status
return CELL_OK;
}
int cellSysutilGetBgmPlaybackStatus2(vm::ptr<CellSysutilBgmPlaybackStatus2> status2)
s32 cellSysutilGetBgmPlaybackStatus2(vm::ptr<CellSysutilBgmPlaybackStatus2> 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;
@ -739,9 +697,9 @@ int cellSysutilGetBgmPlaybackStatus2(vm::ptr<CellSysutilBgmPlaybackStatus2> stat
return CELL_OK;
}
int cellWebBrowserEstimate2(const vm::cptr<CellWebBrowserConfig2> config, vm::ptr<u32> memSize)
s32 cellWebBrowserEstimate2(vm::cptr<CellWebBrowserConfig2> config, vm::ptr<u32> 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.

View File

@ -34,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

View File

@ -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;

View File

@ -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/Cell/PPUInstrTable.h"
#include "Emu/CPU/CPUThreadManager.h"

View File

@ -3,7 +3,6 @@
#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"
@ -12,7 +11,6 @@
#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"
@ -331,9 +329,7 @@ s32 sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr<u32>
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);
ctxt->tropusr->UnlockTrophy(trophyId, 0, 0); // TODO
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
ctxt->tropusr->Save(trophyPath);

View File

@ -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
@ -629,6 +629,13 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
return res;
}
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<char> fmt, u32 g_count, u32 f_count, u32 v_count)
{
std::string result;
@ -1277,6 +1284,8 @@ void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<atomic_be_t<u32>> once_ctrl, vm
}
}
u32 g_ppu_func_index__sys_lwmutex_unlock; // test
Module sysPrxForUser("sysPrxForUser", []()
{
g_tls_start = 0;
@ -1299,7 +1308,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);

View File

@ -1,4 +1,5 @@
#pragma once
#include "Emu/Cell/PPUThread.h"
using ppu_func_caller = void(*)(PPUThread&);

View File

@ -182,7 +182,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)

View File

@ -7,12 +7,13 @@
#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<u32> cond_id, u32 mutex_id, vm::ptr<sys_cond_attribute_t> attr)
{
sys_cond.Warning("sys_cond_create(cond_id=*0x%x, mutex_id=0x%x, attr=*0x%x)", cond_id, mutex_id, attr);

View File

@ -7,12 +7,13 @@
#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");
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)

View File

@ -7,11 +7,12 @@
#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");
extern u64 get_system_time();
s32 sys_event_flag_create(vm::ptr<u32> id, vm::ptr<sys_event_flag_attr> attr, u64 init)
{
sys_event_flag.Warning("sys_event_flag_create(id=*0x%x, attr=*0x%x, init=0x%llx)", id, attr, init);

View File

@ -7,12 +7,13 @@
#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");
extern u64 get_system_time();
s32 _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sys_lwcond_t> control, u64 name, u32 arg5)
{
sys_lwcond.Warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5);

View File

@ -7,11 +7,12 @@
#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");
extern u64 get_system_time();
s32 _sys_lwmutex_create(vm::ptr<u32> lwmutex_id, u32 protocol, vm::ptr<sys_lwmutex_t> control, u32 arg4, u64 name, u32 arg6)
{
sys_lwmutex.Warning("_sys_lwmutex_create(lwmutex_id=*0x%x, protocol=0x%x, control=*0x%x, arg4=0x%x, name=0x%llx, arg6=0x%x)", lwmutex_id, protocol, control, arg4, name, arg6);

View File

@ -7,11 +7,12 @@
#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();
s32 sys_mutex_create(vm::ptr<u32> mutex_id, vm::ptr<sys_mutex_attribute_t> attr)
{
sys_mutex.Warning("sys_mutex_create(mutex_id=*0x%x, attr=*0x%x)", mutex_id, attr);

View File

@ -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<u32> rw_lock_id, vm::ptr<sys_rwlock_attribute_t> attr)
{
sys_rwlock.Warning("sys_rwlock_create(rw_lock_id=*0x%x, attr=*0x%x)", rw_lock_id, attr);

View File

@ -7,11 +7,12 @@
#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<u32> sem, vm::ptr<sys_semaphore_attribute_t> 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);

View File

@ -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 <Windows.h>
#endif
#include "sys_time.h"
#ifdef _WIN32
#include <Windows.h>
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<u32> 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<u64>(ts.tv_sec) * g_timebase_freq + static_cast<u64>(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<u64>(ts.tv_sec) * 1000000u + static_cast<u64>(ts.tv_nsec) / 1000u;
#endif
if (result) return result;
}
}
// Functions
s32 sys_time_get_timezone(vm::ptr<u32> timezone, vm::ptr<u32> summertime)
s32 sys_time_get_timezone(vm::ptr<s32> timezone, vm::ptr<s32> 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<s64> sec, vm::ptr<s64> 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;
}

View File

@ -2,17 +2,7 @@
namespace vm { using namespace ps3; }
enum : u32
{
MHZ = 1000000,
};
// Auxiliary functions
u64 get_time();
u64 get_system_time();
// SysCalls
s32 sys_time_get_timezone(vm::ptr<u32> timezone, vm::ptr<u32> 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<s32> timezone, vm::ptr<s32> summertime);
s32 sys_time_get_current_time(vm::ptr<s64> sec, vm::ptr<s64> nsec);
u64 sys_time_get_timebase_frequency();

View File

@ -5,13 +5,14 @@
#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");
extern u64 get_system_time();
lv2_timer_t::lv2_timer_t()
: start(0)
, period(0)

View File

@ -308,17 +308,20 @@ void Emulator::Pause()
void Emulator::Resume()
{
const u64 time = m_pause_start_time.exchange(0);
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 (const u64 time = m_pause_start_time.exchange(0))
{
m_pause_amend_time += get_system_time() - time;
}
else
if (!time)
{
LOG_ERROR(GENERAL, "Resume(): Concurrent access");
}
@ -337,6 +340,8 @@ extern std::map<u32, std::string> g_armv7_dump;
void Emulator::Stop()
{
LOG_NOTICE(GENERAL, "Stopping emulator...");
if (sync_lock_test_and_set(&m_status, Stopped) == Stopped)
{
return;
@ -344,10 +349,6 @@ void Emulator::Stop()
SendDbgCommand(DID_STOP_EMU);
m_status = Stopped;
LOG_NOTICE(GENERAL, "Stopping emulator...");
for (auto& t : GetCPU().GetAllThreads())
{
t->Sleep(); // trigger status check

View File

@ -62,6 +62,22 @@ template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>> in
return static_cast<T>((value + (align - 1)) & ~(align - 1));
}
// copy null-terminated string from std::string to char array with truncation
template<std::size_t N> inline void strcpy_trunc(char(&dst)[N], const std::string& src)
{
const std::size_t count = src.size() >= N ? N - 1 : src.size();
std::memcpy(dst, src.c_str(), count);
dst[count] = '\0';
}
// copy null-terminated string from char array to char array with truncation
template<std::size_t N, std::size_t N2> 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
{