libmixer draft

and some hacks
This commit is contained in:
Nekotekina 2014-03-06 15:40:50 +04:00
parent 384536ba4f
commit e86a849600
16 changed files with 662 additions and 269 deletions

View file

@ -71,10 +71,16 @@ private:
if(Ini.HLELogging.GetValue())
{
ConLog.Warning("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
ConLog.Warning("SysCall[0x%llx] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
if(CPU.GPR[11] > 1024)
SysCalls::DoFunc(CPU.GPR[11]);
}
/*else if ((s64)CPU.GPR[3] < 0) // probably, error code
{
ConLog.Error("SysCall[0x%llx] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
if(CPU.GPR[11] > 1024)
SysCalls::DoFunc(CPU.GPR[11]);
}*/
#ifdef HLE_CALL_DEBUG
ConLog.Write("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
#endif
@ -2088,6 +2094,11 @@ private:
{
case 0x1: UNK(wxString::Format("HyperCall %d", CPU.GPR[0])); break;
case 0x2: SysCall(); break;
case 0x3:
StaticExecute(CPU.GPR[11]);
ConLog.Write("'%s' done with code[0x%llx]! #pc: 0x%llx",
wxString(g_static_funcs_list[CPU.GPR[11]].name).wx_str(), CPU.GPR[3], CPU.PC);
break;
case 0x22: UNK("HyperCall LV1"); break;
default: UNK(wxString::Format("Unknown sc: %x", sc_code));
}

View file

@ -53,7 +53,7 @@ void Callback::Branch(bool wait)
{
m_has_data = false;
static SMutexGeneral cb_mutex;
static std::mutex cb_mutex;
CPUThread& thr = Emu.GetCallbackThread();
@ -69,7 +69,7 @@ again:
Sleep(1);
}
SMutexGeneralLocker lock(cb_mutex);
std::lock_guard<std::mutex> lock(cb_mutex);
if (thr.IsAlive())
{

View file

@ -8,6 +8,7 @@ uint g_max_module_id = 0;
uint g_module_2_count = 0;
ArrayF<ModuleFunc> g_modules_funcs_list;
std::mutex g_funcs_lock;
ArrayF<SFunc> g_static_funcs_list;
struct ModuleInfo
{

View file

@ -25,6 +25,21 @@ struct ModuleFunc
}
};
struct SFuncOp
{
u32 crc;
u32 mask;
};
struct SFunc
{
func_caller* func;
char* name;
Array<SFuncOp> ops;
};
extern ArrayF<SFunc> g_static_funcs_list;
class Module
{
std::string m_name;
@ -94,6 +109,8 @@ public:
}
template<typename T> __forceinline void AddFunc(u32 id, T func);
template<typename T> __forceinline void AddFuncSub(const u64 ops[], char* name, T func);
};
template<typename T>
@ -102,6 +119,29 @@ __forceinline void Module::AddFunc(u32 id, T func)
m_funcs_list.Move(new ModuleFunc(id, bind_func(func)));
}
template<typename T>
__forceinline void Module::AddFuncSub(const u64 ops[], char* name, T func)
{
if (!ops[0]) return;
SFunc* sf = new SFunc;
sf->func = bind_func(func);
sf->name = name;
// TODO: check for self-inclusions, use CRC
for (u32 i = 0; ops[i]; i++)
{
SFuncOp op;
op.mask = ops[i] >> 32;
op.crc = ops[i] & op.mask;
op.mask = re(op.mask);
op.crc = re(op.crc);
sf->ops.AddCpy(op);
}
g_static_funcs_list.Add(sf);
}
bool IsLoadedFunc(u32 id);
bool CallFunc(u32 num);
bool UnloadFunc(u32 id);

View file

@ -4,9 +4,8 @@
#include "Emu/Audio/cellAudio.h"
void cellAudio_init();
void cellAudio_load();
void cellAudio_unload();
Module cellAudio(0x0011, cellAudio_init, cellAudio_load, cellAudio_unload);
Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload);
extern u64 get_system_time();
@ -135,7 +134,7 @@ struct CellAudioPortConfig
struct AudioPortConfig
{
SMutex m_mutex;
SMutexGeneral m_mutex;
bool m_is_audio_port_opened;
bool m_is_audio_port_started;
u8 channel;
@ -179,64 +178,6 @@ struct AudioConfig //custom structure
}
} m_config;
//libmixer datatypes
typedef void * CellAANHandle;
struct CellSSPlayerConfig
{
be_t<u32> channels;
be_t<u32> outputMode;
};
struct CellSSPlayerWaveParam
{
void *addr;
be_t<s32> format;
be_t<u32> samples;
be_t<u32> loopStartOffset;
be_t<u32> startOffset;
};
struct CellSSPlayerCommonParam
{
be_t<u32> loopMode;
be_t<u32> attackMode;
};
struct CellSurMixerPosition
{
be_t<float> x;
be_t<float> y;
be_t<float> z;
};
struct CellSSPlayerRuntimeInfo
{
be_t<float> level;
be_t<float> speed;
CellSurMixerPosition position;
};
struct CellSurMixerConfig
{
be_t<s32> priority;
be_t<u32> chStrips1;
be_t<u32> chStrips2;
be_t<u32> chStrips6;
be_t<u32> chStrips8;
};
struct CellSurMixerChStripParam
{
be_t<u32> param;
void *attribute;
be_t<s32> dBSwitch;
be_t<float> floatVal;
be_t<s32> intVal;
};
CellSSPlayerWaveParam current_SSPlayerWaveParam;
//libsnd3 datatypes
struct CellSnd3DataCtx
{
@ -368,7 +309,7 @@ int cellAudioInit()
memset(Memory + buf_addr, 0, block_size * sizeof(float));
{
SMutexLocker lock(port.m_mutex);
SMutexGeneralLocker lock(port.m_mutex);
port.counter = m_config.counter;
port.tag++; // absolute index of block that will be read
index = (position + 1) % port.block; // write new value
@ -621,7 +562,7 @@ int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp)
AudioPortConfig& port = m_config.m_ports[portNum];
SMutexLocker lock(port.m_mutex);
SMutexGeneralLocker lock(port.m_mutex);
stamp = m_config.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000;
@ -655,7 +596,7 @@ int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag)
return CELL_AUDIO_ERROR_PARAM;
}
SMutexLocker lock(port.m_mutex);
SMutexGeneralLocker lock(port.m_mutex);
u64 tag_base = port.tag;
if (tag_base % port.block > blockNo)
@ -796,168 +737,6 @@ int cellAudioUnsetPersonalDevice(int iPersonalStream)
return CELL_OK;
}
//Callback Functions
typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused.
// libmixer Functions, NOT active in this moment
int cellAANConnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo)
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellAANDisconnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo)
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellAANAddData(CellAANHandle handle, u32 port, u32 offset, float *addr, u32 samples)
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config)
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSSPlayerRemove(CellAANHandle handle)
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSSPlayerStop() //CellAANHandle handle, u32 mode
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
s32 cellSSPlayerGetState() //CellAANHandle handle
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerCreate() //const CellSurMixerConfig *config
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerGetAANHandle() //CellAANHandle *handle
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerChStripGetAANPortNo() //u32 *port, u32 type, u32 index
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerSetNotifyCallback() //CellSurMixerNotifyCallbackFunction callback, void *arg
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerRemoveNotifyCallback() //CellSurMixerNotifyCallbackFunction callback
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerStart()
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerSetParameter() //u32 param, float value
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerPause() //u32 switch
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerGetCurrentBlockTag() //u64 *tag
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp
{
UNIMPLEMENTED_FUNC(cellAudio);
return 0;
}
void cellSurMixerBeep(); //void *arg
float cellSurMixerUtilGetLevelFromDB() //float dB
{
UNIMPLEMENTED_FUNC(cellAudio);
return CELL_OK; //it's NOT real value
//TODO;
}
float cellSurMixerUtilGetLevelFromDBIndex() //int index
{
UNIMPLEMENTED_FUNC(cellAudio);
return CELL_OK; //it's NOT real value
//TODO;
}
float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note
{
UNIMPLEMENTED_FUNC(cellAudio);
return CELL_OK; //it's NOT real value
//TODO
}
int cellSurMixerFinalize(); //Currently unused. Returns 0 (in the current release).
//*libsnd3 Functions, NOT active in this moment
s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue
{
@ -1399,14 +1178,7 @@ void cellAudio_init()
//TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions
}
void cellAudio_load()
{
m_config.m_is_audio_initialized = false;
m_config.Clear();
}
void cellAudio_unload()
{
m_config.m_is_audio_initialized = false;
m_config.Clear();
//StaticFinalize();
}

