Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/smp/timing/timing.cpp
2 views
1
#ifdef SMP_CPP
2
3
void SMP::add_clocks(unsigned clocks) {
4
step(clocks);
5
synchronize_dsp();
6
7
#if defined(DEBUGGER)
8
#error -DDEBUGGER SMP runtosave() correctness not checked
9
synchronize_cpu();
10
#else
11
//forcefully sync S-SMP to S-CPU in case chips are not communicating
12
//sync if S-SMP is more than 24 samples ahead of S-CPU
13
/*
14
our new smp design guarantees that there is at most one required synchronize_cpu() per uop,
15
inside an op_busread() or op_buswrite(). this extra synchronize can cause problems if we
16
swap out of the SMP at the beginning of a uop with an add_clocks() call when there is an
17
important op_busread() / op_buswrite() later on. the SMP will need to finish that uop in
18
order to reach a savable state, but it might never get to do so until it's too late (ie,
19
scheduler.sync == Scheduler.SynchronizeMode::All). so we remove this call and instead
20
do catchup sync in the main Enter() loop.
21
*/
22
//if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu();
23
#endif
24
}
25
26
void SMP::cycle_edge() {
27
timer0.tick();
28
timer1.tick();
29
timer2.tick();
30
31
//TEST register S-SMP speed control
32
//24 clocks have already been added for this cycle at this point
33
switch(status.clock_speed) {
34
case 0: break; //100% speed
35
case 1: add_clocks(24); break; // 50% speed
36
case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP
37
case 3: add_clocks(24 * 9); break; // 10% speed
38
}
39
}
40
41
template<unsigned timer_frequency>
42
void SMP::Timer<timer_frequency>::tick() {
43
//stage 0 increment
44
stage0_ticks += smp.status.timer_step;
45
if(stage0_ticks < timer_frequency) return;
46
stage0_ticks -= timer_frequency;
47
48
//stage 1 increment
49
stage1_ticks ^= 1;
50
synchronize_stage1();
51
}
52
53
template<unsigned timer_frequency>
54
void SMP::Timer<timer_frequency>::synchronize_stage1() {
55
bool new_line = stage1_ticks;
56
if(smp.status.timers_enable == false) new_line = false;
57
if(smp.status.timers_disable == true) new_line = false;
58
59
bool old_line = current_line;
60
current_line = new_line;
61
if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition
62
63
//stage 2 increment
64
if(enable == false) return;
65
if(++stage2_ticks != target) return;
66
67
//stage 3 increment
68
stage2_ticks = 0;
69
stage3_ticks++;
70
}
71
72
#endif
73
74