Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vblank additions #1182

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions Source/iop/IopBios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#define BIOS_THREAD_LINK_HEAD_BASE (CIopBios::CONTROL_BLOCK_START + 0x0000)
#define BIOS_CURRENT_THREAD_ID_BASE (CIopBios::CONTROL_BLOCK_START + 0x0008)
#define BIOS_CURRENT_TIME_BASE (CIopBios::CONTROL_BLOCK_START + 0x0010)
#define BIOS_IN_VBLANK_BASE (CIopBios::CONTROL_BLOCK_START + 0x0014)
#define BIOS_MODULESTARTREQUEST_HEAD_BASE (CIopBios::CONTROL_BLOCK_START + 0x0018)
#define BIOS_MODULESTARTREQUEST_FREE_BASE (CIopBios::CONTROL_BLOCK_START + 0x0020)
#define BIOS_HANDLERS_BASE (CIopBios::CONTROL_BLOCK_START + 0x0100)
Expand Down Expand Up @@ -116,6 +117,7 @@ CIopBios::CIopBios(CMIPS& cpu, uint8* ram, uint32 ramSize, uint8* spr)
, 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)
, m_currentThreadId(reinterpret_cast<uint32*>(m_ram + BIOS_CURRENT_THREAD_ID_BASE))
, m_inVBlank(reinterpret_cast<bool*>(m_ram + BIOS_IN_VBLANK_BASE))
{
static_assert(BIOS_CALCULATED_END <= CIopBios::CONTROL_BLOCK_END, "Control block size is too small");
static_assert(BIOS_SYSTEM_INTRHANDLER_TABLE_BASE > CIopBios::CONTROL_BLOCK_START, "Intr handler table is outside reserved block");
Expand Down Expand Up @@ -146,6 +148,7 @@ void CIopBios::Reset(const Iop::SifManPtr& sifMan)
CurrentTime() = 0xBE00000;
ThreadLinkHead() = 0;
m_currentThreadId = -1;
m_inVBlank = false;

m_cpu.m_State.nCOP0[CCOP_SCU::STATUS] |= CMIPS::STATUS_IE;

Expand Down Expand Up @@ -1692,6 +1695,30 @@ void CIopBios::SleepThreadTillVBlankEnd()
m_rescheduleNeeded = true;
}

void CIopBios::SleepThreadTillVBlank()
{
if(m_inVBlank)
{
return;
}
THREAD* thread = GetThread(m_currentThreadId);
thread->status = THREAD_STATUS_WAIT_VBLANK_START;
UnlinkThread(thread->id);
m_rescheduleNeeded = true;
}

void CIopBios::SleepThreadTillNonVBlank()
{
if(!m_inVBlank)
{
return;
}
THREAD* thread = GetThread(m_currentThreadId);
thread->status = THREAD_STATUS_WAIT_VBLANK_END;
UnlinkThread(thread->id);
m_rescheduleNeeded = true;
}

void CIopBios::LoadThreadContext(uint32 threadId)
{
THREAD* thread = GetThread(threadId);
Expand Down Expand Up @@ -1849,6 +1876,7 @@ void CIopBios::CountTicks(uint32 ticks)

void CIopBios::NotifyVBlankStart()
{
m_inVBlank = true;
for(auto thread : m_threads)
{
if(!thread) continue;
Expand All @@ -1862,6 +1890,7 @@ void CIopBios::NotifyVBlankStart()

void CIopBios::NotifyVBlankEnd()
{
m_inVBlank = false;
for(auto thread : m_threads)
{
if(!thread) continue;
Expand Down
3 changes: 3 additions & 0 deletions Source/iop/IopBios.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ class CIopBios : public Iop::CBiosBase
int32 FindVblankHandlerByLineAndPtr(uint32 startEnd, uint32 handlerPtr);
void SleepThreadTillVBlankStart();
void SleepThreadTillVBlankEnd();
void SleepThreadTillVBlank();
void SleepThreadTillNonVBlank();

uint32 CreateSemaphore(uint32, uint32, uint32, uint32);
uint32 DeleteSemaphore(uint32);
Expand Down Expand Up @@ -662,6 +664,7 @@ class CIopBios : public Iop::CBiosBase
IopModuleMapType m_modules;

OsVariableWrapper<uint32> m_currentThreadId;
OsVariableWrapper<bool> m_inVBlank;

#ifdef DEBUGGER_INCLUDED
BiosDebugModuleInfoArray m_moduleTags;
Expand Down
19 changes: 17 additions & 2 deletions Source/iop/Iop_Vblank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using namespace Iop;
#define FUNCTION_WAITVBLANKSTART "WaitVblankStart"
#define FUNCTION_WAITVBLANKEND "WaitVblankEnd"
#define FUNCTION_WAITVBLANK "WaitVblank"
#define FUNCTION_WAITNONVBLANK "WaitNonVblank"
#define FUNCTION_REGISTERVBLANKHANDLER "RegisterVblankHandler"
#define FUNCTION_RELEASEVBLANKHANDLER "ReleaseVblankHandler"

Expand All @@ -35,6 +36,9 @@ std::string CVblank::GetFunctionName(unsigned int functionId) const
case 6:
return FUNCTION_WAITVBLANK;
break;
case 7:
return FUNCTION_WAITNONVBLANK;
break;
case 8:
return FUNCTION_REGISTERVBLANKHANDLER;
break;
Expand All @@ -60,6 +64,9 @@ void CVblank::Invoke(CMIPS& context, unsigned int functionId)
case 6:
context.m_State.nGPR[CMIPS::V0].nD0 = WaitVblank();
break;
case 7:
context.m_State.nGPR[CMIPS::V0].nD0 = WaitNonVblank();
break;
case 8:
context.m_State.nGPR[CMIPS::V0].nD0 = RegisterVblankHandler(
context.m_State.nGPR[CMIPS::A0].nV0,
Expand Down Expand Up @@ -101,8 +108,16 @@ int32 CVblank::WaitVblank()
#ifdef _DEBUG
CLog::GetInstance().Print(LOG_NAME, FUNCTION_WAITVBLANK "();\r\n");
#endif
//TODO: Skip waiting if we're already in Vblank
m_bios.SleepThreadTillVBlankStart();
m_bios.SleepThreadTillVBlank();
return 0;
}

int32 CVblank::WaitNonVblank()
{
#ifdef _DEBUG
CLog::GetInstance().Print(LOG_NAME, FUNCTION_WAITNONVBLANK "();\r\n");
#endif
m_bios.SleepThreadTillNonVBlank();
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions Source/iop/Iop_Vblank.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Iop
int32 WaitVblankStart();
int32 WaitVblankEnd();
int32 WaitVblank();
int32 WaitNonVblank();
int32 RegisterVblankHandler(uint32, uint32, uint32, uint32);
int32 ReleaseVblankHandler(uint32, uint32);

Expand Down