summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/core.vcxproj3
-rw-r--r--src/core/core.vcxproj.filters3
-rw-r--r--src/core/src/core_timing.cpp639
-rw-r--r--src/core/src/core_timing.h125
-rw-r--r--src/core/src/system.cpp52
-rw-r--r--src/core/src/system.h3
6 files changed, 823 insertions, 2 deletions
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index d707a566c..d3b26b661 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -141,11 +141,13 @@
141 <ClCompile Include="src\arm\arminit.cpp" /> 141 <ClCompile Include="src\arm\arminit.cpp" />
142 <ClCompile Include="src\arm\disassembler\arm_disasm.cpp" /> 142 <ClCompile Include="src\arm\disassembler\arm_disasm.cpp" />
143 <ClCompile Include="src\core.cpp" /> 143 <ClCompile Include="src\core.cpp" />
144 <ClCompile Include="src\core_timing.cpp" />
144 <ClCompile Include="src\file_sys\directory_file_system.cpp" /> 145 <ClCompile Include="src\file_sys\directory_file_system.cpp" />
145 <ClCompile Include="src\file_sys\meta_file_system.cpp" /> 146 <ClCompile Include="src\file_sys\meta_file_system.cpp" />
146 <ClCompile Include="src\loader.cpp" /> 147 <ClCompile Include="src\loader.cpp" />
147 <ClCompile Include="src\mem_map.cpp" /> 148 <ClCompile Include="src\mem_map.cpp" />
148 <ClCompile Include="src\mem_map_funcs.cpp" /> 149 <ClCompile Include="src\mem_map_funcs.cpp" />
150 <ClCompile Include="src\system.cpp" />
149 </ItemGroup> 151 </ItemGroup>
150 <ItemGroup> 152 <ItemGroup>
151 <ClInclude Include="src\arm\armcpu.h" /> 153 <ClInclude Include="src\arm\armcpu.h" />
@@ -162,6 +164,7 @@
162 <ClInclude Include="src\arm\mmu\wb.h" /> 164 <ClInclude Include="src\arm\mmu\wb.h" />
163 <ClInclude Include="src\arm\skyeye_defs.h" /> 165 <ClInclude Include="src\arm\skyeye_defs.h" />
164 <ClInclude Include="src\core.h" /> 166 <ClInclude Include="src\core.h" />
167 <ClInclude Include="src\core_timing.h" />
165 <ClInclude Include="src\file_sys\directory_file_system.h" /> 168 <ClInclude Include="src\file_sys\directory_file_system.h" />
166 <ClInclude Include="src\file_sys\file_sys.h" /> 169 <ClInclude Include="src\file_sys\file_sys.h" />
167 <ClInclude Include="src\file_sys\meta_file_system.h" /> 170 <ClInclude Include="src\file_sys\meta_file_system.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 039373047..de3aab97f 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -20,6 +20,8 @@
20 <ClCompile Include="src\file_sys\meta_file_system.cpp"> 20 <ClCompile Include="src\file_sys\meta_file_system.cpp">
21 <Filter>file_sys</Filter> 21 <Filter>file_sys</Filter>
22 </ClCompile> 22 </ClCompile>
23 <ClCompile Include="src\system.cpp" />
24 <ClCompile Include="src\core_timing.cpp" />
23 </ItemGroup> 25 </ItemGroup>
24 <ItemGroup> 26 <ItemGroup>
25 <Filter Include="arm"> 27 <Filter Include="arm">
@@ -88,6 +90,7 @@
88 <Filter>file_sys</Filter> 90 <Filter>file_sys</Filter>
89 </ClInclude> 91 </ClInclude>
90 <ClInclude Include="src\system.h" /> 92 <ClInclude Include="src\system.h" />
93 <ClInclude Include="src\core_timing.h" />
91 </ItemGroup> 94 </ItemGroup>
92 <ItemGroup> 95 <ItemGroup>
93 <None Include="CMakeLists.txt" /> 96 <None Include="CMakeLists.txt" />
diff --git a/src/core/src/core_timing.cpp b/src/core/src/core_timing.cpp
new file mode 100644
index 000000000..73dd9b549
--- /dev/null
+++ b/src/core/src/core_timing.cpp
@@ -0,0 +1,639 @@
1// Copyright (c) 2012- PPSSPP Project / 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 or later versions.
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// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
19#include <vector>
20#include <cstdio>
21
22#include "msg_handler.h"
23#include "std_mutex.h"
24#include "atomic.h"
25#include "core_timing.h"
26#include "core.h"
27#include "chunk_file.h"
28
29//#include "HLE/sceKernelThread.h"
30
31int g_clock_rate_arm11 = 268123480;
32
33// is this really necessary?
34#define INITIAL_SLICE_LENGTH 20000
35#define MAX_SLICE_LENGTH 100000000
36
37namespace CoreTiming
38{
39
40struct EventType
41{
42 EventType() {}
43
44 EventType(TimedCallback cb, const char *n)
45 : callback(cb), name(n) {}
46
47 TimedCallback callback;
48 const char *name;
49};
50
51std::vector<EventType> event_types;
52
53struct BaseEvent
54{
55 s64 time;
56 u64 userdata;
57 int type;
58// Event *next;
59};
60
61typedef LinkedListItem<BaseEvent> Event;
62
63Event *first;
64Event *tsFirst;
65Event *tsLast;
66
67// event pools
68Event *eventPool = 0;
69Event *eventTsPool = 0;
70int allocatedTsEvents = 0;
71// Optimization to skip MoveEvents when possible.
72volatile u32 hasTsEvents = false;
73
74// Downcount has been moved to currentMIPS, to save a couple of clocks in every ARM JIT block
75// as we can already reach that structure through a register.
76int slicelength;
77
78MEMORY_ALIGNED16(s64) globalTimer;
79s64 idledCycles;
80
81static std::recursive_mutex externalEventSection;
82
83// Warning: not included in save state.
84void (*advanceCallback)(int cyclesExecuted) = NULL;
85
86void SetClockFrequencyMHz(int cpuMhz)
87{
88 g_clock_rate_arm11 = cpuMhz * 1000000;
89 // TODO: Rescale times of scheduled events?
90}
91
92int GetClockFrequencyMHz()
93{
94 return g_clock_rate_arm11 / 1000000;
95}
96
97
98Event* GetNewEvent()
99{
100 if(!eventPool)
101 return new Event;
102
103 Event* ev = eventPool;
104 eventPool = ev->next;
105 return ev;
106}
107
108Event* GetNewTsEvent()
109{
110 allocatedTsEvents++;
111
112 if(!eventTsPool)
113 return new Event;
114
115 Event* ev = eventTsPool;
116 eventTsPool = ev->next;
117 return ev;
118}
119
120void FreeEvent(Event* ev)
121{
122 ev->next = eventPool;
123 eventPool = ev;
124}
125
126void FreeTsEvent(Event* ev)
127{
128 ev->next = eventTsPool;
129 eventTsPool = ev;
130 allocatedTsEvents--;
131}
132
133int RegisterEvent(const char *name, TimedCallback callback)
134{
135 event_types.push_back(EventType(callback, name));
136 return (int)event_types.size() - 1;
137}
138
139void AntiCrashCallback(u64 userdata, int cyclesLate)
140{
141 ERROR_LOG(TIME, "Savestate broken: an unregistered event was called.");
142 Core::Halt("invalid timing events");
143}
144
145void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback)
146{
147 if (event_type >= (int) event_types.size())
148 event_types.resize(event_type + 1, EventType(AntiCrashCallback, "INVALID EVENT"));
149
150 event_types[event_type] = EventType(callback, name);
151}
152
153void UnregisterAllEvents()
154{
155 if (first)
156 PanicAlert("Cannot unregister events with events pending");
157 event_types.clear();
158}
159
160void Init()
161{
162 //currentMIPS->downcount = INITIAL_SLICE_LENGTH;
163 //slicelength = INITIAL_SLICE_LENGTH;
164 globalTimer = 0;
165 idledCycles = 0;
166 hasTsEvents = 0;
167}
168
169void Shutdown()
170{
171 MoveEvents();
172 ClearPendingEvents();
173 UnregisterAllEvents();
174
175 while(eventPool)
176 {
177 Event *ev = eventPool;
178 eventPool = ev->next;
179 delete ev;
180 }
181
182 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
183 while(eventTsPool)
184 {
185 Event *ev = eventTsPool;
186 eventTsPool = ev->next;
187 delete ev;
188 }
189}
190
191u64 GetTicks()
192{
193 ERROR_LOG(TIME, "Unimplemented function!");
194 return 0;
195 //return (u64)globalTimer + slicelength - currentMIPS->downcount;
196}
197
198u64 GetIdleTicks()
199{
200 return (u64)idledCycles;
201}
202
203
204// This is to be called when outside threads, such as the graphics thread, wants to
205// schedule things to be executed on the main thread.
206void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata)
207{
208 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
209 Event *ne = GetNewTsEvent();
210 ne->time = GetTicks() + cyclesIntoFuture;
211 ne->type = event_type;
212 ne->next = 0;
213 ne->userdata = userdata;
214 if(!tsFirst)
215 tsFirst = ne;
216 if(tsLast)
217 tsLast->next = ne;
218 tsLast = ne;
219
220 Common::AtomicStoreRelease(hasTsEvents, 1);
221}
222
223// Same as ScheduleEvent_Threadsafe(0, ...) EXCEPT if we are already on the CPU thread
224// in which case the event will get handled immediately, before returning.
225void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata)
226{
227 if(false) //Core::IsCPUThread())
228 {
229 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
230 event_types[event_type].callback(userdata, 0);
231 }
232 else
233 ScheduleEvent_Threadsafe(0, event_type, userdata);
234}
235
236void ClearPendingEvents()
237{
238 while (first)
239 {
240 Event *e = first->next;
241 FreeEvent(first);
242 first = e;
243 }
244}
245
246void AddEventToQueue(Event* ne)
247{
248 Event* prev = NULL;
249 Event** pNext = &first;
250 for(;;)
251 {
252 Event*& next = *pNext;
253 if(!next || ne->time < next->time)
254 {
255 ne->next = next;
256 next = ne;
257 break;
258 }
259 prev = next;
260 pNext = &prev->next;
261 }
262}
263
264// This must be run ONLY from within the cpu thread
265// cyclesIntoFuture may be VERY inaccurate if called from anything else
266// than Advance
267void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata)
268{
269 Event *ne = GetNewEvent();
270 ne->userdata = userdata;
271 ne->type = event_type;
272 ne->time = GetTicks() + cyclesIntoFuture;
273 AddEventToQueue(ne);
274}
275
276// Returns cycles left in timer.
277s64 UnscheduleEvent(int event_type, u64 userdata)
278{
279 s64 result = 0;
280 if (!first)
281 return result;
282 while(first)
283 {
284 if (first->type == event_type && first->userdata == userdata)
285 {
286 result = first->time - globalTimer;
287
288 Event *next = first->next;
289 FreeEvent(first);
290 first = next;
291 }
292 else
293 {
294 break;
295 }
296 }
297 if (!first)
298 return result;
299 Event *prev = first;
300 Event *ptr = prev->next;
301 while (ptr)
302 {
303 if (ptr->type == event_type && ptr->userdata == userdata)
304 {
305 result = ptr->time - globalTimer;
306
307 prev->next = ptr->next;
308 FreeEvent(ptr);
309 ptr = prev->next;
310 }
311 else
312 {
313 prev = ptr;
314 ptr = ptr->next;
315 }
316 }
317
318 return result;
319}
320
321s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata)
322{
323 s64 result = 0;
324 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
325 if (!tsFirst)
326 return result;
327 while(tsFirst)
328 {
329 if (tsFirst->type == event_type && tsFirst->userdata == userdata)
330 {
331 result = tsFirst->time - globalTimer;
332
333 Event *next = tsFirst->next;
334 FreeTsEvent(tsFirst);
335 tsFirst = next;
336 }
337 else
338 {
339 break;
340 }
341 }
342 if (!tsFirst)
343 {
344 tsLast = NULL;
345 return result;
346 }
347
348 Event *prev = tsFirst;
349 Event *ptr = prev->next;
350 while (ptr)
351 {
352 if (ptr->type == event_type && ptr->userdata == userdata)
353 {
354 result = ptr->time - globalTimer;
355
356 prev->next = ptr->next;
357 if (ptr == tsLast)
358 tsLast = prev;
359 FreeTsEvent(ptr);
360 ptr = prev->next;
361 }
362 else
363 {
364 prev = ptr;
365 ptr = ptr->next;
366 }
367 }
368
369 return result;
370}
371
372// Warning: not included in save state.
373void RegisterAdvanceCallback(void (*callback)(int cyclesExecuted))
374{
375 advanceCallback = callback;
376}
377
378bool IsScheduled(int event_type)
379{
380 if (!first)
381 return false;
382 Event *e = first;
383 while (e) {
384 if (e->type == event_type)
385 return true;
386 e = e->next;
387 }
388 return false;
389}
390
391void RemoveEvent(int event_type)
392{
393 if (!first)
394 return;
395 while(first)
396 {
397 if (first->type == event_type)
398 {
399 Event *next = first->next;
400 FreeEvent(first);
401 first = next;
402 }
403 else
404 {
405 break;
406 }
407 }
408 if (!first)
409 return;
410 Event *prev = first;
411 Event *ptr = prev->next;
412 while (ptr)
413 {
414 if (ptr->type == event_type)
415 {
416 prev->next = ptr->next;
417 FreeEvent(ptr);
418 ptr = prev->next;
419 }
420 else
421 {
422 prev = ptr;
423 ptr = ptr->next;
424 }
425 }
426}
427
428void RemoveThreadsafeEvent(int event_type)
429{
430 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
431 if (!tsFirst)
432 {
433 return;
434 }
435 while(tsFirst)
436 {
437 if (tsFirst->type == event_type)
438 {
439 Event *next = tsFirst->next;
440 FreeTsEvent(tsFirst);
441 tsFirst = next;
442 }
443 else
444 {
445 break;
446 }
447 }
448 if (!tsFirst)
449 {
450 tsLast = NULL;
451 return;
452 }
453 Event *prev = tsFirst;
454 Event *ptr = prev->next;
455 while (ptr)
456 {
457 if (ptr->type == event_type)
458 {
459 prev->next = ptr->next;
460 if (ptr == tsLast)
461 tsLast = prev;
462 FreeTsEvent(ptr);
463 ptr = prev->next;
464 }
465 else
466 {
467 prev = ptr;
468 ptr = ptr->next;
469 }
470 }
471}
472
473void RemoveAllEvents(int event_type)
474{
475 RemoveThreadsafeEvent(event_type);
476 RemoveEvent(event_type);
477}
478
479//This raise only the events required while the fifo is processing data
480void ProcessFifoWaitEvents()
481{
482 while (first)
483 {
484 if (first->time <= globalTimer)
485 {
486// LOG(TIMER, "[Scheduler] %s (%lld, %lld) ",
487// first->name ? first->name : "?", (u64)globalTimer, (u64)first->time);
488 Event* evt = first;
489 first = first->next;
490 event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
491 FreeEvent(evt);
492 }
493 else
494 {
495 break;
496 }
497 }
498}
499
500void MoveEvents()
501{
502 Common::AtomicStoreRelease(hasTsEvents, 0);
503
504 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
505 // Move events from async queue into main queue
506 while (tsFirst)
507 {
508 Event *next = tsFirst->next;
509 AddEventToQueue(tsFirst);
510 tsFirst = next;
511 }
512 tsLast = NULL;
513
514 // Move free events to threadsafe pool
515 while(allocatedTsEvents > 0 && eventPool)
516 {
517 Event *ev = eventPool;
518 eventPool = ev->next;
519 ev->next = eventTsPool;
520 eventTsPool = ev;
521 allocatedTsEvents--;
522 }
523}
524
525void Advance()
526{
527 ERROR_LOG(TIME, "Unimplemented function!");
528 //int cyclesExecuted = slicelength - currentMIPS->downcount;
529 //globalTimer += cyclesExecuted;
530 //currentMIPS->downcount = slicelength;
531
532 //if (Common::AtomicLoadAcquire(hasTsEvents))
533 // MoveEvents();
534 //ProcessFifoWaitEvents();
535
536 //if (!first)
537 //{
538 // // WARN_LOG(TIMER, "WARNING - no events in queue. Setting currentMIPS->downcount to 10000");
539 // currentMIPS->downcount += 10000;
540 //}
541 //else
542 //{
543 // slicelength = (int)(first->time - globalTimer);
544 // if (slicelength > MAX_SLICE_LENGTH)
545 // slicelength = MAX_SLICE_LENGTH;
546 // currentMIPS->downcount = slicelength;
547 //}
548 //if (advanceCallback)
549 // advanceCallback(cyclesExecuted);
550}
551
552void LogPendingEvents()
553{
554 Event *ptr = first;
555 while (ptr)
556 {
557 //INFO_LOG(TIMER, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, ptr->time, ptr->type);
558 ptr = ptr->next;
559 }
560}
561
562void Idle(int maxIdle)
563{
564 ERROR_LOG(TIME, "Unimplemented function!");
565 //int cyclesDown = currentMIPS->downcount;
566 //if (maxIdle != 0 && cyclesDown > maxIdle)
567 // cyclesDown = maxIdle;
568
569 //if (first && cyclesDown > 0)
570 //{
571 // int cyclesExecuted = slicelength - currentMIPS->downcount;
572 // int cyclesNextEvent = (int) (first->time - globalTimer);
573
574 // if (cyclesNextEvent < cyclesExecuted + cyclesDown)
575 // {
576 // cyclesDown = cyclesNextEvent - cyclesExecuted;
577 // // Now, now... no time machines, please.
578 // if (cyclesDown < 0)
579 // cyclesDown = 0;
580 // }
581 //}
582
583 //INFO_LOG(TIME, "Idle for %i cycles! (%f ms)", cyclesDown, cyclesDown / (float)(g_clock_rate_arm11 * 0.001f));
584
585 //idledCycles += cyclesDown;
586 //currentMIPS->downcount -= cyclesDown;
587 //if (currentMIPS->downcount == 0)
588 // currentMIPS->downcount = -1;
589}
590
591std::string GetScheduledEventsSummary()
592{
593 Event *ptr = first;
594 std::string text = "Scheduled events\n";
595 text.reserve(1000);
596 while (ptr)
597 {
598 unsigned int t = ptr->type;
599 if (t >= event_types.size())
600 PanicAlert("Invalid event type"); // %i", t);
601 const char *name = event_types[ptr->type].name;
602 if (!name)
603 name = "[unknown]";
604 char temp[512];
605 sprintf(temp, "%s : %i %08x%08x\n", name, (int)ptr->time, (u32)(ptr->userdata >> 32), (u32)(ptr->userdata));
606 text += temp;
607 ptr = ptr->next;
608 }
609 return text;
610}
611
612void Event_DoState(PointerWrap &p, BaseEvent *ev)
613{
614 p.Do(*ev);
615}
616
617void DoState(PointerWrap &p)
618{
619 std::lock_guard<std::recursive_mutex> lk(externalEventSection);
620
621 auto s = p.Section("CoreTiming", 1);
622 if (!s)
623 return;
624
625 int n = (int) event_types.size();
626 p.Do(n);
627 // These (should) be filled in later by the modules.
628 event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT"));
629
630 p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, Event_DoState>(first, (Event **) NULL);
631 p.DoLinkedList<BaseEvent, GetNewTsEvent, FreeTsEvent, Event_DoState>(tsFirst, &tsLast);
632
633 p.Do(g_clock_rate_arm11);
634 p.Do(slicelength);
635 p.Do(globalTimer);
636 p.Do(idledCycles);
637}
638
639} // namespace
diff --git a/src/core/src/core_timing.h b/src/core/src/core_timing.h
new file mode 100644
index 000000000..1ef17f6f8
--- /dev/null
+++ b/src/core/src/core_timing.h
@@ -0,0 +1,125 @@
1// Copyright (c) 2012- PPSSPP Project / 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 or later versions.
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// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18#ifndef CORE_CORE_TIMING_H_
19#define CORE_CORE_TIMING_H_
20
21// This is a system to schedule events into the emulated machine's future. Time is measured
22// in main CPU clock cycles.
23
24// To schedule an event, you first have to register its type. This is where you pass in the
25// callback. You then schedule events using the type id you get back.
26
27// See HW/SystemTimers.cpp for the main part of Dolphin's usage of this scheduler.
28
29// The int cyclesLate that the callbacks get is how many cycles late it was.
30// So to schedule a new event on a regular basis:
31// inside callback:
32// ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever")
33
34#include "common.h"
35
36class PointerWrap;
37
38extern int g_clock_rate_arm11;
39
40inline s64 msToCycles(int ms) {
41 return g_clock_rate_arm11 / 1000 * ms;
42}
43
44inline s64 msToCycles(float ms) {
45 return (s64)(g_clock_rate_arm11 * ms * (0.001f));
46}
47
48inline s64 msToCycles(double ms) {
49 return (s64)(g_clock_rate_arm11 * ms * (0.001));
50}
51
52inline s64 usToCycles(float us) {
53 return (s64)(g_clock_rate_arm11 * us * (0.000001f));
54}
55
56inline s64 usToCycles(int us) {
57 return (g_clock_rate_arm11 / 1000000 * (s64)us);
58}
59
60inline s64 usToCycles(s64 us) {
61 return (g_clock_rate_arm11 / 1000000 * us);
62}
63
64inline s64 usToCycles(u64 us) {
65 return (s64)(g_clock_rate_arm11 / 1000000 * us);
66}
67
68inline s64 cyclesToUs(s64 cycles) {
69 return cycles / (g_clock_rate_arm11 / 1000000);
70}
71
72namespace CoreTiming
73{
74 void Init();
75 void Shutdown();
76
77 typedef void (*TimedCallback)(u64 userdata, int cyclesLate);
78
79 u64 GetTicks();
80 u64 GetIdleTicks();
81
82 // Returns the event_type identifier.
83 int RegisterEvent(const char *name, TimedCallback callback);
84 // For save states.
85 void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback);
86 void UnregisterAllEvents();
87
88 // userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk,
89 // when we implement state saves.
90 void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata=0);
91 void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata=0);
92 void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata=0);
93 s64 UnscheduleEvent(int event_type, u64 userdata);
94 s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata);
95
96 void RemoveEvent(int event_type);
97 void RemoveThreadsafeEvent(int event_type);
98 void RemoveAllEvents(int event_type);
99 bool IsScheduled(int event_type);
100 void Advance();
101 void MoveEvents();
102 void ProcessFifoWaitEvents();
103
104 // Pretend that the main CPU has executed enough cycles to reach the next event.
105 void Idle(int maxIdle = 0);
106
107 // Clear all pending events. This should ONLY be done on exit or state load.
108 void ClearPendingEvents();
109
110 void LogPendingEvents();
111
112 // Warning: not included in save states.
113 void RegisterAdvanceCallback(void (*callback)(int cyclesExecuted));
114
115 std::string GetScheduledEventsSummary();
116
117 void DoState(PointerWrap &p);
118
119 void SetClockFrequencyMHz(int cpuMhz);
120 int GetClockFrequencyMHz();
121 extern int slicelength;
122
123}; // namespace
124
125#endif // CORE_CORE_TIMING_H_
diff --git a/src/core/src/system.cpp b/src/core/src/system.cpp
new file mode 100644
index 000000000..36fdf028c
--- /dev/null
+++ b/src/core/src/system.cpp
@@ -0,0 +1,52 @@
1/**
2* Copyright (C) 2013 Citrus Emulator
3*
4* @file system.cpp
5* @author ShizZy <shizzy247@gmail.com>
6* @date 2013-09-26
7* @brief Emulation of main system
8*
9* @section LICENSE
10* This program is free software; you can redistribute it and/or
11* modify it under the terms of the GNU General Public License as
12* published by the Free Software Foundation; either version 2 of
13* the License, or (at your option) any later version.
14*
15* This program is distributed in the hope that it will be useful, but
16* WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18* General Public License for more details at
19* http://www.gnu.org/copyleft/gpl.html
20*
21* Official project repository can be found at:
22* http://code.google.com/p/gekko-gc-emu/
23*/
24
25#include "core_timing.h"
26#include "system.h"
27
28namespace System {
29
30extern volatile State g_state;
31extern MetaFileSystem g_ctr_file_system;
32
33void UpdateState(State state) {
34}
35
36void Init() {
37}
38
39void RunLoopFor(int cycles) {
40 RunLoopUntil(CoreTiming::GetTicks() + cycles);
41}
42
43void RunLoopUntil(u64 global_cycles) {
44}
45
46void Shutdown() {
47 g_ctr_file_system.Shutdown();
48}
49
50
51
52} // namespace
diff --git a/src/core/src/system.h b/src/core/src/system.h
index d35515c66..b86a87164 100644
--- a/src/core/src/system.h
+++ b/src/core/src/system.h
@@ -31,8 +31,6 @@
31 31
32namespace System { 32namespace System {
33 33
34extern MetaFileSystem g_ctr_file_system;
35
36// State of the full emulator 34// State of the full emulator
37typedef enum { 35typedef enum {
38 STATE_NULL = 0, ///< System is in null state, nothing initialized 36 STATE_NULL = 0, ///< System is in null state, nothing initialized
@@ -46,6 +44,7 @@ typedef enum {
46} State; 44} State;
47 45
48extern volatile State g_state; 46extern volatile State g_state;
47extern MetaFileSystem g_ctr_file_system;
49 48
50void UpdateState(State state); 49void UpdateState(State state);
51void Init(); 50void Init();