1 /**********************************************************************************************
2 
3      Ensoniq ES5505/6 driver
4      by Aaron Giles
5 
6 Ensoniq OTIS - ES5505                                            Ensoniq OTTO - ES5506
7 
8   OTIS is a VLSI device designed in a 2 micron double metal        OTTO is a VLSI device designed in a 1.5 micron double metal
9    CMOS process. The device is the next generation of audio         CMOS process. The device is the next generation of audio
10    technology from ENSONIQ. This new chip achieves a new            technology from ENSONIQ. All calculations in the device are
11    level of audio fidelity performance. These improvements          made with at least 18-bit accuracy.
12    are achieved through the use of frequency interpolation
13    and on board real time digital filters. All calculations       The major features of OTTO are:
14    in the device are made with at least 16 bit accuracy.           - 68 pin PLCC package
15                                                                    - On chip real time digital filters
16  The major features of OTIS are:                                   - Frequency interpolation
17   - 48 Pin dual in line package                                    - 32 independent voices
18   - On chip real time digital filters                              - Loop start and stop posistions for each voice
19   - Frequency interpolation                                        - Bidirectional and reverse looping
20   - 32 independent voices (up from 25 in DOCII)                    - 68000 compatibility for asynchronous bus communication
21   - Loop start and stop positions for each voice                   - Seperate host and sound memory interface
22   - Bidirectional and reverse looping                              - 6 channel stereo serial communication port
23   - 68000 compatibility for asynchronous bus communication         - Programmable clocks for defining serial protocol
24   - On board pulse width modulation D to A                         - Internal volume multiplication and stereo panning
25   - 4 channel stereo serial communication port                     - A to D input for pots and wheels
26   - Internal volume multiplication and stereo panning              - Hardware support for envelopes
27   - A to D input for pots and wheels                               - Support for dual OTTO systems
28   - Up to 10MHz operation                                          - Optional compressed data format for sample data
29                                                                    - Up to 16MHz operation
30               ______    ______
31             _|o     \__/      |_
32  A17/D13 - |_|1             48|_| - VSS                                                           A A A A A A
33             _|                |_                                                                  2 1 1 1 1 1 A
34  A18/D14 - |_|2             47|_| - A16/D12                                                       0 9 8 7 6 5 1
35             _|                |_                                                                  / / / / / / 4
36  A19/D15 - |_|3             46|_| - A15/D11                                   H H H H H H H V V H D D D D D D /
37             _|                |_                                              D D D D D D D S D D 1 1 1 1 1 1 D
38       BS - |_|4             45|_| - A14/D10                                   0 1 2 3 4 5 6 S D 7 5 4 3 2 1 0 9
39             _|                |_                                             ------------------------------------+
40   PWZERO - |_|5             44|_| - A13/D9                                  / 9 8 7 6 5 4 3 2 1 6 6 6 6 6 6 6 6  |
41             _|                |_                                           /                    8 7 6 5 4 3 2 1  |
42     SER0 - |_|6             43|_| - A12/D8                                |                                      |
43             _|       E        |_                                      SER0|10                                  60|A13/D8
44     SER1 - |_|7      N      42|_| - A11/D7                            SER1|11                                  59|A12/D7
45             _|       S        |_                                      SER2|12                                  58|A11/D6
46     SER2 - |_|8      O      41|_| - A10/D6                            SER3|13              ENSONIQ             57|A10/D5
47             _|       N        |_                                      SER4|14                                  56|A9/D4
48     SER3 - |_|9      I      40|_| - A9/D5                             SER5|15                                  55|A8/D3
49             _|       Q        |_                                      WCLK|16                                  54|A7/D2
50  SERWCLK - |_|10            39|_| - A8/D4                            LRCLK|17               ES5506             53|A6/D1
51             _|                |_                                      BCLK|18                                  52|A5/D0
52    SERLR - |_|11            38|_| - A7/D3                             RESB|19                                  51|A4
53             _|                |_                                       HA5|20                                  50|A3
54  SERBCLK - |_|12     E      37|_| - A6/D2                              HA4|21                OTTO              49|A2
55             _|       S        |_                                       HA3|22                                  48|A1
56      RLO - |_|13     5      36|_| - A5/D1                              HA2|23                                  47|A0
57             _|       5        |_                                       HA1|24                                  46|BS1
58      RHI - |_|14     0      35|_| - A4/D0                              HA0|25                                  45|BS0
59             _|       5        |_                                    POT_IN|26                                  44|DTACKB
60      LLO - |_|15            34|_| - CLKIN                                 |   2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4  |
61             _|                |_                                          |   7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3  |
62      LHI - |_|16            33|_| - CAS                                   +--------------------------------------+
63             _|                |_                                              B E E B E B B D S B B B E K B W W
64      POT - |_|17     O      32|_| - AMUX                                      S B L N L S S D S S X S   L Q / /
65             _|       T        |_                                              E E R E H M C V V A U A   C R R R
66    DTACK - |_|18     I      31|_| - RAS                                       R R D H           R M C     I M
67             _|       S        |_                                              _ D                 A
68      R/W - |_|19            30|_| - E                                         T
69             _|                |_                                              O
70       MS - |_|20            29|_| - IRQ                                       P
71             _|                |_
72       CS - |_|21            28|_| - A3
73             _|                |_
74      RES - |_|22            27|_| - A2
75             _|                |_
76      VSS - |_|23            26|_| - A1
77             _|                |_
78      VDD - |_|24            25|_| - A0
79              |________________|
80 
81 ***********************************************************************************************/
82 
83 //
84 // FBAlpha notes: (Nov.21.2016)
85 //
86 //   ES5505Write() only supports 16bit writes.
87 //
88 
89 #include "burnint.h"
90 #include "es5506.h"
91 
92 
93 /**********************************************************************************************
94 
95      CONSTANTS
96 
97 ***********************************************************************************************/
98 
99 #define LOG_COMMANDS			0
100 #define RAINE_CHECK				0
101 #define MAKE_WAVS				0
102 
103 #if MAKE_WAVS
104 #include "wavwrite.h"
105 #endif
106 
107 #define ES5506_INLINE			static
108 #define ES5506				1
109 #define ES5505				2
110 
111 #define MAX_SAMPLE_CHUNK		10000
112 #define ULAW_MAXBITS			8
113 
114 #define CONTROL_BS1				0x8000
115 #define CONTROL_BS0				0x4000
116 #define CONTROL_CMPD			0x2000
117 #define CONTROL_CA2				0x1000
118 #define CONTROL_CA1				0x0800
119 #define CONTROL_CA0				0x0400
120 #define CONTROL_LP4				0x0200
121 #define CONTROL_LP3				0x0100
122 #define CONTROL_IRQ				0x0080
123 #define CONTROL_DIR				0x0040
124 #define CONTROL_IRQE			0x0020
125 #define CONTROL_BLE				0x0010
126 #define CONTROL_LPE				0x0008
127 #define CONTROL_LEI				0x0004
128 #define CONTROL_STOP1			0x0002
129 #define CONTROL_STOP0			0x0001
130 
131 #define CONTROL_BSMASK			(CONTROL_BS1 | CONTROL_BS0)
132 #define CONTROL_CAMASK			(CONTROL_CA2 | CONTROL_CA1 | CONTROL_CA0)
133 #define CONTROL_LPMASK			(CONTROL_LP4 | CONTROL_LP3)
134 #define CONTROL_LOOPMASK		(CONTROL_BLE | CONTROL_LPE)
135 #define CONTROL_STOPMASK		(CONTROL_STOP1 | CONTROL_STOP0)
136 
137 
138 
139 /**********************************************************************************************
140 
141      INTERNAL DATA STRUCTURES
142 
143 ***********************************************************************************************/
144 
145 /* struct describing a single playing voice */
146 typedef struct _es5506_voice es5506_voice;
147 struct _es5506_voice
148 {
149 	/* external state */
150 	UINT32		control;				/* control register */
151 	UINT32		freqcount;				/* frequency count register */
152 	UINT32		start;					/* start register */
153 	UINT32		lvol;					/* left volume register */
154 	UINT32		end;					/* end register */
155 	UINT32		lvramp;					/* left volume ramp register */
156 	UINT32		accum;					/* accumulator register */
157 	UINT32		rvol;					/* right volume register */
158 	UINT32		rvramp;					/* right volume ramp register */
159 	UINT32		ecount;					/* envelope count register */
160 	UINT32		k2;						/* k2 register */
161 	UINT32		k2ramp;					/* k2 ramp register */
162 	UINT32		k1;						/* k1 register */
163 	UINT32		k1ramp;					/* k1 ramp register */
164 	INT32		o4n1;					/* filter storage O4(n-1) */
165 	INT32		o3n1;					/* filter storage O3(n-1) */
166 	INT32		o3n2;					/* filter storage O3(n-2) */
167 	INT32		o2n1;					/* filter storage O2(n-1) */
168 	INT32		o2n2;					/* filter storage O2(n-2) */
169 	INT32		o1n1;					/* filter storage O1(n-1) */
170 	UINT32		exbank;					/* external address bank */
171 
172 	/* internal state */
173 	UINT8		index;					/* index of this voice */
174 	UINT8		filtcount;				/* filter count */
175 	UINT32		accum_mask;
176 };
177 
178 //typedef struct _es5506_state es5506_state;
179 struct _es5506_state
180 {
181 	INT32       chiptype;               // 5505 or 5506?
182 	INT32		sample_rate;			/* current sample rate */
183 	UINT16 *	region_base[4];			/* pointer to the base of the region */
184 	UINT32		write_latch;			/* currently accumulated data for write */
185 	UINT32		read_latch;				/* currently accumulated data for read */
186 	UINT32		master_clock;			/* master clock frequency */
187 	void		(*irq_callback)(INT32);	/* IRQ callback */
188 	UINT16		(*port_read)(void);		/* input port read */
189 
190 	UINT8		current_page;			/* current register page */
191 	UINT8		active_voices;			/* number of active voices */
192 	UINT8		mode;					/* MODE register */
193 	UINT8		wst;					/* W_ST register */
194 	UINT8		wend;					/* W_END register */
195 	UINT8		lrend;					/* LR_END register */
196 	UINT8		irqv;					/* IRQV register */
197 
198 	es5506_voice voice[32];				/* the 32 voices */
199 
200 	INT32 *		scratch;
201 
202 	INT16 *		ulaw_lookup;
203 	UINT16 *	volume_lookup;
204 //	device_t *device;
205 
206 	double volume[2];			/* set gain */
207 
208 #if MAKE_WAVS
209 	void *		wavraw;					/* raw waveform */
210 #endif
211 };
212 
213 static struct _es5506_state *chip = NULL;
214 
215 INT32 ES550X_twincobra2_pan_fix = 0;
216 
217 // for resampling
218 static UINT32 nSampleSize;
219 static INT32 nFractionalPosition;
220 static INT32 nPosition;
221 
222 
223 /**********************************************************************************************
224 
225      GLOBAL VARIABLES
226 
227 ***********************************************************************************************/
228 
229 static FILE *eslog;
230 
231 
232 
233 /**********************************************************************************************
234 
235      update_irq_state -- update the IRQ state
236 
237 ***********************************************************************************************/
238 
update_irq_state()239 static void update_irq_state()
240 {
241 	/* ES5505/6 irq line has been set high - inform the host */
242 	if (chip->irq_callback)
243 		(*chip->irq_callback)(1); /* IRQB set high */
244 }
245 
update_internal_irq_state()246 static void update_internal_irq_state()
247 {
248 	/*  Host (cpu) has just read the voice interrupt vector (voice IRQ ack).
249 
250         Reset the voice vector to show the IRQB line is low (top bit set).
251         If we have any stacked interrupts (other voices waiting to be
252         processed - with their IRQ bit set) then they will be moved into
253         the vector next time the voice is processed.  In emulation
254         terms they get updated next time generate_samples() is called.
255     */
256 
257 	chip->irqv=0x80;
258 	if (chip->irq_callback)
259 		(*chip->irq_callback)(0); /* IRQB set low */
260 }
261 
262 /**********************************************************************************************
263 
264      compute_tables -- compute static tables
265 
266 ***********************************************************************************************/
267 
compute_tables()268 static void compute_tables()
269 {
270 	INT32 i;
271 
272 	/* allocate ulaw lookup table */
273 	//chip->ulaw_lookup = auto_alloc_array(chip->device->machine, INT16, 1 << ULAW_MAXBITS);
274 	chip->ulaw_lookup = (INT16*)BurnMalloc((1 << ULAW_MAXBITS) * sizeof(INT16));
275 
276 	/* generate ulaw lookup table */
277 	for (i = 0; i < (1 << ULAW_MAXBITS); i++)
278 	{
279 		UINT16 rawval = (i << (16 - ULAW_MAXBITS)) | (1 << (15 - ULAW_MAXBITS));
280 		UINT8 exponent = rawval >> 13;
281 		UINT32 mantissa = (rawval << 3) & 0xffff;
282 
283 		if (exponent == 0)
284 			chip->ulaw_lookup[i] = (INT16)mantissa >> 7;
285 		else
286 		{
287 			mantissa = (mantissa >> 1) | (~mantissa & 0x8000);
288 			chip->ulaw_lookup[i] = (INT16)mantissa >> (7 - exponent);
289 		}
290 	}
291 
292 	/* allocate volume lookup table */
293 	//chip->volume_lookup = auto_alloc_array(chip->device->machine, UINT16, 4096);
294 	chip->volume_lookup = (UINT16*)BurnMalloc(4096 * sizeof(UINT16));
295 
296 	/* generate volume lookup table */
297 	for (i = 0; i < 4096; i++)
298 	{
299 		UINT8 exponent = i >> 8;
300 		UINT32 mantissa = (i & 0xff) | 0x100;
301 
302 		chip->volume_lookup[i] = (mantissa << 11) >> (20 - exponent);
303 	}
304 }
305 
306 
307 
308 /**********************************************************************************************
309 
310      interpolate -- interpolate between two samples
311 
312 ***********************************************************************************************/
313 
314 #define interpolate(sample1, sample2, accum)								\
315 		(sample1 * (INT32)(0x800 - (accum & 0x7ff)) +						\
316 		 sample2 * (INT32)(accum & 0x7ff)) >> 11;
317 
318 
319 
320 /**********************************************************************************************
321 
322      apply_filters -- apply the 4-pole digital filter to the sample
323 
324 ***********************************************************************************************/
325 
326 #define apply_filters(voice, sample)															\
327 do																								\
328 {																								\
329 	/* pole 1 is always low-pass using K1 */													\
330 	sample = ((INT32)(voice->k1 >> 2) * (sample - voice->o1n1) / 16384) + voice->o1n1;			\
331 	voice->o1n1 = sample;																		\
332 																								\
333 	/* pole 2 is always low-pass using K1 */													\
334 	sample = ((INT32)(voice->k1 >> 2) * (sample - voice->o2n1) / 16384) + voice->o2n1;			\
335 	voice->o2n2 = voice->o2n1;																	\
336 	voice->o2n1 = sample;																		\
337 																								\
338 	/* remaining poles depend on the current filter setting */									\
339 	switch (voice->control & CONTROL_LPMASK)													\
340 	{																							\
341 		case 0:																					\
342 			/* pole 3 is high-pass using K2 */													\
343 			sample = sample - voice->o2n2 + ((INT32)(voice->k2 >> 2) * voice->o3n1) / 32768 + voice->o3n1 / 2; \
344 			voice->o3n2 = voice->o3n1;															\
345 			voice->o3n1 = sample;																\
346 																								\
347 			/* pole 4 is high-pass using K2 */													\
348 			sample = sample - voice->o3n2 + ((INT32)(voice->k2 >> 2) * voice->o4n1) / 32768 + voice->o4n1 / 2; \
349 			voice->o4n1 = sample;																\
350 			break;																				\
351 																								\
352 		case CONTROL_LP3:																		\
353 			/* pole 3 is low-pass using K1 */													\
354 			sample = ((INT32)(voice->k1 >> 2) * (sample - voice->o3n1) / 16384) + voice->o3n1;	\
355 			voice->o3n2 = voice->o3n1;															\
356 			voice->o3n1 = sample;																\
357 																								\
358 			/* pole 4 is high-pass using K2 */													\
359 			sample = sample - voice->o3n2 + ((INT32)(voice->k2 >> 2) * voice->o4n1) / 32768 + voice->o4n1 / 2; \
360 			voice->o4n1 = sample;																\
361 			break;																				\
362 																								\
363 		case CONTROL_LP4:																		\
364 			/* pole 3 is low-pass using K2 */													\
365 			sample = ((INT32)(voice->k2 >> 2) * (sample - voice->o3n1) / 16384) + voice->o3n1;	\
366 			voice->o3n2 = voice->o3n1;															\
367 			voice->o3n1 = sample;																\
368 																								\
369 			/* pole 4 is low-pass using K2 */													\
370 			sample = ((INT32)(voice->k2 >> 2) * (sample - voice->o4n1) / 16384) + voice->o4n1;	\
371 			voice->o4n1 = sample;																\
372 			break;																				\
373 																								\
374 		case CONTROL_LP4 | CONTROL_LP3:															\
375 			/* pole 3 is low-pass using K1 */													\
376 			sample = ((INT32)(voice->k1 >> 2) * (sample - voice->o3n1) / 16384) + voice->o3n1;	\
377 			voice->o3n2 = voice->o3n1;															\
378 			voice->o3n1 = sample;																\
379 																								\
380 			/* pole 4 is low-pass using K2 */													\
381 			sample = ((INT32)(voice->k2 >> 2) * (sample - voice->o4n1) / 16384) + voice->o4n1;	\
382 			voice->o4n1 = sample;																\
383 			break;																				\
384 	}																							\
385 } while (0)
386 
387 
388 
389 /**********************************************************************************************
390 
391      update_envelopes -- update the envelopes
392 
393 ***********************************************************************************************/
394 
395 #define update_envelopes(voice, samples)											\
396 do																					\
397 {																					\
398 	INT32 count = (samples > 1 && samples > (INT32)voice->ecount) ? voice->ecount : samples;	\
399 																					\
400 	/* decrement the envelope counter */											\
401 	voice->ecount -= count;															\
402 																					\
403 	/* ramp left volume */															\
404 	if (voice->lvramp)																\
405 	{																				\
406 		voice->lvol += (INT8)voice->lvramp * count;									\
407 		if ((INT32)voice->lvol < 0) voice->lvol = 0;								\
408 		else if (voice->lvol > 0xffff) voice->lvol = 0xffff;						\
409 	}																				\
410 																					\
411 	/* ramp right volume */															\
412 	if (voice->rvramp)																\
413 	{																				\
414 		voice->rvol += (INT8)voice->rvramp * count;									\
415 		if ((INT32)voice->rvol < 0) voice->rvol = 0;								\
416 		else if (voice->rvol > 0xffff) voice->rvol = 0xffff;						\
417 	}																				\
418 																					\
419 	/* ramp k1 filter constant */													\
420 	if (voice->k1ramp && ((INT32)voice->k1ramp >= 0 || !(voice->filtcount & 7)))	\
421 	{																				\
422 		voice->k1 += (INT8)voice->k1ramp * count;									\
423 		if ((INT32)voice->k1 < 0) voice->k1 = 0;									\
424 		else if (voice->k1 > 0xffff) voice->k1 = 0xffff;							\
425 	}																				\
426 																					\
427 	/* ramp k2 filter constant */													\
428 	if (voice->k2ramp && ((INT32)voice->k2ramp >= 0 || !(voice->filtcount & 7)))	\
429 	{																				\
430 		voice->k2 += (INT8)voice->k2ramp * count;									\
431 		if ((INT32)voice->k2 < 0) voice->k2 = 0;									\
432 		else if (voice->k2 > 0xffff) voice->k2 = 0xffff;							\
433 	}																				\
434 																					\
435 	/* update the filter constant counter */										\
436 	voice->filtcount += count;														\
437 																					\
438 } while (0)
439 
440 
441 
442 /**********************************************************************************************
443 
444      check_for_end_forward
445      check_for_end_reverse -- check for loop end and loop appropriately
446 
447 ***********************************************************************************************/
448 
449 #define check_for_end_forward(voice, accum)											\
450 do																					\
451 {																					\
452 	/* are we past the end? */														\
453 	if (accum > voice->end && !(voice->control & CONTROL_LEI))						\
454 	{																				\
455 		/* generate interrupt if required */										\
456 		if (voice->control&CONTROL_IRQE)											\
457 			voice->control |= CONTROL_IRQ;											\
458 																					\
459 		/* handle the different types of looping */									\
460 		switch (voice->control & CONTROL_LOOPMASK)									\
461 		{																			\
462 			/* non-looping */														\
463 			case 0:																	\
464 				voice->control |= CONTROL_STOP0;									\
465 				goto alldone;														\
466 																					\
467 			/* uni-directional looping */											\
468 			case CONTROL_LPE:														\
469 				accum = (voice->start + (accum - voice->end)) & voice->accum_mask;	\
470 				break;																\
471 																					\
472 			/* trans-wave looping */												\
473 			case CONTROL_BLE:														\
474 				accum = (voice->start + (accum - voice->end)) & voice->accum_mask;	\
475 				voice->control = (voice->control & ~CONTROL_LOOPMASK) | CONTROL_LEI;\
476 				break;																\
477 																					\
478 			/* bi-directional looping */											\
479 			case CONTROL_LPE | CONTROL_BLE:											\
480 				accum = (voice->end - (accum - voice->end)) & voice->accum_mask;	\
481 				voice->control ^= CONTROL_DIR;										\
482 				goto reverse;														\
483 		}																			\
484 	}																				\
485 } while (0)
486 
487 
488 #define check_for_end_reverse(voice, accum)											\
489 do																					\
490 {																					\
491 	/* are we past the end? */														\
492 	if (accum < voice->start && !(voice->control & CONTROL_LEI))					\
493 	{																				\
494 		/* generate interrupt if required */										\
495 		if (voice->control&CONTROL_IRQE)											\
496 			voice->control |= CONTROL_IRQ;											\
497 																					\
498 		/* handle the different types of looping */									\
499 		switch (voice->control & CONTROL_LOOPMASK)									\
500 		{																			\
501 			/* non-looping */														\
502 			case 0:																	\
503 				voice->control |= CONTROL_STOP0;									\
504 				goto alldone;														\
505 																					\
506 			/* uni-directional looping */											\
507 			case CONTROL_LPE:														\
508 				accum = (voice->end - (voice->start - accum)) & voice->accum_mask;	\
509 				break;																\
510 																					\
511 			/* trans-wave looping */												\
512 			case CONTROL_BLE:														\
513 				accum = (voice->end - (voice->start - accum)) & voice->accum_mask;	\
514 				voice->control = (voice->control & ~CONTROL_LOOPMASK) | CONTROL_LEI;\
515 				break;																\
516 																					\
517 			/* bi-directional looping */											\
518 			case CONTROL_LPE | CONTROL_BLE:											\
519 				accum = (voice->start + (voice->start - accum)) & voice->accum_mask;\
520 				voice->control ^= CONTROL_DIR;										\
521 				goto reverse;														\
522 		}																			\
523 	}																				\
524 } while (0)
525 
526 
527 
528 /**********************************************************************************************
529 
530      generate_dummy -- generate nothing, just apply envelopes
531 
532 ***********************************************************************************************/
533 
generate_dummy(es5506_voice * voice,UINT16 *,INT32 *,INT32 *,INT32 samples)534 static void generate_dummy(es5506_voice *voice, UINT16 *, INT32 *, INT32 *, INT32 samples)
535 {
536 	UINT32 freqcount = voice->freqcount;
537 	UINT32 accum = voice->accum & voice->accum_mask;
538 
539 	/* outer loop, in case we switch directions */
540 	while (samples > 0 && !(voice->control & CONTROL_STOPMASK))
541 	{
542 reverse:
543 		/* two cases: first case is forward direction */
544 		if (!(voice->control & CONTROL_DIR))
545 		{
546 			/* loop while we still have samples to generate */
547 			while (samples--)
548 			{
549 				/* fetch two samples */
550 				accum = (accum + freqcount) & voice->accum_mask;
551 
552 				/* update filters/volumes */
553 				if (voice->ecount != 0)
554 					update_envelopes(voice, 1);
555 
556 				/* check for loop end */
557 				check_for_end_forward(voice, accum);
558 			}
559 		}
560 
561 		/* two cases: second case is backward direction */
562 		else
563 		{
564 			/* loop while we still have samples to generate */
565 			while (samples--)
566 			{
567 				/* fetch two samples */
568 				accum = (accum - freqcount) & voice->accum_mask;
569 
570 				/* update filters/volumes */
571 				if (voice->ecount != 0)
572 					update_envelopes(voice, 1);
573 
574 				/* check for loop end */
575 				check_for_end_reverse(voice, accum);
576 			}
577 		}
578 	}
579 
580 	/* if we stopped, process any additional envelope */
581 alldone:
582 	voice->accum = accum;
583 	if (samples > 0)
584 		update_envelopes(voice, samples);
585 }
586 
587 
588 
589 /**********************************************************************************************
590 
591      generate_ulaw -- general u-law decoding routine
592 
593 ***********************************************************************************************/
594 
generate_ulaw(es5506_voice * voice,UINT16 * base,INT32 * lbuffer,INT32 * rbuffer,INT32 samples)595 static void generate_ulaw(es5506_voice *voice, UINT16 *base, INT32 *lbuffer, INT32 *rbuffer, INT32 samples)
596 {
597 	UINT32 freqcount = voice->freqcount;
598 	UINT32 accum = voice->accum & voice->accum_mask;
599 	INT32 lvol = chip->volume_lookup[voice->lvol >> 4];
600 	INT32 rvol = chip->volume_lookup[voice->rvol >> 4];
601 
602 	//bprintf(PRINT_NORMAL, _T("ULAW\n"));
603 
604 	/* pre-add the bank offset */
605 	base += voice->exbank;
606 
607 	/* outer loop, in case we switch directions */
608 	while (samples > 0 && !(voice->control & CONTROL_STOPMASK))
609 	{
610 reverse:
611 		/* two cases: first case is forward direction */
612 		if (!(voice->control & CONTROL_DIR))
613 		{
614 			/* loop while we still have samples to generate */
615 			while (samples--)
616 			{
617 				/* fetch two samples */
618 				INT32 val1 = base[accum >> 11];
619 				INT32 val2 = base[((accum + (1 << 11)) & voice->accum_mask) >> 11];
620 
621 				/* decompress u-law */
622 				val1 = chip->ulaw_lookup[val1 >> (16 - ULAW_MAXBITS)];
623 				val2 = chip->ulaw_lookup[val2 >> (16 - ULAW_MAXBITS)];
624 
625 				/* interpolate */
626 				val1 = interpolate(val1, val2, accum);
627 				accum = (accum + freqcount) & voice->accum_mask;
628 
629 				/* apply filters */
630 				apply_filters(voice, val1);
631 
632 				/* update filters/volumes */
633 				if (voice->ecount != 0)
634 				{
635 					update_envelopes(voice, 1);
636 					lvol = chip->volume_lookup[voice->lvol >> 4];
637 					rvol = chip->volume_lookup[voice->rvol >> 4];
638 				}
639 
640 				/* apply volumes and add */
641 				*lbuffer++ += (val1 * lvol) >> 11;
642 				*rbuffer++ += (val1 * rvol) >> 11;
643 
644 				/* check for loop end */
645 				check_for_end_forward(voice, accum);
646 			}
647 		}
648 
649 		/* two cases: second case is backward direction */
650 		else
651 		{
652 			/* loop while we still have samples to generate */
653 			while (samples--)
654 			{
655 				/* fetch two samples */
656 				INT32 val1 = base[accum >> 11];
657 				INT32 val2 = base[((accum + (1 << 11)) & voice->accum_mask) >> 11];
658 
659 				/* decompress u-law */
660 				val1 = chip->ulaw_lookup[val1 >> (16 - ULAW_MAXBITS)];
661 				val2 = chip->ulaw_lookup[val2 >> (16 - ULAW_MAXBITS)];
662 
663 				/* interpolate */
664 				val1 = interpolate(val1, val2, accum);
665 				accum = (accum - freqcount) & voice->accum_mask;
666 
667 				/* apply filters */
668 				apply_filters(voice, val1);
669 
670 				/* update filters/volumes */
671 				if (voice->ecount != 0)
672 				{
673 					update_envelopes(voice, 1);
674 					lvol = chip->volume_lookup[voice->lvol >> 4];
675 					rvol = chip->volume_lookup[voice->rvol >> 4];
676 				}
677 
678 				/* apply volumes and add */
679 				*lbuffer++ += (val1 * lvol) >> 11;
680 				*rbuffer++ += (val1 * rvol) >> 11;
681 
682 				/* check for loop end */
683 				check_for_end_reverse(voice, accum);
684 			}
685 		}
686 	}
687 
688 	/* if we stopped, process any additional envelope */
689 alldone:
690 	voice->accum = accum;
691 	if (samples > 0)
692 		update_envelopes(voice, samples);
693 }
694 
695 
696 
697 /**********************************************************************************************
698 
699      generate_pcm -- general PCM decoding routine
700 
701 ***********************************************************************************************/
702 
703 #define twincobra2_check() { \
704 	    if (ES550X_twincobra2_pan_fix && lvol > 0x100 && rvol < 7) \
705 	    rvol = lvol; \
706 	}
707 
generate_pcm(es5506_voice * voice,UINT16 * base,INT32 * lbuffer,INT32 * rbuffer,INT32 samples)708 static void generate_pcm(es5506_voice *voice, UINT16 *base, INT32 *lbuffer, INT32 *rbuffer, INT32 samples)
709 {
710 	UINT32 freqcount = voice->freqcount;
711 	UINT32 accum = voice->accum & voice->accum_mask;
712 	INT32 lvol = chip->volume_lookup[voice->lvol >> 4];
713 	INT32 rvol = chip->volume_lookup[voice->rvol >> 4];
714 
715 	//bprintf(PRINT_NORMAL, _T("PCM, %x, %x, %x\n"), lvol, rvol, voice->control & CONTROL_STOPMASK);
716 
717 	twincobra2_check();
718 
719 	/* pre-add the bank offset */
720 	base += voice->exbank;
721 
722 	/* outer loop, in case we switch directions */
723 	while (samples > 0 && !(voice->control & CONTROL_STOPMASK))
724 	{
725 reverse:
726 		/* two cases: first case is forward direction */
727 		if (!(voice->control & CONTROL_DIR))
728 		{
729 			/* loop while we still have samples to generate */
730 			while (samples--)
731 			{
732 				/* fetch two samples */
733 				INT32 val1 = (INT16)base[accum >> 11];
734 				INT32 val2 = (INT16)base[((accum + (1 << 11)) & voice->accum_mask) >> 11];
735 
736 				/* interpolate */
737 				val1 = interpolate(val1, val2, accum);
738 				accum = (accum + freqcount) & voice->accum_mask;
739 
740 				/* apply filters */
741 				apply_filters(voice, val1);
742 
743 				/* update filters/volumes */
744 				if (voice->ecount != 0)
745 				{
746 					update_envelopes(voice, 1);
747 					lvol = chip->volume_lookup[voice->lvol >> 4];
748 					rvol = chip->volume_lookup[voice->rvol >> 4];
749 					twincobra2_check();
750 				}
751 
752 				/* apply volumes and add */
753 				*lbuffer++ += (val1 * lvol) >> 11;
754 				*rbuffer++ += (val1 * rvol) >> 11;
755 
756 				/* check for loop end */
757 				check_for_end_forward(voice, accum);
758 			}
759 		}
760 
761 		/* two cases: second case is backward direction */
762 		else
763 		{
764 			/* loop while we still have samples to generate */
765 			while (samples--)
766 			{
767 				/* fetch two samples */
768 				INT32 val1 = (INT16)base[accum >> 11];
769 				INT32 val2 = (INT16)base[((accum + (1 << 11)) & voice->accum_mask) >> 11];
770 
771 				/* interpolate */
772 				val1 = interpolate(val1, val2, accum);
773 				accum = (accum - freqcount) & voice->accum_mask;
774 
775 				/* apply filters */
776 				apply_filters(voice, val1);
777 
778 				/* update filters/volumes */
779 				if (voice->ecount != 0)
780 				{
781 					update_envelopes(voice, 1);
782 					lvol = chip->volume_lookup[voice->lvol >> 4];
783 					rvol = chip->volume_lookup[voice->rvol >> 4];
784 					twincobra2_check();
785 				}
786 
787 				/* apply volumes and add */
788 				*lbuffer++ += (val1 * lvol) >> 11;
789 				*rbuffer++ += (val1 * rvol) >> 11;
790 
791 				/* check for loop end */
792 				check_for_end_reverse(voice, accum);
793 			}
794 		}
795 	}
796 
797 	/* if we stopped, process any additional envelope */
798 alldone:
799 	voice->accum = accum;
800 	if (samples > 0)
801 		update_envelopes(voice, samples);
802 }
803 
804 
805 
806 /**********************************************************************************************
807 
808      generate_samples -- tell each voice to generate samples
809 
810 ***********************************************************************************************/
811 
generate_samples(INT32 * left,INT32 * right,INT32 samples)812 static void generate_samples(INT32 *left, INT32 *right, INT32 samples)
813 {
814 	INT32 v;
815 
816 	/* skip if nothing to do */
817 	if (!samples)
818 		return;
819 
820 	/* clear out the accumulator */
821 	memset(left, 0, samples * sizeof(left[0]));
822 	memset(right, 0, samples * sizeof(right[0]));
823 
824 	/* loop over voices */
825 	for (v = 0; v <= chip->active_voices; v++)
826 	{
827 		es5506_voice *voice = &chip->voice[v];
828 		UINT16 *base = chip->region_base[voice->control >> 14];
829 
830 		/* special case: if end == start, stop the voice */
831 		if (voice->start == voice->end)
832 			voice->control |= CONTROL_STOP0;
833 
834 		/* generate from the appropriate source */
835 		if (!base)
836 		{
837 			//logerror("NULL region base %d\n",voice->control >> 14);
838 			generate_dummy(voice, base, left, right, samples);
839 		}
840 		else if (voice->control & 0x2000)
841 			generate_ulaw(voice, base, left, right, samples);
842 		else
843 			generate_pcm(voice, base, left, right, samples);
844 
845 		/* does this voice have it's IRQ bit raised? */
846 		if (voice->control&CONTROL_IRQ)
847 		{
848 			//logerror("IRQ raised on voice %d!!\n",v);
849 			/* only update voice vector if existing IRQ is acked by host */
850 			if (chip->irqv&0x80)
851 			{
852 				/* latch voice number into vector, and set high bit low */
853 				chip->irqv=v&0x7f;
854 
855 				/* take down IRQ bit on voice */
856 				voice->control&=~CONTROL_IRQ;
857 
858 				/* inform host of irq */
859 				update_irq_state();
860 			}
861 		}
862 	}
863 }
864 
865 
866 /**********************************************************************************************
867 
868      es5506_update -- update the sound chip so that it is in sync with CPU execution
869 
870 ***********************************************************************************************/
871 
ES5506Update(INT16 * outputs,INT32 samples_len)872 void ES5506Update(INT16 *outputs, INT32 samples_len)
873 {
874 #if defined FBA_DEBUG
875 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506Update called without init\n"));
876 #endif
877 
878 	if (samples_len != nBurnSoundLen) {
879 		bprintf(0, _T("ES550XUpdate(): once per frame, please!\n"));
880 		return;
881 	}
882 
883 #if 0
884 	if (chip->sample_rate == 0) { // probably not needed.. but try if garbage sound issues during boot (before chip->sample_rate is set)
885 		memset(outputs, 0, nBurnSoundLen * 2 * sizeof(INT16));
886 		return;
887 	}
888 #endif
889 
890 	INT32 nSamplesNeeded = ((((((chip->sample_rate * 1000) / nBurnFPS) * samples_len) / nBurnSoundLen)) / 10) + 1;
891 	if (nBurnSoundRate < 44100) nSamplesNeeded += 2; // so we don't end up with negative nPosition below
892 
893 	/* determine left/right source data */
894 	INT32 *lsrc = chip->scratch + 0    + 5 + nPosition;
895 	INT32 *rsrc = chip->scratch + 4096 + 5 + nPosition;
896 
897 	generate_samples(lsrc, rsrc, nSamplesNeeded - nPosition);
898 
899 	INT32 *pBufL = chip->scratch + 0    + 5;
900 	INT32 *pBufR = chip->scratch + 4096 + 5;
901 
902 	for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < (samples_len << 1); i += 2, nFractionalPosition += nSampleSize) {
903 		INT32 nLeftSample[4] = {0, 0, 0, 0};
904 		INT32 nRightSample[4] = {0, 0, 0, 0};
905 		INT32 nTotalLeftSample, nTotalRightSample;
906 
907 		nLeftSample[0] += (INT32)(pBufL[(nFractionalPosition >> 16) - 3]);
908 		nLeftSample[1] += (INT32)(pBufL[(nFractionalPosition >> 16) - 2]);
909 		nLeftSample[2] += (INT32)(pBufL[(nFractionalPosition >> 16) - 1]);
910 		nLeftSample[3] += (INT32)(pBufL[(nFractionalPosition >> 16) - 0]);
911 
912 		nRightSample[0] += (INT32)(pBufR[(nFractionalPosition >> 16) - 3]);
913 		nRightSample[1] += (INT32)(pBufR[(nFractionalPosition >> 16) - 2]);
914 		nRightSample[2] += (INT32)(pBufR[(nFractionalPosition >> 16) - 1]);
915 		nRightSample[3] += (INT32)(pBufR[(nFractionalPosition >> 16) - 0]);
916 
917 		nTotalLeftSample  = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0] >> 4, nLeftSample[1] >> 4, nLeftSample[2] >> 4, nLeftSample[3] >> 4);
918 		nTotalRightSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nRightSample[0] >> 4, nRightSample[1] >> 4, nRightSample[2] >> 4, nRightSample[3] >> 4);
919 
920 		outputs[i + 0] = BURN_SND_CLIP(nTotalLeftSample * chip->volume[0]);
921 		outputs[i + 1] = BURN_SND_CLIP(nTotalRightSample * chip->volume[1]);
922 	}
923 
924 	if (samples_len >= nBurnSoundLen) {
925 		INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition >> 16);
926 
927 		for (INT32 i = -4; i < nExtraSamples; i++) {
928 			pBufL[i] = pBufL[(nFractionalPosition >> 16) + i];
929 			pBufR[i] = pBufR[(nFractionalPosition >> 16) + i];
930 		}
931 
932 		nFractionalPosition &= 0xFFFF;
933 
934 		nPosition = nExtraSamples;
935 	}
936 }
937 
938 
939 /**********************************************************************************************
940 
941      DEVICE_START( es5506 ) -- start emulation of the ES5506
942 
943 ***********************************************************************************************/
944 
init_voices()945 static void init_voices()
946 {
947 	/* init the voices */
948 	UINT32 accum_mask = (chip->chiptype == ES5506) ? 0xffffffff : 0x7fffffff;
949 
950 	for (INT32 j = 0; j < 32; j++)
951 	{
952 		chip->voice[j].index = j;
953 		chip->voice[j].control = CONTROL_STOPMASK;
954 		chip->voice[j].lvol = 0xffff;
955 		chip->voice[j].rvol = 0xffff;
956 		chip->voice[j].exbank = 0;
957 		chip->voice[j].accum_mask = accum_mask;
958 	}
959 }
960 
es5506_start_common(INT32 clock,UINT8 * region0,UINT8 * region1,UINT8 * region2,UINT8 * region3,irq_callback callback,INT32 sndtype)961 static void es5506_start_common(INT32 clock, UINT8* region0, UINT8* region1, UINT8* region2, UINT8* region3, irq_callback callback, INT32 sndtype)
962 {
963 	DebugSnd_ES5506Initted = 1;
964 
965 	/* debugging */
966 	if (LOG_COMMANDS && !eslog)
967 		eslog = fopen("es.log", "w");
968 
969 	/* create the struct */
970 	chip = (struct _es5506_state*)BurnMalloc(sizeof(_es5506_state));
971 	memset(chip, 0, sizeof(_es5506_state));
972 
973 	chip->chiptype = sndtype;
974 
975 	/* initialize the regions */
976 	chip->region_base[0] = region0 ? (UINT16 *)region0 : NULL;
977 	chip->region_base[1] = region1 ? (UINT16 *)region1 : NULL;
978 	chip->region_base[2] = region2 ? (UINT16 *)region2 : NULL;
979 	chip->region_base[3] = region3 ? (UINT16 *)region3 : NULL;
980 
981 	/* initialize the rest of the structure */
982 	chip->master_clock = clock;
983 	chip->irq_callback = callback;
984 	chip->irqv = 0x80;
985 
986 	/* compute the tables */
987 	compute_tables();
988 
989 	// init voices. also used in reset()!
990 	init_voices();
991 
992 	/* allocate memory */
993 	chip->scratch = (INT32*)BurnMalloc(2 * MAX_SAMPLE_CHUNK * sizeof(INT32));
994 	memset(chip->scratch, 0, 2 * MAX_SAMPLE_CHUNK * sizeof(INT32));
995 
996 	/* set volume */
997 	chip->volume[0] = 1.00;
998 	chip->volume[1] = 1.00;
999 
1000 	// for resampling
1001 	nSampleSize = 0; //(UINT32)m_sample_rate * (1 << 16) / nBurnSoundRate;
1002 	nFractionalPosition = 0;
1003 	nPosition = 0;
1004 
1005 	ES550X_twincobra2_pan_fix = 0; // this can be set after init.
1006 
1007 	/* success */
1008 }
1009 
1010 
ES5506Init(INT32 clock,UINT8 * region0,UINT8 * region1,UINT8 * region2,UINT8 * region3,irq_callback callback)1011 void ES5506Init(INT32 clock, UINT8* region0, UINT8* region1, UINT8* region2, UINT8* region3, irq_callback callback)
1012 {
1013 	es5506_start_common(clock, region0, region1, region2, region3, callback, ES5506);
1014 }
1015 
ES5506Scan(INT32 nAction,INT32 * pnMin)1016 void ES5506Scan(INT32 nAction, INT32* pnMin)
1017 {
1018 #if defined FBA_DEBUG
1019 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506Scan called without init\n"));
1020 #endif
1021 
1022 	if (nAction & ACB_DRIVER_DATA) {
1023 		SCAN_VAR(chip->sample_rate);
1024 		SCAN_VAR(chip->write_latch);
1025 		SCAN_VAR(chip->read_latch);
1026 		SCAN_VAR(chip->current_page);
1027 		SCAN_VAR(chip->active_voices);
1028 		SCAN_VAR(chip->mode);
1029 		SCAN_VAR(chip->wst);
1030 		SCAN_VAR(chip->wend);
1031 		SCAN_VAR(chip->lrend);
1032 		SCAN_VAR(chip->irqv);
1033 		SCAN_VAR(chip->voice);
1034 	}
1035 
1036 	if (nAction & ACB_WRITE) {
1037 		nFractionalPosition = 0;
1038 		nPosition = 0;
1039 		nSampleSize = (UINT32)chip->sample_rate * (1 << 16) / nBurnSoundRate;
1040 		memset(chip->scratch, 0, 2 * MAX_SAMPLE_CHUNK * sizeof(INT32));
1041 	}
1042 }
1043 
1044 // Some games (Taito F3) change the l/r volume in-game, this is for them
ES5506ScanRoutes(INT32 nAction,INT32 * pnMin)1045 void ES5506ScanRoutes(INT32 nAction, INT32* pnMin)
1046 {
1047 #if defined FBA_DEBUG
1048 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506ScanRoutes called without init\n"));
1049 #endif
1050 
1051 	ES5506Scan(nAction, pnMin);
1052 
1053 	if (nAction & ACB_DRIVER_DATA) {
1054 		SCAN_VAR(chip->volume);
1055 	}
1056 }
1057 
ES5506SetRoute(INT32,double nVolume,INT32 nRouteDir)1058 void ES5506SetRoute(INT32, double nVolume, INT32 nRouteDir)
1059 {
1060 	if (nRouteDir & 1) { // left
1061 		chip->volume[0] = nVolume;
1062 	}
1063 
1064 	if (nRouteDir & 2) { // right
1065 		chip->volume[1] = nVolume;
1066 	}
1067 }
1068 
1069 
1070 /**********************************************************************************************
1071 
1072      DEVICE_STOP( es5506 ) -- stop emulation of the ES5506
1073 
1074 ***********************************************************************************************/
1075 
ES5506Exit()1076 void ES5506Exit()
1077 {
1078 #if defined FBA_DEBUG
1079 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506Exit called without init\n"));
1080 #endif
1081 
1082 	if (!DebugSnd_ES5506Initted) return;
1083 
1084 	/* debugging */
1085 	if (LOG_COMMANDS && eslog)
1086 	{
1087 		fclose(eslog);
1088 		eslog = NULL;
1089 	}
1090 
1091 #if MAKE_WAVS
1092 	{
1093 		INT32 i;
1094 
1095 		for (i = 0; i < MAX_ES5506; i++)
1096 		{
1097 			if (es5506[i].wavraw)
1098 				wav_close(es5506[i].wavraw);
1099 		}
1100 	}
1101 #endif
1102 
1103 	BurnFree(chip->ulaw_lookup);
1104 	BurnFree(chip->volume_lookup);
1105 	BurnFree(chip->scratch);
1106 	BurnFree(chip);
1107 	chip = NULL;
1108 
1109 	ES550X_twincobra2_pan_fix = 0;
1110 
1111 	DebugSnd_ES5506Initted = 0;
1112 }
1113 
1114 
ES5506Reset()1115 void ES5506Reset()
1116 {
1117 #if defined FBA_DEBUG
1118 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506Reset called without init\n"));
1119 #endif
1120 
1121 	init_voices();
1122 }
1123 
1124 
1125 /**********************************************************************************************
1126 
1127      es5506_reg_write -- handle a write to the selected ES5506 register
1128 
1129 ***********************************************************************************************/
1130 
es5506_reg_write_low(es5506_voice * voice,UINT32 offset,UINT32 data)1131 ES5506_INLINE void es5506_reg_write_low(es5506_voice *voice, UINT32 offset, UINT32 data)
1132 {
1133 	switch (offset)
1134 	{
1135 		case 0x00/8:	/* CR */
1136 			voice->control = data & 0xffff;
1137 			if (LOG_COMMANDS && eslog)
1138 				fprintf(eslog, "voice %d, control=%04x\n", chip->current_page & 0x1f, voice->control);
1139 			break;
1140 
1141 		case 0x08/8:	/* FC */
1142 			voice->freqcount = data & 0x1ffff;
1143 			if (LOG_COMMANDS && eslog)
1144 				fprintf(eslog, "voice %d, freq count=%08x\n", chip->current_page & 0x1f, voice->freqcount);
1145 			break;
1146 
1147 		case 0x10/8:	/* LVOL */
1148 			voice->lvol = data & 0xffff;
1149 			if (LOG_COMMANDS && eslog)
1150 				fprintf(eslog, "voice %d, left vol=%04x\n", chip->current_page & 0x1f, voice->lvol);
1151 			break;
1152 
1153 		case 0x18/8:	/* LVRAMP */
1154 			voice->lvramp = (data & 0xff00) >> 8;
1155 			if (LOG_COMMANDS && eslog)
1156 				fprintf(eslog, "voice %d, left vol ramp=%04x\n", chip->current_page & 0x1f, voice->lvramp);
1157 			break;
1158 
1159 		case 0x20/8:	/* RVOL */
1160 			voice->rvol = data & 0xffff;
1161 			if (LOG_COMMANDS && eslog)
1162 				fprintf(eslog, "voice %d, right vol=%04x\n", chip->current_page & 0x1f, voice->rvol);
1163 			break;
1164 
1165 		case 0x28/8:	/* RVRAMP */
1166 			voice->rvramp = (data & 0xff00) >> 8;
1167 			if (LOG_COMMANDS && eslog)
1168 				fprintf(eslog, "voice %d, right vol ramp=%04x\n", chip->current_page & 0x1f, voice->rvramp);
1169 			break;
1170 
1171 		case 0x30/8:	/* ECOUNT */
1172 			voice->ecount = data & 0x1ff;
1173 			voice->filtcount = 0;
1174 			if (LOG_COMMANDS && eslog)
1175 				fprintf(eslog, "voice %d, envelope count=%04x\n", chip->current_page & 0x1f, voice->ecount);
1176 			break;
1177 
1178 		case 0x38/8:	/* K2 */
1179 			voice->k2 = data & 0xffff;
1180 			if (LOG_COMMANDS && eslog)
1181 				fprintf(eslog, "voice %d, K2=%04x\n", chip->current_page & 0x1f, voice->k2);
1182 			break;
1183 
1184 		case 0x40/8:	/* K2RAMP */
1185 			voice->k2ramp = ((data & 0xff00) >> 8) | ((data & 0x0001) << 31);
1186 			if (LOG_COMMANDS && eslog)
1187 				fprintf(eslog, "voice %d, K2 ramp=%04x\n", chip->current_page & 0x1f, voice->k2ramp);
1188 			break;
1189 
1190 		case 0x48/8:	/* K1 */
1191 			voice->k1 = data & 0xffff;
1192 			if (LOG_COMMANDS && eslog)
1193 				fprintf(eslog, "voice %d, K1=%04x\n", chip->current_page & 0x1f, voice->k1);
1194 			break;
1195 
1196 		case 0x50/8:	/* K1RAMP */
1197 			voice->k1ramp = ((data & 0xff00) >> 8) | ((data & 0x0001) << 31);
1198 			if (LOG_COMMANDS && eslog)
1199 				fprintf(eslog, "voice %d, K1 ramp=%04x\n", chip->current_page & 0x1f, voice->k1ramp);
1200 			break;
1201 
1202 		case 0x58/8:	/* ACTV */
1203 		{
1204 			chip->active_voices = data & 0x1f;
1205 			chip->sample_rate = chip->master_clock / (16 * (chip->active_voices + 1));
1206 
1207 			nSampleSize = (UINT32)chip->sample_rate * (1 << 16) / nBurnSoundRate;
1208 
1209 			if (LOG_COMMANDS && eslog)
1210 				fprintf(eslog, "active voices=%d, sample_rate=%d\n", chip->active_voices, chip->sample_rate);
1211 			break;
1212 		}
1213 
1214 		case 0x60/8:	/* MODE */
1215 			chip->mode = data & 0x1f;
1216 			break;
1217 
1218 		case 0x68/8:	/* PAR - read only */
1219 		case 0x70/8:	/* IRQV - read only */
1220 			break;
1221 
1222 		case 0x78/8:	/* PAGE */
1223 			chip->current_page = data & 0x7f;
1224 			break;
1225 	}
1226 }
1227 
1228 
es5506_reg_write_high(es5506_voice * voice,UINT32 offset,UINT32 data)1229 ES5506_INLINE void es5506_reg_write_high(es5506_voice *voice, UINT32 offset, UINT32 data)
1230 {
1231 	switch (offset)
1232 	{
1233 		case 0x00/8:	/* CR */
1234 			voice->control = data & 0xffff;
1235 			if (LOG_COMMANDS && eslog)
1236 				fprintf(eslog, "voice %d, control=%04x\n", chip->current_page & 0x1f, voice->control);
1237 			break;
1238 
1239 		case 0x08/8:	/* START */
1240 			voice->start = data & 0xfffff800;
1241 			if (LOG_COMMANDS && eslog)
1242 				fprintf(eslog, "voice %d, loop start=%08x\n", chip->current_page & 0x1f, voice->start);
1243 			break;
1244 
1245 		case 0x10/8:	/* END */
1246 			voice->end = data & 0xffffff80;
1247 			if (LOG_COMMANDS && eslog)
1248 				fprintf(eslog, "voice %d, loop end=%08x\n", chip->current_page & 0x1f, voice->end);
1249 			break;
1250 
1251 		case 0x18/8:	/* ACCUM */
1252 			voice->accum = data;
1253 			if (LOG_COMMANDS && eslog)
1254 				fprintf(eslog, "voice %d, accum=%08x\n", chip->current_page & 0x1f, voice->accum);
1255 			break;
1256 
1257 		case 0x20/8:	/* O4(n-1) */
1258 			voice->o4n1 = (INT32)(data << 14) >> 14;
1259 			if (LOG_COMMANDS && eslog)
1260 				fprintf(eslog, "voice %d, O4(n-1)=%05x\n", chip->current_page & 0x1f, voice->o4n1 & 0x3ffff);
1261 			break;
1262 
1263 		case 0x28/8:	/* O3(n-1) */
1264 			voice->o3n1 = (INT32)(data << 14) >> 14;
1265 			if (LOG_COMMANDS && eslog)
1266 				fprintf(eslog, "voice %d, O3(n-1)=%05x\n", chip->current_page & 0x1f, voice->o3n1 & 0x3ffff);
1267 			break;
1268 
1269 		case 0x30/8:	/* O3(n-2) */
1270 			voice->o3n2 = (INT32)(data << 14) >> 14;
1271 			if (LOG_COMMANDS && eslog)
1272 				fprintf(eslog, "voice %d, O3(n-2)=%05x\n", chip->current_page & 0x1f, voice->o3n2 & 0x3ffff);
1273 			break;
1274 
1275 		case 0x38/8:	/* O2(n-1) */
1276 			voice->o2n1 = (INT32)(data << 14) >> 14;
1277 			if (LOG_COMMANDS && eslog)
1278 				fprintf(eslog, "voice %d, O2(n-1)=%05x\n", chip->current_page & 0x1f, voice->o2n1 & 0x3ffff);
1279 			break;
1280 
1281 		case 0x40/8:	/* O2(n-2) */
1282 			voice->o2n2 = (INT32)(data << 14) >> 14;
1283 			if (LOG_COMMANDS && eslog)
1284 				fprintf(eslog, "voice %d, O2(n-2)=%05x\n", chip->current_page & 0x1f, voice->o2n2 & 0x3ffff);
1285 			break;
1286 
1287 		case 0x48/8:	/* O1(n-1) */
1288 			voice->o1n1 = (INT32)(data << 14) >> 14;
1289 			if (LOG_COMMANDS && eslog)
1290 				fprintf(eslog, "voice %d, O1(n-1)=%05x\n", chip->current_page & 0x1f, voice->o1n1 & 0x3ffff);
1291 			break;
1292 
1293 		case 0x50/8:	/* W_ST */
1294 			chip->wst = data & 0x7f;
1295 			break;
1296 
1297 		case 0x58/8:	/* W_END */
1298 			chip->wend = data & 0x7f;
1299 			break;
1300 
1301 		case 0x60/8:	/* LR_END */
1302 			chip->lrend = data & 0x7f;
1303 			break;
1304 
1305 		case 0x68/8:	/* PAR - read only */
1306 		case 0x70/8:	/* IRQV - read only */
1307 			break;
1308 
1309 		case 0x78/8:	/* PAGE */
1310 			chip->current_page = data & 0x7f;
1311 			break;
1312 	}
1313 }
1314 
es5506_reg_write_test(UINT32 offset,UINT32 data)1315 ES5506_INLINE void es5506_reg_write_test(UINT32 offset, UINT32 data)
1316 {
1317 	switch (offset)
1318 	{
1319 		case 0x00/8:	/* CHANNEL 0 LEFT */
1320 			if (LOG_COMMANDS && eslog)
1321 				fprintf(eslog, "Channel 0 left test write %08x\n", data);
1322 			break;
1323 
1324 		case 0x08/8:	/* CHANNEL 0 RIGHT */
1325 			if (LOG_COMMANDS && eslog)
1326 				fprintf(eslog, "Channel 0 right test write %08x\n", data);
1327 			break;
1328 
1329 		case 0x10/8:	/* CHANNEL 1 LEFT */
1330 			if (LOG_COMMANDS && eslog)
1331 				fprintf(eslog, "Channel 1 left test write %08x\n", data);
1332 			break;
1333 
1334 		case 0x18/8:	/* CHANNEL 1 RIGHT */
1335 			if (LOG_COMMANDS && eslog)
1336 				fprintf(eslog, "Channel 1 right test write %08x\n", data);
1337 			break;
1338 
1339 		case 0x20/8:	/* CHANNEL 2 LEFT */
1340 			if (LOG_COMMANDS && eslog)
1341 				fprintf(eslog, "Channel 2 left test write %08x\n", data);
1342 			break;
1343 
1344 		case 0x28/8:	/* CHANNEL 2 RIGHT */
1345 			if (LOG_COMMANDS && eslog)
1346 				fprintf(eslog, "Channel 2 right test write %08x\n", data);
1347 			break;
1348 
1349 		case 0x30/8:	/* CHANNEL 3 LEFT */
1350 			if (LOG_COMMANDS && eslog)
1351 				fprintf(eslog, "Channel 3 left test write %08x\n", data);
1352 			break;
1353 
1354 		case 0x38/8:	/* CHANNEL 3 RIGHT */
1355 			if (LOG_COMMANDS && eslog)
1356 				fprintf(eslog, "Channel 3 right test write %08x\n", data);
1357 			break;
1358 
1359 		case 0x40/8:	/* CHANNEL 4 LEFT */
1360 			if (LOG_COMMANDS && eslog)
1361 				fprintf(eslog, "Channel 4 left test write %08x\n", data);
1362 			break;
1363 
1364 		case 0x48/8:	/* CHANNEL 4 RIGHT */
1365 			if (LOG_COMMANDS && eslog)
1366 				fprintf(eslog, "Channel 4 right test write %08x\n", data);
1367 			break;
1368 
1369 		case 0x50/8:	/* CHANNEL 5 LEFT */
1370 			if (LOG_COMMANDS && eslog)
1371 				fprintf(eslog, "Channel 5 left test write %08x\n", data);
1372 			break;
1373 
1374 		case 0x58/8:	/* CHANNEL 6 RIGHT */
1375 			if (LOG_COMMANDS && eslog)
1376 				fprintf(eslog, "Channel 5 right test write %08x\n", data);
1377 			break;
1378 
1379 		case 0x60/8:	/* EMPTY */
1380 			if (LOG_COMMANDS && eslog)
1381 				fprintf(eslog, "Test write EMPTY %08x\n", data);
1382 			break;
1383 
1384 		case 0x68/8:	/* PAR - read only */
1385 		case 0x70/8:	/* IRQV - read only */
1386 			break;
1387 
1388 		case 0x78/8:	/* PAGE */
1389 			chip->current_page = data & 0x7f;
1390 			break;
1391 	}
1392 }
1393 
ES5506Write(UINT32 offset,UINT8 data)1394 void ES5506Write(UINT32 offset, UINT8 data)
1395 {
1396 #if defined FBA_DEBUG
1397 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506Write called without init\n"));
1398 #endif
1399 
1400 	es5506_voice *voice = &chip->voice[chip->current_page & 0x1f];
1401 	INT32 shift = 8 * (offset & 3);
1402 
1403 	/* accumulate the data */
1404 	chip->write_latch = (chip->write_latch & ~(0xff000000 >> shift)) | (data << (24 - shift));
1405 
1406 	/* wait for a write to complete */
1407 	if (shift != 24)
1408 		return;
1409 
1410 	/* switch off the page and register */
1411 	if (chip->current_page < 0x20)
1412 		es5506_reg_write_low(voice, offset / 4, chip->write_latch);
1413 	else if (chip->current_page < 0x40)
1414 		es5506_reg_write_high(voice, offset / 4, chip->write_latch);
1415 	else
1416 		es5506_reg_write_test(offset / 4, chip->write_latch);
1417 
1418 	/* clear the write latch when done */
1419 	chip->write_latch = 0;
1420 }
1421 
1422 
1423 /**********************************************************************************************
1424 
1425      es5506_reg_read -- read from the specified ES5506 register
1426 
1427 ***********************************************************************************************/
1428 
es5506_reg_read_low(es5506_voice * voice,UINT32 offset)1429 ES5506_INLINE UINT32 es5506_reg_read_low(es5506_voice *voice, UINT32 offset)
1430 {
1431 	UINT32 result = 0;
1432 
1433 	switch (offset)
1434 	{
1435 		case 0x00/8:	/* CR */
1436 			result = voice->control;
1437 			break;
1438 
1439 		case 0x08/8:	/* FC */
1440 			result = voice->freqcount;
1441 			break;
1442 
1443 		case 0x10/8:	/* LVOL */
1444 			result = voice->lvol;
1445 			break;
1446 
1447 		case 0x18/8:	/* LVRAMP */
1448 			result = voice->lvramp << 8;
1449 			break;
1450 
1451 		case 0x20/8:	/* RVOL */
1452 			result = voice->rvol;
1453 			break;
1454 
1455 		case 0x28/8:	/* RVRAMP */
1456 			result = voice->rvramp << 8;
1457 			break;
1458 
1459 		case 0x30/8:	/* ECOUNT */
1460 			result = voice->ecount;
1461 			break;
1462 
1463 		case 0x38/8:	/* K2 */
1464 			result = voice->k2;
1465 			break;
1466 
1467 		case 0x40/8:	/* K2RAMP */
1468 			result = (voice->k2ramp << 8) | (voice->k2ramp >> 31);
1469 			break;
1470 
1471 		case 0x48/8:	/* K1 */
1472 			result = voice->k1;
1473 			break;
1474 
1475 		case 0x50/8:	/* K1RAMP */
1476 			result = (voice->k1ramp << 8) | (voice->k1ramp >> 31);
1477 			break;
1478 
1479 		case 0x58/8:	/* ACTV */
1480 			result = chip->active_voices;
1481 			break;
1482 
1483 		case 0x60/8:	/* MODE */
1484 			result = chip->mode;
1485 			break;
1486 
1487 		case 0x68/8:	/* PAR */
1488 			if (chip->port_read)
1489 				result = (*chip->port_read)();
1490 			break;
1491 
1492 		case 0x70/8:	/* IRQV */
1493 			result = chip->irqv;
1494 			update_internal_irq_state();
1495 			break;
1496 
1497 		case 0x78/8:	/* PAGE */
1498 			result = chip->current_page;
1499 			break;
1500 	}
1501 	return result;
1502 }
1503 
1504 
es5506_reg_read_high(es5506_voice * voice,UINT32 offset)1505 ES5506_INLINE UINT32 es5506_reg_read_high(es5506_voice *voice, UINT32 offset)
1506 {
1507 	UINT32 result = 0;
1508 
1509 	switch (offset)
1510 	{
1511 		case 0x00/8:	/* CR */
1512 			result = voice->control;
1513 			break;
1514 
1515 		case 0x08/8:	/* START */
1516 			result = voice->start;
1517 			break;
1518 
1519 		case 0x10/8:	/* END */
1520 			result = voice->end;
1521 			break;
1522 
1523 		case 0x18/8:	/* ACCUM */
1524 			result = voice->accum;
1525 			break;
1526 
1527 		case 0x20/8:	/* O4(n-1) */
1528 			result = voice->o4n1 & 0x3ffff;
1529 			break;
1530 
1531 		case 0x28/8:	/* O3(n-1) */
1532 			result = voice->o3n1 & 0x3ffff;
1533 			break;
1534 
1535 		case 0x30/8:	/* O3(n-2) */
1536 			result = voice->o3n2 & 0x3ffff;
1537 			break;
1538 
1539 		case 0x38/8:	/* O2(n-1) */
1540 			result = voice->o2n1 & 0x3ffff;
1541 			break;
1542 
1543 		case 0x40/8:	/* O2(n-2) */
1544 			result = voice->o2n2 & 0x3ffff;
1545 			break;
1546 
1547 		case 0x48/8:	/* O1(n-1) */
1548 			result = voice->o1n1 & 0x3ffff;
1549 			break;
1550 
1551 		case 0x50/8:	/* W_ST */
1552 			result = chip->wst;
1553 			break;
1554 
1555 		case 0x58/8:	/* W_END */
1556 			result = chip->wend;
1557 			break;
1558 
1559 		case 0x60/8:	/* LR_END */
1560 			result = chip->lrend;
1561 			break;
1562 
1563 		case 0x68/8:	/* PAR */
1564 			if (chip->port_read)
1565 				result = (*chip->port_read)();
1566 			break;
1567 
1568 		case 0x70/8:	/* IRQV */
1569 			result = chip->irqv;
1570 			update_internal_irq_state();
1571 			break;
1572 
1573 		case 0x78/8:	/* PAGE */
1574 			result = chip->current_page;
1575 			break;
1576 	}
1577 	return result;
1578 }
1579 
es5506_reg_read_test(UINT32 offset)1580 ES5506_INLINE UINT32 es5506_reg_read_test(UINT32 offset)
1581 {
1582 	UINT32 result = 0;
1583 
1584 	switch (offset)
1585 	{
1586 		case 0x68/8:	/* PAR */
1587 			if (chip->port_read)
1588 				result = (*chip->port_read)();
1589 			break;
1590 
1591 		case 0x70/8:	/* IRQV */
1592 			result = chip->irqv;
1593 			break;
1594 
1595 		case 0x78/8:	/* PAGE */
1596 			result = chip->current_page;
1597 			break;
1598 	}
1599 	return result;
1600 }
1601 
ES5506Read(UINT32 offset)1602 UINT8 ES5506Read(UINT32 offset)
1603 {
1604 #if defined FBA_DEBUG
1605 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5506Read called without init\n"));
1606 #endif
1607 
1608 	es5506_voice *voice = &chip->voice[chip->current_page & 0x1f];
1609 	INT32 shift = 8 * (offset & 3);
1610 
1611 	/* only read on offset 0 */
1612 	if (shift != 0)
1613 		return chip->read_latch >> (24 - shift);
1614 
1615 	if (LOG_COMMANDS && eslog)
1616 		fprintf(eslog, "read from %02x/%02x -> ", chip->current_page, offset / 4 * 8);
1617 
1618 	/* switch off the page and register */
1619 	if (chip->current_page < 0x20)
1620 		chip->read_latch = es5506_reg_read_low(voice, offset / 4);
1621 	else if (chip->current_page < 0x40)
1622 		chip->read_latch = es5506_reg_read_high(voice, offset / 4);
1623 	else
1624 		chip->read_latch = es5506_reg_read_test(offset / 4);
1625 
1626 	if (LOG_COMMANDS && eslog)
1627 		fprintf(eslog, "%08x\n", chip->read_latch);
1628 
1629 	/* return the high byte */
1630 	return chip->read_latch >> 24;
1631 }
1632 
es5506_voice_bank_w(INT32 voice,INT32 bank)1633 void es5506_voice_bank_w(INT32 voice, INT32 bank)
1634 {
1635 #if defined FBA_DEBUG
1636 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("es5506_voice_bank_w called without init\n"));
1637 #endif
1638 
1639 	chip->voice[voice].exbank=bank;
1640 }
1641 
1642 
1643 /**********************************************************************************************
1644 
1645      DEVICE_START( es5505 ) -- start emulation of the ES5505
1646 
1647 ***********************************************************************************************/
1648 
ES5505Init(INT32 clock,UINT8 * region0,UINT8 * region1,irq_callback callback)1649 void ES5505Init(INT32 clock, UINT8* region0, UINT8* region1, irq_callback callback)
1650 {
1651 	es5506_start_common(clock, region0, region1, NULL, NULL, callback, ES5505);
1652 }
1653 
1654 /**********************************************************************************************
1655 
1656      es5505_reg_write -- handle a write to the selected ES5505 register
1657 
1658 ***********************************************************************************************/
1659 
es5505_reg_write_low(es5506_voice * voice,UINT32 offset,UINT16 data)1660 ES5506_INLINE void es5505_reg_write_low(es5506_voice *voice, UINT32 offset, UINT16 data)
1661 {
1662 	switch (offset)
1663 	{
1664 		case 0x00:	/* CR */
1665 //			if (ACCESSING_BITS_0_7)
1666 			{
1667 #if RAINE_CHECK
1668 				voice->control &= ~(CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_DIR);
1669 #else
1670 				voice->control &= ~(CONTROL_STOPMASK | CONTROL_BS0 | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ);
1671 #endif
1672 				voice->control |= (data & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |
1673 								  ((data << 12) & CONTROL_BS0);
1674 			}
1675 //			if (ACCESSING_BITS_8_15)
1676 			{
1677 				voice->control &= ~(CONTROL_CA0 | CONTROL_CA1 | CONTROL_LPMASK);
1678 				voice->control |= ((data >> 2) & CONTROL_LPMASK) |
1679 								  ((data << 2) & (CONTROL_CA0 | CONTROL_CA1));
1680 			}
1681 
1682 //			if (LOG_COMMANDS && eslog)
1683 //				fprintf(eslog, "%s:voice %d, control=%04x (raw=%04x & %04x)\n", machine->describe_context(), chip->current_page & 0x1f, voice->control, data, mem_mask ^ 0xffff);
1684 			break;
1685 
1686 		case 0x01:	/* FC */
1687 //			if (ACCESSING_BITS_0_7)
1688 				voice->freqcount = (voice->freqcount & ~0x001fe) | ((data & 0x00ff) << 1);
1689 //			if (ACCESSING_BITS_8_15)
1690 				voice->freqcount = (voice->freqcount & ~0x1fe00) | ((data & 0xff00) << 1);
1691 //			if (LOG_COMMANDS && eslog)
1692 //				fprintf(eslog, "%s:voice %d, freq count=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->freqcount);
1693 			break;
1694 
1695 		case 0x02:	/* STRT (hi) */
1696 //			if (ACCESSING_BITS_0_7)
1697 				voice->start = (voice->start & ~0x03fc0000) | ((data & 0x00ff) << 18);
1698 //			if (ACCESSING_BITS_8_15)
1699 				voice->start = (voice->start & ~0x7c000000) | ((data & 0x1f00) << 18);
1700 //			if (LOG_COMMANDS && eslog)
1701 //				fprintf(eslog, "%s:voice %d, loop start=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->start);
1702 			break;
1703 
1704 		case 0x03:	/* STRT (lo) */
1705 //			if (ACCESSING_BITS_0_7)
1706 				voice->start = (voice->start & ~0x00000380) | ((data & 0x00e0) << 2);
1707 //			if (ACCESSING_BITS_8_15)
1708 				voice->start = (voice->start & ~0x0003fc00) | ((data & 0xff00) << 2);
1709 //			if (LOG_COMMANDS && eslog)
1710 //				fprintf(eslog, "%s:voice %d, loop start=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->start);
1711 			break;
1712 
1713 		case 0x04:	/* END (hi) */
1714 //			if (ACCESSING_BITS_0_7)
1715 				voice->end = (voice->end & ~0x03fc0000) | ((data & 0x00ff) << 18);
1716 //			if (ACCESSING_BITS_8_15)
1717 				voice->end = (voice->end & ~0x7c000000) | ((data & 0x1f00) << 18);
1718 #if RAINE_CHECK
1719 			voice->control |= CONTROL_STOP0;
1720 #endif
1721 //			if (LOG_COMMANDS && eslog)
1722 //				fprintf(eslog, "%s:voice %d, loop end=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->end);
1723 			break;
1724 
1725 		case 0x05:	/* END (lo) */
1726 //			if (ACCESSING_BITS_0_7)
1727 				voice->end = (voice->end & ~0x00000380) | ((data & 0x00e0) << 2);
1728 //			if (ACCESSING_BITS_8_15)
1729 				voice->end = (voice->end & ~0x0003fc00) | ((data & 0xff00) << 2);
1730 #if RAINE_CHECK
1731 			voice->control |= CONTROL_STOP0;
1732 #endif
1733 //			if (LOG_COMMANDS && eslog)
1734 //				fprintf(eslog, "%s:voice %d, loop end=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->end);
1735 			break;
1736 
1737 		case 0x06:	/* K2 */
1738 //			if (ACCESSING_BITS_0_7)
1739 				voice->k2 = (voice->k2 & ~0x00f0) | (data & 0x00f0);
1740 //			if (ACCESSING_BITS_8_15)
1741 				voice->k2 = (voice->k2 & ~0xff00) | (data & 0xff00);
1742 //			if (LOG_COMMANDS && eslog)
1743 //				fprintf(eslog, "%s:voice %d, K2=%04x\n", machine->describe_context(), chip->current_page & 0x1f, voice->k2);
1744 			break;
1745 
1746 		case 0x07:	/* K1 */
1747 //			if (ACCESSING_BITS_0_7)
1748 				voice->k1 = (voice->k1 & ~0x00f0) | (data & 0x00f0);
1749 //			if (ACCESSING_BITS_8_15)
1750 				voice->k1 = (voice->k1 & ~0xff00) | (data & 0xff00);
1751 //			if (LOG_COMMANDS && eslog)
1752 //				fprintf(eslog, "%s:voice %d, K1=%04x\n", machine->describe_context(), chip->current_page & 0x1f, voice->k1);
1753 			break;
1754 
1755 		case 0x08:	/* LVOL */
1756 //			if (ACCESSING_BITS_8_15)
1757 				voice->lvol = (voice->lvol & ~0xff00) | (data & 0xff00);
1758 //			if (LOG_COMMANDS && eslog)
1759 //				fprintf(eslog, "%s:voice %d, left vol=%04x\n", machine->describe_context(), chip->current_page & 0x1f, voice->lvol);
1760 			break;
1761 
1762 		case 0x09:	/* RVOL */
1763 //			if (ACCESSING_BITS_8_15)
1764 				voice->rvol = (voice->rvol & ~0xff00) | (data & 0xff00);
1765 //			if (LOG_COMMANDS && eslog)
1766 //				fprintf(eslog, "%s:voice %d, right vol=%04x\n", machine->describe_context(), chip->current_page & 0x1f, voice->rvol);
1767 			break;
1768 
1769 		case 0x0a:	/* ACC (hi) */
1770 //			if (ACCESSING_BITS_0_7)
1771 				voice->accum = (voice->accum & ~0x03fc0000) | ((data & 0x00ff) << 18);
1772 //			if (ACCESSING_BITS_8_15)
1773 				voice->accum = (voice->accum & ~0x7c000000) | ((data & 0x1f00) << 18);
1774 //			if (LOG_COMMANDS && eslog)
1775 //				fprintf(eslog, "%s:voice %d, accum=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->accum);
1776 			break;
1777 
1778 		case 0x0b:	/* ACC (lo) */
1779 //			if (ACCESSING_BITS_0_7)
1780 				voice->accum = (voice->accum & ~0x000003fc) | ((data & 0x00ff) << 2);
1781 //			if (ACCESSING_BITS_8_15)
1782 				voice->accum = (voice->accum & ~0x0003fc00) | ((data & 0xff00) << 2);
1783 //			if (LOG_COMMANDS && eslog)
1784 //				fprintf(eslog, "%s:voice %d, accum=%08x\n", machine->describe_context(), chip->current_page & 0x1f, voice->accum);
1785 			break;
1786 
1787 		case 0x0c:	/* unused */
1788 			break;
1789 
1790 		case 0x0d:	/* ACT */
1791 //			if (ACCESSING_BITS_0_7)
1792 			{
1793 				chip->active_voices = data & 0x1f;
1794 				chip->sample_rate = chip->master_clock / (16 * (chip->active_voices + 1));
1795 
1796 				nSampleSize = (UINT32)chip->sample_rate * (1 << 16) / nBurnSoundRate;
1797 
1798 //				if (LOG_COMMANDS && eslog)
1799 //					fprintf(eslog, "active voices=%d, sample_rate=%d\n", chip->active_voices, chip->sample_rate);
1800 			}
1801 			break;
1802 
1803 		case 0x0e:	/* IRQV - read only */
1804 			break;
1805 
1806 		case 0x0f:	/* PAGE */
1807 //			if (ACCESSING_BITS_0_7)
1808 				chip->current_page = data & 0x7f;
1809 			break;
1810 	}
1811 }
1812 
1813 
es5505_reg_write_high(es5506_voice * voice,UINT32 offset,UINT16 data)1814 ES5506_INLINE void es5505_reg_write_high(es5506_voice *voice, UINT32 offset, UINT16 data)
1815 {
1816 	switch (offset)
1817 	{
1818 		case 0x00:	/* CR */
1819 //			if (ACCESSING_BITS_0_7)
1820 			{
1821 				voice->control &= ~(CONTROL_STOPMASK | CONTROL_BS0 | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ);
1822 				voice->control |= (data & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |
1823 								  ((data << 12) & CONTROL_BS0);
1824 			}
1825 //			if (ACCESSING_BITS_8_15)
1826 			{
1827 				voice->control &= ~(CONTROL_CA0 | CONTROL_CA1 | CONTROL_LPMASK);
1828 				voice->control |= ((data >> 2) & CONTROL_LPMASK) |
1829 								  ((data << 2) & (CONTROL_CA0 | CONTROL_CA1));
1830 			}
1831 //			if (LOG_COMMANDS && eslog)
1832 //				fprintf(eslog, "%s:voice %d, control=%04x (raw=%04x & %04x)\n", machine->describe_context(), chip->current_page & 0x1f, voice->control, data, mem_mask);
1833 			break;
1834 
1835 		case 0x01:	/* O4(n-1) */
1836 //			if (ACCESSING_BITS_0_7)
1837 				voice->o4n1 = (voice->o4n1 & ~0x00ff) | (data & 0x00ff);
1838 //			if (ACCESSING_BITS_8_15)
1839 				voice->o4n1 = (INT16)((voice->o4n1 & ~0xff00) | (data & 0xff00));
1840 //			if (LOG_COMMANDS && eslog)
1841 //				fprintf(eslog, "%s:voice %d, O4(n-1)=%05x\n", machine->describe_context(), chip->current_page & 0x1f, voice->o4n1 & 0x3ffff);
1842 			break;
1843 
1844 		case 0x02:	/* O3(n-1) */
1845 //			if (ACCESSING_BITS_0_7)
1846 				voice->o3n1 = (voice->o3n1 & ~0x00ff) | (data & 0x00ff);
1847 //			if (ACCESSING_BITS_8_15)
1848 				voice->o3n1 = (INT16)((voice->o3n1 & ~0xff00) | (data & 0xff00));
1849 //			if (LOG_COMMANDS && eslog)
1850 //				fprintf(eslog, "%s:voice %d, O3(n-1)=%05x\n", machine->describe_context(), chip->current_page & 0x1f, voice->o3n1 & 0x3ffff);
1851 			break;
1852 
1853 		case 0x03:	/* O3(n-2) */
1854 //			if (ACCESSING_BITS_0_7)
1855 				voice->o3n2 = (voice->o3n2 & ~0x00ff) | (data & 0x00ff);
1856 //			if (ACCESSING_BITS_8_15)
1857 				voice->o3n2 = (INT16)((voice->o3n2 & ~0xff00) | (data & 0xff00));
1858 //			if (LOG_COMMANDS && eslog)
1859 //				fprintf(eslog, "%s:voice %d, O3(n-2)=%05x\n", machine->describe_context(), chip->current_page & 0x1f, voice->o3n2 & 0x3ffff);
1860 			break;
1861 
1862 		case 0x04:	/* O2(n-1) */
1863 //			if (ACCESSING_BITS_0_7)
1864 				voice->o2n1 = (voice->o2n1 & ~0x00ff) | (data & 0x00ff);
1865 //			if (ACCESSING_BITS_8_15)
1866 				voice->o2n1 = (INT16)((voice->o2n1 & ~0xff00) | (data & 0xff00));
1867 //			if (LOG_COMMANDS && eslog)
1868 //				fprintf(eslog, "%s:voice %d, O2(n-1)=%05x\n", machine->describe_context(), chip->current_page & 0x1f, voice->o2n1 & 0x3ffff);
1869 			break;
1870 
1871 		case 0x05:	/* O2(n-2) */
1872 //			if (ACCESSING_BITS_0_7)
1873 				voice->o2n2 = (voice->o2n2 & ~0x00ff) | (data & 0x00ff);
1874 //			if (ACCESSING_BITS_8_15)
1875 				voice->o2n2 = (INT16)((voice->o2n2 & ~0xff00) | (data & 0xff00));
1876 //			if (LOG_COMMANDS && eslog)
1877 //				fprintf(eslog, "%s:voice %d, O2(n-2)=%05x\n", machine->describe_context(), chip->current_page & 0x1f, voice->o2n2 & 0x3ffff);
1878 			break;
1879 
1880 		case 0x06:	/* O1(n-1) */
1881 //			if (ACCESSING_BITS_0_7)
1882 				voice->o1n1 = (voice->o1n1 & ~0x00ff) | (data & 0x00ff);
1883 //			if (ACCESSING_BITS_8_15)
1884 				voice->o1n1 = (INT16)((voice->o1n1 & ~0xff00) | (data & 0xff00));
1885 //			if (LOG_COMMANDS && eslog)
1886 //				fprintf(eslog, "%s:voice %d, O1(n-1)=%05x (accum=%08x)\n", machine->describe_context(), chip->current_page & 0x1f, voice->o2n1 & 0x3ffff, voice->accum);
1887 			break;
1888 
1889 		case 0x07:
1890 		case 0x08:
1891 		case 0x09:
1892 		case 0x0a:
1893 		case 0x0b:
1894 		case 0x0c:	/* unused */
1895 			break;
1896 
1897 		case 0x0d:	/* ACT */
1898 //			if (ACCESSING_BITS_0_7)
1899 			{
1900 				chip->active_voices = data & 0x1f;
1901 				chip->sample_rate = chip->master_clock / (16 * (chip->active_voices + 1));
1902 
1903 				nSampleSize = (UINT32)chip->sample_rate * (1 << 16) / nBurnSoundRate;
1904 
1905 //				if (LOG_COMMANDS && eslog)
1906 //					fprintf(eslog, "active voices=%d, sample_rate=%d\n", chip->active_voices, chip->sample_rate);
1907 			}
1908 			break;
1909 
1910 		case 0x0e:	/* IRQV - read only */
1911 			break;
1912 
1913 		case 0x0f:	/* PAGE */
1914 //			if (ACCESSING_BITS_0_7)
1915 				chip->current_page = data & 0x7f;
1916 			break;
1917 	}
1918 }
1919 
1920 
es5505_reg_write_test(UINT32 offset,UINT16 data)1921 ES5506_INLINE void es5505_reg_write_test(UINT32 offset, UINT16 data)
1922 {
1923 	switch (offset)
1924 	{
1925 		case 0x00:	/* CH0L */
1926 		case 0x01:	/* CH0R */
1927 		case 0x02:	/* CH1L */
1928 		case 0x03:	/* CH1R */
1929 		case 0x04:	/* CH2L */
1930 		case 0x05:	/* CH2R */
1931 		case 0x06:	/* CH3L */
1932 		case 0x07:	/* CH3R */
1933 			break;
1934 
1935 		case 0x08:	/* SERMODE */
1936 			chip->mode = data & 0x0007;
1937 			break;
1938 
1939 		case 0x09:	/* PAR */
1940 			break;
1941 
1942 		case 0x0d:	/* ACT */
1943 //			if (ACCESSING_BITS_0_7)
1944 			{
1945 				chip->active_voices = data & 0x1f;
1946 				chip->sample_rate = chip->master_clock / (16 * (chip->active_voices + 1));
1947 
1948 				nSampleSize = (UINT32)chip->sample_rate * (1 << 16) / nBurnSoundRate;
1949 
1950 //				if (LOG_COMMANDS && eslog)
1951 //					fprintf(eslog, "active voices=%d, sample_rate=%d\n", chip->active_voices, chip->sample_rate);
1952 			}
1953 			break;
1954 
1955 		case 0x0e:	/* IRQV - read only */
1956 			break;
1957 
1958 		case 0x0f:	/* PAGE */
1959 //			if (ACCESSING_BITS_0_7)
1960 				chip->current_page = data & 0x7f;
1961 			break;
1962 	}
1963 }
1964 
1965 
ES5505Write(UINT32 offset,UINT16 data)1966 void ES5505Write(UINT32 offset, UINT16 data)
1967 {
1968 #if defined FBA_DEBUG
1969 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5505Write called without init\n"));
1970 #endif
1971 
1972 	es5506_voice *voice = &chip->voice[chip->current_page & 0x1f];
1973 
1974 //  logerror("%s:ES5505 write %02x/%02x = %04x & %04x\n", machine->describe_context(), chip->current_page, offset, data, mem_mask);
1975 
1976 	/* switch off the page and register */
1977 	if (chip->current_page < 0x20)
1978 		es5505_reg_write_low(voice, offset, data);
1979 	else if (chip->current_page < 0x40)
1980 		es5505_reg_write_high(voice, offset, data);
1981 	else
1982 		es5505_reg_write_test(offset, data);
1983 }
1984 
1985 
1986 
1987 /**********************************************************************************************
1988 
1989      es5505_reg_read -- read from the specified ES5505 register
1990 
1991 ***********************************************************************************************/
1992 
es5505_reg_read_low(es5506_voice * voice,UINT32 offset)1993 ES5506_INLINE UINT16 es5505_reg_read_low(es5506_voice *voice, UINT32 offset)
1994 {
1995 	UINT16 result = 0;
1996 
1997 	switch (offset)
1998 	{
1999 		case 0x00:	/* CR */
2000 			result = (voice->control & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |
2001 					 ((voice->control & CONTROL_BS0) >> 12) |
2002 					 ((voice->control & CONTROL_LPMASK) << 2) |
2003 					 ((voice->control & (CONTROL_CA0 | CONTROL_CA1)) >> 2) |
2004 					 0xf000;
2005 			break;
2006 
2007 		case 0x01:	/* FC */
2008 			result = voice->freqcount >> 1;
2009 			break;
2010 
2011 		case 0x02:	/* STRT (hi) */
2012 			result = voice->start >> 18;
2013 			break;
2014 
2015 		case 0x03:	/* STRT (lo) */
2016 			result = voice->start >> 2;
2017 			break;
2018 
2019 		case 0x04:	/* END (hi) */
2020 			result = voice->end >> 18;
2021 			break;
2022 
2023 		case 0x05:	/* END (lo) */
2024 			result = voice->end >> 2;
2025 			break;
2026 
2027 		case 0x06:	/* K2 */
2028 			result = voice->k2;
2029 			break;
2030 
2031 		case 0x07:	/* K1 */
2032 			result = voice->k1;
2033 			break;
2034 
2035 		case 0x08:	/* LVOL */
2036 			result = voice->lvol;
2037 			break;
2038 
2039 		case 0x09:	/* RVOL */
2040 			result = voice->rvol;
2041 			break;
2042 
2043 		case 0x0a:	/* ACC (hi) */
2044 			result = voice->accum >> 18;
2045 			break;
2046 
2047 		case 0x0b:	/* ACC (lo) */
2048 			result = voice->accum >> 2;
2049 			break;
2050 
2051 		case 0x0c:	/* unused */
2052 			break;
2053 
2054 		case 0x0d:	/* ACT */
2055 			result = chip->active_voices;
2056 			break;
2057 
2058 		case 0x0e:	/* IRQV */
2059 			result = chip->irqv;
2060 			update_internal_irq_state();
2061 			break;
2062 
2063 		case 0x0f:	/* PAGE */
2064 			result = chip->current_page;
2065 			break;
2066 	}
2067 	return result;
2068 }
2069 
2070 
es5505_reg_read_high(es5506_voice * voice,UINT32 offset)2071 ES5506_INLINE UINT16 es5505_reg_read_high(es5506_voice *voice, UINT32 offset)
2072 {
2073 	UINT16 result = 0;
2074 
2075 	switch (offset)
2076 	{
2077 		case 0x00:	/* CR */
2078 			result = (voice->control & (CONTROL_STOPMASK | CONTROL_LOOPMASK | CONTROL_IRQE | CONTROL_DIR | CONTROL_IRQ)) |
2079 					 ((voice->control & CONTROL_BS0) >> 12) |
2080 					 ((voice->control & CONTROL_LPMASK) << 2) |
2081 					 ((voice->control & (CONTROL_CA0 | CONTROL_CA1)) >> 2) |
2082 					 0xf000;
2083 			break;
2084 
2085 		case 0x01:	/* O4(n-1) */
2086 			result = voice->o4n1;
2087 			break;
2088 
2089 		case 0x02:	/* O3(n-1) */
2090 			result = voice->o3n1;
2091 			break;
2092 
2093 		case 0x03:	/* O3(n-2) */
2094 			result = voice->o3n2;
2095 			break;
2096 
2097 		case 0x04:	/* O2(n-1) */
2098 			result = voice->o2n1;
2099 			break;
2100 
2101 		case 0x05:	/* O2(n-2) */
2102 			result = voice->o2n2;
2103 			break;
2104 
2105 		case 0x06:	/* O1(n-1) */
2106 			/* special case for the Taito F3 games: they set the accumulator on a stopped */
2107 			/* voice and assume the filters continue to process the data. They then read */
2108 			/* the O1(n-1) in order to extract raw data from the sound ROMs. Since we don't */
2109 			/* want to waste time filtering stopped channels, we just look for a read from */
2110 			/* this register on a stopped voice, and return the raw sample data at the */
2111 			/* accumulator */
2112 			if ((voice->control & CONTROL_STOPMASK) && chip->region_base[voice->control >> 14]) {
2113 				voice->o1n1 = chip->region_base[voice->control >> 14][voice->exbank + (voice->accum >> 11)];
2114 //				logerror("%02x %08x ==> %08x\n",voice->o1n1,voice->control >> 14,voice->exbank + (voice->accum >> 11));
2115 			}
2116 				result = voice->o1n1;
2117 			break;
2118 
2119 		case 0x07:
2120 		case 0x08:
2121 		case 0x09:
2122 		case 0x0a:
2123 		case 0x0b:
2124 		case 0x0c:	/* unused */
2125 			break;
2126 
2127 		case 0x0d:	/* ACT */
2128 			result = chip->active_voices;
2129 			break;
2130 
2131 		case 0x0e:	/* IRQV */
2132 			result = chip->irqv;
2133 			update_internal_irq_state();
2134 			break;
2135 
2136 		case 0x0f:	/* PAGE */
2137 			result = chip->current_page;
2138 			break;
2139 	}
2140 	return result;
2141 }
2142 
2143 
es5505_reg_read_test(UINT32 offset)2144 ES5506_INLINE UINT16 es5505_reg_read_test(UINT32 offset)
2145 {
2146 	UINT16 result = 0;
2147 
2148 	switch (offset)
2149 	{
2150 		case 0x00:	/* CH0L */
2151 		case 0x01:	/* CH0R */
2152 		case 0x02:	/* CH1L */
2153 		case 0x03:	/* CH1R */
2154 		case 0x04:	/* CH2L */
2155 		case 0x05:	/* CH2R */
2156 		case 0x06:	/* CH3L */
2157 		case 0x07:	/* CH3R */
2158 			break;
2159 
2160 		case 0x08:	/* SERMODE */
2161 			result = chip->mode;
2162 			break;
2163 
2164 		case 0x09:	/* PAR */
2165 			if (chip->port_read)
2166 				result = (*chip->port_read)();
2167 			break;
2168 
2169 		case 0x0f:	/* PAGE */
2170 			result = chip->current_page;
2171 			break;
2172 	}
2173 	return result;
2174 }
2175 
2176 
ES5505Read(UINT32 offset)2177 UINT16 ES5505Read(UINT32 offset)
2178 {
2179 #if defined FBA_DEBUG
2180 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("ES5505Read called without init\n"));
2181 #endif
2182 
2183 	es5506_voice *voice = &chip->voice[chip->current_page & 0x1f];
2184 	UINT16 result = 0;
2185 
2186 	if (LOG_COMMANDS && eslog)
2187 		fprintf(eslog, "read from %02x/%02x -> ", chip->current_page, offset);
2188 
2189 	/* switch off the page and register */
2190 	if (chip->current_page < 0x20)
2191 		result = es5505_reg_read_low(voice, offset);
2192 	else if (chip->current_page < 0x40)
2193 		result = es5505_reg_read_high(voice, offset);
2194 	else
2195 		result = es5505_reg_read_test(offset);
2196 
2197 	if (LOG_COMMANDS && eslog)
2198 		fprintf(eslog, "%04x (accum=%08x)\n", result, voice->accum);
2199 
2200 	/* return the high byte */
2201 	return result;
2202 }
2203 
2204 
2205 
es5505_voice_bank_w(INT32 voice,INT32 bank)2206 void es5505_voice_bank_w(INT32 voice, INT32 bank)
2207 {
2208 #if defined FBA_DEBUG
2209 	if (!DebugSnd_ES5506Initted) bprintf(PRINT_ERROR, _T("es5505_voice_bank_w called without init\n"));
2210 #endif
2211 
2212 #if RAINE_CHECK
2213 	chip->voice[voice].control = CONTROL_STOPMASK;
2214 #endif
2215 	chip->voice[voice].exbank=bank;
2216 }
2217 
2218 
2219 #if 0
2220 
2221 /**************************************************************************
2222  * Generic get_info
2223  **************************************************************************/
2224 
2225 DEVICE_GET_INFO( es5505 )
2226 {
2227 	switch (state)
2228 	{
2229 		/* --- the following bits of info are returned as 64-bit signed integers --- */
2230 		case DEVINFO_INT_TOKEN_BYTES:					info->i = sizeof(es5506_state);					break;
2231 
2232 		/* --- the following bits of info are returned as pointers to data or functions --- */
2233 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( es5505 );		break;
2234 		case DEVINFO_FCT_STOP:							info->stop = DEVICE_STOP_NAME( es5505 );		break;
2235 		case DEVINFO_FCT_RESET:							info->reset = DEVICE_RESET_NAME( es5505 );		break;
2236 
2237 		/* --- the following bits of info are returned as NULL-terminated strings --- */
2238 		case DEVINFO_STR_NAME:							strcpy(info->s, "ES5505");						break;
2239 		case DEVINFO_STR_FAMILY:					strcpy(info->s, "Ensoniq Wavetable");			break;
2240 		case DEVINFO_STR_VERSION:					strcpy(info->s, "1.0");							break;
2241 		case DEVINFO_STR_SOURCE_FILE:						strcpy(info->s, __FILE__);						break;
2242 		case DEVINFO_STR_CREDITS:					strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
2243 	}
2244 }
2245 
2246 
2247 /**************************************************************************
2248  * Generic get_info
2249  **************************************************************************/
2250 
2251 DEVICE_GET_INFO( es5506 )
2252 {
2253 	switch (state)
2254 	{
2255 		/* --- the following bits of info are returned as 64-bit signed integers --- */
2256 		case DEVINFO_INT_TOKEN_BYTES:					info->i = sizeof(es5506_state);					break;
2257 
2258 		/* --- the following bits of info are returned as pointers to data or functions --- */
2259 		case DEVINFO_FCT_START:							info->start = DEVICE_START_NAME( es5506 );		break;
2260 		case DEVINFO_FCT_STOP:							info->stop = DEVICE_STOP_NAME( es5506 );		break;
2261 		case DEVINFO_FCT_RESET:							info->reset = DEVICE_RESET_NAME( es5506 );		break;
2262 
2263 		/* --- the following bits of info are returned as NULL-terminated strings --- */
2264 		case DEVINFO_STR_NAME:							strcpy(info->s, "ES5506");						break;
2265 		case DEVINFO_STR_FAMILY:					strcpy(info->s, "Ensoniq Wavetable");			break;
2266 		case DEVINFO_STR_VERSION:					strcpy(info->s, "1.0");							break;
2267 		case DEVINFO_STR_SOURCE_FILE:						strcpy(info->s, __FILE__);						break;
2268 		case DEVINFO_STR_CREDITS:					strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
2269 	}
2270 }
2271 
2272 
2273 DEFINE_LEGACY_SOUND_DEVICE(ES5505, es5505);
2274 DEFINE_LEGACY_SOUND_DEVICE(ES5506, es5506);
2275 #endif
2276