2014-07-04 01:55:09 -04:00
|
|
|
#pragma once
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2006-08-20 03:08:17 +00:00
|
|
|
#include <string>
|
2012-03-11 20:06:14 +00:00
|
|
|
#include <boost/signals2.hpp>
|
2006-06-15 04:19:30 +00:00
|
|
|
#include "ELF.h"
|
|
|
|
#include "MIPS.h"
|
2007-12-01 04:08:34 +00:00
|
|
|
#include "GSHandler.h"
|
2008-01-12 01:27:04 +00:00
|
|
|
#include "SIF.h"
|
2012-05-24 05:57:31 +00:00
|
|
|
#include "BiosDebugInfoProvider.h"
|
2015-01-28 03:32:18 -05:00
|
|
|
#include "OsStructManager.h"
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2008-01-19 03:36:27 +00:00
|
|
|
class CIopBios;
|
|
|
|
|
2012-05-24 05:57:31 +00:00
|
|
|
class CPS2OS : public CBiosDebugInfoProvider
|
2006-06-15 04:19:30 +00:00
|
|
|
{
|
|
|
|
public:
|
2012-04-14 21:08:33 +00:00
|
|
|
typedef std::vector<std::string> ArgumentList;
|
|
|
|
|
|
|
|
typedef boost::signals2::signal<void (const char*, const ArgumentList&)> RequestLoadExecutableEvent;
|
|
|
|
|
2015-01-31 23:05:56 -05:00
|
|
|
CPS2OS(CMIPS&, uint8*, uint8*, uint8*, CGSHandler*&, CSIF&, CIopBios&);
|
2012-03-11 20:06:14 +00:00
|
|
|
virtual ~CPS2OS();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
void Initialize();
|
|
|
|
void Release();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2011-05-08 21:58:55 +00:00
|
|
|
bool IsIdle() const;
|
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
void DumpIntcHandlers();
|
|
|
|
void DumpDmacHandlers();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
void BootFromFile(const char*);
|
2012-04-14 21:08:33 +00:00
|
|
|
void BootFromCDROM(const ArgumentList&);
|
2012-03-11 20:06:14 +00:00
|
|
|
CELF* GetELF();
|
|
|
|
const char* GetExecutableName() const;
|
2011-10-21 19:01:59 +00:00
|
|
|
std::pair<uint32, uint32> GetExecutableRange() const;
|
2012-10-24 06:39:29 +00:00
|
|
|
uint32 LoadExecutable(const char*, const char*);
|
|
|
|
|
2014-06-04 23:37:40 -04:00
|
|
|
void HandleInterrupt();
|
|
|
|
void HandleSyscall();
|
|
|
|
void HandleReturnFromException();
|
|
|
|
|
2012-04-16 02:34:36 +00:00
|
|
|
static uint32 TranslateAddress(CMIPS*, uint32);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2014-07-04 01:55:09 -04:00
|
|
|
#ifdef DEBUGGER_INCLUDED
|
2014-07-04 02:18:14 -04:00
|
|
|
BiosDebugModuleInfoArray GetModulesDebugInfo() const override;
|
|
|
|
BiosDebugThreadInfoArray GetThreadsDebugInfo() const override;
|
2014-07-04 01:55:09 -04:00
|
|
|
#endif
|
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
boost::signals2::signal<void ()> OnExecutableChange;
|
|
|
|
boost::signals2::signal<void ()> OnExecutableUnloading;
|
|
|
|
boost::signals2::signal<void ()> OnRequestInstructionCacheFlush;
|
2012-04-14 21:08:33 +00:00
|
|
|
RequestLoadExecutableEvent OnRequestLoadExecutable;
|
2015-04-09 23:59:34 -04:00
|
|
|
boost::signals2::signal<void ()> OnRequestExit;
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
class CRoundRibbon
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CRoundRibbon(void*, uint32);
|
|
|
|
~CRoundRibbon();
|
|
|
|
unsigned int Insert(uint32, uint32);
|
|
|
|
void Remove(unsigned int);
|
|
|
|
unsigned int Begin();
|
|
|
|
|
|
|
|
class ITERATOR
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ITERATOR(CRoundRibbon*);
|
|
|
|
ITERATOR& operator =(unsigned int);
|
|
|
|
ITERATOR& operator ++(int);
|
|
|
|
uint32 GetWeight();
|
|
|
|
uint32 GetValue();
|
|
|
|
unsigned int GetIndex();
|
|
|
|
bool IsEnd();
|
|
|
|
|
|
|
|
private:
|
2014-08-27 01:07:09 -04:00
|
|
|
CRoundRibbon* m_ribbon;
|
|
|
|
unsigned int m_index;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct NODE
|
|
|
|
{
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 value;
|
|
|
|
uint32 weight;
|
|
|
|
unsigned int indexNext;
|
|
|
|
unsigned int valid;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
NODE* GetNode(unsigned int);
|
|
|
|
unsigned int GetNodeIndex(NODE*);
|
|
|
|
NODE* AllocateNode();
|
|
|
|
void FreeNode(NODE*);
|
|
|
|
|
2014-08-27 01:07:09 -04:00
|
|
|
NODE* m_node;
|
|
|
|
uint32 m_maxNode;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SEMAPHOREPARAM
|
|
|
|
{
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 count;
|
|
|
|
uint32 maxCount;
|
|
|
|
uint32 initCount;
|
|
|
|
uint32 waitThreads;
|
|
|
|
uint32 attributes;
|
|
|
|
uint32 options;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct THREADPARAM
|
|
|
|
{
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 status;
|
|
|
|
uint32 threadProc;
|
|
|
|
uint32 stackBase;
|
|
|
|
uint32 stackSize;
|
|
|
|
uint32 gp;
|
|
|
|
uint32 priority;
|
|
|
|
uint32 currentPriority;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SEMAPHORE
|
|
|
|
{
|
2015-01-31 01:40:42 -05:00
|
|
|
uint32 isValid;
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 count;
|
|
|
|
uint32 maxCount;
|
|
|
|
uint32 waitCount;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct THREAD
|
|
|
|
{
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 valid;
|
|
|
|
uint32 status;
|
|
|
|
uint32 contextPtr;
|
|
|
|
uint32 stackBase;
|
|
|
|
uint32 heapBase;
|
2014-08-30 14:51:35 +09:00
|
|
|
uint32 threadProc;
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 epc;
|
|
|
|
uint32 priority;
|
|
|
|
uint32 semaWait;
|
|
|
|
uint32 wakeUpCount;
|
|
|
|
uint32 scheduleID;
|
|
|
|
uint32 stackSize;
|
|
|
|
uint32 quota;
|
2006-06-19 05:43:51 +00:00
|
|
|
};
|
|
|
|
|
2014-08-27 03:37:57 -04:00
|
|
|
enum STACKRES
|
|
|
|
{
|
|
|
|
STACKRES = 0x2A0,
|
|
|
|
};
|
|
|
|
|
|
|
|
//Castlevania: CoD relies on the fact that the GPRs are stored
|
|
|
|
//in order starting from R0 all the way up to RA because it read/writes
|
|
|
|
//values directly in the thread context
|
2006-06-19 05:43:51 +00:00
|
|
|
struct THREADCONTEXT
|
|
|
|
{
|
2014-08-27 03:37:57 -04:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
COP1_REG_COUNT = 0x1C
|
|
|
|
};
|
|
|
|
|
2014-08-27 00:10:31 -04:00
|
|
|
uint128 gpr[0x20];
|
|
|
|
uint128 hi;
|
|
|
|
uint128 lo;
|
|
|
|
uint32 sa;
|
|
|
|
uint32 fcsr;
|
|
|
|
uint32 cop1a;
|
|
|
|
uint32 reserved3;
|
2014-08-27 03:37:57 -04:00
|
|
|
uint32 cop1[COP1_REG_COUNT];
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
2014-08-27 03:37:57 -04:00
|
|
|
static_assert(sizeof(THREADCONTEXT) == STACKRES, "Size of THREADCONTEXT must be STACKRES");
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
struct DMACHANDLER
|
|
|
|
{
|
2015-01-29 01:36:29 -05:00
|
|
|
uint32 isValid;
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 channel;
|
|
|
|
uint32 address;
|
|
|
|
uint32 arg;
|
|
|
|
uint32 gp;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct INTCHANDLER
|
|
|
|
{
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 valid;
|
|
|
|
uint32 cause;
|
|
|
|
uint32 address;
|
|
|
|
uint32 arg;
|
|
|
|
uint32 gp;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DECI2HANDLER
|
|
|
|
{
|
2014-08-27 01:07:09 -04:00
|
|
|
uint32 valid;
|
|
|
|
uint32 device;
|
|
|
|
uint32 bufferAddr;
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
2015-01-28 03:32:18 -05:00
|
|
|
struct ALARM
|
|
|
|
{
|
|
|
|
uint32 isValid;
|
|
|
|
uint32 delay;
|
|
|
|
uint32 callback;
|
|
|
|
uint32 callbackParam;
|
|
|
|
uint32 gp;
|
|
|
|
};
|
|
|
|
|
2011-07-04 03:12:07 +00:00
|
|
|
#ifdef DEBUGGER_INCLUDED
|
|
|
|
struct SYSCALL_NAME
|
|
|
|
{
|
|
|
|
uint32 id;
|
|
|
|
const char* name;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
enum SYSCALL_REGS
|
|
|
|
{
|
|
|
|
SC_RETURN = 2,
|
|
|
|
SC_PARAM0 = 4,
|
|
|
|
SC_PARAM1 = 5,
|
|
|
|
SC_PARAM2 = 6,
|
|
|
|
SC_PARAM3 = 7,
|
|
|
|
SC_PARAM4 = 8
|
|
|
|
};
|
|
|
|
|
|
|
|
enum MAX
|
|
|
|
{
|
|
|
|
MAX_THREAD = 256,
|
|
|
|
MAX_SEMAPHORE = 256,
|
|
|
|
MAX_DMACHANDLER = 128,
|
|
|
|
MAX_INTCHANDLER = 128,
|
|
|
|
MAX_DECI2HANDLER = 32,
|
2015-01-28 03:32:18 -05:00
|
|
|
MAX_ALARM = 4,
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum THREAD_STATUS
|
|
|
|
{
|
2012-06-28 06:03:14 +00:00
|
|
|
THREAD_RUNNING = 0x01,
|
|
|
|
THREAD_SLEEPING = 0x02,
|
|
|
|
THREAD_WAITING = 0x03,
|
|
|
|
THREAD_SUSPENDED = 0x04,
|
|
|
|
THREAD_SUSPENDED_WAITING = 0x05,
|
|
|
|
THREAD_SUSPENDED_SLEEPING = 0x06,
|
|
|
|
THREAD_ZOMBIE = 0x07,
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|
|
|
|
|
2015-01-31 01:40:42 -05:00
|
|
|
typedef COsStructManager<SEMAPHORE> SemaphoreList;
|
2015-01-29 01:36:29 -05:00
|
|
|
typedef COsStructManager<DMACHANDLER> DmacHandlerList;
|
2015-01-28 03:32:18 -05:00
|
|
|
typedef COsStructManager<ALARM> AlarmList;
|
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
typedef void (CPS2OS::*SystemCallHandler)();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2012-04-14 21:08:33 +00:00
|
|
|
void LoadELF(Framework::CStream&, const char*, const ArgumentList&);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2012-12-23 14:59:38 +00:00
|
|
|
void LoadExecutableInternal();
|
2007-12-01 04:08:34 +00:00
|
|
|
void UnloadExecutable();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2007-12-01 04:08:34 +00:00
|
|
|
void ApplyPatches();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2007-12-01 04:08:34 +00:00
|
|
|
void DisassembleSysCall(uint8);
|
2012-03-11 20:06:14 +00:00
|
|
|
std::string GetSysCallDescription(uint8);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2014-08-27 01:07:09 -04:00
|
|
|
static SystemCallHandler m_sysCall[0x80];
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2007-12-01 04:08:34 +00:00
|
|
|
void AssembleCustomSyscallHandler();
|
|
|
|
void AssembleInterruptHandler();
|
|
|
|
void AssembleDmacHandler();
|
|
|
|
void AssembleIntcHandler();
|
2015-01-28 03:32:18 -05:00
|
|
|
void AssembleAlarmHandler();
|
2007-12-01 04:08:34 +00:00
|
|
|
void AssembleThreadEpilog();
|
|
|
|
void AssembleWaitThreadProc();
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
uint32* GetCustomSyscallTable();
|
2007-12-01 04:08:34 +00:00
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
void CreateWaitThread();
|
|
|
|
uint32 GetCurrentThreadId() const;
|
|
|
|
void SetCurrentThreadId(uint32);
|
|
|
|
uint32 GetNextAvailableThreadId();
|
2012-05-21 06:31:50 +00:00
|
|
|
THREAD* GetThread(uint32) const;
|
2012-04-14 21:08:33 +00:00
|
|
|
void ThreadShakeAndBake();
|
2007-12-01 04:08:34 +00:00
|
|
|
bool ThreadHasAllQuotasExpired();
|
|
|
|
void ThreadSwitchContext(unsigned int);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2015-01-31 23:05:56 -05:00
|
|
|
uint8* GetStructPtr(uint32) const;
|
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
uint32 GetNextAvailableIntcHandlerId();
|
|
|
|
INTCHANDLER* GetIntcHandler(uint32);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
uint32 GetNextAvailableDeci2HandlerId();
|
|
|
|
DECI2HANDLER* GetDeci2Handler(uint32);
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
//Various system calls
|
2007-12-01 04:08:34 +00:00
|
|
|
void sc_GsSetCrt();
|
2015-04-09 23:59:34 -04:00
|
|
|
void sc_Exit();
|
2012-04-14 21:08:33 +00:00
|
|
|
void sc_LoadExecPS2();
|
2007-12-01 04:08:34 +00:00
|
|
|
void sc_AddIntcHandler();
|
|
|
|
void sc_RemoveIntcHandler();
|
|
|
|
void sc_AddDmacHandler();
|
|
|
|
void sc_RemoveDmacHandler();
|
|
|
|
void sc_EnableIntc();
|
|
|
|
void sc_DisableIntc();
|
|
|
|
void sc_EnableDmac();
|
|
|
|
void sc_DisableDmac();
|
2015-01-28 03:32:18 -05:00
|
|
|
void sc_SetAlarm();
|
|
|
|
void sc_ReleaseAlarm();
|
2007-12-01 04:08:34 +00:00
|
|
|
void sc_CreateThread();
|
|
|
|
void sc_DeleteThread();
|
|
|
|
void sc_StartThread();
|
|
|
|
void sc_ExitThread();
|
|
|
|
void sc_TerminateThread();
|
|
|
|
void sc_ChangeThreadPriority();
|
|
|
|
void sc_RotateThreadReadyQueue();
|
|
|
|
void sc_GetThreadId();
|
|
|
|
void sc_ReferThreadStatus();
|
|
|
|
void sc_SleepThread();
|
|
|
|
void sc_WakeupThread();
|
2014-09-29 01:27:13 -04:00
|
|
|
void sc_CancelWakeupThread();
|
2012-06-28 06:03:14 +00:00
|
|
|
void sc_SuspendThread();
|
|
|
|
void sc_ResumeThread();
|
2012-04-14 21:08:33 +00:00
|
|
|
void sc_SetupThread();
|
|
|
|
void sc_SetupHeap();
|
2007-12-01 04:08:34 +00:00
|
|
|
void sc_EndOfHeap();
|
|
|
|
void sc_CreateSema();
|
|
|
|
void sc_DeleteSema();
|
|
|
|
void sc_SignalSema();
|
|
|
|
void sc_WaitSema();
|
|
|
|
void sc_PollSema();
|
|
|
|
void sc_ReferSemaStatus();
|
|
|
|
void sc_FlushCache();
|
2012-05-29 04:18:40 +00:00
|
|
|
void sc_GsGetIMR();
|
2007-12-01 04:08:34 +00:00
|
|
|
void sc_GsPutIMR();
|
|
|
|
void sc_SetVSyncFlag();
|
|
|
|
void sc_SetSyscall();
|
|
|
|
void sc_SifDmaStat();
|
|
|
|
void sc_SifSetDma();
|
|
|
|
void sc_SifSetDChain();
|
|
|
|
void sc_SifSetReg();
|
|
|
|
void sc_SifGetReg();
|
|
|
|
void sc_Deci2Call();
|
2015-04-12 23:54:10 -04:00
|
|
|
void sc_MachineType();
|
2007-12-01 04:08:34 +00:00
|
|
|
void sc_GetMemorySize();
|
|
|
|
void sc_Unhandled();
|
|
|
|
|
2015-01-28 03:32:18 -05:00
|
|
|
uint8* m_ram = nullptr;
|
|
|
|
uint8* m_bios = nullptr;
|
2015-01-31 23:05:56 -05:00
|
|
|
uint8* m_spr = nullptr;
|
2015-01-28 03:32:18 -05:00
|
|
|
|
2014-08-27 01:07:09 -04:00
|
|
|
CELF* m_elf;
|
2012-03-11 20:06:14 +00:00
|
|
|
CMIPS& m_ee;
|
2014-08-27 01:07:09 -04:00
|
|
|
CRoundRibbon* m_threadSchedule;
|
2015-01-31 01:40:42 -05:00
|
|
|
SemaphoreList m_semaphores;
|
2015-01-29 01:36:29 -05:00
|
|
|
DmacHandlerList m_dmacHandlers;
|
2015-01-28 03:32:18 -05:00
|
|
|
AlarmList m_alarms;
|
2007-12-01 04:08:34 +00:00
|
|
|
|
2012-04-14 21:08:33 +00:00
|
|
|
std::string m_executableName;
|
|
|
|
ArgumentList m_currentArguments;
|
|
|
|
|
2012-03-11 20:06:14 +00:00
|
|
|
CGSHandler*& m_gs;
|
|
|
|
CSIF& m_sif;
|
|
|
|
CIopBios& m_iopBios;
|
2011-05-08 21:58:55 +00:00
|
|
|
|
|
|
|
uint32 m_semaWaitId;
|
|
|
|
uint32 m_semaWaitCount;
|
|
|
|
uint32 m_semaWaitCaller;
|
2011-05-16 00:04:02 +00:00
|
|
|
uint32 m_semaWaitThreadId;
|
2011-07-04 03:12:07 +00:00
|
|
|
|
|
|
|
#ifdef DEBUGGER_INCLUDED
|
|
|
|
static const SYSCALL_NAME g_syscallNames[];
|
|
|
|
#endif
|
2006-06-15 04:19:30 +00:00
|
|
|
};
|