Skip to content

Commit

Permalink
Merge branch 'jak'
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Aug 3, 2018
2 parents f627b4c + 9268a08 commit f62734c
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Source/ee/SIF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ uint32 CSIF::GetRegister(uint32 nRegister)
return 1;
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Warning. Trying to read an invalid system register (0x%08X).\r\n", nRegister);
CLog::GetInstance().Warn(LOG_NAME, "Warning. Trying to read an invalid system register (0x%08X).\r\n", nRegister);
return 0;
break;
}
Expand All @@ -690,7 +690,7 @@ void CSIF::SetRegister(uint32 nRegister, uint32 nValue)
//Set by RPC library (initialized state?)
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Warning. Trying to write to an invalid system register (0x%08X).\r\n", nRegister);
CLog::GetInstance().Warn(LOG_NAME, "Warning. Trying to write to an invalid system register (0x%08X).\r\n", nRegister);
break;
}
}
114 changes: 107 additions & 7 deletions Source/iop/IopBios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>
#include "xml/FilteringNodeIterator.h"
#include "../StructCollectionStateFile.h"
#include "string_format.h"

#ifdef _IOP_EMULATE_MODULES
#include "Iop_Cdvdfsv.h"
Expand Down Expand Up @@ -54,7 +55,9 @@
#define BIOS_EVENTFLAGS_SIZE (sizeof(CIopBios::EVENTFLAG) * CIopBios::MAX_EVENTFLAG)
#define BIOS_INTRHANDLER_BASE (BIOS_EVENTFLAGS_BASE + BIOS_EVENTFLAGS_SIZE)
#define BIOS_INTRHANDLER_SIZE (sizeof(CIopBios::INTRHANDLER) * CIopBios::MAX_INTRHANDLER)
#define BIOS_MESSAGEBOX_BASE (BIOS_INTRHANDLER_BASE + BIOS_INTRHANDLER_SIZE)
#define BIOS_VBLANKHANDLER_BASE (BIOS_INTRHANDLER_BASE + BIOS_INTRHANDLER_SIZE)
#define BIOS_VBLANKHANDLER_SIZE (sizeof(CIopBios::VBLANKHANDLER) * CIopBios::MAX_VBLANKHANDLER)
#define BIOS_MESSAGEBOX_BASE (BIOS_VBLANKHANDLER_BASE + BIOS_VBLANKHANDLER_SIZE)
#define BIOS_MESSAGEBOX_SIZE (sizeof(CIopBios::MESSAGEBOX) * CIopBios::MAX_MESSAGEBOX)
#define BIOS_VPL_BASE (BIOS_MESSAGEBOX_BASE + BIOS_MESSAGEBOX_SIZE)
#define BIOS_VPL_SIZE (sizeof(CIopBios::VPL) * CIopBios::MAX_VPL)
Expand Down Expand Up @@ -93,6 +96,7 @@ CIopBios::CIopBios(CMIPS& cpu, uint8* ram, uint32 ramSize, uint8* spr)
, m_semaphores(reinterpret_cast<SEMAPHORE*>(&m_ram[BIOS_SEMAPHORES_BASE]), 1, MAX_SEMAPHORE)
, m_eventFlags(reinterpret_cast<EVENTFLAG*>(&m_ram[BIOS_EVENTFLAGS_BASE]), 1, MAX_EVENTFLAG)
, m_intrHandlers(reinterpret_cast<INTRHANDLER*>(&m_ram[BIOS_INTRHANDLER_BASE]), 1, MAX_INTRHANDLER)
, m_vblankHandlers(reinterpret_cast<VBLANKHANDLER*>(&m_ram[BIOS_VBLANKHANDLER_BASE]), 1, MAX_VBLANKHANDLER)
, m_messageBoxes(reinterpret_cast<MESSAGEBOX*>(&m_ram[BIOS_MESSAGEBOX_BASE]), 1, MAX_MESSAGEBOX)
, m_vpls(reinterpret_cast<VPL*>(&m_ram[BIOS_VPL_BASE]), 1, MAX_VPL)
, m_loadedModules(reinterpret_cast<LOADEDMODULE*>(&m_ram[BIOS_LOADEDMODULE_BASE]), 1, MAX_LOADEDMODULE)
Expand All @@ -116,6 +120,7 @@ void CIopBios::Reset(const Iop::SifManPtr& sifMan)
m_idleFunctionAddress = AssembleIdleFunction(assembler);
m_moduleStarterThreadProcAddress = AssembleModuleStarterThreadProc(assembler);
m_alarmThreadProcAddress = AssembleAlarmThreadProc(assembler);
m_vblankHandlerAddress = AssembleVblankHandler(assembler);
assert(BIOS_HANDLERS_END > ((assembler.GetProgramSize() * 4) + BIOS_HANDLERS_BASE));
}

