Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/smp/smp.cpp
2 views
1
#include <snes/snes.hpp>
2
3
#define SMP_CPP
4
namespace SNES {
5
6
SMP smp;
7
8
#include "serialization.cpp"
9
#include "iplrom.cpp"
10
#include "memory/memory.cpp"
11
#include "timing/timing.cpp"
12
13
void SMP::step(unsigned clocks) {
14
clock += clocks * (uint64)cpu.frequency;
15
dsp.clock -= clocks;
16
}
17
18
void SMP::synchronize_cpu() {
19
if(CPU::Threaded == true) {
20
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
21
} else {
22
while(clock >= 0) cpu.enter();
23
}
24
}
25
26
void SMP::synchronize_cpu_force() {
27
if(CPU::Threaded == true) {
28
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All)
29
co_switch(cpu.thread);
30
else if(clock >= 0 && scheduler.sync == Scheduler::SynchronizeMode::All)
31
interface()->message("SMP had to advance nondeterministically!");
32
} else {
33
while(clock >= 0) cpu.enter();
34
}
35
}
36
37
void SMP::synchronize_dsp() {
38
if(DSP::Threaded == true) {
39
if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread);
40
} else {
41
while(dsp.clock < 0) dsp.enter();
42
}
43
}
44
45
void SMP::Enter() { smp.enter(); }
46
47
void SMP::enter() {
48
while(true) {
49
// see comment in timing.cpp
50
if(clock > +(768 * 24 * (int64)24000000))
51
synchronize_cpu();
52
53
if(scheduler.sync == Scheduler::SynchronizeMode::CPU) {
54
synchronize_cpu(); // when in CPU sync mode, always switch back to CPU as soon as possible
55
}
56
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
57
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
58
}
59
60
debugger.op_exec(regs.pc);
61
op_step();
62
}
63
}
64
65
void SMP::power() {
66
//targets not initialized/changed upon reset
67
timer0.target = 0;
68
timer1.target = 0;
69
timer2.target = 0;
70
71
//zero 01-dec-2012
72
//gotta clear these to something, sometime
73
dp.w = sp.w = rd.w = wr.w = bit.w = ya.w = 0;
74
}
75
76
void SMP::reset() {
77
create(Enter, system.apu_frequency());
78
79
regs.pc = 0xffc0;
80
// exact value doesn't matter much, so long as "fetch" is next
81
opcode = 0; // NOP
82
uindex = 1; // fetch phase
83
84
regs.a = 0x00;
85
regs.x = 0x00;
86
regs.y = 0x00;
87
regs.s = 0xef;
88
regs.p = 0x02;
89
90
for(int i=0;i<64*1024;i++) apuram[i] = random(0x00);
91
apuram[0x00f4] = 0x00;
92
apuram[0x00f5] = 0x00;
93
apuram[0x00f6] = 0x00;
94
apuram[0x00f7] = 0x00;
95
96
status.clock_counter = 0;
97
status.dsp_counter = 0;
98
status.timer_step = 3;
99
100
//$00f0
101
status.clock_speed = 0;
102
status.timer_speed = 0;
103
status.timers_enable = true;
104
status.ram_disable = false;
105
status.ram_writable = true;
106
status.timers_disable = false;
107
108
//$00f1
109
status.iplrom_enable = true;
110
111
//$00f2
112
status.dsp_addr = 0x00;
113
114
//$00f8,$00f9
115
status.ram00f8 = 0x00;
116
status.ram00f9 = 0x00;
117
118
timer0.stage0_ticks = 0;
119
timer1.stage0_ticks = 0;
120
timer2.stage0_ticks = 0;
121
122
timer0.stage1_ticks = 0;
123
timer1.stage1_ticks = 0;
124
timer2.stage1_ticks = 0;
125
126
timer0.stage2_ticks = 0;
127
timer1.stage2_ticks = 0;
128
timer2.stage2_ticks = 0;
129
130
timer0.stage3_ticks = 0;
131
timer1.stage3_ticks = 0;
132
timer2.stage3_ticks = 0;
133
134
timer0.current_line = 0;
135
timer1.current_line = 0;
136
timer2.current_line = 0;
137
138
timer0.enable = false;
139
timer1.enable = false;
140
timer2.enable = false;
141
}
142
143
SMP::SMP()
144
: apuram(nullptr)
145
{
146
}
147
148
SMP::~SMP() {
149
interface()->freeSharedMemory(apuram);
150
}
151
152
void SMP::initialize()
153
{
154
apuram = (uint8*)interface()->allocSharedMemory("APURAM",64 * 1024);
155
}
156
157
}
158
159