1 // license:BSD-3-Clause
2 // copyright-holders:Mike Harris
3 /***************************************************************************
4 
5     bally.h
6 
7     Functions to emulate the various Bally pinball sound boards.
8 
9 ***************************************************************************/
10 #ifndef MAME_AUDIO_BALLY_H
11 #define MAME_AUDIO_BALLY_H
12 
13 #pragma once
14 
15 
16 #include "cpu/m6800/m6800.h"
17 #include "cpu/m6800/m6801.h"
18 #include "cpu/m6809/m6809.h"
19 #include "machine/6821pia.h"
20 #include "machine/timer.h"
21 #include "sound/ay8910.h"
22 #include "sound/dac.h"
23 #include "sound/discrete.h"
24 #include "sound/flt_rc.h"
25 #include "sound/hc55516.h"
26 #include "sound/tms5220.h"
27 
28 
29 
30 //**************************************************************************
31 //  GLOBAL VARIABLES
32 //**************************************************************************
33 
DECLARE_DEVICE_TYPE(BALLY_AS2888,bally_as2888_device)34 DECLARE_DEVICE_TYPE(BALLY_AS2888,           bally_as2888_device)
35 DECLARE_DEVICE_TYPE(BALLY_AS3022,           bally_as3022_device)
36 DECLARE_DEVICE_TYPE(BALLY_SOUNDS_PLUS,      bally_sounds_plus_device)
37 DECLARE_DEVICE_TYPE(BALLY_CHEAP_SQUEAK,     bally_cheap_squeak_device)
38 DECLARE_DEVICE_TYPE(BALLY_SQUAWK_N_TALK,    bally_squawk_n_talk_device)
39 DECLARE_DEVICE_TYPE(BALLY_SQUAWK_N_TALK_AY, bally_squawk_n_talk_ay_device)
40 
41 
42 //**************************************************************************
43 //  TYPE DEFINITIONS
44 //**************************************************************************
45 
46 // ======================> bally_as2888_device
47 
48 class bally_as2888_device : public device_t, public device_mixer_interface
49 {
50 public:
51 	bally_as2888_device(
52 			const machine_config &mconfig,
53 			const char *tag,
54 			device_t *owner,
55 			uint32_t clock = 0) :
56 		bally_as2888_device(mconfig, BALLY_AS2888, tag, owner)
57 	{ }
58 
59 	// read/write
60 	void sound_select(uint8_t data);
61 	DECLARE_WRITE_LINE_MEMBER(sound_int);
62 
63 	void as2888_map(address_map &map);
64 
65 protected:
66 	bally_as2888_device(
67 			const machine_config &mconfig,
68 			device_type type,
69 			const char *tag,
70 			device_t *owner) :
71 		device_t(mconfig, type, tag, owner, 0),
72 		device_mixer_interface(mconfig, *this),
73 		m_snd_prom(*this, "sound"),
74 		m_discrete(*this, "discrete"),
75 		m_timer_s_freq(*this, "timer_s_freq"),
76 		m_snd_sustain_timer(*this, "timer_as2888")
77 	{ }
78 
79 	// device-level overrides
80 	virtual void device_add_mconfig(machine_config &config) override;
81 	virtual void device_start() override;
82 
83 private:
84 	uint8_t m_sound_select;
85 	uint8_t m_snd_sel;
86 	uint8_t m_snd_tone_gen;
87 	uint8_t m_snd_div;
88 	required_region_ptr<uint8_t> m_snd_prom;
89 	required_device<discrete_sound_device> m_discrete;
90 	required_device<timer_device> m_timer_s_freq;
91 	required_device<timer_device> m_snd_sustain_timer;
92 
93 
94 	// internal communications
95 	TIMER_CALLBACK_MEMBER(sound_select_sync);
96 	TIMER_CALLBACK_MEMBER(sound_int_sync);
97 	TIMER_DEVICE_CALLBACK_MEMBER(timer_s);
98 	TIMER_DEVICE_CALLBACK_MEMBER(timer_as2888);
99 };
100 
101 
102 // ======================> bally_as3022_device
103 
104 class bally_as3022_device : public device_t, public device_mixer_interface
105 {
106 public:
107 	bally_as3022_device(
108 			const machine_config &mconfig,
109 			const char *tag,
110 			device_t *owner,
111 			uint32_t clock = 3'579'545) :
bally_as3022_device(mconfig,BALLY_AS3022,tag,owner,clock)112 		bally_as3022_device(mconfig, BALLY_AS3022, tag, owner, clock)
113 	{ }
114 
115 	// read/write
116 	DECLARE_INPUT_CHANGED_MEMBER(sw1);
117 	void sound_select(uint8_t data);
118 	DECLARE_WRITE_LINE_MEMBER(sound_int);
119 
120 	void as3022_map(address_map &map);
121 
122 protected:
bally_as3022_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)123 	bally_as3022_device(
124 			const machine_config &mconfig,
125 			device_type type,
126 			const char *tag,
127 			device_t *owner,
128 			uint32_t clock) :
129 		device_t(mconfig, type, tag, owner, clock),
130 		device_mixer_interface(mconfig, *this),
131 		m_cpu(*this, "cpu"),
132 		m_pia(*this, "pia"),
133 		m_ay_filters(*this, "ay_filter%u", 0),
134 		m_ay(*this, "ay"),
135 		m_mc3417_filter(*this, "mc3417_filter"),
136 		m_mc3417(*this, "mc3417")
137 	{ }
138 
139 	// device-level overrides
140 	virtual void device_add_mconfig(machine_config &config) override;
141 	virtual void device_start() override;
142 	virtual ioport_constructor device_input_ports() const override;
143 
144 	// devices
145 	// The schematics list an optional 555, but it never seemed to be used
146 	required_device<m6808_cpu_device> m_cpu;
147 	required_device<pia6821_device> m_pia;
148 	required_device_array<filter_rc_device, 3> m_ay_filters;
149 	required_device<ay8910_device> m_ay;
150 	optional_device<filter_rc_device> m_mc3417_filter;
151 	optional_device<mc3417_device> m_mc3417;
152 
153 	// overwridden by children
154 	void pia_portb_w(uint8_t data);
155 
156 private:
157 	bool m_bc1;
158 	bool m_bdir;
159 	uint8_t m_sound_select;
160 	uint8_t m_ay_data;
161 
162 	// internal communications
163 	TIMER_CALLBACK_MEMBER(sound_select_sync);
164 	TIMER_CALLBACK_MEMBER(sound_int_sync);
165 	uint8_t pia_porta_r();
166 	void pia_porta_w(uint8_t data);
167 	DECLARE_WRITE_LINE_MEMBER(pia_cb2_w);
168 	DECLARE_WRITE_LINE_MEMBER(pia_irq_w);
169 	uint8_t ay_io_r();
170 
171 	void update_ay_bus();
172 };
173 
174 
175 // ======================> bally_sounds_plus_device
176 class bally_sounds_plus_device : public bally_as3022_device
177 {
178 public:
179 	bally_sounds_plus_device(
180 			const machine_config &mconfig,
181 			const char *tag,
182 			device_t *owner,
183 			uint32_t clock = 3'579'545) :
bally_as3022_device(mconfig,BALLY_SOUNDS_PLUS,tag,owner,clock)184 		bally_as3022_device(mconfig, BALLY_SOUNDS_PLUS, tag, owner, clock)
185 	{ }
186 
187 	void sounds_plus_map(address_map &map);
188 
189 protected:
190 	// device-level overrides
191 	virtual void device_add_mconfig(machine_config &config) override;
192 
193 private:
194 	// internal communications
195 	void vocalizer_pia_portb_w(uint8_t data);
196 };
197 
198 
199 // ======================> bally_cheap_squeak_device
200 
201 class bally_cheap_squeak_device : public device_t, public device_mixer_interface
202 {
203 public:
204 	bally_cheap_squeak_device(
205 			const machine_config &mconfig,
206 			const char *tag,
207 			device_t *owner,
208 			uint32_t clock = 3'579'545) :
bally_cheap_squeak_device(mconfig,BALLY_CHEAP_SQUEAK,tag,owner,clock)209 		bally_cheap_squeak_device(mconfig, BALLY_CHEAP_SQUEAK, tag, owner, clock)
210 	{ }
211 
sound_ack_w_handler()212 	auto sound_ack_w_handler() { return m_sound_ack_w_handler.bind(); }
213 
214 	// read/write
215 	DECLARE_INPUT_CHANGED_MEMBER(sw1);
216 	void sound_select(uint8_t data);
217 	DECLARE_WRITE_LINE_MEMBER(sound_int);
218 
219 	void cheap_squeak_map(address_map &map);
220 
221 protected:
bally_cheap_squeak_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)222 	bally_cheap_squeak_device(
223 			const machine_config &mconfig,
224 			device_type type,
225 			const char *tag,
226 			device_t *owner,
227 			uint32_t clock) :
228 		device_t(mconfig, type, tag, owner, clock),
229 		device_mixer_interface(mconfig, *this),
230 		m_cpu(*this, "cpu"),
231 		m_dac(*this, "dac"),
232 		m_sound_ack_w_handler(*this)
233 	{ }
234 
235 	// device-level overrides
236 	virtual void device_add_mconfig(machine_config &config) override;
237 	virtual void device_start() override;
238 	virtual ioport_constructor device_input_ports() const override;
239 
240 	// devices
241 	required_device<m6803_cpu_device> m_cpu;
242 	required_device<dac_byte_interface> m_dac;
243 
244 private:
245 	uint8_t m_sound_select;
246 	bool m_sound_int;
247 	bool m_sound_ack;
248 
249 	devcb_write_line m_sound_ack_w_handler;
250 
251 	// internal communications
252 	TIMER_CALLBACK_MEMBER(sound_select_sync);
253 	TIMER_CALLBACK_MEMBER(sound_int_sync);
254 	void out_p1_cb(uint8_t data);
255 	uint8_t in_p2_cb();
256 	void out_p2_cb(uint8_t data);
257 
258 	void update_led();
259 };
260 
261 // ======================> bally_squawk_n_talk_device
262 
263 // This board comes in different configurations, with or without the DAC and/or AY8910.
264 
265 class bally_squawk_n_talk_device : public device_t, public device_mixer_interface
266 {
267 public:
268 	bally_squawk_n_talk_device(
269 			const machine_config &mconfig,
270 			const char *tag,
271 			device_t *owner,
272 			uint32_t clock = 3'579'545) :
bally_squawk_n_talk_device(mconfig,BALLY_SQUAWK_N_TALK,tag,owner,clock)273 		bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK, tag, owner, clock)
274 	{ }
275 
276 	// read/write
277 	DECLARE_INPUT_CHANGED_MEMBER(sw1);
278 	void sound_select(uint8_t data);
279 	DECLARE_WRITE_LINE_MEMBER(sound_int);
280 
281 	void squawk_n_talk_map(address_map &map);
282 
283 protected:
bally_squawk_n_talk_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)284 	bally_squawk_n_talk_device(
285 			const machine_config &mconfig,
286 			device_type type,
287 			const char *tag,
288 			device_t *owner,
289 			uint32_t clock) :
290 		device_t(mconfig, type, tag, owner, clock),
291 		device_mixer_interface(mconfig, *this),
292 		m_cpu(*this, "cpu"),
293 		m_pia1(*this, "pia1"),
294 		m_pia2(*this, "pia2"),
295 		m_dac_filter(*this, "dac_filter"),
296 		m_dac(*this, "dac"),
297 		m_speech_filter(*this, "speech_filter"),
298 		m_tms5200(*this, "tms5200"),
299 		m_ay_filters(*this, "ay_filter%u", 0),
300 		m_ay(*this, "ay")
301 	{ }
302 
303 	// device-level overrides
304 	virtual void device_add_mconfig(machine_config &config) override;
305 	virtual void device_start() override;
306 	virtual ioport_constructor device_input_ports() const override;
307 
308 	// devices
309 	required_device<m6802_cpu_device> m_cpu;
310 	required_device<pia6821_device> m_pia1;
311 	required_device<pia6821_device> m_pia2;
312 	required_device<filter_rc_device> m_dac_filter;
313 	required_device<dac_byte_interface> m_dac;
314 	required_device<filter_rc_device> m_speech_filter;
315 	required_device<tms5200_device> m_tms5200;
316 	optional_device_array<filter_rc_device, 3> m_ay_filters;
317 	optional_device<ay8910_device> m_ay;
318 
319 	uint8_t m_sound_select;
320 
321 	uint8_t pia2_porta_r();
322 
323 private:
324 	// internal communications
325 	TIMER_CALLBACK_MEMBER(sound_select_sync);
326 	TIMER_CALLBACK_MEMBER(sound_int_sync);
327 	void pia1_portb_w(uint8_t data);
328 	DECLARE_WRITE_LINE_MEMBER(pia2_ca2_w);
329 	DECLARE_WRITE_LINE_MEMBER(pia_irq_w);
330 };
331 
332 
333 class bally_squawk_n_talk_ay_device : public bally_squawk_n_talk_device
334 {
335 public:
336 	bally_squawk_n_talk_ay_device(
337 			const machine_config &mconfig,
338 			const char *tag,
339 			device_t *owner,
340 			uint32_t clock = 3'579'545) :
bally_squawk_n_talk_device(mconfig,BALLY_SQUAWK_N_TALK_AY,tag,owner,clock)341 		bally_squawk_n_talk_device(mconfig, BALLY_SQUAWK_N_TALK_AY, tag, owner, clock)
342 	{ }
343 
344 protected:
345 	// device-level overrides
346 	virtual void device_add_mconfig(machine_config &config) override;
347 	virtual void device_start() override;
348 
349 	uint8_t pia2_porta_r();
350 
351 private:
352 	bool m_bc1;
353 	bool m_bdir;
354 	uint8_t m_ay_data;
355 
356 	void pia2_porta_w(uint8_t data);
357 	void pia2_portb_w(uint8_t data);
358 	DECLARE_WRITE_LINE_MEMBER(pia2_cb2_w);
359 	uint8_t ay_io_r();
360 
361 	void update_ay_bus();
362 };
363 
364 
365 #endif // MAME_AUDIO_BALLY_H
366