Expand Down Expand Up @@ -1436,6 +1441,40 @@ int32 CIopBios::ReleaseWaitThread(uint32 threadId, bool inInterrupt)
return KERNEL_RESULT_OK;
}

int32 CIopBios::RegisterVblankHandler(uint32 startEnd, uint32 priority, uint32 handlerPtr, uint32 handlerParam)
{
assert((startEnd == 0) || (startEnd == 1));

//Make sure interrupt handler is registered
{
uint32 intrLine = startEnd ? Iop::CIntc::LINE_EVBLANK : Iop::CIntc::LINE_VBLANK;
uint32 intrHandlerId = FindIntrHandler(intrLine);
if(intrHandlerId == -1)
{
RegisterIntrHandler(intrLine, 0, m_vblankHandlerAddress, startEnd);

uint32 mask = m_cpu.m_pMemoryMap->GetWord(Iop::CIntc::MASK0);
mask |= (1 << intrLine);
m_cpu.m_pMemoryMap->SetWord(Iop::CIntc::MASK0, mask);
}
}

uint32 handlerId = m_vblankHandlers.Allocate();
assert(handlerId != -1);
if(handlerId == -1)
{
return -1;
}

auto handler = m_vblankHandlers[handlerId];
assert(handler);
handler->handler = handlerPtr;
handler->arg = handlerParam;
handler->type = startEnd;

return KERNEL_RESULT_OK;
}

void CIopBios::SleepThreadTillVBlankStart()
{
THREAD* thread = GetThread(m_currentThreadId);
Expand Down Expand Up @@ -1575,7 +1614,7 @@ uint32 CIopBios::GetNextReadyThread()
return -1;
}

uint64 CIopBios::GetCurrentTime()
uint64 CIopBios::GetCurrentTime() const
{
return CurrentTime();
}
Expand Down Expand Up @@ -2151,10 +2190,8 @@ uint32 CIopBios::ReceiveMessageBox(uint32 messagePtr, uint32 boxId)
return KERNEL_RESULT_ERROR_UNKNOWN_MBXID;
}

if(box->nextMsgPtr != 0)
if(box->numMessage != 0)
{
assert(box->numMessage > 0);

uint32* message = reinterpret_cast<uint32*>(m_ram + messagePtr);
(*message) = box->nextMsgPtr;

Expand Down Expand Up @@ -2189,7 +2226,7 @@ uint32 CIopBios::PollMessageBox(uint32 messagePtr, uint32 boxId)
return KERNEL_RESULT_ERROR_UNKNOWN_MBXID;
}

if(box->nextMsgPtr == 0)
if(box->numMessage == 0)
{
return KERNEL_RESULT_ERROR_MBX_NOMSG;
}
Expand Down Expand Up @@ -2614,6 +2651,60 @@ uint32 CIopBios::AssembleAlarmThreadProc(CMIPSAssembler& assembler)
return address;
}

uint32 CIopBios::AssembleVblankHandler(CMIPSAssembler& assembler)
{
uint32 address = BIOS_HANDLERS_BASE + assembler.GetProgramSize() * 4;
auto checkHandlerLabel = assembler.CreateLabel();
auto moveToNextHandlerLabel = assembler.CreateLabel();

int16 stackAlloc = 0x80;

//Prolog
assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc);
assembler.SW(CMIPS::RA, 0x10, CMIPS::SP);
assembler.SW(CMIPS::S0, 0x14, CMIPS::SP);

assembler.MOV(CMIPS::S0, CMIPS::A0); //S0 = type
assembler.MOV(CMIPS::S1, CMIPS::R0); //S1 = counter

assembler.MarkLabel(checkHandlerLabel);
assembler.LI(CMIPS::T0, BIOS_VBLANKHANDLER_BASE);
assembler.SLL(CMIPS::T1, CMIPS::S1, 4); //Multiples of 0x10 bytes
assembler.ADDU(CMIPS::T0, CMIPS::T0, CMIPS::T1);

//Check isValid
assembler.LW(CMIPS::T1, offsetof(VBLANKHANDLER, isValid), CMIPS::T0);
assembler.BEQ(CMIPS::T1, CMIPS::R0, moveToNextHandlerLabel);
assembler.NOP();

//Check type
assembler.LW(CMIPS::T1, offsetof(VBLANKHANDLER, type), CMIPS::T0);
assembler.BNE(CMIPS::T1, CMIPS::S0, moveToNextHandlerLabel);
assembler.NOP();

