1
6
7 #include "emu.h"
8 #include "cpu/m6800/m6800.h"
9 #include "sound/ay8910.h"
10 #include "sound/msm5205.h"
11 #include "sound/discrete.h"
12 #include "audio/irem.h"
13
14 struct irem_audio_state
15 {
16 UINT8 m_port1;
17 UINT8 m_port2;
18
19 device_t *m_ay1;
20 device_t *m_ay2;
21 device_t *m_adpcm1;
22 device_t *m_adpcm2;
23 };
24
25 INLINE irem_audio_state *get_safe_token( device_t *device )
26 {
27 assert(device != NULL);
28 assert(device->type() == IREM_AUDIO);
29
30 return (irem_audio_state *)downcast<irem_audio_device *>(device)->token();
31 }
32
33
34
35
40
41 static DEVICE_START( irem_audio )
42 {
43 irem_audio_state *state = get_safe_token(device);
44 running_machine &machine = device->machine();
45
46 state->m_adpcm1 = machine.device("msm1");
47 state->m_adpcm2 = machine.device("msm2");
48 state->m_ay1 = machine.device("ay1");
49 state->m_ay2 = machine.device("ay2");
50
51 device->save_item(NAME(state->m_port1));
52 device->save_item(NAME(state->m_port2));
53 }
54
55
56
57
63
64 WRITE8_HANDLER( irem_sound_cmd_w )
65 {
66 driver_device *drvstate = space.machine().driver_data<driver_device>();
67 if ((data & 0x80) == 0)
68 drvstate->soundlatch_byte_w(space, 0, data & 0x7f);
69 else
70 space.machine().device("iremsound")->execute().set_input_line(0, ASSERT_LINE);
71 }
72
73
74
75
80
81 static WRITE8_DEVICE_HANDLER( m6803_port1_w )
82 {
83 irem_audio_state *state = get_safe_token(device);
84
85 state->m_port1 = data;
86 }
87
88
89 static WRITE8_DEVICE_HANDLER( m6803_port2_w )
90 {
91 irem_audio_state *state = get_safe_token(device);
92
93
94 if ((state->m_port2 & 0x01) && !(data & 0x01))
95 {
96
97 if (state->m_port2 & 0x04)
98 {
99
100 if (state->m_port2 & 0x08)
101 ay8910_address_w(state->m_ay1, space, 0, state->m_port1);
102 if (state->m_port2 & 0x10)
103 ay8910_address_w(state->m_ay2, space, 0, state->m_port1);
104 }
105 else
106 {
107
108 if (state->m_port2 & 0x08)
109 ay8910_data_w(state->m_ay1, space, 0, state->m_port1);
110 if (state->m_port2 & 0x10)
111 ay8910_data_w(state->m_ay2, space, 0, state->m_port1);
112 }
113 }
114 state->m_port2 = data;
115 }
116
117
118
119
124
125 static READ8_DEVICE_HANDLER( m6803_port1_r )
126 {
127 irem_audio_state *state = get_safe_token(device);
128
129
130 if (state->m_port2 & 0x08)
131 return ay8910_r(state->m_ay1, space, 0);
132 if (state->m_port2 & 0x10)
133 return ay8910_r(state->m_ay2, space, 0);
134 return 0xff;
135 }
136
137
138 static READ8_DEVICE_HANDLER( m6803_port2_r )
139 {
140 return 0;
141 }
142
143
144
145
150
151 static WRITE8_DEVICE_HANDLER( ay8910_0_portb_w )
152 {
153 irem_audio_state *state = get_safe_token(device);
154
155
156 msm5205_playmode_w(state->m_adpcm1, (data >> 2) & 7);
157 if (state->m_adpcm2 != NULL)
158 msm5205_playmode_w(state->m_adpcm2, ((data >> 2) & 4) | 3);
159
160
161 msm5205_reset_w(state->m_adpcm1, data & 1);
162 if (state->m_adpcm2 != NULL)
163 msm5205_reset_w(state->m_adpcm2, data & 2);
164 }
165
166
167 static WRITE8_DEVICE_HANDLER( ay8910_1_porta_w )
168 {
169 #ifdef MAME_DEBUG
170 if (data & 0x0f) popmessage("analog sound %x",data&0x0f);
171 #endif
172 }
173
174
175
176
181
182 static WRITE8_HANDLER( sound_irq_ack_w )
183 {
184 space.machine().device("iremsound")->execute().set_input_line(0, CLEAR_LINE);
185 }
186
187
188 static WRITE8_DEVICE_HANDLER( m52_adpcm_w )
189 {
190 irem_audio_state *state = get_safe_token(device);
191
192 if (offset & 1)
193 {
194 msm5205_data_w(state->m_adpcm1, data);
195 }
196 if (offset & 2)
197 {
198 if (state->m_adpcm2 != NULL)
199 msm5205_data_w(state->m_adpcm2, data);
200 }
201 }
202
203
204 static WRITE8_DEVICE_HANDLER( m62_adpcm_w )
205 {
206 irem_audio_state *state = get_safe_token(device);
207
208 device_t *adpcm = (offset & 1) ? state->m_adpcm2 : state->m_adpcm1;
209 if (adpcm != NULL)
210 msm5205_data_w(adpcm, data);
211 }
212
213
214
215
220
221 static void adpcm_int(device_t *device)
222 {
223 device_t *adpcm2 = device->machine().device("msm2");
224
225 device->machine().device("iremsound")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
226
227
228 if (adpcm2 != NULL)
229 {
230 msm5205_vclk_w(adpcm2, 1);
231 msm5205_vclk_w(adpcm2, 0);
232 }
233 }
234
235
236
237
242
243
248
249 static const ay8910_interface irem_ay8910_interface_1 =
250 {
251 AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT,
252 {470, 0, 0},
253 DEVCB_DRIVER_MEMBER(driver_device, soundlatch_byte_r),
254 DEVCB_NULL,
255 DEVCB_NULL,
256 DEVCB_DEVICE_HANDLER("irem_audio", ay8910_0_portb_w)
257 };
258
259 static const ay8910_interface irem_ay8910_interface_2 =
260 {
261 AY8910_SINGLE_OUTPUT | AY8910_DISCRETE_OUTPUT,
262 {470, 0, 0},
263 DEVCB_NULL,
264 DEVCB_NULL,
265 DEVCB_HANDLER(ay8910_1_porta_w),
266 DEVCB_NULL
267 };
268
269 static const msm5205_interface irem_msm5205_interface_1 =
270 {
271 adpcm_int,
272 MSM5205_S96_4B
273 };
274
275 static const msm5205_interface irem_msm5205_interface_2 =
276 {
277 0,
278 MSM5205_SEX_4B
279 };
280
281
287
288
291
292 #define M52_R9 560
293 #define M52_R10 330
294 #define M52_R12 RES_K(10)
295 #define M52_R13 RES_K(10)
296 #define M52_R14 RES_K(10)
297 #define M52_R15 RES_K(2.2)
298 #define M52_R19 RES_K(10)
299 #define M52_R22 RES_K(47)
300 #define M52_R23 RES_K(2.2)
301 #define M52_R25 RES_K(10)
302 #define M52_VR1 RES_K(50)
303
304 #define M52_C28 CAP_U(1)
305 #define M52_C30 CAP_U(0.022)
306 #define M52_C32 CAP_U(0.022)
307 #define M52_C35 CAP_U(47)
308 #define M52_C37 CAP_U(0.1)
309 #define M52_C38 CAP_U(0.0068)
310
311
317
318 static const discrete_mixer_desc m52_sound_c_stage1 =
319 {DISC_MIXER_IS_RESISTOR,
320 {M52_R19, M52_R22, M52_R23 },
321 { 0, 0, 0 },
322 {M52_C37, 0, 0 },
323 0, 0,
324 M52_C35*0,
325 0,
326 0, 1};
327
328 static const discrete_op_amp_filt_info m52_sound_c_sallen_key =
329 { M52_R13, M52_R14, 0, 0, 0,
330 M52_C32, M52_C38, 0
331 };
332
333 static const discrete_mixer_desc m52_sound_c_mix1 =
334 {DISC_MIXER_IS_RESISTOR,
335 {M52_R25, M52_R15 },
336 { 0, 0 },
337 { 0, 0 },
338 0, M52_VR1,
339 0,
340 CAP_U(1),
341 0, 1};
342
343 static DISCRETE_SOUND_START( m52_sound_c )
344
345
346 DISCRETE_INPUTX_STREAM(NODE_01, 0, 1.0, 0)
347
348 DISCRETE_INPUTX_STREAM(NODE_02, 1, 1.0, 0)
349
350 DISCRETE_INPUTX_STREAM(NODE_03, 2, 1.0, 0)
351
352
353 DISCRETE_ADDER2(NODE_09, 1, NODE_01, NODE_02)
354 DISCRETE_DIVIDE(NODE_10, 1, NODE_09, 2.0)
355
356
357 DISCRETE_MIXER3(NODE_20, 1, NODE_03, 32767.0, 0, &m52_sound_c_stage1)
358
359
360
361 DISCRETE_RCFILTER(NODE_25, NODE_20, M52_R12, M52_C30)
362 DISCRETE_SALLEN_KEY_FILTER(NODE_30, 1, NODE_25, DISC_SALLEN_KEY_LOW_PASS, &m52_sound_c_sallen_key)
363
364
365 DISCRETE_MIXER2(NODE_40, 1, NODE_10, NODE_25, &m52_sound_c_mix1)
366 DISCRETE_CRFILTER(NODE_45, NODE_40, M52_R10+M52_R9, M52_C28)
367
368 DISCRETE_OUTPUT(NODE_40, 18.0)
369
370 DISCRETE_SOUND_END
371
372
377
378
379
380 static ADDRESS_MAP_START( m52_small_sound_map, AS_PROGRAM, 8, driver_device )
381 ADDRESS_MAP_GLOBAL_MASK(0x7fff)
382 AM_RANGE(0x0000, 0x0fff) AM_DEVWRITE_LEGACY("irem_audio", m52_adpcm_w)
383 AM_RANGE(0x1000, 0x1fff) AM_WRITE_LEGACY(sound_irq_ack_w)
384 AM_RANGE(0x2000, 0x7fff) AM_ROM
385 ADDRESS_MAP_END
386
387 static ADDRESS_MAP_START( m52_large_sound_map, AS_PROGRAM, 8, driver_device )
388 AM_RANGE(0x0000, 0x1fff) AM_DEVWRITE_LEGACY("irem_audio", m52_adpcm_w)
389 AM_RANGE(0x2000, 0x3fff) AM_WRITE_LEGACY(sound_irq_ack_w)
390 AM_RANGE(0x4000, 0xffff) AM_ROM
391 ADDRESS_MAP_END
392
393
394
395 static ADDRESS_MAP_START( m62_sound_map, AS_PROGRAM, 8, driver_device )
396 AM_RANGE(0x0800, 0x0800) AM_MIRROR(0xf7fc) AM_WRITE_LEGACY(sound_irq_ack_w)
397 AM_RANGE(0x0801, 0x0802) AM_MIRROR(0xf7fc) AM_DEVWRITE_LEGACY("irem_audio", m62_adpcm_w)
398 AM_RANGE(0x4000, 0xffff) AM_ROM
399 ADDRESS_MAP_END
400
401
402 static ADDRESS_MAP_START( irem_sound_portmap, AS_IO, 8, driver_device )
403 AM_RANGE(M6801_PORT1, M6801_PORT1) AM_DEVREADWRITE_LEGACY("irem_audio", m6803_port1_r, m6803_port1_w)
404 AM_RANGE(M6801_PORT2, M6801_PORT2) AM_DEVREADWRITE_LEGACY("irem_audio", m6803_port2_r, m6803_port2_w)
405 ADDRESS_MAP_END
406
407
408
409
414
415 static MACHINE_CONFIG_FRAGMENT( irem_audio_base )
416
417
418 MCFG_CPU_ADD("iremsound", M6803, XTAL_3_579545MHz)
419 MCFG_CPU_IO_MAP(irem_sound_portmap)
420
421
422 MCFG_SPEAKER_STANDARD_MONO("mono")
423
424 MCFG_SOUND_ADD("irem_audio", IREM_AUDIO, 0)
425
426 MCFG_SOUND_ADD("ay1", AY8910, XTAL_3_579545MHz/4)
427 MCFG_SOUND_CONFIG(irem_ay8910_interface_1)
428 MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
429
430 MCFG_SOUND_ADD("ay2", AY8910, XTAL_3_579545MHz/4)
431 MCFG_SOUND_CONFIG(irem_ay8910_interface_2)
432 MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
433
434 MCFG_SOUND_ADD("msm1", MSM5205, XTAL_384kHz)
435 MCFG_SOUND_CONFIG(irem_msm5205_interface_1)
436 MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
437
438 MCFG_SOUND_ADD("msm2", MSM5205, XTAL_384kHz)
439 MCFG_SOUND_CONFIG(irem_msm5205_interface_2)
440 MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80)
441 MACHINE_CONFIG_END
442
443 MACHINE_CONFIG_FRAGMENT( m52_sound_c_audio )
444
445
446 MCFG_CPU_ADD("iremsound", M6803, XTAL_3_579545MHz)
447 MCFG_CPU_IO_MAP(irem_sound_portmap)
448 MCFG_CPU_PROGRAM_MAP(m52_small_sound_map)
449
450
451 MCFG_SPEAKER_STANDARD_MONO("mono")
452
453 MCFG_SOUND_ADD("irem_audio", IREM_AUDIO, 0)
454
455 MCFG_SOUND_ADD("ay1", AY8910, XTAL_3_579545MHz/4)
456 MCFG_SOUND_CONFIG(irem_ay8910_interface_1)
457 MCFG_SOUND_ROUTE_EX(0, "filtermix", 1.0, 0)
458
459 MCFG_SOUND_ADD("ay2", AY8910, XTAL_3_579545MHz/4)
460 MCFG_SOUND_CONFIG(irem_ay8910_interface_2)
461 MCFG_SOUND_ROUTE_EX(0, "filtermix", 1.0, 1)
462
463 MCFG_SOUND_ADD("msm1", MSM5205, XTAL_384kHz)
464 MCFG_SOUND_CONFIG(irem_msm5205_interface_1)
465 MCFG_SOUND_ROUTE_EX(0, "filtermix", 1.0, 2)
466
467 MCFG_SOUND_ADD("filtermix", DISCRETE, 0)
468 MCFG_SOUND_CONFIG_DISCRETE(m52_sound_c)
469 MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
470
471 MACHINE_CONFIG_END
472
473 MACHINE_CONFIG_DERIVED( m52_large_audio, irem_audio_base )
474
475
476 MCFG_CPU_MODIFY("iremsound")
477 MCFG_CPU_PROGRAM_MAP(m52_large_sound_map)
478 MACHINE_CONFIG_END
479
480
481 MACHINE_CONFIG_DERIVED( m62_audio, irem_audio_base )
482
483
484 MCFG_CPU_MODIFY("iremsound")
485 MCFG_CPU_PROGRAM_MAP(m62_sound_map)
486 MACHINE_CONFIG_END
487
488 const device_type IREM_AUDIO = &device_creator<irem_audio_device>;
489
490 irem_audio_device::irem_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
491 : device_t(mconfig, IREM_AUDIO, "Irem Audio", tag, owner, clock),
492 device_sound_interface(mconfig, *this)
493 {
494 m_token = global_alloc_clear(irem_audio_state);
495 }
496
497
498
499
500
501
502
503 void irem_audio_device::device_config_complete()
504 {
505 }
506
507
508
509
510
511 void irem_audio_device::device_start()
512 {
513 DEVICE_START_NAME( irem_audio )(this);
514 }
515
516
517
518
519
520 void irem_audio_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
521 {
522
523 fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
524 }