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