assembler.LW(CMIPS::T1, offsetof(VBLANKHANDLER, handler), CMIPS::T0);
assembler.JALR(CMIPS::T1);
assembler.LW(CMIPS::A0, offsetof(VBLANKHANDLER, arg), CMIPS::T0);

//TODO: Check return value

assembler.MarkLabel(moveToNextHandlerLabel);
assembler.ADDIU(CMIPS::S1, CMIPS::S1, 1);
assembler.SLTIU(CMIPS::T0, CMIPS::S1, MAX_VBLANKHANDLER);

assembler.BNE(CMIPS::T0, CMIPS::R0, checkHandlerLabel);
assembler.NOP();

//Epilog
assembler.LW(CMIPS::S0, 0x14, CMIPS::SP);
assembler.LW(CMIPS::RA, 0x10, CMIPS::SP);

assembler.JR(CMIPS::RA);
assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc);

return address;
}

void CIopBios::HandleException()
{
assert(m_cpu.m_State.nHasException == MIPS_EXCEPTION_SYSCALL);
Expand Down Expand Up @@ -3135,13 +3226,22 @@ BiosDebugThreadInfoArray CIopBios::GetThreadsDebugInfo() const
threadInfo.sp = thread->context.gpr[CMIPS::SP];
}

int64 deltaTime = thread->nextActivateTime - GetCurrentTime();

switch(thread->status)
{
case THREAD_STATUS_DORMANT:
threadInfo.stateDescription = "Dormant";
break;
case THREAD_STATUS_RUNNING:
threadInfo.stateDescription = "Running";
if(deltaTime <= 0)
{
threadInfo.stateDescription = "Running";
}
else
{
threadInfo.stateDescription = string_format("Delayed (%ld ticks)", deltaTime);
}
break;
case THREAD_STATUS_SLEEPING:
threadInfo.stateDescription = "Sleeping";
Expand Down
17 changes: 16 additions & 1 deletion Source/iop/IopBios.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class CIopBios : public Iop::CBiosBase
void Reschedule();

void CountTicks(uint32) override;
uint64 GetCurrentTime();
uint64 GetCurrentTime() const;
uint64 MilliSecToClock(uint32);
uint64 MicroSecToClock(uint32);
uint64 ClockToMicroSec(uint64);
Expand Down Expand Up @@ -192,6 +192,7 @@ class CIopBios : public Iop::CBiosBase
int32 RotateThreadReadyQueue(uint32);
int32 ReleaseWaitThread(uint32, bool);

int32 RegisterVblankHandler(uint32, uint32, uint32, uint32);
void SleepThreadTillVBlankStart();
void SleepThreadTillVBlankEnd();

Expand Down Expand Up @@ -280,6 +281,7 @@ class CIopBios : public Iop::CBiosBase
MAX_SEMAPHORE = 128,
MAX_EVENTFLAG = 64,
MAX_INTRHANDLER = 32,
MAX_VBLANKHANDLER = 8,
MAX_MESSAGEBOX = 32,
MAX_VPL = 16,
MAX_MODULESTARTREQUEST = 32,
Expand Down Expand Up @@ -339,6 +341,15 @@ class CIopBios : public Iop::CBiosBase
uint32 arg;
};

struct VBLANKHANDLER
{
uint32 isValid;
uint32 type;
uint32 handler;
uint32 arg;
};
static_assert(sizeof(VBLANKHANDLER) == 0x10, "Size of VBLANKHANDLER must be 16 bytes. AssembleVblankHandler relies on this.");

