Core/SystemTimers: Refactor to class, move to System.
This commit is contained in:
parent
9c91b5edca
commit
07c035e659
|
@ -257,7 +257,8 @@ void Interpreter::WriteControlRegister(u16 val)
|
|||
val &= ~CR_INIT;
|
||||
val |= CR_INIT_CODE;
|
||||
// Number obtained from real hardware on a Wii, but it's not perfectly consistent
|
||||
state.control_reg_init_code_clear_time = SystemTimers::GetFakeTimeBase() + 130;
|
||||
state.control_reg_init_code_clear_time =
|
||||
Core::System::GetInstance().GetSystemTimers().GetFakeTimeBase() + 130;
|
||||
}
|
||||
|
||||
// update cr
|
||||
|
@ -269,10 +270,11 @@ u16 Interpreter::ReadControlRegister()
|
|||
auto& state = m_dsp_core.DSPState();
|
||||
if ((state.control_reg & CR_INIT_CODE) != 0)
|
||||
{
|
||||
if (SystemTimers::GetFakeTimeBase() >= state.control_reg_init_code_clear_time)
|
||||
auto& system = Core::System::GetInstance();
|
||||
if (system.GetSystemTimers().GetFakeTimeBase() >= state.control_reg_init_code_clear_time)
|
||||
state.control_reg &= ~CR_INIT_CODE;
|
||||
else
|
||||
Core::System::GetInstance().GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||
system.GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||
}
|
||||
return state.control_reg;
|
||||
}
|
||||
|
|
|
@ -410,8 +410,9 @@ FifoPlayer& FifoPlayer::GetInstance()
|
|||
void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& info)
|
||||
{
|
||||
// Core timing information
|
||||
auto& vi = Core::System::GetInstance().GetVideoInterface();
|
||||
m_CyclesPerFrame = static_cast<u64>(SystemTimers::GetTicksPerSecond()) *
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& vi = system.GetVideoInterface();
|
||||
m_CyclesPerFrame = static_cast<u64>(system.GetSystemTimers().GetTicksPerSecond()) *
|
||||
vi.GetTargetRefreshRateDenominator() / vi.GetTargetRefreshRateNumerator();
|
||||
m_ElapsedCycles = 0;
|
||||
m_FrameFifoSize = static_cast<u32>(frame.fifoData.size());
|
||||
|
|
|
@ -184,7 +184,7 @@ void AudioInterfaceManager::SetAISSampleRate(SampleRate sample_rate)
|
|||
m_ais_sample_rate_divisor = Get48KHzSampleRateDivisor();
|
||||
}
|
||||
|
||||
m_cpu_cycles_per_sample = static_cast<u64>(SystemTimers::GetTicksPerSecond()) *
|
||||
m_cpu_cycles_per_sample = static_cast<u64>(m_system.GetSystemTimers().GetTicksPerSecond()) *
|
||||
m_ais_sample_rate_divisor / Mixer::FIXED_SAMPLE_RATE_DIVIDEND;
|
||||
SoundStream* sound_stream = m_system.GetSoundStream();
|
||||
sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(m_ais_sample_rate_divisor);
|
||||
|
|
|
@ -55,7 +55,7 @@ u32 DSPHLE::DSP_UpdateRate()
|
|||
{
|
||||
// AX HLE uses 3ms (Wii) or 5ms (GC) timing period
|
||||
// But to be sure, just update the HLE every ms.
|
||||
return SystemTimers::GetTicksPerSecond() / 1000;
|
||||
return Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond() / 1000;
|
||||
}
|
||||
|
||||
void DSPHLE::SendMailToDSP(u32 mail)
|
||||
|
@ -221,7 +221,8 @@ u16 DSPHLE::DSP_WriteControlRegister(u16 value)
|
|||
SetUCode(UCODE_INIT_AUDIO_SYSTEM);
|
||||
temp.DSPInitCode = 1;
|
||||
// Number obtained from real hardware on a Wii, but it's not perfectly consistent
|
||||
m_control_reg_init_code_clear_time = SystemTimers::GetFakeTimeBase() + 130;
|
||||
m_control_reg_init_code_clear_time =
|
||||
Core::System::GetInstance().GetSystemTimers().GetFakeTimeBase() + 130;
|
||||
}
|
||||
|
||||
m_dsp_control.Hex = temp.Hex;
|
||||
|
@ -232,10 +233,11 @@ u16 DSPHLE::DSP_ReadControlRegister()
|
|||
{
|
||||
if (m_dsp_control.DSPInitCode != 0)
|
||||
{
|
||||
if (SystemTimers::GetFakeTimeBase() >= m_control_reg_init_code_clear_time)
|
||||
auto& system = Core::System::GetInstance();
|
||||
if (system.GetSystemTimers().GetFakeTimeBase() >= m_control_reg_init_code_clear_time)
|
||||
m_dsp_control.DSPInitCode = 0;
|
||||
else
|
||||
Core::System::GetInstance().GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||
system.GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||
}
|
||||
return m_dsp_control.Hex;
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ void DVDInterface::DTKStreamingCallback(DIInterruptType interrupt_type,
|
|||
}
|
||||
|
||||
// Read the next chunk of audio data asynchronously.
|
||||
s64 ticks_to_dtk = SystemTimers::GetTicksPerSecond() * s64(m_pending_blocks) *
|
||||
s64 ticks_to_dtk = m_system.GetSystemTimers().GetTicksPerSecond() * s64(m_pending_blocks) *
|
||||
StreamADPCM::SAMPLES_PER_BLOCK * sample_rate_divisor /
|
||||
Mixer::FIXED_SAMPLE_RATE_DIVIDEND;
|
||||
ticks_to_dtk -= cycles_late;
|
||||
|
@ -474,7 +474,8 @@ void DVDInterface::ChangeDisc(const std::string& new_path)
|
|||
EjectDisc(EjectCause::User);
|
||||
|
||||
m_disc_path_to_insert = new_path;
|
||||
m_system.GetCoreTiming().ScheduleEvent(SystemTimers::GetTicksPerSecond(), m_insert_disc);
|
||||
m_system.GetCoreTiming().ScheduleEvent(m_system.GetSystemTimers().GetTicksPerSecond(),
|
||||
m_insert_disc);
|
||||
Movie::SignalDiscChange(new_path);
|
||||
|
||||
for (size_t i = 0; i < m_auto_disc_change_paths.size(); ++i)
|
||||
|
@ -1090,7 +1091,7 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
|||
m_system.GetDVDThread().IsInsertedDiscRunning() && !m_auto_disc_change_paths.empty())
|
||||
{
|
||||
m_system.GetCoreTiming().ScheduleEvent(
|
||||
force_eject ? 0 : SystemTimers::GetTicksPerSecond() / 2, m_auto_change_disc);
|
||||
force_eject ? 0 : m_system.GetSystemTimers().GetTicksPerSecond() / 2, m_auto_change_disc);
|
||||
OSD::AddMessage("Changing discs automatically...", OSD::Duration::NORMAL);
|
||||
}
|
||||
else if (force_eject)
|
||||
|
@ -1181,7 +1182,7 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type)
|
|||
{
|
||||
// TODO: Needs testing to determine if MINIMUM_COMMAND_LATENCY_US is accurate for this
|
||||
m_system.GetCoreTiming().ScheduleEvent(
|
||||
MINIMUM_COMMAND_LATENCY_US * (SystemTimers::GetTicksPerSecond() / 1000000),
|
||||
MINIMUM_COMMAND_LATENCY_US * (m_system.GetSystemTimers().GetTicksPerSecond() / 1000000),
|
||||
m_finish_executing_command, PackFinishExecutingCommandUserdata(reply_type, interrupt_type));
|
||||
}
|
||||
}
|
||||
|
@ -1202,7 +1203,7 @@ void DVDInterface::PerformDecryptingRead(u32 position, u32 length, u32 output_ad
|
|||
{
|
||||
// TODO: Needs testing to determine if MINIMUM_COMMAND_LATENCY_US is accurate for this
|
||||
m_system.GetCoreTiming().ScheduleEvent(
|
||||
MINIMUM_COMMAND_LATENCY_US * (SystemTimers::GetTicksPerSecond() / 1000000),
|
||||
MINIMUM_COMMAND_LATENCY_US * (m_system.GetSystemTimers().GetTicksPerSecond() / 1000000),
|
||||
m_finish_executing_command, PackFinishExecutingCommandUserdata(reply_type, interrupt_type));
|
||||
}
|
||||
}
|
||||
|
@ -1219,7 +1220,7 @@ void DVDInterface::ForceOutOfBoundsRead(ReplyType reply_type)
|
|||
// TODO: Needs testing to determine if MINIMUM_COMMAND_LATENCY_US is accurate for this
|
||||
const DIInterruptType interrupt_type = DIInterruptType::DEINT;
|
||||
m_system.GetCoreTiming().ScheduleEvent(
|
||||
MINIMUM_COMMAND_LATENCY_US * (SystemTimers::GetTicksPerSecond() / 1000000),
|
||||
MINIMUM_COMMAND_LATENCY_US * (m_system.GetSystemTimers().GetTicksPerSecond() / 1000000),
|
||||
m_finish_executing_command, PackFinishExecutingCommandUserdata(reply_type, interrupt_type));
|
||||
}
|
||||
|
||||
|
@ -1321,7 +1322,7 @@ void DVDInterface::ScheduleReads(u64 offset, u32 length, const DiscIO::Partition
|
|||
|
||||
auto& core_timing = m_system.GetCoreTiming();
|
||||
const u64 current_time = core_timing.GetTicks();
|
||||
const u32 ticks_per_second = SystemTimers::GetTicksPerSecond();
|
||||
const u32 ticks_per_second = m_system.GetSystemTimers().GetTicksPerSecond();
|
||||
auto& dvd_thread = m_system.GetDVDThread();
|
||||
const bool wii_disc = dvd_thread.GetDiscType() == DiscIO::Platform::WiiDisc;
|
||||
|
||||
|
@ -1400,7 +1401,7 @@ void DVDInterface::ScheduleReads(u64 offset, u32 length, const DiscIO::Partition
|
|||
length, output_address);
|
||||
|
||||
s64 ticks_until_completion =
|
||||
READ_COMMAND_LATENCY_US * (SystemTimers::GetTicksPerSecond() / 1000000);
|
||||
READ_COMMAND_LATENCY_US * (m_system.GetSystemTimers().GetTicksPerSecond() / 1000000);
|
||||
|
||||
u32 buffered_blocks = 0;
|
||||
u32 unbuffered_blocks = 0;
|
||||
|
@ -1528,7 +1529,7 @@ void DVDInterface::ScheduleReads(u64 offset, u32 length, const DiscIO::Partition
|
|||
"Schedule reads: ECC blocks unbuffered={}, buffered={}, "
|
||||
"ticks={}, time={} us",
|
||||
unbuffered_blocks, buffered_blocks, ticks_until_completion,
|
||||
ticks_until_completion * 1000000 / SystemTimers::GetTicksPerSecond());
|
||||
ticks_until_completion * 1000000 / m_system.GetSystemTimers().GetTicksPerSecond());
|
||||
}
|
||||
|
||||
} // namespace DVD
|
||||
|
|
|
@ -301,7 +301,7 @@ void DVDThread::FinishRead(u64 id, s64 cycles_late)
|
|||
request.realtime_done_us - request.realtime_started_us,
|
||||
Common::Timer::NowUs() - request.realtime_started_us,
|
||||
(m_system.GetCoreTiming().GetTicks() - request.time_started_ticks) /
|
||||
(SystemTimers::GetTicksPerSecond() / 1000000));
|
||||
(m_system.GetSystemTimers().GetTicksPerSecond() / 1000000));
|
||||
|
||||
auto& dvd_interface = m_system.GetDVDInterface();
|
||||
DVD::DIInterruptType interrupt;
|
||||
|
|
|
@ -208,9 +208,9 @@ void ExpansionInterfaceManager::ChangeDevice(u8 channel, u8 device_num, EXIDevic
|
|||
core_timing.ScheduleEvent(0, m_event_type_change_device,
|
||||
((u64)channel << 32) | ((u64)EXIDeviceType::None << 16) | device_num,
|
||||
from_thread);
|
||||
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond(), m_event_type_change_device,
|
||||
((u64)channel << 32) | ((u64)device_type << 16) | device_num,
|
||||
from_thread);
|
||||
core_timing.ScheduleEvent(
|
||||
m_system.GetSystemTimers().GetTicksPerSecond(), m_event_type_change_device,
|
||||
((u64)channel << 32) | ((u64)device_type << 16) | device_num, from_thread);
|
||||
}
|
||||
|
||||
CEXIChannel* ExpansionInterfaceManager::GetChannel(u32 index)
|
||||
|
|
|
@ -411,19 +411,20 @@ u32 CEXIIPL::GetEmulatedTime(Core::System& system, u32 epoch)
|
|||
ltime = Movie::GetRecordingStartTime();
|
||||
|
||||
// let's keep time moving forward, regardless of what it starts at
|
||||
ltime += system.GetCoreTiming().GetTicks() / SystemTimers::GetTicksPerSecond();
|
||||
ltime += system.GetCoreTiming().GetTicks() / system.GetSystemTimers().GetTicksPerSecond();
|
||||
}
|
||||
else if (NetPlay::IsNetPlayRunning())
|
||||
{
|
||||
ltime = NetPlay_GetEmulatedTime();
|
||||
|
||||
// let's keep time moving forward, regardless of what it starts at
|
||||
ltime += system.GetCoreTiming().GetTicks() / SystemTimers::GetTicksPerSecond();
|
||||
ltime += system.GetCoreTiming().GetTicks() / system.GetSystemTimers().GetTicksPerSecond();
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(!Core::WantsDeterminism());
|
||||
ltime = Common::Timer::GetLocalTimeSinceJan1970() - SystemTimers::GetLocalTimeRTCOffset();
|
||||
ltime = Common::Timer::GetLocalTimeSinceJan1970() -
|
||||
system.GetSystemTimers().GetLocalTimeRTCOffset();
|
||||
}
|
||||
|
||||
return static_cast<u32>(ltime) - epoch;
|
||||
|
|
|
@ -532,7 +532,7 @@ void CEXIMemoryCard::DMARead(u32 addr, u32 size)
|
|||
|
||||
// Schedule transfer complete later based on read speed
|
||||
m_system.GetCoreTiming().ScheduleEvent(
|
||||
size * (SystemTimers::GetTicksPerSecond() / MC_TRANSFER_RATE_READ),
|
||||
size * (m_system.GetSystemTimers().GetTicksPerSecond() / MC_TRANSFER_RATE_READ),
|
||||
s_et_transfer_complete[m_card_slot], static_cast<u64>(m_card_slot));
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ void CEXIMemoryCard::DMAWrite(u32 addr, u32 size)
|
|||
|
||||
// Schedule transfer complete later based on write speed
|
||||
m_system.GetCoreTiming().ScheduleEvent(
|
||||
size * (SystemTimers::GetTicksPerSecond() / MC_TRANSFER_RATE_WRITE),
|
||||
size * (m_system.GetSystemTimers().GetTicksPerSecond() / MC_TRANSFER_RATE_WRITE),
|
||||
s_et_transfer_complete[m_card_slot], static_cast<u64>(m_card_slot));
|
||||
}
|
||||
} // namespace ExpansionInterface
|
||||
|
|
|
@ -264,7 +264,7 @@ void CEXIMic::SetCS(int cs)
|
|||
|
||||
void CEXIMic::UpdateNextInterruptTicks()
|
||||
{
|
||||
int diff = (SystemTimers::GetTicksPerSecond() / sample_rate) * buff_size_samples;
|
||||
int diff = (m_system.GetSystemTimers().GetTicksPerSecond() / sample_rate) * buff_size_samples;
|
||||
next_int_ticks = m_system.GetCoreTiming().GetTicks() + diff;
|
||||
m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, diff);
|
||||
}
|
||||
|
|
|
@ -568,7 +568,7 @@ void Core::RunUntil(u64 gc_ticks)
|
|||
if (static_cast<s64>(gc_ticks - m_last_gc_ticks) <= 0)
|
||||
return;
|
||||
|
||||
const u64 gc_frequency = SystemTimers::GetTicksPerSecond();
|
||||
const u64 gc_frequency = ::Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond();
|
||||
const u32 core_frequency = GetCoreFrequency(m_core);
|
||||
|
||||
mTimingSchedule(m_core->timing, &m_event,
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace HW
|
|||
void Init(Core::System& system, const Sram* override_sram)
|
||||
{
|
||||
system.GetCoreTiming().Init();
|
||||
SystemTimers::PreInit();
|
||||
system.GetSystemTimers().PreInit();
|
||||
|
||||
State::Init();
|
||||
|
||||
|
@ -52,7 +52,7 @@ void Init(Core::System& system, const Sram* override_sram)
|
|||
system.GetDVDInterface().Init();
|
||||
system.GetGPFifo().Init();
|
||||
system.GetCPU().Init(Config::Get(Config::MAIN_CPU_CORE));
|
||||
SystemTimers::Init();
|
||||
system.GetSystemTimers().Init();
|
||||
|
||||
if (SConfig::GetInstance().bWii)
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ void Shutdown(Core::System& system)
|
|||
IOS::HLE::Shutdown(); // Depends on Memory
|
||||
IOS::Shutdown();
|
||||
|
||||
SystemTimers::Shutdown();
|
||||
system.GetSystemTimers().Shutdown();
|
||||
system.GetCPU().Shutdown();
|
||||
system.GetDVDInterface().Shutdown();
|
||||
system.GetDSP().Shutdown();
|
||||
|
|
|
@ -262,8 +262,8 @@ void ProcessorInterfaceManager::ResetButton_Tap()
|
|||
core_timing.ScheduleEvent(0, m_event_type_toggle_reset_button, true, CoreTiming::FromThread::ANY);
|
||||
core_timing.ScheduleEvent(0, m_event_type_ios_notify_reset_button, 0,
|
||||
CoreTiming::FromThread::ANY);
|
||||
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond() / 2, m_event_type_toggle_reset_button,
|
||||
false, CoreTiming::FromThread::ANY);
|
||||
core_timing.ScheduleEvent(m_system.GetSystemTimers().GetTicksPerSecond() / 2,
|
||||
m_event_type_toggle_reset_button, false, CoreTiming::FromThread::ANY);
|
||||
}
|
||||
|
||||
void ProcessorInterfaceManager::PowerButton_Tap()
|
||||
|
|
|
@ -525,7 +525,7 @@ void SerialInterfaceManager::ChangeDeviceDeterministic(SIDevices device, int cha
|
|||
|
||||
// Prevent additional device changes on this channel for one second.
|
||||
m_channel[channel].has_recent_device_change = true;
|
||||
m_system.GetCoreTiming().ScheduleEvent(SystemTimers::GetTicksPerSecond(),
|
||||
m_system.GetCoreTiming().ScheduleEvent(m_system.GetSystemTimers().GetTicksPerSecond(),
|
||||
m_event_type_change_device, channel);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "Core/HW/SI/SI_DeviceKeyboard.h"
|
||||
#include "Core/HW/SI/SI_DeviceNull.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
namespace SerialInterface
|
||||
{
|
||||
|
@ -142,10 +143,10 @@ int SIDevice_GetGBATransferTime(EBufferCommands cmd)
|
|||
}
|
||||
}
|
||||
|
||||
u64 cycles =
|
||||
(gba_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GBA_BITS_PER_SECOND) +
|
||||
(gc_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GC_BITS_PER_SECOND) +
|
||||
(stop_bits_ns * SystemTimers::GetTicksPerSecond() / 1000000000LL);
|
||||
const u32 ticks_per_second = Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond();
|
||||
const u64 cycles = (gba_bytes_transferred * 8 * ticks_per_second / GBA_BITS_PER_SECOND) +
|
||||
(gc_bytes_transferred * 8 * ticks_per_second / GC_BITS_PER_SECOND) +
|
||||
(stop_bits_ns * ticks_per_second / 1000000000LL);
|
||||
return static_cast<int>(cycles);
|
||||
}
|
||||
|
||||
|
|
|
@ -154,14 +154,14 @@ void GBASockServer::ClockSync(Core::System& system)
|
|||
{
|
||||
s_num_connected++;
|
||||
m_last_time_slice = core_timing.GetTicks();
|
||||
time_slice = (u32)(SystemTimers::GetTicksPerSecond() / 60);
|
||||
time_slice = (u32)(system.GetSystemTimers().GetTicksPerSecond() / 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_slice = (u32)(core_timing.GetTicks() - m_last_time_slice);
|
||||
}
|
||||
|
||||
time_slice = (u32)((u64)time_slice * 16777216 / SystemTimers::GetTicksPerSecond());
|
||||
time_slice = (u32)((u64)time_slice * 16777216 / system.GetSystemTimers().GetTicksPerSecond());
|
||||
m_last_time_slice = core_timing.GetTicks();
|
||||
char bytes[4] = {0, 0, 0, 0};
|
||||
bytes[0] = (time_slice >> 24) & 0xff;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace SerialInterface
|
|||
{
|
||||
static s64 GetSyncInterval()
|
||||
{
|
||||
return SystemTimers::GetTicksPerSecond() / 1000;
|
||||
return Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond() / 1000;
|
||||
}
|
||||
|
||||
CSIDevice_GBAEmu::CSIDevice_GBAEmu(Core::System& system, SIDevices device, int device_number)
|
||||
|
|
|
@ -264,7 +264,8 @@ CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
|
|||
if (m_last_button_combo != COMBO_NONE)
|
||||
{
|
||||
const u64 current_time = m_system.GetCoreTiming().GetTicks();
|
||||
if (u32(current_time - m_timer_button_combo_start) > SystemTimers::GetTicksPerSecond() * 3)
|
||||
const u32 ticks_per_second = m_system.GetSystemTimers().GetTicksPerSecond();
|
||||
if (u32(current_time - m_timer_button_combo_start) > ticks_per_second * 3)
|
||||
{
|
||||
if (m_last_button_combo == COMBO_RESET)
|
||||
{
|
||||
|
|
|
@ -71,97 +71,88 @@ IPC_HLE_PERIOD: For the Wii Remote this is the call schedule:
|
|||
|
||||
namespace SystemTimers
|
||||
{
|
||||
namespace
|
||||
{
|
||||
CoreTiming::EventType* et_Dec;
|
||||
CoreTiming::EventType* et_VI;
|
||||
CoreTiming::EventType* et_AudioDMA;
|
||||
CoreTiming::EventType* et_DSP;
|
||||
CoreTiming::EventType* et_IPC_HLE;
|
||||
CoreTiming::EventType* et_GPU_sleeper;
|
||||
CoreTiming::EventType* et_perf_tracker;
|
||||
// PatchEngine updates every 1/60th of a second by default
|
||||
CoreTiming::EventType* et_PatchEngine;
|
||||
|
||||
u32 s_cpu_core_clock = 486000000u; // 486 mhz (its not 485, stop bugging me!)
|
||||
|
||||
// This is completely arbitrary. If we find that we need lower latency,
|
||||
// we can just increase this number.
|
||||
int s_ipc_hle_period;
|
||||
|
||||
// Custom RTC
|
||||
s64 s_localtime_rtc_offset = 0;
|
||||
|
||||
// DSP/CPU timeslicing.
|
||||
void DSPCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::DSPCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
// splits up the cycle budget in case lle is used
|
||||
// for hle, just gives all of the slice to hle
|
||||
auto& dsp = system.GetDSP();
|
||||
dsp.UpdateDSPSlice(static_cast<int>(dsp.GetDSPEmulator()->DSP_UpdateRate() - cyclesLate));
|
||||
system.GetCoreTiming().ScheduleEvent(dsp.GetDSPEmulator()->DSP_UpdateRate() - cyclesLate, et_DSP);
|
||||
dsp.UpdateDSPSlice(static_cast<int>(dsp.GetDSPEmulator()->DSP_UpdateRate() - cycles_late));
|
||||
system.GetCoreTiming().ScheduleEvent(dsp.GetDSPEmulator()->DSP_UpdateRate() - cycles_late,
|
||||
system.GetSystemTimers().m_event_type_dsp);
|
||||
}
|
||||
|
||||
int GetAudioDMACallbackPeriod()
|
||||
static int GetAudioDMACallbackPeriod(u32 cpu_core_clock, u32 aid_sample_rate_divisor)
|
||||
{
|
||||
// System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA
|
||||
auto& system = Core::System::GetInstance();
|
||||
return static_cast<u64>(s_cpu_core_clock) * system.GetAudioInterface().GetAIDSampleRateDivisor() /
|
||||
return static_cast<u64>(cpu_core_clock) * aid_sample_rate_divisor /
|
||||
(Mixer::FIXED_SAMPLE_RATE_DIVIDEND * 4 / 32);
|
||||
}
|
||||
|
||||
void AudioDMACallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::AudioDMACallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
system.GetDSP().UpdateAudioDMA(); // Push audio to speakers.
|
||||
system.GetCoreTiming().ScheduleEvent(GetAudioDMACallbackPeriod() - cyclesLate, et_AudioDMA);
|
||||
auto& system_timers = system.GetSystemTimers();
|
||||
const int callback_period = GetAudioDMACallbackPeriod(
|
||||
system_timers.m_cpu_core_clock, system.GetAudioInterface().GetAIDSampleRateDivisor());
|
||||
system.GetCoreTiming().ScheduleEvent(callback_period - cycles_late,
|
||||
system_timers.m_event_type_audio_dma);
|
||||
}
|
||||
|
||||
void IPC_HLE_UpdateCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::IPC_HLE_UpdateCallback(Core::System& system, u64 userdata,
|
||||
s64 cycles_late)
|
||||
{
|
||||
if (SConfig::GetInstance().bWii)
|
||||
{
|
||||
IOS::HLE::GetIOS()->UpdateDevices();
|
||||
system.GetCoreTiming().ScheduleEvent(s_ipc_hle_period - cyclesLate, et_IPC_HLE);
|
||||
auto& system_timers = system.GetSystemTimers();
|
||||
system.GetCoreTiming().ScheduleEvent(system_timers.m_ipc_hle_period - cycles_late,
|
||||
system_timers.m_event_type_ipc_hle);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUSleepCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::GPUSleepCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
system.GetFifo().GpuMaySleep();
|
||||
|
||||
// We want to call GpuMaySleep at about 1000hz so
|
||||
// that the thread can sleep while not doing anything.
|
||||
core_timing.ScheduleEvent(GetTicksPerSecond() / 1000 - cyclesLate, et_GPU_sleeper);
|
||||
auto& system_timers = system.GetSystemTimers();
|
||||
core_timing.ScheduleEvent(system_timers.GetTicksPerSecond() / 1000 - cycles_late,
|
||||
system_timers.m_event_type_gpu_sleeper);
|
||||
}
|
||||
|
||||
void PerfTrackerCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::PerfTrackerCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
g_perf_metrics.CountPerformanceMarker(system, cyclesLate);
|
||||
g_perf_metrics.CountPerformanceMarker(system, cycles_late);
|
||||
|
||||
// Call this performance tracker again in 1/100th of a second.
|
||||
// The tracker stores 256 values so this will let us summarize the last 2.56 seconds.
|
||||
// The performance metrics require this to be called at 100hz for the speed% is correct.
|
||||
core_timing.ScheduleEvent(GetTicksPerSecond() / 100 - cyclesLate, et_perf_tracker);
|
||||
auto& system_timers = system.GetSystemTimers();
|
||||
core_timing.ScheduleEvent(system_timers.GetTicksPerSecond() / 100 - cycles_late,
|
||||
system_timers.m_event_type_perf_tracker);
|
||||
}
|
||||
|
||||
void VICallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::VICallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
auto& vi = system.GetVideoInterface();
|
||||
vi.Update(core_timing.GetTicks() - cyclesLate);
|
||||
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine() - cyclesLate, et_VI);
|
||||
vi.Update(core_timing.GetTicks() - cycles_late);
|
||||
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine() - cycles_late,
|
||||
system.GetSystemTimers().m_event_type_vi);
|
||||
}
|
||||
|
||||
void DecrementerCallback(Core::System& system, u64 userdata, s64 cyclesLate)
|
||||
void SystemTimersManager::DecrementerCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
auto& ppc_state = system.GetPPCState();
|
||||
ppc_state.spr[SPR_DEC] = 0xFFFFFFFF;
|
||||
ppc_state.Exceptions |= EXCEPTION_DECREMENTER;
|
||||
}
|
||||
|
||||
void PatchEngineCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
void SystemTimersManager::PatchEngineCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
||||
{
|
||||
// We have 2 periods, a 1000 cycle error period and the VI period.
|
||||
// We have to carefully combine these together so that we stay on the VI period without drifting.
|
||||
|
@ -183,86 +174,87 @@ void PatchEngineCallback(Core::System& system, u64 userdata, s64 cycles_late)
|
|||
cycles_pruned += next_schedule;
|
||||
}
|
||||
|
||||
system.GetCoreTiming().ScheduleEvent(next_schedule, et_PatchEngine, cycles_pruned);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
u32 GetTicksPerSecond()
|
||||
{
|
||||
return s_cpu_core_clock;
|
||||
system.GetCoreTiming().ScheduleEvent(
|
||||
next_schedule, system.GetSystemTimers().m_event_type_patch_engine, cycles_pruned);
|
||||
}
|
||||
|
||||
void DecrementerSet()
|
||||
SystemTimersManager::SystemTimersManager(Core::System& system) : m_system(system)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
auto& ppc_state = system.GetPPCState();
|
||||
}
|
||||
|
||||
SystemTimersManager::~SystemTimersManager() = default;
|
||||
|
||||
u32 SystemTimersManager::GetTicksPerSecond() const
|
||||
{
|
||||
return m_cpu_core_clock;
|
||||
}
|
||||
|
||||
void SystemTimersManager::DecrementerSet()
|
||||
{
|
||||
auto& core_timing = m_system.GetCoreTiming();
|
||||
auto& ppc_state = m_system.GetPPCState();
|
||||
|
||||
u32 decValue = ppc_state.spr[SPR_DEC];
|
||||
|
||||
core_timing.RemoveEvent(et_Dec);
|
||||
core_timing.RemoveEvent(m_event_type_decrementer);
|
||||
if ((decValue & 0x80000000) == 0)
|
||||
{
|
||||
core_timing.SetFakeDecStartTicks(core_timing.GetTicks());
|
||||
core_timing.SetFakeDecStartValue(decValue);
|
||||
|
||||
core_timing.ScheduleEvent(decValue * TIMER_RATIO, et_Dec);
|
||||
core_timing.ScheduleEvent(decValue * TIMER_RATIO, m_event_type_decrementer);
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetFakeDecrementer()
|
||||
u32 SystemTimersManager::GetFakeDecrementer() const
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
const auto& core_timing = m_system.GetCoreTiming();
|
||||
return (core_timing.GetFakeDecStartValue() -
|
||||
(u32)((core_timing.GetTicks() - core_timing.GetFakeDecStartTicks()) / TIMER_RATIO));
|
||||
}
|
||||
|
||||
void TimeBaseSet()
|
||||
void SystemTimersManager::TimeBaseSet()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
auto& core_timing = m_system.GetCoreTiming();
|
||||
core_timing.SetFakeTBStartTicks(core_timing.GetTicks());
|
||||
core_timing.SetFakeTBStartValue(system.GetPowerPC().ReadFullTimeBaseValue());
|
||||
core_timing.SetFakeTBStartValue(m_system.GetPowerPC().ReadFullTimeBaseValue());
|
||||
}
|
||||
|
||||
u64 GetFakeTimeBase()
|
||||
u64 SystemTimersManager::GetFakeTimeBase() const
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
const auto& core_timing = m_system.GetCoreTiming();
|
||||
return core_timing.GetFakeTBStartValue() +
|
||||
((core_timing.GetTicks() - core_timing.GetFakeTBStartTicks()) / TIMER_RATIO);
|
||||
}
|
||||
|
||||
s64 GetLocalTimeRTCOffset()
|
||||
s64 SystemTimersManager::GetLocalTimeRTCOffset() const
|
||||
{
|
||||
return s_localtime_rtc_offset;
|
||||
return m_localtime_rtc_offset;
|
||||
}
|
||||
|
||||
double GetEstimatedEmulationPerformance()
|
||||
double SystemTimersManager::GetEstimatedEmulationPerformance() const
|
||||
{
|
||||
return g_perf_metrics.GetMaxSpeed();
|
||||
}
|
||||
|
||||
// split from Init to break a circular dependency between VideoInterface::Init and
|
||||
// SystemTimers::Init
|
||||
void PreInit()
|
||||
void SystemTimersManager::PreInit()
|
||||
{
|
||||
ChangePPCClock(SConfig::GetInstance().bWii ? Mode::Wii : Mode::GC);
|
||||
}
|
||||
|
||||
void ChangePPCClock(Mode mode)
|
||||
void SystemTimersManager::ChangePPCClock(Mode mode)
|
||||
{
|
||||
const u32 previous_clock = s_cpu_core_clock;
|
||||
const u32 previous_clock = m_cpu_core_clock;
|
||||
if (mode == Mode::Wii)
|
||||
s_cpu_core_clock = 729000000u;
|
||||
m_cpu_core_clock = 729000000u;
|
||||
else
|
||||
s_cpu_core_clock = 486000000u;
|
||||
Core::System::GetInstance().GetCoreTiming().AdjustEventQueueTimes(s_cpu_core_clock,
|
||||
previous_clock);
|
||||
m_cpu_core_clock = 486000000u;
|
||||
m_system.GetCoreTiming().AdjustEventQueueTimes(m_cpu_core_clock, previous_clock);
|
||||
}
|
||||
|
||||
void Init()
|
||||
void SystemTimersManager::Init()
|
||||
{
|
||||
if (SConfig::GetInstance().bWii)
|
||||
{
|
||||
|
@ -270,55 +262,58 @@ void Init()
|
|||
// Now the 1500 is a pure assumption
|
||||
// We need to figure out the real frequency though
|
||||
const int freq = 1500;
|
||||
s_ipc_hle_period = GetTicksPerSecond() / freq;
|
||||
m_ipc_hle_period = GetTicksPerSecond() / freq;
|
||||
}
|
||||
|
||||
Common::Timer::IncreaseResolution();
|
||||
// store and convert localtime at boot to timebase ticks
|
||||
if (Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE))
|
||||
{
|
||||
s_localtime_rtc_offset =
|
||||
m_localtime_rtc_offset =
|
||||
Common::Timer::GetLocalTimeSinceJan1970() - Config::Get(Config::MAIN_CUSTOM_RTC_VALUE);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
auto& vi = system.GetVideoInterface();
|
||||
auto& core_timing = m_system.GetCoreTiming();
|
||||
auto& vi = m_system.GetVideoInterface();
|
||||
|
||||
core_timing.SetFakeTBStartValue(static_cast<u64>(s_cpu_core_clock / TIMER_RATIO) *
|
||||
core_timing.SetFakeTBStartValue(static_cast<u64>(m_cpu_core_clock / TIMER_RATIO) *
|
||||
static_cast<u64>(ExpansionInterface::CEXIIPL::GetEmulatedTime(
|
||||
system, ExpansionInterface::CEXIIPL::GC_EPOCH)));
|
||||
m_system, ExpansionInterface::CEXIIPL::GC_EPOCH)));
|
||||
|
||||
core_timing.SetFakeTBStartTicks(core_timing.GetTicks());
|
||||
|
||||
core_timing.SetFakeDecStartValue(0xFFFFFFFF);
|
||||
core_timing.SetFakeDecStartTicks(core_timing.GetTicks());
|
||||
|
||||
et_Dec = core_timing.RegisterEvent("DecCallback", DecrementerCallback);
|
||||
et_VI = core_timing.RegisterEvent("VICallback", VICallback);
|
||||
et_DSP = core_timing.RegisterEvent("DSPCallback", DSPCallback);
|
||||
et_AudioDMA = core_timing.RegisterEvent("AudioDMACallback", AudioDMACallback);
|
||||
et_IPC_HLE = core_timing.RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
||||
et_GPU_sleeper = core_timing.RegisterEvent("GPUSleeper", GPUSleepCallback);
|
||||
et_perf_tracker = core_timing.RegisterEvent("PerfTracker", PerfTrackerCallback);
|
||||
et_PatchEngine = core_timing.RegisterEvent("PatchEngine", PatchEngineCallback);
|
||||
m_event_type_decrementer = core_timing.RegisterEvent("DecCallback", DecrementerCallback);
|
||||
m_event_type_vi = core_timing.RegisterEvent("VICallback", VICallback);
|
||||
m_event_type_dsp = core_timing.RegisterEvent("DSPCallback", DSPCallback);
|
||||
m_event_type_audio_dma = core_timing.RegisterEvent("AudioDMACallback", AudioDMACallback);
|
||||
m_event_type_ipc_hle =
|
||||
core_timing.RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
||||
m_event_type_gpu_sleeper = core_timing.RegisterEvent("GPUSleeper", GPUSleepCallback);
|
||||
m_event_type_perf_tracker = core_timing.RegisterEvent("PerfTracker", PerfTrackerCallback);
|
||||
m_event_type_patch_engine = core_timing.RegisterEvent("PatchEngine", PatchEngineCallback);
|
||||
|
||||
core_timing.ScheduleEvent(0, et_perf_tracker);
|
||||
core_timing.ScheduleEvent(0, et_GPU_sleeper);
|
||||
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine(), et_VI);
|
||||
core_timing.ScheduleEvent(0, et_DSP);
|
||||
core_timing.ScheduleEvent(GetAudioDMACallbackPeriod(), et_AudioDMA);
|
||||
core_timing.ScheduleEvent(0, m_event_type_perf_tracker);
|
||||
core_timing.ScheduleEvent(0, m_event_type_gpu_sleeper);
|
||||
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine(), m_event_type_vi);
|
||||
core_timing.ScheduleEvent(0, m_event_type_dsp);
|
||||
|
||||
core_timing.ScheduleEvent(vi.GetTicksPerField(), et_PatchEngine);
|
||||
const int audio_dma_callback_period = GetAudioDMACallbackPeriod(
|
||||
m_cpu_core_clock, m_system.GetAudioInterface().GetAIDSampleRateDivisor());
|
||||
core_timing.ScheduleEvent(audio_dma_callback_period, m_event_type_audio_dma);
|
||||
|
||||
core_timing.ScheduleEvent(vi.GetTicksPerField(), m_event_type_patch_engine);
|
||||
|
||||
if (SConfig::GetInstance().bWii)
|
||||
core_timing.ScheduleEvent(s_ipc_hle_period, et_IPC_HLE);
|
||||
core_timing.ScheduleEvent(m_ipc_hle_period, m_event_type_ipc_hle);
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
void SystemTimersManager::Shutdown()
|
||||
{
|
||||
Common::Timer::RestoreResolution();
|
||||
s_localtime_rtc_offset = 0;
|
||||
m_localtime_rtc_offset = 0;
|
||||
}
|
||||
|
||||
} // namespace SystemTimers
|
||||
|
|
|
@ -5,6 +5,15 @@
|
|||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class System;
|
||||
}
|
||||
namespace CoreTiming
|
||||
{
|
||||
struct EventType;
|
||||
}
|
||||
|
||||
namespace SystemTimers
|
||||
{
|
||||
/*
|
||||
|
@ -47,29 +56,70 @@ enum class Mode
|
|||
Wii,
|
||||
};
|
||||
|
||||
u32 GetTicksPerSecond();
|
||||
void PreInit();
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void ChangePPCClock(Mode mode);
|
||||
class SystemTimersManager
|
||||
{
|
||||
public:
|
||||
explicit SystemTimersManager(Core::System& system);
|
||||
SystemTimersManager(const SystemTimersManager& other) = delete;
|
||||
SystemTimersManager(SystemTimersManager&& other) = delete;
|
||||
SystemTimersManager& operator=(const SystemTimersManager& other) = delete;
|
||||
SystemTimersManager& operator=(SystemTimersManager&& other) = delete;
|
||||
~SystemTimersManager();
|
||||
|
||||
// Notify timing system that somebody wrote to the decrementer
|
||||
void DecrementerSet();
|
||||
u32 GetFakeDecrementer();
|
||||
u32 GetTicksPerSecond() const;
|
||||
void PreInit();
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void ChangePPCClock(Mode mode);
|
||||
|
||||
void TimeBaseSet();
|
||||
u64 GetFakeTimeBase();
|
||||
// Custom RTC
|
||||
s64 GetLocalTimeRTCOffset();
|
||||
// Notify timing system that somebody wrote to the decrementer
|
||||
void DecrementerSet();
|
||||
u32 GetFakeDecrementer() const;
|
||||
|
||||
// Returns an estimate of how fast/slow the emulation is running (excluding throttling induced sleep
|
||||
// time). The estimate is computed over the last 1s of emulated time. Example values:
|
||||
//
|
||||
// - 0.5: the emulator is running at 50% speed (falling behind).
|
||||
// - 1.0: the emulator is running at 100% speed.
|
||||
// - 2.0: the emulator is running at 200% speed (or 100% speed but sleeping half of the time).
|
||||
double GetEstimatedEmulationPerformance();
|
||||
void TimeBaseSet();
|
||||
u64 GetFakeTimeBase() const;
|
||||
// Custom RTC
|
||||
s64 GetLocalTimeRTCOffset() const;
|
||||
|
||||
// Returns an estimate of how fast/slow the emulation is running (excluding throttling induced
|
||||
// sleep time). The estimate is computed over the last 1s of emulated time. Example values:
|
||||
//
|
||||
// - 0.5: the emulator is running at 50% speed (falling behind).
|
||||
// - 1.0: the emulator is running at 100% speed.
|
||||
// - 2.0: the emulator is running at 200% speed (or 100% speed but sleeping half of the time).
|
||||
double GetEstimatedEmulationPerformance() const;
|
||||
|
||||
private:
|
||||
static void DSPCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void AudioDMACallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void IPC_HLE_UpdateCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void GPUSleepCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void PerfTrackerCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void VICallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void DecrementerCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
static void PatchEngineCallback(Core::System& system, u64 userdata, s64 cycles_late);
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
u32 m_cpu_core_clock = 486000000u; // 486 mhz
|
||||
|
||||
// This is completely arbitrary. If we find that we need lower latency,
|
||||
// we can just increase this number.
|
||||
int m_ipc_hle_period = 0;
|
||||
|
||||
// Custom RTC
|
||||
s64 m_localtime_rtc_offset = 0;
|
||||
|
||||
CoreTiming::EventType* m_event_type_decrementer = nullptr;
|
||||
CoreTiming::EventType* m_event_type_vi = nullptr;
|
||||
CoreTiming::EventType* m_event_type_audio_dma = nullptr;
|
||||
CoreTiming::EventType* m_event_type_dsp = nullptr;
|
||||
CoreTiming::EventType* m_event_type_ipc_hle = nullptr;
|
||||
CoreTiming::EventType* m_event_type_gpu_sleeper = nullptr;
|
||||
CoreTiming::EventType* m_event_type_perf_tracker = nullptr;
|
||||
// PatchEngine updates every 1/60th of a second by default
|
||||
CoreTiming::EventType* m_event_type_patch_engine = nullptr;
|
||||
};
|
||||
} // namespace SystemTimers
|
||||
|
||||
inline namespace SystemTimersLiterals
|
||||
|
|
|
@ -484,7 +484,7 @@ float VideoInterfaceManager::GetAspectRatio() const
|
|||
int active_width_samples = (m_h_timing_0.HLW + m_h_timing_1.HBS640 - m_h_timing_1.HBE640);
|
||||
|
||||
// 2. TVs are analog and don't have pixels. So we convert to seconds.
|
||||
float tick_length = (1.0f / SystemTimers::GetTicksPerSecond());
|
||||
float tick_length = (1.0f / m_system.GetSystemTimers().GetTicksPerSecond());
|
||||
float vertical_period = tick_length * GetTicksPerField();
|
||||
float horizontal_period = tick_length * GetTicksPerHalfLine() * 2;
|
||||
float vertical_active_area = active_lines * horizontal_period;
|
||||
|
@ -695,7 +695,7 @@ void VideoInterfaceManager::UpdateParameters()
|
|||
m_even_field_first_hl = equ_hl + m_vblank_timing_even.PRB + GetHalfLinesPerOddField();
|
||||
m_even_field_last_hl = m_even_field_first_hl + acv_hl - 1;
|
||||
|
||||
m_target_refresh_rate_numerator = SystemTimers::GetTicksPerSecond() * 2;
|
||||
m_target_refresh_rate_numerator = m_system.GetSystemTimers().GetTicksPerSecond() * 2;
|
||||
m_target_refresh_rate_denominator = GetTicksPerEvenField() + GetTicksPerOddField();
|
||||
m_target_refresh_rate =
|
||||
static_cast<double>(m_target_refresh_rate_numerator) / m_target_refresh_rate_denominator;
|
||||
|
@ -718,7 +718,7 @@ u32 VideoInterfaceManager::GetTargetRefreshRateDenominator() const
|
|||
|
||||
u32 VideoInterfaceManager::GetTicksPerSample() const
|
||||
{
|
||||
return 2 * SystemTimers::GetTicksPerSecond() / CLOCK_FREQUENCIES[m_clock & 1];
|
||||
return 2 * m_system.GetSystemTimers().GetTicksPerSecond() / CLOCK_FREQUENCIES[m_clock & 1];
|
||||
}
|
||||
|
||||
u32 VideoInterfaceManager::GetTicksPerHalfLine() const
|
||||
|
|
|
@ -71,7 +71,7 @@ IPCReply GetCPUSpeed(Core::System& system, const IOCtlVRequest& request)
|
|||
const bool overclock_enabled = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||
const float oc = overclock_enabled ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f;
|
||||
|
||||
const u32 core_clock = u32(float(SystemTimers::GetTicksPerSecond()) * oc);
|
||||
const u32 core_clock = u32(float(system.GetSystemTimers().GetTicksPerSecond()) * oc);
|
||||
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(core_clock, request.io_vectors[0].address);
|
||||
|
|
|
@ -50,7 +50,7 @@ static void ReinitHardware(Core::System& system)
|
|||
dsp.GetDSPEmulator()->Initialize(SConfig::GetInstance().bWii,
|
||||
Config::Get(Config::MAIN_DSP_THREAD));
|
||||
|
||||
SystemTimers::ChangePPCClock(SystemTimers::Mode::GC);
|
||||
system.GetSystemTimers().ChangePPCClock(SystemTimers::Mode::GC);
|
||||
}
|
||||
|
||||
constexpr u32 ADDRESS_INIT_SEMAPHORE = 0x30f8;
|
||||
|
|
|
@ -346,7 +346,7 @@ void BluetoothEmuDevice::Update()
|
|||
for (auto& wiimote : m_wiimotes)
|
||||
wiimote->Update();
|
||||
|
||||
const u64 interval = SystemTimers::GetTicksPerSecond() / Wiimote::UPDATE_FREQ;
|
||||
const u64 interval = GetSystem().GetSystemTimers().GetTicksPerSecond() / Wiimote::UPDATE_FREQ;
|
||||
const u64 now = GetSystem().GetCoreTiming().GetTicks();
|
||||
|
||||
if (now - m_last_ticks > interval)
|
||||
|
|
|
@ -40,7 +40,7 @@ void TransferCommand::OnTransferComplete(s32 return_value) const
|
|||
|
||||
void TransferCommand::ScheduleTransferCompletion(s32 return_value, u32 expected_time_us) const
|
||||
{
|
||||
auto ticks = SystemTimers::GetTicksPerSecond();
|
||||
auto ticks = m_ios.GetSystem().GetSystemTimers().GetTicksPerSecond();
|
||||
s64 cycles_in_future = static_cast<s64>((static_cast<u64>(ticks) * expected_time_us) / 1'000'000);
|
||||
m_ios.EnqueueIPCReply(ios_request, return_value, cycles_in_future, CoreTiming::FromThread::ANY);
|
||||
}
|
||||
|
|
|
@ -2522,7 +2522,7 @@ void NetPlayClient::SendTimeBase()
|
|||
|
||||
if (netplay_client->m_timebase_frame % 60 == 0)
|
||||
{
|
||||
const sf::Uint64 timebase = SystemTimers::GetFakeTimeBase();
|
||||
const sf::Uint64 timebase = Core::System::GetInstance().GetSystemTimers().GetFakeTimeBase();
|
||||
|
||||
sf::Packet packet;
|
||||
packet << MessageID::TimeBase;
|
||||
|
|
|
@ -245,13 +245,14 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
case SPR_DEC:
|
||||
if ((ppc_state.spr[index] & 0x80000000) == 0) // We are still decrementing
|
||||
{
|
||||
ppc_state.spr[index] = SystemTimers::GetFakeDecrementer();
|
||||
ppc_state.spr[index] = interpreter.m_system.GetSystemTimers().GetFakeDecrementer();
|
||||
}
|
||||
break;
|
||||
|
||||
case SPR_TL:
|
||||
case SPR_TU:
|
||||
interpreter.m_system.GetPowerPC().WriteFullTimeBaseValue(SystemTimers::GetFakeTimeBase());
|
||||
interpreter.m_system.GetPowerPC().WriteFullTimeBaseValue(
|
||||
interpreter.m_system.GetSystemTimers().GetFakeTimeBase());
|
||||
break;
|
||||
|
||||
case SPR_WPAR:
|
||||
|
@ -326,12 +327,12 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
|
||||
case SPR_TL_W:
|
||||
TL(ppc_state) = ppc_state.gpr[inst.RD];
|
||||
SystemTimers::TimeBaseSet();
|
||||
interpreter.m_system.GetSystemTimers().TimeBaseSet();
|
||||
break;
|
||||
|
||||
case SPR_TU_W:
|
||||
TU(ppc_state) = ppc_state.gpr[inst.RD];
|
||||
SystemTimers::TimeBaseSet();
|
||||
interpreter.m_system.GetSystemTimers().TimeBaseSet();
|
||||
break;
|
||||
|
||||
case SPR_PVR:
|
||||
|
@ -433,7 +434,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
INFO_LOG_FMT(POWERPC, "Software triggered Decrementer exception");
|
||||
ppc_state.Exceptions |= EXCEPTION_DECREMENTER;
|
||||
}
|
||||
SystemTimers::DecrementerSet();
|
||||
interpreter.m_system.GetSystemTimers().DecrementerSet();
|
||||
break;
|
||||
|
||||
// Page table base etc
|
||||
|
|
|
@ -199,14 +199,15 @@ void PowerPCManager::ResetRegisters()
|
|||
mmu.DBATUpdated();
|
||||
mmu.IBATUpdated();
|
||||
|
||||
auto& system_timers = m_system.GetSystemTimers();
|
||||
TL(m_ppc_state) = 0;
|
||||
TU(m_ppc_state) = 0;
|
||||
SystemTimers::TimeBaseSet();
|
||||
system_timers.TimeBaseSet();
|
||||
|
||||
// MSR should be 0x40, but we don't emulate BS1, so it would never be turned off :}
|
||||
m_ppc_state.msr.Hex = 0;
|
||||
m_ppc_state.spr[SPR_DEC] = 0xFFFFFFFF;
|
||||
SystemTimers::DecrementerSet();
|
||||
system_timers.DecrementerSet();
|
||||
|
||||
RoundingModeUpdated(m_ppc_state);
|
||||
RecalculateAllFeatureFlags(m_ppc_state);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "Core/HW/ProcessorInterface.h"
|
||||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/Sram.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/HW/VideoInterface.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||
#include "Core/PowerPC/JitInterface.h"
|
||||
|
@ -46,7 +47,7 @@ struct System::Impl
|
|||
m_expansion_interface(system), m_fifo{system}, m_gp_fifo(system),
|
||||
m_memory(system), m_pixel_engine{system}, m_power_pc(system),
|
||||
m_mmu(system, m_memory, m_power_pc), m_processor_interface(system),
|
||||
m_serial_interface(system), m_video_interface(system),
|
||||
m_serial_interface(system), m_system_timers(system), m_video_interface(system),
|
||||
m_interpreter(system, m_power_pc.GetPPCState(), m_mmu), m_jit_interface(system)
|
||||
{
|
||||
}
|
||||
|
@ -78,6 +79,7 @@ struct System::Impl
|
|||
ProcessorInterface::ProcessorInterfaceManager m_processor_interface;
|
||||
SerialInterface::SerialInterfaceManager m_serial_interface;
|
||||
Sram m_sram;
|
||||
SystemTimers::SystemTimersManager m_system_timers;
|
||||
VertexShaderManager m_vertex_shader_manager;
|
||||
XFStateManager m_xf_state_manager;
|
||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||
|
@ -259,6 +261,11 @@ Sram& System::GetSRAM() const
|
|||
return m_impl->m_sram;
|
||||
}
|
||||
|
||||
SystemTimers::SystemTimersManager& System::GetSystemTimers() const
|
||||
{
|
||||
return m_impl->m_system_timers;
|
||||
}
|
||||
|
||||
VertexShaderManager& System::GetVertexShaderManager() const
|
||||
{
|
||||
return m_impl->m_vertex_shader_manager;
|
||||
|
|
|
@ -86,6 +86,10 @@ namespace SerialInterface
|
|||
{
|
||||
class SerialInterfaceManager;
|
||||
};
|
||||
namespace SystemTimers
|
||||
{
|
||||
class SystemTimersManager;
|
||||
}
|
||||
namespace VideoCommon
|
||||
{
|
||||
class CustomAssetLoader;
|
||||
|
@ -155,6 +159,7 @@ public:
|
|||
ProcessorInterface::ProcessorInterfaceManager& GetProcessorInterface() const;
|
||||
SerialInterface::SerialInterfaceManager& GetSerialInterface() const;
|
||||
Sram& GetSRAM() const;
|
||||
SystemTimers::SystemTimersManager& GetSystemTimers() const;
|
||||
VertexShaderManager& GetVertexShaderManager() const;
|
||||
XFStateManager& GetXFStateManager() const;
|
||||
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "Core/Core.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||
|
@ -275,7 +276,8 @@ void AdvancedPane::Update()
|
|||
}
|
||||
|
||||
m_cpu_clock_override_slider_label->setText([] {
|
||||
int core_clock = SystemTimers::GetTicksPerSecond() / std::pow(10, 6);
|
||||
int core_clock =
|
||||
Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond() / std::pow(10, 6);
|
||||
int percent = static_cast<int>(std::round(Config::Get(Config::MAIN_OVERCLOCK) * 100.f));
|
||||
int clock = static_cast<int>(std::round(Config::Get(Config::MAIN_OVERCLOCK) * core_clock));
|
||||
return tr("%1% (%2 MHz)").arg(QString::number(percent), QString::number(clock));
|
||||
|
|
|
@ -436,7 +436,7 @@ void Init()
|
|||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
if ((core_timing.GetTicks() - s_last_init) < SystemTimers::GetTicksPerSecond())
|
||||
if ((core_timing.GetTicks() - s_last_init) < system.GetSystemTimers().GetTicksPerSecond())
|
||||
return;
|
||||
|
||||
s_last_init = core_timing.GetTicks();
|
||||
|
|
|
@ -356,9 +356,10 @@ void FFMpegFrameDump::AddFrame(const FrameData& frame)
|
|||
return;
|
||||
|
||||
// Calculate presentation timestamp from ticks since start.
|
||||
const s64 pts = av_rescale_q(frame.state.ticks - m_context->start_ticks,
|
||||
AVRational{1, int(SystemTimers::GetTicksPerSecond())},
|
||||
m_context->codec->time_base);
|
||||
const s64 pts = av_rescale_q(
|
||||
frame.state.ticks - m_context->start_ticks,
|
||||
AVRational{1, int(Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond())},
|
||||
m_context->codec->time_base);
|
||||
|
||||
if (!IsFirstFrameInCurrentFile())
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "Core/DolphinAnalytics.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "VideoCommon/BPFunctions.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
@ -24,7 +25,8 @@ static Common::EventHook s_before_frame_event =
|
|||
static Common::EventHook s_after_frame_event = AfterFrameEvent::Register(
|
||||
[] {
|
||||
DolphinAnalytics::PerformanceSample perf_sample;
|
||||
perf_sample.speed_ratio = SystemTimers::GetEstimatedEmulationPerformance();
|
||||
perf_sample.speed_ratio =
|
||||
Core::System::GetInstance().GetSystemTimers().GetEstimatedEmulationPerformance();
|
||||
perf_sample.num_prims = g_stats.this_frame.num_prims + g_stats.this_frame.num_dl_prims;
|
||||
perf_sample.num_draw_calls = g_stats.this_frame.num_draw_calls;
|
||||
DolphinAnalytics::Instance().ReportPerformanceInfo(std::move(perf_sample));
|
||||
|
|
|
@ -546,7 +546,7 @@ void VertexManagerBase::Flush()
|
|||
if (g_ActiveConfig.bGraphicMods)
|
||||
{
|
||||
const double seconds_elapsed =
|
||||
static_cast<double>(m_ticks_elapsed) / SystemTimers::GetTicksPerSecond();
|
||||
static_cast<double>(m_ticks_elapsed) / system.GetSystemTimers().GetTicksPerSecond();
|
||||
pixel_shader_manager.constants.time_ms = seconds_elapsed * 1000;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue