void ForceExceptionCheck(int cycles) { if (DowncountToCycles(PowerPC::ppcState.downcount) > cycles) { slicelength -= (DowncountToCycles(PowerPC::ppcState.downcount) - cycles); // Account for cycles already executed by adjusting the slicelength PowerPC::ppcState.downcount = CyclesToDowncount(cycles); } }
void ForceExceptionCheck(s64 cycles) { if (s64(DowncountToCycles(PowerPC::ppcState.downcount)) > cycles) { // downcount is always (much) smaller than MAX_INT so we can safely cast cycles to an int here. g_slicelength -= (DowncountToCycles(PowerPC::ppcState.downcount) - (int)cycles); // Account for cycles already executed by adjusting the g_slicelength PowerPC::ppcState.downcount = CyclesToDowncount((int)cycles); } }
void ForceExceptionCheck(s64 cycles) { cycles = std::max<s64>(0, cycles); if (DowncountToCycles(PowerPC::ppcState.downcount) > cycles) { // downcount is always (much) smaller than MAX_INT so we can safely cast cycles to an int here. // Account for cycles already executed by adjusting the g_slice_length g_slice_length -= DowncountToCycles(PowerPC::ppcState.downcount) - static_cast<int>(cycles); PowerPC::ppcState.downcount = CyclesToDowncount(static_cast<int>(cycles)); } }
void Advance() { MoveEvents(); int cyclesExecuted = slicelength - DowncountToCycles(PowerPC::ppcState.downcount); globalTimer += cyclesExecuted; lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; PowerPC::ppcState.downcount = CyclesToDowncount(slicelength); while (first && first->time <= globalTimer) { //LOG(POWERPC, "[Scheduler] %s (%lld, %lld) ", // event_types[first->type].name ? event_types[first->type].name : "?", (u64)globalTimer, (u64)first->time); Event* evt = first; first = first->next; event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time)); FreeEvent(evt); } if (!first) { WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000"); PowerPC::ppcState.downcount += CyclesToDowncount(10000); } else { slicelength = (int)(first->time - globalTimer); if (slicelength > maxSliceLength) slicelength = maxSliceLength; PowerPC::ppcState.downcount = CyclesToDowncount(slicelength); } }
// This should only be called from the CPU thread. If you are calling // it from any other thread, you are doing something evil u64 GetTicks() { u64 ticks = static_cast<u64>(g_global_timer); if (!s_is_global_timer_sane) { int downcount = DowncountToCycles(PowerPC::ppcState.downcount); ticks += g_slice_length - downcount; } return ticks; }
// This should only be called from the CPU thread, if you are calling it any other thread, you are doing something evil u64 GetTicks() { u64 ticks = (u64)g_globalTimer; if (!globalTimerIsSane) { int downcount = DowncountToCycles(PowerPC::ppcState.downcount); ticks += g_slicelength - downcount; } return ticks; }
void Idle() { if (SConfig::GetInstance().bSyncGPUOnSkipIdleHack) { // When the FIFO is processing data we must not advance because in this way // the VI will be desynchronized. So, We are waiting until the FIFO finish and // while we process only the events required by the FIFO. Fifo::FlushGpu(); } s_idled_cycles += DowncountToCycles(PowerPC::ppcState.downcount); PowerPC::ppcState.downcount = 0; }
void Idle() { //DEBUG_LOG(POWERPC, "Idle"); if (SConfig::GetInstance().bSyncGPUOnSkipIdleHack) { //When the FIFO is processing data we must not advance because in this way //the VI will be desynchronized. So, We are waiting until the FIFO finish and //while we process only the events required by the FIFO. ProcessFifoWaitEvents(); g_video_backend->Video_Sync(0); } idledCycles += DowncountToCycles(PowerPC::ppcState.downcount); PowerPC::ppcState.downcount = 0; }
void Idle() { //DEBUG_LOG(POWERPC, "Idle"); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPUOnSkipIdleHack) { //When the FIFO is processing data we must not advance because in this way //the VI will be desynchronized. So, We are waiting until the FIFO finish and //while we process only the events required by the FIFO. while (g_video_backend->Video_IsPossibleWaitingSetDrawDone()) { ProcessFifoWaitEvents(); Common::YieldCPU(); } } idledCycles += DowncountToCycles(PowerPC::ppcState.downcount); PowerPC::ppcState.downcount = 0; }
void Advance() { MoveEvents(); int cyclesExecuted = g_slicelength - DowncountToCycles(PowerPC::ppcState.downcount); g_globalTimer += cyclesExecuted; s_lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; g_lastOCFactor_inverted = 1.0f / s_lastOCFactor; PowerPC::ppcState.downcount = CyclesToDowncount(g_slicelength); globalTimerIsSane = true; while (first && first->time <= g_globalTimer) { //LOG(POWERPC, "[Scheduler] %s (%lld, %lld) ", // event_types[first->type].name ? event_types[first->type].name : "?", (u64)g_globalTimer, (u64)first->time); Event* evt = first; first = first->next; event_types[evt->type].callback(evt->userdata, (int)(g_globalTimer - evt->time)); FreeEvent(evt); } globalTimerIsSane = false; if (!first) { WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000"); PowerPC::ppcState.downcount += CyclesToDowncount(10000); } else { g_slicelength = (int)(first->time - g_globalTimer); if (g_slicelength > maxslicelength) g_slicelength = maxslicelength; PowerPC::ppcState.downcount = CyclesToDowncount(g_slicelength); } // Check for any external exceptions. // It's important to do this after processing events otherwise any exceptions will be delayed until the next slice: // Pokemon Box refuses to boot if the first exception from the audio DMA is received late PowerPC::CheckExternalExceptions(); }
void Advance() { MoveEvents(); int cyclesExecuted = g_slice_length - DowncountToCycles(PowerPC::ppcState.downcount); g_global_timer += cyclesExecuted; s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; g_last_OC_factor_inverted = 1.0f / s_last_OC_factor; g_slice_length = MAX_SLICE_LENGTH; s_is_global_timer_sane = true; while (!s_event_queue.empty() && s_event_queue.front().time <= g_global_timer) { Event evt = std::move(s_event_queue.front()); std::pop_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>()); s_event_queue.pop_back(); // NOTICE_LOG(POWERPC, "[Scheduler] %-20s (%lld, %lld)", evt.type->name->c_str(), // g_global_timer, evt.time); evt.type->callback(evt.userdata, g_global_timer - evt.time); } s_is_global_timer_sane = false; // Still events left (scheduled in the future) if (!s_event_queue.empty()) { g_slice_length = static_cast<int>( std::min<s64>(s_event_queue.front().time - g_global_timer, MAX_SLICE_LENGTH)); } PowerPC::ppcState.downcount = CyclesToDowncount(g_slice_length); // Check for any external exceptions. // It's important to do this after processing events otherwise any exceptions will be delayed // until the next slice: // Pokemon Box refuses to boot if the first exception from the audio DMA is received late PowerPC::CheckExternalExceptions(); }