struct MESSAGEBOX
{
uint32 isValid;
Expand Down Expand Up @@ -467,6 +478,7 @@ class CIopBios : public Iop::CBiosBase
typedef COsStructManager<SEMAPHORE> SemaphoreList;
typedef COsStructManager<EVENTFLAG> EventFlagList;
typedef COsStructManager<INTRHANDLER> IntrHandlerList;
typedef COsStructManager<VBLANKHANDLER> VblankHandlerList;
typedef COsStructManager<MESSAGEBOX> MessageBoxList;
typedef COsStructManager<VPL> VplList;
typedef COsStructManager<LOADEDMODULE> LoadedModuleList;
Expand Down Expand Up @@ -502,6 +514,7 @@ class CIopBios : public Iop::CBiosBase
uint32 AssembleIdleFunction(CMIPSAssembler&);
uint32 AssembleModuleStarterThreadProc(CMIPSAssembler&);
uint32 AssembleAlarmThreadProc(CMIPSAssembler&);
uint32 AssembleVblankHandler(CMIPSAssembler&);

void InitializeModuleStarter();
void ProcessModuleStart();
Expand All @@ -523,6 +536,7 @@ class CIopBios : public Iop::CBiosBase
uint32 m_idleFunctionAddress;
uint32 m_moduleStarterThreadProcAddress;
uint32 m_alarmThreadProcAddress;
uint32 m_vblankHandlerAddress;

uint32 m_moduleStarterThreadId;

Expand All @@ -533,6 +547,7 @@ class CIopBios : public Iop::CBiosBase
SemaphoreList m_semaphores;
EventFlagList m_eventFlags;
IntrHandlerList m_intrHandlers;
VblankHandlerList m_vblankHandlers;
MessageBoxList m_messageBoxes;
VplList m_vpls;

Expand Down
4 changes: 0 additions & 4 deletions Source/iop/Iop_SifMan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ CSifMan::CSifMan()
{
}

CSifMan::~CSifMan()
{
}

std::string CSifMan::GetId() const
{
return "sifman";
Expand Down
2 changes: 1 addition & 1 deletion Source/iop/Iop_SifMan.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Iop
typedef std::function<void(uint32)> CustomCommandHandler;

CSifMan();
virtual ~CSifMan();
virtual ~CSifMan() = default;

void GenerateHandlers(uint8*, CSysmem&);

Expand Down
4 changes: 0 additions & 4 deletions Source/iop/Iop_SifManPs2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ CSifManPs2::CSifManPs2(CSIF& sif, uint8* eeRam, uint8* iopRam)
{
}

CSifManPs2::~CSifManPs2()
{
}

void CSifManPs2::RegisterModule(uint32 id, CSifModule* module)
{
m_sif.RegisterModule(id, module);
Expand Down
2 changes: 1 addition & 1 deletion Source/iop/Iop_SifManPs2.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Iop
{
public:
CSifManPs2(CSIF&, uint8*, uint8*);
virtual ~CSifManPs2();
virtual ~CSifManPs2() = default;

void RegisterModule(uint32, CSifModule*) override;
bool IsModuleRegistered(uint32) override;
Expand Down
14 changes: 2 additions & 12 deletions Source/iop/Iop_Vblank.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "Iop_Vblank.h"
#include "IopBios.h"
#include "Iop_Intc.h"
#include "../Log.h"

using namespace Iop;
Expand Down Expand Up @@ -59,7 +58,6 @@ void CVblank::Invoke(CMIPS& context, unsigned int functionId)
break;
case 8:
context.m_State.nGPR[CMIPS::V0].nD0 = RegisterVblankHandler(
context,
context.m_State.nGPR[CMIPS::A0].nV0,
context.m_State.nGPR[CMIPS::A1].nV0,
context.m_State.nGPR[CMIPS::A2].nV0,
Expand Down Expand Up @@ -99,19 +97,11 @@ int32 CVblank::WaitVblank()
return 0;
}

int32 CVblank::RegisterVblankHandler(CMIPS& context, uint32 startEnd, uint32 priority, uint32 handlerPtr, uint32 handlerParam)
int32 CVblank::RegisterVblankHandler(uint32 startEnd, uint32 priority, uint32 handlerPtr, uint32 handlerParam)
{
#ifdef _DEBUG
CLog::GetInstance().Print(LOG_NAME, FUNCTION_REGISTERVBLANKHANDLER "(startEnd = %d, priority = %d, handler = 0x%08X, arg = 0x%08X).\r\n",
startEnd, priority, handlerPtr, handlerParam);
#endif
uint32 intrLine = startEnd ? CIntc::LINE_EVBLANK : CIntc::LINE_VBLANK;

m_bios.RegisterIntrHandler(intrLine, 0, handlerPtr, handlerParam);

uint32 mask = context.m_pMemoryMap->GetWord(CIntc::MASK0);
mask |= (1 << intrLine);
context.m_pMemoryMap->SetWord(CIntc::MASK0, mask);

return 0;
return m_bios.RegisterVblankHandler(startEnd, priority, handlerPtr, handlerParam);
}
2 changes: 1 addition & 1 deletion Source/iop/Iop_Vblank.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Iop
int32 WaitVblankStart();
int32 WaitVblankEnd();
int32 WaitVblank();
int32 RegisterVblankHandler(CMIPS&, uint32, uint32, uint32, uint32);
int32 RegisterVblankHandler(uint32, uint32, uint32, uint32);

CIopBios& m_bios;
};
Expand Down

0 comments on commit f62734c

Please sign in to comment.