View file

@ -52,6 +52,9 @@ u32 dmuxOpen(Demuxer* data)
u32 cb_add = 0;
u32 updates_count = 0;
u32 updates_signaled = 0;
while (true)
{
if (Emu.IsStopped())
@ -68,9 +71,17 @@ u32 dmuxOpen(Demuxer* data)
if (!stream.peek(code))
{
dmux.is_running = false;
// demuxing finished
task.type = dmuxResetStream;
goto task;
mem_ptr_t<CellDmuxMsg> dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16));
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
dmuxMsg->supplementalInfo = stream.userdata;
/*Callback cb;
cb.SetAddr(dmux.cbFunc);
cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, true, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
updates_signaled++;
}
else switch (code.ToLE())
{
@ -125,11 +136,14 @@ u32 dmuxOpen(Demuxer* data)
if (esATX[ch])
{
ElementaryStream& es = *esATX[ch];
if (es.isfull())
while (es.isfull())
{
stream = backup;
if (Emu.IsStopped())
{
ConLog.Warning("esATX[%d] was full, waiting aborted", ch);
return;
}
Sleep(1);
continue;
}
//ConLog.Write("*** AT3+ AU sent (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts);
@ -163,10 +177,14 @@ u32 dmuxOpen(Demuxer* data)
if (esAVC[ch])
{
ElementaryStream& es = *esAVC[ch];
if (es.isfull())
while (es.isfull())
{
if (Emu.IsStopped())
{
ConLog.Warning("esAVC[%d] was full, waiting aborted", ch);
return;
}
Sleep(1);
continue;
}
DemuxerStream backup = stream;
@ -177,11 +195,11 @@ u32 dmuxOpen(Demuxer* data)
if (pes.new_au && es.hasdata()) // new AU detected
{
if (es.hasunseen()) // hack, probably useless
/*if (es.hasunseen()) // hack, probably useless
{
stream = backup;
continue;
}
}*/
es.finish(stream);
// callback
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
@ -257,24 +275,11 @@ u32 dmuxOpen(Demuxer* data)
{
break; // Emu is stopped
}
task:
switch (task.type)
{
case dmuxSetStream:
{
bool do_wait = false;
for (u32 i = 0; i < 192; i++)
{
if (esALL[i])
{
if (esALL[i]->hasunseen()) // hack, probably useless
{
do_wait = true;
break;
}
}
}
if (do_wait) continue;
stream = task.stream;
ConLog.Write("*** stream updated(addr=0x%x, size=0x%x, discont=%d, userdata=0x%llx)",
stream.addr, stream.size, stream.discontinuity, stream.userdata);
@ -285,6 +290,7 @@ task:
esALL[i]->reset();
}
}
updates_count++;
dmux.is_running = true;
}
break;
@ -292,7 +298,6 @@ task:
case dmuxResetStream:
case dmuxResetStreamAndWaitDone:
{
// TODO: send CELL_DMUX_MSG_TYPE_DEMUX_DONE callback and provide waiting condition
mem_ptr_t<CellDmuxMsg> dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16));
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
dmuxMsg->supplementalInfo = stream.userdata;
@ -302,6 +307,7 @@ task:
cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone,
dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
updates_signaled++;
dmux.is_running = false;
}
break;
@ -578,10 +584,15 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize
return CELL_DMUX_ERROR_FATAL;
}
if (dmux->is_running)
while (dmux->is_running) // hack
{
Sleep(1); // performance hack
return CELL_DMUX_ERROR_BUSY;
if (Emu.IsStopped())
{
ConLog.Warning("cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle);
break;
}
Sleep(1);
//return CELL_DMUX_ERROR_BUSY;
}
DemuxerTask task(dmuxSetStream);

View file

@ -0,0 +1,404 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
#include "libmixer.h"
void libmixer_init();
Module libmixer("libmixer", libmixer_init);
int cellAANAddData(u32 handle, u32 port, u32 offset, u32 addr, u32 samples)
{
libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)",
handle, port, offset, addr, samples);
return CELL_OK;
}
// libmixer Functions, NOT active in this moment
/*int cellAANConnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo)
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellAANDisconnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo)
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config)
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSSPlayerRemove(CellAANHandle handle)
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSSPlayerStop() //CellAANHandle handle, u32 mode
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
s32 cellSSPlayerGetState() //CellAANHandle handle
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}*/
int cellSurMixerCreate(const mem_ptr_t<CellSurMixerConfig> config)
{
libmixer.Error("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr());
return CELL_OK;
}
int cellSurMixerGetAANHandle(mem32_t handle)
{
libmixer.Error("cellSurMixerGetAANHandle(handle_addr=0x%x)", handle.GetAddr());
return CELL_OK;
}
int cellSurMixerChStripGetAANPortNo(mem32_t port, u32 type, u32 index)
{
libmixer.Error("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x)", port.GetAddr(), type, index);
return CELL_OK;
}
int cellSurMixerSetNotifyCallback(u32 func, u32 arg)
{
libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg);
return CELL_OK;
}
int cellSurMixerRemoveNotifyCallback(u32 func)
{
libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func);
return CELL_OK;
}
int cellSurMixerStart()
{
libmixer.Error("cellSurMixerStart()");
return CELL_OK;
}
int cellSurMixerSetParameter(u32 param, float value)
{
libmixer.Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value);
return CELL_OK;
}
int cellSurMixerFinalize()
{
libmixer.Error("cellSurMixerFinalize()");
return CELL_OK;
}
/*int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSurMixerPause() //u32 switch
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSurMixerGetCurrentBlockTag() //u64 *tag
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp
{
UNIMPLEMENTED_FUNC(libmixer);
return 0;
}
void cellSurMixerBeep(); //void *arg
float cellSurMixerUtilGetLevelFromDB() //float dB
{
UNIMPLEMENTED_FUNC(libmixer);
return CELL_OK; //it's NOT real value
//TODO;
}
float cellSurMixerUtilGetLevelFromDBIndex() //int index
{
UNIMPLEMENTED_FUNC(libmixer);
return CELL_OK; //it's NOT real value
//TODO;
}
float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note
{
UNIMPLEMENTED_FUNC(libmixer);
return CELL_OK; //it's NOT real value
//TODO
}*/
void libmixer_init()
{
static const u64 cellAANAddData_table[] = {
// TODO
0xffffffff7c691b78,
0xffffffff7c0802a6,
0xfffffffff821ff91,
0xfffffffff8010080,
0xffffffff7c802378,
0xffffffff7caa2b78,
0xffffffff81690000,
0xffffffff7c050378,
0xffffffff7cc43378,
// 78 63 00 20 clrldi r3,r3,32 # 20 // may be included
0xffffffff7d465378,
0xffffffff812b0030,
0xffffffff80090000,
0xfffffffff8410028,
0xffffffff7c0903a6,
0xffffffff80490004,
0xffffffff4e800421,
0xffffffffe8410028,
0xffffffffe8010080,
0xffffffff7c6307b4,
0xffffffff7c0803a6,
0xffffffff38210070,
0xffffffff4e800020,
0
};
libmixer.AddFuncSub(cellAANAddData_table, "cellAANAddData", cellAANAddData);
static const u64 cellSurMixerCreate_table[] = {
0xffffffff2f830000,
0xffffffff7c0802a6,
0xfffffffff821ff51,
0xfffffffffbc100a0,
0xfffffffffb210078,
0xfffffffffb410080,
0xfffffffffb610088,
0xfffffffffb810090,
0xfffffffffba10098,
0xfffffffffbe100a8,
0xfffffffff80100c0,
0xffffffff7c7e1b78,
0xf000000040000000, // bne
0xffffffff3fe08031,
0xffffffff63ff0003,
0xffffffffe80100c0,
0xffffffff7fe307b4,
0xffffffffeb210078,
0xffffffffeb410080,
0xffffffff7c0803a6,
0xffffffffeb610088,
0xffffffffeb810090,
0xffffffffeba10098,
0xffffffffebc100a0,
0xffffffffebe100a8,
0xffffffff382100b0,
0
};
libmixer.AddFuncSub(cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate);
static const u64 cellSurMixerGetAANHandle_table[] = {
// first instruction ignored
0xffffffff3d607fce,
0xffffffff616bfffe,
0xffffffff812a0018,
0xffffffff7d2afe70,
0xffffffff91230000,
0xffffffff7d404a78,
0xffffffff7c005050,
0xffffffff7c00fe70,
0xffffffff7c035838,
0xffffffff3c638031,
0xffffffff38630002,
0xffffffff7c6307b4,
0xffffffff4e800020,
0
};
libmixer.AddFuncSub(cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle);
static const u64 cellSurMixerChStripGetAANPortNo_table[] = {
// first instruction ignored
0xffffffff7c661b78,
0xffffffff3c608031,
0xffffffff78c60020,
0xffffffff78840020,
0xffffffff60630002,
0xffffffff80090018,
0xffffffff78a50020,
0xffffffff2f800000,
0xffffffff4d9e0020,
0xffffffff78030020,
0xf000000040000000, // b
0
};
libmixer.AddFuncSub(cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo);
static const u64 cellSurMixerSetNotifyCallback_table[] = {
// first instruction ignored
0xffffffff7c0802a6,
0xfffffffff821ff81,
0xfffffffff8010090,
0xffffffff7c6b1b78,
0xffffffff3c608031,
0xffffffff812a0018,
0xffffffff7c882378,
0xffffffff60630003,
0xffffffff2f890000,
0xffffffff2f0b0000,
0xffffff00409e0020, // bne
0xffffffff3c608031,
0xffffffff60630002,
0xffffffffe8010090,
0xffffffff7c6307b4,
0xffffffff38210080,
0xffffffff7c0803a6,
0xffffffff4e800020,
0xffffff00419affec, // beq
0xf0000000800a001c, // lwz
0xffffffff79290020,
0xffffffff38810070,
0xffffffff2f800000,
0xffffffff7d234b78,
0
};
libmixer.AddFuncSub(cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback);
static const u64 cellSurMixerRemoveNotifyCallback_table[] = {
// first instruction ignored
0xffffffff7c0802a6,
0xfffffffff821ff81,
0xfffffffff8010090,
0xffffffff7c6a1b78,
0xffffffff3d208031,
0xffffffff806b0018,
0xffffffff61290002,
0xffffffff2f830000,
0xf0000000409e0018, // bne
0xffffffffe8010090,
0xffffffff7d2307b4,
0xffffffff38210080,
0xffffffff7c0803a6,
0xffffffff4e800020,
0
};
libmixer.AddFuncSub(cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback);
static const u64 cellSurMixerStart_table[] = {
0xfffffffff821ff71,
0xffffffff7c0802a6,
0xfffffffffbc10080,
0xf000000083c20000, // lwz
0xfffffffff80100a0,
0xfffffffffba10078,
0xfffffffffbe10088,
0xffffffff801e0018,
0xffffffff2f800000,
0xf0000000409e002c, // bne
0xffffffff3fe08031,
0xffffffff63ff0002,
0xffffffffe80100a0,
0xffffffff7fe307b4,
0xffffffffeba10078,
0xffffffffebc10080,
0xffffffff7c0803a6,
0xffffffffebe10088,
0xffffffff38210090,
0xffffffff4e800020,
0
};
libmixer.AddFuncSub(cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart);
static const u64 cellSurMixerSetParameter_table[] = {
0xfffffffff821ff81,
0xffffffff7c0802a6,
0xfffffffffbc10070,
0xfffffffffc000890,
0xf000000083c28250, // lwz
0xffffffff3d208031,
0xfffffffff8010090,
0xfffffffffbe10078,
0xffffffff61290002,
0xffffffff7c7f1b78,
0xffffffff801e0018,
0xffffffff2f800000,
0xffff0000409e0020, // bne
0xffffffffe8010090,
0xffffffff7d2307b4,
0xffffffffebc10070,
0xffffffffebe10078,
0xffffffff7c0803a6,
0xffffffff38210080,
0xffffffff4e800020,
0xffffffff801e001c,
0xffffffff2b03001f,
0xffffffff2f800000,
0xffff0000419cffd8, // blt
0xffffffff2b83002b,
0xffff000040990008, // ble
0xffff0000409d0054, // ble
0
};
libmixer.AddFuncSub(cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter);
static const u64 cellSurMixerFinalize_table[] = {
0xfffffffff821ff91,
0xffffffff7c0802a6,
0xfffffffff8010080,
0xffffff004bfffde1, // bl
0xffffffffe8010080,
0xffffffff38600000,
0xffffffff38210070,
0xffffffff7c0803a6,
0xffffffff4e800020,
0xfffffffff821ff71,
0xffffffff7c0802a6,
0xfffffffffba10078,
0xf000000083a28250, // lwz
0xfffffffff80100a0,
0xffffffff817d0018,
0xffffffff7d635b78,
0xffffffff812b0000,
0xffffffff81490000,
0xffffffff800a0000,
0xfffffffff8410028,
0xffffffff7c0903a6,
0xffffffff804a0004,
0xffffffff4e800421,
0
};
libmixer.AddFuncSub(cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize);
}

