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;
|
||||||
val |= CR_INIT_CODE;
|
val |= CR_INIT_CODE;
|
||||||
// Number obtained from real hardware on a Wii, but it's not perfectly consistent
|
// 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
|
// update cr
|
||||||
|
@ -269,10 +270,11 @@ u16 Interpreter::ReadControlRegister()
|
||||||
auto& state = m_dsp_core.DSPState();
|
auto& state = m_dsp_core.DSPState();
|
||||||
if ((state.control_reg & CR_INIT_CODE) != 0)
|
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;
|
state.control_reg &= ~CR_INIT_CODE;
|
||||||
else
|
else
|
||||||
Core::System::GetInstance().GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
system.GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||||
}
|
}
|
||||||
return state.control_reg;
|
return state.control_reg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,8 +410,9 @@ FifoPlayer& FifoPlayer::GetInstance()
|
||||||
void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& info)
|
void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& info)
|
||||||
{
|
{
|
||||||
// Core timing information
|
// Core timing information
|
||||||
auto& vi = Core::System::GetInstance().GetVideoInterface();
|
auto& system = Core::System::GetInstance();
|
||||||
m_CyclesPerFrame = static_cast<u64>(SystemTimers::GetTicksPerSecond()) *
|
auto& vi = system.GetVideoInterface();
|
||||||
|
m_CyclesPerFrame = static_cast<u64>(system.GetSystemTimers().GetTicksPerSecond()) *
|
||||||
vi.GetTargetRefreshRateDenominator() / vi.GetTargetRefreshRateNumerator();
|
vi.GetTargetRefreshRateDenominator() / vi.GetTargetRefreshRateNumerator();
|
||||||
m_ElapsedCycles = 0;
|
m_ElapsedCycles = 0;
|
||||||
m_FrameFifoSize = static_cast<u32>(frame.fifoData.size());
|
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_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;
|
m_ais_sample_rate_divisor / Mixer::FIXED_SAMPLE_RATE_DIVIDEND;
|
||||||
SoundStream* sound_stream = m_system.GetSoundStream();
|
SoundStream* sound_stream = m_system.GetSoundStream();
|
||||||
sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(m_ais_sample_rate_divisor);
|
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
|
// AX HLE uses 3ms (Wii) or 5ms (GC) timing period
|
||||||
// But to be sure, just update the HLE every ms.
|
// 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)
|
void DSPHLE::SendMailToDSP(u32 mail)
|
||||||
|
@ -221,7 +221,8 @@ u16 DSPHLE::DSP_WriteControlRegister(u16 value)
|
||||||
SetUCode(UCODE_INIT_AUDIO_SYSTEM);
|
SetUCode(UCODE_INIT_AUDIO_SYSTEM);
|
||||||
temp.DSPInitCode = 1;
|
temp.DSPInitCode = 1;
|
||||||
// Number obtained from real hardware on a Wii, but it's not perfectly consistent
|
// 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;
|
m_dsp_control.Hex = temp.Hex;
|
||||||
|
@ -232,10 +233,11 @@ u16 DSPHLE::DSP_ReadControlRegister()
|
||||||
{
|
{
|
||||||
if (m_dsp_control.DSPInitCode != 0)
|
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;
|
m_dsp_control.DSPInitCode = 0;
|
||||||
else
|
else
|
||||||
Core::System::GetInstance().GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
system.GetCoreTiming().ForceExceptionCheck(50); // Keep checking
|
||||||
}
|
}
|
||||||
return m_dsp_control.Hex;
|
return m_dsp_control.Hex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,7 @@ void DVDInterface::DTKStreamingCallback(DIInterruptType interrupt_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the next chunk of audio data asynchronously.
|
// 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 /
|
StreamADPCM::SAMPLES_PER_BLOCK * sample_rate_divisor /
|
||||||
Mixer::FIXED_SAMPLE_RATE_DIVIDEND;
|
Mixer::FIXED_SAMPLE_RATE_DIVIDEND;
|
||||||
ticks_to_dtk -= cycles_late;
|
ticks_to_dtk -= cycles_late;
|
||||||
|
@ -474,7 +474,8 @@ void DVDInterface::ChangeDisc(const std::string& new_path)
|
||||||
EjectDisc(EjectCause::User);
|
EjectDisc(EjectCause::User);
|
||||||
|
|
||||||
m_disc_path_to_insert = new_path;
|
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);
|
Movie::SignalDiscChange(new_path);
|
||||||
|
|
||||||
for (size_t i = 0; i < m_auto_disc_change_paths.size(); ++i)
|
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.GetDVDThread().IsInsertedDiscRunning() && !m_auto_disc_change_paths.empty())
|
||||||
{
|
{
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
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);
|
OSD::AddMessage("Changing discs automatically...", OSD::Duration::NORMAL);
|
||||||
}
|
}
|
||||||
else if (force_eject)
|
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
|
// TODO: Needs testing to determine if MINIMUM_COMMAND_LATENCY_US is accurate for this
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
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));
|
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
|
// TODO: Needs testing to determine if MINIMUM_COMMAND_LATENCY_US is accurate for this
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
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));
|
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
|
// TODO: Needs testing to determine if MINIMUM_COMMAND_LATENCY_US is accurate for this
|
||||||
const DIInterruptType interrupt_type = DIInterruptType::DEINT;
|
const DIInterruptType interrupt_type = DIInterruptType::DEINT;
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
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));
|
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();
|
auto& core_timing = m_system.GetCoreTiming();
|
||||||
const u64 current_time = core_timing.GetTicks();
|
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();
|
auto& dvd_thread = m_system.GetDVDThread();
|
||||||
const bool wii_disc = dvd_thread.GetDiscType() == DiscIO::Platform::WiiDisc;
|
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);
|
length, output_address);
|
||||||
|
|
||||||
s64 ticks_until_completion =
|
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 buffered_blocks = 0;
|
||||||
u32 unbuffered_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={}, "
|
"Schedule reads: ECC blocks unbuffered={}, buffered={}, "
|
||||||
"ticks={}, time={} us",
|
"ticks={}, time={} us",
|
||||||
unbuffered_blocks, buffered_blocks, ticks_until_completion,
|
unbuffered_blocks, buffered_blocks, ticks_until_completion,
|
||||||
ticks_until_completion * 1000000 / SystemTimers::GetTicksPerSecond());
|
ticks_until_completion * 1000000 / m_system.GetSystemTimers().GetTicksPerSecond());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DVD
|
} // namespace DVD
|
||||||
|
|
|
@ -301,7 +301,7 @@ void DVDThread::FinishRead(u64 id, s64 cycles_late)
|
||||||
request.realtime_done_us - request.realtime_started_us,
|
request.realtime_done_us - request.realtime_started_us,
|
||||||
Common::Timer::NowUs() - request.realtime_started_us,
|
Common::Timer::NowUs() - request.realtime_started_us,
|
||||||
(m_system.GetCoreTiming().GetTicks() - request.time_started_ticks) /
|
(m_system.GetCoreTiming().GetTicks() - request.time_started_ticks) /
|
||||||
(SystemTimers::GetTicksPerSecond() / 1000000));
|
(m_system.GetSystemTimers().GetTicksPerSecond() / 1000000));
|
||||||
|
|
||||||
auto& dvd_interface = m_system.GetDVDInterface();
|
auto& dvd_interface = m_system.GetDVDInterface();
|
||||||
DVD::DIInterruptType interrupt;
|
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,
|
core_timing.ScheduleEvent(0, m_event_type_change_device,
|
||||||
((u64)channel << 32) | ((u64)EXIDeviceType::None << 16) | device_num,
|
((u64)channel << 32) | ((u64)EXIDeviceType::None << 16) | device_num,
|
||||||
from_thread);
|
from_thread);
|
||||||
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond(), m_event_type_change_device,
|
core_timing.ScheduleEvent(
|
||||||
((u64)channel << 32) | ((u64)device_type << 16) | device_num,
|
m_system.GetSystemTimers().GetTicksPerSecond(), m_event_type_change_device,
|
||||||
from_thread);
|
((u64)channel << 32) | ((u64)device_type << 16) | device_num, from_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
CEXIChannel* ExpansionInterfaceManager::GetChannel(u32 index)
|
CEXIChannel* ExpansionInterfaceManager::GetChannel(u32 index)
|
||||||
|
|
|
@ -411,19 +411,20 @@ u32 CEXIIPL::GetEmulatedTime(Core::System& system, u32 epoch)
|
||||||
ltime = Movie::GetRecordingStartTime();
|
ltime = Movie::GetRecordingStartTime();
|
||||||
|
|
||||||
// let's keep time moving forward, regardless of what it starts at
|
// 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())
|
else if (NetPlay::IsNetPlayRunning())
|
||||||
{
|
{
|
||||||
ltime = NetPlay_GetEmulatedTime();
|
ltime = NetPlay_GetEmulatedTime();
|
||||||
|
|
||||||
// let's keep time moving forward, regardless of what it starts at
|
// 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
|
else
|
||||||
{
|
{
|
||||||
ASSERT(!Core::WantsDeterminism());
|
ASSERT(!Core::WantsDeterminism());
|
||||||
ltime = Common::Timer::GetLocalTimeSinceJan1970() - SystemTimers::GetLocalTimeRTCOffset();
|
ltime = Common::Timer::GetLocalTimeSinceJan1970() -
|
||||||
|
system.GetSystemTimers().GetLocalTimeRTCOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<u32>(ltime) - epoch;
|
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
|
// Schedule transfer complete later based on read speed
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
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));
|
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
|
// Schedule transfer complete later based on write speed
|
||||||
m_system.GetCoreTiming().ScheduleEvent(
|
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));
|
s_et_transfer_complete[m_card_slot], static_cast<u64>(m_card_slot));
|
||||||
}
|
}
|
||||||
} // namespace ExpansionInterface
|
} // namespace ExpansionInterface
|
||||||
|
|
|
@ -264,7 +264,7 @@ void CEXIMic::SetCS(int cs)
|
||||||
|
|
||||||
void CEXIMic::UpdateNextInterruptTicks()
|
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;
|
next_int_ticks = m_system.GetCoreTiming().GetTicks() + diff;
|
||||||
m_system.GetExpansionInterface().ScheduleUpdateInterrupts(CoreTiming::FromThread::CPU, 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)
|
if (static_cast<s64>(gc_ticks - m_last_gc_ticks) <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const u64 gc_frequency = SystemTimers::GetTicksPerSecond();
|
const u64 gc_frequency = ::Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond();
|
||||||
const u32 core_frequency = GetCoreFrequency(m_core);
|
const u32 core_frequency = GetCoreFrequency(m_core);
|
||||||
|
|
||||||
mTimingSchedule(m_core->timing, &m_event,
|
mTimingSchedule(m_core->timing, &m_event,
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace HW
|
||||||
void Init(Core::System& system, const Sram* override_sram)
|
void Init(Core::System& system, const Sram* override_sram)
|
||||||
{
|
{
|
||||||
system.GetCoreTiming().Init();
|
system.GetCoreTiming().Init();
|
||||||
SystemTimers::PreInit();
|
system.GetSystemTimers().PreInit();
|
||||||
|
|
||||||
State::Init();
|
State::Init();
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void Init(Core::System& system, const Sram* override_sram)
|
||||||
system.GetDVDInterface().Init();
|
system.GetDVDInterface().Init();
|
||||||
system.GetGPFifo().Init();
|
system.GetGPFifo().Init();
|
||||||
system.GetCPU().Init(Config::Get(Config::MAIN_CPU_CORE));
|
system.GetCPU().Init(Config::Get(Config::MAIN_CPU_CORE));
|
||||||
SystemTimers::Init();
|
system.GetSystemTimers().Init();
|
||||||
|
|
||||||
if (SConfig::GetInstance().bWii)
|
if (SConfig::GetInstance().bWii)
|
||||||
{
|
{
|
||||||
|
@ -67,7 +67,7 @@ void Shutdown(Core::System& system)
|
||||||
IOS::HLE::Shutdown(); // Depends on Memory
|
IOS::HLE::Shutdown(); // Depends on Memory
|
||||||
IOS::Shutdown();
|
IOS::Shutdown();
|
||||||
|
|
||||||
SystemTimers::Shutdown();
|
system.GetSystemTimers().Shutdown();
|
||||||
system.GetCPU().Shutdown();
|
system.GetCPU().Shutdown();
|
||||||
system.GetDVDInterface().Shutdown();
|
system.GetDVDInterface().Shutdown();
|
||||||
system.GetDSP().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_toggle_reset_button, true, CoreTiming::FromThread::ANY);
|
||||||
core_timing.ScheduleEvent(0, m_event_type_ios_notify_reset_button, 0,
|
core_timing.ScheduleEvent(0, m_event_type_ios_notify_reset_button, 0,
|
||||||
CoreTiming::FromThread::ANY);
|
CoreTiming::FromThread::ANY);
|
||||||
core_timing.ScheduleEvent(SystemTimers::GetTicksPerSecond() / 2, m_event_type_toggle_reset_button,
|
core_timing.ScheduleEvent(m_system.GetSystemTimers().GetTicksPerSecond() / 2,
|
||||||
false, CoreTiming::FromThread::ANY);
|
m_event_type_toggle_reset_button, false, CoreTiming::FromThread::ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessorInterfaceManager::PowerButton_Tap()
|
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.
|
// Prevent additional device changes on this channel for one second.
|
||||||
m_channel[channel].has_recent_device_change = true;
|
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);
|
m_event_type_change_device, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Core/HW/SI/SI_DeviceKeyboard.h"
|
#include "Core/HW/SI/SI_DeviceKeyboard.h"
|
||||||
#include "Core/HW/SI/SI_DeviceNull.h"
|
#include "Core/HW/SI/SI_DeviceNull.h"
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
namespace SerialInterface
|
namespace SerialInterface
|
||||||
{
|
{
|
||||||
|
@ -142,10 +143,10 @@ int SIDevice_GetGBATransferTime(EBufferCommands cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 cycles =
|
const u32 ticks_per_second = Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond();
|
||||||
(gba_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GBA_BITS_PER_SECOND) +
|
const u64 cycles = (gba_bytes_transferred * 8 * ticks_per_second / GBA_BITS_PER_SECOND) +
|
||||||
(gc_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GC_BITS_PER_SECOND) +
|
(gc_bytes_transferred * 8 * ticks_per_second / GC_BITS_PER_SECOND) +
|
||||||
(stop_bits_ns * SystemTimers::GetTicksPerSecond() / 1000000000LL);
|
(stop_bits_ns * ticks_per_second / 1000000000LL);
|
||||||
return static_cast<int>(cycles);
|
return static_cast<int>(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,14 +154,14 @@ void GBASockServer::ClockSync(Core::System& system)
|
||||||
{
|
{
|
||||||
s_num_connected++;
|
s_num_connected++;
|
||||||
m_last_time_slice = core_timing.GetTicks();
|
m_last_time_slice = core_timing.GetTicks();
|
||||||
time_slice = (u32)(SystemTimers::GetTicksPerSecond() / 60);
|
time_slice = (u32)(system.GetSystemTimers().GetTicksPerSecond() / 60);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
time_slice = (u32)(core_timing.GetTicks() - m_last_time_slice);
|
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();
|
m_last_time_slice = core_timing.GetTicks();
|
||||||
char bytes[4] = {0, 0, 0, 0};
|
char bytes[4] = {0, 0, 0, 0};
|
||||||
bytes[0] = (time_slice >> 24) & 0xff;
|
bytes[0] = (time_slice >> 24) & 0xff;
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SerialInterface
|
||||||
{
|
{
|
||||||
static s64 GetSyncInterval()
|
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)
|
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)
|
if (m_last_button_combo != COMBO_NONE)
|
||||||
{
|
{
|
||||||
const u64 current_time = m_system.GetCoreTiming().GetTicks();
|
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)
|
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 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.
|
// 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
|
// splits up the cycle budget in case lle is used
|
||||||
// for hle, just gives all of the slice to hle
|
// for hle, just gives all of the slice to hle
|
||||||
auto& dsp = system.GetDSP();
|
auto& dsp = system.GetDSP();
|
||||||
dsp.UpdateDSPSlice(static_cast<int>(dsp.GetDSPEmulator()->DSP_UpdateRate() - cyclesLate));
|
dsp.UpdateDSPSlice(static_cast<int>(dsp.GetDSPEmulator()->DSP_UpdateRate() - cycles_late));
|
||||||
system.GetCoreTiming().ScheduleEvent(dsp.GetDSPEmulator()->DSP_UpdateRate() - cyclesLate, et_DSP);
|
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
|
// System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA
|
||||||
auto& system = Core::System::GetInstance();
|
return static_cast<u64>(cpu_core_clock) * aid_sample_rate_divisor /
|
||||||
return static_cast<u64>(s_cpu_core_clock) * system.GetAudioInterface().GetAIDSampleRateDivisor() /
|
|
||||||
(Mixer::FIXED_SAMPLE_RATE_DIVIDEND * 4 / 32);
|
(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.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)
|
if (SConfig::GetInstance().bWii)
|
||||||
{
|
{
|
||||||
IOS::HLE::GetIOS()->UpdateDevices();
|
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();
|
auto& core_timing = system.GetCoreTiming();
|
||||||
system.GetFifo().GpuMaySleep();
|
system.GetFifo().GpuMaySleep();
|
||||||
|
|
||||||
// We want to call GpuMaySleep at about 1000hz so
|
// We want to call GpuMaySleep at about 1000hz so
|
||||||
// that the thread can sleep while not doing anything.
|
// 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();
|
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.
|
// 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 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.
|
// 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& core_timing = system.GetCoreTiming();
|
||||||
auto& vi = system.GetVideoInterface();
|
auto& vi = system.GetVideoInterface();
|
||||||
vi.Update(core_timing.GetTicks() - cyclesLate);
|
vi.Update(core_timing.GetTicks() - cycles_late);
|
||||||
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine() - cyclesLate, et_VI);
|
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();
|
auto& ppc_state = system.GetPPCState();
|
||||||
ppc_state.spr[SPR_DEC] = 0xFFFFFFFF;
|
ppc_state.spr[SPR_DEC] = 0xFFFFFFFF;
|
||||||
ppc_state.Exceptions |= EXCEPTION_DECREMENTER;
|
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 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.
|
// 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;
|
cycles_pruned += next_schedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
system.GetCoreTiming().ScheduleEvent(next_schedule, et_PatchEngine, cycles_pruned);
|
system.GetCoreTiming().ScheduleEvent(
|
||||||
}
|
next_schedule, system.GetSystemTimers().m_event_type_patch_engine, cycles_pruned);
|
||||||
} // namespace
|
|
||||||
|
|
||||||
u32 GetTicksPerSecond()
|
|
||||||
{
|
|
||||||
return s_cpu_core_clock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
u32 decValue = ppc_state.spr[SPR_DEC];
|
||||||
|
|
||||||
core_timing.RemoveEvent(et_Dec);
|
core_timing.RemoveEvent(m_event_type_decrementer);
|
||||||
if ((decValue & 0x80000000) == 0)
|
if ((decValue & 0x80000000) == 0)
|
||||||
{
|
{
|
||||||
core_timing.SetFakeDecStartTicks(core_timing.GetTicks());
|
core_timing.SetFakeDecStartTicks(core_timing.GetTicks());
|
||||||
core_timing.SetFakeDecStartValue(decValue);
|
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();
|
const auto& core_timing = m_system.GetCoreTiming();
|
||||||
auto& core_timing = system.GetCoreTiming();
|
|
||||||
return (core_timing.GetFakeDecStartValue() -
|
return (core_timing.GetFakeDecStartValue() -
|
||||||
(u32)((core_timing.GetTicks() - core_timing.GetFakeDecStartTicks()) / TIMER_RATIO));
|
(u32)((core_timing.GetTicks() - core_timing.GetFakeDecStartTicks()) / TIMER_RATIO));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeBaseSet()
|
void SystemTimersManager::TimeBaseSet()
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& core_timing = m_system.GetCoreTiming();
|
||||||
auto& core_timing = system.GetCoreTiming();
|
|
||||||
core_timing.SetFakeTBStartTicks(core_timing.GetTicks());
|
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();
|
const auto& core_timing = m_system.GetCoreTiming();
|
||||||
auto& core_timing = system.GetCoreTiming();
|
|
||||||
return core_timing.GetFakeTBStartValue() +
|
return core_timing.GetFakeTBStartValue() +
|
||||||
((core_timing.GetTicks() - core_timing.GetFakeTBStartTicks()) / TIMER_RATIO);
|
((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();
|
return g_perf_metrics.GetMaxSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// split from Init to break a circular dependency between VideoInterface::Init and
|
// split from Init to break a circular dependency between VideoInterface::Init and
|
||||||
// SystemTimers::Init
|
// SystemTimers::Init
|
||||||
void PreInit()
|
void SystemTimersManager::PreInit()
|
||||||
{
|
{
|
||||||
ChangePPCClock(SConfig::GetInstance().bWii ? Mode::Wii : Mode::GC);
|
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)
|
if (mode == Mode::Wii)
|
||||||
s_cpu_core_clock = 729000000u;
|
m_cpu_core_clock = 729000000u;
|
||||||
else
|
else
|
||||||
s_cpu_core_clock = 486000000u;
|
m_cpu_core_clock = 486000000u;
|
||||||
Core::System::GetInstance().GetCoreTiming().AdjustEventQueueTimes(s_cpu_core_clock,
|
m_system.GetCoreTiming().AdjustEventQueueTimes(m_cpu_core_clock, previous_clock);
|
||||||
previous_clock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void SystemTimersManager::Init()
|
||||||
{
|
{
|
||||||
if (SConfig::GetInstance().bWii)
|
if (SConfig::GetInstance().bWii)
|
||||||
{
|
{
|
||||||
|
@ -270,55 +262,58 @@ void Init()
|
||||||
// Now the 1500 is a pure assumption
|
// Now the 1500 is a pure assumption
|
||||||
// We need to figure out the real frequency though
|
// We need to figure out the real frequency though
|
||||||
const int freq = 1500;
|
const int freq = 1500;
|
||||||
s_ipc_hle_period = GetTicksPerSecond() / freq;
|
m_ipc_hle_period = GetTicksPerSecond() / freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Timer::IncreaseResolution();
|
Common::Timer::IncreaseResolution();
|
||||||
// store and convert localtime at boot to timebase ticks
|
// store and convert localtime at boot to timebase ticks
|
||||||
if (Config::Get(Config::MAIN_CUSTOM_RTC_ENABLE))
|
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);
|
Common::Timer::GetLocalTimeSinceJan1970() - Config::Get(Config::MAIN_CUSTOM_RTC_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& core_timing = m_system.GetCoreTiming();
|
||||||
auto& core_timing = system.GetCoreTiming();
|
auto& vi = m_system.GetVideoInterface();
|
||||||
auto& vi = 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(
|
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.SetFakeTBStartTicks(core_timing.GetTicks());
|
||||||
|
|
||||||
core_timing.SetFakeDecStartValue(0xFFFFFFFF);
|
core_timing.SetFakeDecStartValue(0xFFFFFFFF);
|
||||||
core_timing.SetFakeDecStartTicks(core_timing.GetTicks());
|
core_timing.SetFakeDecStartTicks(core_timing.GetTicks());
|
||||||
|
|
||||||
et_Dec = core_timing.RegisterEvent("DecCallback", DecrementerCallback);
|
m_event_type_decrementer = core_timing.RegisterEvent("DecCallback", DecrementerCallback);
|
||||||
et_VI = core_timing.RegisterEvent("VICallback", VICallback);
|
m_event_type_vi = core_timing.RegisterEvent("VICallback", VICallback);
|
||||||
et_DSP = core_timing.RegisterEvent("DSPCallback", DSPCallback);
|
m_event_type_dsp = core_timing.RegisterEvent("DSPCallback", DSPCallback);
|
||||||
et_AudioDMA = core_timing.RegisterEvent("AudioDMACallback", AudioDMACallback);
|
m_event_type_audio_dma = core_timing.RegisterEvent("AudioDMACallback", AudioDMACallback);
|
||||||
et_IPC_HLE = core_timing.RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
m_event_type_ipc_hle =
|
||||||
et_GPU_sleeper = core_timing.RegisterEvent("GPUSleeper", GPUSleepCallback);
|
core_timing.RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
|
||||||
et_perf_tracker = core_timing.RegisterEvent("PerfTracker", PerfTrackerCallback);
|
m_event_type_gpu_sleeper = core_timing.RegisterEvent("GPUSleeper", GPUSleepCallback);
|
||||||
et_PatchEngine = core_timing.RegisterEvent("PatchEngine", PatchEngineCallback);
|
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, m_event_type_perf_tracker);
|
||||||
core_timing.ScheduleEvent(0, et_GPU_sleeper);
|
core_timing.ScheduleEvent(0, m_event_type_gpu_sleeper);
|
||||||
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine(), et_VI);
|
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine(), m_event_type_vi);
|
||||||
core_timing.ScheduleEvent(0, et_DSP);
|
core_timing.ScheduleEvent(0, m_event_type_dsp);
|
||||||
core_timing.ScheduleEvent(GetAudioDMACallbackPeriod(), et_AudioDMA);
|
|
||||||
|
|
||||||
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)
|
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();
|
Common::Timer::RestoreResolution();
|
||||||
s_localtime_rtc_offset = 0;
|
m_localtime_rtc_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SystemTimers
|
} // namespace SystemTimers
|
||||||
|
|
|
@ -5,6 +5,15 @@
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
namespace CoreTiming
|
||||||
|
{
|
||||||
|
struct EventType;
|
||||||
|
}
|
||||||
|
|
||||||
namespace SystemTimers
|
namespace SystemTimers
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -47,29 +56,70 @@ enum class Mode
|
||||||
Wii,
|
Wii,
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 GetTicksPerSecond();
|
class SystemTimersManager
|
||||||
void PreInit();
|
{
|
||||||
void Init();
|
public:
|
||||||
void Shutdown();
|
explicit SystemTimersManager(Core::System& system);
|
||||||
void ChangePPCClock(Mode mode);
|
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
|
u32 GetTicksPerSecond() const;
|
||||||
void DecrementerSet();
|
void PreInit();
|
||||||
u32 GetFakeDecrementer();
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
void ChangePPCClock(Mode mode);
|
||||||
|
|
||||||
void TimeBaseSet();
|
// Notify timing system that somebody wrote to the decrementer
|
||||||
u64 GetFakeTimeBase();
|
void DecrementerSet();
|
||||||
// Custom RTC
|
u32 GetFakeDecrementer() const;
|
||||||
s64 GetLocalTimeRTCOffset();
|
|
||||||
|
|
||||||
// Returns an estimate of how fast/slow the emulation is running (excluding throttling induced sleep
|
void TimeBaseSet();
|
||||||
// time). The estimate is computed over the last 1s of emulated time. Example values:
|
u64 GetFakeTimeBase() const;
|
||||||
//
|
// Custom RTC
|
||||||
// - 0.5: the emulator is running at 50% speed (falling behind).
|
s64 GetLocalTimeRTCOffset() const;
|
||||||
// - 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();
|
|
||||||
|
|
||||||
|
// 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
|
} // namespace SystemTimers
|
||||||
|
|
||||||
inline namespace SystemTimersLiterals
|
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);
|
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.
|
// 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 vertical_period = tick_length * GetTicksPerField();
|
||||||
float horizontal_period = tick_length * GetTicksPerHalfLine() * 2;
|
float horizontal_period = tick_length * GetTicksPerHalfLine() * 2;
|
||||||
float vertical_active_area = active_lines * horizontal_period;
|
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_first_hl = equ_hl + m_vblank_timing_even.PRB + GetHalfLinesPerOddField();
|
||||||
m_even_field_last_hl = m_even_field_first_hl + acv_hl - 1;
|
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_denominator = GetTicksPerEvenField() + GetTicksPerOddField();
|
||||||
m_target_refresh_rate =
|
m_target_refresh_rate =
|
||||||
static_cast<double>(m_target_refresh_rate_numerator) / m_target_refresh_rate_denominator;
|
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
|
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
|
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 bool overclock_enabled = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
|
||||||
const float oc = overclock_enabled ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f;
|
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();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(core_clock, request.io_vectors[0].address);
|
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,
|
dsp.GetDSPEmulator()->Initialize(SConfig::GetInstance().bWii,
|
||||||
Config::Get(Config::MAIN_DSP_THREAD));
|
Config::Get(Config::MAIN_DSP_THREAD));
|
||||||
|
|
||||||
SystemTimers::ChangePPCClock(SystemTimers::Mode::GC);
|
system.GetSystemTimers().ChangePPCClock(SystemTimers::Mode::GC);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 ADDRESS_INIT_SEMAPHORE = 0x30f8;
|
constexpr u32 ADDRESS_INIT_SEMAPHORE = 0x30f8;
|
||||||
|
|
|
@ -346,7 +346,7 @@ void BluetoothEmuDevice::Update()
|
||||||
for (auto& wiimote : m_wiimotes)
|
for (auto& wiimote : m_wiimotes)
|
||||||
wiimote->Update();
|
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();
|
const u64 now = GetSystem().GetCoreTiming().GetTicks();
|
||||||
|
|
||||||
if (now - m_last_ticks > interval)
|
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
|
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);
|
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);
|
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)
|
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;
|
sf::Packet packet;
|
||||||
packet << MessageID::TimeBase;
|
packet << MessageID::TimeBase;
|
||||||
|
|
|
@ -245,13 +245,14 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
case SPR_DEC:
|
case SPR_DEC:
|
||||||
if ((ppc_state.spr[index] & 0x80000000) == 0) // We are still decrementing
|
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;
|
break;
|
||||||
|
|
||||||
case SPR_TL:
|
case SPR_TL:
|
||||||
case SPR_TU:
|
case SPR_TU:
|
||||||
interpreter.m_system.GetPowerPC().WriteFullTimeBaseValue(SystemTimers::GetFakeTimeBase());
|
interpreter.m_system.GetPowerPC().WriteFullTimeBaseValue(
|
||||||
|
interpreter.m_system.GetSystemTimers().GetFakeTimeBase());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPR_WPAR:
|
case SPR_WPAR:
|
||||||
|
@ -326,12 +327,12 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
|
|
||||||
case SPR_TL_W:
|
case SPR_TL_W:
|
||||||
TL(ppc_state) = ppc_state.gpr[inst.RD];
|
TL(ppc_state) = ppc_state.gpr[inst.RD];
|
||||||
SystemTimers::TimeBaseSet();
|
interpreter.m_system.GetSystemTimers().TimeBaseSet();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPR_TU_W:
|
case SPR_TU_W:
|
||||||
TU(ppc_state) = ppc_state.gpr[inst.RD];
|
TU(ppc_state) = ppc_state.gpr[inst.RD];
|
||||||
SystemTimers::TimeBaseSet();
|
interpreter.m_system.GetSystemTimers().TimeBaseSet();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPR_PVR:
|
case SPR_PVR:
|
||||||
|
@ -433,7 +434,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
INFO_LOG_FMT(POWERPC, "Software triggered Decrementer exception");
|
INFO_LOG_FMT(POWERPC, "Software triggered Decrementer exception");
|
||||||
ppc_state.Exceptions |= EXCEPTION_DECREMENTER;
|
ppc_state.Exceptions |= EXCEPTION_DECREMENTER;
|
||||||
}
|
}
|
||||||
SystemTimers::DecrementerSet();
|
interpreter.m_system.GetSystemTimers().DecrementerSet();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Page table base etc
|
// Page table base etc
|
||||||
|
|
|
@ -199,14 +199,15 @@ void PowerPCManager::ResetRegisters()
|
||||||
mmu.DBATUpdated();
|
mmu.DBATUpdated();
|
||||||
mmu.IBATUpdated();
|
mmu.IBATUpdated();
|
||||||
|
|
||||||
|
auto& system_timers = m_system.GetSystemTimers();
|
||||||
TL(m_ppc_state) = 0;
|
TL(m_ppc_state) = 0;
|
||||||
TU(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 :}
|
// 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.msr.Hex = 0;
|
||||||
m_ppc_state.spr[SPR_DEC] = 0xFFFFFFFF;
|
m_ppc_state.spr[SPR_DEC] = 0xFFFFFFFF;
|
||||||
SystemTimers::DecrementerSet();
|
system_timers.DecrementerSet();
|
||||||
|
|
||||||
RoundingModeUpdated(m_ppc_state);
|
RoundingModeUpdated(m_ppc_state);
|
||||||
RecalculateAllFeatureFlags(m_ppc_state);
|
RecalculateAllFeatureFlags(m_ppc_state);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Core/HW/ProcessorInterface.h"
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
#include "Core/HW/SI/SI.h"
|
#include "Core/HW/SI/SI.h"
|
||||||
#include "Core/HW/Sram.h"
|
#include "Core/HW/Sram.h"
|
||||||
|
#include "Core/HW/SystemTimers.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||||
#include "Core/PowerPC/JitInterface.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_expansion_interface(system), m_fifo{system}, m_gp_fifo(system),
|
||||||
m_memory(system), m_pixel_engine{system}, m_power_pc(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_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)
|
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;
|
ProcessorInterface::ProcessorInterfaceManager m_processor_interface;
|
||||||
SerialInterface::SerialInterfaceManager m_serial_interface;
|
SerialInterface::SerialInterfaceManager m_serial_interface;
|
||||||
Sram m_sram;
|
Sram m_sram;
|
||||||
|
SystemTimers::SystemTimersManager m_system_timers;
|
||||||
VertexShaderManager m_vertex_shader_manager;
|
VertexShaderManager m_vertex_shader_manager;
|
||||||
XFStateManager m_xf_state_manager;
|
XFStateManager m_xf_state_manager;
|
||||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||||
|
@ -259,6 +261,11 @@ Sram& System::GetSRAM() const
|
||||||
return m_impl->m_sram;
|
return m_impl->m_sram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemTimers::SystemTimersManager& System::GetSystemTimers() const
|
||||||
|
{
|
||||||
|
return m_impl->m_system_timers;
|
||||||
|
}
|
||||||
|
|
||||||
VertexShaderManager& System::GetVertexShaderManager() const
|
VertexShaderManager& System::GetVertexShaderManager() const
|
||||||
{
|
{
|
||||||
return m_impl->m_vertex_shader_manager;
|
return m_impl->m_vertex_shader_manager;
|
||||||
|
|
|
@ -86,6 +86,10 @@ namespace SerialInterface
|
||||||
{
|
{
|
||||||
class SerialInterfaceManager;
|
class SerialInterfaceManager;
|
||||||
};
|
};
|
||||||
|
namespace SystemTimers
|
||||||
|
{
|
||||||
|
class SystemTimersManager;
|
||||||
|
}
|
||||||
namespace VideoCommon
|
namespace VideoCommon
|
||||||
{
|
{
|
||||||
class CustomAssetLoader;
|
class CustomAssetLoader;
|
||||||
|
@ -155,6 +159,7 @@ public:
|
||||||
ProcessorInterface::ProcessorInterfaceManager& GetProcessorInterface() const;
|
ProcessorInterface::ProcessorInterfaceManager& GetProcessorInterface() const;
|
||||||
SerialInterface::SerialInterfaceManager& GetSerialInterface() const;
|
SerialInterface::SerialInterfaceManager& GetSerialInterface() const;
|
||||||
Sram& GetSRAM() const;
|
Sram& GetSRAM() const;
|
||||||
|
SystemTimers::SystemTimersManager& GetSystemTimers() const;
|
||||||
VertexShaderManager& GetVertexShaderManager() const;
|
VertexShaderManager& GetVertexShaderManager() const;
|
||||||
XFStateManager& GetXFStateManager() const;
|
XFStateManager& GetXFStateManager() const;
|
||||||
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
|
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
#include "DolphinQt/Config/ConfigControls/ConfigBool.h"
|
||||||
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
||||||
|
@ -275,7 +276,8 @@ void AdvancedPane::Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cpu_clock_override_slider_label->setText([] {
|
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 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));
|
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));
|
return tr("%1% (%2 MHz)").arg(QString::number(percent), QString::number(clock));
|
||||||
|
|
|
@ -436,7 +436,7 @@ void Init()
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& core_timing = system.GetCoreTiming();
|
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;
|
return;
|
||||||
|
|
||||||
s_last_init = core_timing.GetTicks();
|
s_last_init = core_timing.GetTicks();
|
||||||
|
|
|
@ -356,9 +356,10 @@ void FFMpegFrameDump::AddFrame(const FrameData& frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Calculate presentation timestamp from ticks since start.
|
// Calculate presentation timestamp from ticks since start.
|
||||||
const s64 pts = av_rescale_q(frame.state.ticks - m_context->start_ticks,
|
const s64 pts = av_rescale_q(
|
||||||
AVRational{1, int(SystemTimers::GetTicksPerSecond())},
|
frame.state.ticks - m_context->start_ticks,
|
||||||
m_context->codec->time_base);
|
AVRational{1, int(Core::System::GetInstance().GetSystemTimers().GetTicksPerSecond())},
|
||||||
|
m_context->codec->time_base);
|
||||||
|
|
||||||
if (!IsFirstFrameInCurrentFile())
|
if (!IsFirstFrameInCurrentFile())
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "Core/DolphinAnalytics.h"
|
#include "Core/DolphinAnalytics.h"
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#include "VideoCommon/BPFunctions.h"
|
#include "VideoCommon/BPFunctions.h"
|
||||||
#include "VideoCommon/VideoCommon.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(
|
static Common::EventHook s_after_frame_event = AfterFrameEvent::Register(
|
||||||
[] {
|
[] {
|
||||||
DolphinAnalytics::PerformanceSample perf_sample;
|
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_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;
|
perf_sample.num_draw_calls = g_stats.this_frame.num_draw_calls;
|
||||||
DolphinAnalytics::Instance().ReportPerformanceInfo(std::move(perf_sample));
|
DolphinAnalytics::Instance().ReportPerformanceInfo(std::move(perf_sample));
|
||||||
|
|
|
@ -546,7 +546,7 @@ void VertexManagerBase::Flush()
|
||||||
if (g_ActiveConfig.bGraphicMods)
|
if (g_ActiveConfig.bGraphicMods)
|
||||||
{
|
{
|
||||||
const double seconds_elapsed =
|
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;
|
pixel_shader_manager.constants.time_ms = seconds_elapsed * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue