Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/system/system.cpp
2 views
1
#include <snes/snes.hpp>
2
3
#define SYSTEM_CPP
4
namespace SNES {
5
6
System system;
7
8
#include <snes/config/config.cpp>
9
#include <snes/scheduler/scheduler.cpp>
10
#include <snes/random/random.cpp>
11
12
#include "video.cpp"
13
#include "audio.cpp"
14
#include "input.cpp"
15
#include "serialization.cpp"
16
17
void System::run() {
18
scheduler.sync = Scheduler::SynchronizeMode::None;
19
20
scheduler.enter();
21
if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) {
22
video.update();
23
}
24
}
25
26
void System::runtosave() {
27
if(CPU::Threaded == true) {
28
scheduler.sync = Scheduler::SynchronizeMode::CPU;
29
runthreadtosave();
30
}
31
32
if(SMP::Threaded == true) {
33
scheduler.thread = smp.thread;
34
runthreadtosave();
35
}
36
37
if(PPU::Threaded == true) {
38
scheduler.thread = ppu.thread;
39
runthreadtosave();
40
}
41
42
if(DSP::Threaded == true) {
43
scheduler.thread = dsp.thread;
44
runthreadtosave();
45
}
46
47
for(unsigned i = 0; i < cpu.coprocessors.size(); i++) {
48
Processor &chip = *cpu.coprocessors[i];
49
scheduler.thread = chip.thread;
50
runthreadtosave();
51
}
52
}
53
54
void System::runthreadtosave() {
55
while(true) {
56
scheduler.enter();
57
if(scheduler.exit_reason() == Scheduler::ExitReason::SynchronizeEvent) break;
58
if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) {
59
video.update();
60
}
61
}
62
}
63
64
void System::init() {
65
assert(interface != 0);
66
67
#if defined(GAMEBOY)
68
icd2.init();
69
#endif
70
nss.init();
71
superfx.init();
72
sa1.init();
73
necdsp.init();
74
hitachidsp.init();
75
armdsp.init();
76
bsxsatellaview.init();
77
bsxcartridge.init();
78
bsxflash.init();
79
srtc.init();
80
sdd1.init();
81
spc7110.init();
82
obc1.init();
83
msu1.init();
84
link.init();
85
86
video.init();
87
audio.init();
88
89
input.connect(0, config.controller_port1);
90
input.connect(1, config.controller_port2);
91
}
92
93
void System::term() {
94
}
95
96
void System::load() {
97
audio.coprocessor_enable(false);
98
99
bus.map_reset();
100
bus.map_xml();
101
102
cpu.enable();
103
ppu.enable();
104
105
if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.load();
106
if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.load();
107
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.load();
108
#if defined(GAMEBOY)
109
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.load();
110
#endif
111
112
if(cartridge.has_bsx_slot()) bsxflash.load();
113
if(cartridge.has_nss_dip()) nss.load();
114
if(cartridge.has_superfx()) superfx.load();
115
if(cartridge.has_sa1()) sa1.load();
116
if(cartridge.has_necdsp()) necdsp.load();
117
if(cartridge.has_hitachidsp()) hitachidsp.load();
118
if(cartridge.has_armdsp()) armdsp.load();
119
if(cartridge.has_srtc()) srtc.load();
120
if(cartridge.has_sdd1()) sdd1.load();
121
if(cartridge.has_spc7110()) spc7110.load();
122
if(cartridge.has_obc1()) obc1.load();
123
if(cartridge.has_msu1()) msu1.load();
124
if(cartridge.has_link()) link.load();
125
126
serialize_init();
127
cheat.init();
128
}
129
130
void System::unload() {
131
if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.unload();
132
if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.unload();
133
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.unload();
134
#if defined(GAMEBOY)
135
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.unload();
136
#endif
137
138
if(cartridge.has_bsx_slot()) bsxflash.unload();
139
if(cartridge.has_nss_dip()) nss.unload();
140
if(cartridge.has_superfx()) superfx.unload();
141
if(cartridge.has_sa1()) sa1.unload();
142
if(cartridge.has_necdsp()) necdsp.unload();
143
if(cartridge.has_hitachidsp()) hitachidsp.unload();
144
if(cartridge.has_armdsp()) armdsp.unload();
145
if(cartridge.has_srtc()) srtc.unload();
146
if(cartridge.has_sdd1()) sdd1.unload();
147
if(cartridge.has_spc7110()) spc7110.unload();
148
if(cartridge.has_obc1()) obc1.unload();
149
if(cartridge.has_msu1()) msu1.unload();
150
if(cartridge.has_link()) link.unload();
151
}
152
153
void System::power() {
154
random.seed((unsigned)interface()->randomSeed());
155
156
region = config.region;
157
expansion = config.expansion_port;
158
if(region.value == Region::Autodetect) {
159
region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL);
160
}
161
162
cpu_frequency = region() == Region::NTSC ? config.cpu.ntsc_frequency : config.cpu.pal_frequency;
163
apu_frequency = region() == Region::NTSC ? config.smp.ntsc_frequency : config.smp.pal_frequency;
164
165
cpu.power();
166
smp.power();
167
dsp.power();
168
ppu.power();
169
170
if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.power();
171
if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.power();
172
#if defined(GAMEBOY)
173
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.power();
174
#endif
175
176
if(cartridge.has_bsx_slot()) bsxflash.power();
177
if(cartridge.has_nss_dip()) nss.power();
178
if(cartridge.has_superfx()) superfx.power();
179
if(cartridge.has_sa1()) sa1.power();
180
if(cartridge.has_necdsp()) necdsp.power();
181
if(cartridge.has_hitachidsp()) hitachidsp.power();
182
if(cartridge.has_armdsp()) armdsp.power();
183
if(cartridge.has_srtc()) srtc.power();
184
if(cartridge.has_sdd1()) sdd1.power();
185
if(cartridge.has_spc7110()) spc7110.power();
186
if(cartridge.has_obc1()) obc1.power();
187
if(cartridge.has_msu1()) msu1.power();
188
if(cartridge.has_link()) link.power();
189
190
reset();
191
}
192
193
void System::reset() {
194
cpu.reset();
195
smp.reset();
196
dsp.reset();
197
ppu.reset();
198
199
if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.reset();
200
201
if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.reset();
202
#if defined(GAMEBOY)
203
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.reset();
204
#endif
205
206
if(cartridge.has_bsx_slot()) bsxflash.reset();
207
if(cartridge.has_nss_dip()) nss.reset();
208
if(cartridge.has_superfx()) superfx.reset();
209
if(cartridge.has_sa1()) sa1.reset();
210
if(cartridge.has_necdsp()) necdsp.reset();
211
if(cartridge.has_hitachidsp()) hitachidsp.reset();
212
if(cartridge.has_armdsp()) armdsp.reset();
213
if(cartridge.has_srtc()) srtc.reset();
214
if(cartridge.has_sdd1()) sdd1.reset();
215
if(cartridge.has_spc7110()) spc7110.reset();
216
if(cartridge.has_obc1()) obc1.reset();
217
if(cartridge.has_msu1()) msu1.reset();
218
if(cartridge.has_link()) link.reset();
219
220
#if defined(GAMEBOY)
221
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&icd2);
222
#endif
223
if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);
224
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
225
if(cartridge.has_necdsp()) cpu.coprocessors.append(&necdsp);
226
if(cartridge.has_hitachidsp()) cpu.coprocessors.append(&hitachidsp);
227
if(cartridge.has_armdsp()) cpu.coprocessors.append(&armdsp);
228
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
229
if(cartridge.has_link()) cpu.coprocessors.append(&link);
230
231
scheduler.init();
232
input.connect(0, config.controller_port1);
233
input.connect(1, config.controller_port2);
234
}
235
236
void System::scanline() {
237
video.scanline();
238
/*
239
* the idea is to have the frame boundary (for framestep tasing) come as soon as possible
240
* after the end of a visible frame, so it comes before the input poll.
241
* the old number was constant 241, which is at a very odd time for NTSC.
242
* the new numbers are the minimum possible to still capture a full frame; any lower,
243
* and the last scanline(s) of the frame are still from the old frame.
244
*/
245
int stopline;
246
if (ppu.overscan()) // (region != Region::NTSC)
247
stopline = 240;
248
else
249
stopline = 225;
250
if(cpu.vcounter() == stopline) scheduler.exit(Scheduler::ExitReason::FrameEvent);
251
}
252
253
void System::frame() {
254
}
255
256
System::System() {
257
region = Region::Autodetect;
258
expansion = ExpansionPortDevice::BSX;
259
}
260
261
}
262
263
264
//zero 04-sep-2012
265
extern "C" void snes_set_layer_enable(int layer, int priority, bool enable)
266
{
267
SNES::ppu.layer_enable(layer, priority, enable);
268
}
269
270