- Improved sc function binder.

- Improved GLGSRender.
This commit is contained in:
DH 2013-06-30 11:46:29 +03:00
parent 3bb7a299ca
commit 5753edf6ef
133 changed files with 13624 additions and 3898 deletions

View File

@ -23,6 +23,7 @@ public:
const u32 to = from + count;
if(to > GetCount()) return false;
for(u32 i=0; i<count; ++i) m_array[from + i].~T();
memmove(m_array + from, m_array + to, (m_count-to) * sizeof(T));
m_count -= count;
@ -44,57 +45,71 @@ public:
return true;
}
bool Insert(const u32 pos, T* data)
{
if(!InsertRoom(pos, 1)) return false;
memmove(m_array + pos, data, sizeof(T));
return true;
}
bool Insert(const u32 pos, T& data)
{
return Insert(pos, &data);
}
bool InsertCpy(const u32 pos, const T* data)
inline bool Move(const u32 pos, T* data)
{
if(!InsertRoom(pos, 1)) return false;
memcpy(m_array + pos, data, sizeof(T));
free(data);
return true;
}
bool InsertCpy(const u32 pos, const T& data)
{
return InsertCpy(pos, &data);
}
inline u32 Add(T* data)
{
_InsertRoomEnd(1);
memmove(m_array + GetCount() - 1, data, sizeof(T));
return m_count - 1;
}
inline u32 Add(T& data)
{
return Add(&data);
}
inline u32 AddCpy(const T* data)
inline u32 Move(T* data)
{
_InsertRoomEnd(1);
memcpy(m_array + GetCount() - 1, data, sizeof(T));
free(data);
return m_count - 1;
}
inline bool Add(const u32 pos, T*& data)
{
if(!InsertRoom(pos, 1)) return false;
memcpy(m_array + pos, data, sizeof(T));
free(data);
data = m_array + pos;
return true;
}
inline u32 Add(T*& data)
{
_InsertRoomEnd(1);
memcpy(m_array + GetCount() - 1, data, sizeof(T));
free(data);
data = m_array + GetCount() - 1;
return m_count - 1;
}
inline bool AddCpy(const u32 pos, const T* data, u64 count = 1)
{
if(!InsertRoom(pos, count)) return false;
memcpy(m_array + pos, data, sizeof(T) * count);
return true;
}
inline bool AddCpy(const u32 pos, const T& data)
{
return AddCpy(pos, &data);
}
inline u32 AddCpy(const T* data, u64 count = 1)
{
_InsertRoomEnd(count);
memcpy(m_array + m_count - count, data, sizeof(T)*count);
return m_count - count;
}
inline u32 AddCpy(const T& data)
{
return AddCpy(&data);
@ -102,7 +117,9 @@ public:
inline void Clear()
{
u32 count = m_count;
m_count = 0;
for(u32 i=0; i<count; ++i) m_array[i].~T();
safe_delete(m_array);
}
@ -144,8 +161,20 @@ public:
AppendFrom(src);
}
inline T* GetPtr() { return m_array; }
T& operator[](u32 num) const { return m_array[num]; }
T* operator + (u32 right) const
{
return m_array + right;
}
T* operator ->()
{
return m_array;
}
protected:
void _InsertRoomEnd(const u32 size)
{
@ -180,7 +209,6 @@ template<typename T> struct Stack : public Array<T>
}
};
template<typename T> class ArrayF
{
u32 m_count;
@ -193,7 +221,7 @@ public:
{
}
~ArrayF()
virtual ~ArrayF()
{
Clear();
}
@ -262,6 +290,53 @@ public:
return *m_array[num];
}
T** operator + (u32 right) const
{
return m_array + right;
}
T* operator ->()
{
return *m_array;
}
inline T** GetPtr()
{
return m_array;
}
inline u32 GetCount() const { return m_count; }
T& operator[](u32 num) const { return *m_array[num]; }
};
template<typename T> struct ScopedPtr
{
private:
T* m_ptr;
public:
ScopedPtr() : m_ptr(nullptr)
{
}
ScopedPtr(T* ptr) : m_ptr(ptr)
{
}
~ScopedPtr()
{
Swap(nullptr);
}
operator T*() { return m_ptr; }
operator const T*() const { return m_ptr; }
T* operator ->() { return m_ptr; }
const T* operator ->() const { return m_ptr; }
void Swap(T* ptr)
{
delete m_ptr;
m_ptr = ptr;
}
};

View File

@ -128,7 +128,7 @@ public:
id.m_used = false;
id.m_attr = 0;
id.m_name.Clear();
if(free_data) free(id.m_data);
if(free_data) delete id.m_data;
id.m_data = NULL;
if(IDToNum(_id) == IDs.GetCount()-1) Cleanup();
return true;

View File

@ -1,6 +1,19 @@
#include "stdafx.h"
#include "Thread.h"
ThreadBase* GetCurrentNamedThread()
{
ThreadExec* thr = (ThreadExec*)::wxThread::This();
return thr ? thr->m_parent : nullptr;
}
ThreadBase::ThreadBase(bool detached, const wxString& name)
: m_detached(detached)
, m_name(name)
, m_executor(nullptr)
{
}
void ThreadBase::Start()
{
if(m_executor) return;
@ -8,22 +21,77 @@ void ThreadBase::Start()
m_executor = new ThreadExec(m_detached, this);
}
void ThreadBase::Resume()
{
if(m_executor)
{
m_executor->Resume();
}
}
void ThreadBase::Pause()
{
if(m_executor)
{
m_executor->Pause();
}
}
void ThreadBase::Stop(bool wait)
{
if(!m_executor) return;
ThreadExec* exec = m_executor;
m_executor = nullptr;
exec->Stop(wait);
if(!m_detached)
{
if(wait)
{
exec->Wait();
}
exec->Stop(false);
delete exec;
}
else
{
exec->Stop(wait);
}
}
bool ThreadBase::IsAlive()
bool ThreadBase::Wait() const
{
return m_executor != nullptr && m_executor->Wait() != (wxThread::ExitCode)-1;
}
bool ThreadBase::IsRunning() const
{
return m_executor != nullptr && m_executor->IsRunning();
}
bool ThreadBase::IsPaused() const
{
return m_executor != nullptr && m_executor->IsPaused();
}
bool ThreadBase::IsAlive() const
{
return m_executor != nullptr;
}
bool ThreadBase::TestDestroy()
bool ThreadBase::TestDestroy() const
{
if(!m_executor) return true;
if(!m_executor || !m_executor->m_parent) return true;
return m_executor->TestDestroy();
}
wxString ThreadBase::GetThreadName() const
{
return m_name;
}
void ThreadBase::SetThreadName(const wxString& name)
{
m_name = name;
}

View File

@ -9,33 +9,41 @@ protected:
wxString m_name;
bool m_detached;
public:
wxMutex m_main_mutex;
protected:
ThreadBase(bool detached = true, const wxString& name = "Unknown ThreadBase")
: m_detached(detached)
, m_name(name)
, m_executor(nullptr)
{
}
ThreadBase(bool detached = true, const wxString& name = "Unknown ThreadBase");
public:
ThreadExec* m_executor;
virtual void Task()=0;
void Start();
void Stop(bool wait = true);
virtual void Start();
virtual void Resume();
virtual void Pause();
virtual void Stop(bool wait = true);
bool IsAlive();
bool TestDestroy();
virtual bool Wait() const;
virtual bool IsRunning() const;
virtual bool IsPaused() const;
virtual bool IsAlive() const;
virtual bool TestDestroy() const;
virtual wxString GetThreadName() const;
virtual void SetThreadName(const wxString& name);
};
ThreadBase* GetCurrentNamedThread();
class ThreadExec : public wxThread
{
ThreadBase* m_parent;
wxSemaphore m_wait_for_exit;
wxCriticalSection m_wait_for_exit;
volatile bool m_alive;
public:
ThreadBase* m_parent;
ThreadExec(bool detached, ThreadBase* parent)
: wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE)
, m_parent(parent)
@ -50,20 +58,26 @@ public:
if(!m_alive) return;
m_parent = nullptr;
Delete();
if(wait && m_alive) m_wait_for_exit.Wait();
//if(wait)
{
Delete();
//wxCriticalSectionLocker lock(m_wait_for_exit);
}
}
ExitCode Entry()
{
//wxCriticalSectionLocker lock(m_wait_for_exit);
m_parent->Task();
m_alive = false;
m_wait_for_exit.Post();
if(m_parent) m_parent->m_executor = nullptr;
return (ExitCode)0;
}
};
//ThreadBase* GetCurrentThread();
template<typename T> class MTPacketBuffer
{
protected:
@ -71,6 +85,7 @@ protected:
volatile u32 m_put, m_get;
Array<u8> m_buffer;
u32 m_max_buffer_size;
mutable wxCriticalSection m_cs_main;
void CheckBusy()
{
@ -91,18 +106,43 @@ public:
void Flush()
{
wxCriticalSectionLocker lock(m_cs_main);
m_put = m_get = 0;
m_buffer.Clear();
m_busy = false;
}
virtual void Push(const T& v) = 0;
virtual T Pop() = 0;
private:
virtual void _push(const T& v) = 0;
virtual T _pop() = 0;
bool HasNewPacket() const { return m_put != m_get; }
public:
void Push(const T& v)
{
wxCriticalSectionLocker lock(m_cs_main);
_push(v);
}
T Pop()
{
wxCriticalSectionLocker lock(m_cs_main);
return _pop();
}
bool HasNewPacket() const { wxCriticalSectionLocker lock(m_cs_main); return m_put != m_get; }
bool IsBusy() const { return m_busy; }
};
static __forceinline bool SemaphorePostAndWait(wxSemaphore& sem)
{
if(sem.TryWait() != wxSEMA_BUSY) return false;
sem.Post();
sem.Wait();
return true;
}
/*
class StepThread : public ThreadBase
{

1
bin/make_fself.cmd Normal file
View File

@ -0,0 +1 @@
make_fself compiled.elf EBOOT.BIN

422
rpcs3.sln
View File

@ -2,60 +2,60 @@ Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxproj", "{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}"
ProjectSection(ProjectDependencies) = postProject
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34} = {2E26269D-8BFC-1A93-FD6E-E0CA16399B34}
{DB839A56-59B6-6430-99A9-51D08C6E33FD} = {DB839A56-59B6-6430-99A9-51D08C6E33FD}
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30} = {FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}
{0366B8AE-9D7B-A940-458C-A6B131A12AC8} = {0366B8AE-9D7B-A940-458C-A6B131A12AC8}
{B87F7202-6FA6-FC01-14FE-E92CE882F85B} = {B87F7202-6FA6-FC01-14FE-E92CE882F85B}
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214} = {3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171} = {506026B2-9FD9-7F39-6E6E-55E0C2C8C171}
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495} = {B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99} = {E1973C7F-F026-4596-C19D-6C8FBFAD2C99}
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA} = {7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}
{54994EB2-0674-8592-CF85-8E201FE680E2} = {54994EB2-0674-8592-CF85-8E201FE680E2}
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04} = {7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}
{156E1310-DA46-F664-E3C1-EE90B4CD92AE} = {156E1310-DA46-F664-E3C1-EE90B4CD92AE}
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF} = {90A67BD5-253F-CD50-BB9E-7002DA7D35CF}
{032DB7F5-755A-DF9E-5CBE-553BF92898EC} = {032DB7F5-755A-DF9E-5CBE-553BF92898EC}
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85} = {A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}
{7C123413-10B1-F29F-EEE5-B57A36827C70} = {7C123413-10B1-F29F-EEE5-B57A36827C70}
{F8EC63A1-40C4-541B-911E-3679CCA1132D} = {F8EC63A1-40C4-541B-911E-3679CCA1132D}
{CF3420B3-B31E-FDD0-4897-648FD5125566} = {CF3420B3-B31E-FDD0-4897-648FD5125566}
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6} = {8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B} = {0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}
{350261DE-995E-5363-B942-85B09B015F2B} = {350261DE-995E-5363-B942-85B09B015F2B}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wxWidgets", "wxWidgets", "{5812E712-6213-4372-B095-9EB9BAA1F2DF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adv", "wxWidgets\build\msw\wx_adv.vcxproj", "{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adv", "wxWidgets\build\msw\wx_adv.vcxproj", "{7C123413-10B1-F29F-EEE5-B57A36827C70}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aui", "wxWidgets\build\msw\wx_aui.vcxproj", "{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aui", "wxWidgets\build\msw\wx_aui.vcxproj", "{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "wxWidgets\build\msw\wx_base.vcxproj", "{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "wxWidgets\build\msw\wx_base.vcxproj", "{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "wxWidgets\build\msw\wx_core.vcxproj", "{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "wxWidgets\build\msw\wx_core.vcxproj", "{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbgrid", "wxWidgets\build\msw\wx_dbgrid.vcxproj", "{13138455-15D7-0F02-57C4-083FE663B876}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbgrid", "wxWidgets\build\msw\wx_dbgrid.vcxproj", "{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gl", "wxWidgets\build\msw\wx_gl.vcxproj", "{B87F7202-6FA6-FC01-14FE-E92CE882F85B}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gl", "wxWidgets\build\msw\wx_gl.vcxproj", "{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "html", "wxWidgets\build\msw\wx_html.vcxproj", "{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "html", "wxWidgets\build\msw\wx_html.vcxproj", "{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "media", "wxWidgets\build\msw\wx_media.vcxproj", "{03F61B23-19D0-F1E9-18D0-51504E42CC12}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "media", "wxWidgets\build\msw\wx_media.vcxproj", "{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "wxWidgets\build\msw\wx_net.vcxproj", "{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "wxWidgets\build\msw\wx_net.vcxproj", "{995774A7-FA69-E03D-1759-A4C33AE7FF7C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc", "wxWidgets\build\msw\wx_odbc.vcxproj", "{A0EBB666-81D6-8FDE-6279-E42B597CE104}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc", "wxWidgets\build\msw\wx_odbc.vcxproj", "{EE9EE1EA-E48D-7B28-2825-6F014802A43B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qa", "wxWidgets\build\msw\wx_qa.vcxproj", "{6A708533-20DB-79A7-1DB4-B8DC76D5A105}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qa", "wxWidgets\build\msw\wx_qa.vcxproj", "{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "richtext", "wxWidgets\build\msw\wx_richtext.vcxproj", "{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "richtext", "wxWidgets\build\msw\wx_richtext.vcxproj", "{DCF03EA6-9806-338B-3B07-60273468D4A9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxexpat", "wxWidgets\build\msw\wx_wxexpat.vcxproj", "{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxexpat", "wxWidgets\build\msw\wx_wxexpat.vcxproj", "{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxjpeg", "wxWidgets\build\msw\wx_wxjpeg.vcxproj", "{DB839A56-59B6-6430-99A9-51D08C6E33FD}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxjpeg", "wxWidgets\build\msw\wx_wxjpeg.vcxproj", "{156E1310-DA46-F664-E3C1-EE90B4CD92AE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxpng", "wxWidgets\build\msw\wx_wxpng.vcxproj", "{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxpng", "wxWidgets\build\msw\wx_wxpng.vcxproj", "{CF3420B3-B31E-FDD0-4897-648FD5125566}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxregex", "wxWidgets\build\msw\wx_wxregex.vcxproj", "{0366B8AE-9D7B-A940-458C-A6B131A12AC8}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxregex", "wxWidgets\build\msw\wx_wxregex.vcxproj", "{032DB7F5-755A-DF9E-5CBE-553BF92898EC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxtiff", "wxWidgets\build\msw\wx_wxtiff.vcxproj", "{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxtiff", "wxWidgets\build\msw\wx_wxtiff.vcxproj", "{F8EC63A1-40C4-541B-911E-3679CCA1132D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxzlib", "wxWidgets\build\msw\wx_wxzlib.vcxproj", "{54994EB2-0674-8592-CF85-8E201FE680E2}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxzlib", "wxWidgets\build\msw\wx_wxzlib.vcxproj", "{350261DE-995E-5363-B942-85B09B015F2B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "wxWidgets\build\msw\wx_xml.vcxproj", "{D047D758-2B7F-D39A-B387-01064479E2DA}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "wxWidgets\build\msw\wx_xml.vcxproj", "{503E4C3C-5D61-7928-7745-526C6EE2646F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "wxWidgets\build\msw\wx_xrc.vcxproj", "{F0D3A651-E58B-6E40-75DA-0882C2B5F987}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "wxWidgets\build\msw\wx_xrc.vcxproj", "{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -73,190 +73,190 @@ Global
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release|Win32.Build.0 = Release|Win32
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release|x64.ActiveCfg = Release|x64
{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}.Release|x64.Build.0 = Release|x64
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Debug|Win32.ActiveCfg = Debug|Win32
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Debug|Win32.Build.0 = Debug|Win32
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Debug|x64.ActiveCfg = Debug|x64
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Debug|x64.Build.0 = Debug|x64
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Release|Win32.ActiveCfg = Release|Win32
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Release|Win32.Build.0 = Release|Win32
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Release|x64.ActiveCfg = Release|x64
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214}.Release|x64.Build.0 = Release|x64
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Debug|Win32.ActiveCfg = Debug|Win32
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Debug|Win32.Build.0 = Debug|Win32
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Debug|x64.ActiveCfg = Debug|x64
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Debug|x64.Build.0 = Debug|x64
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Release|Win32.ActiveCfg = Release|Win32
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Release|Win32.Build.0 = Release|Win32
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Release|x64.ActiveCfg = Release|x64
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA}.Release|x64.Build.0 = Release|x64
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Debug|Win32.ActiveCfg = Debug|Win32
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Debug|Win32.Build.0 = Debug|Win32
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Debug|x64.ActiveCfg = Debug|x64
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Debug|x64.Build.0 = Debug|x64
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Release|Win32.ActiveCfg = Release|Win32
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Release|Win32.Build.0 = Release|Win32
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Release|x64.ActiveCfg = Release|x64
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34}.Release|x64.Build.0 = Release|x64
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Debug|Win32.ActiveCfg = Debug|Win32
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Debug|Win32.Build.0 = Debug|Win32
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Debug|x64.ActiveCfg = Debug|x64
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Debug|x64.Build.0 = Debug|x64
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Release|Win32.ActiveCfg = Release|Win32
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Release|Win32.Build.0 = Release|Win32
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Release|x64.ActiveCfg = Release|x64
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99}.Release|x64.Build.0 = Release|x64
{13138455-15D7-0F02-57C4-083FE663B876}.Debug|Win32.ActiveCfg = Debug|Win32
{13138455-15D7-0F02-57C4-083FE663B876}.Debug|Win32.Build.0 = Debug|Win32
{13138455-15D7-0F02-57C4-083FE663B876}.Debug|x64.ActiveCfg = Debug|x64
{13138455-15D7-0F02-57C4-083FE663B876}.Debug|x64.Build.0 = Debug|x64
{13138455-15D7-0F02-57C4-083FE663B876}.Release|Win32.ActiveCfg = Release|Win32
{13138455-15D7-0F02-57C4-083FE663B876}.Release|Win32.Build.0 = Release|Win32
{13138455-15D7-0F02-57C4-083FE663B876}.Release|x64.ActiveCfg = Release|x64
{13138455-15D7-0F02-57C4-083FE663B876}.Release|x64.Build.0 = Release|x64
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Debug|Win32.ActiveCfg = Debug|Win32
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Debug|Win32.Build.0 = Debug|Win32
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Debug|x64.ActiveCfg = Debug|x64
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Debug|x64.Build.0 = Debug|x64
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Release|Win32.ActiveCfg = Release|Win32
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Release|Win32.Build.0 = Release|Win32
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Release|x64.ActiveCfg = Release|x64
{B87F7202-6FA6-FC01-14FE-E92CE882F85B}.Release|x64.Build.0 = Release|x64
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Debug|Win32.ActiveCfg = Debug|Win32
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Debug|Win32.Build.0 = Debug|Win32
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Debug|x64.ActiveCfg = Debug|x64
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Debug|x64.Build.0 = Debug|x64
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Release|Win32.ActiveCfg = Release|Win32
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Release|Win32.Build.0 = Release|Win32
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Release|x64.ActiveCfg = Release|x64
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37}.Release|x64.Build.0 = Release|x64
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Debug|Win32.ActiveCfg = Debug|Win32
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Debug|Win32.Build.0 = Debug|Win32
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Debug|x64.ActiveCfg = Debug|x64
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Debug|x64.Build.0 = Debug|x64
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Release|Win32.ActiveCfg = Release|Win32
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Release|Win32.Build.0 = Release|Win32
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Release|x64.ActiveCfg = Release|x64
{03F61B23-19D0-F1E9-18D0-51504E42CC12}.Release|x64.Build.0 = Release|x64
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Debug|Win32.ActiveCfg = Debug|Win32
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Debug|Win32.Build.0 = Debug|Win32
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Debug|x64.ActiveCfg = Debug|x64
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Debug|x64.Build.0 = Debug|x64
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Release|Win32.ActiveCfg = Release|Win32
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Release|Win32.Build.0 = Release|Win32
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Release|x64.ActiveCfg = Release|x64
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78}.Release|x64.Build.0 = Release|x64
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Debug|Win32.ActiveCfg = Debug|Win32
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Debug|Win32.Build.0 = Debug|Win32
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Debug|x64.ActiveCfg = Debug|x64
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Debug|x64.Build.0 = Debug|x64
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Release|Win32.ActiveCfg = Release|Win32
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Release|Win32.Build.0 = Release|Win32
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Release|x64.ActiveCfg = Release|x64
{A0EBB666-81D6-8FDE-6279-E42B597CE104}.Release|x64.Build.0 = Release|x64
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Debug|Win32.ActiveCfg = Debug|Win32
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Debug|Win32.Build.0 = Debug|Win32
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Debug|x64.ActiveCfg = Debug|x64
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Debug|x64.Build.0 = Debug|x64
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Release|Win32.ActiveCfg = Release|Win32
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Release|Win32.Build.0 = Release|Win32
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Release|x64.ActiveCfg = Release|x64
{6A708533-20DB-79A7-1DB4-B8DC76D5A105}.Release|x64.Build.0 = Release|x64
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Debug|Win32.ActiveCfg = Debug|Win32
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Debug|Win32.Build.0 = Debug|Win32
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Debug|x64.ActiveCfg = Debug|x64
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Debug|x64.Build.0 = Debug|x64
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Release|Win32.ActiveCfg = Release|Win32
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Release|Win32.Build.0 = Release|Win32
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Release|x64.ActiveCfg = Release|x64
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A}.Release|x64.Build.0 = Release|x64
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Debug|Win32.ActiveCfg = Debug|Win32
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Debug|Win32.Build.0 = Debug|Win32
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Debug|x64.ActiveCfg = Debug|x64
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Debug|x64.Build.0 = Debug|x64
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Release|Win32.ActiveCfg = Release|Win32
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Release|Win32.Build.0 = Release|Win32
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Release|x64.ActiveCfg = Release|x64
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30}.Release|x64.Build.0 = Release|x64
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Debug|Win32.ActiveCfg = Debug|Win32
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Debug|Win32.Build.0 = Debug|Win32
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Debug|x64.ActiveCfg = Debug|x64
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Debug|x64.Build.0 = Debug|x64
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Release|Win32.ActiveCfg = Release|Win32
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Release|Win32.Build.0 = Release|Win32
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Release|x64.ActiveCfg = Release|x64
{DB839A56-59B6-6430-99A9-51D08C6E33FD}.Release|x64.Build.0 = Release|x64
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Debug|Win32.ActiveCfg = Debug|Win32
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Debug|Win32.Build.0 = Debug|Win32
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Debug|x64.ActiveCfg = Debug|x64
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Debug|x64.Build.0 = Debug|x64
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Release|Win32.ActiveCfg = Release|Win32
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Release|Win32.Build.0 = Release|Win32
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Release|x64.ActiveCfg = Release|x64
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495}.Release|x64.Build.0 = Release|x64
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Debug|Win32.ActiveCfg = Debug|Win32
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Debug|Win32.Build.0 = Debug|Win32
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Debug|x64.ActiveCfg = Debug|x64
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Debug|x64.Build.0 = Debug|x64
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Release|Win32.ActiveCfg = Release|Win32
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Release|Win32.Build.0 = Release|Win32
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Release|x64.ActiveCfg = Release|x64
{0366B8AE-9D7B-A940-458C-A6B131A12AC8}.Release|x64.Build.0 = Release|x64
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Debug|Win32.ActiveCfg = Debug|Win32
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Debug|Win32.Build.0 = Debug|Win32
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Debug|x64.ActiveCfg = Debug|x64
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Debug|x64.Build.0 = Debug|x64
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Release|Win32.ActiveCfg = Release|Win32
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Release|Win32.Build.0 = Release|Win32
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Release|x64.ActiveCfg = Release|x64
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171}.Release|x64.Build.0 = Release|x64
{54994EB2-0674-8592-CF85-8E201FE680E2}.Debug|Win32.ActiveCfg = Debug|Win32
{54994EB2-0674-8592-CF85-8E201FE680E2}.Debug|Win32.Build.0 = Debug|Win32
{54994EB2-0674-8592-CF85-8E201FE680E2}.Debug|x64.ActiveCfg = Debug|x64
{54994EB2-0674-8592-CF85-8E201FE680E2}.Debug|x64.Build.0 = Debug|x64
{54994EB2-0674-8592-CF85-8E201FE680E2}.Release|Win32.ActiveCfg = Release|Win32
{54994EB2-0674-8592-CF85-8E201FE680E2}.Release|Win32.Build.0 = Release|Win32
{54994EB2-0674-8592-CF85-8E201FE680E2}.Release|x64.ActiveCfg = Release|x64
{54994EB2-0674-8592-CF85-8E201FE680E2}.Release|x64.Build.0 = Release|x64
{D047D758-2B7F-D39A-B387-01064479E2DA}.Debug|Win32.ActiveCfg = Debug|Win32
{D047D758-2B7F-D39A-B387-01064479E2DA}.Debug|Win32.Build.0 = Debug|Win32
{D047D758-2B7F-D39A-B387-01064479E2DA}.Debug|x64.ActiveCfg = Debug|x64
{D047D758-2B7F-D39A-B387-01064479E2DA}.Debug|x64.Build.0 = Debug|x64
{D047D758-2B7F-D39A-B387-01064479E2DA}.Release|Win32.ActiveCfg = Release|Win32
{D047D758-2B7F-D39A-B387-01064479E2DA}.Release|Win32.Build.0 = Release|Win32
{D047D758-2B7F-D39A-B387-01064479E2DA}.Release|x64.ActiveCfg = Release|x64
{D047D758-2B7F-D39A-B387-01064479E2DA}.Release|x64.Build.0 = Release|x64
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Debug|Win32.ActiveCfg = Debug|Win32
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Debug|Win32.Build.0 = Debug|Win32
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Debug|x64.ActiveCfg = Debug|x64
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Debug|x64.Build.0 = Debug|x64
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Release|Win32.ActiveCfg = Release|Win32
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Release|Win32.Build.0 = Release|Win32
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Release|x64.ActiveCfg = Release|x64
{F0D3A651-E58B-6E40-75DA-0882C2B5F987}.Release|x64.Build.0 = Release|x64
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Debug|Win32.ActiveCfg = Debug|Win32
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Debug|Win32.Build.0 = Debug|Win32
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Debug|x64.ActiveCfg = Debug|x64
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Debug|x64.Build.0 = Debug|x64
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Release|Win32.ActiveCfg = Release|Win32
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Release|Win32.Build.0 = Release|Win32
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Release|x64.ActiveCfg = Release|x64
{7C123413-10B1-F29F-EEE5-B57A36827C70}.Release|x64.Build.0 = Release|x64
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Debug|Win32.ActiveCfg = Debug|Win32
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Debug|Win32.Build.0 = Debug|Win32
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Debug|x64.ActiveCfg = Debug|x64
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Debug|x64.Build.0 = Debug|x64
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Release|Win32.ActiveCfg = Release|Win32
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Release|Win32.Build.0 = Release|Win32
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Release|x64.ActiveCfg = Release|x64
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B}.Release|x64.Build.0 = Release|x64
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Debug|Win32.ActiveCfg = Debug|Win32
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Debug|Win32.Build.0 = Debug|Win32
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Debug|x64.ActiveCfg = Debug|x64
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Debug|x64.Build.0 = Debug|x64
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Release|Win32.ActiveCfg = Release|Win32
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Release|Win32.Build.0 = Release|Win32
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Release|x64.ActiveCfg = Release|x64
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04}.Release|x64.Build.0 = Release|x64
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Debug|Win32.ActiveCfg = Debug|Win32
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Debug|Win32.Build.0 = Debug|Win32
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Debug|x64.ActiveCfg = Debug|x64
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Debug|x64.Build.0 = Debug|x64
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Release|Win32.ActiveCfg = Release|Win32
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Release|Win32.Build.0 = Release|Win32
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Release|x64.ActiveCfg = Release|x64
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6}.Release|x64.Build.0 = Release|x64
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Debug|Win32.ActiveCfg = Debug|Win32
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Debug|Win32.Build.0 = Debug|Win32
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Debug|x64.ActiveCfg = Debug|x64
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Debug|x64.Build.0 = Debug|x64
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Release|Win32.ActiveCfg = Release|Win32
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Release|Win32.Build.0 = Release|Win32
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Release|x64.ActiveCfg = Release|x64
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5}.Release|x64.Build.0 = Release|x64
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Debug|Win32.ActiveCfg = Debug|Win32
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Debug|Win32.Build.0 = Debug|Win32
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Debug|x64.ActiveCfg = Debug|x64
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Debug|x64.Build.0 = Debug|x64
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Release|Win32.ActiveCfg = Release|Win32
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Release|Win32.Build.0 = Release|Win32
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Release|x64.ActiveCfg = Release|x64
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85}.Release|x64.Build.0 = Release|x64
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Debug|Win32.ActiveCfg = Debug|Win32
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Debug|Win32.Build.0 = Debug|Win32
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Debug|x64.ActiveCfg = Debug|x64
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Debug|x64.Build.0 = Debug|x64
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Release|Win32.ActiveCfg = Release|Win32
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Release|Win32.Build.0 = Release|Win32
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Release|x64.ActiveCfg = Release|x64
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8}.Release|x64.Build.0 = Release|x64
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Debug|Win32.ActiveCfg = Debug|Win32
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Debug|Win32.Build.0 = Debug|Win32
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Debug|x64.ActiveCfg = Debug|x64
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Debug|x64.Build.0 = Debug|x64
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Release|Win32.ActiveCfg = Release|Win32
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Release|Win32.Build.0 = Release|Win32
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Release|x64.ActiveCfg = Release|x64
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D}.Release|x64.Build.0 = Release|x64
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Debug|Win32.ActiveCfg = Debug|Win32
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Debug|Win32.Build.0 = Debug|Win32
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Debug|x64.ActiveCfg = Debug|x64
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Debug|x64.Build.0 = Debug|x64
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Release|Win32.ActiveCfg = Release|Win32
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Release|Win32.Build.0 = Release|Win32
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Release|x64.ActiveCfg = Release|x64
{995774A7-FA69-E03D-1759-A4C33AE7FF7C}.Release|x64.Build.0 = Release|x64
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Debug|Win32.ActiveCfg = Debug|Win32
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Debug|Win32.Build.0 = Debug|Win32
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Debug|x64.ActiveCfg = Debug|x64
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Debug|x64.Build.0 = Debug|x64
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Release|Win32.ActiveCfg = Release|Win32
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Release|Win32.Build.0 = Release|Win32
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Release|x64.ActiveCfg = Release|x64
{EE9EE1EA-E48D-7B28-2825-6F014802A43B}.Release|x64.Build.0 = Release|x64
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Debug|Win32.ActiveCfg = Debug|Win32
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Debug|Win32.Build.0 = Debug|Win32
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Debug|x64.ActiveCfg = Debug|x64
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Debug|x64.Build.0 = Debug|x64
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Release|Win32.ActiveCfg = Release|Win32
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Release|Win32.Build.0 = Release|Win32
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Release|x64.ActiveCfg = Release|x64
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B}.Release|x64.Build.0 = Release|x64
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Debug|Win32.ActiveCfg = Debug|Win32
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Debug|Win32.Build.0 = Debug|Win32
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Debug|x64.ActiveCfg = Debug|x64
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Debug|x64.Build.0 = Debug|x64
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Release|Win32.ActiveCfg = Release|Win32
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Release|Win32.Build.0 = Release|Win32
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Release|x64.ActiveCfg = Release|x64
{DCF03EA6-9806-338B-3B07-60273468D4A9}.Release|x64.Build.0 = Release|x64
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Debug|Win32.ActiveCfg = Debug|Win32
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Debug|Win32.Build.0 = Debug|Win32
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Debug|x64.ActiveCfg = Debug|x64
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Debug|x64.Build.0 = Debug|x64
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Release|Win32.ActiveCfg = Release|Win32
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Release|Win32.Build.0 = Release|Win32
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Release|x64.ActiveCfg = Release|x64
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF}.Release|x64.Build.0 = Release|x64
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Debug|Win32.ActiveCfg = Debug|Win32
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Debug|Win32.Build.0 = Debug|Win32
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Debug|x64.ActiveCfg = Debug|x64
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Debug|x64.Build.0 = Debug|x64
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Release|Win32.ActiveCfg = Release|Win32
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Release|Win32.Build.0 = Release|Win32
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Release|x64.ActiveCfg = Release|x64
{156E1310-DA46-F664-E3C1-EE90B4CD92AE}.Release|x64.Build.0 = Release|x64
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Debug|Win32.ActiveCfg = Debug|Win32
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Debug|Win32.Build.0 = Debug|Win32
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Debug|x64.ActiveCfg = Debug|x64
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Debug|x64.Build.0 = Debug|x64
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Release|Win32.ActiveCfg = Release|Win32
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Release|Win32.Build.0 = Release|Win32
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Release|x64.ActiveCfg = Release|x64
{CF3420B3-B31E-FDD0-4897-648FD5125566}.Release|x64.Build.0 = Release|x64
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Debug|Win32.ActiveCfg = Debug|Win32
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Debug|Win32.Build.0 = Debug|Win32
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Debug|x64.ActiveCfg = Debug|x64
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Debug|x64.Build.0 = Debug|x64
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Release|Win32.ActiveCfg = Release|Win32
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Release|Win32.Build.0 = Release|Win32
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Release|x64.ActiveCfg = Release|x64
{032DB7F5-755A-DF9E-5CBE-553BF92898EC}.Release|x64.Build.0 = Release|x64
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Debug|Win32.ActiveCfg = Debug|Win32
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Debug|Win32.Build.0 = Debug|Win32
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Debug|x64.ActiveCfg = Debug|x64
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Debug|x64.Build.0 = Debug|x64
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Release|Win32.ActiveCfg = Release|Win32
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Release|Win32.Build.0 = Release|Win32
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Release|x64.ActiveCfg = Release|x64
{F8EC63A1-40C4-541B-911E-3679CCA1132D}.Release|x64.Build.0 = Release|x64
{350261DE-995E-5363-B942-85B09B015F2B}.Debug|Win32.ActiveCfg = Debug|Win32
{350261DE-995E-5363-B942-85B09B015F2B}.Debug|Win32.Build.0 = Debug|Win32
{350261DE-995E-5363-B942-85B09B015F2B}.Debug|x64.ActiveCfg = Debug|x64
{350261DE-995E-5363-B942-85B09B015F2B}.Debug|x64.Build.0 = Debug|x64
{350261DE-995E-5363-B942-85B09B015F2B}.Release|Win32.ActiveCfg = Release|Win32
{350261DE-995E-5363-B942-85B09B015F2B}.Release|Win32.Build.0 = Release|Win32
{350261DE-995E-5363-B942-85B09B015F2B}.Release|x64.ActiveCfg = Release|x64
{350261DE-995E-5363-B942-85B09B015F2B}.Release|x64.Build.0 = Release|x64
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Debug|Win32.ActiveCfg = Debug|Win32
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Debug|Win32.Build.0 = Debug|Win32
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Debug|x64.ActiveCfg = Debug|x64
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Debug|x64.Build.0 = Debug|x64
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Release|Win32.ActiveCfg = Release|Win32
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Release|Win32.Build.0 = Release|Win32
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Release|x64.ActiveCfg = Release|x64
{503E4C3C-5D61-7928-7745-526C6EE2646F}.Release|x64.Build.0 = Release|x64
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Debug|Win32.ActiveCfg = Debug|Win32
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Debug|Win32.Build.0 = Debug|Win32
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Debug|x64.ActiveCfg = Debug|x64
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Debug|x64.Build.0 = Debug|x64
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Release|Win32.ActiveCfg = Release|Win32
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Release|Win32.Build.0 = Release|Win32
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Release|x64.ActiveCfg = Release|x64
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{3B3A5736-72C8-C9BB-FC7C-8B3B096D0214} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{7B39DA9E-3F58-7A74-C4A9-E84F163B0FBA} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{2E26269D-8BFC-1A93-FD6E-E0CA16399B34} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{E1973C7F-F026-4596-C19D-6C8FBFAD2C99} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{13138455-15D7-0F02-57C4-083FE663B876} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{B87F7202-6FA6-FC01-14FE-E92CE882F85B} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{B3E441F3-C4A3-7816-FAAE-2E7B0CA1AD37} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{03F61B23-19D0-F1E9-18D0-51504E42CC12} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{73AF98D9-3335-CAFC-E7A9-9A20BA14EE78} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{A0EBB666-81D6-8FDE-6279-E42B597CE104} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{6A708533-20DB-79A7-1DB4-B8DC76D5A105} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{5CEF975B-7E93-DFD0-C929-38EFBFCF640A} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{FBFC91AB-EA5A-EF88-57EF-12A42BE15C30} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{DB839A56-59B6-6430-99A9-51D08C6E33FD} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{B52A4FC7-1A2C-4959-ACFD-8FF0E0AC7495} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{0366B8AE-9D7B-A940-458C-A6B131A12AC8} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{506026B2-9FD9-7F39-6E6E-55E0C2C8C171} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{54994EB2-0674-8592-CF85-8E201FE680E2} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{D047D758-2B7F-D39A-B387-01064479E2DA} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{F0D3A651-E58B-6E40-75DA-0882C2B5F987} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{7C123413-10B1-F29F-EEE5-B57A36827C70} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{0C1DDDB4-F751-0E8E-982C-A6B14886FC7B} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{7F6DB432-0C72-FFB1-DE82-D450DAD5CF04} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{8A8F7ACD-0DB7-90B1-F4F8-F31D60255FD6} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{16CD4B8D-C653-6AFD-426A-D10A768C1CE5} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{A66455C9-DAD3-9BB7-13E6-08E6E33D9B85} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{CABB82BE-DFB1-E556-0AC3-5FC4D6933AE8} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{28365CAD-FDA4-E41A-7C13-FD86AC470A0D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{995774A7-FA69-E03D-1759-A4C33AE7FF7C} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{EE9EE1EA-E48D-7B28-2825-6F014802A43B} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{D78B0119-3CA8-C0A4-E1C2-4D646A68AC5B} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{DCF03EA6-9806-338B-3B07-60273468D4A9} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{90A67BD5-253F-CD50-BB9E-7002DA7D35CF} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{156E1310-DA46-F664-E3C1-EE90B4CD92AE} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{CF3420B3-B31E-FDD0-4897-648FD5125566} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{032DB7F5-755A-DF9E-5CBE-553BF92898EC} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{F8EC63A1-40C4-541B-911E-3679CCA1132D} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{350261DE-995E-5363-B942-85B09B015F2B} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{503E4C3C-5D61-7928-7745-526C6EE2646F} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
{EB4E73BF-E88A-8B43-D654-EE1A4D88D10E} = {5812E712-6213-4372-B095-9EB9BAA1F2DF}
EndGlobalSection
EndGlobal

32
rpcs3/AppConnector.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "stdafx.h"
#include "AppConnector.h"
AppConnector::~AppConnector()
{
for(uint i=0; i<m_connect_arr.GetCount(); ++i)
{
wxGetApp().Disconnect(
m_connect_arr[i].winid,
m_connect_arr[i].lastId,
m_connect_arr[i].eventType,
m_connect_arr[i].func,
m_connect_arr[i].userData,
m_connect_arr[i].eventSink);
}
}
void AppConnector::Connect(int winid, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
{
m_connect_arr.Move(new ConnectInfo(winid, lastId, eventType, func, userData, eventSink));
wxGetApp().Connect(winid, lastId, eventType, func, userData, eventSink);
}
void AppConnector::Connect(int winid, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
{
Connect(winid, wxID_ANY, eventType, func, userData, eventSink);
}
void AppConnector::Connect(int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
{
Connect(wxID_ANY, wxID_ANY, eventType, func, userData, eventSink);
}

33
rpcs3/AppConnector.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
class AppConnector
{
struct ConnectInfo
{
int winid;
int lastId;
int eventType;
wxObjectEventFunction func;
wxObject* userData;
wxEvtHandler* eventSink;
ConnectInfo(int winid, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData, wxEvtHandler* eventSink)
: winid(winid)
, lastId(lastId)
, eventType(eventType)
, func(func)
, userData(userData)
, eventSink(eventSink)
{
}
};
Array<ConnectInfo> m_connect_arr;
public:
~AppConnector();
void Connect(int winid, int lastId, int eventType, wxObjectEventFunction func, wxObject* userData = nullptr, wxEvtHandler* eventSink = nullptr);
void Connect(int winid, int eventType, wxObjectEventFunction func, wxObject* userData = nullptr, wxEvtHandler* eventSink = nullptr);
void Connect(int eventType, wxObjectEventFunction func, wxObject* userData = nullptr, wxEvtHandler* eventSink = nullptr);
};

View File

@ -76,10 +76,34 @@ protected:
return op;
}
void DisAsm_V4(const wxString& op, OP_REG v0, OP_REG v1, OP_REG v2, OP_REG v3)
{
Write(wxString::Format("%s v%d,v%d,v%d,v%d", FixOp(op), v0, v1, v2, v3));
}
void DisAsm_V3_UIMM(const wxString& op, OP_REG v0, OP_REG v1, OP_REG v2, OP_uIMM uimm)
{
Write(wxString::Format("%s v%d,v%d,v%d,%u #%x", FixOp(op), v0, v1, v2, uimm, uimm));
}
void DisAsm_V3(const wxString& op, OP_REG v0, OP_REG v1, OP_REG v2)
{
Write(wxString::Format("%s v%d,v%d,v%d", FixOp(op), v0, v1, v2));
}
void DisAsm_V2_UIMM(const wxString& op, OP_REG v0, OP_REG v1, OP_uIMM uimm)
{
Write(wxString::Format("%s v%d,v%d,%u #%x", FixOp(op), v0, v1, uimm, uimm));
}
void DisAsm_V2(const wxString& op, OP_REG v0, OP_REG v1)
{
Write(wxString::Format("%s v%d,v%d", FixOp(op), v0, v1));
}
void DisAsm_V1_SIMM(const wxString& op, OP_REG v0, OP_sIMM simm)
{
Write(wxString::Format("%s v%d,%d #%x", FixOp(op), v0, simm, simm));
}
void DisAsm_V1(const wxString& op, OP_REG v0)
{
Write(wxString::Format("%s v%d", FixOp(op), v0));
}
void DisAsm_V1_R2(const wxString& op, OP_REG v0, OP_REG r1, OP_REG r2)
{
Write(wxString::Format("%s v%d,r%d,r%d", FixOp(op), v0, r1, r2));

View File

@ -2,8 +2,14 @@
#include "PPCThread.h"
#include "Gui/InterpreterDisAsm.h"
PPCThread* GetCurrentPPCThread()
{
return (PPCThread*)GetCurrentNamedThread();
}
PPCThread::PPCThread(PPCThreadType type)
: m_type(type)
: ThreadBase(true, "PPCThread")
, m_type(type)
, DisAsmFrame(NULL)
, m_arg(0)
, m_dec(NULL)
@ -79,16 +85,11 @@ void PPCThread::SetId(const u32 id)
m_id = id;
ID& thread = Emu.GetIdManager().GetIDData(m_id);
thread.m_name = GetName();
if(Ini.CPUDecoderMode.GetValue() != 1) return;
DisAsmFrame = new InterpreterDisAsmFrame(GetFName(), this);
(*(InterpreterDisAsmFrame*)DisAsmFrame).Show();
}
void PPCThread::SetName(const wxString& name)
{
m_name = name;
if(DisAsmFrame) (*(InterpreterDisAsmFrame*)DisAsmFrame).SetTitle(GetFName());
}
void PPCThread::NextBranchPc()
@ -119,6 +120,11 @@ void PPCThread::SetPc(const u64 pc)
nPC = PC + 4;
}
void PPCThread::SetEntry(const u64 pc)
{
entry = pc;
}
void PPCThread::SetBranch(const u64 pc)
{
if(!Memory.IsGoodAddr(pc))
@ -164,41 +170,95 @@ void PPCThread::Run()
m_status = Runned;
SetPc(entry);
InitStack();
InitRegs();
DoRun();
Emu.CheckStatus();
wxGetApp().SendDbgCommand(DID_START_THREAD, this);
if(DisAsmFrame) (*(InterpreterDisAsmFrame*)DisAsmFrame).DoUpdate();
}
void PPCThread::Resume()
{
if(!IsPaused()) return;
m_status = Runned;
DoResume();
Emu.CheckStatus();
wxGetApp().SendDbgCommand(DID_RESUME_THREAD, this);
ThreadBase::Start();
}
void PPCThread::Pause()
{
if(!IsRunned()) return;
m_status = Paused;
DoPause();
Emu.CheckStatus();
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, this);
ThreadBase::Stop(false);
}
void PPCThread::Stop()
{
if(IsStopped()) return;
m_status = Stopped;
Reset();
DoStop();
Emu.CheckStatus();
wxGetApp().SendDbgCommand(DID_STOP_THREAD, this);
ThreadBase::Stop();
}
void PPCThread::Exec()
{
if(!IsRunned()) return;
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
ThreadBase::Start();
}
void PPCThread::ExecOnce()
{
DoCode(Memory.Read32(m_offset + PC));
NextPc();
}
}
void PPCThread::Task()
{
ConLog.Write("%s enter", PPCThread::GetFName());
try
{
while(!Emu.IsStopped() && !TestDestroy())
{
if(Emu.IsPaused())
{
Sleep(1);
continue;
}
DoCode(Memory.Read32(m_offset + PC));
NextPc();
}
}
catch(const wxString& e)
{
ConLog.Error("Exception: %s", e);
}
catch(const char* e)
{
ConLog.Error("Exception: %s", e);
}
ConLog.Write("%s leave", PPCThread::GetFName());
}

View File

@ -8,7 +8,7 @@ enum PPCThreadType
PPC_THREAD_SPU,
};
class PPCThread// : public StepThread
class PPCThread : public ThreadBase
{
protected:
u32 m_status;
@ -19,7 +19,6 @@ protected:
PPCThreadType m_type;
u64 m_arg;
u64 m_prio;
wxString m_name;
bool m_joinable;
bool m_joining;
Array<u64> argv_addr;
@ -70,9 +69,15 @@ public:
wxString GetTypeString() const { return PPCThreadTypeToString(m_type); }
virtual wxString GetThreadName() const
{
return GetFName() + wxString::Format("[0x%08llx]", PC);
}
public:
bool isBranch;
u64 entry;
u64 PC;
u64 nPC;
u64 cycle;
@ -88,6 +93,7 @@ public:
void PrevPc();
void SetBranch(const u64 pc);
void SetPc(const u64 pc);
void SetEntry(const u64 entry);
void SetError(const u32 error);
@ -118,6 +124,7 @@ public:
virtual wxString RegsToString() { return wxEmptyString; }
virtual void Exec();
void ExecOnce();
virtual void AddArgv(const wxString& arg) {}
@ -127,7 +134,11 @@ protected:
virtual void DoPause()=0;
virtual void DoResume()=0;
virtual void DoStop()=0;
virtual void Task();
private:
virtual void DoCode(const s32 code)=0;
};
};
PPCThread* GetCurrentPPCThread();

View File

@ -4,7 +4,6 @@
#include "SPUThread.h"
PPCThreadManager::PPCThreadManager()
: ThreadBase(true, "PPCThreadManager")
{
}
@ -15,8 +14,6 @@ PPCThreadManager::~PPCThreadManager()
void PPCThreadManager::Close()
{
if(IsAlive()) Stop();
while(m_threads.GetCount()) RemoveThread(m_threads[0].GetId());
}
@ -29,6 +26,7 @@ PPCThread& PPCThreadManager::AddThread(bool isPPU)
);
m_threads.Add(new_thread);
wxGetApp().SendDbgCommand(DID_CREATE_THREAD, new_thread);
return *new_thread;
}
@ -39,6 +37,7 @@ void PPCThreadManager::RemoveThread(const u32 id)
{
if(m_threads[i].GetId() != id) continue;
wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, &m_threads[i]);
m_threads[i].Close();
m_threads.RemoveAt(i);
@ -62,19 +61,20 @@ s32 PPCThreadManager::GetThreadNumById(bool isPPU, u32 id)
return -1;
}
void PPCThreadManager::Exec()
PPCThread* PPCThreadManager::GetThread(u32 id)
{
Start();
for(u32 i=0; i<m_threads.GetCount(); ++i)
{
if(m_threads[i].GetId() == id) return &m_threads[i];
}
return nullptr;
}
void PPCThreadManager::Task()
void PPCThreadManager::Exec()
{
u32 thread = 0;
while(!TestDestroy() && Emu.IsRunned() && m_threads.GetCount())
for(u32 i=0; i<m_threads.GetCount(); ++i)
{
m_threads[thread].Exec();
thread = (thread + 1) % m_threads.GetCount();
m_threads[i].Exec();
}
}

View File

@ -1,7 +1,7 @@
#pragma once
#include "PPCThread.h"
class PPCThreadManager : public ThreadBase
class PPCThreadManager
{
//IdManager m_threads_id;
//ArrayF<PPUThread> m_ppu_threads;
@ -19,8 +19,8 @@ public:
ArrayF<PPCThread>& GetThreads() { return m_threads; }
s32 GetThreadNumById(bool isPPU, u32 id);
PPCThread* GetThread(u32 id);
//IdManager& GetIDs() {return m_threads_id;}
void Exec();
virtual void Task();
};

View File

@ -10,6 +10,12 @@
switch(temp)\
{
#define START_OPCODES_SUB_GROUP(reg) \
default:\
temp=##reg##;\
switch(temp)\
{
#define END_OPCODES_GROUP(group) \
default:\
m_op.UNK(m_code, opcode, temp);\
@ -17,6 +23,15 @@
}\
break
#define END_OPCODES_SUB_GROUP() \
default:\
m_op.UNK(m_code, opcode, temp);\
break;\
}
#define END_OPCODES_ND_GROUP(group) \
} \
break;
#define ADD_OPCODE(name, ...) case(##name##):m_op.##name##(__VA_ARGS__); break
class PPU_Decoder : public Decoder
@ -36,6 +51,9 @@ class PPU_Decoder : public Decoder
//This field is used to specify a special-purpose register for the mtspr and mfspr instructions
OP_REG SPR() const { return GetField(11, 20); }
//
OP_REG VS() const { return GetField(6, 10); }
//
OP_REG VD() const { return GetField(6, 10); }
@ -45,6 +63,20 @@ class PPU_Decoder : public Decoder
//
OP_REG VB() const { return GetField(16, 20); }
//
OP_REG VC() const { return GetField(21, 25); }
//
OP_uIMM VUIMM() const { return GetField(11, 15); }
//
OP_sIMM VSIMM() const { int i5 = GetField(11, 15);
if(i5 & 0x10) return i5 - 0x20;
return i5; }
//
OP_uIMM VSH() const { return GetField(22, 25); }
//This field is used to specify a GPR to be used as a destination
OP_REG RD() const { return GetField(6, 10); }
@ -174,8 +206,8 @@ class PPU_Decoder : public Decoder
//This field is used to specify an FPR as a source
OP_REG FRC() const { return GetField(21, 25); }
//
OP_REG FXM() const { return GetField(12, 19); }
//This field mask is used to identify the CR fields that are to be updated by the mtcrf instruction.
OP_REG CRM() const { return GetField(12, 19); }
//
const s32 SYS() const { return GetField(6, 31); }
@ -211,6 +243,8 @@ class PPU_Decoder : public Decoder
//Primary opcode field
OP_uIMM OPCD() const { return GetField(0, 5); }
OP_uIMM STRM() const { return GetField(9, 10); }
__forceinline u32 GetField(const u32 p) const
{
@ -234,24 +268,178 @@ public:
virtual void Decode(const u32 code)
{
if(code == 0)
{
m_op.NULL_OP();
return;
}
m_code = code;
u32 opcode, temp;
using namespace PPU_opcodes;
static u32 opcode, temp;
switch((opcode = OPCD()))
{
ADD_OPCODE(TDI, TO(), RA(), simm16());
ADD_OPCODE(TWI, TO(), RA(), simm16());
START_OPCODES_GROUP(G_04, ((m_code >> 1) & 0x3ff))
ADD_OPCODE(VXOR, VD(), VA(), VB());
END_OPCODES_GROUP(G_04);
START_OPCODES_GROUP(G_04, m_code & 0x3f)
ADD_OPCODE(VMADDFP, VD(), VA(), VB(), VC());
ADD_OPCODE(VMHADDSHS, VD(), VA(), VB(), VC());
ADD_OPCODE(VMHRADDSHS, VD(), VA(), VB(), VC());
ADD_OPCODE(VMLADDUHM, VD(), VA(), VB(), VC());
ADD_OPCODE(VMSUMMBM, VD(), VA(), VB(), VC());
ADD_OPCODE(VMSUMSHM, VD(), VA(), VB(), VC());
ADD_OPCODE(VMSUMSHS, VD(), VA(), VB(), VC());
ADD_OPCODE(VMSUMUBM, VD(), VA(), VB(), VC());
ADD_OPCODE(VMSUMUHM, VD(), VA(), VB(), VC());
ADD_OPCODE(VMSUMUHS, VD(), VA(), VB(), VC());
ADD_OPCODE(VNMSUBFP, VD(), VA(), VB(), VC());
ADD_OPCODE(VPERM, VD(), VA(), VB(), VC());
ADD_OPCODE(VSEL, VD(), VA(), VB(), VC());
ADD_OPCODE(VSLDOI, VD(), VA(), VB(), VSH());
START_OPCODES_SUB_GROUP(m_code & 0x7ff);
ADD_OPCODE(MFVSCR, VD());
ADD_OPCODE(MTVSCR, VB());
ADD_OPCODE(VADDCUW, VD(), VA(), VB());
ADD_OPCODE(VADDFP, VD(), VA(), VB());
ADD_OPCODE(VADDSBS, VD(), VA(), VB());
ADD_OPCODE(VADDSHS, VD(), VA(), VB());
ADD_OPCODE(VADDSWS, VD(), VA(), VB());
ADD_OPCODE(VADDUBM, VD(), VA(), VB());
ADD_OPCODE(VADDUBS, VD(), VA(), VB());
ADD_OPCODE(VADDUHM, VD(), VA(), VB());
ADD_OPCODE(VADDUHS, VD(), VA(), VB());
ADD_OPCODE(VADDUWM, VD(), VA(), VB());
ADD_OPCODE(VADDUWS, VD(), VA(), VB());
ADD_OPCODE(VAND, VD(), VA(), VB());
ADD_OPCODE(VANDC, VD(), VA(), VB());
ADD_OPCODE(VAVGSB, VD(), VA(), VB());
ADD_OPCODE(VAVGSH, VD(), VA(), VB());
ADD_OPCODE(VAVGSW, VD(), VA(), VB());
ADD_OPCODE(VAVGUB, VD(), VA(), VB());
ADD_OPCODE(VAVGUH, VD(), VA(), VB());
ADD_OPCODE(VAVGUW, VD(), VA(), VB());
ADD_OPCODE(VCFSX, VD(), VUIMM(), VB());
ADD_OPCODE(VCFUX, VD(), VUIMM(), VB());
ADD_OPCODE(VCMPBFP, VD(), VA(), VB());
ADD_OPCODE(VCMPBFP_, VD(), VA(), VB());
ADD_OPCODE(VCMPEQFP, VD(), VA(), VB());
ADD_OPCODE(VCMPEQFP_, VD(), VA(), VB());
ADD_OPCODE(VCMPEQUB, VD(), VA(), VB());
ADD_OPCODE(VCMPEQUB_, VD(), VA(), VB());
ADD_OPCODE(VCMPEQUH, VD(), VA(), VB());
ADD_OPCODE(VCMPEQUH_, VD(), VA(), VB());
ADD_OPCODE(VCMPEQUW, VD(), VA(), VB());
ADD_OPCODE(VCMPEQUW_, VD(), VA(), VB());
ADD_OPCODE(VCMPGEFP, VD(), VA(), VB());
ADD_OPCODE(VCMPGEFP_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTFP, VD(), VA(), VB());
ADD_OPCODE(VCMPGTFP_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTSB, VD(), VA(), VB());
ADD_OPCODE(VCMPGTSB_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTSH, VD(), VA(), VB());
ADD_OPCODE(VCMPGTSH_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTSW, VD(), VA(), VB());
ADD_OPCODE(VCMPGTSW_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTUB, VD(), VA(), VB());
ADD_OPCODE(VCMPGTUB_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTUH, VD(), VA(), VB());
ADD_OPCODE(VCMPGTUH_, VD(), VA(), VB());
ADD_OPCODE(VCMPGTUW, VD(), VA(), VB());
ADD_OPCODE(VCMPGTUW_, VD(), VA(), VB());
ADD_OPCODE(VCTSXS, VD(), VUIMM(), VB());
ADD_OPCODE(VCTUXS, VD(), VUIMM(), VB());
ADD_OPCODE(VEXPTEFP, VD(), VB());
ADD_OPCODE(VLOGEFP, VD(), VB());
ADD_OPCODE(VMAXFP, VD(), VA(), VB());
ADD_OPCODE(VMAXSB, VD(), VA(), VB());
ADD_OPCODE(VMAXSH, VD(), VA(), VB());
ADD_OPCODE(VMAXSW, VD(), VA(), VB());
ADD_OPCODE(VMAXUB, VD(), VA(), VB());
ADD_OPCODE(VMAXUH, VD(), VA(), VB());
ADD_OPCODE(VMAXUW, VD(), VA(), VB());
ADD_OPCODE(VMINFP, VD(), VA(), VB());
ADD_OPCODE(VMINSB, VD(), VA(), VB());
ADD_OPCODE(VMINSH, VD(), VA(), VB());
ADD_OPCODE(VMINSW, VD(), VA(), VB());
ADD_OPCODE(VMINUB, VD(), VA(), VB());
ADD_OPCODE(VMINUH, VD(), VA(), VB());
ADD_OPCODE(VMINUW, VD(), VA(), VB());
ADD_OPCODE(VMRGHB, VD(), VA(), VB());
ADD_OPCODE(VMRGHH, VD(), VA(), VB());
ADD_OPCODE(VMRGHW, VD(), VA(), VB());
ADD_OPCODE(VMRGLB, VD(), VA(), VB());
ADD_OPCODE(VMRGLH, VD(), VA(), VB());
ADD_OPCODE(VMRGLW, VD(), VA(), VB());
ADD_OPCODE(VMULESB, VD(), VA(), VB());
ADD_OPCODE(VMULESH, VD(), VA(), VB());
ADD_OPCODE(VMULEUB, VD(), VA(), VB());
ADD_OPCODE(VMULEUH, VD(), VA(), VB());
ADD_OPCODE(VMULOSB, VD(), VA(), VB());
ADD_OPCODE(VMULOSH, VD(), VA(), VB());
ADD_OPCODE(VMULOUB, VD(), VA(), VB());
ADD_OPCODE(VMULOUH, VD(), VA(), VB());
ADD_OPCODE(VNOR, VD(), VA(), VB());
ADD_OPCODE(VOR, VD(), VA(), VB());
ADD_OPCODE(VPKPX, VD(), VA(), VB());
ADD_OPCODE(VPKSHSS, VD(), VA(), VB());
ADD_OPCODE(VPKSHUS, VD(), VA(), VB());
ADD_OPCODE(VPKSWSS, VD(), VA(), VB());
ADD_OPCODE(VPKSWUS, VD(), VA(), VB());
ADD_OPCODE(VPKUHUM, VD(), VA(), VB());
ADD_OPCODE(VPKUHUS, VD(), VA(), VB());
ADD_OPCODE(VPKUWUM, VD(), VA(), VB());
ADD_OPCODE(VPKUWUS, VD(), VA(), VB());
ADD_OPCODE(VREFP, VD(), VB());
ADD_OPCODE(VRFIM, VD(), VB());
ADD_OPCODE(VRFIN, VD(), VB());
ADD_OPCODE(VRFIP, VD(), VB());
ADD_OPCODE(VRFIZ, VD(), VB());
ADD_OPCODE(VRLB, VD(), VA(), VB());
ADD_OPCODE(VRLH, VD(), VA(), VB());
ADD_OPCODE(VRLW, VD(), VA(), VB());
ADD_OPCODE(VRSQRTEFP, VD(), VB());
ADD_OPCODE(VSL, VD(), VA(), VB());
ADD_OPCODE(VSLB, VD(), VA(), VB());
ADD_OPCODE(VSLH, VD(), VA(), VB());
ADD_OPCODE(VSLO, VD(), VA(), VB());
ADD_OPCODE(VSLW, VD(), VA(), VB());
ADD_OPCODE(VSPLTB, VD(), VUIMM(), VB());
ADD_OPCODE(VSPLTH, VD(), VUIMM(), VB());
ADD_OPCODE(VSPLTISB, VD(), VSIMM());
ADD_OPCODE(VSPLTISH, VD(), VSIMM());
ADD_OPCODE(VSPLTISW, VD(), VSIMM());
ADD_OPCODE(VSPLTW, VD(), VUIMM(), VB());
ADD_OPCODE(VSR, VD(), VA(), VB());
ADD_OPCODE(VSRAB, VD(), VA(), VB());
ADD_OPCODE(VSRAH, VD(), VA(), VB());
ADD_OPCODE(VSRAW, VD(), VA(), VB());
ADD_OPCODE(VSRB, VD(), VA(), VB());
ADD_OPCODE(VSRH, VD(), VA(), VB());
ADD_OPCODE(VSRO, VD(), VA(), VB());
ADD_OPCODE(VSRW, VD(), VA(), VB());
ADD_OPCODE(VSUBCUW, VD(), VA(), VB());
ADD_OPCODE(VSUBFP, VD(), VA(), VB());
ADD_OPCODE(VSUBSBS, VD(), VA(), VB());
ADD_OPCODE(VSUBSHS, VD(), VA(), VB());
ADD_OPCODE(VSUBSWS, VD(), VA(), VB());
ADD_OPCODE(VSUBUBM, VD(), VA(), VB());
ADD_OPCODE(VSUBUBS, VD(), VA(), VB());
ADD_OPCODE(VSUBUHM, VD(), VA(), VB());
ADD_OPCODE(VSUBUHS, VD(), VA(), VB());
ADD_OPCODE(VSUBUWM, VD(), VA(), VB());
ADD_OPCODE(VSUBUWS, VD(), VA(), VB());
ADD_OPCODE(VSUMSWS, VD(), VA(), VB());
ADD_OPCODE(VSUM2SWS, VD(), VA(), VB());
ADD_OPCODE(VSUM4SBS, VD(), VA(), VB());
ADD_OPCODE(VSUM4SHS, VD(), VA(), VB());
ADD_OPCODE(VSUM4UBS, VD(), VA(), VB());
ADD_OPCODE(VUPKHPX, VD(), VB());
ADD_OPCODE(VUPKHSB, VD(), VB());
ADD_OPCODE(VUPKHSH, VD(), VB());
ADD_OPCODE(VUPKLPX, VD(), VB());
ADD_OPCODE(VUPKLSB, VD(), VB());
ADD_OPCODE(VUPKLSH, VD(), VB());
ADD_OPCODE(VXOR, VD(), VA(), VB());
END_OPCODES_SUB_GROUP();
END_OPCODES_ND_GROUP(G_04);
ADD_OPCODE(MULLI, RD(), RA(), simm16());
ADD_OPCODE(SUBFIC, RD(), RA(), simm16());
@ -300,12 +488,13 @@ public:
START_OPCODES_GROUP(G_1f, GetField(21, 30))
/*0x000*/ADD_OPCODE(CMP, CRFD(), L(), RA(), RB());
/*0x004*/ADD_OPCODE(TW, TO(), RA(), RB());
/*0x006*/ADD_OPCODE(LVSL, VD(), RA(), RB());
/*0x007*/ADD_OPCODE(LVEBX, VD(), RA(), RB());
/*0x008*/ADD_OPCODE(SUBFC, RD(), RA(), RB(), OE(), RC());
/*0x009*/ADD_OPCODE(MULHDU, RD(), RA(), RB(), RC());
/*0x00a*/ADD_OPCODE(ADDC, RD(), RA(), RB(), OE(), RC());
/*0x00b*/ADD_OPCODE(MULHWU, RD(), RA(), RB(), RC());
/*0x013*/ADD_OPCODE(MFOCRF, GetField(11), FXM(), RD());
/*0x013*/ADD_OPCODE(MFOCRF, GetField(11), RD(), CRM());
/*0x014*/ADD_OPCODE(LWARX, RD(), RA(), RB());
/*0x015*/ADD_OPCODE(LDX, RA(), RS(), RB());
/*0x017*/ADD_OPCODE(LWZX, RD(), RA(), RB());
@ -314,11 +503,13 @@ public:
/*0x01b*/ADD_OPCODE(SLD, RA(), RS(), RB(), RC());
/*0x01c*/ADD_OPCODE(AND, RA(), RS(), RB(), RC());
/*0x020*/ADD_OPCODE(CMPL, CRFD(), L(), RA(), RB());
/*0x026*/ADD_OPCODE(LVSR, VD(), RA(), RB());
/*0x027*/ADD_OPCODE(LVEHX, VD(), RA(), RB());
/*0x028*/ADD_OPCODE(SUBF, RD(), RA(), RB(), OE(), RC());
/*0x036*/ADD_OPCODE(DCBST, RA(), RB());
/*0x03a*/ADD_OPCODE(CNTLZD, RA(), RS(), RC());
/*0x03c*/ADD_OPCODE(ANDC, RA(), RS(), RB(), RC());
/*0x047*/ADD_OPCODE(LVEWX, VD(), RA(), RB());
/*0x049*/ADD_OPCODE(MULHD, RD(), RA(), RB(), RC());
/*0x04b*/ADD_OPCODE(MULHW, RD(), RA(), RB(), RC());
/*0x054*/ADD_OPCODE(LDARX, RD(), RA(), RB());
@ -328,17 +519,20 @@ public:
/*0x068*/ADD_OPCODE(NEG, RD(), RA(), OE(), RC());
/*0x077*/ADD_OPCODE(LBZUX, RD(), RA(), RB());
/*0x07c*/ADD_OPCODE(NOR, RA(), RS(), RB(), RC());
/*0x087*/ADD_OPCODE(STVEBX, VS(), RA(), RB());
/*0x088*/ADD_OPCODE(SUBFE, RD(), RA(), RB(), OE(), RC());
/*0x08a*/ADD_OPCODE(ADDE, RD(), RA(), RB(), OE(), RC());
/*0x090*/ADD_OPCODE(MTOCRF, FXM(), RS());
/*0x090*/ADD_OPCODE(MTOCRF, CRM(), RS());
/*0x095*/ADD_OPCODE(STDX, RS(), RA(), RB());
/*0x096*/ADD_OPCODE(STWCX_, RS(), RA(), RB());
/*0x097*/ADD_OPCODE(STWX, RS(), RA(), RB());
/*0x0a7*/ADD_OPCODE(STVEHX, VS(), RA(), RB());
/*0x0b5*/ADD_OPCODE(STDUX, RS(), RA(), RB());
/*0x0c7*/ADD_OPCODE(STVEWX, VS(), RA(), RB());
/*0x0ca*/ADD_OPCODE(ADDZE, RD(), RA(), OE(), RC());
/*0x0d6*/ADD_OPCODE(STDCX_, RS(), RA(), RB());
/*0x0d7*/ADD_OPCODE(STBX, RS(), RA(), RB());
/*0x0e7*/ADD_OPCODE(STVX, VD(), RA(), RB());
/*0x0e7*/ADD_OPCODE(STVX, VS(), RA(), RB());
/*0x0e9*/ADD_OPCODE(MULLD, RD(), RA(), RB(), OE(), RC());
/*0x0ea*/ADD_OPCODE(ADDME, RD(), RA(), OE(), RC());
/*0x0eb*/ADD_OPCODE(MULLW, RD(), RA(), RB(), OE(), RC());
@ -351,9 +545,12 @@ public:
/*0x137*/ADD_OPCODE(LHZUX, RD(), RA(), RB());
/*0x13c*/ADD_OPCODE(XOR, RA(), RS(), RB(), RC());
/*0x153*/ADD_OPCODE(MFSPR, RD(), SPR());
/*0x156*/ADD_OPCODE(DST, RA(), RB(), STRM(), GetField(6));
/*0x157*/ADD_OPCODE(LHAX, RD(), RA(), RB());
/*0x167*/ADD_OPCODE(LVXL, VD(), RA(), RB());
/*0x168*/ADD_OPCODE(ABS, RD(), RA(), OE(), RC());
/*0x173*/ADD_OPCODE(MFTB, RD(), SPR());
/*0x176*/ADD_OPCODE(DSTST, RA(), RB(), STRM(), GetField(6));
/*0x177*/ADD_OPCODE(LHAUX, RD(), RA(), RB());
/*0x197*/ADD_OPCODE(STHX, RS(), RA(), RB());
/*0x19c*/ADD_OPCODE(ORC, RA(), RS(), RB(), RC());
@ -363,20 +560,30 @@ public:
/*0x1cb*/ADD_OPCODE(DIVWU, RD(), RA(), RB(), OE(), RC());
/*0x1d3*/ADD_OPCODE(MTSPR, SPR(), RS());
/*0x1d6*///DCBI
/*0x1dc*/ADD_OPCODE(NAND, RA(), RS(), RB(), RC());
/*0x1e7*/ADD_OPCODE(STVXL, RS(), RA(), RB());
/*0x1e9*/ADD_OPCODE(DIVD, RD(), RA(), RB(), OE(), RC());
/*0x1eb*/ADD_OPCODE(DIVW, RD(), RA(), RB(), OE(), RC());
/*0x207*/ADD_OPCODE(LVLX, VD(), RA(), RB());
/*0x216*/ADD_OPCODE(LWBRX, RD(), RA(), RB());
/*0x217*/ADD_OPCODE(LFSX, FRD(), RA(), RB());
/*0x218*/ADD_OPCODE(SRW, RA(), RS(), RB(), RC());
/*0x21b*/ADD_OPCODE(SRD, RA(), RS(), RB(), RC());
/*0x227*/ADD_OPCODE(LVRX, VD(), RA(), RB());
/*0x237*/ADD_OPCODE(LFSUX, FRD(), RA(), RB());
/*0x256*/ADD_OPCODE(SYNC, GetField(9, 10));
/*0x257*/ADD_OPCODE(LFDX, FRD(), RA(), RB());
/*0x277*/ADD_OPCODE(LFDUX, FRD(), RA(), RB());
/*0x287*/ADD_OPCODE(STVLX, VS(), RA(), RB());
/*0x297*/ADD_OPCODE(STFSX, RS(), RA(), RB());
/*0x2a7*/ADD_OPCODE(STVRX, VS(), RA(), RB());
/*0x2d7*/ADD_OPCODE(STFDX, RS(), RA(), RB());
/*0x307*/ADD_OPCODE(LVLXL, VD(), RA(), RB());
/*0x316*/ADD_OPCODE(LHBRX, RD(), RA(), RB());
/*0x318*/ADD_OPCODE(SRAW, RA(), RS(), RB(), RC());
/*0x31A*/ADD_OPCODE(SRAD, RA(), RS(), RB(), RC());
/*0x31a*/ADD_OPCODE(SRAD, RA(), RS(), RB(), RC());
/*0x327*/ADD_OPCODE(LVRXL, VD(), RA(), RB());
/*0x336*/ADD_OPCODE(DSS, STRM(), GetField(6));
/*0x338*/ADD_OPCODE(SRAWI, RA(), RS(), sh(), RC());
/*0x33a*/ADD_OPCODE(SRADI1, RA(), RS(), sh(), RC());
/*0x33b*/ADD_OPCODE(SRADI2, RA(), RS(), sh(), RC());
@ -431,12 +638,11 @@ public:
END_OPCODES_GROUP(G_3b);
START_OPCODES_GROUP(G_3e, GetField(30, 31))
ADD_OPCODE(STD, RS(), RA(), D());
ADD_OPCODE(STD, RS(), RA(), D());
ADD_OPCODE(STDU, RS(), RA(), DS());
END_OPCODES_GROUP(G_3e);
START_OPCODES_GROUP(G_3f, GetField(26, 30))
ADD_OPCODE(FDIV, FRD(), FRA(), FRB(), RC());
ADD_OPCODE(FSUB, FRD(), FRA(), FRB(), RC());
ADD_OPCODE(FADD, FRD(), FRA(), FRB(), RC());
@ -450,8 +656,7 @@ public:
ADD_OPCODE(FNMADD, FRD(), FRA(), FRC(), FRB(), RC());
ADD_OPCODE(FCMPO, CRFD(), FRA(), FRB());
default:
START_OPCODES_GROUP(0x8, GetField(21, 30))
START_OPCODES_SUB_GROUP(GetField(21, 30))
ADD_OPCODE(FCMPU, CRFD(), FRA(), FRB());
ADD_OPCODE(FRSP, FRD(), FRB(), RC());
ADD_OPCODE(FCTIW, FRD(), FRB(), RC());
@ -470,18 +675,26 @@ public:
ADD_OPCODE(MTFSFI, CRFD(), I(), RC());
ADD_OPCODE(MFFS, FRD(), RC());
ADD_OPCODE(MTFSF, FLM(), FRB(), RC());
END_OPCODES_GROUP(0x8);
break;
}
break;
//END_OPCODES_GROUP(G_3f);
END_OPCODES_SUB_GROUP();
END_OPCODES_ND_GROUP(G_3f);
default: m_op.UNK(m_code, opcode, opcode); break;
default:
if(!code)
{
m_op.NULL_OP();
break;
}
m_op.UNK(m_code, opcode, opcode);
break;
}
}
};
#undef START_OPCODES_GROUP
#undef START_OPCODES_SUB_GROUP
#undef ADD_OPCODE
#undef ADD_NULL_OPCODE
#undef END_OPCODES_GROUP
#undef END_OPCODES_GROUP
#undef END_OPCODES_ND_GROUP
#undef END_OPCODES_SUB_GROUP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,253 +8,434 @@
#define ADD_NULL_OPCODE(name) virtual void(##name##)()=0
#define END_OPCODES_GROUP(x) /*x*/
enum PPU_MainOpcodes
namespace PPU_opcodes
{
TDI = 0x02, //Trap Doubleword Immediate
TWI = 0x03, //Trap Word Immediate
G_04 = 0x04,
MULLI = 0x07, //Multiply Low Immediate
SUBFIC = 0x08, //Subtract from Immediate Carrying
//DOZI = 0x09,
CMPLI = 0x0a, //Compare Logical Immediate
CMPI = 0x0b, //Compare Immediate
ADDIC = 0x0c, //Add Immediate Carrying
ADDIC_ = 0x0d, //Add Immediate Carrying and Record
ADDI = 0x0e, //Add Immediate
ADDIS = 0x0f, //Add Immediate Shifted
BC = 0x10, //Branch Conditional
SC = 0x11, //System Call
B = 0x12, //Branch
G_13 = 0x13,
RLWIMI = 0x14, //Rotate Left Word Immediate then Mask Insert
RLWINM = 0x15, //Rotate Left Word Immediate then AND with Mask
RLWNM = 0x17, //Rotate Left Word then AND with Mask
ORI = 0x18, //OR Immediate
ORIS = 0x19, //OR Immediate Shifted
XORI = 0x1a, //XOR Immediate
XORIS = 0x1b, //XOR Immediate Shifted
ANDI_ = 0x1c, //AND Immediate
ANDIS_ = 0x1d, //AND Immediate Shifted
G_1e = 0x1e,
G_1f = 0x1f,
LWZ = 0x20, //Load Word and Zero Indexed
LWZU = 0x21, //Load Word and Zero with Update Indexed
LBZ = 0x22, //Load Byte and Zero
LBZU = 0x23, //Load Byte and Zero with Update
STW = 0x24, //Store Word
STWU = 0x25, //Store Word with Update
STB = 0x26, //Store Byte
STBU = 0x27, //Store Byte with Update
LHZ = 0x28, //Load Halfword and Zero
LHZU = 0x29, //Load Halfword and Zero with Update
LHA = 0x2a, //Load Halfword Algebraic with Update
LHAU = 0x2b, //Load Halfword Algebraic
STH = 0x2c, //Store Halfword
STHU = 0x2d, //Store Halfword with Update
LMW = 0x2e, //Load Multiple Word
STMW = 0x2f, //Store Multiple Word
LFS = 0x30, //Load Floating-Point Single
LFSU = 0x31, //Load Floating-Point Single with Update
LFD = 0x32, //Load Floating-Point Double
LFDU = 0x33, //Load Floating-Point Double with Update
STFS = 0x34, //Store Floating-Point Single
STFSU = 0x35, //Store Floating-Point Single with Update
STFD = 0x36, //Store Floating-Point Double
STFDU = 0x37, //Store Floating-Point Double with Update
LFQ = 0x38, //
LFQU = 0x39, //
G_3a = 0x3a,
G_3b = 0x3b,
G_3e = 0x3e,
G_3f = 0x3f,
};
enum PPU_MainOpcodes
{
TDI = 0x02, //Trap Doubleword Immediate
TWI = 0x03, //Trap Word Immediate
G_04 = 0x04,
MULLI = 0x07, //Multiply Low Immediate
SUBFIC = 0x08, //Subtract from Immediate Carrying
//DOZI = 0x09,
CMPLI = 0x0a, //Compare Logical Immediate
CMPI = 0x0b, //Compare Immediate
ADDIC = 0x0c, //Add Immediate Carrying
ADDIC_ = 0x0d, //Add Immediate Carrying and Record
ADDI = 0x0e, //Add Immediate
ADDIS = 0x0f, //Add Immediate Shifted
BC = 0x10, //Branch Conditional
SC = 0x11, //System Call
B = 0x12, //Branch
G_13 = 0x13,
RLWIMI = 0x14, //Rotate Left Word Immediate then Mask Insert
RLWINM = 0x15, //Rotate Left Word Immediate then AND with Mask
RLWNM = 0x17, //Rotate Left Word then AND with Mask
ORI = 0x18, //OR Immediate
ORIS = 0x19, //OR Immediate Shifted
XORI = 0x1a, //XOR Immediate
XORIS = 0x1b, //XOR Immediate Shifted
ANDI_ = 0x1c, //AND Immediate
ANDIS_ = 0x1d, //AND Immediate Shifted
G_1e = 0x1e,
G_1f = 0x1f,
LWZ = 0x20, //Load Word and Zero Indexed
LWZU = 0x21, //Load Word and Zero with Update Indexed
LBZ = 0x22, //Load Byte and Zero
LBZU = 0x23, //Load Byte and Zero with Update
STW = 0x24, //Store Word
STWU = 0x25, //Store Word with Update
STB = 0x26, //Store Byte
STBU = 0x27, //Store Byte with Update
LHZ = 0x28, //Load Halfword and Zero
LHZU = 0x29, //Load Halfword and Zero with Update
LHA = 0x2a, //Load Halfword Algebraic with Update
LHAU = 0x2b, //Load Halfword Algebraic
STH = 0x2c, //Store Halfword
STHU = 0x2d, //Store Halfword with Update
LMW = 0x2e, //Load Multiple Word
STMW = 0x2f, //Store Multiple Word
LFS = 0x30, //Load Floating-Point Single
LFSU = 0x31, //Load Floating-Point Single with Update
LFD = 0x32, //Load Floating-Point Double
LFDU = 0x33, //Load Floating-Point Double with Update
STFS = 0x34, //Store Floating-Point Single
STFSU = 0x35, //Store Floating-Point Single with Update
STFD = 0x36, //Store Floating-Point Double
STFDU = 0x37, //Store Floating-Point Double with Update
LFQ = 0x38, //
LFQU = 0x39, //
G_3a = 0x3a,
G_3b = 0x3b,
G_3e = 0x3e,
G_3f = 0x3f,
};
enum G_04Opcodes
{
VXOR = 0x262,
};
enum G_04Opcodes
{
VADDUBM = 0x0,
VMAXUB = 0x2,
VRLB = 0x4,
VCMPEQUB = 0x6,
VMULOUB = 0x8,
VADDFP = 0xa,
VMRGHB = 0xc,
VPKUHUM = 0xe,
VADDUHM = 0x40,
VMAXUH = 0x42,
VRLH = 0x44,
VCMPEQUH = 0x46,
VMULOUH = 0x48,
VSUBFP = 0x4a,
VMRGHH = 0x4c,
VPKUWUM = 0x4e,
VADDUWM = 0x80,
VMAXUW = 0x82,
VRLW = 0x84,
VCMPEQUW = 0x86,
VMRGHW = 0x8c,
VPKUHUS = 0x8e,
VCMPEQFP = 0xc6,
VPKUWUS = 0xce,
VMAXSB = 0x102,
VSLB = 0x104,
VMULOSB = 0x108,
VREFP = 0x10a,
VMRGLB = 0x10c,
VPKSHUS = 0x10e,
VMAXSH = 0x142,
VSLH = 0x144,
VMULOSH = 0x148,
VRSQRTEFP = 0x14a,
VMRGLH = 0x14c,
VPKSWUS = 0x14e,
VADDCUW = 0x180,
VMAXSW = 0x182,
VSLW = 0x184,
VEXPTEFP = 0x18a,
VMRGLW = 0x18c,
VPKSHSS = 0x18e,
VSL = 0x1c4,
VCMPGEFP = 0x1c6,
VLOGEFP = 0x1ca,
VPKSWSS = 0x1ce,
VADDUBS = 0x200,
VMINUB = 0x202,
VSRB = 0x204,
VCMPGTUB = 0x206,
VMULEUB = 0x208,
VRFIN = 0x20a,
VSPLTB = 0x20c,
VUPKHSB = 0x20e,
VADDUHS = 0x240,
VMINUH = 0x242,
VSRH = 0x244,
VCMPGTUH = 0x246,
VMULEUH = 0x248,
VRFIZ = 0x24a,
VSPLTH = 0x24c,
VUPKHSH = 0x24e,
VADDUWS = 0x280,
VMINUW = 0x282,
VSRW = 0x284,
VCMPGTUW = 0x286,
VRFIP = 0x28a,
VSPLTW = 0x28c,
VUPKLSB = 0x28e,
VSR = 0x2c4,
VCMPGTFP = 0x2c6,
VRFIM = 0x2ca,
VUPKLSH = 0x2ce,
VADDSBS = 0x300,
VMINSB = 0x302,
VSRAB = 0x304,
VCMPGTSB = 0x306,
VMULESB = 0x308,
VCFUX = 0x30a,
VSPLTISB = 0x30c,
VPKPX = 0x30e,
VADDSHS = 0x340,
VMINSH = 0x342,
VSRAH = 0x344,
VCMPGTSH = 0x346,
VMULESH = 0x348,
VCFSX = 0x34a,
VSPLTISH = 0x34c,
VUPKHPX = 0x34e,
VADDSWS = 0x380,
VMINSW = 0x382,
VSRAW = 0x384,
VCMPGTSW = 0x386,
VCTUXS = 0x38a,
VSPLTISW = 0x38c,
VCMPBFP = 0x3c6,
VCTSXS = 0x3ca,
VUPKLPX = 0x3ce,
VSUBUBM = 0x400,
VAVGUB = 0x402,
VAND = 0x404,
VCMPEQUB_ = 0x406,
VMAXFP = 0x40a,
VSLO = 0x40c,
VSUBUHM = 0x440,
VAVGUH = 0x442,
VANDC = 0x444,
VCMPEQUH_ = 0x446,
VMINFP = 0x44a,
VSRO = 0x44c,
VSUBUWM = 0x480,
VAVGUW = 0x482,
VOR = 0x484,
VCMPEQUW_ = 0x486,
VXOR = 0x4c4,
VCMPEQFP_ = 0x4c6,
VAVGSB = 0x502,
VNOR = 0x504,
VAVGSH = 0x542,
VSUBCUW = 0x580,
VAVGSW = 0x582,
VCMPGEFP_ = 0x5c6,
VSUBUBS = 0x600,
MFVSCR = 0x604,
VCMPGTUB_ = 0x606,
VSUM4UBS = 0x608,
VSUBUHS = 0x640,
MTVSCR = 0x644,
VCMPGTUH_ = 0x646,
VSUM4SHS = 0x648,
VSUBUWS = 0x680,
VCMPGTUW_ = 0x686,
VSUM2SWS = 0x688,
VCMPGTFP_ = 0x6c6,
VSUBSBS = 0x700,
VCMPGTSB_ = 0x706,
VSUM4SBS = 0x708,
VSUBSHS = 0x740,
VCMPGTSH_ = 0x746,
VSUBSWS = 0x780,
VCMPGTSW_ = 0x786,
VSUMSWS = 0x788,
VCMPBFP_ = 0x7c6,
};
enum G_13Opcodes //Field 21 - 30
{
MCRF = 0x000,
BCLR = 0x010,
CRNOR = 0x021,
CRANDC = 0x081,
ISYNC = 0x096,
CRXOR = 0x0c1,
CRNAND = 0x0e1,
CRAND = 0x101,
CREQV = 0x121,
CRORC = 0x1a1,
CROR = 0x1c1,
BCCTR = 0x210,
};
enum G_04_VA_Opcodes
{
VMHADDSHS = 0x20,
VMHRADDSHS = 0x21,
VMLADDUHM = 0x22,
VMSUMUBM = 0x24,
VMSUMMBM = 0x25,
VMSUMUHM = 0x26,
VMSUMUHS = 0x27,
VMSUMSHM = 0x28,
VMSUMSHS = 0x29,
VSEL = 0x2a,
VPERM = 0x2b,
VSLDOI = 0x2c,
VMADDFP = 0x2e,
VNMSUBFP = 0x2f,
};
enum G_1eOpcodes //Field 27 - 29
{
RLDICL = 0x0,
RLDICR = 0x1,
RLDIC = 0x2,
RLDIMI = 0x3,
};
enum G_13Opcodes //Field 21 - 30
{
MCRF = 0x000,
BCLR = 0x010,
CRNOR = 0x021,
CRANDC = 0x081,
ISYNC = 0x096,
CRXOR = 0x0c1,
CRNAND = 0x0e1,
CRAND = 0x101,
CREQV = 0x121,
CRORC = 0x1a1,
CROR = 0x1c1,
BCCTR = 0x210,
};
enum G_1fOpcodes //Field 21 - 30
{
CMP = 0x000,
TW = 0x004,
LVEBX = 0x007, //Load Vector Element Byte Indexed
SUBFC = 0x008, //Subtract from Carrying
MULHDU = 0x009,
ADDC = 0x00a,
MULHWU = 0x00b,
MFOCRF = 0x013,
LWARX = 0x014,
LDX = 0x015,
LWZX = 0x017,
SLW = 0x018,
CNTLZW = 0x01a,
SLD = 0x01b,
AND = 0x01c,
CMPL = 0x020,
LVEHX = 0x027, //Load Vector Element Halfword Indexed
SUBF = 0x028,
LDUX = 0x035, //Load Doubleword with Update Indexed
DCBST = 0x036,
CNTLZD = 0x03a,
ANDC = 0x03c,
LVEWX = 0x047, //Load Vector Element Word Indexed
MULHD = 0x049,
MULHW = 0x04b,
LDARX = 0x054,
DCBF = 0x056,
LBZX = 0x057,
LVX = 0x067,
NEG = 0x068,
LBZUX = 0x077,
NOR = 0x07c,
SUBFE = 0x088, //Subtract from Extended
ADDE = 0x08a,
MTOCRF = 0x090,
STDX = 0x095,
STWCX_ = 0x096,
STWX = 0x097,
STDUX = 0x0b5,
ADDZE = 0x0ca,
STDCX_ = 0x0d6,
STBX = 0x0d7,
STVX = 0x0e7,
MULLD = 0x0e9,
ADDME = 0x0ea,
MULLW = 0x0eb,
DCBTST = 0x0f6,
DOZ = 0x108,
ADD = 0x10a,
DCBT = 0x116,
LHZX = 0x117,
EQV = 0x11c,
ECIWX = 0x136,
LHZUX = 0x137,
XOR = 0x13c,
MFSPR = 0x153,
LHAX = 0x157,
ABS = 0x168,
MFTB = 0x173,
LHAUX = 0x177,
STHX = 0x197, //Store Halfword Indexed
ORC = 0x19c, //OR with Complement
ECOWX = 0x1b6,
OR = 0x1bc,
DIVDU = 0x1c9,
DIVWU = 0x1cb,
MTSPR = 0x1d3,
DCBI = 0x1d6,
DIVD = 0x1e9,
DIVW = 0x1eb,
LWBRX = 0x216,
LFSX = 0x217,
SRW = 0x218,
SRD = 0x21b,
LFSUX = 0x237,
SYNC = 0x256,
LFDX = 0x257,
LFDUX = 0x277,
STFSX = 0x297,
LHBRX = 0x316,
SRAW = 0x318,
SRAD = 0x31A,
SRAWI = 0x338,
SRADI1 = 0x33a, //sh_5 == 0
SRADI2 = 0x33b, //sh_5 != 0
EIEIO = 0x356,
EXTSH = 0x39a,
EXTSB = 0x3ba,
STFIWX = 0x3d7,
EXTSW = 0x3da,
ICBI = 0x3d6,
DCBZ = 0x3f6,
};
enum G_1eOpcodes //Field 27 - 29
{
RLDICL = 0x0,
RLDICR = 0x1,
RLDIC = 0x2,
RLDIMI = 0x3,
};
enum G_3aOpcodes //Field 30 - 31
{
LD = 0x0,
LDU = 0x1,
};
enum G_1fOpcodes //Field 21 - 30
{
CMP = 0x000,
TW = 0x004,
LVSL = 0x006, //Load Vector for Shift Left
LVEBX = 0x007, //Load Vector Element Byte Indexed
SUBFC = 0x008, //Subtract from Carrying
MULHDU = 0x009,
ADDC = 0x00a,
MULHWU = 0x00b,
MFOCRF = 0x013,
LWARX = 0x014,
LDX = 0x015,
LWZX = 0x017,
SLW = 0x018,
CNTLZW = 0x01a,
SLD = 0x01b,
AND = 0x01c,
CMPL = 0x020,
LVSR = 0x026, //Load Vector for Shift Right
LVEHX = 0x027, //Load Vector Element Halfword Indexed
SUBF = 0x028,
LDUX = 0x035, //Load Doubleword with Update Indexed
DCBST = 0x036,
CNTLZD = 0x03a,
ANDC = 0x03c,
LVEWX = 0x047, //Load Vector Element Word Indexed
MULHD = 0x049,
MULHW = 0x04b,
LDARX = 0x054,
DCBF = 0x056,
LBZX = 0x057,
LVX = 0x067, //Load Vector Indexed
NEG = 0x068,
LBZUX = 0x077,
NOR = 0x07c,
STVEBX = 0x087, //Store Vector Element Byte Indexed
SUBFE = 0x088, //Subtract from Extended
ADDE = 0x08a,
MTOCRF = 0x090,
STDX = 0x095,
STWCX_ = 0x096,
STWX = 0x097,
STVEHX = 0x0a7, //Store Vector Element Halfword Indexed
STDUX = 0x0b5,
STVEWX = 0x0c7, //Store Vector Element Word Indexed
ADDZE = 0x0ca,
STDCX_ = 0x0d6,
STBX = 0x0d7,
STVX = 0x0e7,
MULLD = 0x0e9,
ADDME = 0x0ea,
MULLW = 0x0eb,
DCBTST = 0x0f6,
DOZ = 0x108,
ADD = 0x10a,
DCBT = 0x116,
LHZX = 0x117,
EQV = 0x11c,
ECIWX = 0x136,
LHZUX = 0x137,
XOR = 0x13c,
MFSPR = 0x153,
DST = 0x156, //Data Stream Touch
LHAX = 0x157,
LVXL = 0x167, //Load Vector Indexed Last
ABS = 0x168,
MFTB = 0x173,
DSTST = 0x176, //Data Stream Touch for Store
LHAUX = 0x177,
STHX = 0x197, //Store Halfword Indexed
ORC = 0x19c, //OR with Complement
ECOWX = 0x1b6,
OR = 0x1bc,
DIVDU = 0x1c9,
DIVWU = 0x1cb,
MTSPR = 0x1d3,
DCBI = 0x1d6,
NAND = 0x1dc,
STVXL = 0x1e7, //Store Vector Indexed Last
DIVD = 0x1e9,
DIVW = 0x1eb,
LVLX = 0x207, //Load Vector Left Indexed
LWBRX = 0x216,
LFSX = 0x217,
SRW = 0x218,
SRD = 0x21b,
LVRX = 0x227, //Load Vector Right Indexed
LFSUX = 0x237,
SYNC = 0x256,
LFDX = 0x257,
LFDUX = 0x277,
STVLX = 0x287, //Store Vector Left Indexed
STFSX = 0x297,
STVRX = 0x2a7, //Store Vector Right Indexed
STFDX = 0x2d7, //Store Floating-Point Double Indexed
LVLXL = 0x307, //Load Vector Left Indexed Last
LHBRX = 0x316,
SRAW = 0x318,
SRAD = 0x31a,
LVRXL = 0x327, //Load Vector Right Indexed Last
DSS = 0x336, //Data Stream Stop
SRAWI = 0x338,
SRADI1 = 0x33a, //sh_5 == 0
SRADI2 = 0x33b, //sh_5 != 0
EIEIO = 0x356,
STVLXL = 0x387, //Store Vector Left Indexed Last
EXTSH = 0x39a,
STVRXL = 0x3a7, //Store Vector Right Indexed Last
EXTSB = 0x3ba,
STFIWX = 0x3d7,
EXTSW = 0x3da,
ICBI = 0x3d6,
DCBZ = 0x3f6,
};
enum G_3bOpcodes //Field 26 - 30
{
FDIVS = 0x12,
FSUBS = 0x14,
FADDS = 0x15,
FSQRTS = 0x16,
FRES = 0x18,
FMULS = 0x19,
FMSUBS = 0x1c,
FMADDS = 0x1d,
FNMSUBS = 0x1e,
FNMADDS = 0x1f,
};
enum G_3aOpcodes //Field 30 - 31
{
LD = 0x0,
LDU = 0x1,
};
enum G_3eOpcodes //Field 30 - 31
{
STD = 0x0,
STDU = 0x1,
};
enum G_3bOpcodes //Field 26 - 30
{
FDIVS = 0x12,
FSUBS = 0x14,
FADDS = 0x15,
FSQRTS = 0x16,
FRES = 0x18,
FMULS = 0x19,
FMSUBS = 0x1c,
FMADDS = 0x1d,
FNMSUBS = 0x1e,
FNMADDS = 0x1f,
};
enum G_3fOpcodes //Field 21 - 30
{
MTFSB1 = 0x026,
MCRFS = 0x040,
MTFSB0 = 0x046,
MTFSFI = 0x086,
MFFS = 0x247,
MTFSF = 0x2c7,
enum G_3eOpcodes //Field 30 - 31
{
STD = 0x0,
STDU = 0x1,
};
FCMPU = 0x000,
FRSP = 0x00c,
FCTIW = 0x00e,
FCTIWZ = 0x00f,
FDIV = 0x012,
FSUB = 0x014,
FADD = 0x015,
FSQRT = 0x016,
FSEL = 0x017,
FMUL = 0x019,
FRSQRTE = 0x01a,
FMSUB = 0x01c,
FMADD = 0x01d,
FNMSUB = 0x01e,
FNMADD = 0x01f,
FCMPO = 0x020,
FNEG = 0x028,
FMR = 0x048,
FNABS = 0x088,
FABS = 0x108,
FCTID = 0x32e,
FCTIDZ = 0x32f,
FCFID = 0x34e,
};
enum G_3fOpcodes //Field 21 - 30
{
MTFSB1 = 0x026,
MCRFS = 0x040,
MTFSB0 = 0x046,
MTFSFI = 0x086,
MFFS = 0x247,
MTFSF = 0x2c7,
//118
FCMPU = 0x000,
FRSP = 0x00c,
FCTIW = 0x00e,
FCTIWZ = 0x00f,
FDIV = 0x012,
FSUB = 0x014,
FADD = 0x015,
FSQRT = 0x016,
FSEL = 0x017,
FMUL = 0x019,
FRSQRTE = 0x01a,
FMSUB = 0x01c,
FMADD = 0x01d,
FNMSUB = 0x01e,
FNMADD = 0x01f,
FCMPO = 0x020,
FNEG = 0x028,
FMR = 0x048,
FNABS = 0x088,
FABS = 0x108,
FCTID = 0x32e,
FCTIDZ = 0x32f,
FCFID = 0x34e,
};
}
class PPU_Opcodes
{
@ -273,7 +454,163 @@ public:
ADD_OPCODE(TWI,(OP_uIMM to, OP_REG ra, OP_sIMM simm16));
START_OPCODES_GROUP(G_04)
ADD_OPCODE(VXOR,(OP_REG vrd, OP_REG vra, OP_REG vrb));
ADD_OPCODE(MFVSCR,(OP_REG vd));
ADD_OPCODE(MTVSCR,(OP_REG vb));
ADD_OPCODE(VADDCUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDSBS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDSHS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDSWS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDUBM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDUBS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDUHM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDUHS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDUWM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VADDUWS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAND,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VANDC,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAVGSB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAVGSH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAVGSW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAVGUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAVGUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VAVGUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCFSX,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VCFUX,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VCMPBFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPBFP_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQFP_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQUB_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQUH_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPEQUW_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGEFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGEFP_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTFP_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTSB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTSB_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTSH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTSH_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTSW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTSW_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTUB_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTUH_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCMPGTUW_,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VCTSXS,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VCTUXS,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VEXPTEFP,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VLOGEFP,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VMADDFP,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMAXFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMAXSB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMAXSH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMAXSW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMAXUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMAXUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMAXUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMHADDSHS,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMHRADDSHS,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMINFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMINSB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMINSH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMINSW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMINUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMINUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMINUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMLADDUHM,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMRGHB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMRGHH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMRGHW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMRGLB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMRGLH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMRGLW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMSUMMBM,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMSUMSHM,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMSUMSHS,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMSUMUBM,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMSUMUHM,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMSUMUHS,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VMULESB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULESH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULEUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULEUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULOSB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULOSH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULOUB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VMULOUH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VNMSUBFP,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VNOR,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VOR,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPERM,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VPKPX,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKSHSS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKSHUS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKSWSS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKSWUS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKUHUM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKUHUS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKUWUM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VPKUWUS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VREFP,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VRFIM,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VRFIN,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VRFIP,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VRFIZ,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VRLB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VRLH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VRLW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VRSQRTEFP,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VSEL,(OP_REG vd, OP_REG va, OP_REG vb, OP_REG vc));
ADD_OPCODE(VSL,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSLB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSLDOI,(OP_REG vd, OP_REG va, OP_REG vb, OP_uIMM sh));
ADD_OPCODE(VSLH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSLO,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSLW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSPLTB,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VSPLTH,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VSPLTISB,(OP_REG vd, OP_sIMM simm5));
ADD_OPCODE(VSPLTISH,(OP_REG vd, OP_sIMM simm5));
ADD_OPCODE(VSPLTISW,(OP_REG vd, OP_sIMM simm5));
ADD_OPCODE(VSPLTW,(OP_REG vd, OP_uIMM uimm5, OP_REG vb));
ADD_OPCODE(VSR,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRAB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRAH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRAW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRB,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRH,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRO,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSRW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBCUW,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBFP,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBSBS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBSHS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBSWS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBUBM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBUBS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBUHM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBUHS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBUWM,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUBUWS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUMSWS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUM2SWS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUM4SBS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUM4SHS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VSUM4UBS,(OP_REG vd, OP_REG va, OP_REG vb));
ADD_OPCODE(VUPKHPX,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VUPKHSB,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VUPKHSH,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VUPKLPX,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VUPKLSB,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VUPKLSH,(OP_REG vd, OP_REG vb));
ADD_OPCODE(VXOR,(OP_REG vd, OP_REG va, OP_REG vb));
END_OPCODES_GROUP(G_04);
ADD_OPCODE(MULLI,(OP_REG rd, OP_REG ra, OP_sIMM simm16));
@ -323,12 +660,13 @@ public:
START_OPCODES_GROUP(G_1f)
/*0x000*/ADD_OPCODE(CMP,(OP_REG crfd, OP_REG l, OP_REG ra, OP_REG rb));
/*0x004*/ADD_OPCODE(TW,(OP_uIMM to, OP_REG ra, OP_REG rb));
/*0x006*/ADD_OPCODE(LVSL,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x007*/ADD_OPCODE(LVEBX,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x008*/ADD_OPCODE(SUBFC,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x009*/ADD_OPCODE(MULHDU,(OP_REG rd, OP_REG ra, OP_REG rb, bool rc));
/*0x00a*/ADD_OPCODE(ADDC,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x00b*/ADD_OPCODE(MULHWU,(OP_REG rd, OP_REG ra, OP_REG rb, bool rc));
/*0x013*/ADD_OPCODE(MFOCRF,(OP_REG a, OP_REG fxm, OP_REG rd));
/*0x013*/ADD_OPCODE(MFOCRF,(OP_uIMM a, OP_REG rd, OP_uIMM crm));
/*0x014*/ADD_OPCODE(LWARX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x015*/ADD_OPCODE(LDX,(OP_REG ra, OP_REG rs, OP_REG rb));
/*0x017*/ADD_OPCODE(LWZX,(OP_REG rd, OP_REG ra, OP_REG rb));
@ -337,6 +675,7 @@ public:
/*0x01b*/ADD_OPCODE(SLD,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x01c*/ADD_OPCODE(AND,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x020*/ADD_OPCODE(CMPL,(OP_REG bf, OP_REG l, OP_REG ra, OP_REG rb));
/*0x026*/ADD_OPCODE(LVSR,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x027*/ADD_OPCODE(LVEHX,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x028*/ADD_OPCODE(SUBF,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x035*/ADD_OPCODE(LDUX,(OP_REG rd, OP_REG ra, OP_REG rb));
@ -349,21 +688,24 @@ public:
/*0x054*/ADD_OPCODE(LDARX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x056*/ADD_OPCODE(DCBF,(OP_REG ra, OP_REG rb));
/*0x057*/ADD_OPCODE(LBZX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x067*/ADD_OPCODE(LVX,(OP_REG vrd, OP_REG ra, OP_REG rb));
/*0x067*/ADD_OPCODE(LVX,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x068*/ADD_OPCODE(NEG,(OP_REG rd, OP_REG ra, OP_REG oe, bool rc));
/*0x077*/ADD_OPCODE(LBZUX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x07c*/ADD_OPCODE(NOR,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x087*/ADD_OPCODE(STVEBX,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x088*/ADD_OPCODE(SUBFE,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x08a*/ADD_OPCODE(ADDE,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x090*/ADD_OPCODE(MTOCRF,(OP_REG fxm, OP_REG rs));
/*0x090*/ADD_OPCODE(MTOCRF,(OP_REG crm, OP_REG rs));
/*0x095*/ADD_OPCODE(STDX,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x096*/ADD_OPCODE(STWCX_,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x097*/ADD_OPCODE(STWX,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x0a7*/ADD_OPCODE(STVEHX,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x0b5*/ADD_OPCODE(STDUX,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x0c7*/ADD_OPCODE(STVEWX,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x0ca*/ADD_OPCODE(ADDZE,(OP_REG rd, OP_REG ra, OP_REG oe, bool rc));
/*0x0d6*/ADD_OPCODE(STDCX_,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x0d7*/ADD_OPCODE(STBX,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x0e7*/ADD_OPCODE(STVX,(OP_REG vrd, OP_REG ra, OP_REG rb));
/*0x0e7*/ADD_OPCODE(STVX,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x0e9*/ADD_OPCODE(MULLD,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x0ea*/ADD_OPCODE(ADDME,(OP_REG rd, OP_REG ra, OP_REG oe, bool rc));
/*0x0eb*/ADD_OPCODE(MULLW,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
@ -376,9 +718,12 @@ public:
/*0x137*/ADD_OPCODE(LHZUX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x13c*/ADD_OPCODE(XOR,(OP_REG rs, OP_REG ra, OP_REG rb, bool rc));
/*0x153*/ADD_OPCODE(MFSPR,(OP_REG rd, OP_REG spr));
/*0x156*/ADD_OPCODE(DST,(OP_REG ra, OP_REG rb, OP_uIMM strm, OP_uIMM t));
/*0x157*/ADD_OPCODE(LHAX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x167*/ADD_OPCODE(LVXL,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x168*/ADD_OPCODE(ABS,(OP_REG rd, OP_REG ra, OP_REG oe, bool rc));
/*0x173*/ADD_OPCODE(MFTB,(OP_REG rd, OP_REG spr));
/*0x176*/ADD_OPCODE(DSTST,(OP_REG ra, OP_REG rb, OP_uIMM strm, OP_uIMM t));
/*0x177*/ADD_OPCODE(LHAUX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x197*/ADD_OPCODE(STHX,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x19c*/ADD_OPCODE(ORC,(OP_REG rs, OP_REG ra, OP_REG rb, bool rc));
@ -388,25 +733,37 @@ public:
/*0x1cb*/ADD_OPCODE(DIVWU,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x1d3*/ADD_OPCODE(MTSPR,(OP_REG spr, OP_REG rs));
/*0x1d6*///DCBI
/*0x1dc*/ADD_OPCODE(NAND,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x1e7*/ADD_OPCODE(STVXL,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x1e9*/ADD_OPCODE(DIVD,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x1eb*/ADD_OPCODE(DIVW,(OP_REG rd, OP_REG ra, OP_REG rb, OP_REG oe, bool rc));
/*0x207*/ADD_OPCODE(LVLX,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x216*/ADD_OPCODE(LWBRX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x217*/ADD_OPCODE(LFSX,(OP_REG frd, OP_REG ra, OP_REG rb));
/*0x218*/ADD_OPCODE(SRW,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x21b*/ADD_OPCODE(SRD,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x227*/ADD_OPCODE(LVRX,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x237*/ADD_OPCODE(LFSUX,(OP_REG frd, OP_REG ra, OP_REG rb));
/*0x256*/ADD_OPCODE(SYNC,(OP_REG l));
/*0x257*/ADD_OPCODE(LFDX,(OP_REG frd, OP_REG ra, OP_REG rb));
/*0x277*/ADD_OPCODE(LFDUX,(OP_REG frd, OP_REG ra, OP_REG rb));
/*0x297*/ADD_OPCODE(STFSX,(OP_REG rs, OP_REG ra, OP_REG rb));
/*0x287*/ADD_OPCODE(STVLX,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x297*/ADD_OPCODE(STFSX,(OP_REG frs, OP_REG ra, OP_REG rb));
/*0x2a7*/ADD_OPCODE(STVRX,(OP_REG vs, OP_REG ra, OP_REG rb));
/*0x2d7*/ADD_OPCODE(STFDX,(OP_REG frs, OP_REG ra, OP_REG rb));
/*0x307*/ADD_OPCODE(LVLXL,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x316*/ADD_OPCODE(LHBRX,(OP_REG rd, OP_REG ra, OP_REG rb));
/*0x318*/ADD_OPCODE(SRAW,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x31A*/ADD_OPCODE(SRAD,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x31a*/ADD_OPCODE(SRAD,(OP_REG ra, OP_REG rs, OP_REG rb, bool rc));
/*0x327*/ADD_OPCODE(LVRXL,(OP_REG vd, OP_REG ra, OP_REG rb));
/*0x336*/ADD_OPCODE(DSS,(OP_uIMM strm, OP_uIMM a));
/*0x338*/ADD_OPCODE(SRAWI,(OP_REG ra, OP_REG rs, OP_REG sh, bool rc));
/*0x33a*/ADD_OPCODE(SRADI1,(OP_REG ra, OP_REG rs, OP_REG sh, bool rc));
/*0x33b*/ADD_OPCODE(SRADI2,(OP_REG ra, OP_REG rs, OP_REG sh, bool rc));
/*0x356*/ADD_OPCODE(EIEIO,());
/*0x387*/ADD_OPCODE(STVLXL,(OP_REG sd, OP_REG ra, OP_REG rb));
/*0x39a*/ADD_OPCODE(EXTSH,(OP_REG ra, OP_REG rs, bool rc));
/*0x3a7*/ADD_OPCODE(STVRXL,(OP_REG sd, OP_REG ra, OP_REG rb));
/*0x3ba*/ADD_OPCODE(EXTSB,(OP_REG ra, OP_REG rs, bool rc));
/*0x3d7*/ADD_OPCODE(STFIWX,(OP_REG frs, OP_REG ra, OP_REG rb));
/*0x3da*/ADD_OPCODE(EXTSW,(OP_REG ra, OP_REG rs, bool rc));
@ -493,7 +850,7 @@ public:
ADD_OPCODE(FCFID,(OP_REG frd, OP_REG frb, bool rc));
END_OPCODES_GROUP(G_3f);
ADD_OPCODE(UNK,(const s32 code, const s32 opcode, const s32 gcode));
ADD_OPCODE(UNK,(const u32 code, const u32 opcode, const u32 gcode));
};
#undef START_OPCODES_GROUP

View File

@ -4,11 +4,20 @@
#include "Emu/Cell/PPUInterpreter.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/SysCalls/SysCalls.h"
extern gcmInfo gcm_info;
PPUThread::PPUThread() : PPCThread(PPC_THREAD_PPU)
PPUThread& GetCurrentPPUThread()
{
PPCThread* thread = GetCurrentPPCThread();
if(!thread || thread->IsSPU()) throw wxString("GetCurrentPPUThread: bad thread");
return *(PPUThread*)thread;
}
PPUThread::PPUThread()
: PPCThread(PPC_THREAD_PPU)
, SysCalls(*this)
{
Reset();
}
@ -26,13 +35,14 @@ void PPUThread::DoReset()
memset(GPR, 0, sizeof(GPR));
memset(SPRG, 0, sizeof(SPRG));
CR.CR = 0;
LR = 0;
CTR = 0;
USPRG = 0;
TB = 0;
XER.XER = 0;
CR.CR = 0;
LR = 0;
CTR = 0;
USPRG0 = 0;
TB = 0;
XER.XER = 0;
FPSCR.FPSCR = 0;
VSCR.VSCR = 0;
cycle = 0;
@ -40,50 +50,6 @@ void PPUThread::DoReset()
reserve_addr = 0;
}
void PPUThread::SetBranch(const u64 pc)
{
u64 fid, waddr;
if(Memory.MemFlags.IsFlag(pc, waddr, fid))
{
GPR[3] = SysCallsManager.DoFunc(fid, *this);
if((s64)GPR[3] < 0 && fid != 0x72a577ce && fid != 0x8461e528) ConLog.Write("Func[0x%llx] done with code [0x%llx]! #pc: 0x%llx", fid, GPR[3], PC);
#ifdef HLE_CALL_LOG
else ConLog.Warning("Func[0xll%x] done with code [0x%llx]! #pc: 0x%llx", fid, GPR[3], PC);
#endif
//ConLog.Warning("Func waddr: 0x%llx", waddr);
const u64 addr = Emu.GetTLSAddr();
Memory.Write32(waddr, addr);
Memory.Write32(addr, PC + 4);
if(fid == 0x744680a2) Memory.Write32(addr+4, GPR[3]);
//Memory.Write32(addr+4, Emu.GetTLSMemsz());
}
else if(pc == Emu.GetRSXCallback())
{
//ConLog.Warning("gcm: callback(context=0x%llx, count=0x%llx) #pc: 0x%llx", GPR[3], GPR[4], PC);
CellGcmContextData& ctx = *(CellGcmContextData*)Memory.GetMemFromAddr(GPR[3]);
CellGcmControl& ctrl = *(CellGcmControl*)Memory.GetMemFromAddr(gcm_info.control_addr);
while(ctrl.put != ctrl.get) Sleep(1);
const u32 reserve = GPR[4];
ctx.current = re(re(ctx.begin) + reserve);
Emu.GetGSManager().GetRender().Pause();
ctrl.put = ctrl.get = re(reserve);
Emu.GetGSManager().GetRender().Resume();
GPR[3] = 0;
PPCThread::SetBranch(PC + 4);
return;
}
PPCThread::SetBranch(pc);
}
void PPUThread::AddArgv(const wxString& arg)
{
stack_point -= arg.Len() + 1;
@ -97,6 +63,7 @@ void PPUThread::InitRegs()
const u32 entry = Memory.Read32(PC);
const u32 rtoc = Memory.Read32(PC + 4);
ConLog.Write("entry = 0x%x", entry);
ConLog.Write("rtoc = 0x%x", rtoc);
SetPc(entry);
@ -123,6 +90,7 @@ void PPUThread::InitRegs()
return;
}
/*
const s32 tls_size = Emu.GetTLSFilesz() * thread_num;
if(tls_size >= Emu.GetTLSMemsz())
@ -131,6 +99,7 @@ void PPUThread::InitRegs()
Emu.Pause();
return;
}
*/
stack_point = Memory.AlignAddr(stack_point, 0x200) - 0x200;
@ -154,13 +123,14 @@ void PPUThread::InitRegs()
//GPR[10] = 0x131700;
GPR[11] = 0x80;
GPR[12] = Emu.GetMallocPageSize();
GPR[13] = 0x10007060;
GPR[13] = Memory.MainMem.Alloc(0x10000) + 0x7060;
GPR[28] = GPR[4];
GPR[29] = GPR[3];
GPR[31] = GPR[5];
CTR = PC;
CR.CR = 0x22000082;
VSCR.NJ = 1;
}
u64 PPUThread::GetFreeStackSize() const
@ -193,8 +163,11 @@ void PPUThread::DoPause()
void PPUThread::DoStop()
{
delete m_dec;
m_dec = 0;
if(m_dec)
{
delete m_dec;
m_dec = nullptr;
}
}
bool dump_enable = false;
@ -220,36 +193,31 @@ void PPUThread::DoCode(const s32 code)
m_dec->Decode(code);
}
bool FPRdouble::IsINF(double d)
bool FPRdouble::IsINF(PPCdouble d)
{
return wxFinite(d) ? 1 : 0;
}
bool FPRdouble::IsNaN(double d)
bool FPRdouble::IsNaN(PPCdouble d)
{
return wxIsNaN(d) ? 1 : 0;
}
bool FPRdouble::IsQNaN(double d)
bool FPRdouble::IsQNaN(PPCdouble d)
{
return
((*(u64*)&d & DOUBLE_EXP) == DOUBLE_EXP) &&
((*(u64*)&d & 0x0007fffffffffffULL) == DOUBLE_ZERO) &&
((*(u64*)&d & 0x000800000000000ULL) == 0x000800000000000ULL);
return d.GetType() == FPR_QNAN;
}
bool FPRdouble::IsSNaN(double d)
bool FPRdouble::IsSNaN(PPCdouble d)
{
return
((*(u64*)&d & DOUBLE_EXP) == DOUBLE_EXP) &&
((*(u64*)&d & DOUBLE_FRAC) != DOUBLE_ZERO) &&
((*(u64*)&d & 0x0008000000000000ULL) == DOUBLE_ZERO);
return d.GetType() == FPR_SNAN;
}
int FPRdouble::Cmp(double a, double b)
int FPRdouble::Cmp(PPCdouble a, PPCdouble b)
{
if(a < b) return CR_LT;
if(a > b) return CR_GT;
if(a == b) return CR_EQ;
return CR_SO;
}

View File

@ -1,5 +1,7 @@
#pragma once
#include "Emu/Cell/PPCThread.h"
#include "Emu/SysCalls/SysCalls.h"
#include "rpcs3.h"
enum
{
@ -215,14 +217,14 @@ union CRhdr
struct
{
u8 cr0 : 4;
u8 cr1 : 4;
u8 cr2 : 4;
u8 cr3 : 4;
u8 cr4 : 4;
u8 cr5 : 4;
u8 cr6 : 4;
u8 cr7 : 4;
u8 cr6 : 4;
u8 cr5 : 4;
u8 cr4 : 4;
u8 cr3 : 4;
u8 cr2 : 4;
u8 cr1 : 4;
u8 cr0 : 4;
};
};
@ -239,6 +241,49 @@ union XERhdr
};
};
union VSCRhdr
{
u32 VSCR;
struct
{
/*
Saturation. A sticky status bit indicating that some field in a saturating instruction saturated since the last
time SAT was cleared. In other words when SAT = 1 it remains set to 1 until it is cleared to 0 by an
mtvscr instruction.
1 The vector saturate instruction implicitly sets when saturation has occurred on the results one of
the vector instructions having saturate in its name:
Move To VSCR (mtvscr)
Vector Add Integer with Saturation (vaddubs, vadduhs, vadduws, vaddsbs, vaddshs,
vaddsws)
Vector Subtract Integer with Saturation (vsububs, vsubuhs, vsubuws, vsubsbs, vsubshs,
vsubsws)
Vector Multiply-Add Integer with Saturation (vmhaddshs, vmhraddshs)
Vector Multiply-Sum with Saturation (vmsumuhs, vmsumshs, vsumsws)
Vector Sum-Across with Saturation (vsumsws, vsum2sws, vsum4sbs, vsum4shs,
vsum4ubs)
Vector Pack with Saturation (vpkuhus, vpkuwus, vpkshus, vpkswus, vpkshss, vpkswss)
Vector Convert to Fixed-Point with Saturation (vctuxs, vctsxs)
0 Indicates no saturation occurred; mtvscr can explicitly clear this bit.
*/
u32 SAT : 1;
u32 X : 15;
/*
Non-Java. A mode control bit that determines whether vector floating-point operations will be performed
in a Java-IEEE-C9Xcompliant mode or a possibly faster non-Java/non-IEEE mode.
0 The Java-IEEE-C9Xcompliant mode is selected. Denormalized values are handled as specified
by Java, IEEE, and C9X standard.
1 The non-Java/non-IEEEcompliant mode is selected. If an element in a source vector register
contains a denormalized value, the value 0 is used instead. If an instruction causes an underflow
exception, the corresponding element in the target VR is cleared to 0. In both cases, the 0
has the same sign as the denormalized or underflowing value.
*/
u32 NJ : 1;
u32 Y : 15;
};
};
enum FPRType
{
FPR_NORM,
@ -280,35 +325,53 @@ struct PPCdouble
};
FPRType type;
operator double&() { return _double; }
operator const double&() const { return _double; }
u32 GetType()
PPCdouble& operator = (const PPCdouble& r)
{
if(exp > 0 && exp < 0x7ff) return sign ? FPR_NN : FPR_PN;
if(frac)
{
if(exp) return FPR_QNAN;
return sign ? FPR_INF : FPR_PINF;
}
return sign ? FPR_NZ : FPR_PZ;
_u64 = r._u64;
type = UpdateType();
return *this;
}
u32 To32()
FPRType UpdateType() const
{
if (exp > 896 || (!frac && !exp))
const int fpc = _fpclass(_double);
switch(fpc)
{
return ((_u64 >> 32) & 0xc0000000) | ((_u64 >> 29) & 0x3fffffff);
case _FPCLASS_SNAN: return FPR_SNAN;
case _FPCLASS_QNAN: return FPR_QNAN;
case _FPCLASS_NINF: return FPR_NINF;
case _FPCLASS_NN: return FPR_NN;
case _FPCLASS_ND: return FPR_ND;
case _FPCLASS_NZ: return FPR_NZ;
case _FPCLASS_PZ: return FPR_PZ;
case _FPCLASS_PD: return FPR_PD;
case _FPCLASS_PN: return FPR_PN;
case _FPCLASS_PINF: return FPR_PINF;
}
if (exp >= 874)
{
return ((0x80000000 | (frac >> 21)) >> (905 - exp)) | (_u64 >> 32) & 0x80000000;
}
throw wxString::Format("PPCdouble::UpdateType() -> unknown fpclass (0x%04x).", fpc);
}
//?
return ((_u64 >> 32) & 0xc0000000) | ((_u64 >> 29) & 0x3fffffff);
FPRType GetType() const
{
return type;
}
u32 To32() const
{
float res = _double;
return (u32&)res;
}
u64 To64() const
{
return (u64&)_double;
}
u32 GetZerosCount()
@ -369,370 +432,76 @@ struct PPCdouble
struct FPRdouble
{
static PPCdouble ConvertToIntegerMode(const PPCdouble& d, FPSCRhdr& fpscr, bool is_64, u32 round_mode)
{
PPCdouble ret;
if(d.exp == 2047)
{
if (d.frac == 0)
{
ret.type = FPR_INF;
fpscr.FI = 0;
fpscr.FR = 0;
fpscr.VXCVI = 1;
if(fpscr.VE == 0)
{
if(is_64)
{
return d.sign ? 0x8000000000000000 : 0x7FFFFFFFFFFFFFFF;
}
else
{
return d.sign ? 0x80000000 : 0x7FFFFFFF;
}
fpscr.FPRF = 0;
}
}
else if(d.nan == 0)
{
ret.type = FPR_SNAN;
fpscr.FI = 0;
fpscr.FR = 0;
fpscr.VXCVI = 1;
fpscr.VXSNAN = 1;
if(fpscr.VE == 0)
{
return is_64 ? 0x8000000000000000 : 0x80000000;
fpscr.FPRF = 0;
}
}
else
{
ret.type = FPR_QNAN;
fpscr.FI = 0;
fpscr.FR = 0;
fpscr.VXCVI = 1;
if(fpscr.VE == 0)
{
return is_64 ? 0x8000000000000000 : 0x80000000;
fpscr.FPRF = 0;
}
}
}
else if(d.exp > 1054)
{
fpscr.FI = 0;
fpscr.FR = 0;
fpscr.VXCVI = 1;
if(fpscr.VE == 0)
{
if(is_64)
{
return d.sign ? 0x8000000000000000 : 0x7FFFFFFFFFFFFFFF;
}
else
{
return d.sign ? 0x80000000 : 0x7FFFFFFF;
}
fpscr.FPRF = 0;
}
}
ret.sign = d.sign;
if(d.exp > 0)
{
ret.exp = d.exp - 1023;
ret.frac = 1 | d.frac;
}
else if(d.exp == 0)
{
ret.exp = -1022;
ret.frac = d.frac;
}
/*
if(d.exp == 0)
{
if (d.frac == 0)
{
d.type = FPR_ZERO;
}
else
{
const u32 z = d.GetZerosCount() - 8;
d.frac <<= z + 3;
d.exp -= 1023 - 1 + z;
d.type = FPR_NORM;
}
}
else
{
d.exp -= 1023;
d.type = FPR_NORM;
d.nan = 1;
d.frac <<= 3;
}
*/
return ret;
}
static u32 ConvertToFloatMode(PPCdouble& d, u32 RN)
{
/*
u32 fpscr = 0;
switch (d.type)
{
case FPR_NORM:
d.exp += 1023;
if (d.exp > 0)
{
fpscr |= Round(d, RN);
if(d.nan)
{
d.exp++;
d.frac >>= 4;
}
else
{
d.frac >>= 3;
}
if(d.exp >= 2047)
{
d.exp = 2047;
d.frac = 0;
fpscr |= FPSCR_OX;
}
}
else
{
d.exp = -(s64)d.exp + 1;
if(d.exp <= 56)
{
d.frac >>= d.exp;
fpscr |= Round(d, RN);
d.frac <<= 1;
if(d.nan)
{
d.exp = 1;
d.frac = 0;
}
else
{
d.exp = 0;
d.frac >>= 4;
fpscr |= FPSCR_UX;
}
}
else
{
d.exp = 0;
d.frac = 0;
fpscr |= FPSCR_UX;
}
}
break;
case FPR_ZERO:
d.exp = 0;
d.frac = 0;
break;
case FPR_NAN:
d.exp = 2047;
d.frac = 1;
break;
case FPR_INF:
d.exp = 2047;
d.frac = 0;
break;
}
return fpscr;
*/
return 0;
}
static u32 Round(PPCdouble& d, u32 RN)
{
switch(RN)
{
case FPSCR_RN_NEAR:
if(d.frac & 0x7)
{
if((d.frac & 0x7) != 4 || d.frac & 0x8)
{
d.frac += 4;
}
return FPSCR_XX;
}
return 0;
case FPSCR_RN_ZERO:
if(d.frac & 0x7) return FPSCR_XX;
return 0;
case FPSCR_RN_PINF:
if(!d.sign && (d.frac & 0x7))
{
d.frac += 8;
return FPSCR_XX;
}
return 0;
case FPSCR_RN_MINF:
if(d.sign && (d.frac & 0x7))
{
d.frac += 8;
return FPSCR_XX;
}
return 0;
}
return 0;
}
static const u64 double_sign = 0x8000000000000000ULL;
static const u64 double_frac = 0x000FFFFFFFFFFFFFULL;
static bool IsINF(double d);
static bool IsNaN(double d);
static bool IsQNaN(double d);
static bool IsSNaN(double d);
static int Cmp(double a, double b);
static bool IsINF(PPCdouble d);
static bool IsNaN(PPCdouble d);
static bool IsQNaN(PPCdouble d);
static bool IsSNaN(PPCdouble d);
static int Cmp(PPCdouble a, PPCdouble b);
};
union VPR_reg
{
//__m128i _m128i;
u128 _u128;
s128 _i128;
s128 _s128;
u64 _u64[2];
s64 _i64[2];
s64 _s64[2];
u32 _u32[4];
s32 _i32[4];
s32 _s32[4];
u16 _u16[8];
s16 _i16[8];
s16 _s16[8];
u8 _u8[16];
s8 _i8[16];
//struct { float x, y, z, w; };
s8 _s8[16];
float _f[4];
double _d[2];
VPR_reg() { Clear(); }
VPR_reg(const __m128i val){_u128._u64[0] = val.m128i_u64[0]; _u128._u64[1] = val.m128i_u64[1];}
VPR_reg(const u128 val) { _u128 = val; }
VPR_reg(const u64 val) { Clear(); _u64[0] = val; }
VPR_reg(const u32 val) { Clear(); _u32[0] = val; }
VPR_reg(const u16 val) { Clear(); _u16[0] = val; }
VPR_reg(const u8 val) { Clear(); _u8[0] = val; }
VPR_reg(const s128 val) { _i128 = val; }
VPR_reg(const s64 val) { Clear(); _i64[0] = val; }
VPR_reg(const s32 val) { Clear(); _i32[0] = val; }
VPR_reg(const s16 val) { Clear(); _i16[0] = val; }
VPR_reg(const s8 val) { Clear(); _i8[0] = val; }
operator u128() const { return _u128; }
operator s128() const { return _i128; }
operator u64() const { return _u64[0]; }
operator s64() const { return _i64[0]; }
operator u32() const { return _u32[0]; }
operator s32() const { return _i32[0]; }
operator u16() const { return _u16[0]; }
operator s16() const { return _i16[0]; }
operator u8() const { return _u8[0]; }
operator s8() const { return _i8[0]; }
operator __m128i() { __m128i ret; ret.m128i_u64[0]=_u128._u64[0]; ret.m128i_u64[1]=_u128._u64[1]; return ret; }
operator bool() const { return _u64[0] != 0 || _u64[1] != 0; }
wxString ToString() const
wxString ToString(bool hex=false) const
{
return wxString::Format("%08x%08x%08x%08x", _u32[3], _u32[2], _u32[1], _u32[0]);
if(hex) return wxString::Format("%08x%08x%08x%08x", _u32[3], _u32[2], _u32[1], _u32[0]);
return wxString::Format("x: %g y: %g z: %g w: %g", _f[3], _f[2], _f[1], _f[0]);
}
VPR_reg operator ^ (VPR_reg right) { return _mm_xor_si128(*this, right); }
VPR_reg operator | (VPR_reg right) { return _mm_or_si128 (*this, right); }
VPR_reg operator & (VPR_reg right) { return _mm_and_si128(*this, right); }
u8 GetBit(u8 bit)
{
if(bit < 64) return (_u64[0] >> bit) & 0x1;
VPR_reg operator ^ (__m128i right) { return _mm_xor_si128(*this, right); }
VPR_reg operator | (__m128i right) { return _mm_or_si128 (*this, right); }
VPR_reg operator & (__m128i right) { return _mm_and_si128(*this, right); }
return (_u64[1] >> (bit - 64)) & 0x1;
}
bool operator == (const VPR_reg& right){ return _u64[0] == right._u64[0] && _u64[1] == right._u64[1]; }
void SetBit(u8 bit, u8 value)
{
if(bit < 64)
{
_u64[0] &= ~(1 << bit);
_u64[0] |= (value & 0x1) << bit;
bool operator == (const u128 right) { return _u64[0] == right._u64[0] && _u64[1] == right._u64[1]; }
bool operator == (const s128 right) { return _i64[0] == right._i64[0] && _i64[1] == right._i64[1]; }
bool operator == (const u64 right) { return _u64[0] == (u64)right && _u64[1] == 0; }
bool operator == (const s64 right) { return _i64[0] == (s64)right && _i64[1] == 0; }
bool operator == (const u32 right) { return _u64[0] == (u64)right && _u64[1] == 0; }
bool operator == (const s32 right) { return _i64[0] == (s64)right && _i64[1] == 0; }
bool operator == (const u16 right) { return _u64[0] == (u64)right && _u64[1] == 0; }
bool operator == (const s16 right) { return _i64[0] == (s64)right && _i64[1] == 0; }
bool operator == (const u8 right) { return _u64[0] == (u64)right && _u64[1] == 0; }
bool operator == (const s8 right) { return _i64[0] == (s64)right && _i64[1] == 0; }
return;
}
bool operator != (const VPR_reg& right){ return !(*this == right); }
bool operator != (const u128 right) { return !(*this == right); }
bool operator != (const u64 right) { return !(*this == right); }
bool operator != (const u32 right) { return !(*this == right); }
bool operator != (const u16 right) { return !(*this == right); }
bool operator != (const u8 right) { return !(*this == right); }
bool operator != (const s128 right) { return !(*this == right); }
bool operator != (const s64 right) { return !(*this == right); }
bool operator != (const s32 right) { return !(*this == right); }
bool operator != (const s16 right) { return !(*this == right); }
bool operator != (const s8 right) { return !(*this == right); }
bit -= 64;
s64& d(const u32 c) { return _i64[1 - c]; }
u64& ud(const u32 c) { return _u64[1 - c]; }
s32& w(const u32 c) { return _i32[3 - c]; }
u32& uw(const u32 c) { return _u32[3 - c]; }
s16& h(const u32 c) { return _i16[7 - c]; }
u16& uh(const u32 c) { return _u16[7 - c]; }
s8& b(const u32 c) { return _i8[15 - c]; }
u8& ub(const u32 c) { return _u8[15 - c]; }
_u64[1] &= ~(1 << bit);
_u64[1] |= (value & 0x1) << bit;
}
void Clear() { memset(this, 0, sizeof(*this)); }
};
/*
struct VPR_table
{
VPR_reg t[32];
operator VPR_reg*() { return t; }
VPR_reg& operator [] (int index)
{
return t[index];
}
}
*/
static const s32 MAX_INT_VALUE = 0x7fffffff;
class PPUThread : public PPCThread
class PPUThread
: public PPCThread
, public SysCalls
{
public:
double FPR[32]; //Floating Point Register
PPCdouble FPR[32]; //Floating Point Register
FPSCRhdr FPSCR; //Floating Point Status and Control Register
u64 GPR[32]; //General-Purpose Register
VPR_reg VPR[32];
@ -786,12 +555,16 @@ public:
MSRhdr MSR; //Machine State Register
PVRhdr PVR; //Processor Version Register
VSCRhdr VSCR; // Vector Status and Control Register
u64 LR; //SPR 0x008 : Link Register
u64 CTR; //SPR 0x009 : Count Register
s32 USPRG; //SPR 0x100 : User-SPR General-Purpose Registers
s32 SPRG[8]; //SPR 0x100 - 0x107 : SPR General-Purpose Registers
union
{
u64 USPRG0; //SPR 0x100 : User-SPR General-Purpose Register 0
u64 SPRG[8]; //SPR 0x100 - 0x107 : SPR General-Purpose Registers
};
//TBR : Time-Base Registers
union
@ -818,14 +591,14 @@ public:
{
switch(n)
{
case 7: return CR.cr0;
case 6: return CR.cr1;
case 5: return CR.cr2;
case 4: return CR.cr3;
case 3: return CR.cr4;
case 2: return CR.cr5;
case 1: return CR.cr6;
case 0: return CR.cr7;
case 0: return CR.cr0;
case 1: return CR.cr1;
case 2: return CR.cr2;
case 3: return CR.cr3;
case 4: return CR.cr4;
case 5: return CR.cr5;
case 6: return CR.cr6;
case 7: return CR.cr7;
}
return 0;
@ -835,14 +608,14 @@ public:
{
switch(n)
{
case 7: CR.cr0 = value; break;
case 6: CR.cr1 = value; break;
case 5: CR.cr2 = value; break;
case 4: CR.cr3 = value; break;
case 3: CR.cr4 = value; break;
case 2: CR.cr5 = value; break;
case 1: CR.cr6 = value; break;
case 0: CR.cr7 = value; break;
case 0: CR.cr0 = value; break;
case 1: CR.cr1 = value; break;
case 2: CR.cr2 = value; break;
case 3: CR.cr3 = value; break;
case 4: CR.cr4 = value; break;
case 5: CR.cr5 = value; break;
case 6: CR.cr6 = value; break;
case 7: CR.cr7 = value; break;
}
}
@ -850,14 +623,14 @@ public:
{
switch(n)
{
case 7: value ? CR.cr0 |= bit : CR.cr0 &= ~bit; break;
case 6: value ? CR.cr1 |= bit : CR.cr1 &= ~bit; break;
case 5: value ? CR.cr2 |= bit : CR.cr2 &= ~bit; break;
case 4: value ? CR.cr3 |= bit : CR.cr3 &= ~bit; break;
case 3: value ? CR.cr4 |= bit : CR.cr4 &= ~bit; break;
case 2: value ? CR.cr5 |= bit : CR.cr5 &= ~bit; break;
case 1: value ? CR.cr6 |= bit : CR.cr6 &= ~bit; break;
case 0: value ? CR.cr7 |= bit : CR.cr7 &= ~bit; break;
case 0: value ? CR.cr0 |= bit : CR.cr0 &= ~bit; break;
case 1: value ? CR.cr1 |= bit : CR.cr1 &= ~bit; break;
case 2: value ? CR.cr2 |= bit : CR.cr2 &= ~bit; break;
case 3: value ? CR.cr3 |= bit : CR.cr3 &= ~bit; break;
case 4: value ? CR.cr4 |= bit : CR.cr4 &= ~bit; break;
case 5: value ? CR.cr5 |= bit : CR.cr5 &= ~bit; break;
case 6: value ? CR.cr6 |= bit : CR.cr6 &= ~bit; break;
case 7: value ? CR.cr7 |= bit : CR.cr7 &= ~bit; break;
}
}
@ -916,17 +689,31 @@ public:
virtual wxString RegsToString()
{
wxString ret = PPCThread::RegsToString();
for(uint i=0; i<32; ++i) ret += wxString::Format("GPR[%d] = 0x%llx\n", i, GPR[i]);
for(uint i=0; i<32; ++i) ret += wxString::Format("FPR[%d] = %.6G\n", i, FPR[i]);
for(uint i=0; i<32; ++i) ret += wxString::Format("VPR[%d] = 0x%s [%s]\n", i, VPR[i].ToString(true), VPR[i].ToString());
ret += wxString::Format("CR = 0x%08x\n", CR);
ret += wxString::Format("LR = 0x%llx\n", LR);
ret += wxString::Format("CTR = 0x%llx\n", CTR);
ret += wxString::Format("XER = 0x%llx\n", XER);
ret += wxString::Format("FPSCR = 0x%x\n", FPSCR);
ret += wxString::Format("XER = 0x%llx [CA=%lld | OV=%lld | SO=%lld]\n", XER, XER.CA, XER.OV, XER.SO);
ret += wxString::Format("FPSCR = 0x%x "
"[RN=%d | NI=%d | XE=%d | ZE=%d | UE=%d | OE=%d | VE=%d | "
"VXCVI=%d | VXSQRT=%d | VXSOFT=%d | FPRF=%d | "
"FI=%d | FR=%d | VXVC=%d | VXIMZ=%d | "
"VXZDZ=%d | VXIDI=%d | VXISI=%d | VXSNAN=%d | "
"XX=%d | ZX=%d | UX=%d | OX=%d | VX=%d | FEX=%d | FX=%d]\n",
FPSCR,
FPSCR.RN,
FPSCR.NI, FPSCR.XE, FPSCR.ZE, FPSCR.UE, FPSCR.OE, FPSCR.VE,
FPSCR.VXCVI, FPSCR.VXSQRT, FPSCR.VXSOFT, FPSCR.FPRF,
FPSCR.FI, FPSCR.FR, FPSCR.VXVC, FPSCR.VXIMZ,
FPSCR.VXZDZ, FPSCR.VXIDI, FPSCR.VXISI, FPSCR.VXSNAN,
FPSCR.XX, FPSCR.ZX, FPSCR.UX, FPSCR.OX, FPSCR.VX, FPSCR.FEX, FPSCR.FX);
return ret;
}
void SetBranch(const u64 pc);
virtual void AddArgv(const wxString& arg);
public:
@ -940,6 +727,8 @@ protected:
virtual void DoResume();
virtual void DoStop();
private:
public:
virtual void DoCode(const s32 code);
};
};
PPUThread& GetCurrentPPUThread();

View File

@ -31,18 +31,20 @@ class SPU_Decoder : public Decoder
OP_REG RA() const { return GetField(18, 24); }
OP_REG RB() const { return GetField(11, 17); }
OP_sIMM i7() const { return GetField(11, 17); }
OP_sIMM i10() const { return GetField(8, 17); }
OP_sIMM i16() const { return GetField(9, 24); }
OP_sIMM i18() const { return GetField(7, 24); }
OP_uIMM i7() const { return GetField(11, 17); }
OP_uIMM i8() const { return GetField(10, 17); }
OP_uIMM i10() const { return GetField(8, 17); }
OP_uIMM i16() const { return GetField(9, 24); }
OP_uIMM i18() const { return GetField(7, 24); }
OP_sIMM ROH() const { return GetField(16, 17); }
OP_sIMM ROL() const { return GetField(25, 31); }
OP_sIMM RO() const { return ROL()/* | (ROH() << 8)*/; }
OP_uIMM ROH() const { return GetField(16, 17); }
OP_uIMM ROL() const { return GetField(25, 31); }
OP_uIMM RO() const { return ROL() | (ROH() << 8); }
OP_uIMM RR() const { return GetField(0, 10); }
OP_uIMM RRR() const { return GetField(0, 3); }
OP_uIMM RI7() const { return GetField(0, 10); }
OP_uIMM RI8() const { return GetField(0, 9); }
OP_uIMM RI10() const { return GetField(0, 7); }
OP_uIMM RI16() const { return GetField(0, 8); }
OP_uIMM RI18() const { return GetField(0, 6); }
@ -93,59 +95,219 @@ public:
virtual void Decode(const u32 code)
{
using namespace SPU_opcodes;
m_code = code;
switch(RR()) //& RI7 //0 - 10
{
ADD_OPCODE(STOP,(GetField(18, 31)));
ADD_OPCODE(LNOP,());
ADD_OPCODE(SYNC,(GetField(11)));
ADD_OPCODE(DSYNC,());
ADD_OPCODE(MFSPR,(RT(), RA()));
ADD_OPCODE(RDCH,(RT(), RA()));
ADD_OPCODE(RCHCNT,(RT(), RA()));
ADD_OPCODE(SF,(RT(), RA(), RB()));
ADD_OPCODE(OR,(RT(), RA(), RB()));
ADD_OPCODE(BG,(RT(), RA(), RB()));
ADD_OPCODE(SFH,(RT(), RA(), RB()));
ADD_OPCODE(NOR,(RT(), RA(), RB()));
ADD_OPCODE(ABSDB,(RT(), RA(), RB()));
ADD_OPCODE(ROT,(RT(), RA(), RB()));
ADD_OPCODE(ROTM,(RT(), RA(), RB()));
ADD_OPCODE(ROTMA,(RT(), RA(), RB()));
ADD_OPCODE(SHL,(RT(), RA(), RB()));
ADD_OPCODE(ROTH,(RT(), RA(), RB()));
ADD_OPCODE(ROTHM,(RT(), RA(), RB()));
ADD_OPCODE(ROTMAH,(RT(), RA(), RB()));
ADD_OPCODE(SHLH,(RT(), RA(), RB()));
ADD_OPCODE(ROTI,(RT(), RA(), RB()));
ADD_OPCODE(ROTMI,(RT(), RA(), RB()));
ADD_OPCODE(ROTMAI,(RT(), RA(), RB()));
ADD_OPCODE(SHLI,(RT(), RA(), i7()));
ADD_OPCODE(ROTHI,(RT(), RA(), i7()));
ADD_OPCODE(ROTHMI,(RT(), RA(), i7()));
ADD_OPCODE(ROTMAHI,(RT(), RA(), i7()));
ADD_OPCODE(SHLHI,(RT(), RA(), i7()));
ADD_OPCODE(A,(RT(), RA(), RB()));
ADD_OPCODE(SPU_AND,(RT(), RA(), RB()));
ADD_OPCODE(LQX,(RT(), RA(), RB()));
ADD_OPCODE(AND,(RT(), RA(), RB()));
ADD_OPCODE(CG,(RT(), RA(), RB()));
ADD_OPCODE(AH,(RT(), RA(), RB()));
ADD_OPCODE(NAND,(RT(), RA(), RB()));
ADD_OPCODE(AVGB,(RT(), RA(), RB()));
ADD_OPCODE(MTSPR,(RT(), RA()));
ADD_OPCODE(WRCH,(RA(), RT()));
ADD_OPCODE(BIZ,(RT(), RA()));
ADD_OPCODE(BINZ,(RT(), RA()));
ADD_OPCODE(BIHZ,(RT(), RA()));
ADD_OPCODE(BIHNZ,(RT(), RA()));
ADD_OPCODE(STOPD,(RT(), RA(), RB()));
ADD_OPCODE(STQX,(RT(), RA(), RB()));
ADD_OPCODE(BI,(RA()));
ADD_OPCODE(BISL,(RT(), RA()));
ADD_OPCODE(IRET,(RA()));
ADD_OPCODE(BISLED,(RT(), RA()));
ADD_OPCODE(HBR,(GetField(11), RO(), RA()));
ADD_OPCODE(GB,(RT(), RA()));
ADD_OPCODE(GBH,(RT(), RA()));
ADD_OPCODE(GBB,(RT(), RA()));
ADD_OPCODE(FSM,(RT(), RA()));
ADD_OPCODE(FSMH,(RT(), RA()));
ADD_OPCODE(FSMB,(RT(), RA()));
ADD_OPCODE(FREST,(RT(), RA()));
ADD_OPCODE(FRSQEST,(RT(), RA()));
ADD_OPCODE(LQX,(RT(), RA(), RB()));
ADD_OPCODE(ROTQBYBI,(RT(), RA(), RB()));
ADD_OPCODE(ROTQMBYBI,(RT(), RA(), RB()));
ADD_OPCODE(SHLQBYBI,(RT(), RA(), RB()));
ADD_OPCODE(CBX,(RT(), RA(), RB()));
ADD_OPCODE(CHX,(RT(), RA(), RB()));
ADD_OPCODE(CWX,(RT(), RA(), RB()));
ADD_OPCODE(CDX,(RT(), RA(), RB()));
ADD_OPCODE(ROTQBI,(RT(), RA(), RB()));
ADD_OPCODE(ROTQMBI,(RT(), RA(), RB()));
ADD_OPCODE(SHLQBI,(RT(), RA(), RB()));
ADD_OPCODE(ROTQBY,(RT(), RA(), RB()));
ADD_OPCODE(ROTQMBY,(RT(), RA(), RB()));
ADD_OPCODE(SHLQBY,(RT(), RA(), RB()));
ADD_OPCODE(ORX,(RT(), RA()));
ADD_OPCODE(CBD,(RT(), RA(), exts7(i7())));
ADD_OPCODE(CHD,(RT(), RA(), exts7(i7())));
ADD_OPCODE(CWD,(RT(), RA(), exts7(i7())));
ADD_OPCODE(CDD,(RT(), RA(), exts7(i7())));
ADD_OPCODE(ROTQBII,(RT(), RA(), i7()));
ADD_OPCODE(ROTQMBII,(RT(), RA(), i7()));
ADD_OPCODE(SHLQBII,(RT(), RA(), i7()));
ADD_OPCODE(ROTQBYI,(RT(), RA(), i7()));
ADD_OPCODE(ROTQMBYI,(RT(), RA(), i7()));
ADD_OPCODE(SHLQBYI,(RT(), RA(), i7()));
ADD_OPCODE(SPU_NOP,(RT()));
ADD_OPCODE(NOP,(RT()));
ADD_OPCODE(CGT,(RT(), RA(), RB()));
ADD_OPCODE(XOR,(RT(), RA(), RB()));
ADD_OPCODE(CGTH,(RT(), RA(), RB()));
ADD_OPCODE(EQV,(RT(), RA(), RB()));
ADD_OPCODE(CGTB,(RT(), RA(), RB()));
ADD_OPCODE(SUMB,(RT(), RA(), RB()));
ADD_OPCODE(HGT,(RT(), RA(), RB()));
ADD_OPCODE(CLZ,(RT(), RA()));
ADD_OPCODE(XSWD,(RT(), RA()));
ADD_OPCODE(XSHW,(RT(), RA()));
ADD_OPCODE(CNTB,(RT(), RA()));
ADD_OPCODE(XSBH,(RT(), RA()));
ADD_OPCODE(CLGT,(RT(), RA(), RB()));
ADD_OPCODE(ANDC,(RT(), RA(), RB()));
ADD_OPCODE(FCGT,(RT(), RA(), RB()));
ADD_OPCODE(DFCGT,(RT(), RA(), RB()));
ADD_OPCODE(FA,(RT(), RA(), RB()));
ADD_OPCODE(FS,(RT(), RA(), RB()));
ADD_OPCODE(FM,(RT(), RA(), RB()));
ADD_OPCODE(CLGTH,(RT(), RA(), RB()));
ADD_OPCODE(ORC,(RT(), RA(), RB()));
ADD_OPCODE(FCMGT,(RT(), RA(), RB()));
ADD_OPCODE(DFCMGT,(RT(), RA(), RB()));
ADD_OPCODE(DFA,(RT(), RA(), RB()));
ADD_OPCODE(DFS,(RT(), RA(), RB()));
ADD_OPCODE(DFM,(RT(), RA(), RB()));
ADD_OPCODE(CLGTB,(RT(), RA(), RB()));
ADD_OPCODE(HLGT,(RT(), RA(), RB()));
ADD_OPCODE(DFMA,(RT(), RA(), RB()));
ADD_OPCODE(DFMS,(RT(), RA(), RB()));
ADD_OPCODE(DFNMS,(RT(), RA(), RB()));
ADD_OPCODE(DFNMA,(RT(), RA(), RB()));
ADD_OPCODE(CEQ,(RT(), RA(), RB()));
ADD_OPCODE(MPYHHU,(RT(), RA(), RB()));
ADD_OPCODE(ADDX,(RT(), RA(), RB()));
ADD_OPCODE(SFX,(RT(), RA(), RB()));
ADD_OPCODE(CGX,(RT(), RA(), RB()));
ADD_OPCODE(BGX,(RT(), RA(), RB()));
ADD_OPCODE(MPYHHA,(RT(), RA(), RB()));
ADD_OPCODE(MPYHHAU,(RT(), RA(), RB()));
ADD_OPCODE(FSCRRD,(RT()));
ADD_OPCODE(FESD,(RT(), RA()));
ADD_OPCODE(FRDS,(RT(), RA()));
ADD_OPCODE(FSCRWR,(RT(), RA()));
ADD_OPCODE(DFTSV,(RT(), RA(), i7()));
ADD_OPCODE(FCEQ,(RT(), RA(), RB()));
ADD_OPCODE(DFCEQ,(RT(), RA(), RB()));
ADD_OPCODE(MPY,(RT(), RA(), RB()));
ADD_OPCODE(MPYH,(RT(), RA(), RB()));
ADD_OPCODE(MPYHH,(RT(), RA(), RB()));
ADD_OPCODE(MPYS,(RT(), RA(), RB()));
ADD_OPCODE(CEQH,(RT(), RA(), RB()));
ADD_OPCODE(FCMEQ,(RT(), RA(), RB()));
ADD_OPCODE(DFCMEQ,(RT(), RA(), RB()));
ADD_OPCODE(MPYU,(RT(), RA(), RB()));
ADD_OPCODE(CEQB,(RT(), RA(), RB()));
ADD_OPCODE(FI,(RT(), RA(), RB()));
ADD_OPCODE(HEQ,(RT(), RA(), RB()));
}
switch(RI8()) //0 - 9
{
ADD_OPCODE(CFLTS,(RT(), RA(), i8()));
ADD_OPCODE(CFLTU,(RT(), RA(), i8()));
ADD_OPCODE(CSFLT,(RT(), RA(), i8()));
ADD_OPCODE(CUFLT,(RT(), RA(), i8()));
}
switch(RI16()) //0 - 8
{
ADD_OPCODE(BRZ,(RT(), exts16(i16())));
ADD_OPCODE(STQA,(RT(), exts16(i16())));
ADD_OPCODE(BRNZ,(RT(), exts16(i16())));
ADD_OPCODE(BRHZ,(RT(), exts16(i16())));
ADD_OPCODE(BRHNZ,(RT(), exts16(i16())));
ADD_OPCODE(STQR,(RT(), i16()));
ADD_OPCODE(BRA,(exts16(i16())));
ADD_OPCODE(LQA,(RT(), exts16(i16())));
ADD_OPCODE(BRASL,(RT(), exts16(i16())));
ADD_OPCODE(BR,(exts16(i16())));
ADD_OPCODE(FSMBI,(RT(), i16()));
ADD_OPCODE(BRSL,(RT(), exts16(i16())));
ADD_OPCODE(IL,(RT(), exts16(i16())));
ADD_OPCODE(LQR,(RT(), exts16(i16())));
ADD_OPCODE(IL,(RT(), exts16(i16())));
ADD_OPCODE(ILHU,(RT(), i16()));
ADD_OPCODE(ILH,(RT(), i16()));
ADD_OPCODE(IOHL,(RT(), i16()));
}
switch(RI10()) //0 - 7
{
ADD_OPCODE(SPU_ORI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(ORI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(ORHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(ORBI,(RT(), RA(), i10()));
ADD_OPCODE(SFI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(SFHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(ANDI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(ANDHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(ANDBI,(RT(), RA(), i10()));
ADD_OPCODE(AI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(AHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(STQD,(RT(), exts10(i10()) << 4, RA()));
ADD_OPCODE(LQD,(RT(), exts10(i10()) << 4, RA()));
ADD_OPCODE(CLGTI,(RT(), RA(), i10()));
ADD_OPCODE(CLGTHI,(RT(), RA(), i10()));
ADD_OPCODE(CEQI,(RT(), RA(), i10()));
ADD_OPCODE(XORI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(XORHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(XORBI,(RT(), RA(), i10()));
ADD_OPCODE(CGTI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CGTHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CGTBI,(RT(), RA(), i10()));
ADD_OPCODE(HGTI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CLGTI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CLGTHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CLGTBI,(RT(), RA(), i10()));
ADD_OPCODE(HLGTI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(MPYI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(MPYUI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CEQI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CEQHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(CEQBI,(RT(), RA(), i10()));
ADD_OPCODE(HEQI,(RT(), RA(), exts10(i10())));
}
switch(RI18()) //0 - 6
{
ADD_OPCODE(HBRA,(RO(), i16() << 2));
ADD_OPCODE(HBRR,(RO(), exts16(i16())));
ADD_OPCODE(ILA,(RT(), i18()));
}
@ -154,6 +316,10 @@ public:
{
ADD_OPCODE(SELB,(RC(), RA(), RB(), RT()));
ADD_OPCODE(SHUFB,(RC(), RA(), RB(), RT()));
ADD_OPCODE(MPYA,(RC(), RA(), RB(), RT()));
ADD_OPCODE(FNMS,(RC(), RA(), RB(), RT()));
ADD_OPCODE(FMA,(RC(), RA(), RB(), RT()));
ADD_OPCODE(FMS,(RC(), RA(), RB(), RT()));
}
m_op.UNK(m_code, 0, 0);

View File

@ -58,6 +58,18 @@ private:
{
Write("lnop");
}
virtual void SYNC(OP_uIMM Cbit)
{
Write(wxString::Format("sync %d", Cbit));
}
virtual void DSYNC()
{
Write("dsync");
}
virtual void MFSPR(OP_REG rt, OP_REG sa)
{
Write(wxString::Format("mfspr %s,%s", spu_reg_name[rt], spu_reg_name[sa])); // Are SPR mapped on the GPR or are there 128 additional registers ?
}
virtual void RDCH(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("rdch %s,%s", spu_reg_name[rt], spu_ch_name[ra]));
@ -70,26 +82,142 @@ private:
{
Write(wxString::Format("sf %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void OR(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("or %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void BG(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("bg %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SFH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("sfh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void NOR(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("nor %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ABSDB(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("absdb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rot %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTM(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTMA(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotma %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SHL(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("shl %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("roth %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTHM(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rothm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTMAH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotmah %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SHLH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("shlh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("roti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTMI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotmi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTMAI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotmai %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void SHLI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("shli %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTHI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rothi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTHMI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rothmi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTMAHI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotmahi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void SHLHI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("shlhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void A(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("a %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SPU_AND(OP_REG rt, OP_REG ra, OP_REG rb)
virtual void AND(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("and %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void LQX(OP_REG rt, OP_REG ra, OP_REG rb)
virtual void CG(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("lqx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
Write(wxString::Format("cg %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void AH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("ah %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void NAND(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("nand %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void AVGB(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("avgb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MTSPR(OP_REG rt, OP_REG sa)
{
Write(wxString::Format("mtspr %s,%s", spu_reg_name[rt], spu_reg_name[sa]));
}
virtual void WRCH(OP_REG ra, OP_REG rt)
{
Write(wxString::Format("wrch %s,%s", spu_ch_name[ra], spu_reg_name[rt]));
}
virtual void BIZ(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("biz %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void BINZ(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("binz %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void BIHZ(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("bihz %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void BIHNZ(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("bihnz %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void STOPD(OP_REG rc, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("bihnz %s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void STQX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("stqx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
@ -102,40 +230,418 @@ private:
{
Write(wxString::Format("bisl %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void IRET(OP_REG ra)
{
Write(wxString::Format("iret %s", spu_reg_name[ra]));
}
virtual void BISLED(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("bisled %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void HBR(OP_REG p, OP_REG ro, OP_REG ra)
{
Write(wxString::Format("hbr 0x%x,%s", DisAsmBranchTarget(ro), spu_reg_name[ra]));
}
virtual void GB(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("gb %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void GBH(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("gbh %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void GBB(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("gbb %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FSM(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("fsm %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FSMH(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("fsmh %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FSMB(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("fsmb %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FREST(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("frest %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FRSQEST(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("frsqest %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void LQX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("lqx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTQBYBI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotqbybi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTQMBYBI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotqmbybi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SHLQBYBI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("shlqbybi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CBX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cbx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CHX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("chx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CWX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cwx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CDX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cdx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTQBI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotqbi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTQMBI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotqmbi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SHLQBI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("shlqbi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTQBY(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotqby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], rb));
Write(wxString::Format("rotqby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ROTQMBY(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("rotqmby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SHLQBY(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("shlqby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ORX(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("orx %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void CBD(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("cbd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void CHD(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("chd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void CWD(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("cwd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void CDD(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("cdd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTQBII(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotqbii %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTQMBII(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotqmbii %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void SHLQBII(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("shlqbii %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTQBYI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotqbyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void ROTQMBYI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("rotqmbyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void SHLQBYI(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("shlqbyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void SPU_NOP(OP_REG rt)
virtual void NOP(OP_REG rt)
{
Write(wxString::Format("nop %s", spu_reg_name[rt]));
}
virtual void CGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void XOR(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("xor %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CGTH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cgth %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void EQV(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("eqv %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CGTB(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cgtb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SUMB(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("sumb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void HGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("hgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CLZ(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("clz %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void XSWD(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("xswd %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void XSHW(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("xshw %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void CNTB(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("cntb %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void XSBH(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("xsbh %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void CLGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("clgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ANDC(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("andc %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FCGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fcgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFCGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfcgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FA(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fa %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FS(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fs %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FM(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CLGTH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("clgth %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ORC(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("orc %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FCMGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fcmgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFCMGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfcmgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFA(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfa %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFS(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfs %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFM(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CLGTB(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("clgtb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void HLGT(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("hlgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFMA(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfma %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFMS(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfms %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFNMS(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfnms %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFNMA(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfnma %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CEQ(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("ceq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYHHU(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpyhhu %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void ADDX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("addx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void SFX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("sfx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CGX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("cgx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void BGX(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("bgx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYHHA(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpyhha %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYHHAU(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpyhhau %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FSCRRD(OP_REG rt)
{
Write(wxString::Format("fscrrd %s", spu_reg_name[rt]));
}
virtual void FESD(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("fesd %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FRDS(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("frds %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void FSCRWR(OP_REG rt, OP_REG ra)
{
Write(wxString::Format("fscrwr %s,%s", spu_reg_name[rt], spu_reg_name[ra]));
}
virtual void DFTSV(OP_REG rt, OP_REG ra, OP_sIMM i7)
{
Write(wxString::Format("dftsv %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7));
}
virtual void FCEQ(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fceq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFCEQ(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfceq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPY(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpy %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpyh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYHH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpyhh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYS(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpys %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CEQH(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("ceqh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FCMEQ(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fcmeq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void DFCMEQ(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("dfcmeq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void MPYU(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("mpyu %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void CEQB(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("ceqb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void FI(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("fi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
virtual void HEQ(OP_REG rt, OP_REG ra, OP_REG rb)
{
Write(wxString::Format("heq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]));
}
//0 - 9
virtual void CFLTS(OP_REG rt, OP_REG ra, OP_sIMM i8)
{
Write(wxString::Format("cflts %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8));
}
virtual void CFLTU(OP_REG rt, OP_REG ra, OP_sIMM i8)
{
Write(wxString::Format("cfltu %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8));
}
virtual void CSFLT(OP_REG rt, OP_REG ra, OP_sIMM i8)
{
Write(wxString::Format("csflt %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8));
}
virtual void CUFLT(OP_REG rt, OP_REG ra, OP_sIMM i8)
{
Write(wxString::Format("cuflt %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8));
}
//0 - 8
virtual void BRZ(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("brz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void STQA(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("stqa %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void BRNZ(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("brnz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void BRHZ(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("brhz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
@ -148,6 +654,18 @@ private:
{
Write(wxString::Format("stqr %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void BRA(OP_sIMM i16)
{
Write(wxString::Format("bra 0x%x", DisAsmBranchTarget(i16)));
}
virtual void LQA(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("lqa %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void BRASL(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("brasl %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void BR(OP_sIMM i16)
{
Write(wxString::Format("br 0x%x", DisAsmBranchTarget(i16)));
@ -160,20 +678,61 @@ private:
{
Write(wxString::Format("brsl %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void IL(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("il %s,%d", spu_reg_name[rt], i16));
}
virtual void LQR(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("lqr %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16)));
}
virtual void IL(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("il %s,%d", spu_reg_name[rt], i16));
}
virtual void ILHU(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("ilhu %s,%d", spu_reg_name[rt], i16));
}
virtual void ILH(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("ilh %s,%d", spu_reg_name[rt], i16));
}
virtual void IOHL(OP_REG rt, OP_sIMM i16)
{
Write(wxString::Format("iolh %s,%d", spu_reg_name[rt], i16));
}
//0 - 7
virtual void SPU_ORI(OP_REG rt, OP_REG ra, OP_sIMM i10)
virtual void ORI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("ori %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void ORHI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("orhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void ORBI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("orbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void SFI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("sfi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void SFHI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("sfhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void ANDI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("andi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void ANDHI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("andhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void ANDBI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("andbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void AI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("ai %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
@ -190,6 +749,34 @@ private:
{
Write(wxString::Format("lqd %s,%d(%s)", spu_reg_name[rt], i10, spu_reg_name[ra]));
}
virtual void XORI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("xori %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void XORHI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("xorhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void XORBI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("xorbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CGTI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("cgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CGTHI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("cgthi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CGTBI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("cgtbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void HGTI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("hgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CLGTI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("clgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
@ -198,12 +785,44 @@ private:
{
Write(wxString::Format("clgthi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CLGTBI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("clgtbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void HLGTI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("hlgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void MPYI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("mpyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void MPYUI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("mpyui %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CEQI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("ceqi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CEQHI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("ceqhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void CEQBI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("ceqbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
virtual void HEQI(OP_REG rt, OP_REG ra, OP_sIMM i10)
{
Write(wxString::Format("heqi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10));
}
//0 - 6
virtual void HBRA(OP_sIMM ro, OP_sIMM i16)
{
Write(wxString::Format("hbra 0x%x,0x%x", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16)));
}
virtual void HBRR(OP_sIMM ro, OP_sIMM i16)
{
Write(wxString::Format("hbrr 0x%x,0x%x", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16)));
@ -222,6 +841,22 @@ private:
{
Write(wxString::Format("shufb %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]));
}
virtual void MPYA(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt)
{
Write(wxString::Format("mpya %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]));
}
virtual void FNMS(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt)
{
Write(wxString::Format("fnms %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]));
}
virtual void FMA(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt)
{
Write(wxString::Format("fma %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]));
}
virtual void FMS(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt)
{
Write(wxString::Format("fms %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]));
}
virtual void UNK(const s32 code, const s32 opcode, const s32 gcode)
{

File diff suppressed because it is too large Load Diff

View File

@ -8,65 +8,230 @@
#define ADD_NULL_OPCODE(name) virtual void(##name##)()=0
#define END_OPCODES_GROUP(x) /*x*/
enum SPU_0_10_Opcodes
namespace SPU_opcodes
{
STOP = 0x0,
LNOP = 0x1,
RDCH = 0xd,
RCHCNT = 0xf,
SF = 0x40,
SHLI = 0x7b,
A = 0xc0,
SPU_AND = 0xc1,
LQX = 0x1c4,
WRCH = 0x10d,
STQX = 0x144,
BI = 0x1a8,
BISL = 0x1a9,
HBR = 0x1ac,
CWX = 0x1d6,
ROTQBY = 0x1dc,
ROTQBYI = 0x1fc,
SHLQBYI = 0x1ff,
SPU_NOP = 0x201,
CLGT = 0x2c0,
};
enum SPU_0_10_Opcodes
{
STOP = 0x0,
LNOP = 0x1,
SYNC = 0x2,
DSYNC = 0x3,
MFSPR = 0xc,
RDCH = 0xd,
RCHCNT = 0xf,
SF = 0x40,
OR = 0x41,
BG = 0x42,
SFH = 0x48,
NOR = 0x49,
ABSDB = 0x53,
ROT = 0x58,
ROTM = 0x59,
ROTMA = 0x5a,
SHL = 0x5b,
ROTH = 0x5c,
ROTHM = 0x5d,
ROTMAH = 0x5e,
SHLH = 0x5f,
ROTI = 0x78,
ROTMI = 0x79,
ROTMAI = 0x7a,
SHLI = 0x7b,
ROTHI = 0x7c,
ROTHMI = 0x7d,
ROTMAHI = 0x7e,
SHLHI = 0x7f,
A = 0xc0,
AND = 0xc1,
CG = 0xc2,
AH = 0xc8,
NAND = 0xc9,
AVGB = 0xd3,
MTSPR = 0x10c,
WRCH = 0x10d,
BIZ = 0x128,
BINZ = 0x129,
BIHZ = 0x12a,
BIHNZ = 0x12b,
STOPD = 0x140,
STQX = 0x144,
BI = 0x1a8,
BISL = 0x1a9,
IRET = 0x1aa,
BISLED = 0x1ab,
HBR = 0x1ac,
GB = 0x1b0,
GBH = 0x1b1,
GBB = 0x1b2,
FSM = 0x1b4,
FSMH = 0x1b5,
FSMB = 0x1b6,
FREST = 0x1b8,
FRSQEST = 0x1b9,
LQX = 0x1c4,
ROTQBYBI = 0x1cc,
ROTQMBYBI = 0x1cd,
SHLQBYBI = 0x1cf,
CBX = 0x1d4,
CHX = 0x1d5,
CWX = 0x1d6,
CDX = 0x1d7,
ROTQBI = 0x1d8,
ROTQMBI = 0x1d9,
SHLQBI = 0x1db,
ROTQBY = 0x1dc,
ROTQMBY = 0x1dd,
SHLQBY = 0x1df,
ORX = 0x1f0,
CBD = 0x1f4,
CHD = 0x1f5,
CWD = 0x1f6,
CDD = 0x1f7,
ROTQBII = 0x1f8,
ROTQMBII = 0x1f9,
SHLQBII = 0x1fb,
ROTQBYI = 0x1fc,
ROTQMBYI = 0x1fd,
SHLQBYI = 0x1ff,
NOP = 0x201,
CGT = 0x240,
XOR = 0x241,
CGTH = 0x248,
EQV = 0x249,
CGTB = 0x250,
SUMB = 0x253,
HGT = 0x258,
CLZ = 0x2a5,
XSWD = 0x2a6,
XSHW = 0x2ae,
CNTB = 0x2b4,
XSBH = 0x2b6,
CLGT = 0x2c0,
ANDC = 0x2c1,
FCGT = 0x2c2,
DFCGT = 0x2c3,
FA = 0x2c4,
FS = 0x2c5,
FM = 0x2c6,
CLGTH = 0x2c8,
ORC = 0x2c9,
FCMGT = 0x2ca,
DFCMGT = 0x2cb,
DFA = 0x2cc,
DFS = 0x2cd,
DFM = 0x2ce,
CLGTB = 0x2d0,
HLGT = 0x2d8,
DFMA = 0x35c,
DFMS = 0x35d,
DFNMS = 0x35e,
DFNMA = 0x35f,
CEQ = 0x3c0,
MPYHHU = 0x3ce,
ADDX = 0x340,
SFX = 0x341,
CGX = 0x342,
BGX = 0x343,
MPYHHA = 0x346,
MPYHHAU = 0x34e,
FSCRRD = 0x398,
FESD = 0x3b8,
FRDS = 0x3b9,
FSCRWR = 0x3ba,
DFTSV = 0x3bf,
FCEQ = 0x3c2,
DFCEQ = 0x3c3,
MPY = 0x3c4,
MPYH = 0x3c5,
MPYHH = 0x3c6,
MPYS = 0x3c7,
CEQH = 0x3c8,
FCMEQ = 0x3ca,
DFCMEQ = 0x3cb,
MPYU = 0x3cc,
CEQB = 0x3d0,
FI = 0x3d4,
HEQ = 0x3d8,
};
enum SPU_0_8_Opcodes
{
BRZ = 0x40,
BRHZ = 0x44,
BRHNZ = 0x46,
STQR = 0x47,
BR = 0x64,
FSMBI = 0x65,
BRSL = 0x66,
LQR = 0x67,
IL = 0x81,
};
enum SPU_0_9_Opcodes
{
CFLTS = 0x1d8,
CFLTU = 0x1d9,
CSFLT = 0x1da,
CUFLT = 0x1db,
};
enum SPU_0_7_Opcodes
{
SPU_ORI = 0x4,
AI = 0x1c,
AHI = 0x1d,
STQD = 0x24,
LQD = 0x34,
CLGTI = 0x5c,
CLGTHI = 0x5d,
CEQI = 0x7c,
};
enum SPU_0_8_Opcodes
{
BRZ = 0x40,
STQA = 0x41,
BRNZ = 0x42,
BRHZ = 0x44,
BRHNZ = 0x46,
STQR = 0x47,
BRA = 0x60,
LQA = 0x61,
BRASL = 0x62,
BR = 0x64,
FSMBI = 0x65,
BRSL = 0x66,
LQR = 0x67,
IL = 0x81,
ILHU = 0x82,
ILH = 0x83,
IOHL = 0xc1,
};
enum SPU_0_6_Opcodes
{
HBRR = 0x9,
ILA = 0x21,
};
enum SPU_0_7_Opcodes
{
ORI = 0x4,
ORHI = 0x5,
ORBI = 0x6,
SFI = 0xc,
SFHI = 0xd,
ANDI = 0x14,
ANDHI = 0x15,
ANDBI = 0x16,
AI = 0x1c,
AHI = 0x1d,
STQD = 0x24,
LQD = 0x34,
XORI = 0x44,
XORHI = 0x45,
XORBI = 0x46,
CGTI = 0x4c,
CGTHI = 0x4d,
CGTBI = 0x4e,
HGTI = 0x4f,
CLGTI = 0x5c,
CLGTHI = 0x5d,
CLGTBI = 0x5e,
HLGTI = 0x5f,
MPYI = 0x74,
MPYUI = 0x75,
CEQI = 0x7c,
CEQHI = 0x7d,
CEQBI = 0x7e,
HEQI = 0x7f,
};
enum SPU_0_3_Opcodes
{
SELB = 0x8,
SHUFB = 0xb,
enum SPU_0_6_Opcodes
{
HBRA = 0x8,
HBRR = 0x9,
ILA = 0x21,
};
enum SPU_0_3_Opcodes
{
SELB = 0x8,
SHUFB = 0xb,
MPYA = 0xc,
FNMS = 0xd,
FMA = 0xe,
FMS = 0xf,
};
};
class SPU_Opcodes
@ -79,79 +244,216 @@ public:
virtual void Exit()=0;
/*
- 1: Unk/0xb0c2c58c -> 11c: b0 c2 c5 8c shufb $6,$11,$11,$12
- 2: Unk/0x5800c505 -> 124: 58 00 c5 05 clgt $5,$10,$3
- 3: Unk/0x5c000184 -> 128: 5c 00 01 84 clgti $4,$3,0
- 4: Unk/0x18210282 -> 12c: 18 21 02 82 and $2,$5,$4
- 5: Unk/0x00000000 -> 154: 00 00 00 00 stop
- 6: Unk/0x00200000 -> 1b4: 00 20 00 00 lnop
- 7: Unk/0x0f608487 -> 1c0: 0f 60 84 87 shli $7,$9,2
- 8: Unk/0x18140384 -> 1c8: 18 14 03 84 a $4,$7,$80
- 9: Unk/0x38940386 -> 1cc: 38 94 03 86 lqx $6,$7,$80
- 10: Unk/0x3b810305 -> 1d0: 3b 81 03 05 rotqby $5,$6,$4
- 11: Unk/0x35200280 -> 1d4: 35 20 02 80 bisl $0,$5
- 12: Unk/0x237ff982 -> 1e4: 23 7f f9 82 brhnz $2,0x1b0
- 13: Unk/0x35800014 -> 204: 35 80 00 14 hbr 0x254,$0
- 14: Unk/0x5d13c482 -> 224: 5d 13 c4 82 clgthi $2,$9,79
- 15: Unk/0x3ac1828d -> 240: 3a c1 82 8d cwx $13,$5,$6
- 16: Unk/0x2881828b -> 24c: 28 81 82 8b stqx $11,$5,$6
- 17: Unk/0x21a00b82 -> 25c: 21 a0 0b 82 wrch $ch23,$2
- 18: Unk/0x01e00c05 -> 260: 01 e0 0c 05 rchcnt $5,$ch24
- 19: Unk/0x7c004284 -> 264: 7c 00 42 84 ceqi $4,$5,1
- 20: Unk/0x207ffe84 -> 26c: 20 7f fe 84 brz $4,0x260
- 21: Unk/0x01a00c03 -> 27c: 01 a0 0c 03 rdch $3,$ch24
*/
//0 - 10
ADD_OPCODE(STOP,(OP_uIMM code));
ADD_OPCODE(LNOP,());
ADD_OPCODE(SYNC, (OP_uIMM Cbit));
ADD_OPCODE(DSYNC, ());
ADD_OPCODE(MFSPR,(OP_REG rt, OP_REG sa));
ADD_OPCODE(RDCH,(OP_REG rt, OP_REG ra));
ADD_OPCODE(RCHCNT,(OP_REG rt, OP_REG ra));
ADD_OPCODE(SF,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(OR,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(BG,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SFH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(NOR,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ABSDB,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTM,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTMA,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SHL,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTHM,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTMAH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SHLH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTMI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTMAI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(SHLI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTHI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTHMI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTMAHI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(SHLHI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(A,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SPU_AND,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(LQX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(AND,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CG,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(AH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(NAND,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(AVGB,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MTSPR,(OP_REG rt, OP_REG sa));
ADD_OPCODE(WRCH,(OP_REG ra, OP_REG rt));
ADD_OPCODE(BIZ,(OP_REG rt, OP_REG ra));
ADD_OPCODE(BINZ,(OP_REG rt, OP_REG ra));
ADD_OPCODE(BIHZ,(OP_REG rt, OP_REG ra));
ADD_OPCODE(BIHNZ,(OP_REG rt, OP_REG ra));
ADD_OPCODE(STOPD,(OP_REG rc, OP_REG ra, OP_REG rb));
ADD_OPCODE(STQX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(BI,(OP_REG ra));
ADD_OPCODE(BISL,(OP_REG rt, OP_REG ra));
ADD_OPCODE(IRET,(OP_REG ra));
ADD_OPCODE(BISLED,(OP_REG rt, OP_REG ra));
ADD_OPCODE(HBR,(OP_REG p, OP_REG ro, OP_REG ra));
ADD_OPCODE(GB,(OP_REG rt, OP_REG ra));
ADD_OPCODE(GBH,(OP_REG rt, OP_REG ra));
ADD_OPCODE(GBB,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FSM,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FSMH,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FSMB,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FREST,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FRSQEST,(OP_REG rt, OP_REG ra));
ADD_OPCODE(LQX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTQBYBI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTQMBYBI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SHLQBYBI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CBX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CHX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CWX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CDX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTQBI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTQMBI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SHLQBI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTQBY,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ROTQMBY,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SHLQBY,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ORX,(OP_REG rt, OP_REG ra));
ADD_OPCODE(CBD,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(CHD,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(CWD,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(CDD,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTQBII,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTQMBII,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(SHLQBII,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTQBYI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(ROTQMBYI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(SHLQBYI,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(SPU_NOP,(OP_REG rt));
ADD_OPCODE(NOP,(OP_REG rt));
ADD_OPCODE(CGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(XOR,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CGTH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(EQV,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CGTB,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SUMB,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(HGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CLZ,(OP_REG rt, OP_REG ra));
ADD_OPCODE(XSWD,(OP_REG rt, OP_REG ra));
ADD_OPCODE(XSHW,(OP_REG rt, OP_REG ra));
ADD_OPCODE(CNTB,(OP_REG rt, OP_REG ra));
ADD_OPCODE(XSBH,(OP_REG rt, OP_REG ra));
ADD_OPCODE(CLGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ANDC,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FCGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFCGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FA,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FS,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FM,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CLGTH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ORC,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FCMGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFCMGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFA,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFS,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFM,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CLGTB,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(HLGT,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFMA,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFMS,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFNMS,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFNMA,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CEQ,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYHHU,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(ADDX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(SFX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CGX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(BGX,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYHHA,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYHHAU,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FSCRRD,(OP_REG rt));
ADD_OPCODE(FESD,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FRDS,(OP_REG rt, OP_REG ra));
ADD_OPCODE(FSCRWR,(OP_REG rt, OP_REG ra));
ADD_OPCODE(DFTSV,(OP_REG rt, OP_REG ra, OP_sIMM i7));
ADD_OPCODE(FCEQ,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFCEQ,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPY,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYHH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYS,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CEQH,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FCMEQ,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(DFCMEQ,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(MPYU,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(CEQB,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(FI,(OP_REG rt, OP_REG ra, OP_REG rb));
ADD_OPCODE(HEQ,(OP_REG rt, OP_REG ra, OP_REG rb));
//0 - 9
ADD_OPCODE(CFLTS,(OP_REG rt, OP_REG ra, OP_sIMM i8));
ADD_OPCODE(CFLTU,(OP_REG rt, OP_REG ra, OP_sIMM i8));
ADD_OPCODE(CSFLT,(OP_REG rt, OP_REG ra, OP_sIMM i8));
ADD_OPCODE(CUFLT,(OP_REG rt, OP_REG ra, OP_sIMM i8));
//0 - 8
ADD_OPCODE(BRZ,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(STQA,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BRNZ,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BRHZ,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BRHNZ,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(STQR,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BRA,(OP_sIMM i16));
ADD_OPCODE(LQA,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BRASL,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BR,(OP_sIMM i16));
ADD_OPCODE(FSMBI,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(BRSL,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(IL,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(LQR,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(IL,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(ILHU,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(ILH,(OP_REG rt, OP_sIMM i16));
ADD_OPCODE(IOHL,(OP_REG rt, OP_sIMM i16));
//0 - 7
ADD_OPCODE(SPU_ORI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(ORI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(ORHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(ORBI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(SFI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(SFHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(ANDI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(ANDHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(ANDBI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(AI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(AHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(STQD,(OP_REG rt, OP_sIMM i10, OP_REG ra));
ADD_OPCODE(LQD,(OP_REG rt, OP_sIMM i10, OP_REG ra));
ADD_OPCODE(XORI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(XORHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(XORBI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CGTI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CGTHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CGTBI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(HGTI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CLGTI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CLGTHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CLGTBI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(HLGTI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(MPYI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(MPYUI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CEQI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CEQHI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(CEQBI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
ADD_OPCODE(HEQI,(OP_REG rt, OP_REG ra, OP_sIMM i10));
//0 - 6
ADD_OPCODE(HBRA,(OP_sIMM ro, OP_sIMM i16));
ADD_OPCODE(HBRR,(OP_sIMM ro, OP_sIMM i16));
ADD_OPCODE(ILA,(OP_REG rt, OP_sIMM i18));
//0 - 3
ADD_OPCODE(SELB,(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt));
ADD_OPCODE(SHUFB,(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt));
ADD_OPCODE(MPYA,(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt));
ADD_OPCODE(FNMS,(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt));
ADD_OPCODE(FMA,(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt));
ADD_OPCODE(FMS,(OP_REG rc, OP_REG ra, OP_REG rb, OP_REG rt));
ADD_OPCODE(UNK,(const s32 code, const s32 opcode, const s32 gcode));
};

View File

@ -4,6 +4,15 @@
#include "Emu/Cell/SPUInterpreter.h"
#include "Emu/Cell/SPUDisAsm.h"
SPUThread& GetCurrentSPUThread()
{
PPCThread* thread = GetCurrentPPCThread();
if(!thread || !thread->IsSPU()) throw wxString("GetCurrentSPUThread: bad thread");
return *(SPUThread*)thread;
}
SPUThread::SPUThread() : PPCThread(PPC_THREAD_SPU)
{
Reset();

View File

@ -248,4 +248,6 @@ protected:
private:
virtual void DoCode(const s32 code);
};
};
SPUThread& GetCurrentSPUThread();

View File

@ -6,7 +6,7 @@ BEGIN_EVENT_TABLE(DbgConsole, FrameBase)
END_EVENT_TABLE()
DbgConsole::DbgConsole()
: FrameBase(NULL, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition)
: FrameBase(NULL, wxID_ANY, "DbgConsole", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxDEFAULT_FRAME_STYLE, true)
, ThreadBase(false, "DbgConsole thread")
{
m_console = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
@ -20,7 +20,7 @@ DbgConsole::DbgConsole()
DbgConsole::~DbgConsole()
{
Stop();
ThreadBase::Stop();
m_dbg_buffer.Flush();
}
@ -39,7 +39,7 @@ void DbgConsole::Clear()
void DbgConsole::Task()
{
while(m_dbg_buffer.HasNewPacket())
while(m_dbg_buffer.HasNewPacket() && !TestDestroy())
{
DbgPacket packet = m_dbg_buffer.Pop();
m_console->SetDefaultStyle(packet.m_ch == 1 ? *m_color_red : *m_color_white);
@ -52,5 +52,7 @@ void DbgConsole::Task()
void DbgConsole::OnQuit(wxCloseEvent& event)
{
ThreadBase::Stop();
Hide();
//event.Skip();
}

View File

@ -27,7 +27,7 @@ struct _DbgBuffer : public MTPacketBuffer<DbgPacket>
{
}
void Push(const DbgPacket& data)
void _push(const DbgPacket& data)
{
const u32 stext = data.m_text.Len();
@ -47,7 +47,7 @@ struct _DbgBuffer : public MTPacketBuffer<DbgPacket>
CheckBusy();
}
DbgPacket Pop()
DbgPacket _pop()
{
DbgPacket ret;

91
rpcs3/Emu/FS/VFS.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "stdafx.h"
#include "VFS.h"
int sort_devices(const void* _a, const void* _b)
{
const vfsDevice& a = **(const vfsDevice**)_a;
const vfsDevice& b = **(const vfsDevice**)_b;
if(a.GetPs3Path().Len() > b.GetPs3Path().Len()) return 1;
if(a.GetPs3Path().Len() < b.GetPs3Path().Len()) return -1;
return 0;
}
void VFS::Mount(const wxString& ps3_path, const wxString& local_path, vfsDevice* device)
{
UnMount(ps3_path);
device->SetPath(ps3_path, local_path);
m_devices.Add(device);
if(m_devices.GetCount() > 1)
{
std::qsort(m_devices.GetPtr(), m_devices.GetCount(), sizeof(vfsDevice*), sort_devices);
}
}
void VFS::UnMount(const wxString& ps3_path)
{
for(u32 i=0; i<m_devices.GetCount(); ++i)
{
if(!m_devices[i].GetPs3Path().Cmp(ps3_path))
{
m_devices.RemoveAt(i);
return;
}
}
}
vfsStream* VFS::Open(const wxString& ps3_path, vfsOpenMode mode)
{
vfsDevice* stream = nullptr;
wxString path;
if(vfsDevice* dev = GetDevice(ps3_path, path))
{
stream = dev->GetNew();
stream->Open(path, mode);
}
return stream;
}
void VFS::Create(const wxString& ps3_path)
{
wxString path;
if(vfsDevice* dev = GetDevice(ps3_path, path))
{
dev->Create(path);
}
}
void VFS::Close(vfsStream*& device)
{
delete device;
device = nullptr;
}
vfsDevice* VFS::GetDevice(const wxString& ps3_path, wxString& path)
{
u32 max_eq;
s32 max_i=-1;
for(u32 i=0; i<m_devices.GetCount(); ++i)
{
const u32 eq = m_devices[i].CmpPs3Path(ps3_path);
if(max_i < 0 || eq > max_eq)
{
max_eq = eq;
max_i = i;
}
}
if(max_i < 0) return nullptr;
path = vfsDevice::GetWinPath(m_devices[max_i].GetLocalPath(), ps3_path(max_eq, ps3_path.Len() - max_eq));
return &m_devices[max_i];
}

15
rpcs3/Emu/FS/VFS.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include "vfsDevice.h"
struct VFS
{
ArrayF<vfsDevice> m_devices;
void Mount(const wxString& ps3_path, const wxString& local_path, vfsDevice* device);
void UnMount(const wxString& ps3_path);
vfsStream* Open(const wxString& ps3_path, vfsOpenMode mode);
void Create(const wxString& ps3_path);
void Close(vfsStream*& device);
vfsDevice* GetDevice(const wxString& ps3_path, wxString& path);
};

201
rpcs3/Emu/FS/vfsDevice.cpp Normal file
View File

@ -0,0 +1,201 @@
#include "stdafx.h"
#include "vfsDevice.h"
vfsDevice::vfsDevice(const wxString& ps3_path, const wxString& local_path)
: m_ps3_path(ps3_path)
, m_local_path(GetWinPath(local_path))
{
}
wxString vfsDevice::GetLocalPath() const
{
return m_local_path;
}
wxString vfsDevice::GetPs3Path() const
{
return m_ps3_path;
}
void vfsDevice::SetPath(const wxString& ps3_path, const wxString& local_path)
{
m_ps3_path = ps3_path;
m_local_path = local_path;
}
u32 vfsDevice::CmpPs3Path(const wxString& ps3_path)
{
const u32 lim = min(m_ps3_path.Len(), ps3_path.Len());
u32 ret = 0;
for(u32 i=0; i<lim; ++i, ++ret)
{
if(m_ps3_path[i] != ps3_path[i]) break;
}
return ret;
}
wxString vfsDevice::ErasePath(const wxString& path, u32 start_dir_count, u32 end_dir_count)
{
u32 from = 0;
u32 to = path.Len() - 1;
for(uint i = 0, dir = 0; i < path.Len(); ++i)
{
if(path[i] == '\\' || path[i] == '/' || i == path.Len() - 1)
{
if(++dir == start_dir_count)
{
from = i;
break;
}
}
}
for(int i = path.Len() - 1, dir = 0; i >= 0; --i)
{
if(path[i] == '\\' || path[i] == '/' || i == 0)
{
if(dir++ == end_dir_count)
{
to = i;
break;
}
}
}
return path(from, to - from);
}
wxString vfsDevice::GetRoot(const wxString& path)
{
if(path.IsEmpty()) return wxEmptyString;
u32 first_dir = path.Len() - 1;
for(int i = path.Len() - 1, dir = 0, li = path.Len() - 1; i >= 0 && dir < 2; --i)
{
if(path[i] == '\\' || path[i] == '/' || i == 0)
{
switch(dir++)
{
case 0:
first_dir = i;
break;
case 1:
if(!path(i + 1, li - i).Cmp("USRDIR")) return path(0, i + 1);
continue;
}
li = i - 1;
}
}
return path(0, first_dir + 1);
}
wxString vfsDevice::GetRootPs3(const wxString& path)
{
if(path.IsEmpty()) return wxEmptyString;
static const wxString& home = "/dev_hdd0/game/";
u32 last_dir = 0;
u32 first_dir = path.Len() - 1;
for(int i = path.Len() - 1, dir = 0; i >= 0; --i)
{
if(path[i] == '\\' || path[i] == '/' || i == 0)
{
switch(dir++)
{
case 1:
if(!!path(i + 1, last_dir - i - 1).Cmp("USRDIR")) return wxEmptyString;
break;
case 2:
return GetPs3Path(home + path(i + 1, last_dir - i - 1));
}
last_dir = i;
}
}
return GetPs3Path(home + path(0, last_dir - 1));
}
wxString vfsDevice::GetWinPath(const wxString& p, bool is_dir)
{
if(p.IsEmpty()) return wxEmptyString;
wxString ret;
bool is_ls = false;
for(u32 i=0; i<p.Len(); ++i)
{
if(p[i] == '/' || p[i] == '\\')
{
if(!is_ls)
{
ret += '\\';
is_ls = true;
}
continue;
}
is_ls = false;
ret += p[i];
}
if(is_dir && ret[ret.Len() - 1] != '\\') ret += '\\';
return ret;
}
wxString vfsDevice::GetWinPath(const wxString& l, const wxString& r)
{
if(l.IsEmpty()) return GetWinPath(r, false);
if(r.IsEmpty()) return GetWinPath(l);
return GetWinPath(l + '\\' + r, false);
}
wxString vfsDevice::GetPs3Path(const wxString& p, bool is_dir)
{
if(p.IsEmpty()) return wxEmptyString;
wxString ret;
bool is_ls = false;
for(u32 i=0; i<p.Len(); ++i)
{
if(p[i] == '/' || p[i] == '\\')
{
if(!is_ls)
{
ret += '/';
is_ls = true;
}
continue;
}
is_ls = false;
ret += p[i];
}
if(ret[0] != '/') ret = '/' + ret;
if(is_dir && ret[ret.Len() - 1] != '/') ret += '/';
return ret;
}
wxString vfsDevice::GetPs3Path(const wxString& l, const wxString& r)
{
if(l.IsEmpty()) return GetPs3Path(r, false);
if(r.IsEmpty()) return GetPs3Path(l);
return GetPs3Path(l + '/' + r, false);
}

39
rpcs3/Emu/FS/vfsDevice.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include "vfsStream.h"
enum vfsOpenMode
{
vfsRead,
vfsWrite,
vfsReadWrite,
vfsWriteExcl,
vfsWriteAppend,
};
class vfsDevice : public vfsStream
{
wxString m_ps3_path;
wxString m_local_path;
public:
vfsDevice(const wxString& ps3_path, const wxString& local_path);
vfsDevice() {}
virtual vfsDevice* GetNew()=0;
virtual bool Open(const wxString& path, vfsOpenMode mode = vfsRead)=0;
virtual bool Create(const wxString& path)=0;
wxString GetLocalPath() const;
wxString GetPs3Path() const;
void SetPath(const wxString& ps3_path, const wxString& local_path);
u32 CmpPs3Path(const wxString& ps3_path);
static wxString ErasePath(const wxString& local_path, u32 start_dir_count, u32 end_dir_count);
static wxString GetRoot(const wxString& local_path);
static wxString GetRootPs3(const wxString& local_path);
static wxString GetWinPath(const wxString& p, bool is_dir = true);
static wxString GetWinPath(const wxString& l, const wxString& r);
static wxString GetPs3Path(const wxString& p, bool is_dir = true);
static wxString GetPs3Path(const wxString& l, const wxString& r);
};

View File

@ -0,0 +1,3 @@
#include "stdafx.h"
#include "vfsDirBase.cpp"

19
rpcs3/Emu/FS/vfsDirBase.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
struct DirInfo
{
wxString m_name;
};
class vfsDirBase
{
virtual bool Open(const wxString& path)=0;
virtual Array<DirInfo> GetEntryes()=0;
virtual void Close()=0;
virtual bool Create(const wxString& path)=0;
virtual bool Exists(const wxString& path)=0;
virtual bool Rename(const wxString& from, const wxString& to)=0;
virtual bool Remove(const wxString& path)=0;
};

View File

@ -0,0 +1,43 @@
#include "stdafx.h"
#include "vfsFileBase.h"
vfsFileBase::vfsFileBase() : vfsDevice()
{
}
vfsFileBase::~vfsFileBase()
{
Close();
}
bool Access(const wxString& path, vfsOpenMode mode)
{
return false;
}
bool vfsFileBase::Open(const wxString& path, vfsOpenMode mode)
{
m_path = path;
m_mode = mode;
vfsStream::Reset();
return true;
}
bool vfsFileBase::Close()
{
m_path = wxEmptyString;
return vfsStream::Close();
}
wxString vfsFileBase::GetPath() const
{
return m_path;
}
vfsOpenMode vfsFileBase::GetOpenMode() const
{
return m_mode;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "vfsDevice.h"
struct vfsFileBase : public vfsDevice
{
protected:
wxString m_path;
vfsOpenMode m_mode;
public:
vfsFileBase();
virtual ~vfsFileBase();
virtual bool Open(const wxString& path, vfsOpenMode mode);
virtual bool Close();
/*
virtual bool Create(const wxString& path)=0;
virtual bool Exists(const wxString& path)=0;
virtual bool Rename(const wxString& from, const wxString& to)=0;
virtual bool Remove(const wxString& path)=0;
*/
wxString GetPath() const;
vfsOpenMode GetOpenMode() const;
};

View File

@ -0,0 +1,95 @@
#include "stdafx.h"
#include "vfsLocalFile.h"
static const wxFile::OpenMode vfs2wx_mode(vfsOpenMode mode)
{
switch(mode)
{
case vfsRead: return wxFile::read;
case vfsWrite: return wxFile::write;
case vfsReadWrite: return wxFile::read_write;
case vfsWriteExcl: return wxFile::write_excl;
case vfsWriteAppend: return wxFile::write_append;
}
return wxFile::read;
}
static const wxSeekMode vfs2wx_seek(vfsSeekMode mode)
{
switch(mode)
{
case vfsSeekSet: return wxFromStart;
case vfsSeekCur: return wxFromCurrent;
case vfsSeekEnd: return wxFromEnd;
}
return wxFromStart;
}
vfsLocalFile::vfsLocalFile() : vfsFileBase()
{
}
vfsLocalFile::vfsLocalFile(const wxString path, vfsOpenMode mode) : vfsFileBase()
{
Open(path, mode);
}
vfsDevice* vfsLocalFile::GetNew()
{
return new vfsLocalFile();
}
bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode)
{
Close();
if(mode == vfsRead && !m_file.Access(vfsDevice::GetWinPath(GetLocalPath(), path), vfs2wx_mode(mode))) return false;
return m_file.Open(vfsDevice::GetWinPath(GetLocalPath(), path), vfs2wx_mode(mode)) &&
vfsFileBase::Open(vfsDevice::GetPs3Path(GetPs3Path(), path), mode);
}
bool vfsLocalFile::Create(const wxString& path)
{
if(wxFileExists(path)) return false;
wxFile f;
return f.Create(path);
}
bool vfsLocalFile::Close()
{
return m_file.Close() && vfsFileBase::Close();
}
u64 vfsLocalFile::GetSize()
{
return m_file.Length();
}
u32 vfsLocalFile::Write(const void* src, u32 size)
{
return m_file.Write(src, size);
}
u32 vfsLocalFile::Read(void* dst, u32 size)
{
return m_file.Read(dst, size);
}
u64 vfsLocalFile::Seek(s64 offset, vfsSeekMode mode)
{
return m_file.Seek(offset, vfs2wx_seek(mode));
}
u64 vfsLocalFile::Tell() const
{
return m_file.Tell();
}
bool vfsLocalFile::IsOpened() const
{
return m_file.IsOpened() && vfsFileBase::IsOpened();
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "vfsFileBase.h"
class vfsLocalFile : public vfsFileBase
{
private:
wxFile m_file;
public:
vfsLocalFile();
vfsLocalFile(const wxString path, vfsOpenMode mode = vfsRead);
vfsDevice* GetNew();
virtual bool Open(const wxString& path, vfsOpenMode mode = vfsRead);
virtual bool Create(const wxString& path);
virtual bool Close();
virtual u64 GetSize();
virtual u32 Write(const void* src, u32 size);
virtual u32 Read(void* dst, u32 size);
virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet);
virtual u64 Tell() const;
virtual bool IsOpened() const;
};

View File

@ -0,0 +1,74 @@
#include "stdafx.h"
#include "vfsStream.h"
vfsStream::vfsStream()
{
}
vfsStream::~vfsStream()
{
Close();
}
void vfsStream::Reset()
{
m_pos = 0;
}
bool vfsStream::Close()
{
Reset();
return true;
}
u64 vfsStream::GetSize()
{
u64 last_pos = Tell();
Seek(0, vfsSeekEnd);
u64 size = Tell();
Seek(last_pos, vfsSeekSet);
return size;
}
u32 vfsStream::Write(const void* src, u32 size)
{
m_pos += size;
return size;
}
u32 vfsStream::Read(void* dst, u32 size)
{
m_pos += size;
return size;
}
u64 vfsStream::Seek(s64 offset, vfsSeekMode mode)
{
switch(mode)
{
case vfsSeekSet: m_pos = offset; break;
case vfsSeekCur: m_pos += offset; break;
case vfsSeekEnd: m_pos = GetSize() + offset; break;
}
return m_pos;
}
u64 vfsStream::Tell() const
{
return m_pos;
}
bool vfsStream::Eof()
{
return Tell() >= GetSize();
}
bool vfsStream::IsOpened() const
{
return true;
}

33
rpcs3/Emu/FS/vfsStream.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
enum vfsSeekMode
{
vfsSeekSet,
vfsSeekCur,
vfsSeekEnd,
};
struct vfsStream
{
protected:
u64 m_pos;
public:
vfsStream();
virtual ~vfsStream();
virtual void Reset();
virtual bool Close();
virtual u64 GetSize();
virtual u32 Write(const void* src, u32 size);
virtual u32 Read(void* dst, u32 size);
virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet);
virtual u64 Tell() const;
virtual bool Eof();
virtual bool IsOpened() const;
};

View File

@ -0,0 +1,36 @@
#include "stdafx.h"
#include "vfsStreamMemory.h"
vfsStreamMemory::vfsStreamMemory() : vfsStream()
{
}
vfsStreamMemory::vfsStreamMemory(u64 addr) : vfsStream()
{
Open(addr);
}
void vfsStreamMemory::Open(u64 addr)
{
m_addr = addr;
vfsStream::Reset();
}
u32 vfsStreamMemory::Write(const void* src, u32 size)
{
if(!Memory.IsGoodAddr(m_addr + Tell(), size)) return 0;
memcpy(&Memory[m_addr + Tell()], src, size);
return vfsStream::Write(src, size);
}
u32 vfsStreamMemory::Read(void* dst, u32 size)
{
if(!Memory.IsGoodAddr(m_addr + Tell(), size)) return 0;
memcpy(dst, &Memory[m_addr + Tell()], size);
return vfsStream::Read(dst, size);
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "vfsStream.h"
struct vfsStreamMemory : public vfsStream
{
u64 m_addr;
public:
vfsStreamMemory();
vfsStreamMemory(u64 addr);
void Open(u64 addr);
virtual u32 Write(const void* src, u32 size);
virtual u32 Read(void* dst, u32 size);
};

View File

@ -1,10 +1,17 @@
#pragma once
enum
{
CELL_GCM_DISPLAY_HSYNC = 1,
CELL_GCM_DISPLAY_VSYNC = 2,
CELL_GCM_DISPLAY_HSYNC_WITH_NOISE = 3,
};
struct CellGcmControl
{
volatile u32 put;
volatile u32 get;
volatile u32 ref;
u32 put;
u32 get;
u32 ref;
};
struct CellGcmConfig
@ -332,12 +339,12 @@ enum
NV3089_IMAGE_IN = 0x0000C40C,
};
static const wxString getMethodName(const u32 id)
static const wxString GetMethodName(const u32 id)
{
struct MethodName
{
const u32 id;
const wxString name;
const wxString& name;
} static const METHOD_NAME_LIST[] = {
{ NV4097_NO_OPERATION , "NoOperation" } ,
{ NV4097_NOTIFY , "Notify" } ,

View File

@ -49,7 +49,12 @@ wxString FragmentDecompilerThread::GetMask()
wxString FragmentDecompilerThread::AddReg(u32 index)
{
//if(!index) return "gl_FragColor";
return m_parr.AddParam(index ? PARAM_NONE : PARAM_OUT, "vec4", wxString::Format("r%d", index));
return m_parr.AddParam(index ? PARAM_NONE : PARAM_OUT, "vec4", wxString::Format("r%d", index), index ? -1 : 0);
}
wxString FragmentDecompilerThread::AddConst()
{
return m_parr.AddParam(PARAM_CONST, "vec4", wxString::Format("fc%d", m_const_index++));
}
wxString FragmentDecompilerThread::AddTex()
@ -96,8 +101,10 @@ template<typename T> wxString FragmentDecompilerThread::GetSRC(T src)
}
break;
//case 2: //imm
//break;
case 2: //const
ConLog.Write("reg index = %d", src.tmp_reg_index);
ret += AddConst();
break;
default:
ConLog.Error("Bad src type %d", src.reg_type);
@ -126,17 +133,11 @@ wxString FragmentDecompilerThread::BuildCode()
for(u32 i=0; i<m_parr.params.GetCount(); ++i)
{
for(u32 n=0; n<m_parr.params[i].names.GetCount(); ++n)
{
p += m_parr.params[i].type;
p += " ";
p += m_parr.params[i].names[n];
p += ";\n";
}
p += m_parr.params[i].Format();
}
static const wxString& prot =
"#version 330 core\n"
"#version 330\n"
"\n"
"%s\n"
"void main()\n{\n%s}\n";
@ -144,11 +145,12 @@ wxString FragmentDecompilerThread::BuildCode()
return wxString::Format(prot, p, main);
}
wxThread::ExitCode FragmentDecompilerThread::Entry()
void FragmentDecompilerThread::Task()
{
mem32_t data(m_addr);
m_size = 0;
for(;;)
while(true)
{
dst.HEX = GetData(data[0]);
src0.HEX = GetData(data[1]);
@ -160,7 +162,67 @@ wxThread::ExitCode FragmentDecompilerThread::Entry()
case 0x00: break; //NOP
case 0x01: AddCode(GetSRC(src0)); break; //MOV
case 0x02: AddCode("(" + GetSRC(src0) + " * " + GetSRC(src1) + ")"); break; //MUL
case 0x03: AddCode("(" + GetSRC(src0) + " + " + GetSRC(src1) + ")"); break; //ADD
case 0x04: AddCode("(" + GetSRC(src0) + " * " + GetSRC(src1) + " + " + GetSRC(src2) + ")"); break; //MAD
case 0x05: AddCode("dot(" + GetSRC(src0) + ".xyz, " + GetSRC(src1) + ".xyz)"); break; // DP3
case 0x06: AddCode("dot(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // DP4
//case 0x07: break; // DST
case 0x08: AddCode("min(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MIN
case 0x09: AddCode("max(" + GetSRC(src0) + ", " + GetSRC(src1) + ")"); break; // MAX
//case 0x0a: break; // SLT
//case 0x0b: break; // SGE
//case 0x0c: break; // SLE
//case 0x0d: break; // SGT
//case 0x0e: break; // SNE
//case 0x0f: break; // SEQ
//case 0x10: break; // FRC
//case 0x11: break; // FLR
//case 0x12: break; // KIL
//case 0x13: break; // PK4
//case 0x14: break; // UP4
case 0x15: AddCode("ddx(" + GetSRC(src0) + ")"); break; // DDX
case 0x16: AddCode("ddy(" + GetSRC(src0) + ")"); break; // DDY
case 0x17: AddCode("texture(" + AddTex() + ", (" + GetSRC(src0) + ").xy)"); break; //TEX
//case 0x18: break; // TXP
//case 0x19: break; // TXD
case 0x1a: AddCode("1 / (" + GetSRC(src0) + ")"); break; // RCP
case 0x1b: AddCode("inversesqrt(" + GetSRC(src0) + ")"); break; // RSQ
case 0x1c: AddCode("exp2(" + GetSRC(src0) + ")"); break; // EX2
case 0x1d: AddCode("log2(" + GetSRC(src0) + ")"); break; // LG2
//case 0x1e: break; // LIT
//case 0x1f: break; // LRP
//case 0x20: break; // STR
//case 0x21: break; // SFL
case 0x22: AddCode("cos(" + GetSRC(src0) + ")"); break; // COS
case 0x23: AddCode("sin(" + GetSRC(src0) + ")"); break; // SIN
//case 0x24: break; // PK2
//case 0x25: break; // UP2
//case 0x26: break; // POW
//case 0x27: break; // PKB
//case 0x28: break; // UPB
//case 0x29: break; // PK16
//case 0x2a: break; // UP16
//case 0x2b: break; // BEM
//case 0x2c: break; // PKG
//case 0x2d: break; // UPG
//case 0x2e: break; // DP2A
//case 0x2f: break; // TXL
//case 0x31: break; // TXB
//case 0x33: break; // TEXBEM
//case 0x34: break; // TXPBEM
//case 0x35: break; // BEMLUM
//case 0x36: break; // REFL
//case 0x37: break; // TIMESWTEX
//case 0x38: break; // DP2
//case 0x39: break; // NRM
//case 0x3a: break; // DIV
//case 0x3b: break; // DIVSQ
//case 0x3c: break; // LIF
//case 0x3d: break; // FENCT
//case 0x3e: break; // FENCB
default:
ConLog.Error("Unknown opcode 0x%x", dst.opcode);
@ -177,8 +239,6 @@ wxThread::ExitCode FragmentDecompilerThread::Entry()
m_shader = BuildCode();
main.Clear();
return (ExitCode)0;
}
ShaderProgram::ShaderProgram()
@ -192,8 +252,13 @@ ShaderProgram::~ShaderProgram()
if(m_decompiler_thread)
{
Wait();
if(m_decompiler_thread->IsAlive()) m_decompiler_thread->Delete();
safe_delete(m_decompiler_thread);
if(m_decompiler_thread->IsAlive())
{
m_decompiler_thread->Stop();
}
delete m_decompiler_thread;
m_decompiler_thread = nullptr;
}
Delete();
@ -207,13 +272,17 @@ void ShaderProgram::Decompile()
if(m_decompiler_thread)
{
Wait();
if(m_decompiler_thread->IsAlive()) m_decompiler_thread->Delete();
safe_delete(m_decompiler_thread);
if(m_decompiler_thread->IsAlive())
{
m_decompiler_thread->Stop();
}
delete m_decompiler_thread;
m_decompiler_thread = nullptr;
}
m_decompiler_thread = new FragmentDecompilerThread(shader, parr, addr, size);
m_decompiler_thread->Create();
m_decompiler_thread->Run();
m_decompiler_thread->Start();
#endif
}
@ -242,7 +311,7 @@ void ShaderProgram::Compile()
memset(buf, 0, r+1);
glGetShaderInfoLog(id, r, &len, buf);
ConLog.Error("Failed to compile shader: %s", buf);
free(buf);
delete[] buf;
}
ConLog.Write(shader);
@ -255,9 +324,10 @@ void ShaderProgram::Delete()
{
for(u32 i=0; i<parr.params.GetCount(); ++i)
{
parr.params[i].names.Clear();
parr.params[i].items.Clear();
parr.params[i].type.Clear();
}
parr.params.Clear();
shader.Clear();

View File

@ -1,7 +1,7 @@
#pragma once
#include "ShaderParam.h"
struct FragmentDecompilerThread : public wxThread
struct FragmentDecompilerThread : public ThreadBase
{
union OPDEST
{
@ -99,26 +99,30 @@ struct FragmentDecompilerThread : public wxThread
ParamArray& m_parr;
u32 m_addr;
u32& m_size;
u32 m_const_index;
FragmentDecompilerThread(wxString& shader, ParamArray& parr, u32 addr, u32& size)
: wxThread(wxTHREAD_JOINABLE)
: ThreadBase(false, "Fragment Shader Decompiler Thread")
, m_shader(shader)
, m_parr(parr)
, m_addr(addr)
, m_size(size)
, m_const_index(0)
{
m_size = 0;
}
wxString GetMask();
void AddCode(wxString code);
wxString AddReg(u32 index);
wxString AddConst();
wxString AddTex();
template<typename T> wxString GetSRC(T src);
wxString BuildCode();
ExitCode Entry();
virtual void Task();
u32 GetData(const u32 d) const { return d << 16 | d >> 16; }
};
@ -138,7 +142,13 @@ struct ShaderProgram
u32 id;
void Wait() { if(m_decompiler_thread && m_decompiler_thread->IsRunning()) m_decompiler_thread->Wait(); }
void Wait()
{
if(m_decompiler_thread && m_decompiler_thread->IsAlive())
{
m_decompiler_thread->Wait();
}
}
void Decompile();
void Compile();

View File

@ -2,52 +2,118 @@
#include "GLBuffers.h"
#include "GLGSRender.h"
BufferObject::BufferObject()
: m_id(0)
, m_type(0)
GLBufferObject::GLBufferObject()
{
}
BufferObject::BufferObject(u32 type)
: m_id(0)
, m_type(0)
GLBufferObject::GLBufferObject(u32 type)
{
Create(type);
}
void BufferObject::Create(u32 type)
GLBufferObject::~GLBufferObject()
{
if(m_id) return;
glGenBuffers(1, &m_id);
Delete();
}
void GLBufferObject::Create(GLuint type, u32 count)
{
if(IsCreated()) return;
m_id.InsertRoomEnd(count);
glGenBuffers(count, &m_id[0]);
m_type = type;
}
void BufferObject::Delete()
void GLBufferObject::Delete()
{
if(!m_id) return;
glDeleteBuffers(1, &m_id);
m_id = 0;
if(!IsCreated()) return;
glDeleteBuffers(m_id.GetCount(), &m_id[0]);
m_id.Clear();
m_type = 0;
}
void BufferObject::Bind()
void GLBufferObject::Bind(u32 type, u32 num)
{
if(m_id) glBindBuffer(m_type, m_id);
glBindBuffer(type, m_id[num]);
}
void BufferObject::UnBind()
void GLBufferObject::UnBind(u32 type)
{
glBindBuffer(m_type, 0);
glBindBuffer(type, 0);
}
void BufferObject::SetData(const void* data, u32 size, u32 type)
void GLBufferObject::Bind(u32 num)
{
if(!m_type) return;
Bind();
glBufferData(m_type, size, data, type);
Bind(m_type, num);
}
void VBO::Create()
void GLBufferObject::UnBind()
{
BufferObject::Create(GL_ARRAY_BUFFER);
UnBind(m_type);
}
void GLBufferObject::SetData(u32 type, const void* data, u32 size, u32 usage)
{
glBufferData(type, size, data, usage);
}
void GLBufferObject::SetData(const void* data, u32 size, u32 usage)
{
SetData(m_type, data, size, usage);
}
void GLBufferObject::SetAttribPointer(int location, int size, int type, int pointer, int stride, bool normalized)
{
if(location < 0) return;
glVertexAttribPointer(location, size, type, normalized ? GL_TRUE : GL_FALSE, stride, (const GLvoid*)pointer);
glEnableVertexAttribArray(location);
}
bool GLBufferObject::IsCreated() const
{
return m_id.GetCount() != 0;
}
GLvbo::GLvbo()
{
}
void GLvbo::Create(u32 count)
{
GLBufferObject::Create(GL_ARRAY_BUFFER, count);
}
GLvao::GLvao() : m_id(0)
{
}
GLvao::~GLvao()
{
Delete();
}
void GLvao::Create()
{
if(!IsCreated()) glGenVertexArrays(1, &m_id);
}
void GLvao::Bind() const
{
glBindVertexArray(m_id);
}
void GLvao::Delete()
{
if(!IsCreated()) return;
glDeleteVertexArrays(1, &m_id);
m_id = 0;
}
bool GLvao::IsCreated() const
{
return m_id != 0;
}

View File

@ -1,24 +1,48 @@
#pragma once
#include "OpenGL.h"
struct BufferObject
struct GLBufferObject
{
protected:
u32 m_id;
u32 m_type;
Array<GLuint> m_id;
GLuint m_type;
public:
BufferObject();
BufferObject(u32 type);
void Create(u32 type);
GLBufferObject();
GLBufferObject(u32 type);
~GLBufferObject();
void Create(GLuint type, u32 count = 1);
void Delete();
void Bind();
void Bind(u32 type, u32 num);
void UnBind(u32 type);
void Bind(u32 num = 0);
void UnBind();
void SetData(const void* data, u32 size, u32 type = GL_DYNAMIC_DRAW);
void SetData(u32 type, const void* data, u32 size, u32 usage = GL_DYNAMIC_DRAW);
void SetData(const void* data, u32 size, u32 usage = GL_DYNAMIC_DRAW);
void SetAttribPointer(int location, int size, int type, int pointer, int stride, bool normalized = false);
bool IsCreated() const;
};
struct VBO : public BufferObject
struct GLvbo : public GLBufferObject
{
GLvbo();
void Create(u32 count = 1);
};
class GLvao
{
protected:
GLuint m_id;
public:
GLvao();
~GLvao();
void Create();
void Bind() const;
void Delete();
bool IsCreated() const;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,11 @@
#pragma once
#include "Emu/GS/GSRender.h"
#include "Emu/GS/RSXThread.h"
#include "wx/glcanvas.h"
#include "GLBuffers.h"
#include "Program.h"
#include "OpenGL.h"
#include "ProgramBuffer.h"
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "gl.lib")
@ -66,9 +68,6 @@ public:
void Init()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(!m_id)
{
glGenTextures(1, &m_id);
@ -87,9 +86,9 @@ public:
//TODO: safe init
checkForGlError("GLTexture::Init() -> glBindTexture");
switch(m_format)
switch(m_format & ~(0x20 | 0x40))
{
case 0xA1:
case 0x81:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RED, GL_UNSIGNED_BYTE, Memory.GetMemFromAddr(m_offset));
checkForGlError("GLTexture::Init() -> glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
@ -99,7 +98,7 @@ public:
checkForGlError("GLTexture::Init() -> glTexParameteri");
break;
case 0xA5:
case 0x85:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, Memory.GetMemFromAddr(m_offset));
checkForGlError("GLTexture::Init() -> glTexImage2D");
break;
@ -114,42 +113,32 @@ public:
{
if(!m_id || !m_offset) return;
ConLog.Write("start");
u32* alldata = new u32[m_width * m_height];
glBindTexture(GL_TEXTURE_2D, m_id);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, alldata);
u8* data = new u8[m_width * m_height * 3];
u8* alpha = new u8[m_width * m_height];
u8* src = Memory.GetMemFromAddr(m_offset);
u8* dst = data;
u8* src = (u8*)alldata;
u8* dst_d = data;
u8* dst_a = alpha;
switch(m_format)
for(u32 i=0; i<m_width*m_height;i++)
{
case 0xA1:
for(u32 y=0; y<m_height; ++y) for(u32 x=0; x<m_width; ++x)
{
*dst++ = *src;
*dst++ = *src;
*dst++ = *src;
*dst_a++ = *src;
src++;
}
break;
case 0xA5:
for(u32 y=0; y<m_height; ++y) for(u32 x=0; x<m_width; ++x)
{
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst_a++ = *src++;
}
break;
default: ConLog.Error("Save tex error: Bad tex format (0x%x)", m_format); break;
*dst_d++ = *src++;
*dst_d++ = *src++;
*dst_d++ = *src++;
*dst_a++ = *src++;
}
ConLog.Write("end");
wxImage out;
out.Create(m_width, m_height, data, alpha);
out.SaveFile(name, wxBITMAP_TYPE_PNG);
free(alldata);
//free(data);
//free(alpha);
}
@ -175,6 +164,33 @@ public:
bool IsEnabled() const { return m_enabled; }
};
struct IndexArrayData
{
Array<u8> m_data;
int m_type;
u32 m_first;
u32 m_count;
u32 m_addr;
u32 index_max;
u32 index_min;
IndexArrayData()
{
Reset();
}
void Reset()
{
m_type = 0;
m_first = ~0;
m_count = 0;
m_addr = 0;
index_min = ~0;
index_max = 0;
m_data.Clear();
}
};
struct GLGSFrame : public GSFrame
{
wxGLCanvas* canvas;
@ -197,42 +213,66 @@ private:
extern gcmBuffer gcmBuffers[2];
struct GLRSXThread : public wxThread
struct GLRSXThread : public ThreadBase
{
wxWindow* m_parent;
Stack<u32> call_stack;
volatile bool m_paused;
GLRSXThread(wxWindow* parent);
virtual void OnExit();
void Start();
ExitCode Entry();
virtual void Task();
};
class GLGSRender
: public wxWindow
, public GSRender
, public ExecRSXCMDdata
{
private:
GLRSXThread* m_rsx_thread;
IndexArrayData m_indexed_array;
ShaderProgram m_shader_prog;
VertexData m_vertex_data[16];
Array<u8> m_vdata;
VertexProgram m_vertex_progs[16];
VertexProgram* m_cur_vertex_prog;
Program m_program;
int m_fp_buf_num;
int m_vp_buf_num;
int m_draw_array_count;
int m_draw_mode;
ProgramBuffer m_prog_buffer;
GLvao m_vao;
GLvbo m_vbo;
public:
GLGSFrame* m_frame;
volatile bool m_draw;
u32 m_draw_frames;
u32 m_skip_frames;
GLGSRender();
~GLGSRender();
private:
void EnableVertexData(bool indexed_draw=false);
void DisableVertexData();
void LoadVertexData(u32 first, u32 count);
void InitVertexData();
void Enable(bool enable, const u32 cap);
virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);
virtual void Draw();
virtual void Close();
virtual void Pause();
virtual void Resume();
bool LoadProgram();
public:
void DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count);
void CloseOpenGL();
virtual void ExecCMD();
virtual void Reset();
void Init();
};

View File

@ -1,42 +1,45 @@
OPENGL_PROC(PFNGLGENBUFFERSPROC,glGenBuffers);
OPENGL_PROC(PFNGLDELETEBUFFERSPROC, glDeleteBuffers);
OPENGL_PROC(PFNGLBINDBUFFERPROC, glBindBuffer);
OPENGL_PROC(PFNGLISBUFFERPROC, glIsBuffer);
OPENGL_PROC(PFNGLBUFFERDATAPROC, glBufferData);
OPENGL_PROC(PFNGLBUFFERSUBDATAPROC, glBufferSubData);
OPENGL_PROC(PFNGLGETBUFFERSUBDATAPROC, glGetBufferSubData);
OPENGL_PROC(PFNGLMAPBUFFERPROC, glMapBuffer);
OPENGL_PROC(PFNGLUNMAPBUFFERPROC, glUnmapBuffer);
OPENGL_PROC(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv);
OPENGL_PROC(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv);
OPENGL_PROC(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate);
OPENGL_PROC(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate);
OPENGL_PROC(PFNGLBLENDCOLORPROC, glBlendColor);
OPENGL_PROC(PFNGLBLENDEQUATIONPROC, glBlendEquation);
OPENGL_PROC(PFNGLCREATESHADERPROC, glCreateShader);
OPENGL_PROC(PFNGLDELETESHADERPROC, glDeleteShader);
OPENGL_PROC(PFNGLCOMPILESHADERPROC, glCompileShader);
OPENGL_PROC(PFNGLSHADERSOURCEPROC, glShaderSource);
OPENGL_PROC(PFNGLGETSHADERIVPROC, glGetShaderiv);
OPENGL_PROC(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog);
OPENGL_PROC(PFNGLACTIVETEXTUREPROC, glActiveTexture);
OPENGL_PROC(PFNGLCREATEPROGRAMPROC, glCreateProgram);
OPENGL_PROC(PFNGLDELETEPROGRAMPROC, glDeleteProgram);
OPENGL_PROC(PFNGLATTACHSHADERPROC, glAttachShader);
OPENGL_PROC(PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation);
OPENGL_PROC(PFNGLLINKPROGRAMPROC, glLinkProgram);
OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation);
OPENGL_PROC(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation);
OPENGL_PROC(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation);
OPENGL_PROC(PFNGLGETPROGRAMIVPROC, glGetProgramiv);
OPENGL_PROC(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog);
OPENGL_PROC(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer);
OPENGL_PROC(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray);
OPENGL_PROC(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray);
OPENGL_PROC(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays);
OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray);
OPENGL_PROC(PFNGLDEPTHRANGEFPROC, glDepthRangef);
OPENGL_PROC(PFNGLUNIFORM1IPROC, glUniform1i);
OPENGL_PROC(PFNGLUNIFORM4FPROC, glUniform4f);
OPENGL_PROC(PFNGLUSEPROGRAMPROC, glUseProgram);
OPENGL_PROC(PFNGLGENBUFFERSPROC, GenBuffers);
OPENGL_PROC(PFNGLDELETEBUFFERSPROC, DeleteBuffers);
OPENGL_PROC(PFNGLBINDBUFFERPROC, BindBuffer);
OPENGL_PROC(PFNGLISBUFFERPROC, IsBuffer);
OPENGL_PROC(PFNGLBUFFERDATAPROC, BufferData);
OPENGL_PROC(PFNGLBUFFERSUBDATAPROC, BufferSubData);
OPENGL_PROC(PFNGLGETBUFFERSUBDATAPROC, GetBufferSubData);
OPENGL_PROC(PFNGLMAPBUFFERPROC, MapBuffer);
OPENGL_PROC(PFNGLUNMAPBUFFERPROC, UnmapBuffer);
OPENGL_PROC(PFNGLGETBUFFERPARAMETERIVPROC, GetBufferParameteriv);
OPENGL_PROC(PFNGLGETBUFFERPOINTERVPROC, GetBufferPointerv);
OPENGL_PROC(PFNGLBLENDFUNCSEPARATEPROC, BlendFuncSeparate);
OPENGL_PROC(PFNGLBLENDEQUATIONSEPARATEPROC, BlendEquationSeparate);
OPENGL_PROC(PFNGLBLENDCOLORPROC, BlendColor);
OPENGL_PROC(PFNGLBLENDEQUATIONPROC, BlendEquation);
OPENGL_PROC(PFNGLCREATESHADERPROC, CreateShader);
OPENGL_PROC(PFNGLDELETESHADERPROC, DeleteShader);
OPENGL_PROC(PFNGLCOMPILESHADERPROC, CompileShader);
OPENGL_PROC(PFNGLSHADERSOURCEPROC, ShaderSource);
OPENGL_PROC(PFNGLGETSHADERIVPROC, GetShaderiv);
OPENGL_PROC(PFNGLGETSHADERINFOLOGPROC, GetShaderInfoLog);
OPENGL_PROC(PFNGLACTIVETEXTUREPROC, ActiveTexture);
OPENGL_PROC(PFNGLCREATEPROGRAMPROC, CreateProgram);
OPENGL_PROC(PFNGLDELETEPROGRAMPROC, DeleteProgram);
OPENGL_PROC(PFNGLATTACHSHADERPROC, AttachShader);
OPENGL_PROC(PFNGLGETATTRIBLOCATIONPROC, GetAttribLocation);
OPENGL_PROC(PFNGLLINKPROGRAMPROC, LinkProgram);
OPENGL_PROC(PFNGLBINDFRAGDATALOCATIONPROC, BindFragDataLocation);
OPENGL_PROC(PFNGLBINDATTRIBLOCATIONPROC, BindAttribLocation);
OPENGL_PROC(PFNGLGETUNIFORMLOCATIONPROC, GetUniformLocation);
OPENGL_PROC(PFNGLGETPROGRAMIVPROC, GetProgramiv);
OPENGL_PROC(PFNGLGETPROGRAMINFOLOGPROC, GetProgramInfoLog);
OPENGL_PROC(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer);
OPENGL_PROC(PFNGLENABLEVERTEXATTRIBARRAYPROC, EnableVertexAttribArray);
OPENGL_PROC(PFNGLDISABLEVERTEXATTRIBARRAYPROC, DisableVertexAttribArray);
OPENGL_PROC(PFNGLGENVERTEXARRAYSPROC, GenVertexArrays);
OPENGL_PROC(PFNGLBINDVERTEXARRAYPROC, BindVertexArray);
OPENGL_PROC(PFNGLDELETEVERTEXARRAYSPROC, DeleteVertexArrays);
OPENGL_PROC(PFNGLDEPTHRANGEFPROC, DepthRangef);
OPENGL_PROC(PFNGLUNIFORM1IPROC, Uniform1i);
OPENGL_PROC(PFNGLUNIFORM1FPROC, Uniform1f);
OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4f);
OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv);
OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram);
OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT);

View File

@ -3,11 +3,44 @@
void InitProcTable()
{
#define OPENGL_PROC(p, n) n = (p)wglGetProcAddress(#n)
#define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n)
#define OPENGL_PROC2(p, n, tn) /*if(!gl##n)*/ if(!(gl##n = (p)wglGetProcAddress(#tn))) ConLog.Error("OpenGL: initialization of " #tn " failed.")
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#undef OPENGL_PROC
#undef OPENGL_PROC2
}
#define OPENGL_PROC(p, n) p n = NULL
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#define OPENGL_PROC(p, n) p gl##n = nullptr
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#undef OPENGL_PROC2
OpenGL::OpenGL()
{
Close();
Init();
}
OpenGL::~OpenGL()
{
Close();
}
void OpenGL::Init()
{
#define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n)
#define OPENGL_PROC2(p, n, tn) if(!(n = (p)wglGetProcAddress(#tn))) ConLog.Error("OpenGL: initialization of " #tn " failed.")
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#undef OPENGL_PROC2
}
void OpenGL::Close()
{
#define OPENGL_PROC(p, n) n = nullptr
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#undef OPENGL_PROC2
}

View File

@ -2,8 +2,27 @@
#include <GL/gl.h>
#include "GL/glext.h"
#define OPENGL_PROC(p, n) extern p n
#include "GLProcTable.tbl"
#undef OPENGL_PROC
typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval);
void InitProcTable();
#define OPENGL_PROC(p, n) extern p gl##n
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#undef OPENGL_PROC2
void InitProcTable();
struct OpenGL
{
#define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n)
#define OPENGL_PROC(p, n) p n
#include "GLProcTable.tbl"
#undef OPENGL_PROC
#undef OPENGL_PROC2
OpenGL();
~OpenGL();
void Init();
void Close();
};

View File

@ -6,6 +6,22 @@ Program::Program() : id(0)
{
}
int Program::GetLocation(const wxString& name)
{
for(u32 i=0; i<m_locations.GetCount(); ++i)
{
if(!m_locations[i].name.Cmp(name))
{
return m_locations[i].loc;
}
}
u32 pos = m_locations.Move(new Location());
m_locations[pos].name = name;
return m_locations[pos].loc = glGetUniformLocation(id, name);
}
bool Program::IsCreated() const
{
return id > 0;
@ -19,23 +35,6 @@ void Program::Create(const u32 vp, const u32 fp)
glAttachShader(id, vp);
glAttachShader(id, fp);
glBindFragDataLocation(id, 0, "r0");
static const wxString reg_table[] =
{
"in_pos", "in_weight", "in_normal",
"in_col0", "in_col1",
"in_fogc",
"in_6", "in_7",
"in_tc0", "in_tc1", "in_tc2", "in_tc3",
"in_tc4", "in_tc5", "in_tc6", "in_tc7"
};
for(u32 i=0; i<WXSIZEOF(reg_table); ++i)
{
glBindAttribLocation(id, i, reg_table[i]);
checkForGlError("glBindAttribLocation");
}
glLinkProgram(id);
GLint linkStatus = GL_FALSE;
@ -81,7 +80,7 @@ void Program::Use()
void Program::SetTex(u32 index)
{
glUniform1i(glGetUniformLocation(id, wxString::Format("tex_%d", index)), index);
glUniform1i(GetLocation(wxString::Format("tex_%d", index)), index);
checkForGlError(wxString::Format("SetTex(%d)", index));
}

View File

@ -4,10 +4,21 @@
struct Program
{
private:
struct Location
{
int loc;
wxString name;
};
Array<Location> m_locations;
public:
u32 id;
Program();
int GetLocation(const wxString& name);
bool IsCreated() const;
void Create(const u32 vp, const u32 fp);
void Use();

View File

@ -70,11 +70,9 @@ u32 ProgramBuffer::GetProg(u32 fp, u32 vp) const
void ProgramBuffer::Add(Program& prog, ShaderProgram& fp, VertexProgram& vp)
{
const u32 pos = m_buf.GetCount();
m_buf.Add(new BufferInfo());
BufferInfo& new_buf = m_buf[pos];
BufferInfo& new_buf = *new BufferInfo();
ConLog.Write("Add program (%d):", pos);
ConLog.Write("Add program (%d):", m_buf.GetCount());
ConLog.Write("*** prog id = %d", prog.id);
ConLog.Write("*** vp id = %d", vp.id);
ConLog.Write("*** fp id = %d", fp.id);
@ -88,14 +86,13 @@ void ProgramBuffer::Add(Program& prog, ShaderProgram& fp, VertexProgram& vp)
new_buf.vp_id = vp.id;
new_buf.fp_id = fp.id;
new_buf.fp_data.SetCount(fp.size);
memcpy(&new_buf.fp_data[0], &Memory[fp.addr], fp.size);
new_buf.vp_data.SetCount(vp.data.GetCount());
memcpy(&new_buf.vp_data[0], &vp.data[0], vp.data.GetCount() * 4);
new_buf.fp_data.AddCpy(&Memory[fp.addr], fp.size);
new_buf.vp_data.CopyFrom(vp.data);
new_buf.vp_shader = vp.shader;
new_buf.fp_shader = fp.shader;
m_buf.Move(&new_buf);
}
void ProgramBuffer::Clear()

View File

@ -9,11 +9,23 @@ enum ParamFlag
PARAM_NONE,
};
struct ParamItem
{
wxString name;
wxString location;
ParamItem(const wxString& _name, int _location)
: name(_name)
, location(_location > -1 ? wxString::Format("layout (location = %d) ", _location) : "")
{
}
};
struct ParamType
{
const ParamFlag flag;
wxString type;
wxArrayString names;
Array<ParamItem> items;
ParamType(const ParamFlag _flag, const wxString& _type)
: type(_type)
@ -23,13 +35,29 @@ struct ParamType
bool SearchName(const wxString& name)
{
for(u32 i=0; i<names.GetCount(); ++i)
for(u32 i=0; i<items.GetCount(); ++i)
{
if(names[i].Cmp(name) == 0) return true;
if(items[i].name.Cmp(name) == 0) return true;
}
return false;
}
wxString Format()
{
wxString ret = wxEmptyString;
for(u32 n=0; n<items.GetCount(); ++n)
{
ret += items[n].location;
ret += type;
ret += " ";
ret += items[n].name;
ret += ";\n";
}
return ret;
}
};
struct ParamArray
@ -58,19 +86,20 @@ struct ParamArray
return wxEmptyString;
}
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name)
wxString AddParam(const ParamFlag flag, wxString type, const wxString& name, int location = -1)
{
type = GetParamFlag(flag) + type;
ParamType* t = SearchParam(type);
if(t)
{
if(!t->SearchName(name)) t->names.Add(name);
if(!t->SearchName(name)) t->items.Move(new ParamItem(name, location));
}
else
{
const u32 num = params.GetCount();
params.Add(new ParamType(flag, type));
params[num].names.Add(name);
params.Move(new ParamType(flag, type));
params[num].items.Move(new ParamItem(name, location));
}
return name;

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "VertexProgram.h"
wxString VertexDecompilerThread::GetMask()
wxString VertexDecompilerThread::GetVecMask()
{
wxString ret = wxEmptyString;
@ -13,7 +13,19 @@ wxString VertexDecompilerThread::GetMask()
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
}
wxString VertexDecompilerThread::GetDST()
wxString VertexDecompilerThread::GetScaMask()
{
wxString ret = wxEmptyString;
if(d3.sca_writemask_x) ret += "x";
if(d3.sca_writemask_y) ret += "y";
if(d3.sca_writemask_z) ret += "z";
if(d3.sca_writemask_w) ret += "w";
return ret.IsEmpty() || ret == "xyzw" ? wxEmptyString : ("." + ret);
}
wxString VertexDecompilerThread::GetDST(bool isSca)
{
static const wxString reg_table[] =
{
@ -26,11 +38,12 @@ wxString VertexDecompilerThread::GetDST()
};
wxString ret = wxEmptyString;
u32 dst = isSca ? d3.sca_dst : d3.dst;
switch(d3.dst)
switch(dst)
{
case 0x0: case 0x6:
ret += reg_table[d3.dst];
ret += reg_table[dst];
break;
case 0x1f:
@ -38,13 +51,13 @@ wxString VertexDecompilerThread::GetDST()
break;
default:
if(d3.dst < WXSIZEOF(reg_table))
if(dst < WXSIZEOF(reg_table))
{
ret += m_parr.AddParam(PARAM_OUT, "vec4", reg_table[d3.dst]);
ret += m_parr.AddParam(PARAM_OUT, "vec4", reg_table[dst]);
}
else
{
ConLog.Error("Bad dst reg num: %d", d3.dst);
ConLog.Error("Bad dst reg num: %d", dst);
ret += m_parr.AddParam(PARAM_OUT, "vec4", "unk");
}
break;
@ -53,7 +66,7 @@ wxString VertexDecompilerThread::GetDST()
return ret;
}
wxString VertexDecompilerThread::GetSRC(const u32 n)
wxString VertexDecompilerThread::GetSRC(const u32 n, bool isSca)
{
static const wxString reg_table[] =
{
@ -75,12 +88,12 @@ wxString VertexDecompilerThread::GetSRC(const u32 n)
case 2: //input
if(d1.input_src < WXSIZEOF(reg_table))
{
ret += m_parr.AddParam(PARAM_IN, "vec4", reg_table[d1.input_src]);
ret += m_parr.AddParam(PARAM_IN, "vec4", reg_table[d1.input_src], d1.input_src);
}
else
{
ConLog.Error("Bad input src num: %d", d1.input_src);
ret += m_parr.AddParam(PARAM_IN, "vec4", "in_unk");
ret += m_parr.AddParam(PARAM_IN, "vec4", "in_unk", d1.input_src);
}
break;
case 3: //const
@ -94,15 +107,27 @@ wxString VertexDecompilerThread::GetSRC(const u32 n)
}
static const char f[4] = {'x', 'z', 'w', 'y'};
static const char fSca[4] = {'x', 'z', 'y', 'w'};
wxString swizzle = wxEmptyString;
swizzle += f[src[n].swz_x];
swizzle += f[src[n].swz_y];
swizzle += f[src[n].swz_z];
swizzle += f[src[n].swz_w];
if (isSca)
{
assert(src[n].swz_x == src[n].swz_y);
assert(src[n].swz_z == src[n].swz_w);
assert(src[n].swz_x == src[n].swz_z);
if(swizzle != "xyzw") ret += "." + swizzle;
ret += "." + fSca[src[n].swz_x];
}
else
{
swizzle += f[src[n].swz_x];
swizzle += f[src[n].swz_y];
swizzle += f[src[n].swz_z];
swizzle += f[src[n].swz_w];
if(swizzle != "xyzw") ret += "." + swizzle;
}
bool abs;
@ -119,7 +144,7 @@ wxString VertexDecompilerThread::GetSRC(const u32 n)
return ret;
}
void VertexDecompilerThread::AddCode(wxString code, bool src_mask)
void VertexDecompilerThread::AddVecCode(wxString code, bool src_mask)
{
if(d0.cond == 0) return;
if(d0.cond != 7)
@ -129,7 +154,22 @@ void VertexDecompilerThread::AddCode(wxString code, bool src_mask)
return;
}
code = GetDST() + GetMask() + " = " + (src_mask ? code + GetMask() : code);
code = GetDST() + GetVecMask() + " = " + (src_mask ? code + GetVecMask() : code);
main += "\t" + code + ";\n";
}
void VertexDecompilerThread::AddScaCode(wxString code, bool src_mask)
{
if(d0.cond == 0) return;
if(d0.cond != 7)
{
ConLog.Error("Bad cond! %d", d0.cond);
Emu.Pause();
return;
}
code = GetDST(true) + GetScaMask() + " = " + (src_mask ? code + GetScaMask() : code);
main += "\t" + code + ";\n";
}
@ -140,17 +180,11 @@ wxString VertexDecompilerThread::BuildCode()
for(u32 i=0; i<m_parr.params.GetCount(); ++i)
{
for(u32 n=0; n<m_parr.params[i].names.GetCount(); ++n)
{
p += m_parr.params[i].type;
p += " ";
p += m_parr.params[i].names[n];
p += ";\n";
}
p += m_parr.params[i].Format();
}
static const wxString& prot =
"#version 330 core\n"
"#version 330\n"
"\n"
"%s\n"
"void main()\n{\n%s}\n";
@ -158,7 +192,7 @@ wxString VertexDecompilerThread::BuildCode()
return wxString::Format(prot, p, main);
}
wxThread::ExitCode VertexDecompilerThread::Entry()
void VertexDecompilerThread::Task()
{
for(u32 i=0;;)
{
@ -171,30 +205,62 @@ wxThread::ExitCode VertexDecompilerThread::Entry()
src[1].HEX = d2.src1;
src[2].HEX = d3.src2l | (d2.src2h << 11);
switch(d1.sca_opcode)
{
case 0x00: break; // NOP
case 0x01: AddScaCode(GetSRC(2, true)); break; // MOV
case 0x02: AddScaCode("1 / (" + GetSRC(2, true) + ")"); break; // RCP
case 0x03: AddScaCode("clamp(1 / (" + GetSRC(2, true) + "), 5.42101e-20, 1.884467e19"); break; // RCC
case 0x04: AddScaCode("inversesqrt(" + GetSRC(2, true) + ")"); break; // RSQ
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
//case 0x07: break; // LIT
//case 0x08: break; // BRA
//case 0x09: break; // BRI : works differently (BRI o[1].x(TR) L0;)
//case 0x0a: break; // CAL : works same as BRI
//case 0x0b: break; // CLI : works same as BRI
//case 0x0c: break; // RET : works like BRI but shorter (RET o[1].x(TR);)
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
case 0x10: AddScaCode("cos(" + GetSRC(2, true) + ")"); break; // COS
//case 0x11: break; // BRB : works differently (BRB o[1].x !b0, L0;)
//case 0x12: break; // CLB : works same as BRB
//case 0x13: break; // PSH : works differently (PSH o[1].x A0;)
//case 0x14: break; // POP : works differently (POP o[1].x;)
default:
ConLog.Error("Unknown vp sca_opcode 0x%x", d1.sca_opcode);
Emu.Pause();
break;
}
switch(d1.vec_opcode)
{
case 0x00: break; //NOP
case 0x01: AddCode(GetSRC(0)); break; //MOV
case 0x02: AddCode("(" + GetSRC(0) + " * " + GetSRC(1) + ")"); break; //MUL
case 0x03: AddCode("(" + GetSRC(0) + " + " + GetSRC(1) + ")"); break; //ADD
case 0x04: AddCode("(" + GetSRC(0) + " * " + GetSRC(1) + " + " + GetSRC(2) + ")"); break; //MAD
case 0x05: AddCode("dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz)", false); break; //DP3
//case 0x06: TODO //DPH
case 0x07: AddCode("dot(" + GetSRC(0) + ", " + GetSRC(1) + ")", false); break; //DP4
case 0x08: AddCode("distance(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //DST
case 0x09: AddCode("min(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
case 0x0a: AddCode("max(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
case 0x0b: AddCode("lessThan(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SLT
case 0x0c: AddCode("greaterThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SGE
case 0x0e: AddCode("fract(" + GetSRC(0) + ")"); break; //FRC
case 0x0f: AddCode("floor(" + GetSRC(0) + ")"); break; //FLR
case 0x10: AddCode("equal(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SEQ
case 0x11: AddCode("vec4(0.0f, 0.0f, 0.0f, 0.0f)"); break; //SFL
case 0x12: AddCode("greaterThan(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SGT
case 0x13: AddCode("lessThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SLE
case 0x14: AddCode("notEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SNE
case 0x15: AddCode("vec4(1.0f, 1.0f, 1.0f, 1.0f)"); break; //STR
case 0x16: AddCode("sign(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SSG
case 0x01: AddVecCode(GetSRC(0)); break; //MOV
case 0x02: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + ")"); break; //MUL
case 0x03: AddVecCode("(" + GetSRC(0) + " + " + GetSRC(1) + ")"); break; //ADD
case 0x04: AddVecCode("(" + GetSRC(0) + " * " + GetSRC(1) + " + " + GetSRC(2) + ")"); break; //MAD
case 0x05: AddVecCode("dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz)", false); break; //DP3
case 0x06: AddVecCode("(dot(" + GetSRC(0) + ".xyz, " + GetSRC(1) + ".xyz) + " + GetSRC(1) + ".w)", false); break; //DPH
case 0x07: AddVecCode("dot(" + GetSRC(0) + ", " + GetSRC(1) + ")", false); break; //DP4
case 0x08: AddVecCode("distance(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //DST
case 0x09: AddVecCode("min(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MIN
case 0x0a: AddVecCode("max(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //MAX
case 0x0b: AddVecCode("lessThan(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SLT
case 0x0c: AddVecCode("greaterThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SGE
case 0x0e: AddVecCode("fract(" + GetSRC(0) + ")"); break; //FRC
case 0x0f: AddVecCode("floor(" + GetSRC(0) + ")"); break; //FLR
case 0x10: AddVecCode("equal(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SEQ
case 0x11: AddVecCode("vec4(0.0f, 0.0f, 0.0f, 0.0f)"); break; //SFL
case 0x12: AddVecCode("greaterThan(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SGT
case 0x13: AddVecCode("lessThanEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SLE
case 0x14: AddVecCode("notEqual(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SNE
case 0x15: AddVecCode("vec4(1.0f, 1.0f, 1.0f, 1.0f)"); break; //STR
case 0x16: AddVecCode("sign(" + GetSRC(0) + ", " + GetSRC(1) + ")"); break; //SSG
default:
ConLog.Error("Unknown vp opcode 0x%x", d1.vec_opcode);
@ -207,8 +273,6 @@ wxThread::ExitCode VertexDecompilerThread::Entry()
m_shader = BuildCode();
main = wxEmptyString;
return (ExitCode)0;
}
VertexProgram::VertexProgram()
@ -222,8 +286,13 @@ VertexProgram::~VertexProgram()
if(m_decompiler_thread)
{
Wait();
if(m_decompiler_thread->IsAlive()) m_decompiler_thread->Delete();
safe_delete(m_decompiler_thread);
if(m_decompiler_thread->IsAlive())
{
m_decompiler_thread->Stop();
}
delete m_decompiler_thread;
m_decompiler_thread = nullptr;
}
Delete();
@ -237,13 +306,17 @@ void VertexProgram::Decompile()
if(m_decompiler_thread)
{
Wait();
if(m_decompiler_thread->IsAlive()) m_decompiler_thread->Delete();
safe_delete(m_decompiler_thread);
if(m_decompiler_thread->IsAlive())
{
m_decompiler_thread->Stop();
}
delete m_decompiler_thread;
m_decompiler_thread = nullptr;
}
m_decompiler_thread = new VertexDecompilerThread(data, shader, parr);
m_decompiler_thread->Create();
m_decompiler_thread->Run();
m_decompiler_thread->Start();
#endif
}
@ -272,7 +345,7 @@ void VertexProgram::Compile()
memset(buf, 0, r+1);
glGetShaderInfoLog(id, r, &len, buf);
ConLog.Error("Failed to compile vertex shader: %s", buf);
free(buf);
delete[] buf;
}
ConLog.Write(shader);
@ -287,7 +360,7 @@ void VertexProgram::Delete()
data.Clear();
for(u32 i=0; i<parr.params.GetCount(); ++i)
{
parr.params[i].names.Clear();
parr.params[i].items.Clear();
parr.params[i].type.Clear();
}
parr.params.Clear();

View File

@ -1,7 +1,7 @@
#pragma once
#include "ShaderParam.h"
struct VertexDecompilerThread : public wxThread
struct VertexDecompilerThread : public ThreadBase
{
union D0
{
@ -113,20 +113,22 @@ struct VertexDecompilerThread : public wxThread
ParamArray& m_parr;
VertexDecompilerThread(Array<u32>& data, wxString& shader, ParamArray& parr)
: wxThread(wxTHREAD_JOINABLE)
: ThreadBase(false, "Vertex Shader Decompiler Thread")
, m_data(data)
, m_shader(shader)
, m_parr(parr)
{
}
wxString GetMask();
wxString GetDST();
wxString GetSRC(const u32 n);
void AddCode(wxString code, bool src_mask = true);
wxString GetVecMask();
wxString GetScaMask();
wxString GetDST(bool isSca = false);
wxString GetSRC(const u32 n, bool isSca = false);
void AddVecCode(wxString code, bool src_mask = true);
void AddScaCode(wxString code, bool src_mask = true);
wxString BuildCode();
ExitCode Entry();
virtual void Task();
};
struct VertexProgram
@ -149,7 +151,13 @@ struct VertexProgram
Array<u32> data;
ParamArray parr;
void Wait() { if(m_decompiler_thread && m_decompiler_thread->IsRunning()) m_decompiler_thread->Wait(); }
void Wait()
{
if(m_decompiler_thread && m_decompiler_thread->IsRunning())
{
m_decompiler_thread->Wait();
}
}
void Decompile();
void Compile();
void Delete();

View File

@ -15,6 +15,9 @@ GSManager::GSManager() : m_render(NULL)
void GSManager::Init()
{
if(m_render) return;
m_info.Init();
switch(Ini.GSRenderMode.GetValue())
{
default:
@ -29,9 +32,8 @@ void GSManager::Close()
if(m_render)
{
m_render->Close();
//free(m_render);
m_render = nullptr;
}
m_render = NULL;
}
u8 GSManager::GetState()

View File

@ -4,19 +4,31 @@
struct GSInfo
{
CellVideoOutResolution outresolution;
CellVideoOutDisplayMode mode;
struct
{
u8 resolutionId;
u8 scanMode;
u8 conversion;
u8 aspect;
u8 format;
u16 refreshRates;
u32 pitch;
} mode;
//CellVideoOutDisplayMode mode;
GSInfo()
{
outresolution.width = 740;
outresolution.height = 480;
}
mode.resolutionId = CELL_VIDEO_OUT_RESOLUTION_576;
void Init()
{
mode.resolutionId = Ini.GSResolution.GetValue();
mode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_INTERLACE;
mode.conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE;
mode.aspect = CELL_VIDEO_OUT_ASPECT_4_3;
mode.aspect = Ini.GSAspectRatio.GetValue();
mode.refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_50HZ;
mode.format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8;
mode.pitch = 4;
}
};
@ -47,7 +59,7 @@ public:
void Close();
GSInfo& GetInfo() { return m_info; }
GSRender& GetRender() { return *m_render; }
GSRender& GetRender() { assert(m_render); return *m_render; }
u8 GetState();
u8 GetColorSpace();

View File

@ -21,10 +21,10 @@ wxSize AspectRatio(wxSize rs, const wxSize as)
GSFrame::GSFrame(wxWindow* parent, const wxString& title) : wxFrame(parent, wxID_ANY, title)
{
SetClientSize(720, 576);
//Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(GSFrame::OnLeftDclick));
CellVideoOutResolution res = ResolutionTable[ResolutionIdToNum(Ini.GSResolution.GetValue())];
SetClientSize(res.width, res.height);
wxGetApp().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(GSFrame::OnKeyDown), (wxObject*)0, this);
wxGetApp().Connect(GetId(), wxEVT_CLOSE_WINDOW, wxCloseEventHandler(GSFrame::OnClose), (wxObject*)0, this);
Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(GSFrame::OnClose));
}
void GSFrame::OnPaint(wxPaintEvent& event)
@ -54,7 +54,7 @@ void GSFrame::OnKeyDown(wxKeyEvent& event)
{
switch(event.GetKeyCode())
{
case WXK_RETURN: if(event.ControlDown()) { OnFullScreen(); return; } break;
case WXK_RETURN: if(event.AltDown()) { OnFullScreen(); return; } break;
case WXK_ESCAPE: if(IsFullScreen()) { ShowFullScreen(false); return; } break;
}
event.Skip();
@ -79,7 +79,8 @@ void GSFrame::SetSize(int width, int height)
GSRender::GSRender()
: m_ctrl(NULL)
, m_flip_status(-1)
, m_flip_status(0)
, m_flip_mode(CELL_GCM_DISPLAY_VSYNC)
{
}
@ -91,4 +92,8 @@ u32 GSRender::GetAddress(u32 offset, u8 location)
case CELL_GCM_LOCATION_MAIN: return offset;
}
return 0;
}
GSLockCurrent::GSLockCurrent(GSLockType type) : GSLock(Emu.GetGSManager().GetRender(), type)
{
}

View File

@ -1,6 +1,15 @@
#pragma once
#include "Emu/GS/GCM.h"
enum Method
{
CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000,
CELL_GCM_METHOD_FLAG_JUMP = 0x20000000,
CELL_GCM_METHOD_FLAG_CALL = 0x00000002,
CELL_GCM_METHOD_FLAG_RETURN = 0x00020000,
};
wxSize AspectRatio(wxSize rs, const wxSize as);
class GSFrame : public wxFrame
@ -14,15 +23,15 @@ protected:
//virtual void OnSize(wxSizeEvent&);
void OnKeyDown(wxKeyEvent& event);
void OnFullScreen();
public:
void OnLeftDclick(wxMouseEvent&)
{
OnFullScreen();
}
void OnKeyDown(wxKeyEvent& event);
void OnFullScreen();
public:
//void SetSize(int width, int height);
private:
@ -33,15 +42,60 @@ struct GSRender
{
u32 m_ioAddress, m_ioSize, m_ctrlAddress, m_localAddress;
CellGcmControl* m_ctrl;
wxCriticalSection m_cs_main;
wxSemaphore m_sem_flush;
wxSemaphore m_sem_flip;
int m_flip_status;
int m_flip_mode;
volatile bool m_draw;
GSRender();
virtual void Init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress)=0;
virtual void Draw()=0;
virtual void Close()=0;
virtual void Pause()=0;
virtual void Resume()=0;
u32 GetAddress(u32 offset, u8 location);
};
enum GSLockType
{
GS_LOCK_NOT_WAIT,
GS_LOCK_WAIT_FLUSH,
GS_LOCK_WAIT_FLIP,
};
struct GSLock
{
private:
GSRender& m_renderer;
GSLockType m_type;
public:
GSLock(GSRender& renderer, GSLockType type)
: m_renderer(renderer)
, m_type(type)
{
switch(m_type)
{
case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.Enter(); break;
case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.Wait(); break;
case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.Wait(); break;
}
}
~GSLock()
{
switch(m_type)
{
case GS_LOCK_NOT_WAIT: m_renderer.m_cs_main.Leave(); break;
case GS_LOCK_WAIT_FLUSH: m_renderer.m_sem_flush.Post(); break;
case GS_LOCK_WAIT_FLIP: m_renderer.m_sem_flip.Post(); break;
}
}
};
struct GSLockCurrent : GSLock
{
GSLockCurrent(GSLockType type);
};

View File

@ -5,6 +5,7 @@ struct NullGSFrame : public GSFrame
{
NullGSFrame() : GSFrame(NULL, "GSFrame[Null]")
{
Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(GSFrame::OnLeftDclick));
}
void Draw() { Draw(wxClientDC(this)); }
@ -23,22 +24,33 @@ private:
}
};
struct NullRSXThread : public wxThread
{
wxWindow* m_parent;
Stack<u32> call_stack;
NullRSXThread(wxWindow* parent);
virtual void OnExit();
void Start();
ExitCode Entry();
};
class NullGSRender
: public wxWindow
, public GSRender
{
private:
NullGSFrame* m_frame;
wxTimer* m_update_timer;
bool m_paused;
NullRSXThread* m_rsx_thread;
public:
NullGSFrame* m_frame;
NullGSRender()
: m_frame(NULL)
, m_paused(false)
: m_frame(nullptr)
, m_rsx_thread(nullptr)
{
m_update_timer = new wxTimer(this);
Connect(m_update_timer->GetId(), wxEVT_TIMER, wxTimerEventHandler(NullGSRender::OnTimer));
m_draw = false;
m_frame = new NullGSFrame();
}
@ -62,24 +74,10 @@ private:
m_localAddress = localAddress;
m_ctrl = (CellGcmControl*)Memory.GetMemFromAddr(m_ctrlAddress);
m_update_timer->Start(1);
}
void OnTimer(wxTimerEvent&)
{
while(!m_paused && m_ctrl->get != m_ctrl->put && Emu.IsRunned())
{
const u32 get = re(m_ctrl->get);
const u32 cmd = Memory.Read32(m_ioAddress + get);
const u32 count = (cmd >> 18) & 0x7ff;
mem32_t data(m_ioAddress + get + 4);
m_ctrl->get = re32(get + (count + 1) * 4);
DoCmd(cmd, cmd & 0x3ffff, data, count);
memset(Memory.GetMemFromAddr(m_ioAddress + get), 0, (count + 1) * 4);
}
(m_rsx_thread = new NullRSXThread(this))->Start();
}
public:
void DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count)
{
switch(cmd)
@ -87,32 +85,107 @@ private:
case NV406E_SET_REFERENCE:
m_ctrl->ref = re32(args[0]);
break;
case NV4097_SET_BEGIN_END:
if(!args[0]) m_flip_status = 0;
break;
}
}
virtual void Draw()
{
//if(m_frame && !m_frame->IsBeingDeleted()) m_frame->Draw();
m_draw = true;
}
virtual void Close()
{
m_update_timer->Stop();
if(m_rsx_thread) m_rsx_thread->Delete();
if(m_frame->IsShown()) m_frame->Hide();
m_ctrl = NULL;
}
};
void Pause()
NullRSXThread::NullRSXThread(wxWindow* parent)
: wxThread(wxTHREAD_DETACHED)
, m_parent(parent)
{
}
void NullRSXThread::OnExit()
{
call_stack.Clear();
}
void NullRSXThread::Start()
{
Create();
Run();
}
wxThread::ExitCode NullRSXThread::Entry()
{
ConLog.Write("Null RSX thread entry");
NullGSRender& p = *(NullGSRender*)m_parent;
while(!TestDestroy() && p.m_frame && !p.m_frame->IsBeingDeleted())
{
m_paused = true;
wxCriticalSectionLocker lock(p.m_cs_main);
if(p.m_ctrl->get == p.m_ctrl->put || !Emu.IsRunned())
{
SemaphorePostAndWait(p.m_sem_flush);
if(p.m_draw)
{
p.m_draw = false;
p.m_flip_status = 0;
if(SemaphorePostAndWait(p.m_sem_flip)) continue;
}
Sleep(1);
continue;
}
const u32 get = re(p.m_ctrl->get);
const u32 cmd = Memory.Read32(p.m_ioAddress + get);
const u32 count = (cmd >> 18) & 0x7ff;
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
{
p.m_ctrl->get = re32(cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT));
ConLog.Warning("rsx jump!");
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
{
call_stack.Push(get + 4);
p.m_ctrl->get = re32(cmd & ~CELL_GCM_METHOD_FLAG_CALL);
ConLog.Warning("rsx call!");
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_RETURN)
{
p.m_ctrl->get = re32(call_stack.Pop());
ConLog.Warning("rsx return!");
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
{
//ConLog.Warning("non increment cmd! 0x%x", cmd);
}
if(cmd == 0)
{
ConLog.Warning("null cmd: addr=0x%x, put=0x%x, get=0x%x", p.m_ioAddress + get, re(p.m_ctrl->put), get);
Emu.Pause();
continue;
}
p.DoCmd(cmd, cmd & 0x3ffff, mem32_t(p.m_ioAddress + get + 4), count);
re(p.m_ctrl->get, get + (count + 1) * 4);
}
void Resume()
{
m_paused = false;
}
};
ConLog.Write("Null RSX thread exit...");
call_stack.Clear();
return (ExitCode)0;
}

View File

@ -1,81 +1,14 @@
#include "stdafx.h"
#include "RSXThread.h"
enum MethodFlag
{
CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000,
CELL_GCM_METHOD_FLAG_JUMP = 0x20000000,
CELL_GCM_METHOD_FLAG_CALL = 0x00000002,
CELL_GCM_METHOD_FLAG_RETURN = 0x00020000,
};
RSXThread::RSXThread(
CellGcmControl* ctrl,
u32 ioAddress,
void (&cmd)(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count),
bool (&_flip)(),
bool (&_TestExit)()
)
RSXThread::RSXThread(CellGcmControl* ctrl, u32 ioAddress)
: m_ctrl(*ctrl)
, m_ioAddress(ioAddress)
, DoCmd(cmd)
, flip(_flip)
, TestExit(_TestExit)
{
}
void RSXThread::Task()
{
while(!TestDestroy() && !TestExit())
{
if(m_ctrl.get == m_ctrl.put)
{
flip();
Sleep(1);
continue;
}
const u32 get = re(m_ctrl.get);
const u32 cmd = Memory.Read32(m_ioAddress + get);
const u32 count = (cmd >> 18) & 0x7ff;
mem32_t data(m_ioAddress + get + 4);
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
{
m_ctrl.get = re32(cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT));
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
{
call_stack.AddCpy(get + 4);
m_ctrl.get = re32(cmd & ~CELL_GCM_METHOD_FLAG_CALL);
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_RETURN)
{
const u32 pos = call_stack.GetCount() - 1;
m_ctrl.get = re32(call_stack[pos]);
call_stack.RemoveAt(pos);
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT)
{
//ConLog.Warning("non increment cmd! 0x%x", cmd);
}
#if 0
wxString debug = getMethodName(cmd & 0x3ffff);
debug += "(";
for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + wxString::Format("0x%x", data[i]);
debug += ")";
ConLog.Write(debug);
#endif
DoCmd(cmd, cmd & 0x3ffff, data, count);
m_ctrl.get = re32(get + (count + 1) * 4);
memset(Memory.GetMemFromAddr(m_ioAddress + get), 0, (count + 1) * 4);
}
}
void RSXThread::OnExit()

View File

@ -1,23 +1,73 @@
#pragma once
#include "GCM.h"
class ExecRSXCMDdata
{
protected:
bool m_set_color_mask;
bool m_color_mask_r;
bool m_color_mask_g;
bool m_color_mask_b;
bool m_color_mask_a;
bool m_set_clip;
float m_clip_min;
float m_clip_max;
bool m_set_depth_func;
int m_depth_func;
bool m_set_alpha_test;
bool m_set_blend;
bool m_set_depth_bounds_test;
bool m_depth_test_enable;
bool m_set_viewport_horizontal;
bool m_set_viewport_vertical;
u16 m_viewport_x;
u16 m_viewport_y;
u16 m_viewport_w;
u16 m_viewport_h;
bool m_set_scissor_horizontal;
bool m_set_scissor_vertical;
u16 m_scissor_x;
u16 m_scissor_y;
u16 m_scissor_w;
u16 m_scissor_h;
public:
ExecRSXCMDdata()
{
Reset();
}
virtual void Reset()
{
m_set_color_mask = false;
m_set_alpha_test = false;
m_set_blend = false;
m_set_depth_bounds_test = false;
m_set_clip = false;
m_set_depth_func = false;
m_depth_test_enable = false;
m_set_viewport_horizontal = false;
m_set_viewport_vertical = false;
m_set_scissor_horizontal = false;
m_set_scissor_vertical = false;
}
virtual void ExecCMD()=0;
};
class RSXThread : public ThreadBase
{
Array<u32> call_stack;
void (&DoCmd)(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count);
bool (&flip)();
bool (&TestExit)();
CellGcmControl& m_ctrl;
u32 m_ioAddress;
protected:
RSXThread(
CellGcmControl* ctrl,
u32 ioAddress,
void (&cmd)(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count),
bool (&_flip)(),
bool (&_TestExit)()
);
RSXThread(CellGcmControl* ctrl, u32 ioAddress);
private:
virtual void Task();

View File

@ -14,7 +14,6 @@ enum VideoErrorCode
CELL_VIDEO_OUT_ERROR_VALUE_IS_NOT_SET = 0x8002b228,
};
enum CellVideoOut
{
CELL_VIDEO_OUT_PRIMARY,
@ -166,22 +165,22 @@ struct CellVideoOutDisplayMode
struct CellVideoOutResolution
{
u16 width;
u16 height;
u16 width;
u16 height;
};
struct CellVideoOutDeviceInfo
{
u8 portType;
u8 colorSpace;
u16 latency;
u8 availableModeCount;
u8 state;
u8 rgbOutputRange;
u8 reserved[5];
CellVideoOutColorInfo colorInfo;
CellVideoOutDisplayMode availableModes[32];
CellVideoOutKSVList ksvList;
u8 portType;
u8 colorSpace;
u16 latency;
u8 availableModeCount;
u8 state;
u8 rgbOutputRange;
u8 reserved[5];
CellVideoOutColorInfo colorInfo;
CellVideoOutDisplayMode availableModes[32];
CellVideoOutKSVList ksvList;
};
struct CellVideoOutState
@ -194,11 +193,11 @@ struct CellVideoOutState
struct CellVideoOutConfiguration
{
u8 resolutionId;
u8 format;
u8 aspect;
u8 reserved[9];
u32 pitch;
u8 resolutionId;
u8 format;
u8 aspect;
u8 reserved[9];
u32 pitch;
};
enum CellVideoOutEvent
@ -220,4 +219,58 @@ enum CellVideoOutRGBOutputRange
{
CELL_VIDEO_OUT_RGB_OUTPUT_RANGE_LIMITED,
CELL_VIDEO_OUT_RGB_OUTPUT_RANGE_FULL,
};
};
static const CellVideoOutResolution ResolutionTable[] =
{
{-1, -1}, //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)
{
static const u32 res[] =
{
0, //0
1, //1
2, //2
0, //3
3, //4
4, //5
0, //6
0, //7
0, //8
0, //9
5, //10
6, //11
7, //12
8, //13
};
return id <= 13 ? res[id] : 0;
}
inline static u32 ResolutionNumToId(u32 num)
{
static const u32 res[] =
{
0,
1,
2,
4,
5,
10,
11,
12,
13,
};
return num <= 8 ? res[num] : 0;
}

View File

@ -6,11 +6,13 @@ class WindowsPadHandler
: public wxWindow
, public PadHandlerBase
{
AppConnector m_app_connector;
public:
WindowsPadHandler() : wxWindow()
{
wxGetApp().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(WindowsPadHandler::KeyDown), (wxObject*)0, this);
wxGetApp().Connect(wxEVT_KEY_UP, wxKeyEventHandler(WindowsPadHandler::KeyUp), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(WindowsPadHandler::KeyDown), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_KEY_UP, wxKeyEventHandler(WindowsPadHandler::KeyUp), (wxObject*)0, this);
}
virtual void KeyDown(wxKeyEvent& event) { Key(event.GetKeyCode(), 1); event.Skip(); }
@ -32,27 +34,27 @@ public:
void LoadSettings()
{
m_pads.Add(new Pad(
m_pads.Move(new Pad(
CELL_PAD_STATUS_CONNECTED, CELL_PAD_SETTING_PRESS_ON | CELL_PAD_SETTING_SENSOR_OFF,
CELL_PAD_CAPABILITY_PS3_CONFORMITY | CELL_PAD_CAPABILITY_PRESS_MODE,
CELL_PAD_DEV_TYPE_STANDARD));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'A', CELL_PAD_CTRL_LEFT));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'S', CELL_PAD_CTRL_DOWN));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'D', CELL_PAD_CTRL_RIGHT));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'W', CELL_PAD_CTRL_UP));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, WXK_RETURN, CELL_PAD_CTRL_START));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'X', CELL_PAD_CTRL_R3));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'Z', CELL_PAD_CTRL_L3));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, WXK_SPACE, CELL_PAD_CTRL_SELECT));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'A', CELL_PAD_CTRL_LEFT));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'S', CELL_PAD_CTRL_DOWN));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'D', CELL_PAD_CTRL_RIGHT));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'W', CELL_PAD_CTRL_UP));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, WXK_RETURN, CELL_PAD_CTRL_START));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'X', CELL_PAD_CTRL_R3));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, 'Z', CELL_PAD_CTRL_L3));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL1, WXK_SPACE, CELL_PAD_CTRL_SELECT));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'K', CELL_PAD_CTRL_SQUARE));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'L', CELL_PAD_CTRL_CROSS));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, ';', CELL_PAD_CTRL_CIRCLE));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'O', CELL_PAD_CTRL_TRIANGLE));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'I', CELL_PAD_CTRL_R1));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'Q', CELL_PAD_CTRL_L1));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'P', CELL_PAD_CTRL_R2));
m_pads[0].m_buttons.Add(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'E', CELL_PAD_CTRL_L2));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'K', CELL_PAD_CTRL_SQUARE));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'L', CELL_PAD_CTRL_CROSS));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, ';', CELL_PAD_CTRL_CIRCLE));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'O', CELL_PAD_CTRL_TRIANGLE));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'I', CELL_PAD_CTRL_R1));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'Q', CELL_PAD_CTRL_L1));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'P', CELL_PAD_CTRL_R2));
m_pads[0].m_buttons.Move(new Button(CELL_PAD_BTN_OFFSET_DIGITAL2, 'E', CELL_PAD_CTRL_L2));
}
};

View File

@ -20,13 +20,15 @@ void MemoryBlock::Init()
range_start = 0;
range_size = 0;
mem = NULL;
mem = nullptr;
}
void MemoryBlock::InitMemory()
{
if(!range_size) return;
safe_delete(mem);
mem = new u8[range_size];
mem = (u8*)malloc(range_size);
memset(mem, 0, range_size);
}
@ -43,32 +45,36 @@ u64 MemoryBlock::FixAddr(const u64 addr) const
bool MemoryBlock::GetMemFromAddr(void* dst, const u64 addr, const u32 size)
{
if(!IsMyAddress(addr)) return false;
if(FixAddr(addr) + size > GetSize()) return false;
memcpy(dst, &mem[FixAddr(addr)], size);
if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false;
memcpy(dst, GetMem(FixAddr(addr)), size);
return true;
}
bool MemoryBlock::SetMemFromAddr(void* src, const u64 addr, const u32 size)
{
if(!IsMyAddress(addr)) return false;
if(FixAddr(addr) + size > GetSize()) return false;
memcpy(&mem[FixAddr(addr)], src, size);
if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false;
memcpy(GetMem(FixAddr(addr)), src, size);
return true;
}
bool MemoryBlock::GetMemFFromAddr(void* dst, const u64 addr)
{
if(!IsMyAddress(addr)) return false;
dst = &mem[FixAddr(addr)];
dst = GetMem(FixAddr(addr));
return true;
}
u8* MemoryBlock::GetMemFromAddr(const u64 addr)
{
if(!IsMyAddress(addr)) return NULL;
if(!IsMyAddress(addr) || IsNULL()) return nullptr;
return &mem[FixAddr(addr)];
return GetMem(FixAddr(addr));
}
MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size)
@ -80,24 +86,6 @@ MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size)
return this;
}
bool MemoryBlock::SetNewSize(const u32 size)
{
if(range_size >= size) return false;
u8* new_mem = (u8*)realloc(mem, size);
if(!new_mem)
{
ConLog.Error("Not enought free memory");
Emu.Pause();
return false;
}
mem = new_mem;
range_size = size;
return true;
}
bool MemoryBlock::IsMyAddress(const u64 addr)
{
return addr >= GetStartAddr() && addr < GetEndAddr();
@ -105,7 +93,7 @@ bool MemoryBlock::IsMyAddress(const u64 addr)
__forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const
{
return mem[addr];
return *GetMem(addr);
}
__forceinline const u16 MemoryBlock::FastRead16(const u64 addr) const
@ -126,8 +114,8 @@ __forceinline const u64 MemoryBlock::FastRead64(const u64 addr) const
__forceinline const u128 MemoryBlock::FastRead128(const u64 addr)
{
u128 ret;
ret.hi = FastRead64(addr);
ret.lo = FastRead64(addr + 8);
ret.lo = FastRead64(addr);
ret.hi = FastRead64(addr + 8);
return ret;
}
@ -193,7 +181,7 @@ bool MemoryBlock::Read128(const u64 addr, u128* value)
__forceinline void MemoryBlock::FastWrite8(const u64 addr, const u8 value)
{
mem[addr] = value;
*GetMem(addr) = value;
}
__forceinline void MemoryBlock::FastWrite16(const u64 addr, const u16 value)
@ -216,8 +204,8 @@ __forceinline void MemoryBlock::FastWrite64(const u64 addr, const u64 value)
__forceinline void MemoryBlock::FastWrite128(const u64 addr, const u128 value)
{
FastWrite64(addr, value.hi);
FastWrite64(addr+8, value.lo);
FastWrite64(addr, value.lo);
FastWrite64(addr+8, value.hi);
}
bool MemoryBlock::Write8(const u64 addr, const u8 value)
@ -332,11 +320,22 @@ bool NullMemoryBlock::Write128(const u64 addr, const u128 value)
}
//DynamicMemoryBlock
DynamicMemoryBlock::DynamicMemoryBlock() : m_point(0)
, m_max_size(0)
DynamicMemoryBlock::DynamicMemoryBlock() : m_max_size(0)
{
}
const u32 DynamicMemoryBlock::GetUsedSize() const
{
u32 size = 0;
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
size += m_used_mem[i].size;
}
return size;
}
bool DynamicMemoryBlock::IsInMyRange(const u64 addr)
{
return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize();
@ -363,8 +362,7 @@ bool DynamicMemoryBlock::IsMyAddress(const u64 addr)
MemoryBlock* DynamicMemoryBlock::SetRange(const u64 start, const u32 size)
{
m_max_size = size;
MemoryBlock::SetRange(start, 4);
m_point = GetStartAddr();
MemoryBlock::SetRange(start, 0);
return this;
}
@ -372,146 +370,64 @@ MemoryBlock* DynamicMemoryBlock::SetRange(const u64 start, const u32 size)
void DynamicMemoryBlock::Delete()
{
m_used_mem.Clear();
m_free_mem.Clear();
m_point = 0;
m_max_size = 0;
MemoryBlock::Delete();
}
void DynamicMemoryBlock::UpdateSize(u64 addr, u32 size)
{
u32 used_size = addr + size - GetStartAddr();
if(used_size > GetUsedSize()) SetNewSize(used_size);
}
void DynamicMemoryBlock::CombineFreeMem()
{
if(m_free_mem.GetCount() < 2) return;
for(u32 i1=0; i1<m_free_mem.GetCount(); ++i1)
{
MemBlockInfo& u1 = m_free_mem[i1];
for(u32 i2=i1+1; i2<m_free_mem.GetCount(); ++i2)
{
const MemBlockInfo u2 = m_free_mem[i2];
if(u1.addr + u1.size != u2.addr) continue;
u1.size += u2.size;
m_free_mem.RemoveAt(i2);
break;
}
}
}
bool DynamicMemoryBlock::Alloc(u64 addr, u32 size)
{
if(!IsInMyRange(addr, size) || IsMyAddress(addr) || IsMyAddress(addr + size - 1))
if(!IsInMyRange(addr, size))
{
assert(0);
return false;
}
if(addr == m_point)
if(IsMyAddress(addr) || IsMyAddress(addr + size - 1))
{
UpdateSize(m_point, size);
m_used_mem.AddCpy(MemBlockInfo(m_point, size));
memset(mem + (m_point - GetStartAddr()), 0, size);
m_point += size;
return true;
return false;
}
if(addr > m_point)
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
u64 free_mem_addr = GetStartAddr();
if(free_mem_addr != addr)
{
for(u32 i=0; i<m_free_mem.GetCount(); ++i)
{
if(m_free_mem[i].addr >= free_mem_addr && m_free_mem[i].addr < addr)
{
free_mem_addr = m_free_mem[i].addr + m_free_mem[i].size;
}
}
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
if(m_used_mem[i].addr >= free_mem_addr && m_used_mem[i].addr < addr)
{
free_mem_addr = m_used_mem[i].addr + m_used_mem[i].size;
}
}
m_free_mem.AddCpy(MemBlockInfo(free_mem_addr, addr - GetStartAddr()));
}
UpdateSize(addr, size);
m_used_mem.AddCpy(MemBlockInfo(addr, size));
memset(mem + (addr - GetStartAddr()), 0, size);
m_point = addr + size;
return true;
if(addr >= m_used_mem[i].addr && addr < m_used_mem[i].addr + m_used_mem[i].size) return false;
}
for(u32 i=0; i<m_free_mem.GetCount(); ++i)
{
if(addr < m_free_mem[i].addr || addr >= m_free_mem[i].addr + m_free_mem[i].size
|| m_free_mem[i].size < size) continue;
AppendUsedMem(addr, size);
if(m_free_mem[i].addr != addr)
{
m_free_mem.AddCpy(MemBlockInfo(m_free_mem[i].addr, addr - m_free_mem[i].addr));
}
return true;
}
if(m_free_mem[i].size != size)
{
m_free_mem.AddCpy(MemBlockInfo(m_free_mem[i].addr + size, m_free_mem[i].size - size));
}
m_free_mem.RemoveAt(i);
m_used_mem.AddCpy(MemBlockInfo(addr, size));
memset(mem + (addr - GetStartAddr()), 0, size);
return true;
}
return false;
void DynamicMemoryBlock::AppendUsedMem(u64 addr, u32 size)
{
m_used_mem.Move(new MemBlockInfo(addr, size));
}
u64 DynamicMemoryBlock::Alloc(u32 size)
{
for(u32 i=0; i<m_free_mem.GetCount(); ++i)
for(u64 addr=GetStartAddr(); addr <= GetEndAddr() - size;)
{
if(m_free_mem[i].size < size) continue;
bool is_good_addr = true;
const u32 addr = m_free_mem[i].addr;
if(m_free_mem[i].size != size)
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
m_free_mem.AddCpy(MemBlockInfo(addr + size, m_free_mem[i].size - size));
if((addr >= m_used_mem[i].addr && addr < m_used_mem[i].addr + m_used_mem[i].size) ||
(m_used_mem[i].addr >= addr && m_used_mem[i].addr < addr + size))
{
is_good_addr = false;
addr = m_used_mem[i].addr + m_used_mem[i].size;
break;
}
}
m_free_mem.RemoveAt(i);
m_used_mem.AddCpy(MemBlockInfo(addr, size));
if(!is_good_addr) continue;
AppendUsedMem(addr, size);
memset(mem + (addr - GetStartAddr()), 0, size);
return addr;
}
UpdateSize(m_point, size);
MemBlockInfo res(m_point, size);
m_used_mem.AddCpy(res);
memset(mem + (m_point - GetStartAddr()), 0, size);
m_point += size;
return res.addr;
return 0;
}
bool DynamicMemoryBlock::Alloc()
@ -520,14 +436,12 @@ bool DynamicMemoryBlock::Alloc()
}
bool DynamicMemoryBlock::Free(u64 addr)
{
{
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
if(addr == m_used_mem[i].addr)
{
m_free_mem.AddCpy(MemBlockInfo(m_used_mem[i].addr, m_used_mem[i].size));
m_used_mem.RemoveAt(i);
CombineFreeMem();
return true;
}
}
@ -535,6 +449,23 @@ bool DynamicMemoryBlock::Free(u64 addr)
return false;
}
u8* DynamicMemoryBlock::GetMem(u64 addr) const
{
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
u64 _addr = FixAddr(m_used_mem[i].addr);
if(addr >= _addr && addr < _addr + m_used_mem[i].size)
{
return (u8*)m_used_mem[i].mem + addr - _addr;
}
}
ConLog.Error("GetMem(%llx) from not allocated address.", addr);
assert(0);
return nullptr;
}
//MemoryBase
void MemoryBase::Write8(u64 addr, const u8 data)
{

View File

@ -1,44 +1,6 @@
#pragma once
#include "MemoryBlock.h"
class MemoryFlags
{
struct Flag
{
const u64 addr;
const u64 waddr;
const u64 fid;
Flag(const u64 _addr, const u64 _waddr, const u64 _fid)
: addr(_addr)
, waddr(_waddr)
, fid(_fid)
{
}
};
Array<Flag> m_memflags;
public:
void Add(const u64 addr, const u64 waddr, const u64 fid) {m_memflags.Add(new Flag(addr, waddr, fid));}
void Clear() { m_memflags.Clear(); }
bool IsFlag(const u64 addr, u64& waddr, u64& fid)
{
for(u32 i=0; i<GetCount(); i++)
{
if(m_memflags[i].addr != addr) continue;
fid = m_memflags[i].fid;
waddr = m_memflags[i].waddr;
return true;
}
return false;
}
u64 GetCount() const { return m_memflags.GetCount(); }
};
class MemoryBase
{
NullMemoryBlock NullMem;
@ -55,8 +17,6 @@ public:
MemoryBlock SpuRawMem;
MemoryBlock SpuThrMem;
MemoryFlags MemFlags;
bool m_inited;
MemoryBase()
@ -69,22 +29,28 @@ public:
Close();
}
static u16 Reverse16(const u16 val)
static __forceinline u16 Reverse16(const u16 val)
{
return ((val >> 8) & 0xff) | ((val << 8) & 0xff00);
return _byteswap_ushort(val);
//return ((val >> 8) & 0xff) | ((val << 8) & 0xff00);
}
static u32 Reverse32(const u32 val)
static __forceinline u32 Reverse32(const u32 val)
{
return _byteswap_ulong(val);
/*
return
((val >> 24) & 0x000000ff) |
((val >> 8) & 0x0000ff00) |
((val << 8) & 0x00ff0000) |
((val << 24) & 0xff000000);
*/
}
static u64 Reverse64(const u64 val)
static __forceinline u64 Reverse64(const u64 val)
{
return _byteswap_uint64(val);
/*
return
((val >> 56) & 0x00000000000000ff) |
((val >> 40) & 0x000000000000ff00) |
@ -94,19 +60,19 @@ public:
((val << 24) & 0x0000ff0000000000) |
((val << 40) & 0x00ff000000000000) |
((val << 56) & 0xff00000000000000);
*/
}
template<typename T> static T Reverse(T val)
{
switch(sizeof(T))
{
case 2: return Reverse16(val);
case 4: return Reverse32(val);
case 8: return Reverse64(val);
}
template<typename T> static __forceinline T Reverse(T val);
template<> static __forceinline u8 Reverse(u8 val) { return val; };
template<> static __forceinline u16 Reverse(u16 val) { return Reverse16(val); };
template<> static __forceinline u32 Reverse(u32 val) { return Reverse32(val); };
template<> static __forceinline u64 Reverse(u64 val) { return Reverse64(val); };
return val;
}
template<> static __forceinline s8 Reverse(s8 val) { return val; };
template<> static __forceinline s16 Reverse(s16 val) { return Reverse16(val); };
template<> static __forceinline s32 Reverse(s32 val) { return Reverse32(val); };
template<> static __forceinline s64 Reverse(s64 val) { return Reverse64(val); };
MemoryBlock& GetMemByNum(const u8 num)
{
@ -170,7 +136,7 @@ public:
MemoryBlocks.Add(MainMem.SetRange(0x00010000, 0x2FFF0000));
MemoryBlocks.Add(PRXMem.SetRange(0x30000000, 0x10000000));
MemoryBlocks.Add(RSXCMDMem.SetRange(0x40000000, 0x10000000));
//MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000));
MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000));
MemoryBlocks.Add(RSXFBMem.SetRange(0xC0000000, 0x10000000));
MemoryBlocks.Add(StackMem.SetRange(0xD0000000, 0x10000000));
//MemoryBlocks.Add(SpuRawMem.SetRange(0xE0000000, 0x10000000));
@ -213,7 +179,6 @@ public:
}
MemoryBlocks.Clear();
MemFlags.Clear();
}
void Reset()
@ -243,6 +208,66 @@ public:
u64 Read64(const u64 addr);
u128 Read128(const u64 addr);
void ReadLeft(u8* dst, const u64 addr, const u32 size)
{
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
ConLog.Error("ReadLeft[%d] from null block (0x%llx)", size, addr);
return;
}
u32 offs = mem.FixAddr(addr);
for(u32 i=0; i<size; ++i) dst[size - 1 - i] = mem.FastRead8(offs + i);
}
void WriteLeft(const u64 addr, const u32 size, const u8* src)
{
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
ConLog.Error("WriteLeft[%d] to null block (0x%llx)", size, addr);
return;
}
u32 offs = mem.FixAddr(addr);
for(u32 i=0; i<size; ++i) mem.FastWrite8(offs + i, src[size - 1 - i]);
}
void ReadRight(u8* dst, const u64 addr, const u32 size)
{
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
ConLog.Error("ReadRight[%d] from null block (0x%llx)", size, addr);
return;
}
u32 offs = mem.FixAddr(addr);
for(u32 i=0; i<size; ++i) dst[i] = mem.FastRead8(offs + (size - 1 - i));
}
void WriteRight(const u64 addr, const u32 size, const u8* src)
{
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
ConLog.Error("WriteRight[%d] to null block (0x%llx)", size, addr);
return;
}
u32 offs = mem.FixAddr(addr);
for(u32 i=0; i<size; ++i) mem.FastWrite8(offs + (size - 1 - i), src[i]);
}
template<typename T> void WriteData(const u64 addr, const T* data)
{
memcpy(GetMemFromAddr(addr), data, sizeof(T));
@ -264,26 +289,18 @@ public:
wxString ReadString(const u64 addr)
{
wxString buf = wxEmptyString;
for(u32 i=addr; ; i++)
{
const u8 c = Read8(i);
if(c == 0) break;
buf += c;
}
return buf;
return wxString((const char*)GetMemFromAddr(addr));
}
void WriteString(const u64 addr, const wxString& str)
{
for(u32 i=0; i<str.Length(); i++)
if(!IsGoodAddr(addr, str.Len()))
{
Write8(addr + i, str[i]);
ConLog.Error("Memory::WriteString error: bad address (0x%llx)", addr);
return;
}
Write8(addr + str.Length(), 0);
strcpy((char*)GetMemFromAddr(addr), str);
}
static u64 AlignAddr(const u64 addr, const u64 align)
@ -311,7 +328,17 @@ public:
return PRXMem.Free(addr);
}
u8& operator[] (const u64 vaddr) { return *GetMemFromAddr(vaddr); }
u8* operator + (const u64 vaddr)
{
u8* ret = GetMemFromAddr(vaddr);
if(!ret) throw wxString::Format("GetMemFromAddr(0x%llx)", vaddr);
return ret;
}
u8& operator[] (const u64 vaddr)
{
return *(*this + vaddr);
}
};
extern MemoryBase Memory;

View File

@ -4,11 +4,26 @@ struct MemBlockInfo
{
u64 addr;
u32 size;
void* mem;
MemBlockInfo(u64 _addr, u32 _size)
: addr(_addr)
, size(_size)
, mem(malloc(_size))
{
if(!mem)
{
ConLog.Error("Not enought free memory.");
assert(0);
}
memset(mem, 0, size);
}
~MemBlockInfo()
{
free(mem);
mem = nullptr;
}
};
@ -40,7 +55,6 @@ public:
u8* GetMemFromAddr(const u64 addr);
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
bool SetNewSize(const u32 size);
virtual bool IsMyAddress(const u64 addr);
__forceinline const u8 FastRead8(const u64 addr) const;
@ -68,9 +82,10 @@ public:
virtual bool Write128(const u64 addr, const u128 value);
const u64 GetStartAddr() const { return range_start; }
const u64 GetEndAddr() const { return range_start + range_size - 1; }
const u64 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; }
virtual const u32 GetSize() const { return range_size; }
void* GetMem() const { return mem; }
u8* GetMem() const { return mem; }
virtual u8* GetMem(u64 addr) const { return mem + addr; }
};
class NullMemoryBlock : public MemoryBlock
@ -94,15 +109,13 @@ class NullMemoryBlock : public MemoryBlock
class DynamicMemoryBlock : public MemoryBlock
{
Array<MemBlockInfo> m_used_mem;
Array<MemBlockInfo> m_free_mem;
u64 m_point;
u32 m_max_size;
public:
DynamicMemoryBlock();
const u32 GetSize() const { return m_max_size; }
const u32 GetUsedSize() const { return range_size; }
const u32 GetUsedSize() const;
bool IsInMyRange(const u64 addr);
bool IsInMyRange(const u64 addr, const u32 size);
@ -112,11 +125,13 @@ public:
virtual void Delete();
void UpdateSize(u64 addr, u32 size);
void CombineFreeMem();
bool Alloc(u64 addr, u32 size);
u64 Alloc(u32 size);
bool Alloc();
bool Free(u64 addr);
virtual u8* GetMem(u64 addr) const;
private:
void AppendUsedMem(u64 addr, u32 size);
};

View File

@ -0,0 +1,66 @@
#include "stdafx.h"
#include "Callback.h"
#include "Emu/Cell/PPCThread.h"
Callback::Callback(u32 slot, u64 addr)
: m_addr(addr)
, m_slot(slot)
, a1(0)
, a2(0)
, a3(0)
, m_has_data(false)
{
}
void Callback::Handle(u64 _a1, u64 _a2, u64 _a3)
{
a1 = _a1;
a2 = _a2;
a3 = _a3;
m_has_data = true;
}
void Callback::Branch()
{
m_has_data = false;
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
new_thread.SetPc(m_addr);
new_thread.SetPrio(0x1001);
new_thread.stack_size = 0x10000;
new_thread.SetName("Callback");
new_thread.Run();
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
((PPUThread&)new_thread).GPR[3] = a1;
((PPUThread&)new_thread).GPR[4] = a2;
((PPUThread&)new_thread).GPR[5] = a3;
new_thread.Exec();
while(new_thread.IsAlive()) Sleep(1);
Emu.GetCPU().RemoveThread(new_thread.GetId());
ConLog.Write("Callback EXIT!");
}
Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)
{
a2 = userdata;
}
void Callback2::Handle(u64 status)
{
Callback::Handle(status, a2, 0);
}
Callback3::Callback3(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)
{
a3 = userdata;
}
void Callback3::Handle(u64 status, u64 param)
{
Callback::Handle(status, param, a3);
}

View File

@ -0,0 +1,146 @@
#pragma once
struct Callback
{
u64 m_addr;
u32 m_slot;
u64 a1;
u64 a2;
u64 a3;
bool m_has_data;
Callback(u32 slot, u64 addr);
void Handle(u64 a1, u64 a2, u64 a3);
void Branch();
};
struct Callback2 : public Callback
{
Callback2(u32 slot, u64 addr, u64 userdata);
void Handle(u64 status);
};
struct Callback3 : public Callback
{
Callback3(u32 slot, u64 addr, u64 userdata);
void Handle(u64 status, u64 param);
};
struct Callbacks
{
Array<Callback> m_callbacks;
bool m_in_manager;
Callbacks() : m_in_manager(false)
{
}
virtual void Register(u32 slot, u64 addr, u64 userdata)
{
Unregister(slot);
}
void Unregister(u32 slot)
{
for(u32 i=0; i<m_callbacks.GetCount(); ++i)
{
if(m_callbacks[i].m_slot == slot)
{
m_callbacks.RemoveAt(i);
break;
}
}
}
virtual void Handle(u64 status, u64 param = 0)=0;
bool Check()
{
bool handled = false;
for(u32 i=0; i<m_callbacks.GetCount(); ++i)
{
if(m_callbacks[i].m_has_data)
{
handled = true;
m_callbacks[i].Branch();
}
}
return handled;
}
};
struct Callbacks2 : public Callbacks
{
Callbacks2() : Callbacks()
{
}
void Register(u32 slot, u64 addr, u64 userdata)
{
Callbacks::Register(slot, addr, userdata);
m_callbacks.Move(new Callback2(slot, addr, userdata));
}
void Handle(u64 a1, u64 a2)
{
for(u32 i=0; i<m_callbacks.GetCount(); ++i)
{
((Callback2&)m_callbacks[i]).Handle(a1);
}
}
};
struct Callbacks3 : public Callbacks
{
Callbacks3() : Callbacks()
{
}
void Register(u32 slot, u64 addr, u64 userdata)
{
Callbacks::Register(slot, addr, userdata);
m_callbacks.Move(new Callback3(slot, addr, userdata));
}
void Handle(u64 a1, u64 a2)
{
for(u32 i=0; i<m_callbacks.GetCount(); ++i)
{
((Callback3&)m_callbacks[i]).Handle(a1, a2);
}
}
};
struct CallbackManager
{
ArrayF<Callbacks> m_callbacks;
Callbacks3 m_exit_callback;
void Add(Callbacks& c)
{
if(c.m_in_manager) return;
c.m_in_manager = true;
m_callbacks.Add(c);
}
void Init()
{
Add(m_exit_callback);
}
void Clear()
{
for(u32 i=0; i<m_callbacks.GetCount(); ++i)
{
m_callbacks[i].m_callbacks.Clear();
m_callbacks[i].m_in_manager = false;
}
m_callbacks.ClearF();
}
};

View File

@ -1,8 +1,8 @@
#include "stdafx.h"
#include "SysCalls.h"
#define FUNC_LOG_ERROR(x) ConLog.Warning(x); return 0
s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
#define FUNC_LOG_ERROR(x) ConLog.Error(x); return SC_ARGS_1
s64 SysCalls::DoFunc(const u32 id)
{
switch(id)
{
@ -309,7 +309,7 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x3a33c1fd: FUNC_LOG_ERROR("TODO: _cellGcmFunc15");
case 0x3b9bd5bd: FUNC_LOG_ERROR("TODO: cellGcmUnreserveIoMapSize");
case 0x4524cccd: FUNC_LOG_ERROR("TODO: cellGcmBindTile");
case 0x4ae8d215: FUNC_LOG_ERROR("TODO: cellGcmSetFlipMode");
case 0x4ae8d215: return cellGcmSetFlipMode(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellGcmSetFlipMode");
case 0x4d7ce993: FUNC_LOG_ERROR("TODO: cellGcmSetSecondVFrequency");
case 0x51c9d62b: FUNC_LOG_ERROR("TODO: cellGcmSetDebugOutputLevel");
case 0x527c6439: FUNC_LOG_ERROR("TODO: cellGcmTerminate");
@ -336,7 +336,7 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x9a0159af: FUNC_LOG_ERROR("TODO: cellGcmGetReportDataAddress");
case 0x9ba451e4: FUNC_LOG_ERROR("TODO: cellGcmSetDefaultFifoSize");
case 0x9dc04436: FUNC_LOG_ERROR("TODO: cellGcmBindZcull");
case 0xa114ec67: FUNC_LOG_ERROR("TODO: cellGcmMapMainMemory");
case 0xa114ec67: return cellGcmMapMainMemory(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: cellGcmMapMainMemory");
case 0xa41ef7e8: FUNC_LOG_ERROR("TODO: cellGcmSetFlipHandler");
case 0xa47c09ff: FUNC_LOG_ERROR("TODO: cellGcmSetFlipStatus");
case 0xa53d12ae: return cellGcmSetDisplayBuffer(SC_ARGS_5); //FUNC_LOG_ERROR("TODO: cellGcmSetDisplayBuffer");
@ -356,8 +356,8 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0xc8f3bd09: FUNC_LOG_ERROR("TODO: cellGcmGetCurrentField");
case 0xcaabd992: FUNC_LOG_ERROR("TODO: cellGcmInitDefaultFifoMode");
case 0xd01b570d: FUNC_LOG_ERROR("TODO: cellGcmSetGraphicsHandler");
case 0xd0b1d189: return cellGcmSetTile(SC_ARGS_8);//FUNC_LOG_ERROR("TODO: cellGcmSetTile");
case 0xd34a420d: FUNC_LOG_ERROR("TODO: cellGcmSetZcull");
case 0xd0b1d189: cellGcmSetTile(SC_ARGS_8); return SC_ARGS_1;//FUNC_LOG_ERROR("TODO: cellGcmSetTile");
case 0xd34a420d: ConLog.Error("TODO: cellGcmSetZcull"); return SC_ARGS_1;
case 0xd8f88e1a: FUNC_LOG_ERROR("TODO: _cellGcmSetFlipCommandWithWaitLabel");
case 0xd9a0a879: FUNC_LOG_ERROR("TODO: cellGcmGetZcullInfo");
case 0xd9b7653e: FUNC_LOG_ERROR("TODO: cellGcmUnbindTile");
@ -1410,19 +1410,19 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0xa193143c: FUNC_LOG_ERROR("TODO: cellSysmoduleSetMemcontainer");
case 0x018a1381: FUNC_LOG_ERROR("TODO: cellSysutilAvcSetLayoutMode");
case 0x01f04d94: FUNC_LOG_ERROR("TODO: cellSysutilGamePowerOff_I");
case 0x02ff3c1b: FUNC_LOG_ERROR("TODO: cellSysutilUnregisterCallback");
case 0x02ff3c1b: return cellSysutilUnregisterCallback(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellSysutilUnregisterCallback");
case 0x073b89d5: FUNC_LOG_ERROR("TODO: cellSysutilAvcGetSpeakerVolumeLevel");
case 0x08269f37: FUNC_LOG_ERROR("TODO: cellSysutilAvcGetShowStatus");
case 0x0bae8772: FUNC_LOG_ERROR("TODO: cellVideoOutConfigure");
case 0x0bae8772: return cellVideoOutConfigure(SC_ARGS_4); //FUNC_LOG_ERROR("TODO: cellVideoOutConfigure");
case 0x0c316b87: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigGetHeapSize2");
case 0x0e091c36: FUNC_LOG_ERROR("TODO: cellSaveDataUserListAutoSave");
case 0x0f03cfb0: FUNC_LOG_ERROR("TODO: cellSaveDataUserListSave");
case 0x0f8a3b6b: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetMimeSet");
case 0x10cabeff: FUNC_LOG_ERROR("TODO: cellWebBrowserGetUsrdataOnGameExit");
case 0x15b0b0cd: FUNC_LOG_ERROR("TODO: cellVideoOutGetConfiguration");
case 0x15b0b0cd: return cellVideoOutGetConfiguration(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: cellVideoOutGetConfiguration");
case 0x15df71ed: FUNC_LOG_ERROR("TODO: cellSysutilAvcLoadAsync");
case 0x17dbe8b3: FUNC_LOG_ERROR("TODO: cellSysutilAvcJoinRequest");
case 0x189a74da: return 0; //FUNC_LOG_ERROR("TODO: cellSysutilCheckCallback");
case 0x189a74da: return cellSysutilCheckCallback(); //FUNC_LOG_ERROR("TODO: cellSysutilCheckCallback");
case 0x1a91874b: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetFullScreen2");
case 0x1d99c3ee: FUNC_LOG_ERROR("TODO: cellOskDialogGetInputText");
case 0x1dfbfdd6: FUNC_LOG_ERROR("TODO: cellSaveDataListLoad2");
@ -1484,8 +1484,8 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x71acb8d3: FUNC_LOG_ERROR("TODO: cellSysutilAvcSetVideoMuting");
case 0x744c1544: FUNC_LOG_ERROR("TODO: cellSysCacheClear");
case 0x749c9b5f: FUNC_LOG_ERROR("TODO: cellWebBrowserInitialize");
case 0x75bbb672: FUNC_LOG_ERROR("TODO: cellVideoOutGetNumberOfDevice");
case 0x7603d3db: FUNC_LOG_ERROR("TODO: cellMsgDialogOpen2");
case 0x75bbb672: return cellVideoOutGetNumberOfDevice(SC_ARGS_1); //FUNC_LOG_ERROR("TODO: cellVideoOutGetNumberOfDevice");
case 0x7603d3db: return cellMsgDialogOpen2(SC_ARGS_5); //FUNC_LOG_ERROR("TODO: cellMsgDialogOpen2");
case 0x7663e368: FUNC_LOG_ERROR("TODO: cellAudioOutGetDeviceInfo");
case 0x76948bfc: FUNC_LOG_ERROR("TODO: cellSysconfAbort");
case 0x76fc8fb1: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetHeapSize");
@ -1515,11 +1515,11 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x9c9fe6a4: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigSetFunction");
case 0x9ca9ffa7: FUNC_LOG_ERROR("TODO: cellHddGameSetSystemVer");
case 0x9d6af72a: FUNC_LOG_ERROR("TODO: cellMsgDialogProgressBarSetMsg");
case 0x9d98afa0: FUNC_LOG_ERROR("TODO: cellSysutilRegisterCallback");
case 0x9d98afa0: return cellSysutilRegisterCallback(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: cellSysutilRegisterCallback");
case 0x9dfdad46: FUNC_LOG_ERROR("TODO: cellAudioOutUnregisterCallback");
case 0x9fb97b10: FUNC_LOG_ERROR("TODO: cellWebBrowserNavigate2");
case 0xa11552f6: FUNC_LOG_ERROR("TODO: cellSysutilGetBgmPlaybackStatus");
case 0xa322db75: FUNC_LOG_ERROR("TODO: cellVideoOutGetResolutionAvailability");
case 0xa322db75: return cellVideoOutGetResolutionAvailability(SC_ARGS_4); //FUNC_LOG_ERROR("TODO: cellVideoOutGetResolutionAvailability");
case 0xa36335a5: FUNC_LOG_ERROR("TODO: cellSysutilDisableBgmPlaybackEx");
case 0xa4dd11cc: FUNC_LOG_ERROR("TODO: cellWebBrowserConfigGetHeapSize");
case 0xa4ed7dfe: FUNC_LOG_ERROR("TODO: cellSaveDataDelete");
@ -3563,14 +3563,14 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x05c65656: FUNC_LOG_ERROR("TODO: sys_mempool_try_allocate_block");
case 0x0618936b: FUNC_LOG_ERROR("TODO: _sys_vsnprintf");
case 0x06574237: FUNC_LOG_ERROR("TODO: _sys_snprintf");
case 0x1573dc3f: return Lv2LwmutexLock(CPU);//FUNC_LOG_ERROR("TODO: sys_lwmutex_lock");
case 0x1573dc3f: return sys_lwmutex_lock(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: sys_lwmutex_lock");
case 0x191f0c4a: FUNC_LOG_ERROR("TODO: _sys_strrchr");
case 0x1ae10b92: FUNC_LOG_ERROR("TODO: _sys_spu_printf_attach_thread");
case 0x1bc200f4: return Lv2LwmutexUnlock(CPU);//FUNC_LOG_ERROR("TODO: sys_lwmutex_unlock");
case 0x1bc200f4: return sys_lwmutex_unlock(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: sys_lwmutex_unlock");
case 0x1c9a942c: FUNC_LOG_ERROR("TODO: sys_lwcond_destroy");
case 0x1ca525a2: FUNC_LOG_ERROR("TODO: _sys_strncasecmp");
case 0x1ed454ce: FUNC_LOG_ERROR("TODO: sys_spu_elf_get_information");
case 0x24a1ea07: return lv2PPUThreadCreate(CPU);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_create");
case 0x24a1ea07: return sys_ppu_thread_create(SC_ARGS_7);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_create");
case 0x25596f51: FUNC_LOG_ERROR("TODO: sys_mempool_get_count");
case 0x26090058: FUNC_LOG_ERROR("TODO: sys_prx_load_module");
case 0x27427742: FUNC_LOG_ERROR("TODO: _sys_memmove");
@ -3578,12 +3578,12 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x2c847572: FUNC_LOG_ERROR("TODO: _sys_process_atexitspawn");
case 0x2d36462b:
//FUNC_LOG_ERROR("TODO: _sys_strlen");
ConLog.Write("sys_strlen(addr=0x%x)", SC_ARGS_1);
return Memory.ReadString(SC_ARGS_1).Len();
case 0x2f85c0ef: return Lv2LwmutexCreate(CPU);//FUNC_LOG_ERROR("TODO: sys_lwmutex_create");
ConLog.Write("sys_strlen(addr=0x%x(%s))", SC_ARGS_1, Memory.ReadString(SC_ARGS_1));
return strlen((const char*)&Memory[SC_ARGS_1]);
case 0x2f85c0ef: return sys_lwmutex_create(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: sys_lwmutex_create");
case 0x3172759d: FUNC_LOG_ERROR("TODO: sys_game_get_temperature");
case 0x318f17e1: FUNC_LOG_ERROR("TODO: _sys_memalign");
case 0x350d454e: return lv2PPUThreadGetId(CPU);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_get_id");
case 0x350d454e: return sys_ppu_thread_get_id();//FUNC_LOG_ERROR("TODO: sys_ppu_thread_get_id");
case 0x35168520: return sys_heap_malloc(SC_ARGS_2); //FUNC_LOG_ERROR("TODO: _sys_heap_malloc");
case 0x3bd53c7b: FUNC_LOG_ERROR("TODO: _sys_memchr");
case 0x3dd4a957: FUNC_LOG_ERROR("TODO: sys_ppu_thread_register_atexit");
@ -3617,13 +3617,13 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0x744680a2:
// FUNC_LOG_ERROR("TODO: sys_initialize_tls");
ConLog.Warning("sys_initialize_tls()");
CPU.GPR[4] = Emu.GetTLSFilesz();
CPU.GPR[5] = Emu.GetTLSMemsz();
return Emu.GetTLSAddr();
//CPU.GPR[4] = Emu.GetTLSFilesz();
//CPU.GPR[5] = Emu.GetTLSMemsz();
return 0;//Memory.MainMem.Alloc(Emu.GetTLSMemsz());//Emu.GetTLSAddr();
case 0x7498887b: FUNC_LOG_ERROR("TODO: _sys_strchr");
case 0x791b9219: FUNC_LOG_ERROR("TODO: _sys_vsprintf");
case 0x80fb0c19: FUNC_LOG_ERROR("TODO: sys_prx_stop_module");
case 0x8461e528: return DoSyscall(146, CPU);//FUNC_LOG_ERROR("TODO: sys_time_get_system_time");
case 0x8461e528: return sys_time_get_system_time();//FUNC_LOG_ERROR("TODO: sys_time_get_system_time");
case 0x84bb6774: FUNC_LOG_ERROR("TODO: sys_prx_get_module_info");
case 0x893305fa: FUNC_LOG_ERROR("TODO: sys_raw_spu_load");
case 0x8985b5b6: FUNC_LOG_ERROR("TODO: _sys_heap_stats");
@ -3652,10 +3652,10 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0xaa6d9bff: FUNC_LOG_ERROR("TODO: sys_prx_load_module_on_memcontainer");
case 0xac6fc404: FUNC_LOG_ERROR("TODO: sys_ppu_thread_unregister_atexit");
case 0xacad8fb6: FUNC_LOG_ERROR("TODO: sys_game_watchdog_clear");
case 0xaeb78725: return Lv2LwmutexTrylock(CPU);//FUNC_LOG_ERROR("TODO: sys_lwmutex_trylock");
case 0xaeb78725: return sys_lwmutex_trylock(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: sys_lwmutex_trylock");
case 0xaede4b03: FUNC_LOG_ERROR("TODO: _sys_heap_delete_heap");
case 0xaff080a4: return lv2PPUThreadExit(CPU);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_exit");
case 0xb257540b: FUNC_LOG_ERROR("TODO: sys_mmapper_allocate_memory");
case 0xaff080a4: return sys_ppu_thread_exit(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_exit");
case 0xb257540b: return sys_mmapper_allocate_memory(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: sys_mmapper_allocate_memory");
case 0xb27c8ae7: FUNC_LOG_ERROR("TODO: sys_prx_load_module_list");
case 0xb2fcf2c8: return sys_heap_create_heap(SC_ARGS_3);//FUNC_LOG_ERROR("TODO: _sys_heap_create_heap");
case 0xb3bbcf2a: FUNC_LOG_ERROR("TODO: _sys_spu_printf_detach_thread");
@ -3666,7 +3666,7 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
ConLog.Warning("_sys_malloc(0x%llx)", SC_ARGS_1);
return Memory.Alloc(CPU.GPR[3], Emu.GetMallocPageSize());
FUNC_LOG_ERROR("TODO: _sys_malloc");
case 0xc3476d0c: return Lv2LwmutexDestroy(CPU);////FUNC_LOG_ERROR("TODO: sys_lwmutex_destroy");
case 0xc3476d0c: return sys_lwmutex_destroy(SC_ARGS_1);////FUNC_LOG_ERROR("TODO: sys_lwmutex_destroy");
case 0xc4fd6121: FUNC_LOG_ERROR("TODO: _sys_qsort");
case 0xca9a60bf: FUNC_LOG_ERROR("TODO: sys_mempool_create");
case 0xd0ea47a7: FUNC_LOG_ERROR("TODO: sys_prx_unregister_library");
@ -3674,13 +3674,13 @@ s64 SysCalls::DoFunc(const u32 id, PPUThread& CPU)
case 0xd3039d4d: FUNC_LOG_ERROR("TODO: _sys_strncpy");
case 0xda0eb71a: FUNC_LOG_ERROR("TODO: sys_lwcond_create");
case 0xdb6b3250: FUNC_LOG_ERROR("TODO: sys_spu_elf_get_segments");
case 0xdc578057: FUNC_LOG_ERROR("TODO: sys_mmapper_map_memory");
case 0xdc578057: return sys_mmapper_map_memory(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: sys_mmapper_map_memory");
case 0xdd0c1e09: FUNC_LOG_ERROR("TODO: _sys_spu_printf_attach_group");
case 0xdd3b27ac: FUNC_LOG_ERROR("TODO: _sys_spu_printf_finalize");
case 0xe0998dbf: FUNC_LOG_ERROR("TODO: sys_prx_get_module_id_by_name");
case 0xe0da8efd: FUNC_LOG_ERROR("TODO: sys_spu_image_close");
case 0xe66bac36: FUNC_LOG_ERROR("TODO: console_putc");
case 0xe6f2c1e7: return lv2ProcessExit(CPU);///FUNC_LOG_ERROR("TODO: sys_process_exit");
case 0xe6f2c1e7: return sys_process_exit(SC_ARGS_1);///FUNC_LOG_ERROR("TODO: sys_process_exit");
case 0xe76964f5: FUNC_LOG_ERROR("TODO: sys_game_board_storage_read");
case 0xe7ef3a80: FUNC_LOG_ERROR("TODO: sys_prx_load_module_list_on_memcontainer");
case 0xe9a1bd84: FUNC_LOG_ERROR("TODO: sys_lwcond_signal_all");

View File

@ -0,0 +1,40 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
Module cellGcmSys("cellGcmSys", 0x0010);
s64 cellGcmFunc15()
{
cellGcmSys.Error("cellGcmFunc15()");
return 0;
}
s64 cellGcmSetFlipCommandWithWaitLabel()
{
cellGcmSys.Error("cellGcmSetFlipCommandWithWaitLabel()");
return 0;
}
struct _cellGcmSys_init
{
_cellGcmSys_init()
{
cellGcmSys.AddFunc(0x055bd74d, bind_func(cellGcmGetTiledPitchSize));
cellGcmSys.AddFunc(0x15bae46b, bind_func(cellGcmInit));
cellGcmSys.AddFunc(0x21397818, bind_func(cellGcmFlush));
cellGcmSys.AddFunc(0x21ac3697, bind_func(cellGcmAddressToOffset));
cellGcmSys.AddFunc(0x3a33c1fd, bind_func(cellGcmFunc15));
cellGcmSys.AddFunc(0x4ae8d215, bind_func(cellGcmSetFlipMode));
cellGcmSys.AddFunc(0x5e2ee0f0, bind_func(cellGcmGetDefaultCommandWordSize));
cellGcmSys.AddFunc(0x72a577ce, bind_func(cellGcmGetFlipStatus));
cellGcmSys.AddFunc(0x8cdf8c70, bind_func(cellGcmGetDefaultSegmentWordSize));
cellGcmSys.AddFunc(0x9ba451e4, bind_func(cellGcmSetDefaultFifoSize));
cellGcmSys.AddFunc(0xa53d12ae, bind_func(cellGcmSetDisplayBuffer));
cellGcmSys.AddFunc(0xa547adde, bind_func(cellGcmGetControlRegister));
cellGcmSys.AddFunc(0xb2e761d4, bind_func(cellGcmResetFlipStatus));
cellGcmSys.AddFunc(0xd8f88e1a, bind_func(cellGcmSetFlipCommandWithWaitLabel));
cellGcmSys.AddFunc(0xe315a0b2, bind_func(cellGcmGetConfiguration));
cellGcmSys.AddFunc(0x9dc04436, bind_func(cellGcmBindZcull));
}
} _cellGcmSys_init;

View File

@ -0,0 +1,75 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
Module sysPrxForUser("sysPrxForUser", -1);
void sys_initialize_tls()
{
sysPrxForUser.Log("sys_initialize_tls()");
}
s64 sys_process_atexitspawn()
{
sysPrxForUser.Log("sys_process_atexitspawn()");
return 0;
}
s64 sys_process_at_Exitspawn()
{
sysPrxForUser.Log("sys_process_at_Exitspawn");
return 0;
}
s64 sys_prx_register_library()
{
sysPrxForUser.Error("sys_prx_register_library()");
return 0;
}
s64 sys_prx_exitspawn_with_level()
{
sysPrxForUser.Log("sys_prx_exitspawn_with_level()");
return 0;
}
s64 sys_strlen(u32 addr)
{
const wxString& str = Memory.ReadString(addr);
sysPrxForUser.Log("sys_strlen(0x%x - \"%s\")", addr, str);
return str.Len();
}
struct _sysPrxForUser_init
{
_sysPrxForUser_init()
{
sysPrxForUser.AddFunc(0x744680a2, bind_func(sys_initialize_tls));
sysPrxForUser.AddFunc(0x2f85c0ef, bind_func(sys_lwmutex_create));
sysPrxForUser.AddFunc(0xc3476d0c, bind_func(sys_lwmutex_destroy));
sysPrxForUser.AddFunc(0x1573dc3f, bind_func(sys_lwmutex_lock));
sysPrxForUser.AddFunc(0xaeb78725, bind_func(sys_lwmutex_trylock));
sysPrxForUser.AddFunc(0x1bc200f4, bind_func(sys_lwmutex_unlock));
sysPrxForUser.AddFunc(0x8461e528, bind_func(sys_time_get_system_time));
sysPrxForUser.AddFunc(0xe6f2c1e7, bind_func(sys_process_exit));
sysPrxForUser.AddFunc(0x2c847572, bind_func(sys_process_atexitspawn));
sysPrxForUser.AddFunc(0x96328741, bind_func(sys_process_at_Exitspawn));
sysPrxForUser.AddFunc(0x24a1ea07, bind_func(sys_ppu_thread_create));
sysPrxForUser.AddFunc(0x350d454e, bind_func(sys_ppu_thread_get_id));
sysPrxForUser.AddFunc(0xaff080a4, bind_func(sys_ppu_thread_exit));
sysPrxForUser.AddFunc(0x42b23552, bind_func(sys_prx_register_library));
sysPrxForUser.AddFunc(0xa2c7ba64, bind_func(sys_prx_exitspawn_with_level));
sysPrxForUser.AddFunc(0x2d36462b, bind_func(sys_strlen));
sysPrxForUser.AddFunc(0x35168520, bind_func(sys_heap_malloc));
//sysPrxForUser.AddFunc(0xaede4b03, bind_func(sys_heap_free>);
//sysPrxForUser.AddFunc(0x8a561d92, bind_func(sys_heap_delete_heap>);
sysPrxForUser.AddFunc(0xb2fcf2c8, bind_func(sys_heap_create_heap));
}
} sysPrxForUser_init;

View File

@ -0,0 +1,26 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
Module sys_fs("sys_fs", 0x000e);
struct _sys_fs_init
{
_sys_fs_init()
{
sys_fs.AddFunc(0x718bf5f8, bind_func(cellFsOpen));
sys_fs.AddFunc(0x4d5ff8e2, bind_func(cellFsRead));
sys_fs.AddFunc(0xecdcf2ab, bind_func(cellFsWrite));
sys_fs.AddFunc(0x2cb51f0d, bind_func(cellFsClose));
sys_fs.AddFunc(0x3f61245c, bind_func(cellFsOpendir));
sys_fs.AddFunc(0x5c74903d, bind_func(cellFsReaddir));
sys_fs.AddFunc(0xff42dcc3, bind_func(cellFsClosedir));
sys_fs.AddFunc(0x7de6dced, bind_func(cellFsStat));
sys_fs.AddFunc(0xef3efa34, bind_func(cellFsFstat));
sys_fs.AddFunc(0xba901fe6, bind_func(cellFsMkdir));
sys_fs.AddFunc(0xf12eecc8, bind_func(cellFsRename));
sys_fs.AddFunc(0x2796fdf3, bind_func(cellFsRmdir));
sys_fs.AddFunc(0x7f4677a8, bind_func(cellFsUnlink));
sys_fs.AddFunc(0xa397d042, bind_func(cellFsLseek));
}
} sys_fs_init;

View File

@ -0,0 +1,20 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/SC_FUNC.h"
Module sys_io("sys_io", 0x0017);
struct _sys_io_init
{
_sys_io_init()
{
sys_io.AddFunc(0x1cf98800, bind_func(cellPadInit));
sys_io.AddFunc(0x4d9b75d5, bind_func(cellPadEnd));
sys_io.AddFunc(0x0d5f2c14, bind_func(cellPadClearBuf));
sys_io.AddFunc(0x8b72cda1, bind_func(cellPadGetData));
sys_io.AddFunc(0x6bc09c61, bind_func(cellPadGetDataExtra));
sys_io.AddFunc(0xf65544ee, bind_func(cellPadSetActDirect));
sys_io.AddFunc(0xa703a51d, bind_func(cellPadGetInfo2));
sys_io.AddFunc(0x578e3c98, bind_func(cellPadSetPortSetting));
}
} sys_io_init;

View File

@ -0,0 +1,367 @@
#pragma once
#define RESULT(x) SC_ARGS_1 = (x)
template<typename TR>
class binder_func_0 : public func_caller
{
typedef TR (*func_t)();
const func_t m_call;
public:
binder_func_0(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call()); }
};
template<>
class binder_func_0<void> : public func_caller
{
typedef void (*func_t)();
const func_t m_call;
public:
binder_func_0(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(); }
};
template<typename TR, typename T1>
class binder_func_1 : public func_caller
{
typedef TR (*func_t)(T1);
const func_t m_call;
public:
binder_func_1(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_1)); }
};
template<typename T1>
class binder_func_1<void, T1> : public func_caller
{
typedef void (*func_t)(T1);
const func_t m_call;
public:
binder_func_1(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_1); }
};
template<typename TR, typename T1, typename T2>
class binder_func_2 : public func_caller
{
typedef TR (*func_t)(T1, T2);
const func_t m_call;
public:
binder_func_2(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_2)); }
};
template<typename T1, typename T2>
class binder_func_2<void, T1, T2> : public func_caller
{
typedef void (*func_t)(T1, T2);
const func_t m_call;
public:
binder_func_2(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_2); }
};
template<typename TR, typename T1, typename T2, typename T3>
class binder_func_3 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3);
const func_t m_call;
public:
binder_func_3(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_3)); }
};
template<typename T1, typename T2, typename T3>
class binder_func_3<void, T1, T2, T3> : public func_caller
{
typedef void (*func_t)(T1, T2, T3);
const func_t m_call;
public:
binder_func_3(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_3); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4>
class binder_func_4 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4);
const func_t m_call;
public:
binder_func_4(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_4)); }
};
template<typename T1, typename T2, typename T3, typename T4>
class binder_func_4<void, T1, T2, T3, T4> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4);
const func_t m_call;
public:
binder_func_4(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_4); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5>
class binder_func_5 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5);
const func_t m_call;
public:
binder_func_5(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_5)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5>
class binder_func_5<void, T1, T2, T3, T4, T5> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5);
const func_t m_call;
public:
binder_func_5(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_5); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
class binder_func_6 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6);
const func_t m_call;
public:
binder_func_6(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_6)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
class binder_func_6<void, T1, T2, T3, T4, T5, T6> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6);
const func_t m_call;
public:
binder_func_6(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_6); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
class binder_func_7 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7);
const func_t m_call;
public:
binder_func_7(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_7)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
class binder_func_7<void, T1, T2, T3, T4, T5, T6, T7> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7);
const func_t m_call;
public:
binder_func_7(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_7); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
class binder_func_8 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8);
const func_t m_call;
public:
binder_func_8(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_8)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
class binder_func_8<void, T1, T2, T3, T4, T5, T6, T7, T8> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8);
const func_t m_call;
public:
binder_func_8(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_8); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
class binder_func_9 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
const func_t m_call;
public:
binder_func_9(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_9)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
class binder_func_9<void, T1, T2, T3, T4, T5, T6, T7, T8, T9> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
const func_t m_call;
public:
binder_func_9(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_9); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
class binder_func_10 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
const func_t m_call;
public:
binder_func_10(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_10)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
class binder_func_10<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
const func_t m_call;
public:
binder_func_10(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_10); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
class binder_func_11 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
const func_t m_call;
public:
binder_func_11(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_11)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
class binder_func_11<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
const func_t m_call;
public:
binder_func_11(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_11); }
};
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
class binder_func_12 : public func_caller
{
typedef TR (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
const func_t m_call;
public:
binder_func_12(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_12)); }
};
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
class binder_func_12<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> : public func_caller
{
typedef void (*func_t)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
const func_t m_call;
public:
binder_func_12(func_t call) : func_caller(), m_call(call) {}
virtual void operator()() { declCPU(); m_call(SC_ARGS_12); }
};
template<typename TR>
func_caller* bind_func(TR (*call)())
{
return new binder_func_0<TR>(call);
}
template<typename TR, typename T1>
func_caller* bind_func(TR (*call)(T1))
{
return new binder_func_1<TR, T1>(call);
}
template<typename TR, typename T1, typename T2>
func_caller* bind_func(TR (*call)(T1, T2))
{
return new binder_func_2<TR, T1, T2>(call);
}
template<typename TR, typename T1, typename T2, typename T3>
func_caller* bind_func(TR (*call)(T1, T2, T3))
{
return new binder_func_3<TR, T1, T2, T3>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4))
{
return new binder_func_4<TR, T1, T2, T3, T4>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5))
{
return new binder_func_5<TR, T1, T2, T3, T4, T5>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6))
{
return new binder_func_6<TR, T1, T2, T3, T4, T5, T6>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7))
{
return new binder_func_7<TR, T1, T2, T3, T4, T5, T6, T7>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8))
{
return new binder_func_8<TR, T1, T2, T3, T4, T5, T6, T7, T8>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9))
{
return new binder_func_9<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10))
{
return new binder_func_10<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11))
{
return new binder_func_11<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(call);
}
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12))
{
return new binder_func_12<TR, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(call);
}

View File

@ -0,0 +1,404 @@
#include "stdafx.h"
#include "SysCalls.h"
#include "SC_FUNC.h"
#include <vector>
ArrayF<ModuleFunc> g_modules_funcs_list;
ArrayF<Module> g_modules_list;
bool IsLoadedFunc(u32 id)
{
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
{
if(g_modules_funcs_list[i].id == id)
{
return true;
}
}
return false;
}
bool CallFunc(u32 id)
{
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
{
if(g_modules_funcs_list[i].id == id)
{
(*g_modules_funcs_list[i].func)();
return true;
}
}
return false;
}
bool UnloadFunc(u32 id)
{
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
{
if(g_modules_funcs_list[i].id == id)
{
g_modules_funcs_list.RemoveAt(i);
return true;
}
}
return false;
}
void UnloadModules()
{
for(u32 i=0; i<g_modules_list.GetCount(); ++i)
{
g_modules_list[i].SetLoaded(false);
}
g_modules_funcs_list.Clear();
}
Module* GetModuleByName(const wxString& name)
{
for(u32 i=0; i<g_modules_list.GetCount(); ++i)
{
if(g_modules_list[i].GetName().Cmp(name) == 0)
{
return &g_modules_list[i];
}
}
return nullptr;
}
Module* GetModuleById(u16 id)
{
for(u32 i=0; i<g_modules_list.GetCount(); ++i)
{
if(g_modules_list[i].GetID() == id)
{
return &g_modules_list[i];
}
}
return nullptr;
}
Module::Module(const char* name, u16 id)
: m_is_loaded(false)
, m_name(name)
, m_id(id)
{
g_modules_list.Add(this);
}
void Module::Load()
{
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
{
if(IsLoadedFunc(m_funcs_list[i].id)) continue;
g_modules_funcs_list.Add(m_funcs_list[i]);
}
}
void Module::UnLoad()
{
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
{
UnloadFunc(m_funcs_list[i].id);
}
}
bool Module::Load(u32 id)
{
if(IsLoadedFunc(id)) return false;
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
{
if(m_funcs_list[i].id == id)
{
g_modules_funcs_list.Add(m_funcs_list[i]);
return true;
}
}
return false;
}
bool Module::UnLoad(u32 id)
{
return UnloadFunc(id);
}
static func_caller* sc_table[1024] =
{
null_func, bind_func(sys_process_getpid), null_func, bind_func(sys_process_exit), null_func, //4
null_func, null_func, null_func, null_func, null_func, //9
null_func, null_func, null_func, null_func, null_func, //14
null_func, null_func, null_func, null_func, null_func, //19
null_func, null_func, bind_func(sys_process_exit), null_func, null_func, //24
null_func, null_func, null_func, null_func, null_func, //29
null_func, null_func, null_func, null_func, null_func, //34
null_func, null_func, null_func, null_func, null_func, //39
null_func, bind_func(sys_ppu_thread_exit), null_func, bind_func(sys_ppu_thread_yield), bind_func(sys_ppu_thread_join), //44
bind_func(sys_ppu_thread_detach), bind_func(sys_ppu_thread_detach), bind_func(sys_ppu_thread_get_join_state), bind_func(sys_ppu_thread_set_priority), bind_func(sys_ppu_thread_get_priority), //49
bind_func(sys_ppu_thread_stop), bind_func(sys_ppu_thread_restart), bind_func(sys_ppu_thread_create), null_func, null_func, //54
null_func, null_func, null_func, null_func, null_func, //59
null_func, null_func, null_func, null_func, null_func, //64
null_func, null_func, null_func, null_func, null_func, //69
null_func, null_func, null_func, null_func, null_func, //74
null_func, null_func, null_func, null_func, null_func, //49
null_func, null_func, null_func, null_func, null_func, //84
null_func, null_func, null_func, null_func, null_func, //89
bind_func(sys_semaphore_create), bind_func(sys_semaphore_destroy), bind_func(sys_semaphore_wait), bind_func(sys_semaphore_trywait), bind_func(sys_semaphore_post), //94
bind_func(sys_lwmutex_create), bind_func(sys_lwmutex_destroy), bind_func(sys_lwmutex_lock), bind_func(sys_lwmutex_trylock), bind_func(sys_lwmutex_unlock), //99
bind_func(sys_mutex_create), bind_func(sys_mutex_destroy), bind_func(sys_mutex_lock), bind_func(sys_mutex_trylock), bind_func(sys_mutex_unlock), //104
bind_func(sys_cond_create), bind_func(sys_cond_destroy), bind_func(sys_cond_wait), bind_func(sys_cond_signal), bind_func(sys_cond_signal_all), //109
null_func, null_func, null_func, null_func, null_func, //114
null_func, null_func, null_func, null_func, null_func, //119
null_func, null_func, null_func, null_func, null_func, //124
null_func, null_func, null_func, null_func, null_func, //129
null_func, null_func, null_func, null_func, null_func, //134
null_func, null_func, null_func, null_func, null_func, //139
null_func, null_func, null_func, null_func, null_func, //144
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
null_func, null_func, null_func, null_func, null_func, //154
null_func, null_func, null_func, null_func, null_func, //159
bind_func(sys_raw_spu_create), null_func, null_func, null_func, null_func, //164
null_func, null_func, null_func, null_func, bind_func(sys_spu_initialize), //169
bind_func(sys_spu_thread_group_create), null_func, null_func, null_func, null_func, //174
null_func, null_func, null_func, null_func, null_func, //179
null_func, null_func, null_func, null_func, null_func, //184
null_func, null_func, null_func, null_func, null_func, //189
null_func, null_func, null_func, null_func, null_func, //194
null_func, null_func, null_func, null_func, null_func, //199
null_func, null_func, null_func, null_func, null_func, //204
null_func, null_func, null_func, null_func, null_func, //209
null_func, null_func, null_func, null_func, null_func, //214
null_func, null_func, null_func, null_func, null_func, //219
null_func, null_func, null_func, null_func, null_func, //224
null_func, null_func, null_func, null_func, null_func, //229
null_func, null_func, null_func, null_func, null_func, //234
null_func, null_func, null_func, null_func, null_func, //239
null_func, null_func, null_func, null_func, null_func, //244
null_func, null_func, null_func, null_func, null_func, //249
null_func, null_func, null_func, null_func, null_func, //254
null_func, null_func, null_func, null_func, null_func, //259
null_func, null_func, null_func, null_func, null_func, //264
null_func, null_func, null_func, null_func, null_func, //269
null_func, null_func, null_func, null_func, null_func, //274
null_func, null_func, null_func, null_func, null_func, //279
null_func, null_func, null_func, null_func, null_func, //284
null_func, null_func, null_func, null_func, null_func, //289
null_func, null_func, null_func, null_func, null_func, //294
null_func, null_func, null_func, null_func, null_func, //299
null_func, null_func, null_func, null_func, null_func, //304
null_func, null_func, null_func, null_func, null_func, //309
null_func, null_func, null_func, null_func, null_func, //314
null_func, null_func, null_func, null_func, null_func, //319
null_func, null_func, null_func, null_func, bind_func(sys_memory_container_create), //324
bind_func(sys_memory_container_destroy), null_func, null_func, null_func, null_func, //329
bind_func(sys_mmapper_allocate_address), null_func, null_func, null_func, null_func, //334
null_func, null_func, null_func, null_func, null_func, //339
null_func, null_func, null_func, null_func, null_func, //344
null_func, null_func, null_func, bind_func(sys_memory_allocate), bind_func(sys_memory_free), //349
null_func, null_func, bind_func(sys_memory_get_user_memory_size), null_func, null_func, //354
null_func, null_func, null_func, null_func, null_func, //359
null_func, null_func, null_func, null_func, null_func, //364
null_func, null_func, null_func, null_func, null_func, //369
null_func, null_func, null_func, null_func, null_func, //374
null_func, null_func, null_func, null_func, null_func, //379
null_func, null_func, null_func, null_func, null_func, //384
null_func, null_func, null_func, null_func, null_func, //389
null_func, null_func, null_func, null_func, null_func, //394
null_func, null_func, null_func, null_func, null_func, //399
null_func, null_func, bind_func(sys_tty_read), bind_func(sys_tty_write), null_func, //404
null_func, null_func, null_func, null_func, null_func, //409
null_func, null_func, null_func, null_func, null_func, //414
null_func, null_func, null_func, null_func, null_func, //419
null_func, null_func, null_func, null_func, null_func, //424
null_func, null_func, null_func, null_func, null_func, //429
null_func, null_func, null_func, null_func, null_func, //434
null_func, null_func, null_func, null_func, null_func, //439
null_func, null_func, null_func, null_func, null_func, //444
null_func, null_func, null_func, null_func, null_func, //449
null_func, null_func, null_func, null_func, null_func, //454
null_func, null_func, null_func, null_func, null_func, //459
null_func, null_func, null_func, null_func, null_func, //464
null_func, null_func, null_func, null_func, null_func, //469
null_func, null_func, null_func, null_func, null_func, //474
null_func, null_func, null_func, null_func, null_func, //479
null_func, null_func, null_func, null_func, null_func, //484
null_func, null_func, null_func, null_func, null_func, //489
null_func, null_func, null_func, null_func, null_func, //494
null_func, null_func, null_func, null_func, null_func, //499
null_func, null_func, null_func, null_func, null_func, //504
null_func, null_func, null_func, null_func, null_func, //509
null_func, null_func, null_func, null_func, null_func, //514
null_func, null_func, null_func, null_func, null_func, //519
null_func, null_func, null_func, null_func, null_func, //524
null_func, null_func, null_func, null_func, null_func, //529
null_func, null_func, null_func, null_func, null_func, //534
null_func, null_func, null_func, null_func, null_func, //539
null_func, null_func, null_func, null_func, null_func, //544
null_func, null_func, null_func, null_func, null_func, //549
null_func, null_func, null_func, null_func, null_func, //554
null_func, null_func, null_func, null_func, null_func, //559
null_func, null_func, null_func, null_func, null_func, //564
null_func, null_func, null_func, null_func, null_func, //569
null_func, null_func, null_func, null_func, null_func, //574
null_func, null_func, null_func, null_func, null_func, //579
null_func, null_func, null_func, null_func, null_func, //584
null_func, null_func, null_func, null_func, null_func, //589
null_func, null_func, null_func, null_func, null_func, //594
null_func, null_func, null_func, null_func, null_func, //599
null_func, null_func, null_func, null_func, null_func, //604
null_func, null_func, null_func, null_func, null_func, //609
null_func, null_func, null_func, null_func, null_func, //614
null_func, null_func, null_func, null_func, null_func, //619
null_func, null_func, null_func, null_func, null_func, //624
null_func, null_func, null_func, null_func, null_func, //629
null_func, null_func, null_func, null_func, null_func, //634
null_func, null_func, null_func, null_func, null_func, //639
null_func, null_func, null_func, null_func, null_func, //644
null_func, null_func, null_func, null_func, null_func, //649
null_func, null_func, null_func, null_func, null_func, //654
null_func, null_func, null_func, null_func, null_func, //659
null_func, null_func, null_func, null_func, null_func, //664
null_func, null_func, null_func, null_func, null_func, //669
null_func, null_func, null_func, null_func, null_func, //674
null_func, null_func, null_func, null_func, null_func, //679
null_func, null_func, null_func, null_func, null_func, //684
null_func, null_func, null_func, null_func, null_func, //689
null_func, null_func, null_func, null_func, null_func, //694
null_func, null_func, null_func, null_func, null_func, //699
null_func, null_func, null_func, null_func, null_func, //704
null_func, null_func, null_func, null_func, null_func, //709
null_func, null_func, null_func, null_func, null_func, //714
null_func, null_func, null_func, null_func, null_func, //719
null_func, null_func, null_func, null_func, null_func, //724
null_func, null_func, null_func, null_func, null_func, //729
null_func, null_func, null_func, null_func, null_func, //734
null_func, null_func, null_func, null_func, null_func, //739
null_func, null_func, null_func, null_func, null_func, //744
null_func, null_func, null_func, null_func, null_func, //749
null_func, null_func, null_func, null_func, null_func, //754
null_func, null_func, null_func, null_func, null_func, //759
null_func, null_func, null_func, null_func, null_func, //764
null_func, null_func, null_func, null_func, null_func, //769
null_func, null_func, null_func, null_func, null_func, //774
null_func, null_func, null_func, null_func, null_func, //779
null_func, null_func, null_func, null_func, null_func, //784
null_func, null_func, null_func, null_func, null_func, //789
null_func, null_func, null_func, null_func, null_func, //794
null_func, null_func, null_func, null_func, null_func, //799
null_func, bind_func(cellFsOpen), bind_func(cellFsRead), bind_func(cellFsWrite), bind_func(cellFsClose), //804
bind_func(cellFsOpendir), bind_func(cellFsReaddir), bind_func(cellFsClosedir), null_func, bind_func(cellFsFstat), //809
null_func, bind_func(cellFsMkdir), bind_func(cellFsRename), bind_func(cellFsRmdir), null_func, //814
null_func, null_func, null_func, bind_func(cellFsLseek), null_func, //819
null_func, null_func, null_func, null_func, null_func, //824
null_func, null_func, null_func, null_func, null_func, //829
null_func, null_func, null_func, null_func, null_func, //834
null_func, null_func, null_func, null_func, null_func, //839
null_func, null_func, null_func, null_func, null_func, //844
null_func, null_func, null_func, null_func, null_func, //849
null_func, null_func, null_func, null_func, null_func, //854
null_func, null_func, null_func, null_func, null_func, //859
null_func, null_func, null_func, null_func, null_func, //864
null_func, null_func, null_func, null_func, null_func, //869
null_func, null_func, null_func, null_func, null_func, //874
null_func, null_func, null_func, null_func, null_func, //879
null_func, null_func, null_func, null_func, null_func, //884
null_func, null_func, null_func, null_func, null_func, //889
null_func, null_func, null_func, null_func, null_func, //894
null_func, null_func, null_func, null_func, null_func, //899
null_func, null_func, null_func, null_func, null_func, //904
null_func, null_func, null_func, null_func, null_func, //909
null_func, null_func, null_func, null_func, null_func, //914
null_func, null_func, null_func, null_func, null_func, //919
null_func, null_func, null_func, null_func, null_func, //924
null_func, null_func, null_func, null_func, null_func, //929
null_func, null_func, null_func, null_func, null_func, //934
null_func, null_func, null_func, null_func, null_func, //939
null_func, null_func, null_func, null_func, null_func, //944
null_func, null_func, null_func, null_func, null_func, //949
null_func, null_func, null_func, null_func, null_func, //954
null_func, null_func, null_func, null_func, null_func, //959
null_func, null_func, null_func, null_func, null_func, //964
null_func, null_func, null_func, null_func, null_func, //969
null_func, null_func, null_func, null_func, null_func, //974
null_func, null_func, null_func, null_func, null_func, //979
null_func, null_func, null_func, null_func, null_func, //984
null_func, null_func, null_func, null_func, null_func, //989
null_func, null_func, null_func, null_func, null_func, //994
null_func, null_func, null_func, null_func, null_func, //999
null_func, null_func, null_func, null_func, null_func, //1004
null_func, null_func, null_func, null_func, null_func, //1009
null_func, null_func, null_func, null_func, null_func, //1014
null_func, null_func, null_func, null_func, null_func, //1019
null_func, null_func, null_func, bind_func(cellGcmCallback), //1024
};
SysCalls::SysCalls(PPUThread& cpu) : CPU(cpu)
{
}
SysCalls::~SysCalls()
{
}
s64 SysCalls::DoSyscall(u32 code)
{
if(code < 0x400)
{
if(sc_table[code])
{
(*sc_table[code])();
return SC_ARGS_1;
}
//TODO: remove this
switch(code)
{
//process
case 2: return lv2ProcessWaitForChild(CPU);
case 4: return lv2ProcessGetStatus(CPU);
case 5: return lv2ProcessDetachChild(CPU);
case 12: return lv2ProcessGetNumberOfObject(CPU);
case 13: return lv2ProcessGetId(CPU);
case 18: return lv2ProcessGetPpid(CPU);
case 19: return lv2ProcessKill(CPU);
case 23: return lv2ProcessWaitForChild2(CPU);
case 25: return lv2ProcessGetSdkVersion(CPU);
//timer
case 141:
case 142:
Sleep(SC_ARGS_1 / (1000 * 1000));
return 0;
//tty
case 988:
ConLog.Warning("SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx",
CPU.GPR[3], CPU.GPR[4], CPU.PC);
return 0;
case 999:
dump_enable = !dump_enable;
ConLog.Warning("Dump %s", dump_enable ? "enabled" : "disabled");
return 0;
}
ConLog.Error("Unknown syscall: %d - %08x", code, code);
return 0;
}
if(CallFunc(code)) return SC_ARGS_1;
//ConLog.Error("Unknown function 0x%08x", code);
//return 0;
//TODO: remove this
return DoFunc(code);
}

View File

@ -1,21 +1,180 @@
#pragma once
#include <Emu/Cell/PPUThread.h>
//#include <Emu/Cell/SPUThread.h>
#include "ErrorCodes.h"
//#define SYSCALLS_DEBUG
class SysCallBase
#define declCPU PPUThread& CPU = GetCurrentPPUThread
class func_caller
{
public:
virtual void operator()() = 0;
};
static func_caller *null_func = nullptr;
//TODO
struct ModuleFunc
{
u32 id;
func_caller* func;
ModuleFunc(u32 id, func_caller* func)
: id(id)
, func(func)
{
}
};
class Module
{
const char* m_name;
const u16 m_id;
bool m_is_loaded;
public:
Array<ModuleFunc> m_funcs_list;
Module(const char* name, u16 id);
void Load();
void UnLoad();
bool Load(u32 id);
bool UnLoad(u32 id);
void SetLoaded(bool loaded = true)
{
m_is_loaded = loaded;
}
bool IsLoaded() const
{
return m_is_loaded;
}
u16 GetID() const
{
return m_id;
}
wxString GetName() const
{
return m_name;
}
public:
void Log(const u32 id, wxString fmt, ...)
{
#ifdef SYSCALLS_DEBUG
va_list list;
va_start(list, fmt);
ConLog.Write(GetName() + wxString::Format("[%d]: ", id) + wxString::FormatV(fmt, list));
va_end(list);
#endif
}
void Log(wxString fmt, ...)
{
#ifdef SYSCALLS_DEBUG
va_list list;
va_start(list, fmt);
ConLog.Write(GetName() + ": " + wxString::FormatV(fmt, list));
va_end(list);
#endif
}
void Warning(const u32 id, wxString fmt, ...)
{
//#ifdef SYSCALLS_DEBUG
va_list list;
va_start(list, fmt);
ConLog.Warning(GetName() + wxString::Format("[%d] warning: ", id) + wxString::FormatV(fmt, list));
va_end(list);
//#endif
}
void Warning(wxString fmt, ...)
{
//#ifdef SYSCALLS_DEBUG
va_list list;
va_start(list, fmt);
ConLog.Warning(GetName() + " warning: " + wxString::FormatV(fmt, list));
va_end(list);
//#endif
}
void Error(const u32 id, wxString fmt, ...)
{
va_list list;
va_start(list, fmt);
ConLog.Error(GetName() + wxString::Format("[%d] error: ", id) + wxString::FormatV(fmt, list));
va_end(list);
}
void Error(wxString fmt, ...)
{
va_list list;
va_start(list, fmt);
ConLog.Error(GetName() + " error: " + wxString::FormatV(fmt, list));
va_end(list);
}
bool CheckId(u32 id) const
{
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName());
}
bool CheckId(u32 id, ID& _id) const
{
return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName());
}
template<typename T> bool CheckId(u32 id, T*& data)
{
ID id_data;
if(!CheckId(id, id_data)) return false;
data = (T*)id_data.m_data;
return true;
}
u32 GetNewId(void* data = nullptr, u8 flags = 0)
{
return Emu.GetIdManager().GetNewID(GetName(), data, flags);
}
//protected:
__forceinline void AddFunc(u32 id, func_caller* func)
{
m_funcs_list.Move(new ModuleFunc(id, func));
}
};
static s64 null_function() { return 0; }
bool IsLoadedFunc(u32 id);
bool CallFunc(u32 id);
bool UnloadFunc(u32 id);
void UnloadModules();
Module* GetModuleByName(const wxString& name);
Module* GetModuleById(u16 id);
class SysCallBase //Module
{
private:
wxString m_module_name;
//u32 m_id;
public:
SysCallBase(const wxString& name) : m_module_name(name)
SysCallBase(const wxString& name/*, u32 id*/)
: m_module_name(name)
//, m_id(id)
{
}
wxString GetName() { return m_module_name; }
const wxString& GetName() const { return m_module_name; }
void Log(const u32 id, wxString fmt, ...)
{
@ -39,22 +198,22 @@ public:
void Warning(const u32 id, wxString fmt, ...)
{
#ifdef SYSCALLS_DEBUG
//#ifdef SYSCALLS_DEBUG
va_list list;
va_start(list, fmt);
ConLog.Warning(GetName() + wxString::Format("[%d] warning: ", id) + wxString::FormatV(fmt, list));
va_end(list);
#endif
//#endif
}
void Warning(wxString fmt, ...)
{
#ifdef SYSCALLS_DEBUG
//#ifdef SYSCALLS_DEBUG
va_list list;
va_start(list, fmt);
ConLog.Warning(GetName() + wxString::Format(" warning: ") + wxString::FormatV(fmt, list));
ConLog.Warning(GetName() + " warning: " + wxString::FormatV(fmt, list));
va_end(list);
#endif
//#endif
}
void Error(const u32 id, wxString fmt, ...)
@ -69,11 +228,38 @@ public:
{
va_list list;
va_start(list, fmt);
ConLog.Error(GetName() + wxString::Format(" error: ") + wxString::FormatV(fmt, list));
ConLog.Error(GetName() + " error: " + wxString::FormatV(fmt, list));
va_end(list);
}
bool CheckId(u32 id) const
{
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName());
}
bool CheckId(u32 id, ID& _id) const
{
return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName());
}
template<typename T> bool CheckId(u32 id, T*& data)
{
ID id_data;
if(!CheckId(id, id_data)) return false;
data = (T*)id_data.m_data;
return true;
}
u32 GetNewId(void* data = nullptr, u8 flags = 0)
{
return Emu.GetIdManager().GetNewID(GetName(), data, flags);
}
};
/*
static bool CmpPath(const wxString& path1, const wxString& path2)
{
return path1.Len() >= path2.Len() && path1(0, path2.Len()).CmpNoCase(path2) == 0;
@ -99,37 +285,97 @@ static wxString GetWinPath(const wxString& path)
return wxFileName(Emu.m_path).GetPath() + (path[0] == '/' ? path : "/" + path);
}
*/
//process
extern int sys_process_getpid();
extern int sys_process_exit(int errorcode);
extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr,
u32 data, u32 data_size, int prio, u64 flags );
//sys_semaphore
extern int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_val, int max_val);
extern int sys_semaphore_destroy(u32 sem);
extern int sys_semaphore_wait(u32 sem, u64 timeout);
extern int sys_semaphore_trywait(u32 sem);
extern int sys_semaphore_post(u32 sem, int count);
//sys_lwmutex
extern int sys_lwmutex_create(u64 lwmutex_addr, u64 lwmutex_attr_addr);
extern int sys_lwmutex_destroy(u64 lwmutex_addr);
extern int sys_lwmutex_lock(u64 lwmutex_addr, u64 timeout);
extern int sys_lwmutex_trylock(u64 lwmutex_addr);
extern int sys_lwmutex_unlock(u64 lwmutex_addr);
//sys_cond
extern int sys_cond_create(u32 cond_addr, u32 mutex_id, u32 attr_addr);
extern int sys_cond_destroy(u32 cond_id);
extern int sys_cond_wait(u32 cond_id, u64 timeout);
extern int sys_cond_signal(u32 cond_id);
extern int sys_cond_signal_all(u32 cond_id);
//sys_mutex
extern int sys_mutex_create(u32 mutex_id_addr, u32 attr_addr);
extern int sys_mutex_destroy(u32 mutex_id);
extern int sys_mutex_lock(u32 mutex_id, u64 timeout);
extern int sys_mutex_trylock(u32 mutex_id);
extern int sys_mutex_unlock(u32 mutex_id);
//ppu_thread
extern int sys_ppu_thread_exit(int errorcode);
extern int sys_ppu_thread_yield();
extern int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr);
extern int sys_ppu_thread_detach(u32 thread_id);
extern void sys_ppu_thread_get_join_state(u32 isjoinable_addr);
extern int sys_ppu_thread_set_priority(u32 thread_id, int prio);
extern int sys_ppu_thread_get_priority(u32 thread_id, u32 prio_addr);
extern int sys_ppu_thread_get_stack_information(u32 info_addr);
extern int sys_ppu_thread_stop(u32 thread_id);
extern int sys_ppu_thread_restart(u32 thread_id);
extern int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
extern int sys_ppu_thread_get_id();
//memory
extern int sys_memory_container_create(u32 cid_addr, u32 yield_size);
extern int sys_memory_container_destroy(u32 cid);
extern int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr);
extern int sys_memory_free(u32 start_addr);
extern int sys_memory_get_user_memory_size(u32 mem_info_addr);
extern int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr);
extern int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr);
extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
//cellFs
extern int cellFsOpen(const u32 path_addr, const int flags, const u32 fd_addr, const u32 arg_addr, const u64 size);
extern int cellFsRead(const u32 fd, const u32 buf_addr, const u64 nbytes, const u32 nread_addr);
extern int cellFsWrite(const u32 fd, const u32 buf_addr, const u64 nbytes, const u32 nwrite_addr);
extern int cellFsClose(const u32 fd);
extern int cellFsOpendir(const u32 path_addr, const u32 fd_addr);
extern int cellFsReaddir(const u32 fd, const u32 dir_addr, const u32 nread_addr);
extern int cellFsClosedir(const u32 fd);
extern int cellFsStat(const u32 path_addr, const u32 sb_addr);
extern int cellFsFstat(const u32 fd, const u32 sb_addr);
extern int cellFsMkdir(const u32 path_addr, const u32 mode);
extern int cellFsRename(const u32 from_addr, const u32 to_addr);
extern int cellFsRmdir(const u32 path_addr);
extern int cellFsUnlink(const u32 path_addr);
extern int cellFsLseek(const u32 fd, const s64 offset, const u32 whence, const u32 pos_addr);
extern int cellFsOpen(u32 path_addr, int flags, u32 fd_addr, u32 arg_addr, u64 size);
extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, u32 nread_addr);
extern int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, u32 nwrite_addr);
extern int cellFsClose(u32 fd);
extern int cellFsOpendir(u32 path_addr, u32 fd_addr);
extern int cellFsReaddir(u32 fd, u32 dir_addr, u32 nread_addr);
extern int cellFsClosedir(u32 fd);
extern int cellFsStat(u32 path_addr, u32 sb_addr);
extern int cellFsFstat(u32 fd, u32 sb_addr);
extern int cellFsMkdir(u32 path_addr, u32 mode);
extern int cellFsRename(u32 from_addr, u32 to_addr);
extern int cellFsRmdir(u32 path_addr);
extern int cellFsUnlink(u32 path_addr);
extern int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_addr);
//cellVideo
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
extern int cellVideoOutGetResolution(u32 resolutionId, u32 resolution_addr);
extern int cellVideoOutConfigure(u32 videoOut, u32 config_addr, u32 option_addr, u32 waitForEvent);
extern int cellVideoOutGetConfiguration(u32 videoOut, u32 config_addr, u32 option_addr);
extern int cellVideoOutGetNumberOfDevice(u32 videoOut);
extern int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option);
//cellSysutil
extern int cellSysutilCheckCallback();
extern int cellSysutilRegisterCallback(int slot, u64 func_addr, u64 userdata);
extern int cellSysutilUnregisterCallback(int slot);
//cellMsgDialog
extern int cellMsgDialogOpen2(u32 type, u32 msgString_addr, u32 callback_addr, u32 userData, u32 extParam);
//cellPad
extern int cellPadInit(u32 max_connect);
@ -142,17 +388,29 @@ extern int cellPadGetInfo2(u32 info_addr);
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);
//cellGcm
extern int cellGcmInit(const u32 context_addr, const u32 cmdSize, const u32 ioSize, const u32 ioAddress);
extern int cellGcmGetConfiguration(const u32 config_addr);
extern int cellGcmAddressToOffset(const u32 address, const u32 offset_addr);
extern int cellGcmSetDisplayBuffer(const u8 id, const u32 offset, const u32 pitch, const u32 width, const u32 height);
extern u32 cellGcmGetLabelAddress(const u32 index);
extern int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress);
extern int cellGcmMapMainMemory(u32 address, u32 size, u32 offset_addr);
extern int cellGcmCallback(u32 context_addr, u32 count);
extern int cellGcmGetConfiguration(u32 config_addr);
extern int cellGcmAddressToOffset(u32 address, u32 offset_addr);
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
extern u32 cellGcmGetLabelAddress(u32 index);
extern u32 cellGcmGetControlRegister();
extern int cellGcmFlush(const u32 ctx, const u8 id);
extern int cellGcmSetTile(const u8 index, const u8 location, const u32 offset, const u32 size, const u32 pitch, const u8 comp, const u16 base, const u8 bank);
extern int cellGcmFlush(u32 ctx, u32 id);
extern void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank);
extern int cellGcmBindTile(u32 index);
extern int cellGcmBindZcull(u32 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask);
extern int cellGcmGetFlipStatus();
extern int cellGcmResetFlipStatus();
extern u32 cellGcmGetTiledPitchSize(const u32 size);
extern u32 cellGcmGetTiledPitchSize(u32 size);
extern int cellGcmSetFlipMode(u32 mode);
extern u32 cellGcmGetDefaultCommandWordSize();
extern u32 cellGcmGetDefaultSegmentWordSize();
extern int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize);
//sys_tty
extern int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);
extern int sys_tty_write(u32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr);
//cellResc
extern int cellRescSetSrc(const int idx, const u32 src_addr);
@ -173,7 +431,7 @@ extern int sys_time_get_current_time(u32 sec_addr, u32 nsec_addr);
extern s64 sys_time_get_system_time();
extern u64 sys_time_get_timebase_frequency();
#define SC_ARGS_1 CPU.GPR[3]
#define SC_ARGS_1 CPU.GPR[3]
#define SC_ARGS_2 SC_ARGS_1,CPU.GPR[4]
#define SC_ARGS_3 SC_ARGS_2,CPU.GPR[5]
#define SC_ARGS_4 SC_ARGS_3,CPU.GPR[6]
@ -181,11 +439,18 @@ extern u64 sys_time_get_timebase_frequency();
#define SC_ARGS_6 SC_ARGS_5,CPU.GPR[8]
#define SC_ARGS_7 SC_ARGS_6,CPU.GPR[9]
#define SC_ARGS_8 SC_ARGS_7,CPU.GPR[10]
#define SC_ARGS_9 SC_ARGS_8,CPU.GPR[11]
#define SC_ARGS_10 SC_ARGS_9,CPU.GPR[12]
#define SC_ARGS_11 SC_ARGS_10,CPU.GPR[13]
#define SC_ARGS_12 SC_ARGS_11,CPU.GPR[14]
extern bool dump_enable;
class PPUThread;
class SysCalls
{
PPUThread& CPU;
public:
//process
int lv2ProcessGetPid(PPUThread& CPU);
@ -196,138 +461,16 @@ public:
int lv2ProcessGetId(PPUThread& CPU);
int lv2ProcessGetPpid(PPUThread& CPU);
int lv2ProcessKill(PPUThread& CPU);
int lv2ProcessExit(PPUThread& CPU);
int lv2ProcessWaitForChild2(PPUThread& CPU);
int lv2ProcessGetSdkVersion(PPUThread& CPU);
//ppu thread
int lv2PPUThreadCreate(PPUThread& CPU);
int lv2PPUThreadExit(PPUThread& CPU);
int lv2PPUThreadYield(PPUThread& CPU);
int lv2PPUThreadJoin(PPUThread& CPU);
int lv2PPUThreadDetach(PPUThread& CPU);
int lv2PPUThreadGetJoinState(PPUThread& CPU);
int lv2PPUThreadSetPriority(PPUThread& CPU);
int lv2PPUThreadGetPriority(PPUThread& CPU);
int lv2PPUThreadGetStackInformation(PPUThread& CPU);
int lv2PPUThreadRename(PPUThread& CPU);
int lv2PPUThreadRecoverPageFault(PPUThread& CPU);
int lv2PPUThreadGetPageFaultContext(PPUThread& CPU);
int lv2PPUThreadGetId(PPUThread& CPU);
//lwmutex
int Lv2LwmutexCreate(PPUThread& CPU);
int Lv2LwmutexDestroy(PPUThread& CPU);
int Lv2LwmutexLock(PPUThread& CPU);
int Lv2LwmutexTrylock(PPUThread& CPU);
int Lv2LwmutexUnlock(PPUThread& CPU);
//tty
int lv2TtyRead(PPUThread& CPU);
int lv2TtyWrite(PPUThread& CPU);
protected:
SysCalls(PPUThread& cpu);
~SysCalls();
public:
SysCalls()// : CPU(cpu)
{
}
~SysCalls()
{
Close();
}
void Close()
{
}
s64 DoSyscall(u32 code, PPUThread& CPU)
{
switch(code)
{
//=== lv2 ===
//process
case 1: return sys_process_getpid();
case 2: return lv2ProcessWaitForChild(CPU);
case 3: return lv2ProcessExit(CPU);
case 4: return lv2ProcessGetStatus(CPU);
case 5: return lv2ProcessDetachChild(CPU);
case 12: return lv2ProcessGetNumberOfObject(CPU);
case 13: return lv2ProcessGetId(CPU);
case 18: return lv2ProcessGetPpid(CPU);
case 19: return lv2ProcessKill(CPU);
case 22: return lv2ProcessExit(CPU);
case 23: return lv2ProcessWaitForChild2(CPU);
case 25: return lv2ProcessGetSdkVersion(CPU);
//ppu thread
//case ?: return lv2PPUThreadCreate(CPU);
//case ?: return lv2PPUThreadExit(CPU);
case 43: return lv2PPUThreadYield(CPU);
case 44: return lv2PPUThreadJoin(CPU);
case 45: return lv2PPUThreadDetach(CPU);
case 46: return lv2PPUThreadGetJoinState(CPU);
case 47: return lv2PPUThreadSetPriority(CPU);
case 48: return lv2PPUThreadGetPriority(CPU);
case 49: return lv2PPUThreadGetStackInformation(CPU);
case 56: return lv2PPUThreadRename(CPU);
case 57: return lv2PPUThreadRecoverPageFault(CPU);
case 58: return lv2PPUThreadGetPageFaultContext(CPU);
//case ?: return lv2PPUThreadGetId(CPU);
//lwmutex
case 95: return Lv2LwmutexCreate(CPU);
case 96: return Lv2LwmutexDestroy(CPU);
case 97: return Lv2LwmutexLock(CPU);
case 98: return Lv2LwmutexTrylock(CPU);
case 99: return Lv2LwmutexUnlock(CPU);
//timer
case 141:
case 142:
//wxSleep(Emu.GetCPU().GetThreads().GetCount() > 1 ? 1 : /*SC_ARGS_1*/1);
return 0;
//time
case 145: return sys_time_get_current_time(SC_ARGS_2);
case 146: return sys_time_get_system_time();
case 147: return sys_time_get_timebase_frequency();
//sys_spu
case 160: return sys_raw_spu_create(SC_ARGS_2);
case 169: return sys_spu_initialize(SC_ARGS_2);
case 170: return sys_spu_thread_group_create(SC_ARGS_4);
//memory
case 324: return sys_memory_container_create(SC_ARGS_2);
case 325: return sys_memory_container_destroy(SC_ARGS_1);
case 348: return sys_memory_allocate(SC_ARGS_3);
case 352: return sys_memory_get_user_memory_size(SC_ARGS_1);
//tty
case 402: return lv2TtyRead(CPU);
case 403: return lv2TtyWrite(CPU);
//file system
case 801: return cellFsOpen(SC_ARGS_5);
case 802: return cellFsRead(SC_ARGS_4);
case 803: return cellFsWrite(SC_ARGS_4);
case 804: return cellFsClose(SC_ARGS_1);
case 805: return cellFsOpendir(SC_ARGS_2);
case 806: return cellFsReaddir(SC_ARGS_3);
case 807: return cellFsClosedir(SC_ARGS_1);
case 809: return cellFsFstat(SC_ARGS_2);
case 811: return cellFsMkdir(SC_ARGS_2);
case 812: return cellFsRename(SC_ARGS_2);
case 813: return cellFsRmdir(SC_ARGS_1);
case 818: return cellFsLseek(SC_ARGS_4);
case 988:
ConLog.Warning("SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx",
CPU.GPR[3], CPU.GPR[4], CPU.PC);
return 0;
case 999:
dump_enable = !dump_enable;
ConLog.Warning("Dump %s", dump_enable ? "enabled" : "disabled");
return 0;
}
ConLog.Error("Unknown syscall: %d - %08x", code, code);
return 0;
}
s64 DoFunc(const u32 id, PPUThread& CPU);
s64 DoSyscall(u32 code);
s64 DoFunc(const u32 id);
};
extern SysCalls SysCallsManager;
//extern SysCalls SysCallsManager;

View File

@ -0,0 +1,98 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "SC_Mutex.h"
SysCallBase sys_cond("sys_cond");
extern SysCallBase sys_mtx;
struct condition_attr
{
u32 pshared;
int flags;
u64 ipc_key;
char name[8];
};
struct condition
{
wxCondition cond;
condition_attr attr;
condition(wxMutex& mtx, const condition_attr& attr)
: cond(mtx)
, attr(attr)
{
}
};
int sys_cond_create(u32 cond_addr, u32 mutex_id, u32 attr_addr)
{
sys_cond.Log("sys_cond_create(cond_addr=0x%x, mutex_id=0x%x, attr_addr=%d)",
cond_addr, mutex_id, attr_addr);
if(!Memory.IsGoodAddr(cond_addr) || !Memory.IsGoodAddr(attr_addr)) return CELL_EFAULT;
condition_attr attr = (condition_attr&)Memory[attr_addr];
attr.pshared = re(attr.pshared);
attr.ipc_key = re(attr.ipc_key);
attr.flags = re(attr.flags);
sys_cond.Log("*** pshared = %d", attr.pshared);
sys_cond.Log("*** ipc_key = 0x%llx", attr.ipc_key);
sys_cond.Log("*** flags = 0x%x", attr.flags);
sys_cond.Log("*** name = %s", attr.name);
mutex* mtx_data = nullptr;
if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH;
Memory.Write32(cond_addr, sys_cond.GetNewId(new condition(mtx_data->mtx, attr)));
return CELL_OK;
}
int sys_cond_destroy(u32 cond_id)
{
sys_cond.Log("sys_cond_destroy(cond_id=0x%x)", cond_id);
if(!sys_cond.CheckId(cond_id)) return CELL_ESRCH;
Emu.GetIdManager().RemoveID(cond_id);
return CELL_OK;
}
int sys_cond_wait(u32 cond_id, u64 timeout)
{
sys_cond.Log("sys_cond_wait(cond_id=0x%x, timeout=0x%llx)", cond_id, timeout);
condition* cond_data = nullptr;
if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH;
cond_data->cond.WaitTimeout(timeout ? timeout : INFINITE);
return CELL_OK;
}
int sys_cond_signal(u32 cond_id)
{
sys_cond.Log("sys_cond_signal(cond_id=0x%x)", cond_id);
condition* cond_data = nullptr;
if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH;
cond_data->cond.Signal();
return CELL_OK;
}
int sys_cond_signal_all(u32 cond_id)
{
sys_cond.Log("sys_cond_signal_all(cond_id=0x%x)", cond_id);
condition* cond_data = nullptr;
if(!sys_cond.CheckId(cond_id, cond_data)) return CELL_ESRCH;
cond_data->cond.Broadcast();
return CELL_OK;
}

View File

@ -1,7 +1,6 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
typedef u64 GPRtype;
enum Lv2FsOflag
{
LV2_O_RDONLY = 000000,
@ -83,26 +82,22 @@ enum FsDirentType
CELL_FS_TYPE_SYMLINK = 3,
};
SysCallBase sc_log("cellFs");
extern Module sys_fs;
wxString ReadString(const u32 addr)
{
return GetWinPath(Memory.ReadString(addr));
}
int cellFsOpen(const u32 path_addr, const int flags, const u32 fd_addr, const u32 arg_addr, const u64 size)
int cellFsOpen(u32 path_addr, int flags, u32 fd_addr, u32 arg_addr, u64 size)
{
const wxString& path = Memory.ReadString(path_addr);
sc_log.Log("cellFsOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
sys_fs.Log("cellFsOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
path, flags, fd_addr, arg_addr, size);
const wxString& ppath = GetWinPath(path);
const wxString& ppath = path;
//ConLog.Warning("path: %s [%s]", ppath, path);
s32 _oflags = flags;
if(flags & LV2_O_CREAT)
{
_oflags &= ~LV2_O_CREAT;
/*
//create path
for(uint p=1;p<ppath.Length();p++)
{
@ -116,7 +111,6 @@ int cellFsOpen(const u32 path_addr, const int flags, const u32 fd_addr, const u3
wxMkdir(dir);
}
}
//create file
if(!wxFileExists(ppath))
{
@ -124,15 +118,18 @@ int cellFsOpen(const u32 path_addr, const int flags, const u32 fd_addr, const u3
f.Create(ppath);
f.Close();
}
*/
Emu.GetVFS().Create(ppath);
}
wxFile::OpenMode o_mode;
vfsOpenMode o_mode;
switch(flags & LV2_O_ACCMODE)
{
case LV2_O_RDONLY:
_oflags &= ~LV2_O_RDONLY;
o_mode = wxFile::read;
o_mode = vfsRead;
break;
case LV2_O_WRONLY:
@ -141,107 +138,109 @@ int cellFsOpen(const u32 path_addr, const int flags, const u32 fd_addr, const u3
if(flags & LV2_O_APPEND)
{
_oflags &= ~LV2_O_APPEND;
o_mode = wxFile::write_append;
o_mode = vfsWriteAppend;
}
else if(flags & LV2_O_EXCL)
{
_oflags &= ~LV2_O_EXCL;
o_mode = wxFile::write_excl;
o_mode = vfsWriteExcl;
}
else //if(flags & LV2_O_TRUNC)
{
_oflags &= ~LV2_O_TRUNC;
o_mode = wxFile::write;
o_mode = vfsWrite;
}
break;
case LV2_O_RDWR:
_oflags &= ~LV2_O_RDWR;
o_mode = wxFile::read_write;
o_mode = vfsReadWrite;
break;
}
if(_oflags != 0)
{
sc_log.Error("'%s' has unknown flags! flags: 0x%08x", ppath, flags);
sys_fs.Error("'%s' has unknown flags! flags: 0x%08x", ppath, flags);
return CELL_EINVAL;
}
if(!wxFile::Access(ppath, o_mode))
vfsStream* stream = Emu.GetVFS().Open(ppath, o_mode);
if(!stream || !stream->IsOpened())
{
sc_log.Error("'%s' not found! flags: 0x%08x", ppath, flags);
sys_fs.Error("'%s' not found! flags: 0x%08x", ppath, flags);
delete stream;
return CELL_ENOENT;
}
Memory.Write32(fd_addr,
Emu.GetIdManager().GetNewID(sc_log.GetName(), new wxFile(ppath, o_mode), flags));
Memory.Write32(fd_addr, sys_fs.GetNewId(stream, flags));
return CELL_OK;
}
int cellFsRead(const u32 fd, const u32 buf_addr, const u64 nbytes, const u32 nread_addr)
int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, u32 nread_addr)
{
sc_log.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
fd, buf_addr, nbytes, nread_addr);
if(!Emu.GetIdManager().CheckID(fd)) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(fd);
if(!!id.m_name.Cmp(sc_log.GetName())) return CELL_ESRCH;
wxFile& file = *(wxFile*)id.m_data;
ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
Memory.Write64NN(nread_addr, file.Read(Memory.GetMemFromAddr(buf_addr), nbytes));
return CELL_OK;
}
int cellFsWrite(const u32 fd, const u32 buf_addr, const u64 nbytes, const u32 nwrite_addr)
int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, u32 nwrite_addr)
{
sc_log.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
fd, buf_addr, nbytes, nwrite_addr);
if(!Emu.GetIdManager().CheckID(fd)) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(fd);
if(!!id.m_name.Cmp(sc_log.GetName())) return CELL_ESRCH;
wxFile& file = *(wxFile*)id.m_data;
ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
Memory.Write64NN(nwrite_addr, file.Write(Memory.GetMemFromAddr(buf_addr), nbytes));
return CELL_OK;
}
int cellFsClose(const u32 fd)
int cellFsClose(u32 fd)
{
sc_log.Log("cellFsClose(fd: %d)", fd);
if(!Emu.GetIdManager().CheckID(fd)) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(fd);
if(!!id.m_name.Cmp(sc_log.GetName())) return CELL_ESRCH;
wxFile& file = *(wxFile*)id.m_data;
sys_fs.Log("cellFsClose(fd: %d)", fd);
ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
file.Close();
Emu.GetIdManager().RemoveID(fd);
return CELL_OK;
}
int cellFsOpendir(const u32 path_addr, const u32 fd_addr)
int cellFsOpendir(u32 path_addr, u32 fd_addr)
{
const wxString& path = Memory.ReadString(path_addr);
sc_log.Error("cellFsOpendir(path: %s, fd_addr: 0x%x)", path, fd_addr);
sys_fs.Error("cellFsOpendir(path_addr: 0x%x(%s), fd_addr: 0x%x)", path_addr, path, fd_addr);
if(!Memory.IsGoodAddr(path_addr, sizeof(u32)) || !Memory.IsGoodAddr(fd_addr, sizeof(u32))) return CELL_EFAULT;
return CELL_OK;
}
int cellFsReaddir(const u32 fd, const u32 dir_addr, const u32 nread_addr)
int cellFsReaddir(u32 fd, u32 dir_addr, u32 nread_addr)
{
sc_log.Error("cellFsReaddir(fd: %d, dir_addr: 0x%x, nread_addr: 0x%x)", fd, dir_addr, nread_addr);
sys_fs.Error("cellFsReaddir(fd: %d, dir_addr: 0x%x, nread_addr: 0x%x)", fd, dir_addr, nread_addr);
return CELL_OK;
}
int cellFsClosedir(const u32 fd)
int cellFsClosedir(u32 fd)
{
sc_log.Error("cellFsClosedir(fd: %d)", fd);
sys_fs.Error("cellFsClosedir(fd: %d)", fd);
return CELL_OK;
}
int cellFsStat(const u32 path_addr, const u32 sb_addr)
{
const wxString& path = ReadString(path_addr);
sc_log.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb_addr);
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb_addr);
if(!wxFileExists(path)) return CELL_ENOENT;
@ -275,11 +274,10 @@ int cellFsStat(const u32 path_addr, const u32 sb_addr)
int cellFsFstat(u32 fd, u32 sb_addr)
{
sc_log.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb_addr);
if(!Emu.GetIdManager().CheckID(fd)) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(fd);
if(!!id.m_name.Cmp(sc_log.GetName())) return CELL_ESRCH;
wxFile& file = *(wxFile*)id.m_data;
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb_addr);
ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
Lv2FsStat stat;
stat.st_mode =
@ -293,7 +291,7 @@ int cellFsFstat(u32 fd, u32 sb_addr)
stat.st_atime = 0; //TODO
stat.st_mtime = 0; //TODO
stat.st_ctime = 0; //TODO
stat.st_size = file.Length();
stat.st_size = file.GetSize();
stat.st_blksize = 4096;
mem_class_t stat_c(sb_addr);
@ -309,59 +307,58 @@ int cellFsFstat(u32 fd, u32 sb_addr)
return CELL_OK;
}
int cellFsMkdir(const u32 path_addr, const u32 mode)
int cellFsMkdir(u32 path_addr, u32 mode)
{
const wxString& path = ReadString(path_addr);
sc_log.Log("cellFsMkdir(path: %s, mode: 0x%x)", path, mode);
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsMkdir(path: %s, mode: 0x%x)", path, mode);
if(wxDirExists(path)) return CELL_EEXIST;
if(!wxMkdir(path)) return CELL_EBUSY;
return CELL_OK;
}
int cellFsRename(const u32 from_addr, const u32 to_addr)
int cellFsRename(u32 from_addr, u32 to_addr)
{
const wxString& from = ReadString(from_addr);
const wxString& to = ReadString(to_addr);
sc_log.Log("cellFsRename(from: %s, to: %s)", from, to);
const wxString& from = Memory.ReadString(from_addr);
const wxString& to = Memory.ReadString(to_addr);
sys_fs.Log("cellFsRename(from: %s, to: %s)", from, to);
if(!wxFileExists(from)) return CELL_ENOENT;
if(wxFileExists(to)) return CELL_EEXIST;
if(!wxRenameFile(from, to)) return CELL_EBUSY;
return CELL_OK;
}
int cellFsRmdir(const u32 path_addr)
int cellFsRmdir(u32 path_addr)
{
const wxString& path = ReadString(path_addr);
sc_log.Log("cellFsRmdir(path: %s)", path);
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Log("cellFsRmdir(path: %s)", path);
if(!wxDirExists(path)) return CELL_ENOENT;
if(!wxRmdir(path)) return CELL_EBUSY;
return CELL_OK;
}
int cellFsUnlink(const u32 path_addr)
int cellFsUnlink(u32 path_addr)
{
const wxString& path = ReadString(path_addr);
sc_log.Error("cellFsUnlink(path: %s)", path);
const wxString& path = Memory.ReadString(path_addr);
sys_fs.Error("cellFsUnlink(path: %s)", path);
return CELL_OK;
}
int cellFsLseek(const u32 fd, const s64 offset, const u32 whence, const u32 pos_addr)
int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_addr)
{
wxSeekMode seek_mode;
sc_log.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos_addr);
vfsSeekMode seek_mode;
sys_fs.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos_addr);
switch(whence)
{
case LV2_SEEK_SET: seek_mode = wxFromStart; break;
case LV2_SEEK_CUR: seek_mode = wxFromCurrent; break;
case LV2_SEEK_END: seek_mode = wxFromEnd; break;
case LV2_SEEK_SET: seek_mode = vfsSeekSet; break;
case LV2_SEEK_CUR: seek_mode = vfsSeekCur; break;
case LV2_SEEK_END: seek_mode = vfsSeekEnd; break;
default:
sc_log.Error(fd, "Unknown seek whence! (%d)", whence);
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
return CELL_EINVAL;
}
if(!Emu.GetIdManager().CheckID(fd)) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(fd);
if(!!id.m_name.Cmp(sc_log.GetName())) return CELL_ESRCH;
wxFile& file = *(wxFile*)id.m_data;
ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
Memory.Write64(pos_addr, file.Seek(offset, seek_mode));
return CELL_OK;
}

View File

@ -2,15 +2,24 @@
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/GS/GCM.h"
SysCallBase sc_gcm("cellGcm");
extern Module cellGcmSys;
CellGcmConfig current_config;
CellGcmContextData current_context;
gcmInfo gcm_info;
int cellGcmInit(const u32 context_addr, const u32 cmdSize, const u32 ioSize, const u32 ioAddress)
int cellGcmMapMainMemory(u32 address, u32 size, u32 offset_addr)
{
sc_gcm.Log("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
cellGcmSys.Warning("cellGcmMapMainMemory(address=0x%x,size=0x%x,offset_addr=0x%x)", address, size, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
Memory.Write32(offset_addr, address & 0xffff);
return CELL_OK;
}
int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
{
cellGcmSys.Log("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
const u32 local_size = 0xf900000; //TODO
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
@ -38,7 +47,7 @@ int cellGcmInit(const u32 context_addr, const u32 cmdSize, const u32 ioSize, con
Memory.WriteData(gcm_info.context_addr, current_context);
Memory.Write32(context_addr, gcm_info.context_addr);
CellGcmControl& ctrl = *(CellGcmControl*)Memory.GetMemFromAddr(gcm_info.control_addr);
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
ctrl.put = 0;
ctrl.get = 0;
ctrl.ref = -1;
@ -48,16 +57,40 @@ int cellGcmInit(const u32 context_addr, const u32 cmdSize, const u32 ioSize, con
return CELL_OK;
}
int cellGcmGetConfiguration(const u32 config_addr)
int cellGcmCallback(u32 context_addr, u32 count)
{
sc_gcm.Log("cellGcmGetConfiguration(config_addr=0x%x)", config_addr);
GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH);
CellGcmContextData& ctx = (CellGcmContextData&)Memory[context_addr];
CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr];
const s32 res = re(ctx.current) - re(ctx.begin) - re(ctrl.put);
if(res > 0) memcpy(&Memory[re(ctx.begin)], &Memory[re(ctx.current) - res], res);
ctx.current = re(re(ctx.begin) + res);
ctrl.put = re(res);
ctrl.get = 0;
return CELL_OK;
}
int cellGcmGetConfiguration(u32 config_addr)
{
cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config_addr);
if(!Memory.IsGoodAddr(config_addr, sizeof(CellGcmConfig))) return CELL_EFAULT;
Memory.WriteData(config_addr, current_config);
return CELL_OK;
}
int cellGcmAddressToOffset(const u32 address, const u32 offset_addr)
int cellGcmAddressToOffset(u32 address, u32 offset_addr)
{
sc_gcm.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset_addr);
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
Memory.Write32(offset_addr,
Memory.RSXFBMem.IsInMyRange(address)
? address - Memory.RSXFBMem.GetStartAddr()
@ -66,9 +99,9 @@ int cellGcmAddressToOffset(const u32 address, const u32 offset_addr)
return CELL_OK;
}
int cellGcmSetDisplayBuffer(const u8 id, const u32 offset, const u32 pitch, const u32 width, const u32 height)
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
{
sc_gcm.Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
id, offset, width ? pitch/width : pitch, width, height);
if(id > 1) return CELL_EINVAL;
@ -81,22 +114,22 @@ int cellGcmSetDisplayBuffer(const u8 id, const u32 offset, const u32 pitch, cons
return CELL_OK;
}
u32 cellGcmGetLabelAddress(const u32 index)
u32 cellGcmGetLabelAddress(u32 index)
{
sc_gcm.Log("cellGcmGetLabelAddress(index=%d)", index);
cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index);
return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index;
}
u32 cellGcmGetControlRegister()
{
sc_gcm.Log("cellGcmGetControlRegister()");
cellGcmSys.Log("cellGcmGetControlRegister()");
return gcm_info.control_addr;
}
int cellGcmFlush(const u32 ctx, const u8 id)
int cellGcmFlush(u32 ctx, u32 id)
{
sc_gcm.Log("cellGcmFlush(ctx=0x%x, id=0x%x)", ctx, id);
cellGcmSys.Log("cellGcmFlush(ctx=0x%x, id=0x%x)", ctx, id);
if(id > 1) return CELL_EINVAL;
Emu.GetGSManager().GetRender().Draw();
@ -104,12 +137,25 @@ int cellGcmFlush(const u32 ctx, const u8 id)
return CELL_OK;
}
int cellGcmSetTile(const u8 index, const u8 location, const u32 offset, const u32 size,
const u32 pitch, const u8 comp, const u16 base, const u8 bank)
void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank)
{
sc_gcm.Log("cellGcmSetTile(index=%d, location=%d, offset=0x%x, size=0x%x, pitch=0x%x, comp=0x%x, base=0x%x, bank=0x%x)",
cellGcmSys.Warning("cellGcmSetTile(index=%d, location=%d, offset=0x%x, size=0x%x, pitch=0x%x, comp=0x%x, base=0x%x, bank=0x%x)",
index, location, offset, size, pitch, comp, base, bank);
//return CELL_OK;
}
int cellGcmBindTile(u32 index)
{
cellGcmSys.Warning("TODO: cellGcmBindTile(index=%d)", index);
return CELL_OK;
}
int cellGcmBindZcull(u32 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask)
{
cellGcmSys.Warning("TODO: cellGcmBindZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)", index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask);
return CELL_OK;
}
@ -121,13 +167,51 @@ int cellGcmGetFlipStatus()
int cellGcmResetFlipStatus()
{
Emu.GetGSManager().GetRender().m_flip_status = 1;
return CELL_OK;
}
u32 cellGcmGetTiledPitchSize(const u32 size)
int cellGcmSetFlipMode(u32 mode)
{
cellGcmSys.Warning("cellGcmSetFlipMode(mode=%d)", mode);
switch(mode)
{
case CELL_GCM_DISPLAY_HSYNC:
case CELL_GCM_DISPLAY_VSYNC:
case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE:
Emu.GetGSManager().GetRender().m_flip_mode = mode;
break;
default:
return CELL_EINVAL;
}
return CELL_OK;
}
u32 cellGcmGetTiledPitchSize(u32 size)
{
//TODO
sc_gcm.Log("cellGcmGetTiledPitchSize(size=%d)", size);
cellGcmSys.Warning("cellGcmGetTiledPitchSize(size=%d)", size);
return size;
}
}
u32 cellGcmGetDefaultCommandWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultCommandWordSize()");
return 0x400;
}
u32 cellGcmGetDefaultSegmentWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultSegmentWordSize()");
return 0x100;
}
int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize)
{
cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize);
return CELL_OK;
}

View File

@ -29,77 +29,85 @@ struct lwmutex_attr
char name[8];
};
SysCallBase sc_lwmutex("Lwmutex");
SysCallBase sc_lwmutex("sys_wmutex");
//TODO
int SysCalls::Lv2LwmutexCreate(PPUThread& CPU)
int sys_lwmutex_create(u64 lwmutex_addr, u64 lwmutex_attr_addr)
{
/*
//int sys_lwmutex_create(sys_lwmutex_t *lwmutex, sys_lwmutex_attribute_t *attr)
const u64 lwmutex_addr = CPU.GPR[3];
const u64 lwmutex_attr_addr = CPU.GPR[4];
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
lwmutex_attr& lmtx_attr = (lwmutex_attr&)Memory[lwmutex_attr_addr];
//ConLog.Write("Lv2LwmutexCreate[r3: 0x%llx, r4: 0x%llx]", lwmutex_addr, lwmutex_attr_addr);
//sc_lwmutex.Warning("sys_lwmutex_create(lwmutex_addr = 0x%llx, lwmutex_attr_addr = 0x%llx)", lwmutex_addr, lwmutex_attr_addr);
lwmutex& lmtx = *(lwmutex*)Memory.GetMemFromAddr(lwmutex_addr);
lwmutex_attr& lmtx_attr = *(lwmutex_attr*)Memory.GetMemFromAddr(lwmutex_attr_addr);
lmtx.lock_var.info.owner = CPU.GetId();
lmtx.attribute = Emu.GetIdManager().GetNewID(wxString::Format("Lwmutex[%s]", lmtx_attr.name), NULL, lwmutex_addr);
*/
lmtx.lock_var.info.owner = 0;
lmtx.lock_var.info.waiter = 0;
lmtx.attribute = Emu.GetIdManager().GetNewID(wxString::Format("lwmutex[%s]", lmtx_attr.name), nullptr, lwmutex_addr);
/*
ConLog.Write("r3:");
ConLog.Write("*** lock_var[owner: 0x%x, waiter: 0x%x]", lmtx.lock_var.info.owner, lmtx.lock_var.info.waiter);
ConLog.Write("*** attribute: 0x%x", lmtx.attribute);
ConLog.Write("*** recursive_count: 0x%x", lmtx.recursive_count);
ConLog.Write("*** sleep_queue: 0x%x", lmtx.sleep_queue);
ConLog.Write("*** lock_var[owner: 0x%x, waiter: 0x%x]", re(lmtx.lock_var.info.owner), re(lmtx.lock_var.info.waiter));
ConLog.Write("*** attribute: 0x%x", re(lmtx.attribute));
ConLog.Write("*** recursive_count: 0x%x", re(lmtx.recursive_count));
ConLog.Write("*** sleep_queue: 0x%x", re(lmtx.sleep_queue));
ConLog.Write("r4:");
ConLog.Write("*** attr_protocol: 0x%x", lmtx_attr.attr_protocol);
ConLog.Write("*** attr_recursive: 0x%x", lmtx_attr.attr_recursive);
ConLog.Write("*** attr_protocol: 0x%x", re(lmtx_attr.attr_protocol));
ConLog.Write("*** attr_recursive: 0x%x", re(lmtx_attr.attr_recursive));
ConLog.Write("*** name: %s", lmtx_attr.name);
*/
return 0;
return CELL_OK;
}
int SysCalls::Lv2LwmutexDestroy(PPUThread& CPU)
int sys_lwmutex_destroy(u64 lwmutex_addr)
{
/*
const u64 lwmutex_addr = CPU.GPR[3];
//ConLog.Write("Lv2LwmutexDestroy[r3: 0x%llx]", lwmutex_addr);
//sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr = 0x%llx)", lwmutex_addr);
lwmutex& lmtx = *(lwmutex*)Memory.GetMemFromAddr(lwmutex_addr);
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
Emu.GetIdManager().RemoveID(lmtx.attribute);
//memset(Memory.GetMemFromAddr(lwmutex_addr), 0, sizeof(lwmutex));
*/
return 0;
return CELL_OK;
}
int SysCalls::Lv2LwmutexLock(PPUThread& CPU)
int sys_lwmutex_lock(u64 lwmutex_addr, u64 timeout)
{
//int sys_lwmutex_lock(sys_lwmutex_t *lwmutex, usecond_t timeout)
const u64 lwmutex_addr = CPU.GPR[3];
const u64 timeout = CPU.GPR[4];
//ConLog.Write("Lv2LwmutexLock[r3: 0x%llx, r4: 0x%llx]", lwmutex_addr, timeout);
//sc_lwmutex.Warning("sys_lwmutex_lock(lwmutex_addr = 0x%llx, timeout = 0x%llx)", lwmutex_addr, timeout);
//lwmutex& lmtx = *(lwmutex*)Memory.GetMemFromAddr(lwmutex_addr);
//lmtx.lock_var.info.waiter = CPU.GetId();
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
return 0;//CELL_ESRCH;
if(!lmtx.lock_var.info.owner)
{
re(lmtx.lock_var.info.owner, GetCurrentPPUThread().GetId());
}
else if(!lmtx.lock_var.info.waiter)
{
re(lmtx.lock_var.info.waiter, GetCurrentPPUThread().GetId());
while(re(lmtx.lock_var.info.owner) != GetCurrentPPUThread().GetId()) Sleep(1);
}
else
{
return -1;
}
return CELL_OK;
}
int SysCalls::Lv2LwmutexTrylock(PPUThread& CPU)
int sys_lwmutex_trylock(u64 lwmutex_addr)
{
//int sys_lwmutex_trylock(sys_lwmutex_t *lwmutex)
const u64 lwmutex_addr = CPU.GPR[3];
//ConLog.Write("Lv2LwmutexTrylock[r3: 0x%llx]", lwmutex_addr);
return 0;
//sc_lwmutex.Warning("sys_lwmutex_trylock(lwmutex_addr = 0x%llx)", lwmutex_addr);
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
if(lmtx.lock_var.info.owner) return CELL_EBUSY;
return CELL_OK;
}
int SysCalls::Lv2LwmutexUnlock(PPUThread& CPU)
int sys_lwmutex_unlock(u64 lwmutex_addr)
{
//int sys_lwmutex_unlock(sys_lwmutex_t *lwmutex)
const u64 lwmutex_addr = CPU.GPR[3];
//ConLog.Write("Lv2LwmutexUnlock[r3: 0x%llx]", lwmutex_addr);
return 0;
//sc_lwmutex.Warning("sys_lwmutex_unlock(lwmutex_addr = 0x%llx)", lwmutex_addr);
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
lmtx.lock_var.info.owner = lmtx.lock_var.info.waiter;
lmtx.lock_var.info.waiter = 0;
return CELL_OK;
}

View File

@ -201,6 +201,62 @@ int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr)
return CELL_OK;
}
int sys_memory_free(u32 start_addr)
{
sc_mem.Log("sys_memory_free(start_addr=0x%x)", start_addr);
if(!Memory.Free(start_addr)) return CELL_EFAULT;
return CELL_OK;
}
struct mmapper_info
{
u32 size;
u32 flags;
mmapper_info(u32 _size, u32 _flags)
: size(_size)
, flags(_flags)
{
}
mmapper_info()
{
}
};
int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr)
{
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
Memory.Write32(alloc_addr, Memory.Alloc(size, 4));
return CELL_OK;
}
int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr)
{
sc_mem.Warning("sys_mmapper_allocate_memory(size=0x%x, flags=0x%llx, mem_id_addr=0x%x)", size, flags, mem_id_addr);
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
Memory.Write32(mem_id_addr, sc_mem.GetNewId(new mmapper_info(size, flags)));
return CELL_OK;
}
int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
{
sc_mem.Warning("sys_mmapper_map_memory(start_addr=0x%x, mem_id=0x%x, flags=0x%llx)", start_addr, mem_id, flags);
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info)) return CELL_ESRCH;
//Memory.MemoryBlocks.Add((new MemoryBlock())->SetRange(start_addr, info->size));
return CELL_OK;
}
struct sys_memory_info
{
u32 total_user_memory;

View File

@ -0,0 +1,78 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "SC_Mutex.h"
SysCallBase sys_mtx("sys_mutex");
int sys_mutex_create(u32 mutex_id_addr, u32 attr_addr)
{
sys_mtx.Log("sys_mutex_create(mutex_id_addr=0x%x, attr_addr=0x%x)",
mutex_id_addr, attr_addr);
if(!Memory.IsGoodAddr(mutex_id_addr) || !Memory.IsGoodAddr(attr_addr)) return CELL_EFAULT;
mutex_attr attr = (mutex_attr&)Memory[attr_addr];
attr.protocol = re(attr.protocol);
attr.recursive = re(attr.recursive);
attr.pshared = re(attr.pshared);
attr.adaptive = re(attr.adaptive);
attr.ipc_key = re(attr.ipc_key);
attr.flags = re(attr.flags);
sys_mtx.Log("*** protocol = %d", attr.protocol);
sys_mtx.Log("*** recursive = %d", attr.recursive);
sys_mtx.Log("*** pshared = %d", attr.pshared);
sys_mtx.Log("*** ipc_key = 0x%llx", attr.ipc_key);
sys_mtx.Log("*** flags = 0x%x", attr.flags);
sys_mtx.Log("*** name = %s", attr.name);
Memory.Write32(mutex_id_addr, sys_mtx.GetNewId(new mutex(attr)));
return CELL_OK;
}
int sys_mutex_destroy(u32 mutex_id)
{
sys_mtx.Log("sys_mutex_destroy(mutex_id=0x%x)", mutex_id);
if(!sys_mtx.CheckId(mutex_id)) return CELL_ESRCH;
Emu.GetIdManager().RemoveID(mutex_id);
return CELL_OK;
}
int sys_mutex_lock(u32 mutex_id, u64 timeout)
{
sys_mtx.Log("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx)", mutex_id, timeout);
mutex* mtx_data = nullptr;
if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH;
mtx_data->mtx.Lock();
return CELL_OK;
}
int sys_mutex_trylock(u32 mutex_id)
{
sys_mtx.Log("sys_mutex_trylock(mutex_id=0x%x)", mutex_id);
mutex* mtx_data = nullptr;
if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH;
if(mtx_data->mtx.TryLock()) return 1;
return CELL_OK;
}
int sys_mutex_unlock(u32 mutex_id)
{
sys_mtx.Log("sys_mutex_unlock(mutex_id=0x%x)", mutex_id);
mutex* mtx_data = nullptr;
if(!sys_mtx.CheckId(mutex_id, mtx_data)) return CELL_ESRCH;
mtx_data->mtx.Unlock();
return CELL_OK;
}

View File

@ -0,0 +1,25 @@
#pragma once
struct mutex_attr
{
u32 protocol;
u32 recursive;
u32 pshared;
u32 adaptive;
u64 ipc_key;
int flags;
u32 pad;
char name[8];
};
struct mutex
{
wxMutex mtx;
mutex_attr attr;
mutex(const mutex_attr& attr)
: mtx()
, attr(attr)
{
}
};

View File

@ -1,126 +1,135 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
extern Module sysPrxForUser;
#define PPU_THREAD_ID_INVALID 0xFFFFFFFFU
int SysCalls::lv2PPUThreadCreate(PPUThread& CPU)
int sys_ppu_thread_exit(int errorcode)
{
ConLog.Write("lv2PPUThreadCreate:");
//ConLog.Write("**** id: %d", CPU.GPR[3]);
ConLog.Write("**** entry: 0x%x", CPU.GPR[4]);
ConLog.Write("**** arg: 0x%x", CPU.GPR[5]);
ConLog.Write("**** prio: 0x%x", CPU.GPR[6]);
ConLog.Write("**** stacksize: 0x%x", CPU.GPR[7]);
ConLog.Write("**** flags: 0x%x", CPU.GPR[8]);
ConLog.Write("**** threadname: \"%s\"[0x%x]", Memory.ReadString(CPU.GPR[9]), CPU.GPR[9]);
sysPrxForUser.Log("sys_ppu_thread_exit(errorcode=%d)", errorcode);
Emu.GetCPU().RemoveThread(GetCurrentPPUThread().GetId());
if(!Memory.IsGoodAddr(CPU.GPR[4])) return CELL_EFAULT;
return CELL_OK;
}
int sys_ppu_thread_yield()
{
sysPrxForUser.Log("sys_ppu_thread_yield()");
wxThread::Yield();
return CELL_OK;
}
int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr)
{
sysPrxForUser.Error("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr_addr);
return CELL_OK;
}
int sys_ppu_thread_detach(u32 thread_id)
{
sysPrxForUser.Error("sys_ppu_thread_detach(thread_id=%d)", thread_id);
return CELL_OK;
}
void sys_ppu_thread_get_join_state(u32 isjoinable_addr)
{
sysPrxForUser.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable_addr);
Memory.Write32(isjoinable_addr, GetCurrentPPUThread().IsJoinable());
}
int sys_ppu_thread_set_priority(u32 thread_id, int prio)
{
sysPrxForUser.Warning("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio);
PPCThread* thr = Emu.GetCPU().GetThread(thread_id);
if(!thr) return CELL_ESRCH;
thr->SetPrio(prio);
return CELL_OK;
}
int sys_ppu_thread_get_priority(u32 thread_id, u32 prio_addr)
{
sysPrxForUser.Log("sys_ppu_thread_get_priority(thread_id=%d, prio_addr=0x%x)", thread_id, prio_addr);
PPCThread* thr = Emu.GetCPU().GetThread(thread_id);
if(!thr) return CELL_ESRCH;
if(!Memory.IsGoodAddr(prio_addr)) return CELL_EFAULT;
Memory.Write32(prio_addr, thr->GetPrio());
return CELL_OK;
}
int sys_ppu_thread_get_stack_information(u32 info_addr)
{
sysPrxForUser.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr);
if(!Memory.IsGoodAddr(info_addr)) return CELL_EFAULT;
declCPU();
Memory.Write32(info_addr, CPU.GetStackAddr());
Memory.Write32(info_addr+4, CPU.GetStackSize());
return CELL_OK;
}
int sys_ppu_thread_stop(u32 thread_id)
{
sysPrxForUser.Warning("sys_ppu_thread_stop(thread_id=%d)", thread_id);
PPCThread* thr = Emu.GetCPU().GetThread(thread_id);
if(!thr) return CELL_ESRCH;
thr->Stop();
return CELL_OK;
}
int sys_ppu_thread_restart(u32 thread_id)
{
sysPrxForUser.Warning("sys_ppu_thread_restart(thread_id=%d)", thread_id);
PPCThread* thr = Emu.GetCPU().GetThread(thread_id);
if(!thr) return CELL_ESRCH;
thr->Stop();
thr->Run();
return CELL_OK;
}
int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr)
{
sysPrxForUser.Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
thread_id_addr, entry, arg, prio, stacksize, flags, threadname_addr, Memory.ReadString(threadname_addr));
if(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr) || !Memory.IsGoodAddr(threadname_addr)) return CELL_EFAULT;
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
Memory.Write32(CPU.GPR[3], new_thread.GetId());
new_thread.SetPc(CPU.GPR[4]);
new_thread.SetArg(CPU.GPR[5]);
new_thread.SetPrio(CPU.GPR[6]);
new_thread.stack_size = CPU.GPR[7];
//new_thread.flags = CPU.GPR[8];
new_thread.SetName(Memory.ReadString(CPU.GPR[9]));
Memory.Write32(thread_id_addr, new_thread.GetId());
new_thread.SetEntry(entry);
new_thread.SetArg(arg);
new_thread.SetPrio(prio);
new_thread.stack_size = stacksize;
//new_thread.flags = flags;
new_thread.SetName(Memory.ReadString(threadname_addr));
new_thread.Run();
new_thread.Exec();
return CELL_OK;
}
int SysCalls::lv2PPUThreadExit(PPUThread& CPU)
int sys_ppu_thread_get_id()
{
ConLog.Warning("PPU[%d] thread exit(%lld)", CPU.GetId(), CPU.GPR[3]);
Emu.GetCPU().RemoveThread(CPU.GetId());
return CELL_OK;
}
sysPrxForUser.Log("sys_ppu_thread_get_id()");
int SysCalls::lv2PPUThreadYield(PPUThread& CPU)
{
//ConLog.Warning("TODO: PPU[%d] thread yield!", CPU.GetId());
return CELL_OK;
return GetCurrentPPUThread().GetId();
}
int SysCalls::lv2PPUThreadJoin(PPUThread& CPU)
{
ConLog.Warning("TODO: PPU[%d] thread join!", CPU.GPR[3]);
return CELL_OK;
}
int SysCalls::lv2PPUThreadDetach(PPUThread& CPU)
{
ConLog.Warning("PPU[%d] thread detach", CPU.GPR[3]);
if(!Emu.GetIdManager().CheckID(CPU.GPR[3])) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(CPU.GPR[3]);
if(!id.m_used) return CELL_ESRCH;
PPCThread& thread = *(PPCThread*)id.m_data;
if(thread.IsJoinable()) return CELL_EINVAL;
if(thread.IsJoining()) return CELL_EBUSY;
thread.SetJoinable(false);
if(!thread.IsRunned()) Emu.GetCPU().RemoveThread(thread.GetId());
return CELL_OK;
}
int SysCalls::lv2PPUThreadGetJoinState(PPUThread& CPU)
{
ConLog.Warning("PPU[%d] get join state", CPU.GetId());
Memory.Write32(CPU.GPR[3], CPU.IsJoinable() ? 1 : 0);
return CELL_OK;
}
int SysCalls::lv2PPUThreadSetPriority(PPUThread& CPU)
{
ConLog.Write("PPU[%d] thread set priority", CPU.GPR[3]);
if(!Emu.GetIdManager().CheckID(CPU.GPR[3])) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(CPU.GPR[3]);
CPU.SetPrio(CPU.GPR[4]);
return CELL_OK;
}
int SysCalls::lv2PPUThreadGetPriority(PPUThread& CPU)
{
ConLog.Write("PPU[%d] thread get priority", CPU.GPR[3]);
if(!Emu.GetIdManager().CheckID(CPU.GPR[3])) return CELL_ESRCH;
const ID& id = Emu.GetIdManager().GetIDData(CPU.GPR[3]);
Memory.Write32(CPU.GPR[4], CPU.GetPrio());
return CELL_OK;
}
int SysCalls::lv2PPUThreadGetStackInformation(PPUThread& CPU)
{
ConLog.Write("PPU[%d] thread get stack information(0x%llx)", CPU.GetId(), CPU.GPR[3]);
Memory.Write32(CPU.GPR[3], CPU.GetStackAddr());
Memory.Write32(CPU.GPR[3]+4, CPU.GetStackSize());
return CELL_OK;
}
int SysCalls::lv2PPUThreadRename(PPUThread& CPU)
{
ConLog.Write("PPU[%d] thread rename(%s)", CPU.GPR[3], Memory.ReadString(CPU.GPR[4]));
return CELL_OK;
}
int SysCalls::lv2PPUThreadRecoverPageFault(PPUThread& CPU)
{
ConLog.Warning("TODO: PPU[%d] thread recover page fault!", CPU.GPR[3]);
return CELL_OK;
}
int SysCalls::lv2PPUThreadGetPageFaultContext(PPUThread& CPU)
{
ConLog.Warning("TODO: PPU[%d] thread get page fault context!", CPU.GPR[3]);
return CELL_OK;
}
int SysCalls::lv2PPUThreadGetId(PPUThread& CPU)
{
//ConLog.Write("PPU[%d] thread get id(0x%llx)", CPU.GetId(), CPU.GPR[3]);
Memory.Write64(CPU.GPR[3], CPU.GetId());
return CELL_OK;
}
int sys_spu_thread_once(u64 once_ctrl_addr, u64 init_addr)
{
return 0;
}

View File

@ -2,7 +2,7 @@
#include "Emu/Io/Pad.h"
#include "Emu/SysCalls/SysCalls.h"
SysCallBase sc_pad("cellPad");
extern Module sys_io;
enum CELL_PAD_ERROR_CODE
{
@ -37,7 +37,7 @@ struct CellPadInfo2
int cellPadInit(u32 max_connect)
{
sc_pad.Log("cellPadInit(max_connect=%d)", max_connect);
sys_io.Log("cellPadInit(max_connect=%d)", max_connect);
if(Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_ALREADY_INITIALIZED;
Emu.GetPadManager().Init(max_connect);
return CELL_OK;
@ -45,7 +45,7 @@ int cellPadInit(u32 max_connect)
int cellPadEnd()
{
sc_pad.Log("cellPadEnd()");
sys_io.Log("cellPadEnd()");
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
Emu.GetPadManager().Close();
return CELL_OK;
@ -53,7 +53,7 @@ int cellPadEnd()
int cellPadClearBuf(u32 port_no)
{
sc_pad.Log("cellPadClearBuf(port_no=%d)", port_no);
sys_io.Log("cellPadClearBuf(port_no=%d)", port_no);
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
if(port_no >= Emu.GetPadManager().GetPads().GetCount()) return CELL_PAD_ERROR_INVALID_PARAMETER;
@ -120,7 +120,7 @@ int cellPadGetData(u32 port_no, u32 data_addr)
int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr)
{
sc_pad.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_addr=0x%x, device_type_addr=0x%x)", port_no, device_type_addr, data_addr);
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
if(port_no >= Emu.GetPadManager().GetPads().GetCount()) return CELL_PAD_ERROR_INVALID_PARAMETER;
return CELL_OK;
@ -128,7 +128,7 @@ int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr)
int cellPadSetActDirect(u32 port_no, u32 param_addr)
{
sc_pad.Log("cellPadSetActDirect(port_no=%d, param_addr=0x%x)", port_no, param_addr);
sys_io.Log("cellPadSetActDirect(port_no=%d, param_addr=0x%x)", port_no, param_addr);
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
if(port_no >= Emu.GetPadManager().GetPads().GetCount()) return CELL_PAD_ERROR_INVALID_PARAMETER;
return CELL_OK;
@ -136,7 +136,7 @@ int cellPadSetActDirect(u32 port_no, u32 param_addr)
int cellPadGetInfo2(u32 info_addr)
{
sc_pad.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr);
sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr);
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
CellPadInfo2 info;
@ -165,7 +165,7 @@ int cellPadGetInfo2(u32 info_addr)
int cellPadSetPortSetting(u32 port_no, u32 port_setting)
{
sc_pad.Log("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);
sys_io.Log("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
Array<Pad>& pads = Emu.GetPadManager().GetPads();
if(port_no >= pads.GetCount()) return CELL_PAD_ERROR_INVALID_PARAMETER;

View File

@ -8,26 +8,27 @@ int sys_process_getpid()
return 1;
}
int sys_process_exit(int errorcode)
{
ConLog.Warning("sys_process_exit(%d)", errorcode);
Emu.Pause();
return CELL_OK;
}
int sys_game_process_exitspawn( u32 path_addr, u32 argv_addr, u32 envp_addr,
u32 data, u32 data_size, int prio, u64 flags )
{
sc_p.Log("sys_game_process_exitspawn: ");
sc_p.Log("path: %s", Memory.ReadString(path_addr));
sc_p.Log("argv: %x", Memory.Read32(argv_addr));
sc_p.Log("envp: %x", Memory.Read32(envp_addr));
sc_p.Log("data: %x", data);
sc_p.Log("data_size: %x", data_size);
sc_p.Log("argv: 0x%x", Memory.Read32(argv_addr));
sc_p.Log("envp: 0x%x", Memory.Read32(envp_addr));
sc_p.Log("data: 0x%x", data);
sc_p.Log("data_size: 0x%x", data_size);
sc_p.Log("prio: %d", prio);
sc_p.Log("flags: %d", flags);
return CELL_OK;
}
int SysCalls::lv2ProcessGetPid(PPUThread& CPU)
{
ConLog.Warning("lv2ProcessGetPid");
Memory.Write32(CPU.GPR[4], CPU.GetId());
return CELL_OK;
}
int SysCalls::lv2ProcessWaitForChild(PPUThread& CPU)
{
ConLog.Warning("lv2ProcessWaitForChild");
@ -69,12 +70,14 @@ int SysCalls::lv2ProcessKill(PPUThread& CPU)
CPU.Close();
return CELL_OK;
}
/*
int SysCalls::lv2ProcessExit(PPUThread& CPU)
{
ConLog.Warning("lv2ProcessExit(%lld)", CPU.GPR[3]);
Emu.Pause();
return CELL_OK;
}
*/
int SysCalls::lv2ProcessWaitForChild2(PPUThread& CPU)
{
ConLog.Warning("lv2ProcessWaitForChild2[r3: 0x%llx, r4: 0x%llx, r5: 0x%llx, r6: 0x%llx, r7: 0x%llx, r8: 0x%llx]",

View File

@ -15,8 +15,16 @@ struct CellRescSrc
int cellRescSetSrc(const int idx, const u32 src_addr)
{
sc_resc.Warning("cellRescSetSrc(idx=0x%x, src_addr=0x%x)", idx, src_addr);
const CellRescSrc& src = *(CellRescSrc*)Memory.GetMemFromAddr(src_addr);
sc_resc.Warning(" *** format=%d", src.format);
if(!Memory.IsGoodAddr(src_addr, sizeof(CellRescSrc))) return CELL_EFAULT;
CellRescSrc src = (CellRescSrc&)Memory[src_addr];
re(src.format, src.format);
re(src.pitch, src.pitch);
re(src.width, src.width);
re(src.height, src.height);
re(src.offset, src.offset);
sc_resc.Warning(" *** format=0x%x", src.format);
sc_resc.Warning(" *** pitch=%d", src.pitch);
sc_resc.Warning(" *** width=%d", src.width);
sc_resc.Warning(" *** height=%d", src.height);

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "Loader/ELF.h"
SysCallBase sc_spu("sys_spu");
@ -11,6 +12,34 @@ struct sys_spu_thread_group_attribute
union{u32 ct;} option;
};
struct sys_spu_image
{
u32 type;
u32 entry_point;
u32 segs_addr;
int nsegs;
};
u32 LoadImage(vfsStream& stream)
{
ELFLoader l(stream);
l.LoadInfo();
l.LoadData(Memory.MainMem.Alloc(stream.GetSize()));
return l.GetEntry();
}
int sys_spu_image_open(u32 img_addr, u32 path_addr)
{
const wxString& path = Memory.ReadString(path_addr);
sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img_addr, path_addr, path);
vfsLocalFile stream(path);
LoadImage(stream);
return CELL_OK;
}
//170
int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr)
{
@ -45,11 +74,11 @@ int sys_spu_thread_create(u64 thread_id_addr, u64 entry_addr, u64 arg,
//160
int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
{
sc_spu.Log("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id_addr, attr_addr);
sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id_addr, attr_addr);
PPCThread& new_thread = Emu.GetCPU().AddThread(false);
Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId()));
//PPCThread& new_thread = Emu.GetCPU().AddThread(false);
//Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
//Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId()));
return CELL_OK;
}
@ -57,7 +86,7 @@ int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
//169
int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
{
sc_spu.Log("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu);
sc_spu.Warning("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu);
if(!Memory.InitSpuRawMem(max_raw_spu))
{

View File

@ -0,0 +1,96 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
SysCallBase sys_sem("sys_semaphore");
struct semaphore_attr
{
u32 protocol;
u32 pshared;
u64 ipc_key;
int flags;
u32 pad;
char name[8];
};
struct semaphore
{
wxSemaphore sem;
semaphore_attr attr;
semaphore(int initial_count, int max_count, semaphore_attr attr)
: sem(initial_count, max_count)
, attr(attr)
{
}
};
int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_count, int max_count)
{
sys_sem.Log("sys_semaphore_create(sem_addr=0x%x, attr_addr=0x%x, initial_count=%d, max_count=%d)",
sem_addr, attr_addr, initial_count, max_count);
if(!Memory.IsGoodAddr(sem_addr) || !Memory.IsGoodAddr(attr_addr)) return CELL_EFAULT;
semaphore_attr attr = (semaphore_attr&)Memory[attr_addr];
attr.protocol = re(attr.protocol);
attr.pshared = re(attr.pshared);
attr.ipc_key = re(attr.ipc_key);
attr.flags = re(attr.flags);
sys_sem.Log("*** protocol = %d", attr.protocol);
sys_sem.Log("*** pshared = %d", attr.pshared);
sys_sem.Log("*** ipc_key = 0x%llx", attr.ipc_key);
sys_sem.Log("*** flags = 0x%x", attr.flags);
sys_sem.Log("*** name = %s", attr.name);
Memory.Write32(sem_addr, sys_sem.GetNewId(new semaphore(initial_count, max_count, attr)));
return CELL_OK;
}
int sys_semaphore_destroy(u32 sem)
{
sys_sem.Log("sys_semaphore_destroy(sem=0x%x)", sem);
if(!sys_sem.CheckId(sem)) return CELL_ESRCH;
Emu.GetIdManager().RemoveID(sem);
return CELL_OK;
}
int sys_semaphore_wait(u32 sem, u64 timeout)
{
sys_sem.Log("sys_semaphore_wait(sem=0x%x, timeout=0x%llx)", sem, timeout);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
sem_data->sem.WaitTimeout(timeout ? timeout : INFINITE);
return CELL_OK;
}
int sys_semaphore_trywait(u32 sem)
{
sys_sem.Log("sys_semaphore_trywait(sem=0x%x)", sem);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
if(sem_data->sem.TryWait()) return 1;
return CELL_OK;
}
int sys_semaphore_post(u32 sem, int count)
{
sys_sem.Log("sys_semaphore_post(sem=0x%x, count=%d)", sem, count);
semaphore* sem_data = nullptr;
if(!sys_sem.CheckId(sem, sem_data)) return CELL_ESRCH;
while(count--) sem_data->sem.Post();
return CELL_OK;
}

View File

@ -48,53 +48,157 @@ int cellVideoOutGetResolution(u32 resolutionId, u32 resolution_addr)
sc_v.Log("cellVideoOutGetResolution(resolutionId=%d, resolution_addr=0x%x)",
resolutionId, resolution_addr);
CellVideoOutResolution res = {0, 0};
switch(resolutionId)
if(!Memory.IsGoodAddr(resolution_addr, sizeof(CellVideoOutResolution)))
{
case CELL_VIDEO_OUT_RESOLUTION_1080:
res.width = re16(1920);
res.height = re16(1080);
break;
return CELL_EFAULT;
}
u32 num = ResolutionIdToNum(resolutionId);
case CELL_VIDEO_OUT_RESOLUTION_720:
res.width = re16(1280);
res.height = re16(720);
break;
case CELL_VIDEO_OUT_RESOLUTION_480:
res.width = re16(720);
res.height = re16(480);
break;
case CELL_VIDEO_OUT_RESOLUTION_576:
res.width = re16(720);
res.height = re16(576);
break;
case CELL_VIDEO_OUT_RESOLUTION_1600x1080:
res.width = re16(1600);
res.height = re16(1080);
break;
case CELL_VIDEO_OUT_RESOLUTION_1440x1080:
res.width = re16(1440);
res.height = re16(1080);
break;
case CELL_VIDEO_OUT_RESOLUTION_1280x1080:
res.width = re16(1280);
res.height = re16(1080);
break;
case CELL_VIDEO_OUT_RESOLUTION_960x1080:
res.width = re16(960);
res.height = re16(1080);
break;
default: return CELL_EINVAL;
if(!num)
{
return CELL_EINVAL;
}
CellVideoOutResolution res;
re(res.width, ResolutionTable[num].width);
re(res.height, ResolutionTable[num].height);
Memory.WriteData(resolution_addr, res);
return CELL_VIDEO_OUT_SUCCEEDED;
}
int cellVideoOutConfigure(u32 videoOut, u32 config_addr, u32 option_addr, u32 waitForEvent)
{
sc_v.Warning("cellVideoOutConfigure(videoOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=0x%x)",
videoOut, config_addr, option_addr, waitForEvent);
if(!Memory.IsGoodAddr(config_addr, sizeof(CellVideoOutConfiguration)))
{
return CELL_EFAULT;
}
CellVideoOutConfiguration& config = (CellVideoOutConfiguration&)Memory[config_addr];
switch(videoOut)
{
case CELL_VIDEO_OUT_PRIMARY:
if(config.resolutionId)
{
Emu.GetGSManager().GetInfo().mode.resolutionId = config.resolutionId;
}
Emu.GetGSManager().GetInfo().mode.format = config.format;
if(config.aspect)
{
Emu.GetGSManager().GetInfo().mode.aspect = config.aspect;
}
if(config.pitch)
{
Emu.GetGSManager().GetInfo().mode.pitch = re(config.pitch);
}
return CELL_VIDEO_OUT_SUCCEEDED;
case CELL_VIDEO_OUT_SECONDARY:
return CELL_VIDEO_OUT_SUCCEEDED;
}
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetConfiguration(u32 videoOut, u32 config_addr, u32 option_addr)
{
sc_v.Warning("cellVideoOutGetConfiguration(videoOut=%d, config_addr=0x%x, option_addr=0x%x)",
videoOut, config_addr, option_addr);
if(!Memory.IsGoodAddr(config_addr, sizeof(CellVideoOutConfiguration))) return CELL_EFAULT;
CellVideoOutConfiguration config;
memset(&config, 0, sizeof(CellVideoOutConfiguration));
switch(videoOut)
{
case CELL_VIDEO_OUT_PRIMARY:
config.resolutionId = Emu.GetGSManager().GetInfo().mode.resolutionId;
config.format = Emu.GetGSManager().GetInfo().mode.format;
config.aspect = Emu.GetGSManager().GetInfo().mode.aspect;
config.pitch = re(Emu.GetGSManager().GetInfo().mode.pitch);
Memory.WriteData(config_addr, config);
return CELL_VIDEO_OUT_SUCCEEDED;
case CELL_VIDEO_OUT_SECONDARY:
Memory.WriteData(config_addr, config);
return CELL_VIDEO_OUT_SUCCEEDED;
}
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetNumberOfDevice(u32 videoOut)
{
sc_v.Warning("cellVideoOutGetNumberOfDevice(videoOut=%d)", videoOut);
switch(videoOut)
{
case CELL_VIDEO_OUT_PRIMARY: return 1;
case CELL_VIDEO_OUT_SECONDARY: return 0;
}
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option)
{
sc_v.Warning("cellVideoOutGetResolutionAvailability(videoOut=%d, resolutionId=0x%x, option_addr=0x%x, aspect=0x%x, option=0x%x)",
videoOut, resolutionId, aspect, option);
if(!ResolutionIdToNum(resolutionId))
{
return CELL_EINVAL;
}
switch(videoOut)
{
case CELL_VIDEO_OUT_PRIMARY: return 1;
case CELL_VIDEO_OUT_SECONDARY: return 0;
}
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
}
SysCallBase sc_sysutil("cellSysutil");
int cellSysutilCheckCallback()
{
//sc_sysutil.Warning("cellSysutilCheckCallback()");
Emu.GetCallbackManager().m_exit_callback.Check();
return CELL_OK;
}
int cellSysutilRegisterCallback(int slot, u64 func_addr, u64 userdata)
{
sc_sysutil.Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%llx, userdata=0x%llx)", slot, func_addr, userdata);
Emu.GetCallbackManager().m_exit_callback.Register(slot, func_addr, userdata);
wxGetApp().m_MainFrame->UpdateUI();
return CELL_OK;
}
int cellSysutilUnregisterCallback(int slot)
{
sc_sysutil.Warning("cellSysutilUnregisterCallback(slot=%d)", slot);
Emu.GetCallbackManager().m_exit_callback.Unregister(slot);
wxGetApp().m_MainFrame->UpdateUI();
return CELL_OK;
}

View File

@ -0,0 +1,76 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
SysCallBase sc_md("cellMsgDialog");
enum
{
CELL_MSGDIALOG_BUTTON_NONE = -1,
CELL_MSGDIALOG_BUTTON_INVALID = 0,
CELL_MSGDIALOG_BUTTON_OK = 1,
CELL_MSGDIALOG_BUTTON_YES = 1,
CELL_MSGDIALOG_BUTTON_NO = 2,
CELL_MSGDIALOG_BUTTON_ESCAPE = 3,
};
enum CellMsgDialogType
{
CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000,
CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001,
CELL_MSGDIALOG_BUTTON_TYPE_NONE = 0x00000000,
CELL_MSGDIALOG_BUTTON_TYPE_YESNO = 0x00000010,
CELL_MSGDIALOG_DEFAULT_CURSOR_YES = 0x00000000,
CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100,
};
int cellMsgDialogOpen2(u32 type, u32 msgString_addr, u32 callback_addr, u32 userData, u32 extParam)
{
long style = 0;
if(type & CELL_MSGDIALOG_DIALOG_TYPE_NORMAL)
{
style |= wxICON_EXCLAMATION;
}
else
{
style |= wxICON_ERROR;
}
if(type & CELL_MSGDIALOG_BUTTON_TYPE_YESNO)
{
style |= wxYES_NO;
}
else
{
style |= wxOK;
}
int res = wxMessageBox(Memory.ReadString(msgString_addr), wxGetApp().GetAppName(), style);
u64 status;
switch(res)
{
case wxOK: status = CELL_MSGDIALOG_BUTTON_OK; break;
case wxYES: status = CELL_MSGDIALOG_BUTTON_YES; break;
case wxNO: status = CELL_MSGDIALOG_BUTTON_NO; break;
default:
if(res)
{
status = CELL_MSGDIALOG_BUTTON_INVALID;
break;
}
status = CELL_MSGDIALOG_BUTTON_NONE;
break;
}
Callback2 callback(0, callback_addr, userData);
callback.Handle(status);
callback.Branch();
return CELL_OK;
}

View File

@ -1,28 +1,18 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
int SysCalls::lv2TtyRead(PPUThread& CPU)
int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
{
const u32 ch = CPU.GPR[3];
const u64 buf_addr = CPU.GPR[4];
const u32 len = CPU.GPR[5];
const u64 preadlen_addr = CPU.GPR[6];
ConLog.Warning("lv2TtyRead: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
ConLog.Warning("sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
Memory.Write32NN(preadlen_addr, len);
return CELL_OK;
}
int SysCalls::lv2TtyWrite(PPUThread& CPU)
int sys_tty_write(u32 ch, u64 buf_addr, u32 len, u64 pwritelen_addr)
{
const u32 ch = CPU.GPR[3];
const u64 buf_addr = CPU.GPR[4];
const u32 len = CPU.GPR[5];
const u64 pwritelen_addr = CPU.GPR[6];
//for(uint i=0; i<32; ++i) ConLog.Write("r%d = 0x%llx", i, CPU.GPR[i]);
//ConLog.Warning("lv2TtyWrite: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
if(ch < 0 || ch > 15 || len <= 0) return CELL_EINVAL;
if(!Memory.IsGoodAddr(buf_addr)) return CELL_EINVAL;
if(!Memory.IsGoodAddr(buf_addr)) return CELL_EFAULT;
Emu.GetDbgCon().Write(ch, Memory.ReadString(buf_addr, len));
@ -31,4 +21,4 @@ int SysCalls::lv2TtyWrite(PPUThread& CPU)
Memory.Write32(pwritelen_addr, len);
return CELL_OK;
}
}

View File

@ -8,11 +8,11 @@ static const u64 timebase_frequency = 79800000;
int 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);
__timeb64 cur_time;
_ftime64_s(&cur_time);
Memory.Write64(sec_addr, cur_time.time);
Memory.Write64(nsec_addr, (u64)cur_time.millitm * 1000000);
u64 time = sys_time_get_system_time();
Memory.Write64(sec_addr, time / 1000000);
Memory.Write64(nsec_addr, time % 1000000);
return CELL_OK;
}

View File

@ -6,10 +6,11 @@
#include "Emu/Cell/PPCThreadManager.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Gui/CompilerELF.h"
#include "Emu/SysCalls/SysCalls.h"
using namespace PPU_opcodes;
SysCalls SysCallsManager;
//SysCalls SysCallsManager;
Emulator::Emulator()
: m_status(Stopped)
@ -55,7 +56,7 @@ void Emulator::CheckStatus()
}
if(IsAllPaused)
{
ConLog.Warning("all paused!");
//ConLog.Warning("all paused!");
Pause();
return;
}
@ -69,41 +70,41 @@ void Emulator::CheckStatus()
}
if(IsAllStoped)
{
ConLog.Warning("all stoped!");
//ConLog.Warning("all stoped!");
Pause(); //Stop();
}
}
void Emulator::Run()
void Emulator::Load()
{
if(IsRunned()) Stop();
if(IsPaused())
{
Resume();
return;
}
//ConLog.Write("run...");
m_status = Runned;
if(!wxFileExists(m_path)) return;
ConLog.Write("loading '%s'...", m_path);
Memory.Init();
GetInfo().Reset();
//SetTLSData(0, 0, 0);
//SetMallocPageSize(0x100000);
Loader l(m_path);
if(!l.Load())
Memory.Write64(Memory.PRXMem.Alloc(8), 0xDEADBEEFABADCAFE);
bool is_error;
vfsLocalFile f(m_path);
Loader l(f);
try
{
Memory.Close();
Stop();
return;
is_error = !l.Load() || l.GetMachine() == MACHINE_Unknown;
}
if(l.GetMachine() == MACHINE_Unknown)
catch(const wxString& e)
{
ConLog.Error(e);
is_error = true;
}
catch(...)
{
ConLog.Error("Unhandled loader error.");
is_error = true;
}
if(is_error)
{
ConLog.Error("Unknown machine type");
Memory.Close();
Stop();
return;
@ -111,38 +112,76 @@ void Emulator::Run()
PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64);
Memory.MainMem.Alloc(0x10000000, 0x10010000);
Memory.PRXMem.Write64(Memory.PRXMem.GetStartAddr(), 0xDEADBEEFABADCAFE);
thread.SetPc(l.GetEntry());
thread.SetEntry(l.GetEntry());
thread.SetArg(thread.GetId());
Memory.StackMem.Alloc(0x1000);
thread.InitStack();
thread.AddArgv(m_path);
//thread.AddArgv("-emu");
m_rsx_callback = Memory.MainMem.Alloc(0x10) + 4;
m_rsx_callback = Memory.MainMem.Alloc(4 * 4) + 4;
Memory.Write32(m_rsx_callback - 4, m_rsx_callback);
mem32_t callback_data(m_rsx_callback);
callback_data += ToOpcode(ADDI) | ToRD(11) | ToRA(0) | ToIMM16(0x3ff);
callback_data += ToOpcode(SC) | ToSYS(2);
callback_data += ToOpcode(G_13) | SetField(BCLR, 21, 30) | ToBO(0x10 | 0x04) | ToBI(0) | ToLK(0);
m_ppu_thr_exit = Memory.MainMem.Alloc(4 * 3);
mem32_t ppu_thr_exit_data(m_ppu_thr_exit);
ppu_thr_exit_data += ToOpcode(ADDI) | ToRD(11) | ToRA(0) | ToIMM16(41);
ppu_thr_exit_data += ToOpcode(SC) | ToSYS(2);
ppu_thr_exit_data += ToOpcode(G_13) | SetField(BCLR, 21, 30) | ToBO(0x10 | 0x04) | ToBI(0) | ToLK(0);
thread.Run();
wxGetApp().m_MainFrame->UpdateUI();
wxCriticalSectionLocker lock(m_cs_status);
m_status = Ready;
}
void Emulator::Run()
{
if(!IsReady())
{
Load();
if(!IsReady()) return;
}
if(IsRunned()) Stop();
if(IsPaused())
{
Resume();
return;
}
wxCriticalSectionLocker lock(m_cs_status);
//ConLog.Write("run...");
m_status = Runned;
m_vfs.Mount("/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
m_vfs.Mount("/dev_hdd0/", wxGetCwd() + "\\dev_hdd0\\", new vfsLocalFile());
m_vfs.Mount("/app_home/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
m_vfs.Mount(vfsDevice::GetRootPs3(m_path), vfsDevice::GetRoot(m_path), new vfsLocalFile());
for(uint i=0; i<m_vfs.m_devices.GetCount(); ++i) ConLog.Write("%s -> %s", m_vfs.m_devices[i].GetPs3Path(), m_vfs.m_devices[i].GetLocalPath());
//if(m_memory_viewer && m_memory_viewer->exit) safe_delete(m_memory_viewer);
//m_memory_viewer->SetPC(loader.GetEntry());
//m_memory_viewer->Show();
//m_memory_viewer->ShowPC();
wxGetApp().SendDbgCommand(DID_START_EMU);
wxGetApp().m_MainFrame->UpdateUI();
if(!m_dbg_console) m_dbg_console = new DbgConsole();
GetGSManager().Init();
GetCallbackManager().Init();
if(Ini.CPUDecoderMode.GetValue() != 1)
{
GetCPU().Start();
GetCPU().Exec();
}
GetCPU().Exec();
}
void Emulator::Pause()
@ -150,7 +189,9 @@ void Emulator::Pause()
if(!IsRunned()) return;
//ConLog.Write("pause...");
wxCriticalSectionLocker lock(m_cs_status);
m_status = Paused;
wxGetApp().SendDbgCommand(DID_PAUSE_EMU);
wxGetApp().m_MainFrame->UpdateUI();
}
@ -159,7 +200,9 @@ void Emulator::Resume()
if(!IsPaused()) return;
//ConLog.Write("resume...");
wxCriticalSectionLocker lock(m_cs_status);
m_status = Runned;
wxGetApp().SendDbgCommand(DID_RESUME_EMU);
wxGetApp().m_MainFrame->UpdateUI();
CheckStatus();
@ -170,16 +213,22 @@ void Emulator::Stop()
{
if(IsStopped()) return;
//ConLog.Write("shutdown...");
{
wxCriticalSectionLocker lock(m_cs_status);
m_status = Stopped;
}
m_rsx_callback = 0;
m_status = Stopped;
wxGetApp().SendDbgCommand(DID_STOP_EMU);
wxGetApp().m_MainFrame->UpdateUI();
GetGSManager().Close();
GetCPU().Close();
SysCallsManager.Close();
//SysCallsManager.Close();
GetIdManager().Clear();
GetPadManager().Close();
GetCallbackManager().Clear();
UnloadModules();
CurGameInfo.Reset();
Memory.Close();
@ -187,7 +236,7 @@ void Emulator::Stop()
if(m_dbg_console)
{
GetDbgCon().Close();
m_dbg_console = NULL;
GetDbgCon().Clear();
}
//if(m_memory_viewer && m_memory_viewer->IsShown()) m_memory_viewer->Hide();
}

View File

@ -3,9 +3,11 @@
#include "Gui/MemoryViewer.h"
#include "Emu/Cell/PPCThreadManager.h"
#include "Emu/Io/Pad.h"
#include "Emu/DbgConsole.h"
#include "Emu/GS/GSManager.h"
#include "Emu/FS/VFS.h"
#include "Emu/DbgConsole.h"
#include "Loader/Loader.h"
#include "SysCalls/Callback.h"
struct EmuInfo
{
@ -52,10 +54,12 @@ class Emulator
Interpreter,
};
mutable wxCriticalSection m_cs_status;
Status m_status;
uint m_mode;
u32 m_rsx_callback;
u32 m_ppu_thr_exit;
MemoryViewerPanel* m_memory_viewer;
//ArrayF<CPUThread> m_cpu_threads;
@ -64,6 +68,8 @@ class Emulator
IdManager m_id_manager;
DbgConsole* m_dbg_console;
GSManager m_gs_manager;
CallbackManager m_callback_manager;
VFS m_vfs;
EmuInfo m_info;
@ -74,14 +80,16 @@ public:
Emulator();
void Init();
virtual void SetSelf(const wxString& path);
virtual void SetElf(const wxString& path);
void SetSelf(const wxString& path);
void SetElf(const wxString& path);
PPCThreadManager& GetCPU() { return m_thread_manager; }
PadManager& GetPadManager() { return m_pad_manager; }
IdManager& GetIdManager() { return m_id_manager; }
DbgConsole& GetDbgCon() { return *m_dbg_console; }
GSManager& GetGSManager() { return m_gs_manager; }
PPCThreadManager& GetCPU() { return m_thread_manager; }
PadManager& GetPadManager() { return m_pad_manager; }
IdManager& GetIdManager() { return m_id_manager; }
DbgConsole& GetDbgCon() { return *m_dbg_console; }
GSManager& GetGSManager() { return m_gs_manager; }
CallbackManager& GetCallbackManager() { return m_callback_manager; }
VFS& GetVFS() { return m_vfs; }
void SetTLSData(const u64 addr, const u64 filesz, const u64 memsz)
{
@ -97,17 +105,20 @@ public:
u32 GetMallocPageSize() { return m_info.GetProcParam().malloc_pagesize; }
u32 GetRSXCallback() const { return m_rsx_callback; }
u32 GetPPUThreadExit() const { return m_ppu_thr_exit; }
void CheckStatus();
virtual void Run();
virtual void Pause();
virtual void Resume();
virtual void Stop();
void Load();
void Run();
void Pause();
void Resume();
void Stop();
virtual bool IsRunned() const { return m_status == Runned; }
virtual bool IsPaused() const { return m_status == Paused; }
virtual bool IsStopped() const { return m_status == Stopped; }
__forceinline bool IsRunned() const { wxCriticalSectionLocker lock(m_cs_status); return m_status == Runned; }
__forceinline bool IsPaused() const { wxCriticalSectionLocker lock(m_cs_status); return m_status == Paused; }
__forceinline bool IsStopped() const { wxCriticalSectionLocker lock(m_cs_status); return m_status == Stopped; }
__forceinline bool IsReady() const { wxCriticalSectionLocker lock(m_cs_status); return m_status == Ready; }
};
extern Emulator Emu;

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "CompilerELF.h"
using namespace PPU_opcodes;
void Write8(wxFile& f, const u8 data)
{
@ -33,44 +34,6 @@ wxFont GetFont(int size)
return wxFont(size, wxMODERN, wxNORMAL, wxNORMAL);
}
u32 SetField(u32 src, u32 from, u32 to)
{
return (src & ((1 << ((to - from) + 1)) - 1)) << (31 - to);
}
u32 SetField(s32 src, u32 p)
{
return (src & 0x1) << (31 - p);
}
u32 ToOpcode(u32 i) { return SetField(i, 0, 5); }
u32 ToRS(u32 i) { return SetField(i, 6, 10); }
u32 ToRD(u32 i) { return SetField(i, 6, 10); }
u32 ToRA(u32 i) { return SetField(i, 11, 15); }
u32 ToRB(u32 i) { return SetField(i, 16, 20); }
u32 ToLL(u32 i) { return i & 0x03fffffc; }
u32 ToAA(u32 i) { return SetField(i, 30); }
u32 ToLK(u32 i) { return SetField(i, 31); }
u32 ToIMM16(s32 i) { return SetField(i, 16, 31); }
u32 ToD(s32 i) { return SetField(i, 16, 31); }
u32 ToDS(s32 i)
{
if(i < 0) return ToD(i + 1);
return ToD(i);
}
u32 ToSYS(u32 i) { return SetField(i, 6, 31); }
u32 ToBF(u32 i) { return SetField(i, 6, 10); }
u32 ToBO(u32 i) { return SetField(i, 6, 10); }
u32 ToBI(u32 i) { return SetField(i, 11, 15); }
u32 ToBD(u32 i) { return i & 0xfffc; }
u32 ToMB(u32 i) { return SetField(i, 21, 25); }
u32 ToME(u32 i) { return SetField(i, 26, 30); }
u32 ToSH(u32 i) { return SetField(i, 16, 20); }
u32 ToRC(u32 i) { return SetField(i, 31); }
u32 ToOE(u32 i) { return SetField(i, 21); }
u32 ToL(u32 i) { return SetField(i, 10); }
u32 ToCRFD(u32 i) { return SetField(i, 6, 8); }
struct InstrField
{
u32 (*To)(u32 i);
@ -90,6 +53,8 @@ enum MASKS
MASK_LL,
MASK_RA_RS_SH_MB_ME,
MASK_RA_RS_RB_MB_ME,
MASK_RA_RS_RB,
MASK_RD_RA_RB,
MASK_RST_RA_D,
MASK_RST_RA_DS,
MASK_TO_RA_IMM16,
@ -126,92 +91,119 @@ static const struct Instruction
{
MASKS mask;
wxString name;
u32 op_num;
u32 op_g;
u32 op;
struct
{
u32 op;
u32 from;
u32 to;
} subop;
u32 smask;
u32 bo;
u32 bi;
} m_instructions[] =
{
{MASK_NO_ARG, "nop", ORI, 0, SMASK_NULL},
{MASK_TO_RA_IMM16, "tdi", TDI, 0, SMASK_NULL},
{MASK_TO_RA_IMM16, "twi", TWI, 0, SMASK_NULL},
{MASK_NO_ARG, "nop", ORI, {0}, SMASK_NULL},
{MASK_TO_RA_IMM16, "tdi", TDI, {0}, SMASK_NULL},
{MASK_TO_RA_IMM16, "twi", TWI, {0}, SMASK_NULL},
//G_04 = 0x04,
{MASK_RSD_RA_IMM16, "mulli", MULLI, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "subfic", SUBFIC, 0, SMASK_NULL},
{MASK_CRFD_RA_IMM16, "cmplwi", CMPLI, 0, SMASK_NULL},
{MASK_CRFD_RA_IMM16, "cmpldi", CMPLI, 0, SMASK_L},
{MASK_CRFD_RA_IMM16, "cmpwi", CMPI, 0, SMASK_NULL},
{MASK_CRFD_RA_IMM16, "cmpdi", CMPI, 0, SMASK_L},
{MASK_RSD_RA_IMM16, "addic", ADDIC, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "addic.", ADDIC_, 0, SMASK_RC},
{MASK_RSD_RA_IMM16, "addi", ADDI, 0, SMASK_NULL},
{MASK_RSD_IMM16, "li", ADDI, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "addis", ADDIS, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "mulli", MULLI, {0}, SMASK_NULL},
{MASK_RSD_RA_IMM16, "subfic", SUBFIC, {0}, SMASK_NULL},
{MASK_CRFD_RA_IMM16, "cmplwi", CMPLI, {0}, SMASK_NULL},
{MASK_CRFD_RA_IMM16, "cmpldi", CMPLI, {0}, SMASK_L},
{MASK_CRFD_RA_IMM16, "cmpwi", CMPI, {0}, SMASK_NULL},
{MASK_CRFD_RA_IMM16, "cmpdi", CMPI, {0}, SMASK_L},
{MASK_RSD_RA_IMM16, "addic", ADDIC, {0}, SMASK_NULL},
{MASK_RSD_RA_IMM16, "addic.", ADDIC_, {0}, SMASK_RC},
{MASK_RSD_RA_IMM16, "addi", ADDI, {0}, SMASK_NULL},
{MASK_RSD_IMM16, "li", ADDI, {0}, SMASK_NULL},
{MASK_RSD_RA_IMM16, "addis", ADDIS, {0}, SMASK_NULL},
{MASK_BO_BI_BD, "bc", BC, 0, SMASK_NULL},
{MASK_BO_BI_BD, "bca", BC, 0, SMASK_AA},
{MASK_BO_BI_BD, "bcl", BC, 0, SMASK_LK},
{MASK_BO_BI_BD, "bcla", BC, 0, SMASK_AA | SMASK_LK},
{MASK_BI_BD, "bdz", BC, 0, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO3},
{MASK_BI_BD, "bdz-", BC, 0, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1 | BO_MASK_BO3},
{MASK_BI_BD, "bdz+", BC, 0, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1 | BO_MASK_BO3 | BO_MASK_BO4},
{MASK_BI_BD, "bdnz", BC, 0, SMASK_BO, BO_MASK_BO0},
{MASK_BI_BD, "bdnz-", BC, 0, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1},
{MASK_BI_BD, "bdnz+", BC, 0, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1 | BO_MASK_BO4},
{MASK_BI_BD, "bge", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2, BI_GE},
{MASK_BI_BD, "ble", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2, BI_LE},
{MASK_BI_BD, "bne", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2, BI_NE},
{MASK_BI_BD, "bge-", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3, BI_GE},
{MASK_BI_BD, "ble-", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3, BI_LE},
{MASK_BI_BD, "bne-", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3, BI_NE},
{MASK_BI_BD, "bge+", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_GE},
{MASK_BI_BD, "ble+", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_LE},
{MASK_BI_BD, "bne+", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_NE},
{MASK_BI_BD, "bgt", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2, BI_GT},
{MASK_BI_BD, "blt", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2, BI_LT},
{MASK_BI_BD, "beq", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2, BI_EQ},
{MASK_BI_BD, "bgt-", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3, BI_GT},
{MASK_BI_BD, "blt-", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3, BI_LT},
{MASK_BI_BD, "beq-", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3, BI_EQ},
{MASK_BI_BD, "bgt+", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_GT},
{MASK_BI_BD, "blt+", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_LT},
{MASK_BI_BD, "beq+", BC, 0, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_EQ},
{MASK_BO_BI_BD, "bc", BC, {0}, SMASK_NULL},
{MASK_BO_BI_BD, "bca", BC, {0}, SMASK_AA},
{MASK_BO_BI_BD, "bcl", BC, {0}, SMASK_LK},
{MASK_BO_BI_BD, "bcla", BC, {0}, SMASK_AA | SMASK_LK},
{MASK_BI_BD, "bdz", BC, {0}, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO3},
{MASK_BI_BD, "bdz-", BC, {0}, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1 | BO_MASK_BO3},
{MASK_BI_BD, "bdz+", BC, {0}, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1 | BO_MASK_BO3 | BO_MASK_BO4},
{MASK_BI_BD, "bdnz", BC, {0}, SMASK_BO, BO_MASK_BO0},
{MASK_BI_BD, "bdnz-", BC, {0}, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1},
{MASK_BI_BD, "bdnz+", BC, {0}, SMASK_BO, BO_MASK_BO0 | BO_MASK_BO1 | BO_MASK_BO4},
{MASK_BI_BD, "bge", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2, BI_GE},
{MASK_BI_BD, "ble", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2, BI_LE},
{MASK_BI_BD, "bne", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2, BI_NE},
{MASK_BI_BD, "bge-", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3, BI_GE},
{MASK_BI_BD, "ble-", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3, BI_LE},
{MASK_BI_BD, "bne-", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3, BI_NE},
{MASK_BI_BD, "bge+", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_GE},
{MASK_BI_BD, "ble+", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_LE},
{MASK_BI_BD, "bne+", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_NE},
{MASK_BI_BD, "bgt", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2, BI_GT},
{MASK_BI_BD, "blt", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2, BI_LT},
{MASK_BI_BD, "beq", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2, BI_EQ},
{MASK_BI_BD, "bgt-", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3, BI_GT},
{MASK_BI_BD, "blt-", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3, BI_LT},
{MASK_BI_BD, "beq-", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3, BI_EQ},
{MASK_BI_BD, "bgt+", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_GT},
{MASK_BI_BD, "blt+", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_LT},
{MASK_BI_BD, "beq+", BC, {0}, SMASK_BO | SMASK_BI, BO_MASK_BO1 | BO_MASK_BO2 | BO_MASK_BO3 | BO_MASK_BO4, BI_EQ},
{MASK_SYS, "sc", SC, 0, SMASK_NULL},
{MASK_LL, "b", B, 0, SMASK_NULL},
{MASK_LL, "ba", B, 0, SMASK_AA},
{MASK_LL, "bl", B, 0, SMASK_LK},
{MASK_LL, "bla", B, 0, SMASK_AA | SMASK_LK},
{MASK_SYS, "sc", SC, {0}, SMASK_NULL},
{MASK_LL, "b", B, {0}, SMASK_NULL},
{MASK_LL, "ba", B, {0}, SMASK_AA},
{MASK_LL, "bl", B, {0}, SMASK_LK},
{MASK_LL, "bla", B, {0}, SMASK_AA | SMASK_LK},
//G_13 = 0x13,
{MASK_RA_RS_SH_MB_ME, "rlwimi", RLWIMI, 0, SMASK_NULL},
{MASK_RA_RS_SH_MB_ME, "rlwimi.", RLWIMI, 0, SMASK_RC},
{MASK_RA_RS_SH_MB_ME, "rlwinm", RLWINM, 0, SMASK_NULL},
{MASK_RA_RS_SH_MB_ME, "rlwinm.", RLWINM, 0, SMASK_RC},
{MASK_RA_RS_RB_MB_ME, "rlwnm", RLWNM, 0, SMASK_NULL},
{MASK_RA_RS_RB_MB_ME, "rlwnm.", RLWNM, 0, SMASK_RC},
{MASK_RSD_RA_IMM16, "ori", ORI, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "oris", ORIS, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "xori", XORI, 0, SMASK_NULL},
{MASK_RSD_RA_IMM16, "xoris", XORIS, 0, SMASK_NULL},
{MASK_RA_RST_IMM16, "andi.", ANDI_, 0, SMASK_RC},
{MASK_RA_RST_IMM16, "andis.", ANDIS_, 0, SMASK_RC},
{MASK_RA_RS_SH_MB_ME, "rlwimi", RLWIMI, {0}, SMASK_NULL},
{MASK_RA_RS_SH_MB_ME, "rlwimi.", RLWIMI, {0}, SMASK_RC},
{MASK_RA_RS_SH_MB_ME, "rlwinm", RLWINM, {0}, SMASK_NULL},
{MASK_RA_RS_SH_MB_ME, "rlwinm.", RLWINM, {0}, SMASK_RC},
{MASK_RA_RS_RB_MB_ME, "rlwnm", RLWNM, {0}, SMASK_NULL},
{MASK_RA_RS_RB_MB_ME, "rlwnm.", RLWNM, {0}, SMASK_RC},
{MASK_RSD_RA_IMM16, "ori", ORI, {0}, SMASK_NULL},
{MASK_RSD_RA_IMM16, "oris", ORIS, {0}, SMASK_NULL},
{MASK_RSD_RA_IMM16, "xori", XORI, {0}, SMASK_NULL},
{MASK_RSD_RA_IMM16, "xoris", XORIS, {0}, SMASK_NULL},
{MASK_RA_RST_IMM16, "andi.", ANDI_, {0}, SMASK_RC},
{MASK_RA_RST_IMM16, "andis.", ANDIS_, {0}, SMASK_RC},
//G_1e = 0x1e,
//G_1f = 0x1f,
{MASK_RST_RA_D, "lwz", LWZ, 0, SMASK_NULL},
{MASK_RST_RA_D, "lwzu", LWZU, 0, SMASK_NULL},
{MASK_RST_RA_D, "lbz", LBZ, 0, SMASK_NULL},
{MASK_RST_RA_D, "lbzu", LBZU, 0, SMASK_NULL},
{MASK_RST_RA_D, "stw", STW, 0, SMASK_NULL},
{MASK_RST_RA_D, "stwu", STWU, 0, SMASK_NULL},
{MASK_RST_RA_D, "stb", STB, 0, SMASK_NULL},
{MASK_RST_RA_D, "stbu", STBU, 0, SMASK_NULL},
{MASK_RST_RA_D, "lhz", LHZ, 0, SMASK_NULL},
{MASK_RST_RA_D, "lhzu", LHZU, 0, SMASK_NULL},
{MASK_RST_RA_D, "lha", LHA, 0, SMASK_NULL},
{MASK_RST_RA_D, "lhau", LHAU, 0, SMASK_NULL},
{MASK_RST_RA_D, "sth", STH, 0, SMASK_NULL},
{MASK_RD_RA_RB, "lwarx", G_1f, {LWARX, 21, 30}, SMASK_NULL},
{MASK_RA_RS_RB, "ldx", G_1f, {LDX, 21, 30}, SMASK_NULL},
{MASK_RA_RS_RB, "slw", G_1f, {SLW, 21, 30}, SMASK_NULL},
{MASK_RA_RS_RB, "slw.", G_1f, {SLW, 21, 30}, SMASK_RC},
{MASK_RA_RS_RB, "sld", G_1f, {SLD, 21, 30}, SMASK_NULL},
{MASK_RA_RS_RB, "sld.", G_1f, {SLD, 21, 30}, SMASK_RC},
{MASK_RA_RS_RB, "and", G_1f, {AND, 21, 30}, SMASK_NULL},
{MASK_RA_RS_RB, "and.", G_1f, {AND, 21, 30}, SMASK_RC},
{MASK_RD_RA_RB, "subf", G_1f, {SUBF, 21, 30}, SMASK_NULL},
{MASK_RD_RA_RB, "subf.", G_1f, {SUBF, 21, 30}, SMASK_RC},
{MASK_RD_RA_RB, "subfo", G_1f, {SUBF, 21, 30}, SMASK_OE},
{MASK_RD_RA_RB, "subfo.", G_1f, {SUBF, 21, 30}, SMASK_OE | SMASK_RC},
{MASK_RA_RS_RB, "andc", G_1f, {ANDC, 21, 30}, SMASK_NULL},
{MASK_RA_RS_RB, "andc.", G_1f, {ANDC, 21, 30}, SMASK_RC},
{MASK_RD_RA_RB, "mulhd", G_1f, {MULHD, 21, 30}, SMASK_NULL},
{MASK_RD_RA_RB, "mulhd.", G_1f, {MULHD, 21, 30}, SMASK_RC},
{MASK_RD_RA_RB, "mulhw", G_1f, {MULHW, 21, 30}, SMASK_NULL},
{MASK_RD_RA_RB, "mulhw.", G_1f, {MULHW, 21, 30}, SMASK_RC},
{MASK_RD_RA_RB, "ldarx", G_1f, {LDARX, 21, 30}, SMASK_NULL},
{MASK_RD_RA_RB, "lbzx", G_1f, {LBZX, 21, 30}, SMASK_NULL},
{MASK_RST_RA_D, "lwz", LWZ, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lwzu", LWZU, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lbz", LBZ, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lbzu", LBZU, {0}, SMASK_NULL},
{MASK_RST_RA_D, "stw", STW, {0}, SMASK_NULL},
{MASK_RST_RA_D, "stwu", STWU, {0}, SMASK_NULL},
{MASK_RST_RA_D, "stb", STB, {0}, SMASK_NULL},
{MASK_RST_RA_D, "stbu", STBU, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lhz", LHZ, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lhzu", LHZU, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lha", LHA, {0}, SMASK_NULL},
{MASK_RST_RA_D, "lhau", LHAU, {0}, SMASK_NULL},
{MASK_RST_RA_D, "sth", STH, {0}, SMASK_NULL},
//{0, "lmw", LMW, 0, false, false},
//LFS = 0x30,
//LFSU = 0x31,
@ -225,8 +217,8 @@ static const struct Instruction
//G_3b = 0x3b,
//G_3e = 0x3e,
//G_3f = 0x3f,
{MASK_UNK, "unk", 0, 0, SMASK_NULL},
}, m_error_instr = {MASK_ERROR, "err", 0, 0, SMASK_ERROR};
{MASK_UNK, "unk", 0, {0}, SMASK_NULL},
}, m_error_instr = {MASK_ERROR, "err", 0, {0}, SMASK_ERROR};
static const u32 instr_count = WXSIZEOF(m_instructions);
enum ArgType
@ -271,6 +263,8 @@ Instruction GetInstruction(const wxString& str)
u32 CompileInstruction(Instruction instr, Array<Arg>& arr)
{
if(instr.mask == MASK_ERROR) return 0;
u32 code =
ToOE(instr.smask & SMASK_OE) | ToRC(instr.smask & SMASK_RC) |
ToAA(instr.smask & SMASK_AA) | ToLK(instr.smask & SMASK_LK) |
@ -279,7 +273,9 @@ u32 CompileInstruction(Instruction instr, Array<Arg>& arr)
if(instr.smask & SMASK_BO) code |= ToBO(instr.bo);
if(instr.smask & SMASK_BI) code |= ToBI(instr.bi);
code |= ToOpcode(instr.op_num);
code |= ToOpcode(instr.op);
if(instr.subop.from < instr.subop.to) code |= SetField(instr.subop.op, instr.subop.from, instr.subop.to);
switch(instr.mask)
{
@ -299,10 +295,18 @@ u32 CompileInstruction(Instruction instr, Array<Arg>& arr)
return code | ToLL(arr[0].value);
case MASK_RA_RS_SH_MB_ME:
return code | ToRA(arr[0].value) | ToRS(arr[1].value) | ToSH(arr[2].value) | ToMB(arr[3].value) | ToME(arr[4].value);
case MASK_RA_RS_RB_MB_ME:
return code | ToRA(arr[0].value) | ToRS(arr[1].value) | ToRB(arr[2].value) | ToMB(arr[3].value) | ToME(arr[4].value);
case MASK_RA_RS_RB:
return code | ToRA(arr[0].value) | ToRS(arr[1].value) | ToRB(arr[2].value);
case MASK_RD_RA_RB:
return code | ToRD(arr[0].value) | ToRA(arr[1].value) | ToRB(arr[2].value);
case MASK_RST_RA_D:
return code | ToRS(arr[0].value) | ToRA(arr[1].value) | ToD(arr[2].value);
case MASK_RST_RA_DS:
return code | ToRS(arr[0].value) | ToRA(arr[1].value) | ToDS(arr[2].value);
case MASK_TO_RA_IMM16:
return code | ToTO(arr[0].value) | ToRA(arr[1].value) | ToIMM16(arr[2].value);
case MASK_RSD_IMM16:
return code | ToRS(arr[0].value) | ToIMM16(arr[1].value);
@ -417,78 +421,46 @@ CompilerELF::CompilerELF(wxWindow* parent)
asm_list->SetFont(wxFont(-1, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
hex_list->SetFont(wxFont(-1, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
wxGetApp().Connect(wxEVT_SCROLLWIN_TOP, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
wxGetApp().Connect(wxEVT_SCROLLWIN_BOTTOM, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
wxGetApp().Connect(wxEVT_SCROLLWIN_LINEUP, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
wxGetApp().Connect(wxEVT_SCROLLWIN_LINEDOWN, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
wxGetApp().Connect(wxEVT_SCROLLWIN_THUMBTRACK, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
wxGetApp().Connect(wxEVT_SCROLLWIN_THUMBRELEASE,wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_SCROLLWIN_TOP, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_SCROLLWIN_BOTTOM, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_SCROLLWIN_LINEUP, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_SCROLLWIN_LINEDOWN, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_SCROLLWIN_THUMBTRACK, wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_SCROLLWIN_THUMBRELEASE,wxScrollWinEventHandler(CompilerELF::OnScroll), (wxObject*)0, this);
wxGetApp().Connect(asm_list->GetId(), wxEVT_MOUSEWHEEL, wxMouseEventHandler(CompilerELF::MouseWheel), (wxObject*)0, this);
wxGetApp().Connect(hex_list->GetId(), wxEVT_MOUSEWHEEL, wxMouseEventHandler(CompilerELF::MouseWheel), (wxObject*)0, this);
m_app_connector.Connect(asm_list->GetId(), wxEVT_MOUSEWHEEL, wxMouseEventHandler(CompilerELF::MouseWheel), (wxObject*)0, this);
m_app_connector.Connect(hex_list->GetId(), wxEVT_MOUSEWHEEL, wxMouseEventHandler(CompilerELF::MouseWheel), (wxObject*)0, this);
wxGetApp().Connect(asm_list->GetId(), wxEVT_KEY_DOWN, wxKeyEventHandler(CompilerELF::OnKeyDown), (wxObject*)0, this);
wxGetApp().Connect(hex_list->GetId(), wxEVT_KEY_DOWN, wxKeyEventHandler(CompilerELF::OnKeyDown), (wxObject*)0, this);
m_app_connector.Connect(asm_list->GetId(), wxEVT_KEY_DOWN, wxKeyEventHandler(CompilerELF::OnKeyDown), (wxObject*)0, this);
m_app_connector.Connect(hex_list->GetId(), wxEVT_KEY_DOWN, wxKeyEventHandler(CompilerELF::OnKeyDown), (wxObject*)0, this);
asm_list->WriteText(
"[sysPrxForUser, sys_initialize_tls, 0x744680a2]\n"
"[sysPrxForUser, sys_process_exit, 0xe6f2c1e7]\n"
"[sys_fs, cellFsOpen, 0x718bf5f8]\n"
"[sys_fs, cellFsClose, 0x2cb51f0d]\n"
"[sys_fs, cellFsRead, 0x4d5ff8e2]\n"
"[sys_fs, cellFsWrite, 0xecdcf2ab]\n"
"[sys_fs, cellFsLseek, 0xa397d042]\n"
"[sys_fs, cellFsMkdir, 0xba901fe6]\n"
"\n"
".int [flags, 577] #LV2_O_WRONLY | LV2_O_CREAT | LV2_O_TRUNC\n"
".string [path, \"dev_hdd0/game/TEST12345/USRDIR/test.txt\"]\n"
".string [str, \"Hello World!\"]\n"
".int [sys_tty_write, 0x193]\n"
".int [sys_process_exit, 0x003]\n"
".string [str, \"Hello World!\\n\"]\n"
".strlen [str_len, str]\n"
".buf [fd, 8]\n"
"\n"
".srr [fd_hi, fd, 16]\n"
".and [fd_lo, fd, 0xffff]\n"
"\n"
".srr [path_hi, path, 16]\n"
".and [path_lo, path, 0xffff]\n"
".buf [ret, 8]\n"
"\n"
".srr [str_hi, str, 16]\n"
".and [str_lo, str, 0xffff]\n"
"\n"
"\tbl \tsys_initialize_tls\n"
".srr [ret_hi, str, 16]\n"
".and [ret_lo, str, 0xffff]\n"
"\n"
"\tli \tr3, path_lo\n"
"\toris \tr3, r3, path_hi\n"
"\tli \tr4, flags\n"
"\tli \tr5, fd_lo\n"
"\toris \tr5, r5, fd_hi\n"
"\tli \tr6, 0\n"
"\tli \tr7, 0\n"
"\tbl \tcellFsOpen\n"
"\tcmpwi \tcr7, r3, 0\n"
"\tblt- \tcr7, exit_err\n"
"\n"
"\tli \tr3, fd_lo\n"
"\toris \tr3, r3, fd_hi\n"
"\tlwz \tr3, r3, 0\n"
"\tli \tr4, str_lo\n"
"\toris \tr4, r4, str_hi\n"
"\tli \tr5, str_len\n"
"\tli \tr6, 0\n"
"\tbl \tcellFsWrite\n"
"\tcmpwi \tcr7, r3, 0\n"
"\tblt- \tcr7, exit_err\n"
"\n"
"\tli \tr3, fd_lo\n"
"\toris \tr3, r3, fd_hi\n"
"\tlwz \tr3, r3, 0\n"
"\tbl \tcellFsClose\n"
"\tcmpwi \tcr7, r3, 0\n"
"\tblt- \tcr7, exit_err\n"
" li r3, 0\n"
" li r4, str_lo\n"
" oris r4, r4, str_hi\n"
" li r5, str_len\n"
" li r6, ret_lo\n"
" oris r6, r6, ret_hi\n"
" li r11, sys_tty_write\n"
" sc\n"
" cmpwi cr7, r3, 0\n"
" bne- cr7, exit_err\n"
"\n"
"exit_ok:\n"
"\tli \tr3, 0\n"
"\tb \texit\n"
" li r3, 0\n"
" b exit\n"
"\n"
"exit_err:\n"
".string [str, \"error.\\n\"]\n"
@ -497,21 +469,21 @@ CompilerELF::CompilerELF(wxWindow* parent)
".strlen [str_len, str]\n"
".int [written_len_lo, fd_lo]\n"
".int [written_len_hi, fd_hi]\n"
"\tli \tr3, 1\n"
"\tli \tr4, str_lo\n"
"\toris \tr4, r4, str_hi\n"
"\tli \tr5, str_len\n"
"\tli \tr6, written_len_lo\n"
"\toris \tr6, r6, written_len_hi\n"
"\tli \tr11, 403\n"
"\tsc\n"
"\tli \tr3, 1\n"
"\tb \texit\n"
" li r3, 1\n"
" li r4, str_lo\n"
" oris r4, r4, str_hi\n"
" li r5, str_len\n"
" li r6, written_len_lo\n"
" oris r6, r6, written_len_hi\n"
" li r11, sys_tty_write\n"
" sc\n"
" li r3, 1\n"
"\n"
"exit:\n"
"\tbl \tsys_process_exit\n"
"\tli \tr3, 1\n"
"\tb \texit\n"
" li r11, sys_process_exit\n"
" sc\n"
" li r3, 1\n"
" b exit\n"
);
::SendMessage((HWND)hex_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0);
@ -685,6 +657,8 @@ void CompilerELF::OnUpdate(wxCommandEvent& event)
void CompilerELF::OnScroll(wxScrollWinEvent& event)
{
if(!m_aui_mgr.GetManagedWindow()) return;
const int id = event.GetEventObject() ? ((wxScrollBar*)event.GetEventObject())->GetId() : -1;
wxTextCtrl* src = NULL;
@ -960,13 +934,12 @@ struct CompileProgram
return false;
}
bool GetArg(wxString& result, bool func = false)
int GetArg(wxString& result, bool func = false)
{
s64 from = -1;
for(;;)
for(char cur_char = NextChar(); !m_error; cur_char = NextChar())
{
const char cur_char = NextChar();
const bool skip = IsSkip(cur_char);
const bool commit = IsCommit(cur_char);
const bool endln = IsEndLn(cur_char);
@ -976,7 +949,7 @@ struct CompileProgram
if(from == -1)
{
if(endln || commit || end) return false;
if(endln || commit || end) return 0;
if(!skip) from = p - 1;
continue;
}
@ -984,7 +957,7 @@ struct CompileProgram
const bool text = m_asm[from] == '"';
const bool end_text = cur_char == '"';
if((text ? end_text : skip || commit || end) || endln)
if((text ? end_text : (skip || commit || end)) || endln)
{
if(text && p > 2 && m_asm[p - 2] == '\\' && (p <= 3 || m_asm[p - 3] != '\\'))
{
@ -997,14 +970,13 @@ struct CompileProgram
m_error = true;
}
const s64 to = (endln || text ? p : p - 1) - from;
bool ret = true;
const s64 to = ((endln || text) ? p : p - 1) - from;
int ret = 1;
if(skip || text)
{
for(;;)
for(char cur_char = NextChar(); !m_error; cur_char = NextChar())
{
const char cur_char = NextChar();
const bool skip = IsSkip(cur_char);
const bool commit = IsCommit(cur_char);
const bool endln = IsEndLn(cur_char);
@ -1015,20 +987,20 @@ struct CompileProgram
if(commit)
{
ret = false;
EndLn();
ret = -1;
break;
}
if(endln)
{
ret = false;
p--;
break;
}
WriteError(wxString::Format("Bad symbol '%c'", cur_char));
m_error = true;
break;
}
}
@ -1059,11 +1031,19 @@ struct CompileProgram
return ret;
}
}
return 0;
}
bool CheckEnd(bool show_err = true)
{
for(;;)
if(m_error)
{
NextLn();
return false;
}
while(true)
{
const char cur_char = NextChar();
const bool skip = IsSkip(cur_char);
@ -1266,14 +1246,15 @@ struct CompileProgram
m_cur_arg = 0;
wxString str;
while(GetArg(str))
while(int r = GetArg(str))
{
Arg arg(str);
DetectArgInfo(arg);
m_args.AddCpy(arg);
Arg* arg = new Arg(str);
DetectArgInfo(*arg);
m_args.Add(arg);
if(r == -1) break;
}
m_end_args = true;
m_end_args = m_args.GetCount() > 0;
}
u32 GetBranchValue(const wxString& branch)
@ -1444,7 +1425,7 @@ struct CompileProgram
{
if(create)
{
m_branches.Add(new Branch(name, -1, addr));
m_branches.Move(new Branch(name, -1, addr));
return;
}
@ -1500,7 +1481,7 @@ struct CompileProgram
case ARG_ERR:
{
m_branches.Add(new Branch(wxEmptyString, -1, 0));
m_branches.Move(new Branch(wxEmptyString, -1, 0));
dst_branch = &m_branches[m_branches.GetCount() - 1];
}
break;
@ -1579,7 +1560,7 @@ struct CompileProgram
if(!founded)
{
const u32 addr = s_opd.sh_addr + s_opd.sh_size;
m_sp_string.Add(new SpData(src1, addr));
m_sp_string.Move(new SpData(src1, addr));
s_opd.sh_size += src1.Len() + 1;
*dst_branch = Branch(dst, -1, addr);
}
@ -1879,7 +1860,7 @@ struct CompileProgram
if(!CheckEnd()) continue;
m_branches.Add(new Branch(name, a_id.value, 0));
m_branches.Move(new Branch(name, a_id.value, 0));
const u32 import = m_branches.GetCount() - 1;
bool founded = false;
@ -1891,7 +1872,7 @@ struct CompileProgram
break;
}
if(!founded) modules.Add(new Module(module, import));
if(!founded) modules.Move(new Module(module, import));
}
u32 imports_count = 0;
@ -2117,7 +2098,7 @@ struct CompileProgram
if(m_error) break;
m_branches.Add(new Branch(name, m_branch_pos));
m_branches.Move(new Branch(name, m_branch_pos));
CheckEnd();
continue;
@ -2136,7 +2117,7 @@ struct CompileProgram
break;
}
if(!has_entry) m_branches.Add(new Branch("entry", 0));
if(!has_entry) m_branches.Move(new Branch("entry", 0));
if(m_analyze) m_error = false;
FirstChar();
@ -2202,7 +2183,7 @@ struct CompileProgram
break;
case ARG_REG_R:
m_args.InsertCpy(0, Arg("cr0", 0, ARG_REG_CR));
m_args.Move(0, new Arg("cr0", 0, ARG_REG_CR));
break;
}
}
@ -2219,13 +2200,13 @@ struct CompileProgram
case MASK_BI_BD:
if(!SetNextArgType(ARG_REG_CR, false))
{
m_args.InsertCpy(0, Arg("cr0", 0, ARG_REG_CR));
m_args.Move(0, new Arg("cr0", 0, ARG_REG_CR));
}
SetNextArgBranch(instr.smask & SMASK_AA);
break;
case MASK_SYS:
if(!SetNextArgType(ARG_IMM, false)) m_args.AddCpy(Arg("2", 2, ARG_IMM));
if(!SetNextArgType(ARG_IMM, false)) m_args.Move(new Arg("2", 2, ARG_IMM));
break;
case MASK_LL:
@ -2248,6 +2229,18 @@ struct CompileProgram
SetNextArgType(ARG_IMM);
break;
case MASK_RA_RS_RB:
SetNextArgType(ARG_REG_R);
SetNextArgType(ARG_REG_R);
SetNextArgType(ARG_REG_R);
break;
case MASK_RD_RA_RB:
SetNextArgType(ARG_REG_R);
SetNextArgType(ARG_REG_R);
SetNextArgType(ARG_REG_R);
break;
case MASK_RST_RA_D:
SetNextArgType(ARG_REG_R);
SetNextArgType(ARG_REG_R);
@ -2527,7 +2520,7 @@ struct CompileProgram
WritePhdr(f, p_loos_2);
sections_names.Clear();
free(opd_data);
delete[] opd_data;
for(u32 i=0; i<modules.GetCount(); ++i) modules[i].Clear();
modules.Clear();
}

Some files were not shown because too many files have changed in this diff Show More