View file

@ -0,0 +1,63 @@
#pragma once
//Callback Functions
typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused.
//libmixer datatypes
typedef void * CellAANHandle;
struct CellSSPlayerConfig
{
be_t<u32> channels;
be_t<u32> outputMode;
};
struct CellSSPlayerWaveParam
{
void *addr;
be_t<s32> format;
be_t<u32> samples;
be_t<u32> loopStartOffset;
be_t<u32> startOffset;
};
struct CellSSPlayerCommonParam
{
be_t<u32> loopMode;
be_t<u32> attackMode;
};
struct CellSurMixerPosition
{
be_t<float> x;
be_t<float> y;
be_t<float> z;
};
struct CellSSPlayerRuntimeInfo
{
be_t<float> level;
be_t<float> speed;
CellSurMixerPosition position;
};
struct CellSurMixerConfig
{
be_t<s32> priority;
be_t<u32> chStrips1;
be_t<u32> chStrips2;
be_t<u32> chStrips6;
be_t<u32> chStrips8;
};
struct CellSurMixerChStripParam
{
be_t<u32> param;
void *attribute;
be_t<s32> dBSwitch;
be_t<float> floatVal;
be_t<s32> intVal;
};
CellSSPlayerWaveParam current_SSPlayerWaveParam;

View file

@ -0,0 +1,63 @@
#include "stdafx.h"
#include "Modules.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
extern ArrayF<SFunc> g_static_funcs_list;
void StaticAnalyse(void* ptr, u32 size)
{
u32* data = (u32*)ptr; size /= 4;
// TODO: optimize search
for (u32 i = 0; i < size; i++)
{
for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++)
{
if ((data[i] & g_static_funcs_list[j].ops[0].mask) == g_static_funcs_list[j].ops[0].crc && (i + g_static_funcs_list[j].ops.GetCount()) < size)
{
bool found = true;
for (u32 k = i + 1, x = 1; x < g_static_funcs_list[j].ops.GetCount(); k++, x++)
{
// skip NOP
if (data[k] == se32(0x60000000))
{
k++;
continue;
}
if ((data[k] & g_static_funcs_list[j].ops[x].mask) != g_static_funcs_list[j].ops[x].crc)
{
found = false;
break;
}
}
if (found)
{
ConLog.Success("Function '%s' hooked", wxString(g_static_funcs_list[j].name).wx_str());
data[i] = re(0x39600000 | j); // li r11, j
data[i+1] = se32(0x44000003); // sc 3
data[i+2] = se32(0x4e800020); // blr
i += g_static_funcs_list[j].ops.GetCount(); // ???
}
}
}
}
}
void StaticExecute(u32 code)
{
if (code < g_static_funcs_list.GetCount())
{
(*g_static_funcs_list[code].func)();
}
else
{
ConLog.Error("StaticExecute(%d): unknown function or illegal opcode", code);
}
}
void StaticFinalize()
{
g_static_funcs_list.Clear();
}

