5151#define BIOS_THREAD_LINK_HEAD_BASE (CIopBios::CONTROL_BLOCK_START + 0x0000 )
5252#define BIOS_CURRENT_THREAD_ID_BASE (CIopBios::CONTROL_BLOCK_START + 0x0008 )
5353#define BIOS_CURRENT_TIME_BASE (CIopBios::CONTROL_BLOCK_START + 0x0010 )
54+ #define BIOS_IN_VBLANK_BASE (CIopBios::CONTROL_BLOCK_START + 0x0014 )
5455#define BIOS_MODULESTARTREQUEST_HEAD_BASE (CIopBios::CONTROL_BLOCK_START + 0x0018 )
5556#define BIOS_MODULESTARTREQUEST_FREE_BASE (CIopBios::CONTROL_BLOCK_START + 0x0020 )
5657#define BIOS_HANDLERS_BASE (CIopBios::CONTROL_BLOCK_START + 0x0100 )
@@ -116,6 +117,7 @@ CIopBios::CIopBios(CMIPS& cpu, uint8* ram, uint32 ramSize, uint8* spr)
116117 , m_vpls(reinterpret_cast <VPL*>(&m_ram[BIOS_VPL_BASE]), 1, MAX_VPL)
117118 , m_loadedModules(reinterpret_cast <LOADEDMODULE*>(&m_ram[BIOS_LOADEDMODULE_BASE]), 1, MAX_LOADEDMODULE)
118119 , m_currentThreadId(reinterpret_cast <uint32*>(m_ram + BIOS_CURRENT_THREAD_ID_BASE))
120+ , m_inVBlank(reinterpret_cast <bool *>(m_ram + BIOS_IN_VBLANK_BASE))
119121{
120122 static_assert (BIOS_CALCULATED_END <= CIopBios::CONTROL_BLOCK_END, " Control block size is too small" );
121123 static_assert (BIOS_SYSTEM_INTRHANDLER_TABLE_BASE > CIopBios::CONTROL_BLOCK_START, " Intr handler table is outside reserved block" );
@@ -146,6 +148,7 @@ void CIopBios::Reset(const Iop::SifManPtr& sifMan)
146148 CurrentTime () = 0xBE00000 ;
147149 ThreadLinkHead () = 0 ;
148150 m_currentThreadId = -1 ;
151+ m_inVBlank = false ;
149152
150153 m_cpu.m_State .nCOP0 [CCOP_SCU::STATUS] |= CMIPS::STATUS_IE;
151154
@@ -1692,6 +1695,30 @@ void CIopBios::SleepThreadTillVBlankEnd()
16921695 m_rescheduleNeeded = true ;
16931696}
16941697
1698+ void CIopBios::SleepThreadTillVBlank ()
1699+ {
1700+ if (m_inVBlank)
1701+ {
1702+ return ;
1703+ }
1704+ THREAD* thread = GetThread (m_currentThreadId);
1705+ thread->status = THREAD_STATUS_WAIT_VBLANK_START;
1706+ UnlinkThread (thread->id );
1707+ m_rescheduleNeeded = true ;
1708+ }
1709+
1710+ void CIopBios::SleepThreadTillNonVBlank ()
1711+ {
1712+ if (!m_inVBlank)
1713+ {
1714+ return ;
1715+ }
1716+ THREAD* thread = GetThread (m_currentThreadId);
1717+ thread->status = THREAD_STATUS_WAIT_VBLANK_END;
1718+ UnlinkThread (thread->id );
1719+ m_rescheduleNeeded = true ;
1720+ }
1721+
16951722void CIopBios::LoadThreadContext (uint32 threadId)
16961723{
16971724 THREAD* thread = GetThread (threadId);
@@ -1849,6 +1876,7 @@ void CIopBios::CountTicks(uint32 ticks)
18491876
18501877void CIopBios::NotifyVBlankStart ()
18511878{
1879+ m_inVBlank = true ;
18521880 for (auto thread : m_threads)
18531881 {
18541882 if (!thread) continue ;
@@ -1862,6 +1890,7 @@ void CIopBios::NotifyVBlankStart()
18621890
18631891void CIopBios::NotifyVBlankEnd ()
18641892{
1893+ m_inVBlank = false ;
18651894 for (auto thread : m_threads)
18661895 {
18671896 if (!thread) continue ;
0 commit comments