1
// Copyright (C) 2003 Dolphin Project.
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0.
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
15
// Official Git repository and contact information can be found at
16
// http://code.google.com/p/dolphin-emu/
19
// This file controls all system timers
21
/* (shuffle2) I don't know who wrote this, but take it with salt. For starters, "time" is contextual...
22
"Time" is measured in frames, not time: These update frequencies are determined by the passage
23
of frames. So if a game runs slow, on a slow computer for example, these updates will occur
24
less frequently. This makes sense because almost all console games are controlled by frames
25
rather than time, so if a game can't keep up with the normal framerate all animations and
26
actions slows down and the game runs to slow. This is different from PC games that are
27
often controlled by time instead and may not have maximum framerates.
29
However, I'm not sure if the Bluetooth communication for the Wiimote is entirely frame
30
dependent, the timing problems with the ack command in Zelda - TP may be related to
31
time rather than frames? For now the IPC_HLE_PERIOD is frame dependent, but because of
32
different conditions on the way to PluginWiimote::Wiimote_Update() the updates may actually
33
be time related after all, or not?
35
I'm not sure about this but the text below seems to assume that 60 fps means that the game
36
runs in the normal intended speed. In that case an update time of [GetTicksPerSecond() / 60]
37
would mean one update per frame and [GetTicksPerSecond() / 250] would mean four updates per
41
IPC_HLE_PERIOD: For the Wiimote this is the call schedule:
42
IPC_HLE_UpdateCallback() // In this file
44
// This function seems to call all devices' Update() function four times per frame
45
WII_IPC_HLE_Interface::Update()
47
// If the AclFrameQue is empty this will call Wiimote_Update() and make it send
48
the current input status to the game. I'm not sure if this occurs approximately
49
once every frame or if the frequency is not exactly tied to rendered frames
50
CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
51
PluginWiimote::Wiimote_Update()
53
// This is also a device updated by WII_IPC_HLE_Interface::Update() but it doesn't
54
seem to ultimately call PluginWiimote::Wiimote_Update(). However it can be called
55
by the /dev/usb/oh1 device if the AclFrameQue is empty.
56
CWII_IPC_HLE_WiiMote::Update()
62
#include "../PatchEngine.h"
63
#include "SystemTimers.h"
64
#include "../HW/DSP.h"
65
#include "../HW/AudioInterface.h"
66
#include "../HW/VideoInterface.h"
68
#include "../HW/EXI_DeviceIPL.h"
69
#include "../PowerPC/PowerPC.h"
70
#include "../CoreTiming.h"
71
#include "../ConfigManager.h"
72
#include "../IPC_HLE/WII_IPC_HLE.h"
73
#include "../DSPEmulator.h"
76
#include "VideoBackendBase.h"
77
#include "CommandProcessor.h"
80
namespace SystemTimers
83
u32 CPU_CORE_CLOCK = 486000000u; // 486 mhz (its not 485, stop bugging me!)
87
flipper <-> ARAM bus: 81 (DSP)
88
gekko <-> flipper bus: 162
89
flipper <-> 1T-SRAM bus: 324
92
These contain some guesses:
94
hollywood <-> GDDR3 RAM bus: ??? no idea really
95
broadway <-> hollywood bus: 243
96
hollywood <-> 1T-SRAM bus: 486
99
// Ratio of TB and Decrementer to clock cycles.
100
// TB clk is 1/4 of BUS clk. And it seems BUS clk is really 1/3 of CPU clk.
101
// So, ratio is 1 / (1/4 * 1/3 = 1/12) = 12.
102
// note: ZWW is ok and faster with TIMER_RATIO=8 though.
103
// !!! POSSIBLE STABLE PERF BOOST HACK THERE !!!
117
int et_PatchEngine; // PatchEngine updates every 1/60th of a second by default
119
// These are badly educated guesses
120
// Feel free to experiment. Set these in Init below.
122
// This is a fixed value, don't change it
125
// Regulates the speed of the Command Processor
128
// This is completely arbitrary. If we find that we need lower latency, we can just
129
// increase this number.
134
u32 GetTicksPerSecond()
136
return CPU_CORE_CLOCK;
139
u32 ConvertMillisecondsToTicks(u32 _Milliseconds)
141
return GetTicksPerSecond() / 1000 * _Milliseconds;
144
// DSP/CPU timeslicing.
145
void DSPCallback(u64 userdata, int cyclesLate)
147
//splits up the cycle budget in case lle is used
148
//for hle, just gives all of the slice to hle
149
DSP::UpdateDSPSlice(DSP::GetDSPEmulator()->DSP_UpdateRate() - cyclesLate);
150
CoreTiming::ScheduleEvent(DSP::GetDSPEmulator()->DSP_UpdateRate() - cyclesLate, et_DSP);
153
void AudioDMACallback(u64 userdata, int cyclesLate)
155
int fields = VideoInterface::GetNumFields();
156
int period = CPU_CORE_CLOCK / (AudioInterface::GetAIDSampleRate() * 4 / 32 * fields);
157
DSP::UpdateAudioDMA(); // Push audio to speakers.
158
CoreTiming::ScheduleEvent(period - cyclesLate, et_AudioDMA);
161
void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate)
163
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
165
WII_IPC_HLE_Interface::Update();
166
CoreTiming::ScheduleEvent(IPC_HLE_PERIOD - cyclesLate, et_IPC_HLE);
170
void VICallback(u64 userdata, int cyclesLate)
172
VideoInterface::Update();
173
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine() - cyclesLate, et_VI);
176
void SICallback(u64 userdata, int cyclesLate)
178
SerialInterface::UpdateDevices();
179
CoreTiming::ScheduleEvent(SerialInterface::GetTicksToNextSIPoll() - cyclesLate, et_SI);
182
void CPCallback(u64 userdata, int cyclesLate)
184
CommandProcessor::Update();
185
CoreTiming::ScheduleEvent(CP_PERIOD - cyclesLate, et_CP);
188
void DecrementerCallback(u64 userdata, int cyclesLate)
190
PowerPC::ppcState.spr[SPR_DEC] = 0xFFFFFFFF;
191
Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER);
194
void DecrementerSet()
196
u32 decValue = PowerPC::ppcState.spr[SPR_DEC];
198
CoreTiming::RemoveEvent(et_Dec);
199
if ((decValue & 0x80000000) == 0)
201
CoreTiming::SetFakeDecStartTicks(CoreTiming::GetTicks());
202
CoreTiming::SetFakeDecStartValue(decValue);
204
CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec);
208
u32 GetFakeDecrementer()
210
return (CoreTiming::GetFakeDecStartValue() - (u32)((CoreTiming::GetTicks() - CoreTiming::GetFakeDecStartTicks()) / TIMER_RATIO));
215
CoreTiming::SetFakeTBStartTicks(CoreTiming::GetTicks());
216
CoreTiming::SetFakeTBStartValue(*((u64 *)&TL));
219
u64 GetFakeTimeBase()
221
return CoreTiming::GetFakeTBStartValue() + ((CoreTiming::GetTicks() - CoreTiming::GetFakeTBStartTicks()) / TIMER_RATIO);
224
void PatchEngineCallback(u64 userdata, int cyclesLate)
226
// Patch mem and run the Action Replay
227
PatchEngine::ApplyFramePatches();
228
PatchEngine::ApplyARPatches();
229
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_PatchEngine);
232
// split from Init to break a circular dependency between VideoInterface::Init and SystemTimers::Init
235
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
236
CPU_CORE_CLOCK = 729000000u;
238
CPU_CORE_CLOCK = 486000000u;
243
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
245
// AyuanX: TO BE TWEAKED
246
// Now the 1500 is a pure assumption
247
// We need to figure out the real frequency though
249
// FYI, WII_IPC_HLE_Interface::Update is also called in WII_IPCInterface::Write32
250
const int freq = 1500;
251
IPC_HLE_PERIOD = GetTicksPerSecond() / (freq * VideoInterface::GetNumFields());
254
// System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA
255
AUDIO_DMA_PERIOD = CPU_CORE_CLOCK / (AudioInterface::GetAIDSampleRate() * 4 / 32);
257
// Emulated gekko <-> flipper bus speed ratio (cpu clock / flipper clock)
258
CP_PERIOD = GetTicksPerSecond() / 10000;
260
Common::Timer::IncreaseResolution();
261
// store and convert localtime at boot to timebase ticks
262
CoreTiming::SetFakeTBStartValue((u64)(CPU_CORE_CLOCK / TIMER_RATIO) * (u64)CEXIIPL::GetGCTime());
263
CoreTiming::SetFakeTBStartTicks(CoreTiming::GetTicks());
265
CoreTiming::SetFakeDecStartValue(0xFFFFFFFF);
266
CoreTiming::SetFakeDecStartTicks(CoreTiming::GetTicks());
268
et_Dec = CoreTiming::RegisterEvent("DecCallback", DecrementerCallback);
269
et_VI = CoreTiming::RegisterEvent("VICallback", VICallback);
270
et_SI = CoreTiming::RegisterEvent("SICallback", SICallback);
271
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU)
272
et_CP = CoreTiming::RegisterEvent("CPCallback", CPCallback);
273
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
274
et_AudioDMA = CoreTiming::RegisterEvent("AudioDMACallback", AudioDMACallback);
275
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
276
et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback);
278
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine(), et_VI);
279
CoreTiming::ScheduleEvent(0, et_DSP);
280
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_SI);
281
CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA);
282
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU)
283
CoreTiming::ScheduleEvent(CP_PERIOD, et_CP);
285
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_PatchEngine);
287
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
288
CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE);
293
Common::Timer::RestoreResolution();