1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 #ifndef MAME_AUDIO_EXIDY_H
4 #define MAME_AUDIO_EXIDY_H
5 
6 #pragma once
7 
8 #include "machine/6532riot.h"
9 #include "machine/6821pia.h"
10 #include "machine/timer.h"
11 #include "sound/flt_biquad.h"
12 #include "sound/hc55516.h"
13 #include "sound/tms5220.h"
14 
15 
16 class exidy_sound_device : public device_t,
17 									public device_sound_interface
18 {
19 	/* 6840 variables */
20 	struct sh6840_timer_channel
21 	{
22 		uint8_t   cr;
23 		uint8_t   state;
24 		uint8_t   leftovers;
25 		uint16_t  timer;
26 		uint32_t  clocks;
27 		union
28 		{
29 #ifdef LSB_FIRST
30 			struct { uint8_t l, h; } b;
31 #else
32 			struct { uint8_t h, l; } b;
33 #endif
34 			uint16_t w;
35 		} counter;
36 	};
37 
38 public:
39 	exidy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
~exidy_sound_device()40 	~exidy_sound_device() {}
41 
42 	uint8_t sh6840_r(offs_t offset);
43 	void sh6840_w(offs_t offset, uint8_t data);
44 	void sfxctrl_w(offs_t offset, uint8_t data);
45 
46 protected:
47 	exidy_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
48 
49 	// device-level overrides
50 	virtual void device_start() override;
51 	virtual void device_reset() override;
52 
53 	void common_sh_start();
54 	void common_sh_reset();
55 
56 	void sh6840_register_state_globals();
57 
58 	// sound stream update overrides
59 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
60 	virtual s32 generate_music_sample();
61 
62 	static inline void sh6840_apply_clock(sh6840_timer_channel *t, int clocks);
63 
64 	/* sound streaming variables */
65 	sound_stream *m_stream;
66 	double m_freq_to_step;
67 
68 private:
69 	// internal state
70 	sh6840_timer_channel m_sh6840_timer[3];
71 	int16_t m_sh6840_volume[3];
72 	uint8_t m_sh6840_MSB_latch;
73 	uint8_t m_sh6840_LSB_latch;
74 	uint8_t m_sh6840_LFSR_oldxor;
75 	uint32_t m_sh6840_LFSR_0;
76 	uint32_t m_sh6840_LFSR_1;
77 	uint32_t m_sh6840_LFSR_2;
78 	uint32_t m_sh6840_LFSR_3;
79 	uint32_t m_sh6840_clocks_per_sample;
80 	uint32_t m_sh6840_clock_count;
81 
82 	uint8_t m_sfxctrl;
83 
84 	inline int sh6840_update_noise(int clocks);
85 };
86 
DECLARE_DEVICE_TYPE(EXIDY,exidy_sound_device)87 DECLARE_DEVICE_TYPE(EXIDY, exidy_sound_device)
88 
89 class exidy_sh8253_sound_device : public exidy_sound_device
90 {
91 	struct sh8253_timer_channel
92 	{
93 		uint8_t   clstate;
94 		uint8_t   enable;
95 		uint16_t  count;
96 		uint32_t  step;
97 		uint32_t  fraction;
98 	};
99 
100 protected:
101 	exidy_sh8253_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
102 
103 	// device-level overrides
104 	virtual void device_start() override;
105 	virtual void device_reset() override;
106 
107 	virtual s32 generate_music_sample() override;
108 
109 	void r6532_porta_w(uint8_t data);
110 	uint8_t r6532_porta_r();
111 	void r6532_portb_w(uint8_t data);
112 	uint8_t r6532_portb_r();
113 
114 	void sh8253_w(offs_t offset, uint8_t data);
115 
116 	void sh8253_register_state_globals();
117 
118 	/* 8253 variables */
119 	sh8253_timer_channel m_sh8253_timer[3];
120 
121 	/* 6532 variables */
122 	required_device<riot6532_device> m_riot;
123 
124 	/* 5220/CVSD variables */
125 	optional_device<mc3417_device> m_cvsd;
126 	optional_device<filter_biquad_device> m_cvsd_filter;
127 	optional_device<filter_biquad_device> m_cvsd_filter2;
128 	optional_device<cpu_device> m_cvsdcpu;
129 	optional_device<tms5220_device> m_tms;
130 	required_device<pia6821_device> m_pia;
131 };
132 
133 class venture_sound_device : public exidy_sh8253_sound_device
134 {
135 public:
136 	venture_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
137 
138 	// configuration access
pa_callback()139 	auto pa_callback() { return m_pa_callback.bind(); }
pb_callback()140 	auto pb_callback() { return m_pb_callback.bind(); }
ca2_callback()141 	auto ca2_callback() { return m_ca2_callback.bind(); }
cb2_callback()142 	auto cb2_callback() { return m_cb2_callback.bind(); }
143 
144 	// external access
145 	void pa_w(uint8_t data);
146 	void pb_w(uint8_t data);
147 	DECLARE_WRITE_LINE_MEMBER(ca_w);
148 	DECLARE_WRITE_LINE_MEMBER(cb_w);
149 
150 protected:
151 	venture_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
152 
153 	// device-level overrides
154 	virtual void device_resolve_objects() override;
155 	virtual void device_add_mconfig(machine_config &config) override;
156 
157 	void venture_audio_map(address_map &map);
158 
159 private:
160 	void filter_w(uint8_t data);
161 
162 	void pia_pa_w(uint8_t data);
163 	void pia_pb_w(uint8_t data);
164 	DECLARE_WRITE_LINE_MEMBER(pia_ca2_w);
165 	DECLARE_WRITE_LINE_MEMBER(pia_cb2_w);
166 
167 	void venture_audio(machine_config &config);
168 
169 	devcb_write8 m_pa_callback;
170 	devcb_write8 m_pb_callback;
171 	devcb_write_line m_ca2_callback;
172 	devcb_write_line m_cb2_callback;
173 };
174 
DECLARE_DEVICE_TYPE(EXIDY_VENTURE,venture_sound_device)175 DECLARE_DEVICE_TYPE(EXIDY_VENTURE, venture_sound_device)
176 
177 class mtrap_sound_device : public venture_sound_device
178 {
179 public:
180 	mtrap_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
181 
182 protected:
183 	// device-level overrides
184 	virtual void device_start() override;
185 	virtual void device_add_mconfig(machine_config &config) override;
186 
187 private:
188 	required_device<timer_device> m_cvsd_timer;
189 	TIMER_DEVICE_CALLBACK_MEMBER(cvsd_timer);
190 	void voiceio_w(offs_t offset, uint8_t data);
191 	uint8_t voiceio_r(offs_t offset);
192 	bool m_cvsd_clk;
193 
194 	void cvsd_map(address_map &map);
195 	void cvsd_iomap(address_map &map);
196 };
197 
DECLARE_DEVICE_TYPE(EXIDY_MTRAP,mtrap_sound_device)198 DECLARE_DEVICE_TYPE(EXIDY_MTRAP, mtrap_sound_device)
199 
200 class victory_sound_device : public exidy_sh8253_sound_device
201 {
202 public:
203 	victory_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
204 
205 	// external access
206 	uint8_t response_r();
207 	uint8_t status_r();
208 	void command_w(uint8_t data);
209 
210 protected:
211 	// device-level overrides
212 	virtual void device_start() override;
213 	virtual void device_reset() override;
214 	virtual void device_add_mconfig(machine_config &config) override;
215 
216 private:
217 	DECLARE_WRITE_LINE_MEMBER(irq_clear_w);
218 	DECLARE_WRITE_LINE_MEMBER(main_ack_w);
219 
220 	void victory_audio_map(address_map &map);
221 
222 	// internal state
223 	uint8_t m_victory_sound_response_ack_clk; /* 7474 @ F4 */
224 
225 	TIMER_CALLBACK_MEMBER( delayed_command_w );
226 
227 	int m_pia_ca1;
228 	int m_pia_cb1;
229 };
230 
231 DECLARE_DEVICE_TYPE(EXIDY_VICTORY, victory_sound_device)
232 
233 #endif // MAME_AUDIO_EXIDY_H
234