1 // license:BSD-3-Clause
2 // copyright-holders:Ryan Holtz
3 /*****************************************************************************
4 
5     SunPlus SPG2xx-series SoC peripheral emulation (Audio)
6 
7 **********************************************************************/
8 
9 #ifndef MAME_MACHINE_SPG2XX_AUDIO_H
10 #define MAME_MACHINE_SPG2XX_AUDIO_H
11 
12 #pragma once
13 
14 #include "sound/okiadpcm.h"
15 #include "cpu/unsp/unsp.h"
16 
17 class spg2xx_audio_device : public device_t, public device_sound_interface
18 {
19 public:
20 	spg2xx_audio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
21 	spg2xx_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
22 
space_read_callback()23 	auto space_read_callback() { return m_space_read_cb.bind(); }
write_irq_callback()24 	auto write_irq_callback() { return m_irq_cb.bind(); }
channel_irq_callback()25 	auto channel_irq_callback() { return m_ch_irq_cb.bind(); }
26 
27 	uint16_t audio_r(offs_t offset);
28 	virtual void audio_w(offs_t offset, uint16_t data);
29 	uint16_t audio_ctrl_r(offs_t offset);
30 	void audio_ctrl_w(offs_t offset, uint16_t data);
31 	uint16_t audio_phase_r(offs_t offset);
32 	void audio_phase_w(offs_t offset, uint16_t data);
33 
34 protected:
35 	// sound stream update overrides
36 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
37 
38 	void audio_beat_tick();
39 	void audio_rampdown_tick(const uint32_t channel);
40 	bool audio_envelope_tick(const uint32_t channel);
41 	inline uint32_t get_rampdown_frame_count(const uint32_t channel);
42 	inline uint32_t get_envclk_frame_count(const uint32_t channel);
43 
44 	// Audio getters
get_channel_enable(const offs_t channel)45 	bool get_channel_enable(const offs_t channel) const { return m_audio_ctrl_regs[AUDIO_CHANNEL_ENABLE] & (1 << channel); }
get_channel_status(const offs_t channel)46 	bool get_channel_status(const offs_t channel) const { return m_audio_ctrl_regs[AUDIO_CHANNEL_STATUS] & (1 << channel); }
get_manual_envelope_enable(const offs_t channel)47 	bool get_manual_envelope_enable(const offs_t channel) const { return m_audio_ctrl_regs[AUDIO_CHANNEL_ENV_MODE] & (1 << channel); }
get_auto_envelope_enable(const offs_t channel)48 	bool get_auto_envelope_enable(const offs_t channel) const { return !get_manual_envelope_enable(channel); }
49 	uint32_t get_envelope_clock(const offs_t channel) const;
get_vol_sel()50 	uint16_t get_vol_sel() const { return (m_audio_ctrl_regs[AUDIO_CONTROL] & AUDIO_CONTROL_VOLSEL_MASK) >> AUDIO_CONTROL_VOLSEL_SHIFT; }
51 
52 	// Audio Mode getters
get_wave_addr_high(const offs_t channel)53 	uint16_t get_wave_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_WADDR_HIGH_MASK; }
get_loop_addr_high(const offs_t channel)54 	uint16_t get_loop_addr_high(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_LADDR_HIGH_MASK) >> AUDIO_LADDR_HIGH_SHIFT; }
get_tone_mode(const offs_t channel)55 	uint16_t get_tone_mode(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_TONE_MODE_MASK) >> AUDIO_TONE_MODE_SHIFT; }
get_16bit_bit(const offs_t channel)56 	virtual uint16_t get_16bit_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_16M_MASK) ? 1 : 0; }
get_adpcm_bit(const offs_t channel)57 	virtual uint16_t get_adpcm_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_MODE] & AUDIO_ADPCM_MASK) ? 1 : 0; }
58 
59 	// Audio Pan getters
get_volume(const offs_t channel)60 	uint16_t get_volume(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_VOLUME_MASK; }
get_pan(const offs_t channel)61 	uint16_t get_pan(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_PAN_VOL] & AUDIO_PAN_MASK) >> AUDIO_PAN_SHIFT; }
62 
63 	// Audio Envelope0 Data getters
get_envelope_inc(const offs_t channel)64 	uint16_t get_envelope_inc(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_INC_MASK; }
get_envelope_sign_bit(const offs_t channel)65 	uint16_t get_envelope_sign_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_SIGN_MASK) ? 1 : 0; }
get_envelope_target(const offs_t channel)66 	uint16_t get_envelope_target(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_TARGET_MASK) >> AUDIO_ENVELOPE_TARGET_SHIFT; }
get_repeat_period_bit(const offs_t channel)67 	uint16_t get_repeat_period_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE0] & AUDIO_ENVELOPE_REPEAT_PERIOD_MASK) ? 1 : 0; }
68 
69 	// Audio Envelope Data getters
get_edd(const offs_t channel)70 	uint16_t get_edd(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & AUDIO_EDD_MASK; }
get_envelope_count(const offs_t channel)71 	uint16_t get_envelope_count(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & AUDIO_ENVELOPE_COUNT_MASK) >> AUDIO_ENVELOPE_COUNT_SHIFT; }
set_edd(const offs_t channel,uint8_t edd)72 	void set_edd(const offs_t channel, uint8_t edd) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] & ~AUDIO_EDD_MASK) | edd; }
set_envelope_count(const offs_t channel,uint16_t count)73 	void set_envelope_count(const offs_t channel, uint16_t count) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_DATA] = get_edd(channel) | (count << AUDIO_ENVELOPE_COUNT_SHIFT); }
74 
75 	// Audio Envelope1 Data getters
get_envelope_load(const offs_t channel)76 	uint16_t get_envelope_load(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_LOAD_MASK; }
get_envelope_repeat_bit(const offs_t channel)77 	uint16_t get_envelope_repeat_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_RPT_MASK) ? 1 : 0; }
get_envelope_repeat_count(const offs_t channel)78 	uint16_t get_envelope_repeat_count(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & AUDIO_ENVELOPE_RPCNT_MASK) >> AUDIO_ENVELOPE_RPCNT_SHIFT; }
set_envelope_repeat_count(const offs_t channel,const uint16_t count)79 	inline void set_envelope_repeat_count(const offs_t channel, const uint16_t count) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE1] & ~AUDIO_ENVELOPE_RPCNT_MASK) | ((count << AUDIO_ENVELOPE_RPCNT_SHIFT) & AUDIO_ENVELOPE_RPCNT_MASK); }
80 
81 	// Audio Envelope Address getters
get_envelope_addr_high(const offs_t channel)82 	uint16_t get_envelope_addr_high(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_EADDR_HIGH_MASK; }
get_audio_irq_enable_bit(const offs_t channel)83 	uint16_t get_audio_irq_enable_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_IRQ_EN_MASK) ? 1 : 0; }
get_audio_irq_addr(const offs_t channel)84 	uint16_t get_audio_irq_addr(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR_HIGH] & AUDIO_IRQ_ADDR_MASK) >> AUDIO_IRQ_ADDR_SHIFT; }
85 
86 	// Audio Envelope Loop getters
get_envelope_eaoffset(const offs_t channel)87 	uint16_t get_envelope_eaoffset(const offs_t channel) const { return m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & AUDIO_EAOFFSET_MASK; }
get_rampdown_offset(const offs_t channel)88 	uint16_t get_rampdown_offset(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & AUDIO_RAMPDOWN_OFFSET_MASK) >> AUDIO_RAMPDOWN_OFFSET_SHIFT; }
set_envelope_eaoffset(const offs_t channel,uint16_t eaoffset)89 	void set_envelope_eaoffset(const offs_t channel, uint16_t eaoffset) { m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] = (m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_LOOP_CTRL] & ~AUDIO_RAMPDOWN_OFFSET_MASK) | (eaoffset & AUDIO_EAOFFSET_MASK); }
90 
91 	// Audio ADPCM getters
get_point_number(const offs_t channel)92 	uint16_t get_point_number(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ADPCM_SEL] & AUDIO_POINT_NUMBER_MASK) >> AUDIO_POINT_NUMBER_SHIFT; }
get_adpcm36_bit(const offs_t channel)93 	uint16_t get_adpcm36_bit(const offs_t channel) const { return (m_audio_regs[(channel << 4) | AUDIO_ADPCM_SEL] & AUDIO_ADPCM36_MASK) ? 1 : 0; }
94 
95 	// Audio high-word getters
get_phase_high(const offs_t channel)96 	uint16_t get_phase_high(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_HIGH] & AUDIO_PHASE_HIGH_MASK; }
get_phase_accum_high(const offs_t channel)97 	uint16_t get_phase_accum_high(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_ACCUM_HIGH] & AUDIO_PHASE_ACCUM_HIGH_MASK; }
get_target_phase_high(const offs_t channel)98 	uint16_t get_target_phase_high(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_TARGET_PHASE_HIGH] & AUDIO_TARGET_PHASE_HIGH_MASK; }
get_rampdown_clock(const offs_t channel)99 	uint16_t get_rampdown_clock(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_RAMP_DOWN_CLOCK] & AUDIO_RAMP_DOWN_CLOCK_MASK; }
100 
101 	// Audio ADPCM getters
get_phase_offset(const offs_t channel)102 	uint16_t get_phase_offset(const offs_t channel) const { return m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_OFFSET_MASK; }
get_phase_sign_bit(const offs_t channel)103 	uint16_t get_phase_sign_bit(const offs_t channel) const { return (m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_SIGN_MASK) >> AUDIO_PHASE_SIGN_SHIFT; }
get_phase_time_step(const offs_t channel)104 	uint16_t get_phase_time_step(const offs_t channel) const { return (m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_CTRL] & AUDIO_PHASE_TIME_STEP_MASK) >> AUDIO_PHASE_TIME_STEP_SHIFT; }
105 
106 	// Audio combined getters
get_phase(const offs_t channel)107 	virtual uint32_t get_phase(const offs_t channel) const { return ((uint32_t)get_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE]; }
get_phase_accum(const offs_t channel)108 	uint32_t get_phase_accum(const offs_t channel) const { return ((uint32_t)get_phase_accum_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_PHASE_ACCUM]; }
get_target_phase(const offs_t channel)109 	uint32_t get_target_phase(const offs_t channel) const { return ((uint32_t)get_target_phase_high(channel) << 16) | m_audio_phase_regs[(channel << 4) | AUDIO_TARGET_PHASE]; }
110 
get_wave_addr(const offs_t channel)111 	uint32_t get_wave_addr(const offs_t channel) const { return ((uint32_t)get_wave_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_WAVE_ADDR]; }
get_loop_addr(const offs_t channel)112 	uint32_t get_loop_addr(const offs_t channel) const { return ((uint32_t)get_loop_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_LOOP_ADDR]; }
get_envelope_addr(const offs_t channel)113 	uint32_t get_envelope_addr(const offs_t channel) const { return ((uint32_t)get_envelope_addr_high(channel) << 16) | m_audio_regs[(channel << 4) | AUDIO_ENVELOPE_ADDR]; }
114 
115 	enum // at audio write offset 0x000 in spg2xx
116 	{
117 		AUDIO_WAVE_ADDR             = 0x000,
118 
119 		AUDIO_MODE                  = 0x001,
120 		AUDIO_WADDR_HIGH_MASK       = 0x003f,
121 		AUDIO_LADDR_HIGH_MASK       = 0x0fc0,
122 		AUDIO_LADDR_HIGH_SHIFT      = 6,
123 		AUDIO_TONE_MODE_MASK        = 0x3000,
124 		AUDIO_TONE_MODE_SHIFT       = 12,
125 		AUDIO_TONE_MODE_SW          = 0,
126 		AUDIO_TONE_MODE_HW_ONESHOT  = 1,
127 		AUDIO_TONE_MODE_HW_LOOP     = 2,
128 		AUDIO_16M_MASK              = 0x4000,
129 		AUDIO_ADPCM_MASK            = 0x8000,
130 
131 		AUDIO_LOOP_ADDR             = 0x002,
132 
133 		AUDIO_PAN_VOL               = 0x003,
134 		AUDIO_PAN_VOL_MASK          = 0x7f7f,
135 		AUDIO_VOLUME_MASK           = 0x007f,
136 		AUDIO_PAN_MASK              = 0x7f00,
137 		AUDIO_PAN_SHIFT             = 8,
138 
139 		AUDIO_ENVELOPE0             = 0x004,
140 		AUDIO_ENVELOPE_INC_MASK     = 0x007f,
141 		AUDIO_ENVELOPE_SIGN_MASK    = 0x0080,
142 		AUDIO_ENVELOPE_TARGET_MASK  = 0x7f00,
143 		AUDIO_ENVELOPE_TARGET_SHIFT = 8,
144 		AUDIO_ENVELOPE_REPEAT_PERIOD_MASK = 0x8000,
145 
146 		AUDIO_ENVELOPE_DATA         = 0x005,
147 		AUDIO_ENVELOPE_DATA_MASK    = 0xff7f,
148 		AUDIO_EDD_MASK              = 0x007f,
149 		AUDIO_ENVELOPE_COUNT_MASK   = 0xff00,
150 		AUDIO_ENVELOPE_COUNT_SHIFT  = 8,
151 
152 		AUDIO_ENVELOPE1             = 0x006,
153 		AUDIO_ENVELOPE_LOAD_MASK    = 0x00ff,
154 		AUDIO_ENVELOPE_RPT_MASK     = 0x0100,
155 		AUDIO_ENVELOPE_RPCNT_MASK   = 0xfe00,
156 		AUDIO_ENVELOPE_RPCNT_SHIFT  = 9,
157 
158 		AUDIO_ENVELOPE_ADDR_HIGH    = 0x007,
159 		AUDIO_EADDR_HIGH_MASK       = 0x003f,
160 		AUDIO_IRQ_EN_MASK           = 0x0040,
161 		AUDIO_IRQ_ADDR_MASK         = 0xff80,
162 		AUDIO_IRQ_ADDR_SHIFT        = 7,
163 
164 		AUDIO_ENVELOPE_ADDR         = 0x008,
165 		AUDIO_WAVE_DATA_PREV        = 0x009,
166 
167 		AUDIO_ENVELOPE_LOOP_CTRL    = 0x00a,
168 		AUDIO_EAOFFSET_MASK         = 0x01ff,
169 		AUDIO_RAMPDOWN_OFFSET_MASK  = 0xfe00,
170 		AUDIO_RAMPDOWN_OFFSET_SHIFT = 9,
171 
172 		AUDIO_WAVE_DATA             = 0x00b,
173 
174 		AUDIO_ADPCM_SEL             = 0x00d,
175 		AUDIO_ADPCM_SEL_MASK        = 0xfe00,
176 		AUDIO_POINT_NUMBER_MASK     = 0x7e00,
177 		AUDIO_POINT_NUMBER_SHIFT    = 9,
178 		AUDIO_ADPCM36_MASK          = 0x8000,
179 	};
180 
181 	enum // at audio write offset 0x200 in spg2xx
182 	{
183 		AUDIO_PHASE_HIGH            = 0x000,
184 		AUDIO_PHASE_HIGH_MASK       = 0x0007,
185 
186 		AUDIO_PHASE_ACCUM_HIGH      = 0x001,
187 		AUDIO_PHASE_ACCUM_HIGH_MASK = 0x0007,
188 
189 		AUDIO_TARGET_PHASE_HIGH     = 0x002,
190 		AUDIO_TARGET_PHASE_HIGH_MASK= 0x0007,
191 
192 		AUDIO_RAMP_DOWN_CLOCK       = 0x003,
193 		AUDIO_RAMP_DOWN_CLOCK_MASK  = 0x0007,
194 
195 		AUDIO_PHASE                 = 0x004,
196 		AUDIO_PHASE_ACCUM           = 0x005,
197 		AUDIO_TARGET_PHASE          = 0x006,
198 
199 		AUDIO_PHASE_CTRL            = 0x007,
200 		AUDIO_PHASE_OFFSET_MASK     = 0x0fff,
201 		AUDIO_PHASE_SIGN_MASK       = 0x1000,
202 		AUDIO_PHASE_SIGN_SHIFT      = 12,
203 		AUDIO_PHASE_TIME_STEP_MASK  = 0xe000,
204 		AUDIO_PHASE_TIME_STEP_SHIFT = 13,
205 
206 		AUDIO_CHAN_OFFSET_MASK      = 0xf0f,
207 	};
208 
209 	enum // at audio write offset 0x400 in spg2xx
210 	{
211 
212 		AUDIO_CHANNEL_ENABLE            = 0x000,
213 		AUDIO_CHANNEL_ENABLE_MASK       = 0xffff,
214 
215 		AUDIO_MAIN_VOLUME               = 0x001,
216 		AUDIO_MAIN_VOLUME_MASK          = 0x007f,
217 
218 		AUDIO_CHANNEL_FIQ_ENABLE        = 0x002,
219 		AUDIO_CHANNEL_FIQ_ENABLE_MASK   = 0xffff,
220 
221 		AUDIO_CHANNEL_FIQ_STATUS        = 0x003,
222 		AUDIO_CHANNEL_FIQ_STATUS_MASK   = 0xffff,
223 
224 		AUDIO_BEAT_BASE_COUNT           = 0x004,
225 		AUDIO_BEAT_BASE_COUNT_MASK      = 0x07ff,
226 
227 		AUDIO_BEAT_COUNT                = 0x005,
228 		AUDIO_BEAT_COUNT_MASK           = 0x3fff,
229 		AUDIO_BIS_MASK                  = 0x4000,
230 		AUDIO_BIE_MASK                  = 0x8000,
231 
232 		AUDIO_ENVCLK0                   = 0x006,
233 
234 		AUDIO_ENVCLK0_HIGH              = 0x007,
235 		AUDIO_ENVCLK0_HIGH_MASK         = 0xffff,
236 
237 		AUDIO_ENVCLK1                   = 0x008,
238 
239 		AUDIO_ENVCLK1_HIGH              = 0x009,
240 		AUDIO_ENVCLK1_HIGH_MASK         = 0xffff,
241 
242 		AUDIO_ENV_RAMP_DOWN             = 0x00a,
243 		AUDIO_ENV_RAMP_DOWN_MASK        = 0xffff,
244 
245 		AUDIO_CHANNEL_STOP              = 0x00b,
246 		AUDIO_CHANNEL_STOP_MASK         = 0xffff,
247 
248 		AUDIO_CHANNEL_ZERO_CROSS        = 0x00c,
249 		AUDIO_CHANNEL_ZERO_CROSS_MASK   = 0xffff,
250 
251 		AUDIO_CONTROL                   = 0x00d,
252 		AUDIO_CONTROL_MASK              = 0x9fe8,
253 		AUDIO_CONTROL_SATURATE_MASK     = 0x8000,
254 		AUDIO_CONTROL_SOFTCH_MASK       = 0x1000,
255 		AUDIO_CONTROL_COMPEN_MASK       = 0x0800,
256 		AUDIO_CONTROL_NOHIGH_MASK       = 0x0400,
257 		AUDIO_CONTROL_NOINT_MASK        = 0x0200,
258 		AUDIO_CONTROL_EQEN_MASK         = 0x0100,
259 		AUDIO_CONTROL_VOLSEL_MASK       = 0x00c0,
260 		AUDIO_CONTROL_VOLSEL_SHIFT      = 6,
261 		AUDIO_CONTROL_FOF_MASK          = 0x0020,
262 		AUDIO_CONTROL_INIT_MASK         = 0x0008,
263 
264 		AUDIO_COMPRESS_CTRL             = 0x00e,
265 		AUDIO_COMPRESS_CTRL_PEAK_MASK   = 0x8000,
266 		AUDIO_COMPRESS_CTRL_THRESHOLD_MASK  = 0x7f00,
267 		AUDIO_COMPRESS_CTRL_THRESHOLD_SHIFT = 8,
268 		AUDIO_COMPRESS_CTRL_ATTSCALE_MASK   = 0x00c0,
269 		AUDIO_COMPRESS_CTRL_ATTSCALE_SHIFT  = 6,
270 		AUDIO_COMPRESS_CTRL_RELSCALE_MASK   = 0x0030,
271 		AUDIO_COMPRESS_CTRL_RELSCALE_SHIFT  = 4,
272 		AUDIO_COMPRESS_CTRL_DISZC_MASK      = 0x0008,
273 		AUDIO_COMPRESS_CTRL_RATIO_MASK      = 0x0007,
274 
275 		AUDIO_CHANNEL_STATUS            = 0x00f,
276 		AUDIO_CHANNEL_STATUS_MASK       = 0xffff,
277 
278 		AUDIO_WAVE_IN_L                 = 0x010,
279 
280 		AUDIO_WAVE_IN_R                 = 0x011,
281 		AUDIO_SOFTIRQ_MASK              = 0x8000,
282 		AUDIO_SOFTIRQ_EN_MASK           = 0x4000,
283 		AUDIO_SOFT_PHASE_HIGH_MASK      = 0x0070,
284 		AUDIO_SOFT_PHASE_HIGH_SHIFT     = 4,
285 		AUDIO_FIFO_IRQ_THRESHOLD_MASK   = 0x000f,
286 
287 		AUDIO_WAVE_OUT_L                = 0x012,
288 		AUDIO_WAVE_OUT_R                = 0x013,
289 
290 		AUDIO_CHANNEL_REPEAT            = 0x014,
291 		AUDIO_CHANNEL_REPEAT_MASK       = 0xffff,
292 
293 		AUDIO_CHANNEL_ENV_MODE          = 0x015,
294 		AUDIO_CHANNEL_ENV_MODE_MASK     = 0xffff,
295 
296 		AUDIO_CHANNEL_TONE_RELEASE      = 0x016,
297 		AUDIO_CHANNEL_TONE_RELEASE_MASK = 0xffff,
298 
299 		AUDIO_CHANNEL_ENV_IRQ           = 0x017,
300 		AUDIO_CHANNEL_ENV_IRQ_MASK      = 0xffff,
301 
302 		AUDIO_CHANNEL_PITCH_BEND        = 0x018,
303 		AUDIO_CHANNEL_PITCH_BEND_MASK   = 0xffff,
304 
305 		AUDIO_SOFT_PHASE                = 0x019,
306 
307 		AUDIO_ATTACK_RELEASE            = 0x01a,
308 		AUDIO_RELEASE_TIME_MASK         = 0x00ff,
309 		AUDIO_ATTACK_TIME_MASK          = 0xff00,
310 		AUDIO_ATTACK_TIME_SHIFT         = 8,
311 
312 		AUDIO_EQ_CUTOFF10               = 0x01b,
313 		AUDIO_EQ_CUTOFF10_MASK          = 0x7f7f,
314 
315 		AUDIO_EQ_CUTOFF32               = 0x01c,
316 		AUDIO_EQ_CUTOFF32_MASK          = 0x7f7f,
317 
318 		AUDIO_EQ_GAIN10                 = 0x01d,
319 		AUDIO_EQ_GAIN10_MASK            = 0x7f7f,
320 
321 		AUDIO_EQ_GAIN32                 = 0x01e,
322 		AUDIO_EQ_GAIN32_MASK            = 0x7f7f
323 	};
324 
325 	struct adpcm36_state
326 	{
327 		uint16_t m_remaining;
328 		uint16_t m_header;
329 		int16_t m_prevsamp[2];
330 	};
331 
332 	static const device_timer_id TIMER_BEAT = 3;
333 	static const device_timer_id TIMER_IRQ = 4;
334 
335 	void check_irqs(const uint16_t changed);
336 
337 	virtual void device_start() override;
338 	virtual void device_reset() override;
339 	virtual void device_stop() override;
340 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
341 
342 	uint16_t read_space(offs_t offset);
343 
344 	void stop_channel(const uint32_t channel);
345 	bool advance_channel(const uint32_t channel);
346 	bool fetch_sample(const uint32_t channel);
347 	void loop_channel(const uint32_t channel);
348 	uint16_t decode_adpcm36_nybble(const uint32_t channel, const uint8_t data);
349 	void read_adpcm36_header(const uint32_t channel);
350 
351 	bool m_debug_samples;
352 	bool m_debug_rates;
353 
354 	uint16_t m_audio_regs[0x200];
355 	uint16_t m_audio_phase_regs[0x200];
356 	uint16_t m_audio_ctrl_regs[0x400];
357 	uint8_t m_sample_shift[16];
358 	uint32_t m_sample_count[16];
359 	uint32_t m_sample_addr[16];
360 	double m_channel_rate[16];
361 	double m_channel_rate_accum[16];
362 	uint32_t m_rampdown_frame[16];
363 	uint32_t m_envclk_frame[16];
364 	uint32_t m_envelope_addr[16];
365 	int m_channel_debug;
366 	uint16_t m_audio_curr_beat_base_count;
367 
368 	emu_timer *m_audio_beat;
369 	emu_timer *m_channel_irq[16];
370 
371 	sound_stream *m_stream;
372 	oki_adpcm_state m_adpcm[16];
373 	adpcm36_state m_adpcm36_state[16];
374 
375 	static const uint32_t s_rampdown_frame_counts[8];
376 	static const uint32_t s_envclk_frame_counts[16];
377 
378 private:
379 	devcb_read16 m_space_read_cb;
380 	devcb_write_line m_irq_cb;
381 	devcb_write_line m_ch_irq_cb;
382 };
383 
384 class spg110_audio_device : public spg2xx_audio_device
385 {
386 public:
387 	spg110_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
388 
389 	virtual void audio_w(offs_t offset, uint16_t data) override;
390 
391 	// these either come from somewhere else on spg110 or are hardcoded
get_16bit_bit(const offs_t channel)392 	virtual uint16_t get_16bit_bit(const offs_t channel) const override { return 1; }
get_adpcm_bit(const offs_t channel)393 	virtual uint16_t get_adpcm_bit(const offs_t channel) const override { return 0; }
394 
get_phase(const offs_t channel)395 	virtual uint32_t get_phase(const offs_t channel) const override { return m_audio_regs[(channel << 4) | 0xe]; }
396 };
397 
398 class sunplus_gcm394_audio_device : public spg2xx_audio_device
399 {
400 public:
401 	sunplus_gcm394_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
402 
403 	uint16_t control_r(offs_t offset);
404 	void control_w(offs_t offset, uint16_t data);
405 
406 	virtual void device_start() override;
407 
408 private:
409 	uint16_t control_group16_r(uint8_t group, uint8_t offset);
410 	void control_group16_w(uint8_t group, uint8_t offset, uint16_t data);
411 
412 	uint16_t m_control[2][0x20];
413 };
414 
415 DECLARE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device)
416 DECLARE_DEVICE_TYPE(SPG110_AUDIO, spg110_audio_device)
417 DECLARE_DEVICE_TYPE(SUNPLUS_GCM394_AUDIO, sunplus_gcm394_audio_device)
418 
419 #endif // MAME_MACHINE_SPG2XX_AUDIO_H
420