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