Beispiel #1
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);
	}
}
Beispiel #2
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);
	}
}
Beispiel #3
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);
	}
}
Beispiel #4
0
void Init()
{
	lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
	PowerPC::ppcState.downcount = CyclesToDowncount(maxSliceLength);
	slicelength = maxSliceLength;
	globalTimer = 0;
	idledCycles = 0;

	ev_lost = RegisterEvent("_lost_event", &EmptyTimedCallback);
}
Beispiel #5
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();
}
Beispiel #6
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));
    }
}
Beispiel #7
0
void Init()
{
	s_lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
	g_lastOCFactor_inverted = 1.0f / s_lastOCFactor;
	PowerPC::ppcState.downcount = CyclesToDowncount(maxslicelength);
	g_slicelength = maxslicelength;
	g_globalTimer = 0;
	idledCycles = 0;
	globalTimerIsSane = true;

	ev_lost = RegisterEvent("_lost_event", &EmptyTimedCallback);
}
Beispiel #8
0
void Init()
{
    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;
    PowerPC::ppcState.downcount = CyclesToDowncount(MAX_SLICE_LENGTH);
    g_slice_length = MAX_SLICE_LENGTH;
    g_global_timer = 0;
    s_idled_cycles = 0;

    // The time between CoreTiming being intialized and the first call to Advance() is considered
    // the slice boundary between slice -1 and slice 0. Dispatcher loops must call Advance() before
    // executing the first PPC cycle of each slice to prepare the slice length and downcount for
    // that slice.
    s_is_global_timer_sane = true;

    s_event_fifo_id = 0;
    s_ev_lost = RegisterEvent("_lost_event", &EmptyTimedCallback);
}
Beispiel #9
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();
}