~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Core/Src/HW/SystemTimers.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2003 Dolphin Project.
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official Git repository and contact information can be found at
 
16
// http://code.google.com/p/dolphin-emu/
 
17
 
 
18
 
 
19
// This file controls all system timers
 
20
 
 
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.
 
28
 
 
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?
 
34
 
 
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
 
38
frame.
 
39
 
 
40
 
 
41
IPC_HLE_PERIOD: For the Wiimote this is the call schedule:
 
42
        IPC_HLE_UpdateCallback() // In this file
 
43
 
 
44
                // This function seems to call all devices' Update() function four times per frame
 
45
                WII_IPC_HLE_Interface::Update()
 
46
 
 
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()
 
52
 
 
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()
 
57
*/
 
58
 
 
59
 
 
60
#include "Common.h"
 
61
#include "Atomic.h"
 
62
#include "../PatchEngine.h"
 
63
#include "SystemTimers.h"
 
64
#include "../HW/DSP.h"
 
65
#include "../HW/AudioInterface.h"
 
66
#include "../HW/VideoInterface.h"
 
67
#include "../HW/SI.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"
 
74
#include "Thread.h"
 
75
#include "Timer.h"
 
76
#include "VideoBackendBase.h"
 
77
#include "CommandProcessor.h"
 
78
 
 
79
 
 
80
namespace SystemTimers
 
81
{
 
82
 
 
83
u32 CPU_CORE_CLOCK  = 486000000u;             // 486 mhz (its not 485, stop bugging me!)
 
84
 
 
85
/*
 
86
Gamecube                                                MHz
 
87
flipper <-> ARAM bus:                   81 (DSP)
 
88
gekko <-> flipper bus:                  162
 
89
flipper <-> 1T-SRAM bus:                324
 
90
gekko:                                                  486
 
91
 
 
92
These contain some guesses:
 
93
Wii                                                             MHz
 
94
hollywood <-> GDDR3 RAM bus:    ??? no idea really
 
95
broadway <-> hollywood bus:             243
 
96
hollywood <-> 1T-SRAM bus:              486
 
97
broadway:                                               729
 
98
*/
 
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 !!!
 
104
 
 
105
enum
 
106
{
 
107
        TIMER_RATIO = 12
 
108
};
 
109
 
 
110
int et_Dec;
 
111
int et_VI;
 
112
int et_SI;
 
113
int et_CP;
 
114
int et_AudioDMA;
 
115
int et_DSP;
 
116
int et_IPC_HLE;
 
117
int et_PatchEngine;     // PatchEngine updates every 1/60th of a second by default
 
118
 
 
119
// These are badly educated guesses
 
120
// Feel free to experiment. Set these in Init below.
 
121
int
 
122
        // This is a fixed value, don't change it 
 
123
        AUDIO_DMA_PERIOD,
 
124
 
 
125
        // Regulates the speed of the Command Processor
 
126
        CP_PERIOD,
 
127
 
 
128
        // This is completely arbitrary. If we find that we need lower latency, we can just
 
129
        // increase this number.
 
130
        IPC_HLE_PERIOD;
 
131
 
 
132
 
 
133
 
 
134
u32 GetTicksPerSecond()
 
135
{
 
136
        return CPU_CORE_CLOCK;
 
137
}
 
138
 
 
139
u32 ConvertMillisecondsToTicks(u32 _Milliseconds)
 
140
{
 
141
        return GetTicksPerSecond() / 1000 * _Milliseconds;
 
142
}
 
143
 
 
144
// DSP/CPU timeslicing.
 
145
void DSPCallback(u64 userdata, int cyclesLate)
 
146
{
 
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);
 
151
}
 
152
 
 
153
void AudioDMACallback(u64 userdata, int cyclesLate)
 
154
{
 
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);
 
159
}
 
160
 
 
161
void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate)
 
162
{
 
163
        if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
 
164
        {
 
165
                WII_IPC_HLE_Interface::Update();
 
166
                CoreTiming::ScheduleEvent(IPC_HLE_PERIOD - cyclesLate, et_IPC_HLE);
 
167
        }
 
168
}
 
169
 
 
170
void VICallback(u64 userdata, int cyclesLate)
 
