Example #1
0
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);
	}
}
Example #2
0
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);
	}
}
Example #3
0
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));
    }
}
Example #4
0
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);
	}
}
Example #5
0
// 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;
}
Example #6
0
// 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;
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
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;
}
Example #10
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();
}
Example #11
0
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();
}