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