Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/dsp/dsp.cpp
2 views
1
#include <snes/snes.hpp>
2
3
#define DSP_CPP
4
namespace SNES {
5
6
DSP dsp;
7
8
#define REG(n) state.regs[r_##n]
9
#define VREG(n) state.regs[v.vidx + v_##n]
10
11
#include "serialization.cpp"
12
#include "gaussian.cpp"
13
#include "counter.cpp"
14
#include "envelope.cpp"
15
#include "brr.cpp"
16
#include "misc.cpp"
17
#include "voice.cpp"
18
#include "echo.cpp"
19
20
/* timing */
21
22
void DSP::step(unsigned clocks) {
23
clock += clocks;
24
}
25
26
void DSP::synchronize_smp() {
27
if(SMP::Threaded == true) {
28
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread);
29
} else {
30
while(clock >= 0) smp.enter();
31
}
32
}
33
34
void DSP::Enter() { dsp.enter(); }
35
36
void DSP::enter() {
37
while(true) {
38
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
39
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
40
}
41
42
voice_5(voice[0]);
43
voice_2(voice[1]);
44
tick();
45
46
voice_6(voice[0]);
47
voice_3(voice[1]);
48
tick();
49
50
voice_7(voice[0]);
51
voice_4(voice[1]);
52
voice_1(voice[3]);
53
tick();
54
55
voice_8(voice[0]);
56
voice_5(voice[1]);
57
voice_2(voice[2]);
58
tick();
59
60
voice_9(voice[0]);
61
voice_6(voice[1]);
62
voice_3(voice[2]);
63
tick();
64
65
voice_7(voice[1]);
66
voice_4(voice[2]);
67
voice_1(voice[4]);
68
tick();
69
70
voice_8(voice[1]);
71
voice_5(voice[2]);
72
voice_2(voice[3]);
73
tick();
74
75
voice_9(voice[1]);
76
voice_6(voice[2]);
77
voice_3(voice[3]);
78
tick();
79
80
voice_7(voice[2]);
81
voice_4(voice[3]);
82
voice_1(voice[5]);
83
tick();
84
85
voice_8(voice[2]);
86
voice_5(voice[3]);
87
voice_2(voice[4]);
88
tick();
89
90
voice_9(voice[2]);
91
voice_6(voice[3]);
92
voice_3(voice[4]);
93
tick();
94
95
voice_7(voice[3]);
96
voice_4(voice[4]);
97
voice_1(voice[6]);
98
tick();
99
100
voice_8(voice[3]);
101
voice_5(voice[4]);
102
voice_2(voice[5]);
103
tick();
104
105
voice_9(voice[3]);
106
voice_6(voice[4]);
107
voice_3(voice[5]);
108
tick();
109
110
voice_7(voice[4]);
111
voice_4(voice[5]);
112
voice_1(voice[7]);
113
tick();
114
115
voice_8(voice[4]);
116
voice_5(voice[5]);
117
voice_2(voice[6]);
118
tick();
119
120
voice_9(voice[4]);
121
voice_6(voice[5]);
122
voice_3(voice[6]);
123
tick();
124
125
voice_1(voice[0]);
126
voice_7(voice[5]);
127
voice_4(voice[6]);
128
tick();
129
130
voice_8(voice[5]);
131
voice_5(voice[6]);
132
voice_2(voice[7]);
133
tick();
134
135
voice_9(voice[5]);
136
voice_6(voice[6]);
137
voice_3(voice[7]);
138
tick();
139
140
voice_1(voice[1]);
141
voice_7(voice[6]);
142
voice_4(voice[7]);
143
tick();
144
145
voice_8(voice[6]);
146
voice_5(voice[7]);
147
voice_2(voice[0]);
148
tick();
149
150
voice_3a(voice[0]);
151
voice_9(voice[6]);
152
voice_6(voice[7]);
153
echo_22();
154
tick();
155
156
voice_7(voice[7]);
157
echo_23();
158
tick();
159
160
voice_8(voice[7]);
161
echo_24();
162
tick();
163
164
voice_3b(voice[0]);
165
voice_9(voice[7]);
166
echo_25();
167
tick();
168
169
echo_26();
170
tick();
171
172
misc_27();
173
echo_27();
174
tick();
175
176
misc_28();
177
echo_28();
178
tick();
179
180
misc_29();
181
echo_29();
182
tick();
183
184
misc_30();
185
voice_3c(voice[0]);
186
echo_30();
187
tick();
188
189
voice_4(voice[0]);
190
voice_1(voice[2]);
191
tick();
192
}
193
}
194
195
void DSP::tick() {
196
step(3 * 8);
197
synchronize_smp();
198
}
199
200
/* register interface for S-SMP $00f2,$00f3 */
201
202
uint8 DSP::read(uint8 addr) {
203
return state.regs[addr];
204
}
205
206
void DSP::write(uint8 addr, uint8 data) {
207
state.regs[addr] = data;
208
209
if((addr & 0x0f) == v_envx) {
210
state.envx_buf = data;
211
} else if((addr & 0x0f) == v_outx) {
212
state.outx_buf = data;
213
} else if(addr == r_kon) {
214
state.new_kon = data;
215
} else if(addr == r_endx) {
216
//always cleared, regardless of data written
217
state.endx_buf = 0;
218
state.regs[r_endx] = 0;
219
}
220
}
221
222
/* initialization */
223
224
void DSP::power() {
225
memset(&state.regs, 0, sizeof state.regs);
226
227
//zero 01-dec-2012 - gotta reset these sometime, somewhere
228
//zero 17-may-2014 - WHAT?
229
//state.echo_hist[0] = state.echo_hist[1] = 0;
230
231
state.echo_hist_pos = 0;
232
state.every_other_sample = false;
233
state.kon = 0;
234
state.noise = 0;
235
state.counter = 0;
236
state.echo_offset = 0;
237
state.echo_length = 0;
238
state.new_kon = 0;
239
state.endx_buf = 0;
240
state.envx_buf = 0;
241
state.outx_buf = 0;
242
state.t_pmon = 0;
243
state.t_non = 0;
244
state.t_eon = 0;
245
state.t_dir = 0;
246
state.t_koff = 0;
247
state.t_brr_next_addr = 0;
248
state.t_adsr0 = 0;
249
state.t_brr_header = 0;
250
state.t_brr_byte = 0;
251
state.t_srcn = 0;
252
state.t_esa = 0;
253
state.t_echo_disabled = 0;
254
state.t_dir_addr = 0;
255
state.t_pitch = 0;
256
state.t_output = 0;
257
state.t_looped = 0;
258
state.t_echo_ptr = 0;
259
state.t_main_out[0] = state.t_main_out[1] = 0;
260
state.t_echo_out[0] = state.t_echo_out[1] = 0;
261
state.t_echo_in[0] = state.t_echo_in[1] = 0;
262
263
for(unsigned i = 0; i < 8; i++) {
264
voice[i].buf_pos = 0;
265
voice[i].interp_pos = 0;
266
voice[i].brr_addr = 0;
267
voice[i].brr_offset = 1;
268
voice[i].vbit = 1 << i;
269
voice[i].vidx = i * 0x10;
270
voice[i].kon_delay = 0;
271
voice[i].env_mode = env_release;
272
voice[i].env = 0;
273
voice[i].t_envx_out = 0;
274
voice[i].hidden_env = 0;
275
}
276
}
277
278
void DSP::reset() {
279
create(Enter, system.apu_frequency());
280
281
REG(flg) = 0xe0;
282
283
state.noise = 0x4000;
284
state.echo_hist_pos = 0;
285
state.every_other_sample = 1;
286
state.echo_offset = 0;
287
state.counter = 0;
288
}
289
290
DSP::DSP() {
291
static_assert(sizeof(int) >= 32 / 8, "int >= 32-bits");
292
static_assert((int8)0x80 == -0x80, "8-bit sign extension");
293
static_assert((int16)0x8000 == -0x8000, "16-bit sign extension");
294
static_assert((uint16)0xffff0000 == 0, "16-bit unsigned clip");
295
static_assert((-1 >> 1) == -1, "arithmetic shift right");
296
297
//-0x8000 <= n <= +0x7fff
298
assert(sclamp<16>(+0x8000) == +0x7fff);
299
assert(sclamp<16>(-0x8001) == -0x8000);
300
}
301
302
DSP::~DSP() {
303
}
304
305
#undef REG
306
#undef VREG
307
308
}
309
310