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