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