1 /***************************************************************************
2 
3   ay8910.c
4 
5   Emulation of the AY-3-8910 / YM2149 sound chip.
6 
7   Based on various code snippets by Ville Hallik, Michael Cuddy,
8   Tatsuyuki Satoh, Fabrice Frances, Nicola Salmoria.
9 
10   Mostly rewritten by couriersud in 2008
11 
12   Public documentation:
13 
14   - http://privatfrickler.de/blick-auf-den-chip-soundchip-general-instruments-ay-3-8910/
15     Die pictures of the AY8910
16 
17   - US Patent 4933980
18 
19   Games using ADSR: gyruss
20 
21   A list with more games using ADSR can be found here:
22         http://mametesters.org/view.php?id=3043
23 
24   TODO:
25   * The AY8930 has an extended mode which is currently
26     not emulated.
27   * The YMZ284 only has one 1 output channel (mixed chan A,B,C).
28     This should be forced.
29   * YM2610 & YM2608 will need a separate flag in their config structures
30     to distinguish between legacy and discrete mode.
31 
32   The rewrite also introduces a generic model for the DAC. This model is
33   not perfect, but allows channel mixing based on a parametrized approach.
34   This model also allows to factor in different loads on individual channels.
35   If a better model is developped in the future or better measurements are
36   available, the driver should be easy to change. The model is described
37   later.
38 
39   In order to not break hundreds of existing drivers by default the flag
40   AY8910_LEGACY_OUTPUT is used by drivers not changed to take into account the
41   new model. All outputs are normalized to the old output range (i.e. 0 .. 7ffff).
42   In the case of channel mixing, output range is 0...3 * 7fff.
43 
44   The main difference between the AY-3-8910 and the YM2149 is, that the
45   AY-3-8910 datasheet mentions, that fixed volume level 0, which is set by
46   registers 8 to 10 is "channel off". The YM2149 mentions, that the generated
47   signal has a 2V DC component. This is confirmed by measurements. The approach
48   taken here is to assume the 2V DC offset for all outputs for the YM2149.
49   For the AY-3-8910, an offset is used if envelope is active for a channel.
50   This is backed by oscilloscope pictures from the datasheet. If a fixed volume
51   is set, i.e. envelope is disabled, the output voltage is set to 0V. Recordings
52   I found on the web for gyruss indicate, that the AY-3-8910 offset should
53   be around 0.2V. This will also make sound levels more compatible with
54   user observations for scramble.
55 
56   The Model:
57                      5V     5V
58                       |      |
59                       /      |
60   Volume Level x >---|       Z
61                       >      Z Pullup Resistor RU
62                        |     Z
63                        Z     |
64                     Rx Z     |
65                        Z     |
66                        |     |
67                        '-----+-------->  >---+----> Output signal
68                              |               |
69                              Z               Z
70                Pulldown RD   Z               Z Load RL
71                              Z               Z
72                              |               |
73                             GND             GND
74 
75 Each Volume level x will select a different resistor Rx. Measurements from fpgaarcade.com
76 where used to calibrate channel mixing for the YM2149. This was done using
77 a least square approach using a fixed RL of 1K Ohm.
78 
79 For the AY measurements cited in e.g. openmsx as "Hacker Kay" for a single
80 channel were taken. These were normalized to 0 ... 65535 and consequently
81 adapted to an offset of 0.2V and a VPP of 1.3V. These measurements are in
82 line e.g. with the formula used by pcmenc for the volume: vol(i) = exp(i/2-7.5).
83 
84 The following is documentation from the code moved here and amended to reflect
85 the changes done:
86 
87 Careful studies of the chip output prove that the chip counts up from 0
88 until the counter becomes greater or equal to the period. This is an
89 important difference when the program is rapidly changing the period to
90 modulate the sound. This is worthwhile noting, since the datasheets
91 say, that the chip counts down.
92 Also, note that period = 0 is the same as period = 1. This is mentioned
93 in the YM2203 data sheets. However, this does NOT apply to the Envelope
94 period. In that case, period = 0 is half as period = 1.
95 
96 Envelope shapes:
97     C AtAlH
98     0 0 x x  \___
99     0 1 x x  /___
100     1 0 0 0  \\\\
101     1 0 0 1  \___
102     1 0 1 0  \/\/
103     1 0 1 1  \```
104     1 1 0 0  ////
105     1 1 0 1  /```
106     1 1 1 0  /\/\
107     1 1 1 1  /___
108 
109 The envelope counter on the AY-3-8910 has 16 steps. On the YM2149 it
110 has twice the steps, happening twice as fast.
111 
112 ***************************************************************************/
113 
114 #include "mamedef.h"
115 //#include "sndintrf.h"
116 //#include "streams.h"
117 //#include "cpuintrf.h"
118 //#include "cpuexec.h"
119 #include <stdlib.h>
120 #include <memory.h>
121 #include <stdio.h>
122 #include "ay8910.h"
123 
124 #define NULL	((void *)0)
125 
126 /*************************************
127  *
128  *  Defines
129  *
130  *************************************/
131 
132 #define ENABLE_REGISTER_TEST		(0)		/* Enable preprogrammed registers */
133 
134 //#define MAX_OUTPUT 0x7fff
135 #define MAX_OUTPUT 0x4000
136 #define NUM_CHANNELS 3
137 
138 /* register id's */
139 #define AY_AFINE	(0)
140 #define AY_ACOARSE	(1)
141 #define AY_BFINE	(2)
142 #define AY_BCOARSE	(3)
143 #define AY_CFINE	(4)
144 #define AY_CCOARSE	(5)
145 #define AY_NOISEPER	(6)
146 #define AY_ENABLE	(7)
147 #define AY_AVOL		(8)
148 #define AY_BVOL		(9)
149 #define AY_CVOL		(10)
150 #define AY_EFINE	(11)
151 #define AY_ECOARSE	(12)
152 #define AY_ESHAPE	(13)
153 
154 #define AY_PORTA	(14)
155 #define AY_PORTB	(15)
156 
157 #define NOISE_ENABLEQ(_psg, _chan)	(((_psg)->regs[AY_ENABLE] >> (3 + _chan)) & 1)
158 #define TONE_ENABLEQ(_psg, _chan)	(((_psg)->regs[AY_ENABLE] >> (_chan)) & 1)
159 #define TONE_PERIOD(_psg, _chan)	( (_psg)->regs[(_chan) << 1] | (((_psg)->regs[((_chan) << 1) | 1] & 0x0f) << 8) )
160 #define NOISE_PERIOD(_psg)			( (_psg)->regs[AY_NOISEPER] & 0x1f)
161 #define TONE_VOLUME(_psg, _chan)	( (_psg)->regs[AY_AVOL + (_chan)] & 0x0f)
162 //#define TONE_ENVELOPE(_psg, _chan)	(((_psg)->regs[AY_AVOL + (_chan)] >> 4) & (((_psg)->device->type() == AY8914) ? 3 : 1))
163 #define TONE_ENVELOPE(_psg, _chan)	(((_psg)->regs[AY_AVOL + (_chan)] >> 4) & (((_psg)->chip_type == CHTYPE_AY8914) ? 3 : 1))
164 #define ENVELOPE_PERIOD(_psg)		(((_psg)->regs[AY_EFINE] | ((_psg)->regs[AY_ECOARSE]<<8)))
165 #define NOISE_OUTPUT(_psg)			((_psg)->rng & 1)
166 
167 #define CHTYPE_AY8910	0x00
168 #define CHTYPE_AY8912	0x01
169 #define CHTYPE_AY8913	0x02
170 #define CHTYPE_AY8930	0x03
171 #define CHTYPE_AY8914	0x04
172 #define CHTYPE_YM2149	0x10
173 #define CHTYPE_YM3439	0x11
174 #define CHTYPE_YMZ284	0x12
175 #define CHTYPE_YMZ294	0x13
176 #define CHTYPE_YM2203	0x20
177 #define CHTYPE_YM2608	0x21
178 #define CHTYPE_YM2610	0x22
179 #define CHTYPE_YM2610B	0x23
180 
181 /*************************************
182  *
183  *  Type definitions
184  *
185  *************************************/
186 
187 typedef struct _ay_ym_param ay_ym_param;
188 struct _ay_ym_param
189 {
190 	double r_up;
191 	double r_down;
192 	int    res_count;
193 	double res[32];
194 };
195 
196 typedef struct _ay8910_context ay8910_context;
197 struct _ay8910_context
198 {
199 	//const device_config *device;
200 	int streams;
201 	int ready;
202 	//sound_stream *channel;
203 	const ay8910_interface *intf;
204 	INT32 register_latch;
205 	UINT8 regs[16];
206 	INT32 last_enable;
207 	INT32 count[NUM_CHANNELS];
208 	UINT8 output[NUM_CHANNELS];
209 	UINT8 prescale_noise;
210 	INT32 count_noise;
211 	INT32 count_env;
212 	INT8 env_step;
213 	UINT32 env_volume;
214 	UINT8 hold,alternate,attack,holding;
215 	INT32 rng;
216 	UINT8 env_step_mask;
217 	/* init parameters ... */
218 	int step;
219 	int zero_is_off;
220 	UINT8 vol_enabled[NUM_CHANNELS];
221 	const ay_ym_param *par;
222 	const ay_ym_param *par_env;
223 	INT32 vol_table[NUM_CHANNELS][16];
224 	INT32 env_table[NUM_CHANNELS][32];
225 	INT32 vol3d_table[8*32*32*32];
226 	//devcb_resolved_read8 portAread;
227 	//devcb_resolved_read8 portBread;
228 	//devcb_resolved_write8 portAwrite;
229 	//devcb_resolved_write8 portBwrite;
230 	UINT8 StereoMask[NUM_CHANNELS];
231 	UINT32 MuteMsk[NUM_CHANNELS];
232 	UINT8 chip_type;
233 	UINT8 IsDisabled;
234 
235 	SRATE_CALLBACK SmpRateFunc;
236 	void* SmpRateData;
237 };
238 
239 //#define MAX_CHIPS	0x02
240 //static ay8910_context AY8910Data[MAX_CHIPS];
241 
242 #define MAX_UPDATE_LEN	0x10	// in samples
243 static stream_sample_t AYBuf[NUM_CHANNELS][MAX_UPDATE_LEN];
244 
245 
246 /*INLINE ay8910_context *get_safe_token(const device_config *device)
247 {
248 	assert(device != NULL);
249 	assert(device->token != NULL);
250 	assert(device->type == SOUND);
251 	assert(sound_get_type(device) == SOUND_AY8910 ||
252 		   sound_get_type(device) == SOUND_AY8912 ||
253 		   sound_get_type(device) == SOUND_AY8913 ||
254 		   sound_get_type(device) == SOUND_AY8930 ||
255 		   sound_get_type(device) == SOUND_YM2149 ||
256 		   sound_get_type(device) == SOUND_YM3439 ||
257 		   sound_get_type(device) == SOUND_YMZ284 ||
258 		   sound_get_type(device) == SOUND_YMZ294);
259 	return (ay8910_context *)device->token;
260 }*/
261 
262 
263 /*************************************
264  *
265  *  Static
266  *
267  *************************************/
268 
269 static const ay_ym_param ym2149_param =
270 {
271 	630, 801,
272 	16,
273 	{ 73770, 37586, 27458, 21451, 15864, 12371, 8922,  6796,
274 	   4763,  3521,  2403,  1737,  1123,   762,  438,   251 },
275 };
276 
277 static const ay_ym_param ym2149_param_env =
278 {
279 	630, 801,
280 	32,
281 	{ 103350, 73770, 52657, 37586, 32125, 27458, 24269, 21451,
282 	   18447, 15864, 14009, 12371, 10506,  8922,  7787,  6796,
283 	    5689,  4763,  4095,  3521,  2909,  2403,  2043,  1737,
284 	    1397,  1123,   925,   762,   578,   438,   332,   251 },
285 };
286 
287 #if 0
288 /* RL = 1000, Hacker Kay normalized, 2.1V to 3.2V */
289 static const ay_ym_param ay8910_param =
290 {
291 	664, 913,
292 	16,
293 	{ 85785, 34227, 26986, 20398, 14886, 10588,  7810,  4856,
294 	   4120,  2512,  1737,  1335,  1005,   747,   586,    451 },
295 };
296 
297 /*
298  * RL = 3000, Hacker Kay normalized pattern, 1.5V to 2.8V
299  * These values correspond with guesses based on Gyruss schematics
300  * They work well with scramble as well.
301  */
302 static const ay_ym_param ay8910_param =
303 {
304 	930, 454,
305 	16,
306 	{ 85066, 34179, 27027, 20603, 15046, 10724, 7922, 4935,
307 	   4189,  2557,  1772,  1363,  1028,  766,   602,  464 },
308 };
309 
310 /*
311  * RL = 1000, Hacker Kay normalized pattern, 0.75V to 2.05V
312  * These values correspond with guesses based on Gyruss schematics
313  * They work well with scramble as well.
314  */
315 static const ay_ym_param ay8910_param =
316 {
317 	1371, 313,
318 	16,
319 	{ 93399, 33289, 25808, 19285, 13940, 9846,  7237,  4493,
320 	   3814,  2337,  1629,  1263,   962,  727,   580,   458 },
321 };
322 
323 /*
324  * RL = 1000, Hacker Kay normalized pattern, 0.2V to 1.5V
325  */
326 static const ay_ym_param ay8910_param =
327 {
328 	5806, 300,
329 	16,
330 	{ 118996, 42698, 33105, 24770, 17925, 12678,  9331,  5807,
331         4936,  3038,  2129,  1658,  1271,   969,   781,   623 }
332 };
333 #endif
334 
335 /*
336  * RL = 2000, Based on Matthew Westcott's measurements from Dec 2001.
337  * -------------------------------------------------------------------
338  *
339  * http://groups.google.com/group/comp.sys.sinclair/browse_thread/thread/fb3091da4c4caf26/d5959a800cda0b5e?lnk=gst&q=Matthew+Westcott#d5959a800cda0b5e
340  * After what Russell mentioned a couple of weeks back about the lack of
341  * publicised measurements of AY chip volumes - I've finally got round to
342  * making these readings, and I'm placing them in the public domain - so
343  * anyone's welcome to use them in emulators or anything else.
344 
345  * To make the readings, I set up the chip to produce a constant voltage on
346  * channel C (setting bits 2 and 5 of register 6), and varied the amplitude
347  * (the low 4 bits of register 10). The voltages were measured between the
348  * channel C output (pin 1) and ground (pin 6).
349  *
350  * Level  Voltage
351  *  0     1.147
352  *  1     1.162
353  *  2     1.169
354  *  3     1.178
355  *  4     1.192
356  *  5     1.213
357  *  6     1.238
358  *  7     1.299
359  *  8     1.336
360  *  9     1.457
361  * 10     1.573
362  * 11     1.707
363  * 12     1.882
364  * 13     2.06
365  * 14     2.32
366  * 15     2.58
367  * -------------------------------------------------------------------
368  *
369  * The ZX spectrum output circuit was modelled in SwitcherCAD and
370  * the resistor values below create the voltage levels above.
371  * RD was measured on a real chip to be 8m Ohm, RU was 0.8m Ohm.
372  */
373 
374 static const ay_ym_param ay8910_param =
375 {
376 	800000, 8000000,
377 	16,
378 	{ 15950, 15350, 15090, 14760, 14275, 13620, 12890, 11370,
379       10600,  8590,  7190,  5985,  4820,  3945,  3017,  2345 }
380 };
381 
382 /*************************************
383  *
384  *  Inline
385  *
386  *************************************/
387 
build_3D_table(double rl,const ay_ym_param * par,const ay_ym_param * par_env,int normalize,double factor,int zero_is_off,INT32 * tab)388 INLINE void build_3D_table(double rl, const ay_ym_param *par, const ay_ym_param *par_env, int normalize, double factor, int zero_is_off, INT32 *tab)
389 {
390 	int j, j1, j2, j3, e, indx;
391 	double rt, rw, n;
392 	double min = 10.0,  max = 0.0;
393 	double *temp;
394 	double spdup;
395 
396 	temp = (double *)malloc(8*32*32*32*sizeof(*temp));
397 
398 	for (e=0; e < 8; e++)
399 		for (j1=0; j1 < 32; j1++)
400 			for (j2=0; j2 < 32; j2++)
401 				for (j3=0; j3 < 32; j3++)
402 				{
403 					if (zero_is_off)
404 					{
405 						n  = (j1 != 0 || (e & 0x01)) ? 1 : 0;
406 						n += (j2 != 0 || (e & 0x02)) ? 1 : 0;
407 						n += (j3 != 0 || (e & 0x04)) ? 1 : 0;
408 					}
409 					else
410 						n = 3.0;
411 
412 					rt = n / par->r_up + 3.0 / par->r_down + 1.0 / rl;
413 					rw = n / par->r_up;
414 
415 					/*rw += 1.0 / ( (e & 0x01) ? par_env->res[j1] : par->res[j1]);
416 					rt += 1.0 / ( (e & 0x01) ? par_env->res[j1] : par->res[j1]);
417 					rw += 1.0 / ( (e & 0x02) ? par_env->res[j2] : par->res[j2]);
418 					rt += 1.0 / ( (e & 0x02) ? par_env->res[j2] : par->res[j2]);
419 					rw += 1.0 / ( (e & 0x04) ? par_env->res[j3] : par->res[j3]);
420 					rt += 1.0 / ( (e & 0x04) ? par_env->res[j3] : par->res[j3]);*/
421 					/* this should speed up the initialsation a bit (it calculates 262144 values) */
422 					spdup  = 1.0 / ( (e & 0x01) ? par_env->res[j1] : par->res[j1]);
423 					spdup += 1.0 / ( (e & 0x02) ? par_env->res[j2] : par->res[j2]);
424 					spdup += 1.0 / ( (e & 0x04) ? par_env->res[j3] : par->res[j3]);
425 					if (spdup > 1.0)
426 					{
427 						// Bugfix for spdup being 1.#INF
428 						indx = (e << 15) | (j3<<10) | (j2<<5) | j1;
429 						temp[indx] = 0.0;
430 						continue;
431 					}
432 					rw += spdup;
433 					rt += spdup;
434 
435 					indx = (e << 15) | (j3<<10) | (j2<<5) | j1;
436 					temp[indx] = rw / rt;
437 					if (temp[indx] < min)
438 						min = temp[indx];
439 					if (temp[indx] > max)
440 						max = temp[indx];
441 				}
442 
443 	if (normalize)
444 	{
445 		for (j=0; j < 32*32*32*8; j++)
446 			//tab[j] = MAX_OUTPUT * (((temp[j] - min)/(max-min))) * factor;
447 			tab[j] = MAX_OUTPUT * (((temp[j] - min)/(max-min)) * 0.5) * factor;
448 	}
449 	else
450 	{
451 		for (j=0; j < 32*32*32*8; j++)
452 			tab[j] = MAX_OUTPUT * temp[j];
453 	}
454 
455 	/* for (e=0;e<16;e++) printf("%d %d\n",e<<10, tab[e<<10]); */
456 
457 	free(temp);
458 }
459 
build_single_table(double rl,const ay_ym_param * par,int normalize,INT32 * tab,int zero_is_off)460 INLINE void build_single_table(double rl, const ay_ym_param *par, int normalize, INT32 *tab, int zero_is_off)
461 {
462 	int j;
463 	double rt, rw = 0;
464 	double temp[32], min=10.0, max=0.0;
465 
466 	for (j=0; j < par->res_count; j++)
467 	{
468 		rt = 1.0 / par->r_down + 1.0 / rl;
469 
470 		rw = 1.0 / par->res[j];
471 		rt += 1.0 / par->res[j];
472 
473 		if (!(zero_is_off && j == 0))
474 		{
475 			rw += 1.0 / par->r_up;
476 			rt += 1.0 / par->r_up;
477 		}
478 
479 		temp[j] = rw / rt;
480 		if (temp[j] < min)
481 			min = temp[j];
482 		if (temp[j] > max)
483 			max = temp[j];
484 	}
485 	if (normalize)
486 	{
487 		for (j=0; j < par->res_count; j++)
488 			/* The following line generates values that cause clicks when starting/pausing/stopping
489 				because there're off (the center is at zero, not the base).
490 				That's quite bad for a player.
491 			tab[j] = MAX_OUTPUT * (((temp[j] - min)/(max-min)) - 0.25) * 0.5;
492 			*/
493 			tab[j] = MAX_OUTPUT * ((temp[j] - min)/(max-min)) / NUM_CHANNELS;
494 	}
495 	else
496 	{
497 		for (j=0; j < par->res_count; j++)
498 			tab[j] = MAX_OUTPUT * temp[j] / NUM_CHANNELS;
499 	}
500 
501 }
502 
mix_3D(ay8910_context * psg)503 INLINE UINT16 mix_3D(ay8910_context *psg)
504 {
505 	int indx = 0, chan;
506 
507 	for (chan = 0; chan < NUM_CHANNELS; chan++)
508 		if (TONE_ENVELOPE(psg, chan) != 0)
509 		{
510 			//if (psg->device->type() == AY8914) // AY8914 Has a two bit tone_envelope field
511 			if (psg->chip_type == CHTYPE_AY8914) // AY8914 Has a two bit tone_envelope field
512 			{
513 				indx |= (1 << (chan+15)) | ( psg->vol_enabled[chan] ? ((psg->env_volume >> (3-TONE_ENVELOPE(psg, chan))) << (chan*5)) : 0);
514 			}
515 			else
516 			{
517 				indx |= (1 << (chan+15)) | ( psg->vol_enabled[chan] ? psg->env_volume << (chan*5) : 0);
518 			}
519 		}
520 		else
521 		{
522 			indx |= (psg->vol_enabled[chan] ? TONE_VOLUME(psg, chan) << (chan*5) : 0);
523 		}
524 	return psg->vol3d_table[indx];
525 }
526 
527 /*************************************
528  *
529  * Static functions
530  *
531  *************************************/
532 
ay8910_write_reg(ay8910_context * psg,int r,int v)533 static void ay8910_write_reg(ay8910_context *psg, int r, int v)
534 {
535 	//if (r >= 11 && r <= 13 ) printf("%d %x %02x\n", PSG->index, r, v);
536 	psg->regs[r] = v;
537 
538 	switch( r )
539 	{
540 		case AY_AFINE:
541 		case AY_ACOARSE:
542 		case AY_BFINE:
543 		case AY_BCOARSE:
544 		case AY_CFINE:
545 		case AY_CCOARSE:
546 		case AY_NOISEPER:
547 		case AY_AVOL:
548 		case AY_BVOL:
549 		case AY_CVOL:
550 		case AY_EFINE:
551 			/* No action required */
552 			break;
553 		case AY_ECOARSE:
554 			#ifdef MAME_DEBUG
555 			if ( (v & 0x0f) > 0)
556 				popmessage("Write to ECoarse register detected - please inform www.mametesters.org");
557 			#endif
558 			/* No action required */
559 			break;
560 		case AY_ENABLE:
561 			/*if ((psg->last_enable == -1) ||
562 			    ((psg->last_enable & 0x40) != (psg->regs[AY_ENABLE] & 0x40)))
563 			{
564 				// write out 0xff if port set to input
565 				devcb_call_write8(&psg->portAwrite, 0, (psg->regs[AY_ENABLE] & 0x40) ? psg->regs[AY_PORTA] : 0xff);
566 			}
567 
568 			if ((psg->last_enable == -1) ||
569 			    ((psg->last_enable & 0x80) != (psg->regs[AY_ENABLE] & 0x80)))
570 			{
571 				// write out 0xff if port set to input
572 				devcb_call_write8(&psg->portBwrite, 0, (psg->regs[AY_ENABLE] & 0x80) ? psg->regs[AY_PORTB] : 0xff);
573 			}*/
574 			if (~v & 0x3F)	// one of the channels gets enabled -> Enable emulation
575 				psg->IsDisabled = 0x00;
576 
577 			psg->last_enable = psg->regs[AY_ENABLE];
578 			break;
579 		case AY_ESHAPE:
580 			#ifdef MAME_DEBUG
581 			if ( (v & 0x0f) > 0)
582 				popmessage("Write to EShape register detected - please inform www.mametesters.org");
583 			#endif
584 			psg->attack = (psg->regs[AY_ESHAPE] & 0x04) ? psg->env_step_mask : 0x00;
585 			if ((psg->regs[AY_ESHAPE] & 0x08) == 0)
586 			{
587 				/* if Continue = 0, map the shape to the equivalent one which has Continue = 1 */
588 				psg->hold = 1;
589 				psg->alternate = psg->attack;
590 			}
591 			else
592 			{
593 				psg->hold = psg->regs[AY_ESHAPE] & 0x01;
594 				psg->alternate = psg->regs[AY_ESHAPE] & 0x02;
595 			}
596 			psg->env_step = psg->env_step_mask;
597 			psg->holding = 0;
598 			psg->env_volume = (psg->env_step ^ psg->attack);
599 			break;
600 		case AY_PORTA:
601 			/*if (psg->regs[AY_ENABLE] & 0x40)
602 			{
603 				if (psg->portAwrite.write)
604 					devcb_call_write8(&psg->portAwrite, 0, psg->regs[AY_PORTA]);
605 				else
606 					logerror("warning - write %02x to 8910 '%s' Port A\n",psg->regs[AY_PORTA],psg->device->tag);
607 			}
608 			else
609 			{
610 				logerror("warning: write to 8910 '%s' Port A set as input - ignored\n",psg->device->tag);
611 			}*/
612 			break;
613 		case AY_PORTB:
614 			/*if (psg->regs[AY_ENABLE] & 0x80)
615 			{
616 				if (psg->portBwrite.write)
617 					devcb_call_write8(&psg->portBwrite, 0, psg->regs[AY_PORTB]);
618 				else
619 					logerror("warning - write %02x to 8910 '%s' Port B\n",psg->regs[AY_PORTB],psg->device->tag);
620 			}
621 			else
622 			{
623 				logerror("warning: write to 8910 '%s' Port B set as input - ignored\n",psg->device->tag);
624 			}*/
625 			break;
626 	}
627 }
628 
629 //static STREAM_UPDATE( ay8910_update )
630 /*void ay8910_update(UINT8 ChipID, stream_sample_t **outputs, int samples)
631 {
632 	ay8910_context *psg = &AY8910Data[ChipID];
633 
634 	memset(outputs[0], 0x00, samples * sizeof(stream_sample_t));
635 	memset(outputs[1], 0x00, samples * sizeof(stream_sample_t));
636 	ay8910_update_one(psg, outputs, samples);
637 
638 	return;
639 }*/
640 
ay8910_update_one(void * param,stream_sample_t ** outputs,int samples)641 void ay8910_update_one(void *param, stream_sample_t **outputs, int samples)
642 {
643 	ay8910_context *psg = (ay8910_context *)param;
644 	stream_sample_t *buf[NUM_CHANNELS];
645 	int chan;
646 	int cursmpl;
647 	int buf_smpls;
648 	stream_sample_t *bufL = outputs[0];
649 	stream_sample_t *bufR = outputs[1];
650 	//stream_sample_t bufSmpl;
651 
652 	memset(outputs[0], 0x00, samples * sizeof(stream_sample_t));
653 	memset(outputs[1], 0x00, samples * sizeof(stream_sample_t));
654 
655 	// Speed hack for OPN chips (YM2203, YM26xx), that have an often unused AY8910
656 	if (psg->IsDisabled)
657 		return;
658 
659 	buf_smpls = samples;
660 	//buf[0] = outputs[0];
661 	buf[0] = AYBuf[0];
662 	buf[1] = NULL;
663 	buf[2] = NULL;
664 	//if (psg->streams == NUM_CHANNELS)
665 	//{
666 		//buf[1] = outputs[1];
667 		//buf[2] = outputs[2];
668 		buf[1] = AYBuf[1];
669 		buf[2] = AYBuf[2];
670 	//}
671 
672 	/* hack to prevent us from hanging when starting filtered outputs */
673 	//if (!psg->ready)
674 	//{
675 		for (chan = 0; chan < NUM_CHANNELS; chan++)
676 			if (buf[chan] != NULL)
677 				memset(buf[chan], 0, samples * sizeof(*buf[chan]));
678 	//}
679 
680 	/* The 8910 has three outputs, each output is the mix of one of the three */
681 	/* tone generators and of the (single) noise generator. The two are mixed */
682 	/* BEFORE going into the DAC. The formula to mix each channel is: */
683 	/* (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable). */
684 	/* Note that this means that if both tone and noise are disabled, the output */
685 	/* is 1, not 0, and can be modulated changing the volume. */
686 
687 	if (buf_smpls > MAX_UPDATE_LEN)
688 		buf_smpls = MAX_UPDATE_LEN;
689 	/* buffering loop */
690 	while (buf_smpls)
691 	{
692 		for (chan = 0; chan < NUM_CHANNELS; chan++)
693 		{
694 			psg->count[chan]++;
695 			if (psg->count[chan] >= TONE_PERIOD(psg, chan))
696 			{
697 				psg->output[chan] ^= 1;
698 				psg->count[chan] = 0;
699 			}
700 		}
701 
702 		psg->count_noise++;
703 		if (psg->count_noise >= NOISE_PERIOD(psg))
704 		{
705 			/* toggle the prescaler output. Noise is no different to
706 			 * channels.
707 			 */
708 			psg->count_noise = 0;
709 			psg->prescale_noise ^= 1;
710 
711 			if ( psg->prescale_noise)
712 			{
713 				/* The Random Number Generator of the 8910 is a 17-bit shift */
714 				/* register. The input to the shift register is bit0 XOR bit3 */
715 				/* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */
716 
717 				psg->rng ^= (((psg->rng & 1) ^ ((psg->rng >> 3) & 1)) << 17);
718 				psg->rng >>= 1;
719 			}
720 		}
721 
722 		for (chan = 0; chan < NUM_CHANNELS; chan++)
723 		{
724 			psg->vol_enabled[chan] = (psg->output[chan] | TONE_ENABLEQ(psg, chan)) & (NOISE_OUTPUT(psg) | NOISE_ENABLEQ(psg, chan));
725 		}
726 
727 		/* update envelope */
728 		if (psg->holding == 0)
729 		{
730 			psg->count_env++;
731 			if (psg->count_env >= ENVELOPE_PERIOD(psg) * psg->step )
732 			{
733 				psg->count_env = 0;
734 				psg->env_step--;
735 
736 				/* check envelope current position */
737 				if (psg->env_step < 0)
738 				{
739 					if (psg->hold)
740 					{
741 						if (psg->alternate)
742 							psg->attack ^= psg->env_step_mask;
743 						psg->holding = 1;
744 						psg->env_step = 0;
745 					}
746 					else
747 					{
748 						/* if CountEnv has looped an odd number of times (usually 1), */
749 						/* invert the output. */
750 						if (psg->alternate && (psg->env_step & (psg->env_step_mask + 1)))
751  							psg->attack ^= psg->env_step_mask;
752 
753 						psg->env_step &= psg->env_step_mask;
754 					}
755 				}
756 
757 			}
758 		}
759 		psg->env_volume = (psg->env_step ^ psg->attack);
760 
761 		//if (psg->streams == NUM_CHANNELS)
762 		//{
763 			for (chan = 0; chan < NUM_CHANNELS; chan++)
764 				if (TONE_ENVELOPE(psg, chan) != 0)
765 				{
766 					/* Envolope has no "off" state */
767 					//if (psg->device->type() == AY8914) // AY8914 Has a two bit tone_envelope field
768 					if (psg->chip_type == CHTYPE_AY8914) // AY8914 Has a two bit tone_envelope field
769 					{
770 						*(buf[chan]++) = psg->env_table[chan][psg->vol_enabled[chan] ? psg->env_volume >> (3-TONE_ENVELOPE(psg,chan)) : 0];
771 					}
772 					else
773 					{
774 						*(buf[chan]++) = psg->env_table[chan][psg->vol_enabled[chan] ? psg->env_volume : 0];
775 					}
776 				}
777 				else
778 				{
779 					*(buf[chan]++) = psg->vol_table[chan][psg->vol_enabled[chan] ? TONE_VOLUME(psg, chan) : 0];
780 				}
781 		/*}
782 		else
783 		{
784 			*(buf[0]++) = mix_3D(psg);
785 #if 0
786 			*(buf[0]) = (  vol_enabled[0] * psg->vol_table[psg->Vol[0]]
787 			             + vol_enabled[1] * psg->vol_table[psg->Vol[1]]
788 			             + vol_enabled[2] * psg->vol_table[psg->Vol[2]]) / psg->step;
789 #endif
790 		}*/
791 		buf_smpls--;
792 
793 	}
794 
795 	buf_smpls = samples;
796 	if (buf_smpls > MAX_UPDATE_LEN)
797 		buf_smpls = MAX_UPDATE_LEN;
798 	for (cursmpl = 0; cursmpl < buf_smpls; cursmpl ++)
799 	{
800 		/*bufSmpl = AYBuf[0][cursmpl] & psg->MuteMsk[0];
801 		if (psg->streams == NUM_CHANNELS)
802 		{
803 			bufSmpl += AYBuf[1][cursmpl] & psg->MuteMsk[1];
804 			bufSmpl += AYBuf[2][cursmpl] & psg->MuteMsk[2];
805 		}
806 		bufL[cursmpl] += bufSmpl;
807 		bufR[cursmpl] += bufSmpl;*/
808 		for (chan = 0; chan < NUM_CHANNELS; chan ++)
809 		{
810 			if (psg->MuteMsk[chan])
811 			{
812 				if (psg->StereoMask[chan] & 0x01)
813 					bufL[cursmpl] += AYBuf[chan][cursmpl];
814 				if (psg->StereoMask[chan] & 0x02)
815 					bufR[cursmpl] += AYBuf[chan][cursmpl];
816 			}
817 		}
818 	}
819 }
820 
build_mixer_table(ay8910_context * psg)821 static void build_mixer_table(ay8910_context *psg)
822 {
823 	int	normalize = 0;
824 	int	chan;
825 
826 	if ((psg->intf->flags & AY8910_LEGACY_OUTPUT) != 0)
827 	{
828 #ifdef _DEBUG
829 		//logerror("AY-3-8910/YM2149 using legacy output levels!\n");
830 #endif
831 		//normalize = 1;
832 	}
833 	normalize = 1;
834 
835 	/* skip unnecessary things to speed up the AY8910 init
836 		1-channel AY uses the 3D table, 3-channel AY uses envelope and volume
837 		but building the 3D table still takes too long */
838 	//if (psg->streams == NUM_CHANNELS)
839 	{
840 		for (chan=0; chan < NUM_CHANNELS; chan++)
841 		{
842 			build_single_table(psg->intf->res_load[chan], psg->par, normalize, psg->vol_table[chan], psg->zero_is_off);
843 			build_single_table(psg->intf->res_load[chan], psg->par_env, normalize, psg->env_table[chan], 0);
844 		}
845 	}
846 	//else
847 	//{
848 	//	/*
849 	//	 * The previous implementation added all three channels up instead of averaging them.
850 	//	 * The factor of 3 will force the same levels if normalizing is used.
851 	//	 */
852 	//	build_3D_table(psg->intf->res_load[0], psg->par, psg->par_env, normalize, 3, psg->zero_is_off, psg->vol3d_table);
853 	//}
854 }
855 
856 /*static void ay8910_statesave(ay8910_context *psg, const device_config *device)
857 {
858 	state_save_register_device_item(device, 0, psg->register_latch);
859 	state_save_register_device_item_array(device, 0, psg->regs);
860 	state_save_register_device_item(device, 0, psg->last_enable);
861 
862 	state_save_register_device_item_array(device, 0, psg->count);
863 	state_save_register_device_item(device, 0, psg->count_noise);
864 	state_save_register_device_item(device, 0, psg->count_env);
865 
866 	state_save_register_device_item(device, 0, psg->env_volume);
867 
868 	state_save_register_device_item_array(device, 0, psg->output);
869 	state_save_register_device_item(device, 0, psg->output_noise);
870 
871 	state_save_register_device_item(device, 0, psg->env_step);
872 	state_save_register_device_item(device, 0, psg->hold);
873 	state_save_register_device_item(device, 0, psg->alternate);
874 	state_save_register_device_item(device, 0, psg->attack);
875 	state_save_register_device_item(device, 0, psg->holding);
876 	state_save_register_device_item(device, 0, psg->rng);
877 }*/
878 
879 /*************************************
880  *
881  * Public functions
882  *
883  *   used by e.g. YM2203, YM2210 ...
884  *
885  *************************************/
886 
887 //void *ay8910_start_ym(void *infoptr, sound_type chip_type, const device_config *device, int clock, const ay8910_interface *intf)
ay8910_start_ym(void * infoptr,unsigned char chip_type,int clock,const ay8910_interface * intf)888 void *ay8910_start_ym(void *infoptr, unsigned char chip_type, int clock, const ay8910_interface *intf)
889 {
890 	ay8910_context *info = (ay8910_context *)infoptr;
891 	int master_clock = clock;
892 	UINT8 CurChn;
893 
894 	if (info == NULL)
895 	{
896 		//info = auto_alloc_clear(device->machine, ay8910_context);
897 		info = (ay8910_context*)malloc(sizeof(ay8910_context));
898 		memset(info, 0x00, sizeof(ay8910_context));
899 	}
900 
901 	//info->device = device;
902 	info->intf = intf;
903 	info->SmpRateFunc = NULL;
904 	//devcb_resolve_read8(&info->portAread, &intf->portAread, device);
905 	//devcb_resolve_read8(&info->portBread, &intf->portBread, device);
906 	//devcb_resolve_write8(&info->portAwrite, &intf->portAwrite, device);
907 	//devcb_resolve_write8(&info->portBwrite, &intf->portBwrite, device);
908 	if ((info->intf->flags & AY8910_SINGLE_OUTPUT) != 0)
909 	{
910 #ifdef _DEBUG
911 		//logerror("AY-3-8910/YM2149 using single output!\n");
912 #endif
913 		//info->streams = 1;
914 		info->streams = 3;	// set to 3 to greatly speed up loading times
915 	}
916 	else
917 		info->streams = 3;
918 
919 	info->chip_type = chip_type;
920 	//if (chip_type == CHTYPE_AY8910 || chip_type == CHTYPE_AY8914 || chip_type == CHTYPE_AY8930)
921 	if ((chip_type & 0xF0) == 0x00)	// CHTYPE_AY89xx variants
922 	{
923 		info->step = 2;
924 		info->par = &ay8910_param;
925 		info->par_env = &ay8910_param;
926 		info->zero_is_off = 0;		/* FIXME: Remove after verification that off=vol(0) */
927 		info->env_step_mask = 0x0F;
928 	}
929 	else //if ((chip_type & 0xF0) == 0x10)	// CHTYPE_YMxxxx variants (also YM2203/2608/2610)
930 	{
931 		info->step = 1;
932 		info->par = &ym2149_param;
933 		info->par_env = &ym2149_param_env;
934 		info->zero_is_off = 0;
935 		info->env_step_mask = 0x1F;
936 
937 		/* YM2149 master clock divider? */
938 		if (info->intf->flags & YM2149_PIN26_LOW)
939 			master_clock /= 2;
940 	}
941 	if (intf->flags & AY8910_ZX_STEREO)
942 	{
943 		// ABC Stereo
944 		info->StereoMask[0] = 0x01;
945 		info->StereoMask[1] = 0x03;
946 		info->StereoMask[2] = 0x02;
947 	}
948 	else
949 	{
950 		info->StereoMask[0] = 0x03;
951 		info->StereoMask[1] = 0x03;
952 		info->StereoMask[2] = 0x03;
953 	}
954 
955 	build_mixer_table(info);
956 
957 	/* The envelope is pacing twice as fast for the YM2149 as for the AY-3-8910,    */
958 	/* This handled by the step parameter. Consequently we use a divider of 8 here. */
959 	//info->channel = stream_create(device, 0, info->streams, device->clock / 8, info, ay8910_update);
960 
961 	ay8910_set_clock_ym(info,clock);
962 	//ay8910_statesave(info, device);
963 
964 	for (CurChn = 0; CurChn < NUM_CHANNELS; CurChn ++)
965 		info->MuteMsk[CurChn] = 0;
966 
967 	return info;
968 }
969 
ay8910_stop_ym(void * chip)970 void ay8910_stop_ym(void *chip)
971 {
972 	free(chip);
973 }
974 
ay8910_reset_ym(void * chip)975 void ay8910_reset_ym(void *chip)
976 {
977 	ay8910_context *psg = (ay8910_context *)chip;
978 	int i;
979 
980 	psg->register_latch = 0;
981 	psg->rng = 1;
982 	psg->output[0] = 0;
983 	psg->output[1] = 0;
984 	psg->output[2] = 0;
985 	psg->count[0] = 0;
986 	psg->count[1] = 0;
987 	psg->count[2] = 0;
988 	psg->count_noise = 0;
989 	psg->count_env = 0;
990 	psg->prescale_noise = 0;
991 	psg->last_enable = -1;	/* force a write */
992 	for (i = 0;i < AY_PORTA;i++)
993 		ay8910_write_reg(psg,i,0);
994 	psg->ready = 1;
995 #if ENABLE_REGISTER_TEST
996 	ay8910_write_reg(psg, AY_AFINE, 0);
997 	ay8910_write_reg(psg, AY_ACOARSE, 1);
998 	ay8910_write_reg(psg, AY_BFINE, 0);
999 	ay8910_write_reg(psg, AY_BCOARSE, 2);
1000 	ay8910_write_reg(psg, AY_CFINE, 0);
1001 	ay8910_write_reg(psg, AY_CCOARSE, 4);
1002 	//#define AY_NOISEPER   (6)
1003 	ay8910_write_reg(psg, AY_ENABLE, ~7);
1004 	ay8910_write_reg(psg, AY_AVOL, 10);
1005 	ay8910_write_reg(psg, AY_BVOL, 10);
1006 	ay8910_write_reg(psg, AY_CVOL, 10);
1007 	//#define AY_EFINE  (11)
1008 	//#define AY_ECOARSE    (12)
1009 	//#define AY_ESHAPE (13)
1010 #endif
1011 	if (psg->chip_type & 0x20)
1012 		psg->IsDisabled = 0x01;
1013 }
1014 
1015 /*void ay8910_set_volume(UINT8 ChipID,int channel,int volume)
1016 {
1017 	//ay8910_context *psg = get_safe_token(device);
1018 	int ch;
1019 
1020 	for (ch = 0; ch < psg->streams; ch++)
1021 		if (channel == ch || psg->streams == 1 || channel == ALL_8910_CHANNELS)
1022 			stream_set_output_gain(psg->channel, ch, volume / 100.0);
1023 }*/
1024 
ay8910_set_clock_ym(void * chip,int clock)1025 void ay8910_set_clock_ym(void *chip, int clock)
1026 {
1027 	ay8910_context *psg = (ay8910_context *)chip;
1028 
1029 	if ((psg->chip_type & 0xF0) == 0x10 && (psg->intf->flags & YM2149_PIN26_LOW))
1030 		clock /= 2;
1031 
1032 	//stream_set_sample_rate(psg->channel, clock / 8 );
1033 	if (psg->SmpRateFunc != NULL)
1034 		psg->SmpRateFunc(psg->SmpRateData, clock / 8);
1035 
1036 	return;
1037 }
1038 
ay8910_write_ym(void * chip,int addr,int data)1039 void ay8910_write_ym(void *chip, int addr, int data)
1040 {
1041 	ay8910_context *psg = (ay8910_context *)chip;
1042 
1043 	if (addr & 1)
1044 	{	/* Data port */
1045 		int r = psg->register_latch;
1046 
1047 		if (r > 15) return;
1048 		if (r == AY_ESHAPE || psg->regs[r] != data)
1049 		{
1050 			/* update the output buffer before changing the register */
1051 			//stream_update(psg->channel);
1052 		}
1053 
1054 		ay8910_write_reg(psg,r,data);
1055 	}
1056 	else
1057 	{	/* Register port */
1058 		psg->register_latch = data & 0x0f;
1059 	}
1060 }
1061 
ay8910_read_ym(void * chip)1062 int ay8910_read_ym(void *chip)
1063 {
1064 	ay8910_context *psg = (ay8910_context *)chip;
1065 	int r = psg->register_latch;
1066 
1067 	if (r > 15) return 0;
1068 
1069 	/* There are no state dependent register in the AY8910! */
1070 	/* stream_update(psg->channel); */
1071 
1072 	switch (r)
1073 	{
1074 	case AY_PORTA:
1075 		//if ((psg->regs[AY_ENABLE] & 0x40) != 0)
1076 		//	logerror("warning: read from 8910 '%s' Port A set as output\n",psg->device->tag);
1077 		/*
1078            even if the port is set as output, we still need to return the external
1079            data. Some games, like kidniki, need this to work.
1080          */
1081 		/*if (psg->portAread.read)
1082 			psg->regs[AY_PORTA] = devcb_call_read8(&psg->portAread, 0);
1083 		else
1084 			logerror("%s: warning - read 8910 '%s' Port A\n",cpuexec_describe_context(psg->device->machine),psg->device->tag);*/
1085 		break;
1086 	case AY_PORTB:
1087 		//if ((psg->regs[AY_ENABLE] & 0x80) != 0)
1088 		//	logerror("warning: read from 8910 '%s' Port B set as output\n",psg->device->tag);
1089 		/*if (psg->portBread.read)
1090 			psg->regs[AY_PORTB] = devcb_call_read8(&psg->portBread, 0);
1091 		else
1092 			logerror("%s: warning - read 8910 '%s' Port B\n",cpuexec_describe_context(psg->device->machine),psg->device->tag);*/
1093 		break;
1094 	}
1095 
1096 	/* Depending on chip type, unused bits in registers may or may not be accessible.
1097 	Untested chips are assumed to regard them as 'ram'
1098 	Tested and confirmed on hardware:
1099 	- AY-3-8910: inaccessible bits (see masks below) read back as 0
1100 	- YM2149: no anomaly
1101 	*/
1102 	if (! (psg->chip_type & 0x10)) {
1103 		const UINT8 mask[0x10]={
1104 			0xff,0x0f,0xff,0x0f,0xff,0x0f,0x1f,0xff,0x1f,0x1f,0x1f,0xff,0xff,0x0f,0xff,0xff
1105 		};
1106 
1107 		return psg->regs[r] & mask[r];
1108 	}
1109 	else return psg->regs[r];
1110 }
1111 
1112 /*************************************
1113  *
1114  * Sound Interface
1115  *
1116  *************************************/
1117 
1118 //static DEVICE_START( ay8910 )
1119 /*int device_start_ay8910(UINT8 ChipID, int clock, unsigned char chip_type, unsigned char Flags)
1120 {
1121 	static const ay8910_interface generic_ay8910 =
1122 	{
1123 		AY8910_LEGACY_OUTPUT,
1124 		AY8910_DEFAULT_LOADS
1125 	};
1126 	//const ay8910_interface *intf = (device->static_config ? (const ay8910_interface *)device->static_config : &generic_ay8910);
1127 	ay8910_interface intf = generic_ay8910;
1128 	ay8910_context *psg;
1129 
1130 	if (ChipID >= MAX_CHIPS)
1131 		return 0;
1132 
1133 	psg = &AY8910Data[ChipID];
1134 	intf.flags = Flags;
1135 	ay8910_start_ym(psg, chip_type, clock, &intf);
1136 
1137 	return clock / 8;
1138 }*/
ay8910_start(void ** chip,int clock,UINT8 chip_type,UINT8 Flags)1139 int ay8910_start(void **chip, int clock, UINT8 chip_type, UINT8 Flags)
1140 {
1141 	static const ay8910_interface generic_ay8910 =
1142 	{
1143 		AY8910_LEGACY_OUTPUT,
1144 		AY8910_DEFAULT_LOADS
1145 	};
1146 	ay8910_interface intf = generic_ay8910;
1147 	ay8910_context *psg = (ay8910_context*)chip;
1148 
1149 	psg = (ay8910_context*)malloc(sizeof(ay8910_context));
1150 	if(psg == NULL)
1151 		return 0;
1152 	memset(psg, 0x00, sizeof(ay8910_context));
1153 	*chip = psg;
1154 
1155 	intf.flags = Flags;
1156 	ay8910_start_ym(psg, chip_type, clock, &intf);
1157 
1158 	if (Flags & YM2149_PIN26_LOW)
1159 		return clock / 16;
1160 	else
1161 		return clock / 8;
1162 }
1163 
1164 /*static DEVICE_START( ym2149 )
1165 {
1166 	static const ay8910_interface generic_ay8910 =
1167 	{
1168 		AY8910_LEGACY_OUTPUT,
1169 		AY8910_DEFAULT_LOADS,
1170 		DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL
1171 	};
1172 	const ay8910_interface *intf = (device->static_config ? (const ay8910_interface *)device->static_config : &generic_ay8910);
1173 	ay8910_start_ym(get_safe_token(device), SOUND_YM2149, device, device->clock, intf);
1174 }*/
1175 
1176 //static DEVICE_STOP( ay8910 )
1177 /*void device_stop_ay8910(UINT8 ChipID)
1178 {
1179 	ay8910_context *psg = &AY8910Data[ChipID];
1180 	ay8910_stop_ym(psg);
1181 }
1182 
1183 //static DEVICE_RESET( ay8910 )
1184 void device_reset_ay8910(UINT8 ChipID)
1185 {
1186 	ay8910_context *psg = &AY8910Data[ChipID];
1187 	ay8910_reset_ym(psg);
1188 }*/
1189 
1190 /*DEVICE_GET_INFO( ay8910 )
1191 {
1192 	switch (state)
1193 	{
1194 		// --- the following bits of info are returned as 64-bit signed integers ---
1195 		case DEVINFO_INT_TOKEN_BYTES:					info->i = sizeof(ay8910_context);				break;
1196 
1197 		// --- the following bits of info are returned as pointers to data or functions ---
1198 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ay8910 );			break;
1199 		case DEVINFO_FCT_STOP:							info->stop = DEVICE_STOP_NAME( ay8910 );			break;
1200 		case DEVINFO_FCT_RESET:							info->reset = DEVICE_RESET_NAME( ay8910 );			break;
1201 
1202 		// --- the following bits of info are returned as NULL-terminated strings ---
1203 		case DEVINFO_STR_NAME:							strcpy(info->s, "AY-3-8910A");					break;
1204 		case DEVINFO_STR_FAMILY:					strcpy(info->s, "PSG");							break;
1205 		case DEVINFO_STR_VERSION:					strcpy(info->s, "1.0");							break;
1206 		case DEVINFO_STR_SOURCE_FILE:						strcpy(info->s, __FILE__);						break;
1207 		case DEVINFO_STR_CREDITS:					strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
1208 	}
1209 }
1210 
1211 DEVICE_GET_INFO( ay8912 )
1212 {
1213 	switch (state)
1214 	{
1215 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ay8910 );			break;
1216 		case DEVINFO_STR_NAME:							strcpy(info->s, "AY-3-8912A");					break;
1217 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1218 	}
1219 }
1220 
1221 DEVICE_GET_INFO( ay8913 )
1222 {
1223 	switch (state)
1224 	{
1225 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ay8910 );			break;
1226 		case DEVINFO_STR_NAME:							strcpy(info->s, "AY-3-8913A");					break;
1227 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1228 	}
1229 }
1230 
1231 DEVICE_GET_INFO( ay8930 )
1232 {
1233 	switch (state)
1234 	{
1235 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ay8910 );			break;
1236 		case DEVINFO_STR_NAME:							strcpy(info->s, "AY8930");						break;
1237 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1238 	}
1239 }
1240 
1241 DEVICE_GET_INFO( ym2149 )
1242 {
1243 	switch (state)
1244 	{
1245 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ym2149 );			break;
1246 		case DEVINFO_STR_NAME:							strcpy(info->s, "YM2149");						break;
1247 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1248 	}
1249 }
1250 
1251 DEVICE_GET_INFO( ym3439 )
1252 {
1253 	switch (state)
1254 	{
1255 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ym2149 );			break;
1256 		case DEVINFO_STR_NAME:							strcpy(info->s, "YM3439");						break;
1257 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1258 	}
1259 }
1260 
1261 DEVICE_GET_INFO( ymz284 )
1262 {
1263 	switch (state)
1264 	{
1265 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ym2149 );			break;
1266 		case DEVINFO_STR_NAME:							strcpy(info->s, "YMZ284");						break;
1267 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1268 	}
1269 }
1270 
1271 DEVICE_GET_INFO( ymz294 )
1272 {
1273 	switch (state)
1274 	{
1275 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( ym2149 );			break;
1276 		case DEVINFO_STR_NAME:							strcpy(info->s, "YMZ294");						break;
1277 		default: 										DEVICE_GET_INFO_CALL(ay8910);						break;
1278 	}
1279 }*/
1280 
1281 /*************************************
1282  *
1283  * Read/Write Handlers
1284  *
1285  *************************************/
1286 
1287 //READ8_DEVICE_HANDLER( ay8910_r )
1288 /*UINT8 ay8910_r(UINT8 ChipID, offs_t offset)
1289 {
1290 	ay8910_context *psg = &AY8910Data[ChipID];
1291 	return ay8910_read_ym(psg);
1292 }
1293 
1294 //WRITE8_DEVICE_HANDLER( ay8910_data_address_w )
1295 void ay8910_data_address_w(UINT8 ChipID, offs_t offset, UINT8 data)
1296 {
1297 	ay8910_context *psg = &AY8910Data[ChipID];
1298 	// note that directly connecting BC1 to A0 puts data on 0 and address on 1
1299 	ay8910_write_ym(psg, ~offset & 1, data);
1300 }
1301 
1302 //WRITE8_DEVICE_HANDLER( ay8910_address_data_w )
1303 void ay8910_address_data_w(UINT8 ChipID, offs_t offset, UINT8 data)
1304 {
1305 	ay8910_context *psg = &AY8910Data[ChipID];
1306 	ay8910_write_ym(psg, offset & 1, data);
1307 }
1308 
1309 //WRITE8_DEVICE_HANDLER( ay8910_address_w )
1310 void ay8910_address_w(UINT8 ChipID, offs_t offset, UINT8 data)
1311 {
1312 #if ENABLE_REGISTER_TEST
1313 	return;
1314 #endif
1315 	ay8910_data_address_w(ChipID, 1, data);
1316 }
1317 
1318 //WRITE8_DEVICE_HANDLER( ay8910_data_w )
1319 void ay8910_data_w(UINT8 ChipID, offs_t offset, UINT8 data)
1320 {
1321 #if ENABLE_REGISTER_TEST
1322 	return;
1323 #endif
1324 	ay8910_data_address_w(ChipID, 0, data);
1325 }*/
1326 
1327 
ay8910_set_mute_mask_ym(void * chip,UINT32 MuteMask)1328 void ay8910_set_mute_mask_ym(void *chip, UINT32 MuteMask)
1329 {
1330 	ay8910_context *psg = (ay8910_context *)chip;
1331 	UINT8 CurChn;
1332 
1333 	for (CurChn = 0; CurChn < NUM_CHANNELS; CurChn ++)
1334 		psg->MuteMsk[CurChn] = (MuteMask & (1 << CurChn)) ? 0 : ~0;
1335 
1336 	return;
1337 }
1338 
1339 /*void ay8910_set_mute_mask(UINT8 ChipID, UINT32 MuteMask)
1340 {
1341 	ay8910_context *psg = &AY8910Data[ChipID];
1342 	ay8910_set_mute_mask_ym(psg, MuteMask);
1343 }*/
1344 
ay8910_set_srchg_cb_ym(void * chip,SRATE_CALLBACK CallbackFunc,void * DataPtr)1345 void ay8910_set_srchg_cb_ym(void *chip, SRATE_CALLBACK CallbackFunc, void* DataPtr)
1346 {
1347 	ay8910_context *info = (ay8910_context *)chip;
1348 
1349 	// set Sample Rate Change Callback routine
1350 	info->SmpRateFunc = CallbackFunc;
1351 	info->SmpRateData = DataPtr;
1352 
1353 	return;
1354 }
1355