View file

@ -433,3 +433,7 @@ public:
};
//extern SysCalls SysCallsManager;
void StaticAnalyse(void* ptr, u32 size);
void StaticExecute(u32 code);
void StaticFinalize();

View file

@ -57,7 +57,7 @@ int sys_lwmutex_destroy(mem_ptr_t<sys_lwmutex_t> lwmutex)
{
case CELL_OK:
lwmutex->all_info() = 0;
lwmutex->attribute = 0;
lwmutex->attribute = 0xDEADBEEF;
lwmutex->sleep_queue = 0;
Emu.GetIdManager().RemoveID(sq_id);
default: return res;
@ -205,7 +205,17 @@ bool SleepQueue::finalize()
int sys_lwmutex_t::trylock(be_t<u32> tid)
{
if (!attribute.ToBE()) return CELL_EINVAL;
if (attribute.ToBE() == se32(0xDEADBEEF)) return CELL_EINVAL;
while ((attribute.ToBE() & se32(SYS_SYNC_ATTR_RECURSIVE_MASK)) == 0)
{
if (Emu.IsStopped())
{
ConLog.Warning("(hack) sys_lwmutex_t::trylock aborted (waiting for recursive attribute, attr=0x%x)", (u32)attribute);
return CELL_ESRCH;
}
Sleep(1);
}
if (tid == mutex.GetOwner())
{

View file

@ -52,12 +52,12 @@ int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 1);
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 1);
addr = Memory.Alloc(size, 0x10000);
break;
default: return CELL_EINVAL;

View file

@ -37,7 +37,12 @@ int sys_mutex_create(mem32_t mutex_id, mem_ptr_t<sys_mutex_attribute> attr)
return CELL_EINVAL;
}
mutex_id = sys_mtx.GetNewId(new Mutex((u32)attr->protocol, is_recursive, attr->name_u64));
u32 tid = GetCurrentPPUThread().GetId();
Mutex* mutex = new Mutex((u32)attr->protocol, is_recursive, attr->name_u64);
u32 id = sys_mtx.GetNewId(mutex);
mutex->m_mutex.lock(tid);
mutex_id = id;
mutex->m_mutex.unlock(tid);
sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d",
wxString(attr->name, 8).wx_str(), (u32)attr->protocol,
wxString(is_recursive ? "true" : "false").wx_str(), mutex_id.GetValue());

View file

@ -246,6 +246,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset)
{
elf64_f.Seek(phdr_arr[i].p_offset);
elf64_f.Read(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz);
StaticAnalyse(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz);
}
}
break;

View file

@ -301,11 +301,13 @@
<ClCompile Include="Emu\SysCalls\Modules\cellSysutilAp.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellVdec.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellVpost.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\libmixer.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sceNp.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sceNpTrophy.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sys_fs.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sys_io.cpp" />
<ClCompile Include="Emu\SysCalls\Static.cpp" />
<ClCompile Include="Emu\SysCalls\SysCalls.cpp" />
<ClCompile Include="Emu\System.cpp" />
<ClCompile Include="Gui\CompilerELF.cpp" />

View file

@ -436,6 +436,12 @@
<ClCompile Include="Crypto\utils.cpp">
<Filter>Crypto</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Static.cpp">
<Filter>Emu\SysCalls</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Modules\libmixer.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />