1 #include "driver.h"
2
3
4 /***************************************************************************
5
6 Many games use a master-slave CPU setup. Typically, the main CPU writes
7 a command to some register, and then writes to another register to trigger
8 an interrupt on the slave CPU (the interrupt might also be triggered by
9 the first write). The slave CPU, notified by the interrupt, goes and reads
10 the command.
11
12 ***************************************************************************/
13
14 static int cleared_value = 0x00;
15
16 static int latch;
17 /*static int read_debug;*/
18
19
soundlatch_callback(int param)20 static void soundlatch_callback(int param)
21 {
22 #if 0
23 if (read_debug == 0 && latch != param)
24 log_cb(RETRO_LOG_ERROR, LOGPRE "Warning: sound latch written before being read. Previous: %02x, new: %02x\n",latch,param);
25 #endif
26 latch = param;
27 /*read_debug = 0;*/
28 }
29
WRITE_HANDLER(soundlatch_w)30 WRITE_HANDLER( soundlatch_w )
31 {
32 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
33 timer_set(TIME_NOW,data,soundlatch_callback);
34 }
35
WRITE16_HANDLER(soundlatch_word_w)36 WRITE16_HANDLER( soundlatch_word_w )
37 {
38 static data16_t word;
39 COMBINE_DATA(&word);
40
41 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
42 timer_set(TIME_NOW,word,soundlatch_callback);
43 }
44
READ_HANDLER(soundlatch_r)45 READ_HANDLER( soundlatch_r )
46 {
47 /*read_debug = 1;*/
48 return latch;
49 }
50
READ16_HANDLER(soundlatch_word_r)51 READ16_HANDLER( soundlatch_word_r )
52 {
53 /*read_debug = 1;*/
54 return latch;
55 }
56
WRITE_HANDLER(soundlatch_clear_w)57 WRITE_HANDLER( soundlatch_clear_w )
58 {
59 latch = cleared_value;
60 }
61
62
63 static int latch2;
64 /*static int read_debug2;*/
65
soundlatch2_callback(int param)66 static void soundlatch2_callback(int param)
67 {
68 #if 0
69 if (read_debug2 == 0 && latch2 != param)
70 log_cb(RETRO_LOG_ERROR, LOGPRE "Warning: sound latch 2 written before being read. Previous: %02x, new: %02x\n",latch2,param);
71 #endif
72 latch2 = param;
73 /*read_debug2 = 0;*/
74 }
75
WRITE_HANDLER(soundlatch2_w)76 WRITE_HANDLER( soundlatch2_w )
77 {
78 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
79 timer_set(TIME_NOW,data,soundlatch2_callback);
80 }
81
WRITE16_HANDLER(soundlatch2_word_w)82 WRITE16_HANDLER( soundlatch2_word_w )
83 {
84 static data16_t word;
85 COMBINE_DATA(&word);
86
87 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
88 timer_set(TIME_NOW,word,soundlatch2_callback);
89 }
90
READ_HANDLER(soundlatch2_r)91 READ_HANDLER( soundlatch2_r )
92 {
93 /*read_debug2 = 1;*/
94 return latch2;
95 }
96
READ16_HANDLER(soundlatch2_word_r)97 READ16_HANDLER( soundlatch2_word_r )
98 {
99 /*read_debug2 = 1;*/
100 return latch2;
101 }
102
WRITE_HANDLER(soundlatch2_clear_w)103 WRITE_HANDLER( soundlatch2_clear_w )
104 {
105 latch2 = cleared_value;
106 }
107
108
109 static int latch3;
110 /*static int read_debug3;*/
111
soundlatch3_callback(int param)112 static void soundlatch3_callback(int param)
113 {
114 #if 0
115 if (read_debug3 == 0 && latch3 != param)
116 log_cb(RETRO_LOG_ERROR, LOGPRE "Warning: sound latch 3 written before being read. Previous: %02x, new: %02x\n",latch3,param);
117 #endif
118 latch3 = param;
119 /*read_debug3 = 0;*/
120 }
121
WRITE_HANDLER(soundlatch3_w)122 WRITE_HANDLER( soundlatch3_w )
123 {
124 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
125 timer_set(TIME_NOW,data,soundlatch3_callback);
126 }
127
WRITE16_HANDLER(soundlatch3_word_w)128 WRITE16_HANDLER( soundlatch3_word_w )
129 {
130 static data16_t word;
131 COMBINE_DATA(&word);
132
133 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
134 timer_set(TIME_NOW,word,soundlatch3_callback);
135 }
136
READ_HANDLER(soundlatch3_r)137 READ_HANDLER( soundlatch3_r )
138 {
139 /*read_debug3 = 1;*/
140 return latch3;
141 }
142
READ16_HANDLER(soundlatch3_word_r)143 READ16_HANDLER( soundlatch3_word_r )
144 {
145 /*read_debug3 = 1;*/
146 return latch3;
147 }
148
WRITE_HANDLER(soundlatch3_clear_w)149 WRITE_HANDLER( soundlatch3_clear_w )
150 {
151 latch3 = cleared_value;
152 }
153
154
155 static int latch4;
156 /*static int read_debug4;*/
157
soundlatch4_callback(int param)158 static void soundlatch4_callback(int param)
159 {
160 #if 0
161 if (read_debug4 == 0 && latch4 != param)
162 log_cb(RETRO_LOG_ERROR, LOGPRE "Warning: sound latch 4 written before being read. Previous: %02x, new: %02x\n",latch2,param);
163 #endif
164 latch4 = param;
165 /*read_debug4 = 0;*/
166 }
167
WRITE_HANDLER(soundlatch4_w)168 WRITE_HANDLER( soundlatch4_w )
169 {
170 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
171 timer_set(TIME_NOW,data,soundlatch4_callback);
172 }
173
WRITE16_HANDLER(soundlatch4_word_w)174 WRITE16_HANDLER( soundlatch4_word_w )
175 {
176 static data16_t word;
177 COMBINE_DATA(&word);
178
179 /* make all the CPUs synchronize, and only AFTER that write the new command to the latch */
180 timer_set(TIME_NOW,word,soundlatch4_callback);
181 }
182
READ_HANDLER(soundlatch4_r)183 READ_HANDLER( soundlatch4_r )
184 {
185 /*read_debug4 = 1;*/
186 return latch4;
187 }
188
READ16_HANDLER(soundlatch4_word_r)189 READ16_HANDLER( soundlatch4_word_r )
190 {
191 /*read_debug4 = 1;*/
192 return latch4;
193 }
194
WRITE_HANDLER(soundlatch4_clear_w)195 WRITE_HANDLER( soundlatch4_clear_w )
196 {
197 latch4 = cleared_value;
198 }
199
200
soundlatch_setclearedvalue(int value)201 void soundlatch_setclearedvalue(int value)
202 {
203 cleared_value = value;
204 }
205
206
207
208
209
210 /***************************************************************************
211
212
213
214 ***************************************************************************/
215
216 static void *sound_update_timer;
217 static double refresh_period;
218 static double refresh_period_inv;
219
220
221 struct snd_interface
222 {
223 unsigned sound_num; /* ID */
224 const char *name; /* description */
225 int (*chips_num)(const struct MachineSound *msound); /* returns number of chips if applicable */
226 int (*chips_clock)(const struct MachineSound *msound); /* returns chips clock if applicable */
227 int (*start)(const struct MachineSound *msound); /* starts sound emulation */
228 void (*stop)(void); /* stops sound emulation */
229 void (*update)(void); /* updates emulation once per frame if necessary */
230 void (*reset)(void); /* resets sound emulation */
231 };
232
233
234 #if (HAS_CUSTOM)
235 static const struct CustomSound_interface *cust_intf;
236
custom_sh_start(const struct MachineSound * msound)237 int custom_sh_start(const struct MachineSound *msound)
238 {
239 cust_intf = msound->sound_interface;
240
241 if (cust_intf->sh_start)
242 return (*cust_intf->sh_start)(msound);
243 else return 0;
244 }
custom_sh_stop(void)245 void custom_sh_stop(void)
246 {
247 if (cust_intf->sh_stop) (*cust_intf->sh_stop)();
248 }
custom_sh_update(void)249 void custom_sh_update(void)
250 {
251 if (cust_intf->sh_update) (*cust_intf->sh_update)();
252 }
253 #endif
254 #if (HAS_DAC)
DAC_num(const struct MachineSound * msound)255 int DAC_num(const struct MachineSound *msound) { return ((struct DACinterface*)msound->sound_interface)->num; }
256 #endif
257 #if (HAS_ADPCM)
ADPCM_num(const struct MachineSound * msound)258 int ADPCM_num(const struct MachineSound *msound) { return ((struct ADPCMinterface*)msound->sound_interface)->num; }
259 #endif
260 #if (HAS_OKIM6295)
OKIM6295_num(const struct MachineSound * msound)261 int OKIM6295_num(const struct MachineSound *msound) { return ((struct OKIM6295interface*)msound->sound_interface)->num; }
OKIM6295_clock(const struct MachineSound * msound)262 int OKIM6295_clock(const struct MachineSound *msound) { return ((struct OKIM6295interface*)msound->sound_interface)->frequency[0]; }
263 #endif
264 #if (HAS_MSM5205)
MSM5205_num(const struct MachineSound * msound)265 int MSM5205_num(const struct MachineSound *msound) { return ((struct MSM5205interface*)msound->sound_interface)->num; }
266 #endif
267 #if (HAS_MSM5232)
MSM5232_num(const struct MachineSound * msound)268 int MSM5232_num(const struct MachineSound *msound) { return ((struct MSM5232interface*)msound->sound_interface)->num; }
269 #endif
270 #if (HAS_HC55516)
HC55516_num(const struct MachineSound * msound)271 int HC55516_num(const struct MachineSound *msound) { return ((struct hc55516_interface*)msound->sound_interface)->num; }
272 #endif
273 #if (HAS_K007232)
K007232_clock(const struct MachineSound * msound)274 int K007232_clock(const struct MachineSound *msound) { return ((struct K007232_interface*)msound->sound_interface)->baseclock; }
K007232_num(const struct MachineSound * msound)275 int K007232_num(const struct MachineSound *msound) { return ((struct K007232_interface*)msound->sound_interface)->num_chips; }
276 #endif
277 #if (HAS_AY8910)
AY8910_clock(const struct MachineSound * msound)278 int AY8910_clock(const struct MachineSound *msound) { return ((struct AY8910interface*)msound->sound_interface)->baseclock; }
AY8910_num(const struct MachineSound * msound)279 int AY8910_num(const struct MachineSound *msound) { return ((struct AY8910interface*)msound->sound_interface)->num; }
280 #endif
281 #if (HAS_YM2203)
YM2203_clock(const struct MachineSound * msound)282 int YM2203_clock(const struct MachineSound *msound) { return ((struct YM2203interface*)msound->sound_interface)->baseclock; }
YM2203_num(const struct MachineSound * msound)283 int YM2203_num(const struct MachineSound *msound) { return ((struct YM2203interface*)msound->sound_interface)->num; }
284 #endif
285 #if (HAS_YM2413)
YM2413_clock(const struct MachineSound * msound)286 int YM2413_clock(const struct MachineSound *msound) { return ((struct YM2413interface*)msound->sound_interface)->baseclock; }
YM2413_num(const struct MachineSound * msound)287 int YM2413_num(const struct MachineSound *msound) { return ((struct YM2413interface*)msound->sound_interface)->num; }
288 #endif
289 #if (HAS_YM2608)
YM2608_clock(const struct MachineSound * msound)290 int YM2608_clock(const struct MachineSound *msound) { return ((struct YM2608interface*)msound->sound_interface)->baseclock; }
YM2608_num(const struct MachineSound * msound)291 int YM2608_num(const struct MachineSound *msound) { return ((struct YM2608interface*)msound->sound_interface)->num; }
292 #endif
293 #if (HAS_YM2610)
YM2610_clock(const struct MachineSound * msound)294 int YM2610_clock(const struct MachineSound *msound) { return ((struct YM2610interface*)msound->sound_interface)->baseclock; }
YM2610_num(const struct MachineSound * msound)295 int YM2610_num(const struct MachineSound *msound) { return ((struct YM2610interface*)msound->sound_interface)->num; }
296 #endif
297 #if (HAS_YM2612 || HAS_YM3438)
YM2612_clock(const struct MachineSound * msound)298 int YM2612_clock(const struct MachineSound *msound) { return ((struct YM2612interface*)msound->sound_interface)->baseclock; }
YM2612_num(const struct MachineSound * msound)299 int YM2612_num(const struct MachineSound *msound) { return ((struct YM2612interface*)msound->sound_interface)->num; }
300 #endif
301 #if (HAS_POKEY)
POKEY_clock(const struct MachineSound * msound)302 int POKEY_clock(const struct MachineSound *msound) { return ((struct POKEYinterface*)msound->sound_interface)->baseclock; }
POKEY_num(const struct MachineSound * msound)303 int POKEY_num(const struct MachineSound *msound) { return ((struct POKEYinterface*)msound->sound_interface)->num; }
304 #endif
305 #if (HAS_YM3812)
YM3812_clock(const struct MachineSound * msound)306 int YM3812_clock(const struct MachineSound *msound) { return ((struct YM3812interface*)msound->sound_interface)->baseclock; }
YM3812_num(const struct MachineSound * msound)307 int YM3812_num(const struct MachineSound *msound) { return ((struct YM3812interface*)msound->sound_interface)->num; }
308 #endif
309 #if (HAS_YM3526)
YM3526_clock(const struct MachineSound * msound)310 int YM3526_clock(const struct MachineSound *msound) { return ((struct YM3526interface*)msound->sound_interface)->baseclock; }
YM3526_num(const struct MachineSound * msound)311 int YM3526_num(const struct MachineSound *msound) { return ((struct YM3526interface*)msound->sound_interface)->num; }
312 #endif
313 #if (HAS_Y8950)
Y8950_clock(const struct MachineSound * msound)314 int Y8950_clock(const struct MachineSound *msound) { return ((struct Y8950interface*)msound->sound_interface)->baseclock; }
Y8950_num(const struct MachineSound * msound)315 int Y8950_num(const struct MachineSound *msound) { return ((struct Y8950interface*)msound->sound_interface)->num; }
316 #endif
317 #if (HAS_YMZ280B)
YMZ280B_clock(const struct MachineSound * msound)318 int YMZ280B_clock(const struct MachineSound *msound) { return ((struct YMZ280Binterface*)msound->sound_interface)->baseclock[0]; }
YMZ280B_num(const struct MachineSound * msound)319 int YMZ280B_num(const struct MachineSound *msound) { return ((struct YMZ280Binterface*)msound->sound_interface)->num; }
320 #endif
321 #if (HAS_VLM5030)
VLM5030_clock(const struct MachineSound * msound)322 int VLM5030_clock(const struct MachineSound *msound) { return ((struct VLM5030interface*)msound->sound_interface)->baseclock; }
323 #endif
324 #if (HAS_TMS36XX)
TMS36XX_num(const struct MachineSound * msound)325 int TMS36XX_num(const struct MachineSound *msound) { return ((struct TMS36XXinterface*)msound->sound_interface)->num; }
326 #endif
327 #if (HAS_TMS5110)
TMS5110_clock(const struct MachineSound * msound)328 int TMS5110_clock(const struct MachineSound *msound) { return ((struct TMS5110interface*)msound->sound_interface)->baseclock; }
329 #endif
330 #if (HAS_TMS5220)
TMS5220_clock(const struct MachineSound * msound)331 int TMS5220_clock(const struct MachineSound *msound) { return ((struct TMS5220interface*)msound->sound_interface)->baseclock; }
332 #endif
333 #if (HAS_YM2151 || HAS_YM2151_ALT)
YM2151_clock(const struct MachineSound * msound)334 int YM2151_clock(const struct MachineSound *msound) { return ((struct YM2151interface*)msound->sound_interface)->baseclock; }
YM2151_num(const struct MachineSound * msound)335 int YM2151_num(const struct MachineSound *msound) { return ((struct YM2151interface*)msound->sound_interface)->num; }
336 #endif
337 #if (HAS_NES)
NES_num(const struct MachineSound * msound)338 int NES_num(const struct MachineSound *msound) { return ((struct NESinterface*)msound->sound_interface)->num; }
339 #endif
340 #if (HAS_SN76477)
SN76477_num(const struct MachineSound * msound)341 int SN76477_num(const struct MachineSound *msound) { return ((struct SN76477interface*)msound->sound_interface)->num; }
342 #endif
343 #if (HAS_SN76496)
SN76496_clock(const struct MachineSound * msound)344 int SN76496_clock(const struct MachineSound *msound) { return ((struct SN76496interface*)msound->sound_interface)->baseclock[0]; }
SN76496_num(const struct MachineSound * msound)345 int SN76496_num(const struct MachineSound *msound) { return ((struct SN76496interface*)msound->sound_interface)->num; }
346 #endif
347 #if (HAS_MSM5205)
MSM5205_clock(const struct MachineSound * msound)348 int MSM5205_clock(const struct MachineSound *msound) { return ((struct MSM5205interface*)msound->sound_interface)->baseclock; }
349 #endif
350 #if (HAS_MSM5232)
MSM5232_clock(const struct MachineSound * msound)351 int MSM5232_clock(const struct MachineSound *msound) { return ((struct MSM5232interface*)msound->sound_interface)->baseclock; }
352 #endif
353 #if (HAS_ASTROCADE)
ASTROCADE_clock(const struct MachineSound * msound)354 int ASTROCADE_clock(const struct MachineSound *msound) { return ((struct astrocade_interface*)msound->sound_interface)->baseclock; }
ASTROCADE_num(const struct MachineSound * msound)355 int ASTROCADE_num(const struct MachineSound *msound) { return ((struct astrocade_interface*)msound->sound_interface)->num; }
356 #endif
357 #if (HAS_K051649)
K051649_clock(const struct MachineSound * msound)358 int K051649_clock(const struct MachineSound *msound) { return ((struct k051649_interface*)msound->sound_interface)->master_clock; }
359 #endif
360 #if (HAS_K053260)
K053260_clock(const struct MachineSound * msound)361 int K053260_clock(const struct MachineSound *msound) { return ((struct K053260_interface*)msound->sound_interface)->clock[0]; }
K053260_num(const struct MachineSound * msound)362 int K053260_num(const struct MachineSound *msound) { return ((struct K053260_interface*)msound->sound_interface)->num; }
363 #endif
364 #if (HAS_K054539)
K054539_clock(const struct MachineSound * msound)365 int K054539_clock(const struct MachineSound *msound) { return ((struct K054539interface*)msound->sound_interface)->clock; }
K054539_num(const struct MachineSound * msound)366 int K054539_num(const struct MachineSound *msound) { return ((struct K054539interface*)msound->sound_interface)->num; }
367 #endif
368 #if (HAS_CEM3394)
cem3394_num(const struct MachineSound * msound)369 int cem3394_num(const struct MachineSound *msound) { return ((struct cem3394_interface*)msound->sound_interface)->numchips; }
370 #endif
371 #if (HAS_QSOUND)
qsound_clock(const struct MachineSound * msound)372 int qsound_clock(const struct MachineSound *msound) { return ((struct QSound_interface*)msound->sound_interface)->clock; }
373 #endif
374 #if (HAS_SAA1099)
saa1099_num(const struct MachineSound * msound)375 int saa1099_num(const struct MachineSound *msound) { return ((struct SAA1099_interface*)msound->sound_interface)->numchips; }
376 #endif
377 #if (HAS_IREMGA20)
iremga20_clock(const struct MachineSound * msound)378 int iremga20_clock(const struct MachineSound *msound) { return ((struct IremGA20_interface*)msound->sound_interface)->clock; }
379 #endif
380 #if (HAS_ES5505)
ES5505_clock(const struct MachineSound * msound)381 int ES5505_clock(const struct MachineSound *msound) { return ((struct ES5505interface*)msound->sound_interface)->baseclock[0]; }
ES5505_num(const struct MachineSound * msound)382 int ES5505_num(const struct MachineSound *msound) { return ((struct ES5505interface*)msound->sound_interface)->num; }
383 #endif
384 #if (HAS_ES5506)
ES5506_clock(const struct MachineSound * msound)385 int ES5506_clock(const struct MachineSound *msound) { return ((struct ES5506interface*)msound->sound_interface)->baseclock[0]; }
ES5506_num(const struct MachineSound * msound)386 int ES5506_num(const struct MachineSound *msound) { return ((struct ES5506interface*)msound->sound_interface)->num; }
387 #endif
388 #if (HAS_BSMT2000)
BSMT2000_clock(const struct MachineSound * msound)389 int BSMT2000_clock(const struct MachineSound *msound) { return ((struct BSMT2000interface*)msound->sound_interface)->baseclock[0]; }
BSMT2000_num(const struct MachineSound * msound)390 int BSMT2000_num(const struct MachineSound *msound) { return ((struct BSMT2000interface*)msound->sound_interface)->num; }
391 #endif
392 #if (HAS_YMF262)
YMF262_clock(const struct MachineSound * msound)393 int YMF262_clock(const struct MachineSound *msound) { return ((struct YMF262interface*)msound->sound_interface)->baseclock; }
YMF262_num(const struct MachineSound * msound)394 int YMF262_num(const struct MachineSound *msound) { return ((struct YMF262interface*)msound->sound_interface)->num; }
395 #endif
396 #if (HAS_YMF278B)
YMF278B_clock(const struct MachineSound * msound)397 int YMF278B_clock(const struct MachineSound *msound) { return ((struct YMF278B_interface*)msound->sound_interface)->clock[0]; }
YMF278B_num(const struct MachineSound * msound)398 int YMF278B_num(const struct MachineSound *msound) { return ((struct YMF278B_interface*)msound->sound_interface)->num; }
399 #endif
400 #if (HAS_X1_010)
seta_clock(const struct MachineSound * msound)401 int seta_clock(const struct MachineSound *msound) { return ((struct x1_010_interface*)msound->sound_interface)->clock; }
402 #endif
403 #if (HAS_MULTIPCM)
MultiPCM_num(const struct MachineSound * msound)404 int MultiPCM_num(const struct MachineSound *msound) { return ((struct MultiPCM_interface*)msound->sound_interface)->chips; }
405 #endif
406 #if (HAS_C6280)
c6280_clock(const struct MachineSound * msound)407 int c6280_clock(const struct MachineSound *msound) { return ((struct C6280_interface*)msound->sound_interface)->clock[0]; }
c6280_num(const struct MachineSound * msound)408 int c6280_num(const struct MachineSound *msound) { return ((struct C6280_interface*)msound->sound_interface)->num; }
409 #endif
410 #if (HAS_TIA)
TIA_clock(const struct MachineSound * msound)411 int TIA_clock(const struct MachineSound *msound) { return ((struct TIAinterface*)msound->sound_interface)->baseclock; }
412 #endif
413
414 struct snd_interface sndintf[] =
415 {
416 {
417 SOUND_DUMMY,
418 "",
419 0,
420 0,
421 0,
422 0,
423 0,
424 0
425 },
426 #if (HAS_CUSTOM)
427 {
428 SOUND_CUSTOM,
429 "Custom",
430 0,
431 0,
432 custom_sh_start,
433 custom_sh_stop,
434 custom_sh_update,
435 0
436 },
437 #endif
438 #if (HAS_SAMPLES)
439 {
440 SOUND_SAMPLES,
441 "Samples",
442 0,
443 0,
444 samples_sh_start,
445 0,
446 0,
447 0
448 },
449 #endif
450 #if (HAS_DAC)
451 {
452 SOUND_DAC,
453 "DAC",
454 DAC_num,
455 0,
456 DAC_sh_start,
457 0,
458 0,
459 0
460 },
461 #endif
462 #if (HAS_DISCRETE)
463 {
464 SOUND_DISCRETE,
465 "Discrete Components",
466 0,
467 0,
468 discrete_sh_start,
469 discrete_sh_stop,
470 0,
471 discrete_sh_reset
472 },
473 #endif
474 #if (HAS_AY8910)
475 {
476 SOUND_AY8910,
477 "AY-3-8910",
478 AY8910_num,
479 AY8910_clock,
480 AY8910_sh_start,
481 AY8910_sh_stop,
482 0,
483 AY8910_sh_reset
484 },
485 #endif
486 #if (HAS_YM2203)
487 {
488 SOUND_YM2203,
489 "YM2203",
490 YM2203_num,
491 YM2203_clock,
492 YM2203_sh_start,
493 YM2203_sh_stop,
494 0,
495 YM2203_sh_reset
496 },
497 #endif
498 #if (HAS_YM2151 || HAS_YM2151_ALT)
499 {
500 SOUND_YM2151,
501 "YM2151",
502 YM2151_num,
503 YM2151_clock,
504 YM2151_sh_start,
505 YM2151_sh_stop,
506 0,
507 YM2151_sh_reset
508 },
509 #endif
510 #if (HAS_YM2608)
511 {
512 SOUND_YM2608,
513 "YM2608",
514 YM2608_num,
515 YM2608_clock,
516 YM2608_sh_start,
517 YM2608_sh_stop,
518 0,
519 YM2608_sh_reset
520 },
521 #endif
522 #if (HAS_YM2610)
523 {
524 SOUND_YM2610,
525 "YM2610",
526 YM2610_num,
527 YM2610_clock,
528 YM2610_sh_start,
529 YM2610_sh_stop,
530 0,
531 YM2610_sh_reset
532 },
533 #endif
534 #if (HAS_YM2610B)
535 {
536 SOUND_YM2610B,
537 "YM2610B",
538 YM2610_num,
539 YM2610_clock,
540 YM2610B_sh_start,
541 YM2610_sh_stop,
542 0,
543 YM2610_sh_reset
544 },
545 #endif
546 #if (HAS_YM2612)
547 {
548 SOUND_YM2612,
549 "YM2612",
550 YM2612_num,
551 YM2612_clock,
552 YM2612_sh_start,
553 YM2612_sh_stop,
554 0,
555 YM2612_sh_reset
556 },
557 #endif
558 #if (HAS_YM3438)
559 {
560 SOUND_YM3438,
561 "YM3438",
562 YM2612_num,
563 YM2612_clock,
564 YM2612_sh_start,
565 YM2612_sh_stop,
566 0,
567 YM2612_sh_reset
568 },
569 #endif
570 #if (HAS_YM2413)
571 {
572 SOUND_YM2413,
573 "YM2413",
574 YM2413_num,
575 YM2413_clock,
576 YM2413_sh_start,
577 YM2413_sh_stop,
578 0,
579 0
580 },
581 #endif
582 #if (HAS_YM3812)
583 {
584 SOUND_YM3812,
585 "YM3812",
586 YM3812_num,
587 YM3812_clock,
588 YM3812_sh_start,
589 YM3812_sh_stop,
590 0,
591 0
592 },
593 #endif
594 #if (HAS_YM3526)
595 {
596 SOUND_YM3526,
597 "YM3526",
598 YM3526_num,
599 YM3526_clock,
600 YM3526_sh_start,
601 YM3526_sh_stop,
602 0,
603 0
604 },
605 #endif
606 #if (HAS_YMZ280B)
607 {
608 SOUND_YMZ280B,
609 "YMZ280B",
610 YMZ280B_num,
611 YMZ280B_clock,
612 YMZ280B_sh_start,
613 YMZ280B_sh_stop,
614 0,
615 0
616 },
617 #endif
618 #if (HAS_Y8950)
619 {
620 SOUND_Y8950,
621 "Y8950", /* (MSX-AUDIO) */
622 Y8950_num,
623 Y8950_clock,
624 Y8950_sh_start,
625 Y8950_sh_stop,
626 0,
627 0
628 },
629 #endif
630 #if (HAS_SN76477)
631 {
632 SOUND_SN76477,
633 "SN76477",
634 SN76477_num,
635 0,
636 SN76477_sh_start,
637 SN76477_sh_stop,
638 0,
639 0
640 },
641 #endif
642 #if (HAS_SN76496)
643 {
644 SOUND_SN76496,
645 "SN76496",
646 SN76496_num,
647 SN76496_clock,
648 SN76496_sh_start,
649 0,
650 0
651 },
652 #endif
653 #if (HAS_POKEY)
654 {
655 SOUND_POKEY,
656 "Pokey",
657 POKEY_num,
658 POKEY_clock,
659 pokey_sh_start,
660 pokey_sh_stop,
661 0,
662 0
663 },
664 #endif
665 #if (HAS_NES)
666 {
667 SOUND_NES,
668 "Nintendo",
669 NES_num,
670 0,
671 NESPSG_sh_start,
672 NESPSG_sh_stop,
673 NESPSG_sh_update,
674 0
675 },
676 #endif
677 #if (HAS_ASTROCADE)
678 {
679 SOUND_ASTROCADE,
680 "Astrocade",
681 ASTROCADE_num,
682 ASTROCADE_clock,
683 astrocade_sh_start,
684 astrocade_sh_stop,
685 astrocade_sh_update,
686 0
687 },
688 #endif
689 #if (HAS_NAMCO)
690 {
691 SOUND_NAMCO,
692 "Namco",
693 0,
694 0,
695 namco_sh_start,
696 namco_sh_stop,
697 0,
698 0
699 },
700 #endif
701 #if (HAS_NAMCO_54XX)
702 {
703 SOUND_NAMCO_54XX,
704 "Namco 54XX",
705 0,
706 namco_54xx_clock,
707 namco_54xx_sh_start,
708 namco_54xx_sh_stop,
709 0,
710 0
711 },
712 #endif
713 #if (HAS_NAMCONA)
714 {
715 SOUND_NAMCONA,
716 "Namco NA",
717 0,
718 0,
719 NAMCONA_sh_start,
720 NAMCONA_sh_stop,
721 0,
722 0
723 },
724 #endif
725 #if (HAS_TMS36XX)
726 {
727 SOUND_TMS36XX,
728 "TMS36XX",
729 TMS36XX_num,
730 0,
731 tms36xx_sh_start,
732 tms36xx_sh_stop,
733 tms36xx_sh_update,
734 0
735 },
736 #endif
737 #if (HAS_TMS5110)
738 {
739 SOUND_TMS5110,
740 "TMS5110",
741 0,
742 TMS5110_clock,
743 tms5110_sh_start,
744 tms5110_sh_stop,
745 tms5110_sh_update,
746 0
747 },
748 #endif
749 #if (HAS_TMS5220)
750 {
751 SOUND_TMS5220,
752 "TMS5220",
753 0,
754 TMS5220_clock,
755 tms5220_sh_start,
756 tms5220_sh_stop,
757 tms5220_sh_update,
758 0
759 },
760 #endif
761 #if (HAS_VLM5030)
762 {
763 SOUND_VLM5030,
764 "VLM5030",
765 0,
766 VLM5030_clock,
767 VLM5030_sh_start,
768 VLM5030_sh_stop,
769 VLM5030_sh_update,
770 0
771 },
772 #endif
773 #if (HAS_ADPCM)
774 {
775 SOUND_ADPCM,
776 "ADPCM",
777 ADPCM_num,
778 0,
779 ADPCM_sh_start,
780 ADPCM_sh_stop,
781 ADPCM_sh_update,
782 0
783 },
784 #endif
785 #if (HAS_OKIM6295)
786 {
787 SOUND_OKIM6295,
788 "MSM6295",
789 OKIM6295_num,
790 OKIM6295_clock,
791 OKIM6295_sh_start,
792 OKIM6295_sh_stop,
793 OKIM6295_sh_update,
794 0
795 },
796 #endif
797 #if (HAS_MSM5205)
798 {
799 SOUND_MSM5205,
800 "MSM5205",
801 MSM5205_num,
802 MSM5205_clock,
803 MSM5205_sh_start,
804 0,
805 0,
806 MSM5205_sh_reset,
807 },
808 #endif
809 #if (HAS_MSM5232)
810 {
811 SOUND_MSM5232,
812 "MSM5232",
813 MSM5232_num,
814 MSM5232_clock,
815 MSM5232_sh_start,
816 MSM5232_sh_stop,
817 0,
818 MSM5232_sh_reset,
819 },
820 #endif
821 #if (HAS_UPD7759)
822 {
823 SOUND_UPD7759,
824 "uPD7759",
825 0,
826 0,
827 UPD7759_sh_start,
828 0,
829 0,
830 0
831 },
832 #endif
833 #if (HAS_HC55516)
834 {
835 SOUND_HC55516,
836 "HC55516",
837 HC55516_num,
838 0,
839 hc55516_sh_start,
840 0,
841 0,
842 0
843 },
844 #endif
845 #if (HAS_K005289)
846 {
847 SOUND_K005289,
848 "005289",
849 0,
850 0,
851 K005289_sh_start,
852 K005289_sh_stop,
853 0,
854 0
855 },
856 #endif
857 #if (HAS_K007232)
858 {
859 SOUND_K007232,
860 "007232",
861 K007232_num,
862 K007232_clock,
863 K007232_sh_start,
864 0,
865 0,
866 0
867 },
868 #endif
869 #if (HAS_K051649)
870 {
871 SOUND_K051649,
872 "051649",
873 0,
874 K051649_clock,
875 K051649_sh_start,
876 K051649_sh_stop,
877 0,
878 0
879 },
880 #endif
881 #if (HAS_K053260)
882 {
883 SOUND_K053260,
884 "053260",
885 K053260_num,
886 K053260_clock,
887 K053260_sh_start,
888 K053260_sh_stop,
889 0,
890 0
891 },
892 #endif
893 #if (HAS_K054539)
894 {
895 SOUND_K054539,
896 "054539",
897 K054539_num,
898 K054539_clock,
899 K054539_sh_start,
900 K054539_sh_stop,
901 0,
902 0
903 },
904 #endif
905 #if (HAS_SEGAPCM)
906 {
907 SOUND_SEGAPCM,
908 "Sega PCM",
909 0,
910 0,
911 SEGAPCM_sh_start,
912 SEGAPCM_sh_stop,
913 0,
914 0
915 },
916 #endif
917 #if (HAS_RF5C68)
918 {
919 SOUND_RF5C68,
920 "RF5C68",
921 0,
922 0,
923 RF5C68_sh_start,
924 RF5C68_sh_stop,
925 0,
926 0
927 },
928 #endif
929 #if (HAS_CEM3394)
930 {
931 SOUND_CEM3394,
932 "CEM3394",
933 cem3394_num,
934 0,
935 cem3394_sh_start,
936 cem3394_sh_stop,
937 0,
938 0
939 },
940 #endif
941 #if (HAS_C140)
942 {
943 SOUND_C140,
944 "C140",
945 0,
946 0,
947 C140_sh_start,
948 C140_sh_stop,
949 0,
950 0
951 },
952 #endif
953 #if (HAS_QSOUND)
954 {
955 SOUND_QSOUND,
956 "QSound",
957 0,
958 qsound_clock,
959 qsound_sh_start,
960 qsound_sh_stop,
961 0,
962 0
963 },
964 #endif
965 #if (HAS_SAA1099)
966 {
967 SOUND_SAA1099,
968 "SAA1099",
969 saa1099_num,
970 0,
971 saa1099_sh_start,
972 saa1099_sh_stop,
973 0,
974 0
975 },
976 #endif
977 #if (HAS_IREMGA20)
978 {
979 SOUND_IREMGA20,
980 "GA20",
981 0,
982 iremga20_clock,
983 IremGA20_sh_start,
984 IremGA20_sh_stop,
985 0,
986 0
987 },
988 #endif
989 #if (HAS_ES5505)
990 {
991 SOUND_ES5505,
992 "ES5505",
993 ES5505_num,
994 ES5505_clock,
995 ES5505_sh_start,
996 ES5505_sh_stop,
997 0,
998 0
999 },
1000 #endif
1001 #if (HAS_ES5506)
1002 {
1003 SOUND_ES5506,
1004 "ES5506",
1005 ES5506_num,
1006 ES5506_clock,
1007 ES5506_sh_start,
1008 ES5506_sh_stop,
1009 0,
1010 0
1011 },
1012 #endif
1013 #if (HAS_BSMT2000)
1014 {
1015 SOUND_BSMT2000,
1016 "BSMT2000",
1017 BSMT2000_num,
1018 BSMT2000_clock,
1019 BSMT2000_sh_start,
1020 BSMT2000_sh_stop,
1021 0,
1022 0
1023 },
1024 #endif
1025 #if (HAS_YMF262)
1026 {
1027 SOUND_YMF262,
1028 "YMF262",
1029 YMF262_num,
1030 YMF262_clock,
1031 YMF262_sh_start,
1032 YMF262_sh_stop,
1033 0,
1034 0
1035 },
1036 #endif
1037 #if (HAS_YMF278B)
1038 {
1039 SOUND_YMF278B,
1040 "YMF278B",
1041 YMF278B_num,
1042 YMF278B_clock,
1043 YMF278B_sh_start,
1044 YMF278B_sh_stop,
1045 0,
1046 0
1047 },
1048 #endif
1049 #if (HAS_GAELCO_CG1V)
1050 {
1051 SOUND_GAELCO_CG1V,
1052 "GAELCO CG-1V",
1053 0,
1054 0,
1055 gaelco_cg1v_sh_start,
1056 gaelcosnd_sh_stop,
1057 0,
1058 0
1059 },
1060 #endif
1061 #if (HAS_GAELCO_GAE1)
1062 {
1063 SOUND_GAELCO_GAE1,
1064 "GAELCO GAE1",
1065 0,
1066 0,
1067 gaelco_gae1_sh_start,
1068 gaelcosnd_sh_stop,
1069 0,
1070 0
1071 },
1072 #endif
1073 #if (HAS_X1_010)
1074 {
1075 SOUND_X1_010,
1076 "X1-010",
1077 0,
1078 seta_clock,
1079 seta_sh_start,
1080 seta_sh_stop,
1081 0,
1082 0
1083 },
1084 #endif
1085 #if (HAS_MULTIPCM)
1086 {
1087 SOUND_MULTIPCM,
1088 "Sega 315-5560",
1089 MultiPCM_num,
1090 0,
1091 MultiPCM_sh_start,
1092 MultiPCM_sh_stop,
1093 0,
1094 0
1095 },
1096 #endif
1097 #if (HAS_C6280)
1098 {
1099 SOUND_C6280,
1100 "HuC6280",
1101 0,
1102 c6280_clock,
1103 c6280_sh_start,
1104 c6280_sh_stop,
1105 0,
1106 0
1107 },
1108 #endif
1109 #if (HAS_TIA)
1110 {
1111 SOUND_TIA,
1112 "TIA",
1113 0,
1114 TIA_clock,
1115 tia_sh_start,
1116 tia_sh_stop,
1117 tia_sh_update,
1118 0
1119 },
1120 #endif
1121 #if (HAS_SP0250)
1122 {
1123 SOUND_SP0250,
1124 "GI SP0250",
1125 0,
1126 0,
1127 sp0250_sh_start,
1128 sp0250_sh_stop,
1129 0,
1130 0
1131 },
1132 #endif
1133 #if (HAS_SCSP)
1134 {
1135 SOUND_SCSP,
1136 "YMF292-F SCSP",
1137 0,
1138 0,
1139 SCSP_sh_start,
1140 SCSP_sh_stop,
1141 0,
1142 0
1143 },
1144 #endif
1145 #if (HAS_PSXSPU)
1146 {
1147 SOUND_PSXSPU,
1148 "PSX SPU",
1149 0,
1150 0,
1151 PSX_sh_start,
1152 PSX_sh_stop,
1153 0,
1154 0
1155 },
1156 #endif
1157 #if (HAS_YMF271)
1158 {
1159 SOUND_YMF271,
1160 "YMF271",
1161 0,
1162 0,
1163 YMF271_sh_start,
1164 YMF271_sh_stop,
1165 0,
1166 0
1167 },
1168 #endif
1169
1170 };
1171
1172
sound_start(void)1173 int sound_start(void)
1174 {
1175 int totalsound = 0;
1176 int i;
1177
1178 /* Verify the order of entries in the sndintf[] array */
1179 for (i = 0;i < SOUND_COUNT;i++)
1180 {
1181 if (sndintf[i].sound_num != i)
1182 {
1183 int j;
1184 log_cb(RETRO_LOG_ERROR, LOGPRE "Sound #%d wrong ID %d: check enum SOUND_... in src/sndintrf.h!\n",i,sndintf[i].sound_num);
1185 for (j = 0; j < i; j++)
1186 log_cb(RETRO_LOG_ERROR, LOGPRE "ID %2d: %s\n", j, sndintf[j].name);
1187 return 1;
1188 }
1189 }
1190
1191
1192 /* samples will be read later if needed */
1193 Machine->samples = 0;
1194
1195 refresh_period = TIME_IN_HZ(Machine->drv->frames_per_second);
1196 refresh_period_inv = 1.0 / refresh_period;
1197 sound_update_timer = timer_alloc(NULL);
1198
1199 if (mixer_sh_start() != 0)
1200 return 1;
1201
1202 if (streams_sh_start() != 0)
1203 return 1;
1204
1205 while (Machine->drv->sound[totalsound].sound_type != 0 && totalsound < MAX_SOUND)
1206 {
1207 if ((*sndintf[Machine->drv->sound[totalsound].sound_type].start)(&Machine->drv->sound[totalsound]) != 0)
1208 goto getout;
1209
1210 totalsound++;
1211 }
1212
1213 return 0;
1214
1215
1216 getout:
1217 /* TODO: should also free the resources allocated before */
1218 return 1;
1219 }
1220
1221
1222
sound_stop(void)1223 void sound_stop(void)
1224 {
1225 int totalsound = 0;
1226
1227
1228 while (Machine->drv->sound[totalsound].sound_type != 0 && totalsound < MAX_SOUND)
1229 {
1230 if (sndintf[Machine->drv->sound[totalsound].sound_type].stop)
1231 (*sndintf[Machine->drv->sound[totalsound].sound_type].stop)();
1232
1233 totalsound++;
1234 }
1235
1236 streams_sh_stop();
1237 mixer_sh_stop();
1238
1239 /* free audio samples */
1240 Machine->samples = 0;
1241 }
1242
1243
1244
sound_update(void)1245 void sound_update(void)
1246 {
1247 int totalsound = 0;
1248
1249
1250 /*profiler_mark(PROFILER_SOUND);*/
1251
1252 while (Machine->drv->sound[totalsound].sound_type != 0 && totalsound < MAX_SOUND)
1253 {
1254 if (sndintf[Machine->drv->sound[totalsound].sound_type].update)
1255 (*sndintf[Machine->drv->sound[totalsound].sound_type].update)();
1256
1257 totalsound++;
1258 }
1259
1260 streams_sh_update();
1261 mixer_sh_update();
1262
1263 timer_adjust(sound_update_timer, TIME_NEVER, 0, 0);
1264
1265 /*profiler_mark(PROFILER_END);*/
1266 }
1267
1268
sound_reset(void)1269 void sound_reset(void)
1270 {
1271 int totalsound = 0;
1272
1273
1274 while (Machine->drv->sound[totalsound].sound_type != 0 && totalsound < MAX_SOUND)
1275 {
1276 if (sndintf[Machine->drv->sound[totalsound].sound_type].reset)
1277 (*sndintf[Machine->drv->sound[totalsound].sound_type].reset)();
1278
1279 totalsound++;
1280 }
1281 }
1282
1283
1284
soundtype_name(int soundtype)1285 const char *soundtype_name(int soundtype)
1286 {
1287 if (soundtype < SOUND_COUNT)
1288 return sndintf[soundtype].name;
1289 else
1290 return "";
1291 }
1292
sound_name(const struct MachineSound * msound)1293 const char *sound_name(const struct MachineSound *msound)
1294 {
1295 return soundtype_name(msound->sound_type);
1296 }
1297
sound_num(const struct MachineSound * msound)1298 int sound_num(const struct MachineSound *msound)
1299 {
1300 if (msound->sound_type < SOUND_COUNT && sndintf[msound->sound_type].chips_num)
1301 return (*sndintf[msound->sound_type].chips_num)(msound);
1302 else
1303 return 0;
1304 }
1305
sound_clock(const struct MachineSound * msound)1306 int sound_clock(const struct MachineSound *msound)
1307 {
1308 if (msound->sound_type < SOUND_COUNT && sndintf[msound->sound_type].chips_clock)
1309 return (*sndintf[msound->sound_type].chips_clock)(msound);
1310 else
1311 return 0;
1312 }
1313
1314
sound_scalebufferpos(int value)1315 int sound_scalebufferpos(int value)
1316 {
1317 int result = (int)((double)value * timer_timeelapsed(sound_update_timer) * refresh_period_inv);
1318 if (value >= 0) return (result < value) ? result : value;
1319 else return (result > value) ? result : value;
1320 }
1321