1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     Midway DCS Audio Board
6 
7 ****************************************************************************/
8 
9 #ifndef MAME_AUDIO_DCS_H
10 #define MAME_AUDIO_DCS_H
11 
12 #pragma once
13 
14 #include "cpu/adsp2100/adsp2100.h"
15 #include "sound/dmadac.h"
16 #include "machine/bankdev.h"
17 #include "machine/timer.h"
18 
19 
20 class dcs_audio_device : public device_t
21 {
22 public:
23 	// for dcs2 (int dram_in_mb, offs_t polling_offset)
set_dram_in_mb(int dram_in_mb)24 	void set_dram_in_mb(int dram_in_mb) { m_dram_in_mb = dram_in_mb; }
set_polling_offset(offs_t polling_offset)25 	void set_polling_offset(offs_t polling_offset) { m_polling_offset = polling_offset; }
26 
27 	void set_auto_ack(int state);
28 
29 	void set_fifo_callbacks(read16smo_delegate fifo_data_r, read16mo_delegate fifo_status_r, write_line_delegate fifo_reset_w);
30 	void set_io_callbacks(write_line_delegate output_full_cb, write_line_delegate input_empty_cb);
31 
32 	uint16_t data_r();
33 	void ack_w();
34 	int data2_r();
35 	int control_r();
36 
37 	void data_w(uint16_t data);
38 	void reset_w(int state);
39 
40 	void fifo_notify(int count, int max);
41 
42 	void dsio_idma_addr_w(uint32_t data);
43 	void dsio_idma_data_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
44 	uint32_t dsio_idma_data_r();
45 	void dmovlay_remap_memory();
46 	void dmovlay_callback(uint32_t data);
47 	void denver_postload(void);
48 	void install_speedup(void);
49 
50 	// non public
51 	void dcs_boot();
52 	TIMER_CALLBACK_MEMBER( dcs_reset );
53 	void dcs_register_state();
54 	uint16_t dcs_dataram_r(offs_t offset);
55 	void dcs_dataram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
56 	void dcs_data_bank_select_w(uint16_t data);
57 	void dcs_data_bank_select2_w(uint16_t data);
58 	inline void sdrc_update_bank_pointers();
59 	void sdrc_remap_memory();
60 	void sdrc_reset();
61 	uint16_t sdrc_r(offs_t offset);
62 	void sdrc_w(offs_t offset, uint16_t data);
63 	void dsio_reset();
64 	uint16_t dsio_r(offs_t offset);
65 	void dsio_w(offs_t offset, uint16_t data);
66 	void denver_alloc_dmadac(void);
67 	void denver_reset();
68 	uint16_t denver_r(offs_t offset);
69 	void denver_w(offs_t offset, uint16_t data);
70 	uint16_t latch_status_r(address_space &space);
71 	uint16_t fifo_input_r();
72 	void dcs_delayed_data_w(uint16_t data);
73 	TIMER_CALLBACK_MEMBER( dcs_delayed_data_w_callback );
74 	void input_latch_ack_w(uint16_t data);
75 	uint16_t input_latch_r();
76 	uint32_t input_latch32_r();
77 	TIMER_CALLBACK_MEMBER( latch_delayed_w );
78 	void output_latch_w(uint16_t data);
79 	void output_latch32_w(uint32_t data);
80 	void delayed_ack_w();
81 	TIMER_CALLBACK_MEMBER( delayed_ack_w_callback );
82 	TIMER_CALLBACK_MEMBER( output_control_delayed_w );
83 	void output_control_w(uint16_t data);
84 	uint16_t output_control_r();
85 	void update_timer_count();
86 	TIMER_DEVICE_CALLBACK_MEMBER( internal_timer_callback );
87 	void reset_timer();
88 	DECLARE_WRITE_LINE_MEMBER(timer_enable_callback);
89 	uint16_t adsp_control_r(offs_t offset);
90 	void adsp_control_w(offs_t offset, uint16_t data);
91 	TIMER_DEVICE_CALLBACK_MEMBER( dcs_irq );
92 	TIMER_DEVICE_CALLBACK_MEMBER( sport0_irq );
93 	void recompute_sample_rate();
94 	void sound_tx_callback(offs_t offset, uint32_t data);
95 	uint16_t dcs_polling_r(address_space &space);
96 	void dcs_polling_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
97 	uint32_t dcs_polling32_r(address_space &space);
98 	void dcs_polling32_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
99 	TIMER_DEVICE_CALLBACK_MEMBER( transfer_watchdog_callback );
100 	TIMER_CALLBACK_MEMBER( s1_ack_callback2 );
101 	TIMER_CALLBACK_MEMBER( s1_ack_callback1 );
102 	int preprocess_stage_1(uint16_t data);
103 	TIMER_CALLBACK_MEMBER( s2_ack_callback );
104 	int preprocess_stage_2(uint16_t data);
105 	int preprocess_write(uint16_t data);
106 
107 	void dcs2_2104_data_map(address_map &map);
108 	void dcs2_2104_program_map(address_map &map);
109 	void dcs2_2115_data_map(address_map &map);
110 	void dcs2_2115_program_map(address_map &map);
111 	void dcs_2k_data_map(address_map &map);
112 	void dcs_2k_program_map(address_map &map);
113 	void dcs_2k_uart_data_map(address_map &map);
114 	void dcs_8k_data_map(address_map &map);
115 	void dcs_8k_program_map(address_map &map);
116 	void dcs_wpc_program_map(address_map &map);
117 	void denver_data_map(address_map &map);
118 	void denver_io_map(address_map &map);
119 	void denver_program_map(address_map &map);
120 	void denver_rambank_map(address_map &map);
121 	void dsio_data_map(address_map &map);
122 	void dsio_io_map(address_map &map);
123 	void dsio_program_map(address_map &map);
124 	void dsio_rambank_map(address_map &map);
125 
get_rev()126 	uint8_t get_rev() { return m_rev; } // TODO(RH): This can be done better, and shouldn't be necessary.
get_cpu()127 	cpu_device *get_cpu() { return m_cpu; } // TODO(RH): Same.
128 
129 	enum { REV_DCS1, REV_DCS1P5, REV_DCS2, REV_DSIO, REV_DENV };
130 
131 protected:
132 	// construction/destruction
133 	dcs_audio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rev);
134 
135 	// device-level overrides
136 	virtual void device_start() override;
137 	virtual void device_reset() override;
138 	void add_mconfig_dcs(machine_config &config);
139 
140 	static constexpr const char *const denver_regname[4] =
141 	{ "SDRC_ROM", "SDRC_IO", "RAM_PAGE", "VER/FIFO_RESET" };
142 
143 	struct sdrc_state
144 	{
145 		uint16_t      reg[4];
146 		uint8_t       seed;
147 	};
148 
149 
150 	struct dsio_state
151 	{
152 		uint16_t      reg[4];
153 		uint8_t       start_on_next_write;
154 		uint16_t      channelbits;
155 	};
156 
157 
158 	struct hle_transfer_state
159 	{
160 		uint8_t       hle_enabled;
161 		int32_t       dcs_state;
162 		int32_t       state;
163 		int32_t       start;
164 		int32_t       stop;
165 		int32_t       type;
166 		int32_t       temp;
167 		int32_t       writes_left;
168 		uint16_t      sum;
169 		int32_t       fifo_entries;
170 		timer_device *watchdog;
171 	};
172 
173 	adsp21xx_device *m_cpu;
174 	address_space *m_program;
175 	address_space *m_data;
176 	uint8_t       m_rev;
177 	offs_t      m_polling_offset;
178 	uint32_t      m_polling_count;
179 	/* sound output */
180 	uint8_t       m_channels;
181 	uint16_t      m_size;
182 	uint16_t      m_incs;
183 	dmadac_sound_device *m_dmadac[6];
184 	timer_device *m_reg_timer;
185 	timer_device *m_sport0_timer;
186 	timer_device *m_internal_timer;
187 	int32_t       m_ireg;
188 	uint16_t      m_ireg_base;
189 	uint16_t      m_control_regs[32];
190 
191 	/* memory access/booting */
192 	uint16_t *    m_bootrom;
193 	uint32_t      m_bootrom_words;
194 	uint16_t *    m_sounddata;
195 	std::unique_ptr<uint16_t[]> m_sounddata_ptr;
196 	uint32_t      m_sounddata_words;
197 	uint32_t      m_sounddata_banks;
198 	uint16_t      m_sounddata_bank;
199 
200 	optional_device<address_map_bank_device> m_ram_map;
201 	optional_memory_bank    m_data_bank;
202 	memory_bank *           m_rom_page;
203 	memory_bank *           m_dram_page;
204 
205 	/* I/O with the host */
206 	uint8_t       m_auto_ack;
207 	uint16_t      m_latch_control;
208 	uint16_t      m_input_data;
209 	uint16_t      m_output_data;
210 	uint16_t      m_pre_output_data;
211 	uint16_t      m_output_control;
212 	uint64_t      m_output_control_cycles;
213 	uint8_t       m_last_output_full;
214 	uint8_t       m_last_input_empty;
215 	uint16_t      m_progflags;
216 
217 	write_line_delegate m_output_full_cb;
218 	write_line_delegate m_input_empty_cb;
219 
220 	read16smo_delegate m_fifo_data_r;
221 	read16mo_delegate m_fifo_status_r;
222 	write_line_delegate m_fifo_reset_w;
223 
224 	/* timers */
225 	uint8_t       m_timer_enable;
226 	bool          m_timer_ignore;
227 	uint64_t      m_timer_start_cycles;
228 	uint32_t      m_timer_start_count;
229 	uint32_t      m_timer_scale;
230 	uint32_t      m_timer_period;
231 	uint32_t      m_timers_fired;
232 
233 	std::unique_ptr<uint16_t[]> m_sram;
234 	uint16_t m_polling_value;
235 	uint32_t m_polling32_value;
236 	uint32_t *m_internal_program_ram;
237 	uint32_t *m_external_program_ram;
238 	uint32_t *m_internal_data_ram;
239 
240 	int m_dmovlay_val;
241 
242 	sdrc_state m_sdrc;
243 	dsio_state m_dsio;
244 	hle_transfer_state m_transfer;
245 
246 	int m_dram_in_mb;
247 
248 	optional_shared_ptr<uint16_t> m_iram;
249 	optional_device<device_execute_interface> m_maincpu;
250 };
251 
252 
253 // dcs_audio_2k_device
254 
255 class dcs_audio_2k_device : public dcs_audio_device
256 {
257 public:
258 	// construction/destruction
259 	dcs_audio_2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
260 
261 protected:
262 	// optional information overrides
263 	virtual void device_add_mconfig(machine_config &config) override;
264 
265 };
266 
267 // device type definition
DECLARE_DEVICE_TYPE(DCS_AUDIO_2K,dcs_audio_2k_device)268 DECLARE_DEVICE_TYPE(DCS_AUDIO_2K, dcs_audio_2k_device)
269 
270 // dcs_audio_2k_uart_device
271 
272 class dcs_audio_2k_uart_device : public dcs_audio_device
273 {
274 public:
275 	// construction/destruction
276 	dcs_audio_2k_uart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
277 
278 protected:
279 	// optional information overrides
280 	virtual void device_add_mconfig(machine_config &config) override;
281 };
282 
283 // device type definition
DECLARE_DEVICE_TYPE(DCS_AUDIO_2K_UART,dcs_audio_2k_uart_device)284 DECLARE_DEVICE_TYPE(DCS_AUDIO_2K_UART, dcs_audio_2k_uart_device)
285 
286 // dcs_audio_8k_device
287 
288 class dcs_audio_8k_device : public dcs_audio_device
289 {
290 public:
291 	// construction/destruction
292 	dcs_audio_8k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
293 
294 protected:
295 	// optional information overrides
296 	virtual void device_add_mconfig(machine_config &config) override;
297 };
298 
299 // device type definition
DECLARE_DEVICE_TYPE(DCS_AUDIO_8K,dcs_audio_8k_device)300 DECLARE_DEVICE_TYPE(DCS_AUDIO_8K, dcs_audio_8k_device)
301 
302 // dcs_audio_wpc_device
303 
304 class dcs_audio_wpc_device : public dcs_audio_device
305 {
306 public:
307 	// construction/destruction
308 	dcs_audio_wpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
309 
310 	void dcs_wpc_data_map(address_map &map);
311 protected:
312 	// optional information overrides
313 	virtual void device_add_mconfig(machine_config &config) override;
314 };
315 
316 // device type definition
DECLARE_DEVICE_TYPE(DCS_AUDIO_WPC,dcs_audio_wpc_device)317 DECLARE_DEVICE_TYPE(DCS_AUDIO_WPC, dcs_audio_wpc_device)
318 
319 
320 // dcs2_audio_device
321 
322 class dcs2_audio_device : public dcs_audio_device
323 {
324 protected:
325 	// construction/destruction
326 	dcs2_audio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
327 
328 	// device-level overrides
329 	virtual void device_start() override;
330 	void add_mconfig_dcs2(machine_config &config);
331 };
332 
333 // dcs2_audio_2115_device
334 
335 class dcs2_audio_2115_device : public dcs2_audio_device
336 {
337 public:
338 	// construction/destruction
339 	dcs2_audio_2115_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
340 
341 protected:
342 	// optional information overrides
343 	virtual void device_add_mconfig(machine_config &config) override;
344 };
345 
346 // device type definition
DECLARE_DEVICE_TYPE(DCS2_AUDIO_2115,dcs2_audio_2115_device)347 DECLARE_DEVICE_TYPE(DCS2_AUDIO_2115, dcs2_audio_2115_device)
348 
349 // dcs2_audio_2104_device
350 
351 class dcs2_audio_2104_device : public dcs2_audio_device
352 {
353 public:
354 	// construction/destruction
355 	dcs2_audio_2104_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
356 
357 protected:
358 	// optional information overrides
359 	virtual void device_add_mconfig(machine_config &config) override;
360 };
361 
362 // device type definition
DECLARE_DEVICE_TYPE(DCS2_AUDIO_2104,dcs2_audio_2104_device)363 DECLARE_DEVICE_TYPE(DCS2_AUDIO_2104, dcs2_audio_2104_device)
364 
365 // dcs2_audio_dsio_device
366 
367 class dcs2_audio_dsio_device : public dcs2_audio_device
368 {
369 public:
370 	// construction/destruction
371 	dcs2_audio_dsio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
372 
373 protected:
374 	// optional information overrides
375 	virtual void device_add_mconfig(machine_config &config) override;
376 };
377 
378 // device type definition
DECLARE_DEVICE_TYPE(DCS2_AUDIO_DSIO,dcs2_audio_dsio_device)379 DECLARE_DEVICE_TYPE(DCS2_AUDIO_DSIO, dcs2_audio_dsio_device)
380 
381 // dcs2_audio_denver_device types
382 class dcs2_audio_denver_device : public dcs2_audio_device
383 {
384 public:
385 	// construction/destruction
386 	dcs2_audio_denver_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
387 protected:
388 	// optional information overrides
389 	virtual void device_add_mconfig(machine_config &config) override;
390 };
391 
392 class dcs2_audio_denver_5ch_device : public dcs2_audio_denver_device
393 {
394 public:
395 	// construction/destruction
396 	dcs2_audio_denver_5ch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
397 protected:
398 	// optional information overrides
399 	virtual void device_add_mconfig(machine_config &config) override;
400 };
401 
402 class dcs2_audio_denver_2ch_device : public dcs2_audio_denver_device
403 {
404 public:
405 	// construction/destruction
406 	dcs2_audio_denver_2ch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
407 protected:
408 	// optional information overrides
409 	virtual void device_add_mconfig(machine_config &config) override;
410 };
411 
412 // device type definition
413 DECLARE_DEVICE_TYPE(DCS2_AUDIO_DENVER_5CH, dcs2_audio_denver_5ch_device)
414 
415 DECLARE_DEVICE_TYPE(DCS2_AUDIO_DENVER_2CH, dcs2_audio_denver_2ch_device)
416 
417 #endif // MAME_AUDIO_DCS_H
418