171
{
 
172
        VideoInterface::Update();
 
173
        CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine() - cyclesLate, et_VI);
 
174
}
 
175
 
 
176
void SICallback(u64 userdata, int cyclesLate)
 
177
{
 
178
        SerialInterface::UpdateDevices();
 
179
        CoreTiming::ScheduleEvent(SerialInterface::GetTicksToNextSIPoll() - cyclesLate, et_SI);
 
180
}
 
181
 
 
182
void CPCallback(u64 userdata, int cyclesLate)
 
183
{
 
184
        CommandProcessor::Update();
 
185
        CoreTiming::ScheduleEvent(CP_PERIOD - cyclesLate, et_CP);
 
186
}
 
187
 
 
188
void DecrementerCallback(u64 userdata, int cyclesLate)
 
189
{
 
190
        PowerPC::ppcState.spr[SPR_DEC] = 0xFFFFFFFF;
 
191
        Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER);
 
192
}
 
193
 
 
194
void DecrementerSet()
 
195
{
 
196
        u32 decValue = PowerPC::ppcState.spr[SPR_DEC];
 
197
 
 
198
        CoreTiming::RemoveEvent(et_Dec);
 
199
        if ((decValue & 0x80000000) == 0)
 
200
        {
 
201
                CoreTiming::SetFakeDecStartTicks(CoreTiming::GetTicks());
 
202
                CoreTiming::SetFakeDecStartValue(decValue);
 
203
                
 
204
                CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec);
 
205
        }
 
206
}
 
207
 
 
208
u32 GetFakeDecrementer()
 
209
{
 
210
        return (CoreTiming::GetFakeDecStartValue() - (u32)((CoreTiming::GetTicks() - CoreTiming::GetFakeDecStartTicks()) / TIMER_RATIO));
 
211
}
 
212
 
 
213
void TimeBaseSet()
 
214
{
 
215
        CoreTiming::SetFakeTBStartTicks(CoreTiming::GetTicks());
 
216
        CoreTiming::SetFakeTBStartValue(*((u64 *)&TL));
 
217
}
 
218
 
 
219
u64 GetFakeTimeBase()
 
220
{
 
221
        return CoreTiming::GetFakeTBStartValue() + ((CoreTiming::GetTicks() - CoreTiming::GetFakeTBStartTicks()) / TIMER_RATIO);
 
222
}
 
223
 
 
224
void PatchEngineCallback(u64 userdata, int cyclesLate)
 
225
{
 
226
        // Patch mem and run the Action Replay
 
227
        PatchEngine::ApplyFramePatches();
 
228
        PatchEngine::ApplyARPatches();
 
229
        CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_PatchEngine);
 
230
}
 
231
 
 
232
// split from Init to break a circular dependency between VideoInterface::Init and SystemTimers::Init
 
233
void PreInit()
 
234
{
 
235
        if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
 
236
                CPU_CORE_CLOCK = 729000000u;
 
237
        else
 
238
                CPU_CORE_CLOCK = 486000000u;
 
239
}
 
240
 
 
241
void Init()
 
242
{
 
243
        if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
 
244
        {
 
245
                // AyuanX: TO BE TWEAKED
 
246
                // Now the 1500 is a pure assumption
 
247
                // We need to figure out the real frequency though
 
248
 
 
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());
 
252
        }
 
253
 
 
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);
 
256
 
 
257
        // Emulated gekko <-> flipper bus speed ratio (cpu clock / flipper clock)
 
258
        CP_PERIOD = GetTicksPerSecond() / 10000;
 
259
 
 
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());
 
264
 
 
265
        CoreTiming::SetFakeDecStartValue(0xFFFFFFFF);
 
266
        CoreTiming::SetFakeDecStartTicks(CoreTiming::GetTicks());
 
267
 
 
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);
 
277
 
 
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);
 
284
 
 
285
        CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_PatchEngine);
 
286
 
 
287
        if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
 
288
                CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE);
 
289
}
 
290
 
 
291
void Shutdown()
 
292
{
 
293
        Common::Timer::RestoreResolution();
 
294
}
 
295
 
 
296
}  // namespace