1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     Midway DCS Audio Board
6 
7 ****************************************************************************
8 
9     There are several variations of this board, which was in use by
10     Midway and eventually Atari for almost 10 years.
11 
12     DCS ROM-based mono:
13         * ADSP-2105 @ 10MHz
14         * single channel output
15         * 2k external shared program/data RAM
16         * ROM-based, up to 8MB total
17         * used in:
18             Mortal Kombat 2 (1993)
19             Cruisin' USA (1994)
20             Revolution X (1994)
21             Killer Instinct (1994)
22             Killer Instinct 2 (1995)
23             Cruisin' World (1996)
24             Offroad Challenge (1997)
25 
26         * 8k external shared program/data RAM
27         * used in:
28             Mortal Kombat 3 (1994)
29             Ultimate Mortal Kombat 3 (1994)
30             2 On 2 Open Ice Challenge (1995)
31             WWF Wrestlemania (1995)
32             NBA Hangtime (1996)
33             NBA Maximum Hangtime (1996)
34             Rampage World Tour (1997)
35 
36     DCS2 RAM-based stereo (Seattle):
37         * ADSP-2115 @ 16MHz
38         * dual channel output (stereo)
39         * SDRC ASIC for RAM/ROM access
40         * RAM-based, 2MB total
41         * used in:
42             War Gods (1995)
43             Wayne Gretzky's 3D Hockey (1996)
44             Mace: The Dark Age (1996)
45             Biofreaks (1997)
46             NFL Blitz (1997)
47             California Speed (1998)
48             Vapor TRX (1998)
49             NFL Blitz '99 (1998)
50             CarnEvil (1998)
51             Hyperdrive (1998)
52             NFL Blitz 2000 Gold (1999)
53 
54     DCS2 ROM-based stereo (Zeus):
55         * ADSP-2104 @ 16MHz
56         * dual channel output (stereo)
57         * SDRC ASIC for RAM/ROM access
58         * ROM-based, up to 16MB total
59         * used in:
60             Mortal Kombat 4 (1997)
61             Invasion (1999)
62             Cruisin' Exotica (1999)
63             The Grid (2001)
64 
65     DCS2 RAM-based stereo (Vegas):
66         * ADSP-2104 @ 16MHz
67         * dual channel output (stereo)
68         * SDRC ASIC for RAM/ROM access
69         * RAM-based, 4MB total
70         * used in:
71             Gauntlet Legends (1998)
72             Tenth Degree (1998)
73             Gauntlet Dark Legacy (1999)
74             War: The Final Assault (1999)
75 
76     DCS2 RAM-based stereo (DSIO):
77         * ADSP-2181 @ 16.667MHz
78         * dual channel output (stereo)
79         * custom ASIC for RAM/ROM access
80         * RAM-based, 4MB total
81         * used in:
82             Road Burners (1999)
83 
84     DCS2 RAM-based multi-channel (Denver):
85         * ADSP-2181 @ 16.667MHz
86         * 2-6 channel output
87         * custom ASIC for RAM/ROM access
88         * RAM-based, 4MB total
89         * used in:
90             San Francisco Rush: 2049 (1998)
91 
92     Unknown other DCS boards:
93         * NBA Jam Extreme
94         * NBA Showtime
95         * NBA Showtime / NFL Blitz 2000 Gold
96         * Cart Fury
97 
98 *****************************************************************************
99 
100     SDRC (Sound DRAM Control) ASIC
101         * Boot ROM = 32k x 8
102         * Data ROM = Up to 16MB ROM (4 chip selects)
103         * SRAM = 32k x 24 or 8k x 24
104             * common map:
105                  PGM 0800-0fff -> RAM 4800-4fff
106                  PGM 1000-1fff -> RAM 5000-5fff
107                  PGM 2000-2fff -> RAM 6000-6fff
108                  PGM 3000-3fff -> RAM 7000-7fff
109             * bank = 0:
110                 DATA 0800-0fff -> RAM 0800-0fff
111                 DATA 1000-17ff -> RAM 0000-07ff
112                 DATA 1800-1fff -> RAM 1800-1fff
113                 DATA 2000-27ff -> RAM 1000-17ff
114                 DATA 2800-2fff -> RAM 2800-2fff
115                 DATA 3000-37ff -> RAM 2000-27ff
116             * bank = 1:
117                 DATA 0800-0fff -> unmapped
118                 DATA 1000-17ff -> unmapped
119                 DATA 1800-1fff -> RAM 3800-3fff
120                 DATA 2000-27ff -> RAM 3000-37ff
121                 DATA 2800-2fff -> RAM 2800-2fff
122                 DATA 3000-37ff -> RAM 2000-27ff
123 
124     0480 (reset = XXX0 0X00 0X00 XX00)
125         15:13 = SMODE (write only)
126           12  = SM_BK (SRAM bank: 0 or 1)
127           11  = SM_EN (SRAM enable: 0=disabled, 1=enabled)
128          9:7  = ROM_PG (ROM page select: 0-7)
129           5   = ROM_MS (ROM memory select: 0=boot memory, 1=data memory)
130           4   = ROM_SZ (ROM area size: 0=4k words, 1=1k words)
131          1:0  = ROM_ST (ROM memory start: 0=0000, 1=3000, 2=3400, 3=none)
132 
133     0481 (reset = 000X 00X0 0X00 XX00)
134           15  = AREF_ACT (read only, 1=DRAM auto refresh in progress)
135           14  = /MUTE (mute output)
136           13  = /LED (LED output)
137         11:10 = /RES_TFS (Reset TFS outputs: low bit = channel 1&2, high = channel 3&4)
138           8   = TFS_INV (TFS output polarity: 0=same, 1=inverted)
139           7   = DM_3WS (DRAM wait states: 0=2, 1=3)
140          5:4  = DM_REF (DRAM refresh: 0=disabled, 1=manual, 2=auto, 3=auto 2x)
141          1:0  = DM_ST (DRAM memory start: 0=none, 1=0000, 2=3000, 3=3400)
142 
143     0482 (reset = XXX0 0000 0000 0000)
144         10:0  = DM_PG[10..0] (DRAM page)
145         12:0  = EPM_PG[12..0] (EPROM page [low 10 bits used for 4k pages])
146 
147     0483 (reset = 1010 0000 1000 0001)
148         15:8  = SDRC_ID[7..0] (revision: 5A = ASIC version, A0 = FPGA version)
149           7   = SEC_D7
150           6   = SEC_D[6..1]
151           0   = SEC_D0
152 
153 ****************************************************************************/
154 
155 #include "emu.h"
156 #include "dcs.h"
157 #include "speaker.h"
158 
159 
160 #define LOG_DCS_TRANSFERS           (0)
161 #define LOG_DCS_IO                  (0)
162 #define LOG_BUFFER_FILLING          (0)
163 
164 #define ENABLE_HLE_TRANSFERS        (1)
165 
166 
167 
168 /*************************************
169  *
170  *  Constants
171  *
172  *************************************/
173 
174 #define LCTRL_OUTPUT_EMPTY          0x400
175 #define LCTRL_INPUT_EMPTY           0x800
176 
177 #define IS_OUTPUT_EMPTY()           (m_latch_control & LCTRL_OUTPUT_EMPTY)
178 #define IS_OUTPUT_FULL()            (!(m_latch_control & LCTRL_OUTPUT_EMPTY))
179 #define SET_OUTPUT_EMPTY()          (m_latch_control |= LCTRL_OUTPUT_EMPTY)
180 #define SET_OUTPUT_FULL()           (m_latch_control &= ~LCTRL_OUTPUT_EMPTY)
181 
182 #define IS_INPUT_EMPTY()            (m_latch_control & LCTRL_INPUT_EMPTY)
183 #define IS_INPUT_FULL()             (!(m_latch_control & LCTRL_INPUT_EMPTY))
184 #define SET_INPUT_EMPTY()           (m_latch_control |= LCTRL_INPUT_EMPTY)
185 #define SET_INPUT_FULL()            (m_latch_control &= ~LCTRL_INPUT_EMPTY)
186 
187 
188 /* These are some of the control registers. We don't use them all */
189 enum
190 {
191 	IDMA_CONTROL_REG = 0,   /* 3fe0 */
192 	BDMA_INT_ADDR_REG,      /* 3fe1 */
193 	BDMA_EXT_ADDR_REG,      /* 3fe2 */
194 	BDMA_CONTROL_REG,       /* 3fe3 */
195 	BDMA_WORD_COUNT_REG,    /* 3fe4 */
196 	PROG_FLAG_DATA_REG,     /* 3fe5 */
197 	PROG_FLAG_CONTROL_REG,  /* 3fe6 */
198 
199 	S1_AUTOBUF_REG = 15,    /* 3fef */
200 	S1_RFSDIV_REG,          /* 3ff0 */
201 	S1_SCLKDIV_REG,         /* 3ff1 */
202 	S1_CONTROL_REG,         /* 3ff2 */
203 	S0_AUTOBUF_REG,         /* 3ff3 */
204 	S0_RFSDIV_REG,          /* 3ff4 */
205 	S0_SCLKDIV_REG,         /* 3ff5 */
206 	S0_CONTROL_REG,         /* 3ff6 */
207 	S0_MCTXLO_REG,          /* 3ff7 */
208 	S0_MCTXHI_REG,          /* 3ff8 */
209 	S0_MCRXLO_REG,          /* 3ff9 */
210 	S0_MCRXHI_REG,          /* 3ffa */
211 	TIMER_SCALE_REG,        /* 3ffb */
212 	TIMER_COUNT_REG,        /* 3ffc */
213 	TIMER_PERIOD_REG,       /* 3ffd */
214 	WAITSTATES_REG,         /* 3ffe */
215 	SYSCONTROL_REG          /* 3fff */
216 };
217 
218 
219 /* these macros are used to reference the SDRC ASIC */
220 #define SDRC_ROM_ST     ((m_sdrc.reg[0] >> 0) & 3)    /* 0=0000, 1=3000, 2=3400, 3=none */
221 #define SDRC_ROM_SZ     ((m_sdrc.reg[0] >> 4) & 1)    /* 0=4k, 1=1k */
222 #define SDRC_ROM_MS     ((m_sdrc.reg[0] >> 5) & 1)    /* 0=/BMS, 1=/DMS */
223 #define SDRC_ROM_PG     ((m_sdrc.reg[0] >> 7) & 7)
224 #define SDRC_SM_EN      ((m_sdrc.reg[0] >> 11) & 1)
225 #define SDRC_SM_BK      ((m_sdrc.reg[0] >> 12) & 1)
226 #define SDRC_SMODE      ((m_sdrc.reg[0] >> 13) & 7)
227 
228 #define SDRC_DM_ST      ((m_sdrc.reg[1] >> 0) & 3)    /* 0=none, 1=0000, 2=3000, 3=3400 */
229 #define SDRC_DM_REF     ((m_sdrc.reg[1] >> 4) & 3)
230 #define SDRC_DM_3WS     ((m_sdrc.reg[1] >> 7) & 1)
231 #define SDRC_TFS_INV    ((m_sdrc.reg[1] >> 8) & 1)
232 #define SDRC_RES_TFS    ((m_sdrc.reg[1] >> 10) & 3)
233 #define SDRC_LED        ((m_sdrc.reg[1] >> 13) & 1)
234 #define SDRC_MUTE       ((m_sdrc.reg[1] >> 14) & 1)
235 #define SDRC_AREF_ACT   ((m_sdrc.reg[1] >> 15) & 1)
236 
237 #define SDRC_DM_PG      ((m_sdrc.reg[2] >> 0) & 0x7ff)
238 #define SDRC_EPM_PG     ((m_sdrc.reg[2] >> 0) & 0x1fff)
239 
240 
241 /* these macros are used to reference the DSIO ASIC */
242 #define DSIO_EMPTY_FIFO ((m_dsio.reg[1] >> 0) & 1)
243 #define DSIO_CUR_OUTPUT ((m_dsio.reg[1] >> 4) & 1)
244 #define DSIO_RES_TFS    ((m_dsio.reg[1] >> 10) & 1)
245 #define DSIO_LED        ((m_dsio.reg[1] >> 13) & 1)
246 #define DSIO_MUTE       ((m_dsio.reg[1] >> 14) & 1)
247 
248 #define DSIO_DM_PG      ((m_dsio.reg[2] >> 0) & 0x1fff)
249 
250 #define DSIO_BANK_END   0x3ff
251 
252 /* these macros are used to reference the DENVER ASIC */
253 #define DENV_DSP_SPEED  ((m_dsio.reg[1] >> 2) & 3)    /* read only: 1=33.33MHz */
254 #define DENV_RES_TFS    ((m_dsio.reg[1] >> 10) & 1)
255 #define DENV_CHANNELS   ((m_dsio.reg[1] >> 11) & 3)   /* 0=2ch, 1=4ch, 2=6ch */
256 #define DENV_LED        ((m_dsio.reg[1] >> 13) & 1)
257 #define DENV_MUTE       ((m_dsio.reg[1] >> 14) & 1)
258 
259 #define DENV_DM_PG      ((m_dsio.reg[2] >> 0) & 0x1fff)
260 
261 #define DENV_NUM_BANK 0x800
262 
263 
264 /*************************************
265  *
266  *  Original DCS Memory Maps
267  *
268  *************************************/
269 
270 /* DCS 2k memory map */
dcs_2k_program_map(address_map & map)271 void dcs_audio_device::dcs_2k_program_map(address_map &map)
272 {
273 	map(0x0000, 0x03ff).ram().share("dcsint");
274 	map(0x0800, 0x0fff).ram().share("dcsext");
275 	map(0x1000, 0x17ff).ram().share("dcsext");
276 	map(0x1800, 0x1fff).ram().share("dcsext");
277 }
278 
dcs_2k_data_map(address_map & map)279 void dcs_audio_device::dcs_2k_data_map(address_map &map)
280 {
281 	map(0x0000, 0x07ff).mirror(0x1800).rw(FUNC(dcs_audio_device::dcs_dataram_r), FUNC(dcs_audio_device::dcs_dataram_w));
282 	map(0x2000, 0x2fff).bankr("databank");
283 	map(0x3000, 0x33ff).w(FUNC(dcs_audio_device::dcs_data_bank_select_w));
284 	map(0x3400, 0x37ff).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::output_latch_w));
285 	map(0x3800, 0x39ff).ram();
286 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
287 }
288 
289 
290 /* DCS 2k with UART memory map */
dcs_2k_uart_data_map(address_map & map)291 void dcs_audio_device::dcs_2k_uart_data_map(address_map &map)
292 {
293 	map(0x0000, 0x07ff).mirror(0x1800).rw(FUNC(dcs_audio_device::dcs_dataram_r), FUNC(dcs_audio_device::dcs_dataram_w));
294 	map(0x2000, 0x2fff).bankr("databank");
295 	map(0x3000, 0x33ff).w(FUNC(dcs_audio_device::dcs_data_bank_select_w));
296 	map(0x3400, 0x3402).noprw();                             /* UART (ignored) */
297 	map(0x3403, 0x3403).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::output_latch_w));
298 	map(0x3404, 0x3405).noprw();                             /* UART (ignored) */
299 	map(0x3800, 0x39ff).ram().share("iram");
300 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
301 }
302 
303 
304 /* DCS 8k memory map */
dcs_8k_program_map(address_map & map)305 void dcs_audio_device::dcs_8k_program_map(address_map &map)
306 {
307 	map(0x0000, 0x03ff).ram().share("dcsint");
308 	map(0x0800, 0x1fff).ram().share("dcsext");
309 	map(0x3000, 0x3003).rw(FUNC(dcs_audio_device::input_latch32_r), FUNC(dcs_audio_device::output_latch32_w)); // why?
310 }
311 
dcs_8k_data_map(address_map & map)312 void dcs_audio_device::dcs_8k_data_map(address_map &map)
313 {
314 	map(0x0000, 0x07ff).ram();
315 	map(0x0800, 0x1fff).rw(FUNC(dcs_audio_device::dcs_dataram_r), FUNC(dcs_audio_device::dcs_dataram_w));
316 	map(0x2000, 0x2fff).bankr("databank");
317 	map(0x3000, 0x3000).w(FUNC(dcs_audio_device::dcs_data_bank_select_w));
318 	map(0x3400, 0x3403).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::output_latch_w)); // mk3 etc. need this
319 	map(0x3800, 0x39ff).ram().share("iram");
320 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
321 }
322 
323 /* Williams WPC DCS/Security Pinball */
dcs_wpc_program_map(address_map & map)324 void dcs_audio_device::dcs_wpc_program_map(address_map &map)
325 {
326 	map(0x0000, 0x03ff).ram().share("dcsint");
327 	map(0x1000, 0x3fff).ram().share("dcsext");
328 }
329 
dcs_wpc_data_map(address_map & map)330 void dcs_audio_wpc_device::dcs_wpc_data_map(address_map &map)
331 {
332 	map(0x0000, 0x07ff).bankr("databank");
333 	map(0x1000, 0x2fff).rw(FUNC(dcs_audio_wpc_device::dcs_dataram_r), FUNC(dcs_audio_wpc_device::dcs_dataram_w));
334 	map(0x3000, 0x3000).w(FUNC(dcs_audio_wpc_device::dcs_data_bank_select_w));
335 	map(0x3100, 0x3100).w(FUNC(dcs_audio_wpc_device::dcs_data_bank_select2_w));
336 	map(0x3300, 0x3303).rw(FUNC(dcs_audio_wpc_device::input_latch_r), FUNC(dcs_audio_wpc_device::output_latch_w));
337 	map(0x3800, 0x39ff).ram().share("iram");
338 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_wpc_device::adsp_control_r), FUNC(dcs_audio_wpc_device::adsp_control_w));
339 }
340 
341 /*************************************
342  *
343  *  DCS2 Memory Maps
344  *
345  *************************************/
346 
dcs2_2115_program_map(address_map & map)347 void dcs_audio_device::dcs2_2115_program_map(address_map &map)
348 {
349 	map.unmap_value_high();
350 	map(0x0000, 0x03ff).ram().share("dcsint");
351 }
352 
dcs2_2104_program_map(address_map & map)353 void dcs_audio_device::dcs2_2104_program_map(address_map &map)
354 {
355 	map.unmap_value_high();
356 	map(0x0000, 0x01ff).ram().share("dcsint");
357 }
358 
359 
dcs2_2115_data_map(address_map & map)360 void dcs_audio_device::dcs2_2115_data_map(address_map &map)
361 {
362 	map.unmap_value_high();
363 	map(0x0400, 0x0400).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::input_latch_ack_w));
364 	map(0x0401, 0x0401).w(FUNC(dcs_audio_device::output_latch_w));
365 	map(0x0402, 0x0402).rw(FUNC(dcs_audio_device::output_control_r), FUNC(dcs_audio_device::output_control_w));
366 	map(0x0403, 0x0403).r(FUNC(dcs_audio_device::latch_status_r));
367 	map(0x0404, 0x0407).r(FUNC(dcs_audio_device::fifo_input_r));
368 	map(0x0480, 0x0483).rw(FUNC(dcs_audio_device::sdrc_r), FUNC(dcs_audio_device::sdrc_w));
369 	map(0x3800, 0x39ff).ram().share("iram");
370 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
371 }
372 
dcs2_2104_data_map(address_map & map)373 void dcs_audio_device::dcs2_2104_data_map(address_map &map)
374 {
375 	map.unmap_value_high();
376 	map(0x0400, 0x0400).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::input_latch_ack_w));
377 	map(0x0401, 0x0401).w(FUNC(dcs_audio_device::output_latch_w));
378 	map(0x0402, 0x0402).rw(FUNC(dcs_audio_device::output_control_r), FUNC(dcs_audio_device::output_control_w));
379 	map(0x0403, 0x0403).r(FUNC(dcs_audio_device::latch_status_r));
380 	map(0x0404, 0x0407).r(FUNC(dcs_audio_device::fifo_input_r));
381 	map(0x0480, 0x0483).rw(FUNC(dcs_audio_device::sdrc_r), FUNC(dcs_audio_device::sdrc_w));
382 	map(0x3800, 0x39ff).ram().share("iram");
383 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
384 }
385 
386 
387 
388 /*************************************
389  *
390  *  DSIO Memory Maps
391  *
392  *************************************/
393 
dsio_program_map(address_map & map)394 void dcs_audio_device::dsio_program_map(address_map &map)
395 {
396 	map.unmap_value_high();
397 	map(0x0000, 0x3fff).ram().share("dcsint");
398 }
399 
400 
dsio_data_map(address_map & map)401 void dcs_audio_device::dsio_data_map(address_map &map)
402 {
403 	map.unmap_value_high();
404 	map(0x0000, 0x1fff).m("data_map_bank", FUNC(address_map_bank_device::amap16));
405 	map(0x2000, 0x3fdf).ram().share("dcsint_data");
406 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
407 }
408 
dsio_rambank_map(address_map & map)409 void dcs_audio_device::dsio_rambank_map(address_map &map)
410 {
411 	map(0x0000, 0x1fff).ram();
412 	map(0x2000, 0x3fff).bankrw("databank");
413 }
414 
dsio_io_map(address_map & map)415 void dcs_audio_device::dsio_io_map(address_map &map)
416 {
417 	map.unmap_value_high();
418 	map(0x0400, 0x0400).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::input_latch_ack_w));
419 	map(0x0401, 0x0401).w(FUNC(dcs_audio_device::output_latch_w));
420 	map(0x0402, 0x0402).rw(FUNC(dcs_audio_device::output_control_r), FUNC(dcs_audio_device::output_control_w));
421 	map(0x0403, 0x0403).r(FUNC(dcs_audio_device::latch_status_r));
422 	map(0x0404, 0x0407).r(FUNC(dcs_audio_device::fifo_input_r));
423 	map(0x0480, 0x0483).rw(FUNC(dcs_audio_device::dsio_r), FUNC(dcs_audio_device::dsio_w));
424 }
425 
426 
427 
428 /*************************************
429  *
430  *  Denver Memory Maps
431  *
432  *************************************/
433 
denver_program_map(address_map & map)434 void dcs_audio_device::denver_program_map(address_map &map)
435 {
436 	map.unmap_value_high();
437 	map(0x0000, 0x3fff).ram().share("dcsint");
438 }
439 
440 
denver_data_map(address_map & map)441 void dcs_audio_device::denver_data_map(address_map &map)
442 {
443 	map.unmap_value_high();
444 	map(0x0000, 0x1fff).m("data_map_bank", FUNC(address_map_bank_device::amap16));
445 	map(0x2000, 0x3fdf).ram().share("dcsint_data");
446 	map(0x3fe0, 0x3fff).rw(FUNC(dcs_audio_device::adsp_control_r), FUNC(dcs_audio_device::adsp_control_w));
447 }
448 
denver_rambank_map(address_map & map)449 void dcs_audio_device::denver_rambank_map(address_map &map)
450 {
451 	map(0x0000, 0x3fff).ram();
452 	map(0x4000, 0x7fff).bankrw("databank");
453 }
454 
455 
denver_io_map(address_map & map)456 void dcs_audio_device::denver_io_map(address_map &map)
457 {
458 	map.unmap_value_high();
459 	map(0x0400, 0x0400).rw(FUNC(dcs_audio_device::input_latch_r), FUNC(dcs_audio_device::input_latch_ack_w));
460 	map(0x0401, 0x0401).w(FUNC(dcs_audio_device::output_latch_w));
461 	map(0x0402, 0x0402).rw(FUNC(dcs_audio_device::output_control_r), FUNC(dcs_audio_device::output_control_w));
462 	map(0x0403, 0x0403).r(FUNC(dcs_audio_device::latch_status_r));
463 	map(0x0404, 0x0407).r(FUNC(dcs_audio_device::fifo_input_r));
464 	map(0x0480, 0x0483).rw(FUNC(dcs_audio_device::denver_r), FUNC(dcs_audio_device::denver_w));
465 }
466 
467 
468 /*************************************
469  *
470  *  ADSP booting
471  *
472  *************************************/
473 
dcs_boot()474 void dcs_audio_device::dcs_boot()
475 {
476 	switch (m_rev)
477 	{
478 		/* rev 1/1.5: use the last set data bank to boot from */
479 		case REV_DCS1:
480 		case REV_DCS1P5:
481 		{
482 			/* determine the base */
483 			// max_banks = m_bootrom_words / 0x1000;
484 			uint16_t* base = m_bootrom + ((m_sounddata_bank * 0x1000) % m_bootrom_words);
485 
486 			/* convert from 16-bit data to 8-bit data and boot */
487 			uint8_t buffer[0x1000];
488 			for (int i = 0; i < 0x1000; i++)
489 			{
490 				buffer[i] = base[i];
491 			}
492 			assert(m_internal_program_ram != nullptr);
493 			m_cpu->load_boot_data(buffer, m_internal_program_ram);
494 			break;
495 		}
496 
497 		/* rev 2: use the ROM page in the SDRC to boot from */
498 		case REV_DCS2:
499 		{
500 			/* determine the base */
501 			uint16_t* base;
502 			if (m_bootrom == m_sounddata)
503 			{
504 				/* EPROM case: page is selected from the page register */
505 				base = m_bootrom + ((SDRC_EPM_PG * 0x1000) % m_bootrom_words);
506 			}
507 			else
508 			{
509 				/* DRAM case: page is selected from the ROM page register */
510 				base = m_bootrom + ((SDRC_ROM_PG * 0x1000) % m_bootrom_words);
511 			}
512 
513 			/* convert from 16-bit data to 8-bit data and boot */
514 			uint8_t buffer[0x1000];
515 			for (int i = 0; i < 0x1000; i++)
516 			{
517 				buffer[i] = base[i];
518 			}
519 			assert(m_internal_program_ram != nullptr);
520 			m_cpu->load_boot_data(buffer, m_internal_program_ram);
521 			break;
522 		}
523 
524 		/* rev 3/4: HALT the ADSP-2181 until program is downloaded via IDMA */
525 		case REV_DSIO:
526 		case REV_DENV:
527 			m_cpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
528 			m_dsio.start_on_next_write = 0;
529 			break;
530 	}
531 }
532 
533 
534 
535 /*************************************
536  *
537  *  System reset
538  *
539  *************************************/
540 
TIMER_CALLBACK_MEMBER(dcs_audio_device::dcs_reset)541 TIMER_CALLBACK_MEMBER( dcs_audio_device::dcs_reset )
542 {
543 	if (LOG_DCS_IO)
544 		logerror("dcs_reset\n");
545 
546 	/* reset the memory banking */
547 	switch (m_rev)
548 	{
549 		/* rev 1/1.5: just reset the bank to 0 */
550 		case REV_DCS1:
551 		case REV_DCS1P5:
552 			m_sounddata_bank = 0;
553 			m_data_bank->set_entry(0);
554 			break;
555 
556 		/* rev 2: reset the SDRC ASIC */
557 		case REV_DCS2:
558 			sdrc_reset();
559 			break;
560 
561 		/* rev 3: reset the DSIO ASIC */
562 		case REV_DSIO:
563 			dsio_reset();
564 			break;
565 
566 		/* rev 4: reset the Denver ASIC */
567 		case REV_DENV:
568 			denver_reset();
569 			break;
570 	}
571 	/* initialize our state structure and install the transmit callback */
572 	m_size = 0;
573 	m_incs = 0;
574 	m_ireg = 0;
575 
576 	/* initialize the ADSP control regs */
577 	memset(m_control_regs, 0, sizeof(m_control_regs));
578 	/* clear all interrupts */
579 	m_cpu->set_input_line(ADSP2105_IRQ0, CLEAR_LINE);
580 	m_cpu->set_input_line(ADSP2105_IRQ1, CLEAR_LINE);
581 	m_cpu->set_input_line(ADSP2105_IRQ2, CLEAR_LINE);
582 
583 	/* initialize the comm bits */
584 	SET_INPUT_EMPTY();
585 	SET_OUTPUT_EMPTY();
586 	if (!m_last_input_empty && !m_input_empty_cb.isnull())
587 		m_input_empty_cb(m_last_input_empty = 1);
588 	if (m_last_output_full && !m_output_full_cb.isnull())
589 		m_output_full_cb(m_last_output_full = 0);
590 
591 	/* boot */
592 	dcs_boot();
593 
594 	/* reset timers */
595 	m_timer_ignore = false;
596 	m_timer_enable = 0;
597 	m_timer_scale = 1;
598 	m_internal_timer->reset();
599 
600 	/* reset the HLE transfer states */
601 	m_transfer.dcs_state = m_transfer.state = 0;
602 
603 }
604 
605 
606 
607 /*************************************
608  *
609  *  System setup
610  *
611  *************************************/
612 
dcs_register_state()613 void dcs_audio_device::dcs_register_state()
614 {
615 	save_item(NAME(m_sdrc.reg));
616 	save_item(NAME(m_sdrc.seed));
617 
618 	save_item(NAME(m_dsio.reg));
619 	save_item(NAME(m_dsio.start_on_next_write));
620 	save_item(NAME(m_dsio.channelbits));
621 
622 	save_item(NAME(m_channels));
623 	save_item(NAME(m_size));
624 	save_item(NAME(m_incs));
625 	save_item(NAME(m_ireg));
626 	save_item(NAME(m_ireg_base));
627 	save_item(NAME(m_control_regs));
628 
629 	save_item(NAME(m_sounddata_bank));
630 	save_item(NAME(m_dmovlay_val));
631 
632 	save_item(NAME(m_auto_ack));
633 	save_item(NAME(m_latch_control));
634 	save_item(NAME(m_input_data));
635 	save_item(NAME(m_output_data));
636 	save_item(NAME(m_output_control));
637 	save_item(NAME(m_output_control_cycles));
638 	save_item(NAME(m_last_output_full));
639 	save_item(NAME(m_last_input_empty));
640 	save_item(NAME(m_progflags));
641 
642 	save_item(NAME(m_timer_enable));
643 	save_item(NAME(m_timer_ignore));
644 	save_item(NAME(m_timer_start_cycles));
645 	save_item(NAME(m_timer_start_count));
646 	save_item(NAME(m_timer_scale));
647 	save_item(NAME(m_timer_period));
648 	save_item(NAME(m_timers_fired));
649 
650 	save_item(NAME(m_transfer.dcs_state));
651 	save_item(NAME(m_transfer.state));
652 	save_item(NAME(m_transfer.start));
653 	save_item(NAME(m_transfer.stop));
654 	save_item(NAME(m_transfer.type));
655 	save_item(NAME(m_transfer.temp));
656 	save_item(NAME(m_transfer.writes_left));
657 	save_item(NAME(m_transfer.sum));
658 	save_item(NAME(m_transfer.fifo_entries));
659 
660 	save_item(NAME(m_polling_value));
661 	save_item(NAME(m_polling32_value));
662 
663 	if (m_sram != nullptr)
664 		save_pointer(NAME(m_sram), 0x8000*4 / sizeof(m_sram[0]));
665 
666 	if (m_rev == REV_DCS2)
667 		machine().save().register_postload(save_prepost_delegate(FUNC(dcs_audio_device::sdrc_remap_memory), this));
668 
669 	if (m_rev == REV_DENV)
670 		machine().save().register_postload(save_prepost_delegate(FUNC(dcs_audio_device::denver_postload), this));
671 }
672 
denver_postload()673 void dcs_audio_device::denver_postload()
674 {
675 	m_data_bank->set_entry(DENV_DM_PG % m_sounddata_banks);
676 	dmovlay_remap_memory();
677 	denver_alloc_dmadac();
678 	install_speedup();
679 }
680 
681 //-------------------------------------------------
682 //  dcs_audio_device - constructor
683 //-------------------------------------------------
684 
dcs_audio_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int rev)685 dcs_audio_device::dcs_audio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rev) :
686 	device_t(mconfig, type, tag, owner, clock),
687 	m_cpu(nullptr),
688 	m_program(nullptr),
689 	m_data(nullptr),
690 	m_rev(rev),
691 	m_polling_offset(0),
692 	m_polling_count(0),
693 	m_channels(0),
694 	m_size(0),
695 	m_incs(0),
696 	m_reg_timer(nullptr),
697 	m_sport0_timer(nullptr),
698 	m_internal_timer(nullptr),
699 	m_ireg(0),
700 	m_ireg_base(0),
701 	m_bootrom(nullptr),
702 	m_bootrom_words(0),
703 	m_sounddata(nullptr),
704 	m_sounddata_words(0),
705 	m_sounddata_banks(0),
706 	m_sounddata_bank(0),
707 	m_ram_map(*this, "data_map_bank"),
708 	m_data_bank(*this, "databank"),
709 	m_rom_page(nullptr),
710 	m_dram_page(nullptr),
711 	m_auto_ack(0),
712 	m_latch_control(0),
713 	m_input_data(0),
714 	m_output_data(0),
715 	m_output_control(0),
716 	m_output_control_cycles(0),
717 	m_last_output_full(0),
718 	m_last_input_empty(0),
719 	m_progflags(0),
720 	m_output_full_cb(*this),
721 	m_input_empty_cb(*this),
722 	m_fifo_data_r(*this),
723 	m_fifo_status_r(*this),
724 	m_fifo_reset_w(*this),
725 	m_timer_enable(0),
726 	m_timer_ignore(false),
727 	m_timer_start_cycles(0),
728 	m_timer_start_count(0),
729 	m_timer_scale(0),
730 	m_timer_period(0),
731 	m_timers_fired(0),
732 	m_sram(nullptr),
733 	m_internal_program_ram(nullptr),
734 	m_external_program_ram(nullptr),
735 	m_internal_data_ram(nullptr),
736 	m_dram_in_mb(0),
737 	m_iram(*this, "iram"),
738 	m_maincpu(*this, ":maincpu")
739 {
740 	m_dmadac[0] = m_dmadac[1] = m_dmadac[2] = m_dmadac[3] = m_dmadac[4] = m_dmadac[5] = nullptr;
741 	memset(m_control_regs, 0, sizeof(m_control_regs));
742 	memset(&m_sdrc, 0, sizeof(m_sdrc));
743 	memset(&m_dsio, 0, sizeof(m_dsio));
744 	memset(&m_transfer, 0, sizeof(m_transfer));
745 }
746 
device_reset()747 void dcs_audio_device::device_reset()
748 {
749 	dcs_reset(nullptr, 0);
750 }
751 
device_start()752 void dcs_audio_device::device_start()
753 {
754 	m_sram = nullptr;
755 
756 	memory_share *internal_ram = memshare("dcsint");
757 	if (internal_ram != nullptr)
758 	{
759 		m_internal_program_ram = (uint32_t *)internal_ram->ptr();
760 	}
761 	memory_share *external_ram = memshare("dcsext");
762 	if (external_ram != nullptr)
763 	{
764 		m_external_program_ram = (uint32_t *)external_ram->ptr();
765 	}
766 
767 	/* find the DCS CPU and the sound ROMs */
768 	m_cpu = subdevice<adsp21xx_device>("dcs");
769 	if (m_cpu != nullptr && !m_cpu->started())
770 		throw device_missing_dependencies();
771 
772 	m_program = &m_cpu->space(AS_PROGRAM);
773 	m_data = &m_cpu->space(AS_DATA);
774 	m_channels = 1;
775 	m_dmadac[0] = subdevice<dmadac_sound_device>("dac");
776 
777 	/* configure boot and sound ROMs */
778 	m_bootrom = (uint16_t *)machine().root_device().memregion("dcs")->base();
779 	m_bootrom_words = machine().root_device().memregion("dcs")->bytes() / 2;
780 	m_sounddata = m_bootrom;
781 	m_sounddata_words = m_bootrom_words;
782 	if (m_rev == REV_DCS1)
783 	{
784 		m_sounddata_banks = m_sounddata_words / 0x1000;
785 		m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, 0x1000*2);
786 	}
787 	else
788 	{
789 		m_sounddata_banks = m_sounddata_words / 0x800;
790 		m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, 0x800*2);
791 	}
792 
793 	/* create the timers */
794 	m_internal_timer = subdevice<timer_device>("dcs_int_timer");
795 	m_reg_timer = subdevice<timer_device>("dcs_reg_timer");
796 
797 	/* non-RAM based automatically acks */
798 	m_auto_ack = true;
799 	/* register for save states */
800 	dcs_register_state();
801 	/* reset the system */
802 	dcs_reset(nullptr, 0);
803 }
804 
805 
device_start()806 void dcs2_audio_device::device_start()
807 {
808 	int soundbank_words;
809 
810 	memory_share *internal_ram = memshare("dcsint");
811 	if (internal_ram != nullptr)
812 	{
813 		m_internal_program_ram = (uint32_t *)internal_ram->ptr();
814 	}
815 	memory_share *external_ram = memshare("dcsext");
816 	if (external_ram != nullptr)
817 	{
818 		m_external_program_ram = (uint32_t *)external_ram->ptr();
819 	}
820 	memory_share *internal_data_ram = memshare("dcsint_data");
821 	if (internal_data_ram != nullptr)
822 	{
823 		m_internal_data_ram = (uint32_t *)internal_ram->ptr();
824 	}
825 
826 	/* find the DCS CPU and the sound ROMs */
827 	m_cpu = subdevice<adsp21xx_device>("dcs2");
828 	m_rev = REV_DCS2;
829 	soundbank_words = 0x1000;
830 	if (m_cpu == nullptr)
831 	{
832 		m_cpu = subdevice<adsp21xx_device>("dsio");
833 		m_rev = REV_DSIO;
834 		soundbank_words = DSIO_BANK_END + 1;
835 	}
836 	if (m_cpu == nullptr)
837 	{
838 		m_cpu = subdevice<adsp21xx_device>("denver");
839 		m_rev = REV_DENV;
840 		soundbank_words = ((m_dram_in_mb << 20) / 2) / DENV_NUM_BANK;
841 	}
842 	if (m_cpu != nullptr && !m_cpu->started())
843 		throw device_missing_dependencies();
844 
845 	m_program = &m_cpu->space(AS_PROGRAM);
846 	m_data = &m_cpu->space(AS_DATA);
847 	m_channels = 2;
848 	m_dmadac[0] = subdevice<dmadac_sound_device>("dac1");
849 	m_dmadac[1] = subdevice<dmadac_sound_device>("dac2");
850 
851 	/* always boot from the base of "dcs" */
852 	memory_region *bootrom_region = machine().root_device().memregion("dcs");
853 	if (bootrom_region != nullptr)
854 	{
855 		m_bootrom = (uint16_t *)bootrom_region->base();
856 		m_bootrom_words = bootrom_region->bytes() / 2;
857 	}
858 
859 	/* supports both RAM and ROM variants */
860 	if (m_dram_in_mb != 0)
861 	{
862 		m_sounddata_words = (m_dram_in_mb << 20) / 2;
863 		m_sounddata_ptr = std::make_unique<uint16_t[]>(m_sounddata_words);
864 		m_sounddata = m_sounddata_ptr.get();
865 		save_pointer(NAME(m_sounddata), m_sounddata_words);
866 	}
867 	else
868 	{
869 		m_sounddata = m_bootrom;
870 		m_sounddata_words = m_bootrom_words;
871 	}
872 	m_sounddata_banks = m_sounddata_words / soundbank_words;
873 	if (m_rev != REV_DCS2)
874 	{
875 		if (m_ram_map)
876 			m_ram_map->set_bank(0);
877 		m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, soundbank_words * 2);
878 		logerror("device_start: audio ram banks: %x size: %x\n", m_sounddata_banks, soundbank_words);
879 	}
880 
881 
882 	/* allocate memory for the SRAM */
883 	m_sram = std::make_unique<uint16_t[]>(0x8000*4/2);
884 
885 	/* create the timers */
886 	m_internal_timer = subdevice<timer_device>("dcs_int_timer");
887 	m_reg_timer = subdevice<timer_device>("dcs_reg_timer");
888 	m_sport0_timer = subdevice<timer_device>("dcs_sport0_timer");
889 
890 	/* we don't do auto-ack by default */
891 	m_auto_ack = false;
892 
893 	/* install the speedup handler */
894 	install_speedup();
895 
896 	/* allocate a watchdog timer for HLE transfers */
897 	m_transfer.hle_enabled = (ENABLE_HLE_TRANSFERS && m_dram_in_mb != 0 && m_rev < REV_DSIO);
898 	if (m_transfer.hle_enabled)
899 		m_transfer.watchdog = subdevice<timer_device>("dcs_hle_timer");
900 
901 	/* register for save states */
902 	dcs_register_state();
903 
904 	/* reset the system */
905 	dcs_reset(nullptr, 0);
906 }
907 
908 
install_speedup(void)909 void dcs_audio_device::install_speedup(void)
910 {
911 	if (m_polling_offset) {
912 		if (m_rev < REV_DSIO) {
913 			m_cpu->space(AS_DATA).install_read_handler(m_polling_offset, m_polling_offset, read16mo_delegate(*this, FUNC(dcs_audio_device::dcs_polling_r)));
914 			m_cpu->space(AS_DATA).install_write_handler(m_polling_offset, m_polling_offset, write16s_delegate(*this, FUNC(dcs_audio_device::dcs_polling_w)));
915 		}
916 		else {
917 			// ADSP 2181 (DSIO and DENVER) use program memory
918 			m_cpu->space(AS_PROGRAM).install_read_handler(m_polling_offset, m_polling_offset, read32mo_delegate(*this, FUNC(dcs_audio_device::dcs_polling32_r)));
919 			m_cpu->space(AS_PROGRAM).install_write_handler(m_polling_offset, m_polling_offset, write32s_delegate(*this, FUNC(dcs_audio_device::dcs_polling32_w)));
920 			// DSIO and DENVER poll in two spots.  This offset covers all three machines (mwskins, sf2049, roadburn).
921 			m_cpu->space(AS_PROGRAM).install_read_handler(m_polling_offset + 9, m_polling_offset + 9, read32mo_delegate(*this, FUNC(dcs_audio_device::dcs_polling32_r)));
922 			m_cpu->space(AS_PROGRAM).install_write_handler(m_polling_offset + 9, m_polling_offset + 9, write32s_delegate(*this, FUNC(dcs_audio_device::dcs_polling32_w)));
923 		}
924 	}
925 }
926 
set_auto_ack(int state)927 void dcs_audio_device::set_auto_ack(int state)
928 {
929 	m_auto_ack = state;
930 }
931 
932 
933 
934 /*************************************
935  *
936  *  Original DCS read/write handlers
937  *
938  *************************************/
939 
dcs_dataram_r(offs_t offset)940 uint16_t dcs_audio_device::dcs_dataram_r(offs_t offset)
941 {
942 	assert(m_external_program_ram != nullptr);
943 	return m_external_program_ram[offset] >> 8;
944 }
945 
946 
dcs_dataram_w(offs_t offset,uint16_t data,uint16_t mem_mask)947 void dcs_audio_device::dcs_dataram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
948 {
949 	assert(m_external_program_ram != nullptr);
950 	uint16_t val = m_external_program_ram[offset] >> 8;
951 	COMBINE_DATA(&val);
952 	m_external_program_ram[offset] = (val << 8) | (m_external_program_ram[offset] & 0x0000ff);
953 }
954 
955 
dcs_data_bank_select_w(uint16_t data)956 void dcs_audio_device::dcs_data_bank_select_w(uint16_t data)
957 {
958 	if (m_rev != REV_DCS1P5)
959 		m_sounddata_bank = data & 0x7ff;
960 	else
961 		m_sounddata_bank = (m_sounddata_bank & 0xff00) | (data & 0xff);
962 
963 	m_data_bank->set_entry(m_sounddata_bank % m_sounddata_banks);
964 
965 	/* bit 11 = sound board led */
966 #if 0
967 	if (m_rev != REV_DCS1P5)
968 		output().set_led_value(2, data & 0x800);
969 #endif
970 }
971 
dcs_data_bank_select2_w(uint16_t data)972 void dcs_audio_device::dcs_data_bank_select2_w(uint16_t data)
973 {
974 	m_sounddata_bank = (m_sounddata_bank & 0x00ff) | ((data & 0x01) << 8) | ((data & 0xfc) << 7);
975 
976 	m_data_bank->set_entry(m_sounddata_bank % m_sounddata_banks);
977 }
978 
979 /*************************************
980  *
981  *  SDRC ASIC Memory handling
982  *
983  *************************************/
984 
sdrc_update_bank_pointers()985 void dcs_audio_device::sdrc_update_bank_pointers()
986 {
987 	if (SDRC_SM_EN != 0)
988 	{
989 		int pagesize = (SDRC_ROM_SZ == 0 && SDRC_ROM_ST != 0) ? 4096 : 1024;
990 
991 		/* update the bank pointer based on whether we are ROM-based or RAM-based */
992 		if (m_bootrom == m_sounddata)
993 		{
994 			/* ROM-based; use the memory page to select from ROM */
995 			if (SDRC_ROM_MS == 1 && SDRC_ROM_ST != 3)
996 			{
997 				m_rom_page->set_base(&m_sounddata[(SDRC_EPM_PG * pagesize) % m_sounddata_words]);
998 			}
999 		}
1000 		else
1001 		{
1002 			/* RAM-based; use the ROM page to select from ROM, and the memory page to select from RAM */
1003 			if (SDRC_ROM_MS == 1 && SDRC_ROM_ST != 3)
1004 			{
1005 				m_rom_page->set_base(&m_bootrom[(SDRC_ROM_PG * 4096 /*pagesize*/) % m_bootrom_words]);
1006 			}
1007 			if (SDRC_DM_ST != 0)
1008 			{
1009 				m_dram_page->set_base(&m_sounddata[(SDRC_DM_PG * 1024) % m_sounddata_words]);
1010 			}
1011 		}
1012 	}
1013 }
1014 
1015 
sdrc_remap_memory()1016 void dcs_audio_device::sdrc_remap_memory()
1017 {
1018 	/* if SRAM disabled, clean it out */
1019 	if (SDRC_SM_EN == 0)
1020 	{
1021 		m_program->unmap_readwrite(0x0800, 0x3fff);
1022 		m_data->unmap_readwrite(0x0800, 0x37ff);
1023 	}
1024 
1025 	/* otherwise, map the SRAM */
1026 	else
1027 	{
1028 		/* first start with a clean program map */
1029 		m_program->install_ram(0x0800, 0x3fff, &m_sram[0x4800]);
1030 
1031 		/* set up the data map based on the SRAM banking */
1032 		/* map 0: ram from 0800-37ff */
1033 		if (SDRC_SM_BK == 0)
1034 		{
1035 			m_data->install_ram(0x0800, 0x17ff, &m_sram[0x0000]);
1036 			m_data->install_ram(0x1800, 0x27ff, &m_sram[0x1000]);
1037 			m_data->install_ram(0x2800, 0x37ff, &m_sram[0x2000]);
1038 		}
1039 
1040 		/* map 1: nothing from 0800-17ff, alternate RAM at 1800-27ff, same RAM at 2800-37ff */
1041 		else
1042 		{
1043 			m_data->unmap_readwrite(0x0800, 0x17ff);
1044 			m_data->install_ram(0x1800, 0x27ff, &m_sram[0x3000]);
1045 			m_data->install_ram(0x2800, 0x37ff, &m_sram[0x2000]);
1046 		}
1047 	}
1048 
1049 	/* map the ROM page as bank 25 */
1050 	if (SDRC_ROM_MS == 1 && SDRC_ROM_ST != 3)
1051 	{
1052 		int baseaddr = (SDRC_ROM_ST == 0) ? 0x0000 : (SDRC_ROM_ST == 1) ? 0x3000 : 0x3400;
1053 		int pagesize = (SDRC_ROM_SZ == 0 && SDRC_ROM_ST != 0) ? 4096 : 1024;
1054 		m_data->install_read_bank(baseaddr, baseaddr + pagesize - 1, "rompage");
1055 		m_rom_page = membank("rompage");
1056 	}
1057 
1058 	/* map the DRAM page as bank 26 */
1059 	if (SDRC_DM_ST != 0)
1060 	{
1061 		int baseaddr = (SDRC_DM_ST == 1) ? 0x0000 : (SDRC_DM_ST == 2) ? 0x3000 : 0x3400;
1062 		m_data->install_readwrite_bank(baseaddr, baseaddr + 0x3ff, "drampage");
1063 		m_dram_page = membank("drampage");
1064 	}
1065 
1066 	/* update the bank pointers */
1067 	sdrc_update_bank_pointers();
1068 
1069 	/* reinstall the polling hotspot */
1070 	install_speedup();
1071 }
1072 
1073 
sdrc_reset()1074 void dcs_audio_device::sdrc_reset()
1075 {
1076 	memset(m_sdrc.reg, 0, sizeof(m_sdrc.reg));
1077 	sdrc_remap_memory();
1078 }
1079 
1080 
1081 
1082 /*************************************
1083  *
1084  *  SDRC ASIC read/write
1085  *
1086  *************************************/
1087 
sdrc_r(offs_t offset)1088 uint16_t dcs_audio_device::sdrc_r(offs_t offset)
1089 {
1090 	sdrc_state &sdrc = m_sdrc;
1091 	uint16_t result = sdrc.reg[offset];
1092 
1093 	/* offset 3 is for security */
1094 	if (offset == 3)
1095 	{
1096 		switch (SDRC_SMODE)
1097 		{
1098 			default:
1099 			case 0: /* no-op */
1100 				result = 0x5a81;
1101 				break;
1102 
1103 			case 1: /* write seed */
1104 				result = 0x5aa4;
1105 				break;
1106 
1107 			case 2: /* read data */
1108 				result = 0x5a00 | ((sdrc.seed & 0x3f) << 1);
1109 				break;
1110 
1111 			case 3: /* shift left */
1112 				result = 0x5ab9;
1113 				break;
1114 
1115 			case 4: /* add */
1116 				result = 0x5a03;
1117 				break;
1118 
1119 			case 5: /* xor */
1120 				result = 0x5a69;
1121 				break;
1122 
1123 			case 6: /* prg */
1124 				result = 0x5a20;
1125 				break;
1126 
1127 			case 7: /* invert */
1128 				result = 0x5aff;
1129 				break;
1130 		}
1131 	}
1132 
1133 	return result;
1134 }
1135 
1136 
sdrc_w(offs_t offset,uint16_t data)1137 void dcs_audio_device::sdrc_w(offs_t offset, uint16_t data)
1138 {
1139 	sdrc_state &sdrc = m_sdrc;
1140 	uint16_t diff = sdrc.reg[offset] ^ data;
1141 
1142 	switch (offset)
1143 	{
1144 		/* offset 0 controls ROM mapping */
1145 		case 0:
1146 			sdrc.reg[0] = data;
1147 			if (diff & 0x1833)
1148 				sdrc_remap_memory();
1149 			if (diff & 0x0380)
1150 				sdrc_update_bank_pointers();
1151 			break;
1152 
1153 		/* offset 1 controls RAM mapping */
1154 		case 1:
1155 			sdrc.reg[1] = data;
1156 			//dmadac_enable(&m_dmadac[0], m_channels, SDRC_MUTE);
1157 			if (diff & 0x0003)
1158 				sdrc_remap_memory();
1159 			break;
1160 
1161 		/* offset 2 controls paging */
1162 		case 2:
1163 			sdrc.reg[2] = data;
1164 			if (diff & 0x1fff)
1165 				sdrc_update_bank_pointers();
1166 			break;
1167 
1168 		/* offset 3 controls security */
1169 		case 3:
1170 			switch (SDRC_SMODE)
1171 			{
1172 				case 0: /* no-op */
1173 				case 2: /* read data */
1174 					break;
1175 
1176 				case 1: /* write seed */
1177 					sdrc.seed = data & 0xff;
1178 					break;
1179 
1180 				case 3: /* shift left */
1181 					sdrc.seed = (sdrc.seed << 1) | 1;
1182 					break;
1183 
1184 				case 4: /* add */
1185 					sdrc.seed += sdrc.seed >> 1;
1186 					break;
1187 
1188 				case 5: /* xor */
1189 					sdrc.seed ^= (sdrc.seed << 1) | 1;
1190 					break;
1191 
1192 				case 6: /* prg */
1193 					sdrc.seed = (((sdrc.seed << 7) ^ (sdrc.seed << 5) ^ (sdrc.seed << 4) ^ (sdrc.seed << 3)) & 0x80) | (sdrc.seed >> 1);
1194 					break;
1195 
1196 				case 7: /* invert */
1197 					sdrc.seed = ~sdrc.seed;
1198 					break;
1199 			}
1200 			break;
1201 	}
1202 }
1203 
1204 
1205 
1206 /*************************************
1207  *
1208  *  DSIO ASIC read/write
1209  *
1210  *************************************/
1211 
dsio_reset()1212 void dcs_audio_device::dsio_reset()
1213 {
1214 	memset(&m_dsio, 0, sizeof(m_dsio));
1215 	m_dmovlay_val = 0;
1216 	dmovlay_remap_memory();
1217 }
1218 
1219 
dsio_r(offs_t offset)1220 uint16_t dcs_audio_device::dsio_r(offs_t offset)
1221 {
1222 	dsio_state &dsio = m_dsio;
1223 	uint16_t result = dsio.reg[offset];
1224 
1225 	if (offset == 1)
1226 	{
1227 		/* bit 4 specifies which channel is being output */
1228 		dsio.channelbits ^= 0x0010;
1229 		result = (result & ~0x0010) | dsio.channelbits;
1230 	}
1231 	if (LOG_DCS_IO && offset != 2) logerror("%s dsio_r 0x%x = %04x\n", machine().describe_context(), offset, result);
1232 	return result;
1233 }
1234 
1235 
dsio_w(offs_t offset,uint16_t data)1236 void dcs_audio_device::dsio_w(offs_t offset, uint16_t data)
1237 {
1238 	dsio_state &dsio = m_dsio;
1239 
1240 	switch (offset)
1241 	{
1242 		/* offset 1 controls I/O */
1243 		case 1:
1244 			dsio.reg[1] = data;
1245 
1246 			/* determine /MUTE and number of channels */
1247 			dmadac_enable(&m_dmadac[0], m_channels, DSIO_MUTE);
1248 
1249 			/* bit 0 resets the FIFO */
1250 			if (!m_fifo_reset_w.isnull())
1251 				m_fifo_reset_w(DSIO_EMPTY_FIFO ^ 1);
1252 			break;
1253 
1254 		/* offset 2 controls RAM pages */
1255 		case 2:
1256 			dsio.reg[2] = data;
1257 			m_data_bank->set_entry(DSIO_DM_PG % m_sounddata_banks);
1258 			break;
1259 	}
1260 	if (LOG_DCS_IO) logerror("%s dsio_w 0x%x = %04x\n", machine().describe_context(), offset, data);
1261 }
1262 
1263 
1264 
1265 /*************************************
1266  *
1267  *  Denver ASIC read/write
1268  *
1269  *************************************/
1270 
denver_reset()1271 void dcs_audio_device::denver_reset()
1272 {
1273 	memset(&m_dsio, 0, sizeof(m_dsio));
1274 	m_dmovlay_val = 0;
1275 	dmovlay_remap_memory();
1276 	dmadac_enable(&m_dmadac[0], m_channels, 0);
1277 	m_reg_timer->reset();
1278 	m_sport0_timer->reset();
1279 }
1280 
denver_alloc_dmadac()1281 void dcs_audio_device::denver_alloc_dmadac()
1282 {
1283 	int enable = DENV_MUTE;
1284 	for (int chan = 0; chan < m_channels; chan++)
1285 	{
1286 		char buffer[10];
1287 		sprintf(buffer, "dac%d", chan + 1);
1288 		m_dmadac[chan] = subdevice<dmadac_sound_device>(buffer);
1289 	}
1290 	dmadac_enable(&m_dmadac[0], m_channels, enable);
1291 	if (m_channels < 6)
1292 		dmadac_enable(&m_dmadac[m_channels], 6 - m_channels, false);
1293 	//if (enable)
1294 	//  recompute_sample_rate();
1295 }
1296 
denver_r(offs_t offset)1297 uint16_t dcs_audio_device::denver_r(offs_t offset)
1298 {
1299 	uint16_t result = m_dsio.reg[offset];
1300 
1301 	if (offset == 3)
1302 	{
1303 		/* returns 1 for DRAM, 2 for EPROM-based */
1304 		// SDRC Revision
1305 		result = 0x0003;
1306 	}
1307 	if (LOG_DCS_IO && offset != 0x2) logerror("%s denver_r %s 0x%x = %04x\n", machine().describe_context(), denver_regname[offset], offset, result);
1308 
1309 	return result;
1310 }
1311 
1312 
denver_w(offs_t offset,uint16_t data)1313 void dcs_audio_device::denver_w(offs_t offset, uint16_t data)
1314 {
1315 	dsio_state &dsio = m_dsio;
1316 	int channels;
1317 
1318 	uint16_t data_change = dsio.reg[offset] ^ data;
1319 
1320 	switch (offset)
1321 	{
1322 		/* offset 1 controls I/O */
1323 		case 1:
1324 			dsio.reg[1] = data;
1325 			// Ignore LED
1326 			data_change &= ~(1 << 13);
1327 			/* determine /MUTE and number of channels */
1328 			channels = 2 + 2 * DENV_CHANNELS;
1329 
1330 			/* if the number of channels has changed adjust */
1331 			if (channels != m_channels)
1332 			{
1333 				m_channels = channels;
1334 				denver_alloc_dmadac();
1335 			}
1336 			// Set MUTE
1337 			if (data_change & (1 << 14)) {
1338 				dmadac_enable(&m_dmadac[0], m_channels, DENV_MUTE);
1339 				if (m_channels < 6)
1340 					dmadac_enable(&m_dmadac[m_channels], 6 - m_channels, false);
1341 			}
1342 			// Disable timer after DENV_RES_TFS
1343 			if (!m_timer_ignore && DENV_RES_TFS && DENV_MUTE) {
1344 				logerror("%s denver_w: Disabling timer\n", machine().describe_context());
1345 				m_timer_ignore = true;
1346 			}
1347 			break;
1348 
1349 		/* offset 2 controls RAM pages */
1350 		case 2:
1351 			dsio.reg[2] = data;
1352 			m_data_bank->set_entry(DENV_DM_PG % m_sounddata_banks);
1353 			break;
1354 		/* offset 3 controls FIFO reset */
1355 		case 3:
1356 			if (!m_fifo_reset_w.isnull())
1357 				m_fifo_reset_w(1);
1358 			break;
1359 	}
1360 	if (LOG_DCS_IO && offset != 0x2) logerror("%s denver_w %s 0x%x = %04x\n", machine().describe_context(), denver_regname[offset], offset, data);
1361 }
1362 
1363 
1364 
1365 /*************************************
1366  *
1367  *  DSIO/Denver IDMA access
1368  *
1369  *************************************/
1370 
dsio_idma_addr_w(uint32_t data)1371 void dcs_audio_device::dsio_idma_addr_w(uint32_t data)
1372 {
1373 	if (LOG_DCS_TRANSFERS)
1374 		logerror("%s IDMA_addr = %04X\n", machine().describe_context(), data);
1375 	downcast<adsp2181_device *>(m_cpu)->idma_addr_w(data);
1376 	if (data == 0)
1377 		m_dsio.start_on_next_write = 2;
1378 }
1379 
1380 
dsio_idma_data_w(offs_t offset,uint32_t data,uint32_t mem_mask)1381 void dcs_audio_device::dsio_idma_data_w(offs_t offset, uint32_t data, uint32_t mem_mask)
1382 {
1383 	dsio_state &dsio = m_dsio;
1384 	// IDMA is to internal memory only
1385 	if (m_dmovlay_val)
1386 		m_ram_map->set_bank(0);
1387 	if (ACCESSING_BITS_0_15)
1388 	{
1389 		if (LOG_DCS_TRANSFERS && !(downcast<adsp2181_device *>(m_cpu)->idma_addr_r() & 0x00ff))
1390 			logerror("%s IDMA_data_w(%04X) = %04X\n", machine().describe_context(), downcast<adsp2181_device *>(m_cpu)->idma_addr_r(), data & 0xffff);
1391 		downcast<adsp2181_device *>(m_cpu)->idma_data_w(data & 0xffff);
1392 	}
1393 	if (ACCESSING_BITS_16_31)
1394 	{
1395 		if (LOG_DCS_TRANSFERS && !(downcast<adsp2181_device *>(m_cpu)->idma_addr_r() & 0x00ff))
1396 			logerror("%s IDMA_data_w(%04X) = %04X\n", machine().describe_context(), downcast<adsp2181_device *>(m_cpu)->idma_addr_r(), data >> 16);
1397 		downcast<adsp2181_device *>(m_cpu)->idma_data_w(data >> 16);
1398 	}
1399 	if (dsio.start_on_next_write && --dsio.start_on_next_write == 0)
1400 	{
1401 		logerror("%s: Starting DSIO CPU\n", machine().describe_context());
1402 		m_cpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
1403 	}
1404 	// Restore internal/external mapping
1405 	if (m_dmovlay_val)
1406 		m_ram_map->set_bank(m_dmovlay_val);
1407 
1408 }
1409 
1410 
dsio_idma_data_r()1411 uint32_t dcs_audio_device::dsio_idma_data_r()
1412 {
1413 	uint32_t result;
1414 	// IDMA is to internal memory only
1415 	m_ram_map->set_bank(0);
1416 	result = downcast<adsp2181_device *>(m_cpu)->idma_data_r();
1417 	// Restore internal/external mapping
1418 	m_ram_map->set_bank(m_dmovlay_val);
1419 	if (LOG_DCS_TRANSFERS)
1420 		logerror("%s IDMA_data_r(%04X) = %04X\n", machine().describe_context(), downcast<adsp2181_device *>(m_cpu)->idma_addr_r(), result);
1421 	return result;
1422 }
1423 
dmovlay_remap_memory()1424 void dcs_audio_device::dmovlay_remap_memory()
1425 {
1426 	// Switch banks
1427 	// Internal ram is bank 0
1428 	if (m_dmovlay_val == 0) {
1429 		m_ram_map->set_bank(0);
1430 	} else {
1431 		m_ram_map->set_bank(1);
1432 	}
1433 	if (LOG_DCS_IO) {
1434 		if (m_dmovlay_val==0)
1435 			logerror("%s dmovlay_remap_memory: Switching to internal data ram location dmovlay=%i\n", machine().describe_context(), m_dmovlay_val);
1436 		else
1437 			logerror("%s dmovlay_remap_memory: Switching to external data ram location dmovlay=%i\n", machine().describe_context(), m_dmovlay_val);
1438 	}
1439 }
1440 
dmovlay_callback(uint32_t data)1441 void dcs_audio_device::dmovlay_callback(uint32_t data)
1442 {
1443 	// Do some checking first
1444 	if (data < 0 || data > 1) {
1445 		logerror("dmovlay_callback: Error! dmovlay called with value = %X\n", data);
1446 	} else {
1447 		m_dmovlay_val = data;
1448 		dmovlay_remap_memory();
1449 	}
1450 }
1451 
1452 
1453 /***************************************************************************
1454     DCS COMMUNICATIONS
1455 ****************************************************************************/
1456 
set_io_callbacks(write_line_delegate output_full_cb,write_line_delegate input_empty_cb)1457 void dcs_audio_device::set_io_callbacks(write_line_delegate output_full_cb, write_line_delegate input_empty_cb)
1458 {
1459 	m_input_empty_cb = input_empty_cb;
1460 	m_output_full_cb = output_full_cb;
1461 }
1462 
1463 
set_fifo_callbacks(read16smo_delegate fifo_data_r,read16mo_delegate fifo_status_r,write_line_delegate fifo_reset_w)1464 void dcs_audio_device::set_fifo_callbacks(read16smo_delegate fifo_data_r, read16mo_delegate fifo_status_r, write_line_delegate fifo_reset_w)
1465 {
1466 	m_fifo_data_r = fifo_data_r;
1467 	m_fifo_status_r = fifo_status_r;
1468 	m_fifo_reset_w = fifo_reset_w;
1469 }
1470 
1471 
control_r()1472 int dcs_audio_device::control_r()
1473 {
1474 	/* only boost for DCS2 boards */
1475 	if (!m_auto_ack && !m_transfer.hle_enabled)
1476 		machine().scheduler().boost_interleave(attotime::from_nsec(500), attotime::from_usec(5));
1477 	if ( /* m_rev == REV_DSC1 || */ m_rev == REV_DCS1P5) // == 1 check breaks mk3
1478 		return IS_OUTPUT_FULL() ? 0x80 : 0x00;
1479 	return m_latch_control;
1480 }
1481 
1482 
reset_w(int state)1483 void dcs_audio_device::reset_w(int state)
1484 {
1485 	/* going low halts the CPU */
1486 	if (!state)
1487 	{
1488 		//      logerror("%s: DCS reset = %d\n", machine().describe_context(), state);
1489 
1490 		/* just run through the init code again */
1491 		machine().scheduler().synchronize(timer_expired_delegate(FUNC(dcs_audio_device::dcs_reset),this));
1492 		m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
1493 	}
1494 
1495 	/* going high resets and reactivates the CPU */
1496 	else
1497 		m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
1498 }
1499 
1500 
latch_status_r(address_space & space)1501 uint16_t dcs_audio_device::latch_status_r(address_space &space)
1502 {
1503 	int result = 0;
1504 	if (IS_INPUT_FULL())
1505 		result |= 0x80;
1506 	if (IS_OUTPUT_EMPTY())
1507 		result |= 0x40;
1508 	if (!m_fifo_status_r.isnull() && (!m_transfer.hle_enabled || m_transfer.state == 0))
1509 		result |= m_fifo_status_r(space) & 0x38;
1510 	if (m_transfer.hle_enabled && m_transfer.state != 0)
1511 		result |= 0x08;
1512 	return result;
1513 }
1514 
1515 
fifo_input_r()1516 uint16_t dcs_audio_device::fifo_input_r()
1517 {
1518 	if (!m_fifo_data_r.isnull())
1519 		return m_fifo_data_r();
1520 	else
1521 		return 0xffff;
1522 }
1523 
1524 
1525 
1526 /***************************************************************************
1527     INPUT LATCH (data from host to DCS)
1528 ****************************************************************************/
1529 
dcs_delayed_data_w(uint16_t data)1530 void dcs_audio_device::dcs_delayed_data_w(uint16_t data)
1531 {
1532 	if (LOG_DCS_IO)
1533 		logerror("%s:dcs_data_w(%04X)\n", machine().describe_context(), data);
1534 
1535 	/* boost the interleave temporarily */
1536 	machine().scheduler().boost_interleave(attotime::from_nsec(500), attotime::from_usec(5));
1537 
1538 	/* set the IRQ line on the ADSP */
1539 	m_cpu->set_input_line(ADSP2105_IRQ2, ASSERT_LINE);
1540 
1541 	/* indicate we are no longer empty */
1542 	if (m_last_input_empty && !m_input_empty_cb.isnull())
1543 		m_input_empty_cb(m_last_input_empty = 0);
1544 	SET_INPUT_FULL();
1545 
1546 	/* set the data */
1547 	m_input_data = data;
1548 }
1549 
1550 
TIMER_CALLBACK_MEMBER(dcs_audio_device::dcs_delayed_data_w_callback)1551 TIMER_CALLBACK_MEMBER( dcs_audio_device::dcs_delayed_data_w_callback )
1552 {
1553 	dcs_delayed_data_w(param);
1554 }
1555 
1556 
data_w(uint16_t data)1557 void dcs_audio_device::data_w(uint16_t data)
1558 {
1559 	/* preprocess the write */
1560 	// ADSP2181 variants use IDMA to transfer data
1561 	if (m_rev <= REV_DCS2 && preprocess_write(data))
1562 		return;
1563 
1564 	/* if we are DCS1, set a timer to latch the data */
1565 	if (m_sport0_timer == nullptr)
1566 		machine().scheduler().synchronize(timer_expired_delegate(FUNC(dcs_audio_device::dcs_delayed_data_w_callback),this), data);
1567 	else
1568 		dcs_delayed_data_w(data);
1569 }
1570 
1571 
input_latch_ack_w(uint16_t data)1572 void dcs_audio_device::input_latch_ack_w(uint16_t data)
1573 {
1574 	if (!m_last_input_empty && !m_input_empty_cb.isnull())
1575 		m_input_empty_cb(m_last_input_empty = 1);
1576 	SET_INPUT_EMPTY();
1577 	m_cpu->set_input_line(ADSP2105_IRQ2, CLEAR_LINE);
1578 
1579 	if (LOG_DCS_IO)
1580 		logerror("%s input_latch_ack_w\n", machine().describe_context());
1581 }
1582 
1583 
input_latch_r()1584 uint16_t dcs_audio_device::input_latch_r()
1585 {
1586 	if (m_auto_ack)
1587 		input_latch_ack_w(0);
1588 
1589 	if (LOG_DCS_IO)
1590 		logerror("%s input_latch_r(%04X)\n", machine().describe_context(), m_input_data);
1591 	return m_input_data;
1592 }
1593 
input_latch32_r()1594 uint32_t dcs_audio_device::input_latch32_r()
1595 {
1596 	if (m_auto_ack)
1597 		input_latch_ack_w(0);
1598 	if (LOG_DCS_IO)
1599 		logerror("%s input_latch32_r(%04X)\n", machine().describe_context(), m_input_data);
1600 	return m_input_data << 8;
1601 }
1602 
1603 /***************************************************************************
1604     OUTPUT LATCH (data from DCS to host)
1605 ****************************************************************************/
1606 
TIMER_CALLBACK_MEMBER(dcs_audio_device::latch_delayed_w)1607 TIMER_CALLBACK_MEMBER( dcs_audio_device::latch_delayed_w )
1608 {
1609 	if (!m_last_output_full && !m_output_full_cb.isnull())
1610 		m_output_full_cb(m_last_output_full = 1);
1611 	SET_OUTPUT_FULL();
1612 	m_output_data = m_pre_output_data;
1613 }
1614 
1615 
output_latch_w(uint16_t data)1616 void dcs_audio_device::output_latch_w(uint16_t data)
1617 {
1618 	m_pre_output_data = data;
1619 	if (LOG_DCS_IO)
1620 		logerror("%s output_latch_w(%04X) (empty=%d)\n", machine().describe_context(), data, IS_OUTPUT_EMPTY());
1621 
1622 	machine().scheduler().synchronize(timer_expired_delegate(FUNC(dcs_audio_device::latch_delayed_w),this), data>>8);
1623 }
1624 
output_latch32_w(uint32_t data)1625 void dcs_audio_device::output_latch32_w(uint32_t data)
1626 {
1627 	m_pre_output_data = data >> 8;
1628 	if (LOG_DCS_IO)
1629 		logerror("%s output_latch32_w(%04X) (empty=%d)\n", machine().describe_context(), data>>8, IS_OUTPUT_EMPTY());
1630 
1631 	machine().scheduler().synchronize(timer_expired_delegate(FUNC(dcs_audio_device::latch_delayed_w),this), data>>8);
1632 }
1633 
1634 
delayed_ack_w()1635 void dcs_audio_device::delayed_ack_w()
1636 {
1637 	SET_OUTPUT_EMPTY();
1638 }
1639 
1640 
TIMER_CALLBACK_MEMBER(dcs_audio_device::delayed_ack_w_callback)1641 TIMER_CALLBACK_MEMBER( dcs_audio_device::delayed_ack_w_callback )
1642 {
1643 	delayed_ack_w();
1644 }
1645 
1646 
ack_w()1647 void dcs_audio_device::ack_w()
1648 {
1649 	if (LOG_DCS_IO)
1650 		logerror("%s:ack_w\n", machine().describe_context());
1651 	machine().scheduler().synchronize(timer_expired_delegate(FUNC(dcs_audio_device::delayed_ack_w_callback),this));
1652 }
1653 
1654 
data_r()1655 uint16_t dcs_audio_device::data_r()
1656 {
1657 	// If the cpu is reading empty data it is probably polling so eat some cyles
1658 	if IS_OUTPUT_EMPTY()
1659 		m_maincpu->eat_cycles(4444);
1660 
1661 	/* data is actually only 8 bit (read from d8-d15, which is d0-d7 from the data access instructions POV) on early dcs, but goes 16 on later (seattle) */
1662 	if (m_last_output_full && !m_output_full_cb.isnull())
1663 		m_output_full_cb(m_last_output_full = 0);
1664 	if (m_auto_ack)
1665 		delayed_ack_w();
1666 
1667 	if (LOG_DCS_IO)
1668 		logerror("%s:dcs_data_r(%04X)\n", machine().describe_context(), m_output_data);
1669 	return m_output_data;
1670 }
1671 
1672 
1673 
1674 /***************************************************************************
1675     OUTPUT CONTROL BITS (has 3 additional lines to the host)
1676 ****************************************************************************/
1677 
TIMER_CALLBACK_MEMBER(dcs_audio_device::output_control_delayed_w)1678 TIMER_CALLBACK_MEMBER( dcs_audio_device::output_control_delayed_w )
1679 {
1680 	//if (LOG_DCS_IO)
1681 	//  logerror("output_control = %04X\n", param);
1682 	m_output_control = param;
1683 	m_output_control_cycles = 0;
1684 }
1685 
1686 
output_control_w(uint16_t data)1687 void dcs_audio_device::output_control_w(uint16_t data)
1688 {
1689 	if (LOG_DCS_IO)
1690 		logerror("%s output_control_w = %04X\n", machine().describe_context(), data);
1691 	machine().scheduler().synchronize(timer_expired_delegate(FUNC(dcs_audio_device::output_control_delayed_w),this), data);
1692 }
1693 
1694 
output_control_r()1695 uint16_t dcs_audio_device::output_control_r()
1696 {
1697 	if (LOG_DCS_IO)
1698 		logerror("%s output_control_r = %04X\n", machine().describe_context(), m_output_control);
1699 	m_output_control_cycles = m_cpu->total_cycles();
1700 	return m_output_control;
1701 }
1702 
1703 
data2_r()1704 int dcs_audio_device::data2_r()
1705 {
1706 	if (LOG_DCS_IO)
1707 		logerror("%s: dcs:data2_r = %04X\n", machine().describe_context(), m_output_control);
1708 
1709 	return m_output_control;
1710 }
1711 
1712 
1713 
1714 /*************************************
1715  *
1716  *  Timer management
1717  *
1718  *************************************/
1719 
update_timer_count()1720 void dcs_audio_device::update_timer_count()
1721 {
1722 	uint64_t periods_since_start;
1723 	uint64_t elapsed_cycles;
1724 	uint64_t elapsed_clocks;
1725 
1726 	/* if not enabled, skip */
1727 	if (!m_timer_enable)
1728 		return;
1729 
1730 	/* count cycles */
1731 	elapsed_cycles = m_cpu->total_cycles() - m_timer_start_cycles;
1732 	elapsed_clocks = elapsed_cycles / m_timer_scale;
1733 
1734 	/* if we haven't counted past the initial count yet, just do that */
1735 	if (elapsed_clocks < m_timer_start_count + 1) {
1736 		m_timer_start_count -= elapsed_clocks;
1737 		m_control_regs[TIMER_COUNT_REG] = m_timer_start_count;
1738 
1739 	/* otherwise, count how many periods */
1740 	}
1741 	else
1742 	{
1743 		elapsed_clocks -= m_timer_start_count + 1;
1744 		periods_since_start = elapsed_clocks / (m_timer_period + 1);
1745 		elapsed_clocks -= periods_since_start * (m_timer_period + 1);
1746 		m_timer_start_count = m_timer_period - elapsed_clocks;
1747 		m_control_regs[TIMER_COUNT_REG] = m_timer_start_count;
1748 	}
1749 }
1750 
1751 
TIMER_DEVICE_CALLBACK_MEMBER(dcs_audio_device::internal_timer_callback)1752 TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::internal_timer_callback )
1753 {
1754 	int64_t target_cycles;
1755 
1756 	/* compute the absolute cycle when the next one should fire */
1757 	/* we do this to avoid drifting */
1758 	m_timers_fired++;
1759 	target_cycles = m_timer_start_cycles + m_timer_scale * (m_timer_start_count + 1 + m_timers_fired * (uint64_t)(m_timer_period + 1));
1760 	target_cycles -= m_cpu->total_cycles();
1761 
1762 	/* set the next timer, but only if it's for a reasonable number */
1763 	if (!m_timer_ignore && (m_timer_period > 10 || m_timer_scale > 1))
1764 		timer.adjust(m_cpu->cycles_to_attotime(target_cycles));
1765 
1766 	/* the IRQ line is edge triggered */
1767 	m_cpu->set_input_line(ADSP2105_TIMER, ASSERT_LINE);
1768 	m_cpu->set_input_line(ADSP2105_TIMER, CLEAR_LINE);
1769 }
1770 
1771 
reset_timer()1772 void dcs_audio_device::reset_timer()
1773 {
1774 	/* if not enabled, skip */
1775 	if (!m_timer_enable)
1776 		return;
1777 
1778 	/* compute the time until the first firing */
1779 	m_timer_start_cycles = m_cpu->total_cycles();
1780 	m_timers_fired = 0;
1781 
1782 	/* if this is the first timer, check the IRQ routine for the DRAM refresh stub */
1783 	/* if that's all the timer does, we don't really need to fire */
1784 	if (!m_timer_ignore)
1785 	{
1786 		// Denver variants (mwskins and sf2049) use the timer as a scaler for another count so we can't disable here
1787 		// Denver gets disabled when reset TFS in the adsp control written
1788 		// Road Burners: Code gets moved after initial diagnostic checks
1789 		/* Road Burners: @ 28: JMP $0032  18032F, same code at $32 */
1790 		/* Road Burners: @ 28: JMP $0030  18030F, same code at $30 */
1791 		if (m_rev < REV_DSIO &&
1792 			m_program->read_dword(0x18) == 0x0c0030 &&      /* ENA SEC_REG */
1793 			m_program->read_dword(0x19) == 0x804828 &&      /* SI = DM($0482) */
1794 			m_program->read_dword(0x1a) == 0x904828 &&      /* DM($0482) = SI */
1795 			m_program->read_dword(0x1b) == 0x0C0020 &&      /* DIS SEC_REG */
1796 			m_program->read_dword(0x1c) == 0x0A001F)            /* RTI */
1797 		{
1798 			if (LOG_DCS_IO)
1799 				logerror("reset_timer: Disabled timer %llu\n", m_timer_start_cycles);
1800 			m_timer_ignore = true;
1801 		} else if (m_rev == REV_DSIO &&
1802 			m_program->read_dword(0x30) == 0x0c0030 &&      /* ENA SEC_REG */
1803 			m_program->read_dword(0x31) == 0x014828 &&      /* SI = IO($0482) */
1804 			m_program->read_dword(0x32) == 0x01c828 &&      /* IO($0482) = SI */
1805 			m_program->read_dword(0x33) == 0x0C0020 &&      /* DIS SEC_REG */
1806 			m_program->read_dword(0x34) == 0x0A001F)            /* RTI */
1807 		{
1808 			if (LOG_DCS_IO)
1809 				logerror("reset_timer: Disabled timer %llu\n", m_timer_start_cycles);
1810 			m_timer_ignore = true;
1811 		}
1812 	}
1813 
1814 	/* adjust the timer if not optimized */
1815 	if (!m_timer_ignore)
1816 		m_internal_timer->adjust(m_cpu->cycles_to_attotime(m_timer_scale * (m_timer_start_count + 1)));
1817 }
1818 
1819 
WRITE_LINE_MEMBER(dcs_audio_device::timer_enable_callback)1820 WRITE_LINE_MEMBER(dcs_audio_device::timer_enable_callback)
1821 {
1822 	if (state)
1823 	{
1824 		//logerror("Timer enabled @ %d cycles/int, or %f Hz\n", m_timer_scale * (m_timer_period + 1), 1.0 / m_cpu->cycles_to_attotime(m_timer_scale * (m_timer_period + 1)).as_double());
1825 		m_timer_enable = state;
1826 		reset_timer();
1827 	}
1828 	else
1829 	{
1830 		//logerror("Timer disabled\n");
1831 		// Update the timer so the start count is correct the next time the timer is enabled
1832 		update_timer_count();
1833 		m_timer_enable = state;
1834 		m_internal_timer->reset();
1835 	}
1836 }
1837 
1838 
1839 
1840 /***************************************************************************
1841     ADSP CONTROL & TRANSMIT CALLBACK
1842 ****************************************************************************/
1843 
1844 /*
1845     The ADSP2105 memory map when in boot rom mode is as follows:
1846 
1847     Program Memory:
1848     0x0000-0x03ff = Internal Program Ram (contents of boot rom gets copied here)
1849     0x0400-0x07ff = Reserved
1850     0x0800-0x3fff = External Program Ram
1851 
1852     Data Memory:
1853     0x0000-0x03ff = External Data - 0 Waitstates
1854     0x0400-0x07ff = External Data - 1 Waitstates
1855     0x0800-0x2fff = External Data - 2 Waitstates
1856     0x3000-0x33ff = External Data - 3 Waitstates
1857     0x3400-0x37ff = External Data - 4 Waitstates
1858     0x3800-0x39ff = Internal Data Ram
1859     0x3a00-0x3bff = Reserved (extra internal ram space on ADSP2101, etc)
1860     0x3c00-0x3fff = Memory Mapped control registers & reserved.
1861 */
1862 
adsp_control_r(offs_t offset)1863 uint16_t dcs_audio_device::adsp_control_r(offs_t offset)
1864 {
1865 	uint16_t result = 0xffff;
1866 
1867 	switch (offset)
1868 	{
1869 		case PROG_FLAG_DATA_REG:
1870 			// Probably some sort of frame start for DAC with external clock
1871 			// Denver Atlantis mwskins wants 0x2 to toggle
1872 			// Denver Durnago sf2049te wants 0x6 to toogle
1873 			result = (m_control_regs[PROG_FLAG_CONTROL_REG] & m_control_regs[PROG_FLAG_DATA_REG]) | (m_progflags & ~m_control_regs[PROG_FLAG_CONTROL_REG]);
1874 			m_progflags ^= 0x6;
1875 			break;
1876 
1877 		case IDMA_CONTROL_REG:
1878 			if (m_rev == REV_DSIO || m_rev == REV_DENV)
1879 				result = downcast<adsp2181_device *>(m_cpu)->idma_addr_r();
1880 			break;
1881 
1882 		case TIMER_COUNT_REG:
1883 			update_timer_count();
1884 			result = m_control_regs[offset];
1885 			break;
1886 
1887 		default:
1888 			result = m_control_regs[offset];
1889 			break;
1890 	}
1891 	if (LOG_DCS_IO)
1892 		logerror("%s adsp_control_r(%06x) = %04X\n", machine().describe_context(), offset + 0x3fe0, result);
1893 	return result;
1894 }
1895 
1896 
adsp_control_w(offs_t offset,uint16_t data)1897 void dcs_audio_device:: adsp_control_w(offs_t offset, uint16_t data)
1898 {
1899 	m_control_regs[offset] = data;
1900 
1901 	switch (offset)
1902 	{
1903 		case SYSCONTROL_REG:
1904 			/* bit 9 forces a reset (not on 2181) */
1905 			if ((data & 0x0200) && !(m_rev == REV_DSIO || m_rev == REV_DENV))
1906 			{
1907 				logerror("%s Rebooting DCS due to SYSCONTROL write = %04X\n", machine().describe_context(), data);
1908 				m_cpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
1909 				dcs_boot();
1910 				m_control_regs[SYSCONTROL_REG] = 0;
1911 			}
1912 
1913 			/* see if SPORT1 got disabled */
1914 			if ((data & 0x0800) == 0)
1915 			{
1916 				dmadac_enable(&m_dmadac[0], m_channels, 0);
1917 				m_reg_timer->reset();
1918 			}
1919 
1920 			// Check SPORT0 enabled
1921 			if (m_sport0_timer != nullptr) {
1922 				if (data & 0x1000) {
1923 					// Start the SPORT0 timer
1924 					// SPORT0 is used as a 1kHz timer
1925 					m_sport0_timer->adjust(attotime::from_usec(10), 0, attotime::from_hz(1000));
1926 					if (LOG_DCS_IO)
1927 						logerror("adsp_control_w: Setting SPORT0 freqency to 1kHz\n");
1928 				}
1929 				else {
1930 					// Stop the SPORT0 timer
1931 					m_sport0_timer->reset();
1932 				}
1933 			}
1934 			break;
1935 
1936 		case S1_AUTOBUF_REG:
1937 			/* autobuffer off: nuke the timer, and disable the DAC */
1938 			if ((data & 0x0002) == 0)
1939 			{
1940 				dmadac_enable(&m_dmadac[0], m_channels, 0);
1941 				m_reg_timer->reset();
1942 			}
1943 			break;
1944 
1945 		case S1_CONTROL_REG:
1946 			if (((data >> 4) & 3) == 2)
1947 				logerror("DCS: Oh no!, the data is compressed with u-law encoding\n");
1948 			if (((data >> 4) & 3) == 3)
1949 				logerror("DCS: Oh no!, the data is compressed with A-law encoding\n");
1950 			break;
1951 
1952 		case TIMER_SCALE_REG:
1953 			data = (data & 0xff) + 1;
1954 			if (data != m_timer_scale)
1955 			{
1956 				update_timer_count();
1957 				m_timer_scale = data;
1958 				reset_timer();
1959 			}
1960 			break;
1961 
1962 		case TIMER_COUNT_REG:
1963 			m_timer_start_count = data;
1964 			reset_timer();
1965 			break;
1966 
1967 		case TIMER_PERIOD_REG:
1968 			if (data != m_timer_period)
1969 			{
1970 				update_timer_count();
1971 				m_timer_period = data;
1972 				reset_timer();
1973 			}
1974 			break;
1975 
1976 		case IDMA_CONTROL_REG:
1977 			if (m_rev == REV_DSIO || m_rev == REV_DENV)
1978 				dsio_idma_addr_w(data);
1979 			break;
1980 	}
1981 	if (LOG_DCS_IO)
1982 		logerror("%s adsp_control_w(%06x) = %04X\n", machine().describe_context(), offset + 0x3fe0, data);
1983 }
1984 
1985 
1986 /***************************************************************************
1987     DCS IRQ GENERATION CALLBACKS
1988 ****************************************************************************/
1989 
TIMER_DEVICE_CALLBACK_MEMBER(dcs_audio_device::dcs_irq)1990 TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq )
1991 {
1992 	/* get the index register */
1993 	int reg = m_cpu->state_int(ADSP2100_I0 + m_ireg);
1994 	if (LOG_DCS_IO)
1995 		logerror("dcs_irq: m_ireg: %x m_size: %x m_incs: %x m_channels: %d m_ireg_base: %x reg: %06x\n", m_ireg, m_size, m_incs, m_channels, m_ireg_base, reg);
1996 
1997 	/* copy the current data into the buffer */
1998 	{
1999 		int count = m_size / (2*(m_incs ? m_incs : 1));
2000 		// sf2049se was having overflow issues with fixed size of 0x400 buffer (m_size==0xb40, count=0x5a0).
2001 		int16_t buffer[0x800];
2002 		int i;
2003 
2004 		for (i = 0; i < count; i++)
2005 		{
2006 			buffer[i] = m_data->read_word(reg);
2007 			reg += m_incs;
2008 		}
2009 
2010 		if (m_channels)
2011 			dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer);
2012 	}
2013 
2014 	/* check for wrapping */
2015 	m_ireg_base = m_cpu->get_ibase(m_ireg);
2016 	if (reg >= m_ireg_base + m_size)
2017 	{
2018 		/* reset the base pointer */
2019 		reg = m_ireg_base;
2020 
2021 		/* generate the (internal, thats why the pulse) irq */
2022 		if (LOG_DCS_IO)
2023 			logerror("dcs_irq: Genrating interrupt\n");
2024 		m_cpu->pulse_input_line(ADSP2105_IRQ1, m_cpu->minimum_quantum_time());
2025 	}
2026 
2027 	/* store it */
2028 	m_cpu->set_state_int(ADSP2100_I0 + m_ireg, reg);
2029 	if (LOG_DCS_IO)
2030 		logerror("dcs_irq end: m_size: %x m_incs: %x m_channels: %d m_ireg_base: %x reg: %06x\n", m_size, m_incs, m_channels, m_ireg_base, reg);
2031 }
2032 
TIMER_DEVICE_CALLBACK_MEMBER(dcs_audio_device::sport0_irq)2033 TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::sport0_irq )
2034 {
2035 
2036 	/* this latches internally, so we just pulse */
2037 	/* note that there is non-interrupt code that reads/modifies/writes the output_control */
2038 	/* register; if we don't interlock it, we will eventually lose sound (see CarnEvil) */
2039 	/* so we skip the SPORT interrupt if we read with output_control within the last 5 cycles */
2040 	uint64_t diff = m_cpu->total_cycles() - m_output_control_cycles;
2041 	if (diff > 5)
2042 	{
2043 		m_cpu->set_input_line(ADSP2115_SPORT0_RX, ASSERT_LINE);
2044 		m_cpu->set_input_line(ADSP2115_SPORT0_RX, CLEAR_LINE);
2045 	}
2046 }
2047 
2048 
recompute_sample_rate()2049 void dcs_audio_device::recompute_sample_rate()
2050 {
2051 	/* calculate how long until we generate an interrupt */
2052 
2053 	/* frequency the time per each bit sent */
2054 	attotime sample_period;
2055 	if (m_control_regs[S1_CONTROL_REG] & 0x4000) {
2056 		// Use internal clock for SPORT1 Tx timing
2057 		sample_period = attotime::from_hz(m_cpu->unscaled_clock()) * (2 * (m_control_regs[S1_SCLKDIV_REG] + 1));
2058 		/* now put it down to samples, so we know what the channel frequency has to be */
2059 		sample_period *= (16 * m_channels);
2060 	}
2061 	else {
2062 		// Use external clock for SPORT1 Tx timing 31.25 KHz sample clock
2063 		sample_period = attotime::from_hz(31250);
2064 	}
2065 
2066 	dmadac_set_frequency(&m_dmadac[0], m_channels, sample_period.as_hz());
2067 	dmadac_enable(&m_dmadac[0], m_channels, 1);
2068 	if (LOG_DCS_IO)
2069 		logerror("recompute_sample_rate: Channels: %d Freq: %e Size: 0x%x m_incs: 0x%x\n", m_channels, sample_period.as_hz(), m_size, m_incs);
2070 
2071 	/* fire off a timer which will hit every half-buffer */
2072 	if (m_incs)
2073 	{
2074 		attotime period = (sample_period * m_size) / (2 * m_channels * m_incs);
2075 		m_reg_timer->adjust(period, 0, period);
2076 	}
2077 }
2078 
sound_tx_callback(offs_t offset,uint32_t data)2079 void dcs_audio_device::sound_tx_callback(offs_t offset, uint32_t data)
2080 {
2081 	/* check if it's for SPORT1 */
2082 	if (offset != 1) {
2083 		logerror("sound_tx_callback: No code for offset %x\n", offset);
2084 		return;
2085 	}
2086 
2087 	/* check if SPORT1 is enabled */
2088 	if (m_control_regs[SYSCONTROL_REG] & 0x0800) /* bit 11 */
2089 	{
2090 		/* we only support autobuffer here (wich is what this thing uses), bail if not enabled */
2091 		if (m_control_regs[S1_AUTOBUF_REG] & 0x0002) /* bit 1 */
2092 		{
2093 			/* get the autobuffer registers */
2094 			int     mreg, lreg;
2095 			uint16_t  source;
2096 
2097 			m_ireg = (m_control_regs[S1_AUTOBUF_REG] >> 9) & 7;
2098 			mreg = (m_control_regs[S1_AUTOBUF_REG] >> 7) & 3;
2099 			mreg |= m_ireg & 0x04; /* msb comes from ireg */
2100 			lreg = m_ireg;
2101 
2102 			/* now get the register contents in a more legible format */
2103 			/* we depend on register indexes to be continuous (which is the case in our core) */
2104 			source = m_cpu->state_int(ADSP2100_I0 + m_ireg);
2105 			m_incs = m_cpu->state_int(ADSP2100_M0 + mreg);
2106 			m_size = m_cpu->state_int(ADSP2100_L0 + lreg);
2107 
2108 			/* get the base value, since we need to keep it around for wrapping */
2109 			//source -= m_incs;
2110 			// Just clear lower 4 bits of source since some DCS versions haven't incremented yet
2111 			source &= ~0xf;
2112 
2113 			/* make it go back one so we dont lose the first sample */
2114 			m_cpu->set_state_int(ADSP2100_I0 + m_ireg, source);
2115 
2116 			/* save it as it is now */
2117 			m_ireg_base = source;
2118 
2119 			if (LOG_DCS_IO)
2120 				logerror("sound_tx_callback: m_ireg_base: %x m_size: %x m_incs: %x \n", m_ireg_base, m_size, m_incs);
2121 			/* recompute the sample rate and timer */
2122 			recompute_sample_rate();
2123 			return;
2124 		}
2125 		else
2126 			logerror( "ADSP SPORT1: trying to transmit and autobuffer not enabled!\n" );
2127 	}
2128 
2129 	/* if we get there, something went wrong. Disable playing */
2130 	dmadac_enable(&m_dmadac[0], m_channels, 0);
2131 
2132 	/* remove timer */
2133 	m_reg_timer->reset();
2134 }
2135 
2136 
2137 
2138 /***************************************************************************
2139     VERY BASIC & SAFE OPTIMIZATIONS
2140 ****************************************************************************/
2141 
dcs_polling_r(address_space & space)2142 uint16_t dcs_audio_device::dcs_polling_r(address_space &space)
2143 {
2144 	if (m_polling_count++ > 5)
2145 		space.device().execute().eat_cycles(2000);
2146 	return m_polling_value;
2147 }
2148 
2149 
dcs_polling_w(offs_t offset,uint16_t data,uint16_t mem_mask)2150 void dcs_audio_device::dcs_polling_w(offs_t offset, uint16_t data, uint16_t mem_mask)
2151 {
2152 	m_polling_count = 0;
2153 	COMBINE_DATA(&m_polling_value);
2154 }
2155 
dcs_polling32_r(address_space & space)2156 uint32_t dcs_audio_device::dcs_polling32_r(address_space &space)
2157 {
2158 	space.device().execute().eat_cycles(1000);
2159 	return m_polling32_value;
2160 }
2161 
dcs_polling32_w(offs_t offset,uint32_t data,uint32_t mem_mask)2162 void dcs_audio_device::dcs_polling32_w(offs_t offset, uint32_t data, uint32_t mem_mask)
2163 {
2164 	m_polling_count = 0;
2165 	COMBINE_DATA(&m_polling32_value);
2166 }
2167 
2168 
2169 
2170 /***************************************************************************
2171     DATA TRANSFER HLE MECHANISM
2172 ****************************************************************************/
2173 
fifo_notify(int count,int max)2174 void dcs_audio_device::fifo_notify(int count, int max)
2175 {
2176 	hle_transfer_state &transfer = m_transfer;
2177 
2178 	/* skip if not in mid-transfer */
2179 	if (!transfer.hle_enabled || transfer.state == 0 || m_fifo_data_r.isnull())
2180 	{
2181 		transfer.fifo_entries = 0;
2182 		return;
2183 	}
2184 
2185 	/* preprocess a word */
2186 	transfer.fifo_entries = count;
2187 	if (transfer.state != 5 || transfer.fifo_entries == transfer.writes_left || transfer.fifo_entries >= 256)
2188 	{
2189 		for ( ; transfer.fifo_entries; transfer.fifo_entries--)
2190 			preprocess_write(m_fifo_data_r());
2191 	}
2192 }
2193 
2194 
TIMER_DEVICE_CALLBACK_MEMBER(dcs_audio_device::transfer_watchdog_callback)2195 TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::transfer_watchdog_callback )
2196 {
2197 	hle_transfer_state &transfer = m_transfer;
2198 	int starting_writes_left = param;
2199 
2200 	if (transfer.fifo_entries && starting_writes_left == transfer.writes_left)
2201 	{
2202 		for ( ; transfer.fifo_entries; transfer.fifo_entries--)
2203 			preprocess_write(m_fifo_data_r());
2204 	}
2205 	if (transfer.watchdog != nullptr)
2206 		transfer.watchdog->adjust(attotime::from_msec(1), transfer.writes_left);
2207 }
2208 
2209 
TIMER_CALLBACK_MEMBER(dcs_audio_device::s1_ack_callback2)2210 TIMER_CALLBACK_MEMBER( dcs_audio_device::s1_ack_callback2 )
2211 {
2212 	/* if the output is full, stall for a usec */
2213 	if (IS_OUTPUT_FULL())
2214 	{
2215 		machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(dcs_audio_device::s1_ack_callback2),this), param);
2216 		return;
2217 	}
2218 	output_latch_w(0x000a);
2219 }
2220 
2221 
TIMER_CALLBACK_MEMBER(dcs_audio_device::s1_ack_callback1)2222 TIMER_CALLBACK_MEMBER( dcs_audio_device::s1_ack_callback1 )
2223 {
2224 	/* if the output is full, stall for a usec */
2225 	if (IS_OUTPUT_FULL())
2226 	{
2227 		machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(dcs_audio_device::s1_ack_callback1),this), param);
2228 		return;
2229 	}
2230 	output_latch_w(param);
2231 
2232 	/* chain to the next word we need to write back */
2233 	machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(dcs_audio_device::s1_ack_callback2),this));
2234 }
2235 
2236 
preprocess_stage_1(uint16_t data)2237 int dcs_audio_device::preprocess_stage_1(uint16_t data)
2238 {
2239 	hle_transfer_state &transfer = m_transfer;
2240 
2241 	switch (transfer.state)
2242 	{
2243 		case 0:
2244 			/* look for command 0x001a to transfer chunks of data */
2245 			if (data == 0x001a)
2246 			{
2247 				if (LOG_DCS_TRANSFERS)
2248 					logerror("%s:DCS Transfer command %04X\n", machine().describe_context(), data);
2249 				transfer.state++;
2250 				if (transfer.hle_enabled)
2251 					return 1;
2252 			}
2253 
2254 			/* look for command 0x002a to start booting the uploaded program */
2255 			else if (data == 0x002a)
2256 			{
2257 				if (LOG_DCS_TRANSFERS)
2258 					logerror("%s:DCS State change %04X\n", machine().describe_context(), data);
2259 				transfer.dcs_state = 1;
2260 			}
2261 
2262 			/* anything else is ignored */
2263 			else
2264 			{
2265 				if (LOG_DCS_TRANSFERS)
2266 					logerror("Command: %04X\n", data);
2267 			}
2268 			break;
2269 
2270 		case 1:
2271 			/* first word is the start address */
2272 			transfer.start = data;
2273 			transfer.state++;
2274 			if (LOG_DCS_TRANSFERS)
2275 				logerror("Start address = %04X\n", transfer.start);
2276 			if (transfer.hle_enabled)
2277 				return 1;
2278 			break;
2279 
2280 		case 2:
2281 			/* second word is the stop address */
2282 			transfer.stop = data;
2283 			transfer.state++;
2284 			if (LOG_DCS_TRANSFERS)
2285 				logerror("Stop address = %04X\n", transfer.stop);
2286 			if (transfer.hle_enabled)
2287 				return 1;
2288 			break;
2289 
2290 		case 3:
2291 			/* third word is the transfer type */
2292 			/* transfer type 0 = program memory */
2293 			/* transfer type 1 = SRAM bank 0 */
2294 			/* transfer type 2 = SRAM bank 1 */
2295 			transfer.type = data;
2296 			transfer.state++;
2297 			if (LOG_DCS_TRANSFERS) logerror("Transfer type = %04X\n", transfer.type);
2298 
2299 			/* at this point, we can compute how many words to expect for the transfer */
2300 			transfer.writes_left = transfer.stop - transfer.start + 1;
2301 			if (transfer.type == 0)
2302 				transfer.writes_left *= 2;
2303 
2304 			/* reset the checksum */
2305 			transfer.sum = 0;
2306 
2307 			/* handle the HLE case */
2308 			if (transfer.hle_enabled)
2309 			{
2310 				if (transfer.type == 1 && SDRC_SM_BK == 1)
2311 				{
2312 					m_sdrc.reg[0] &= ~0x1000;
2313 					sdrc_remap_memory();
2314 				}
2315 				if (transfer.type == 2 && SDRC_SM_BK == 0)
2316 				{
2317 					m_sdrc.reg[0] |= 0x1000;
2318 					sdrc_remap_memory();
2319 				}
2320 				return 1;
2321 			}
2322 			break;
2323 
2324 		case 4:
2325 			/* accumulate the sum over all data */
2326 			transfer.sum += data;
2327 
2328 			/* if we're out, stop the transfer */
2329 			if (--transfer.writes_left == 0)
2330 			{
2331 				if (LOG_DCS_TRANSFERS) logerror("Transfer done, sum = %04X\n", transfer.sum);
2332 				transfer.state = 0;
2333 			}
2334 
2335 			/* handle the HLE case */
2336 			if (transfer.hle_enabled)
2337 			{
2338 				/* write the new data to memory */
2339 				if (transfer.type == 0)
2340 				{
2341 					if (transfer.writes_left & 1)
2342 						transfer.temp = data;
2343 					else
2344 						m_program->write_dword(transfer.start++, (transfer.temp << 8) | (data & 0xff));
2345 				}
2346 				else
2347 					m_data->write_word(transfer.start++, data);
2348 
2349 				/* if we're done, start a timer to send the response words */
2350 				if (transfer.state == 0)
2351 					machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(dcs_audio_device::s1_ack_callback1),this), transfer.sum);
2352 				return 1;
2353 			}
2354 			break;
2355 	}
2356 	return 0;
2357 }
2358 
2359 
TIMER_CALLBACK_MEMBER(dcs_audio_device::s2_ack_callback)2360 TIMER_CALLBACK_MEMBER( dcs_audio_device::s2_ack_callback )
2361 {
2362 	/* if the output is full, stall for a usec */
2363 	if (IS_OUTPUT_FULL())
2364 	{
2365 		machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(dcs_audio_device::s2_ack_callback),this), param);
2366 		return;
2367 	}
2368 	output_latch_w(param);
2369 	output_control_w((m_output_control & ~0xff00) | 0x0300);
2370 }
2371 
2372 
preprocess_stage_2(uint16_t data)2373 int dcs_audio_device::preprocess_stage_2(uint16_t data)
2374 {
2375 	hle_transfer_state &transfer = m_transfer;
2376 
2377 	switch (transfer.state)
2378 	{
2379 		case 0:
2380 			/* look for command 0x55d0 or 0x55d1 to transfer chunks of data */
2381 			if (data == 0x55d0 || data == 0x55d1)
2382 			{
2383 				if (LOG_DCS_TRANSFERS)
2384 					logerror("%s:DCS Transfer command %04X\n", machine().describe_context(), data);
2385 				transfer.state++;
2386 				if (transfer.hle_enabled)
2387 					return 1;
2388 			}
2389 
2390 			/* anything else is ignored */
2391 			else
2392 			{
2393 				if (LOG_DCS_TRANSFERS)
2394 					logerror("%s:Command: %04X\n", machine().describe_context(), data);
2395 			}
2396 			break;
2397 
2398 		case 1:
2399 			/* first word is the upper bits of the start address */
2400 			transfer.start = data << 16;
2401 			transfer.state++;
2402 			if (transfer.hle_enabled)
2403 				return 1;
2404 			break;
2405 
2406 		case 2:
2407 			/* second word is the lower bits of the start address */
2408 			transfer.start |= data;
2409 			transfer.state++;
2410 			if (LOG_DCS_TRANSFERS)
2411 				logerror("Start address = %08X\n", transfer.start);
2412 			if (transfer.hle_enabled)
2413 				return 1;
2414 			break;
2415 
2416 		case 3:
2417 			/* third word is the upper bits of the stop address */
2418 			transfer.stop = data << 16;
2419 			transfer.state++;
2420 			if (transfer.hle_enabled)
2421 				return 1;
2422 			break;
2423 
2424 		case 4:
2425 			/* fourth word is the lower bits of the stop address */
2426 			transfer.stop |= data;
2427 			transfer.state++;
2428 			if (LOG_DCS_TRANSFERS)
2429 				logerror("Stop address = %08X\n", transfer.stop);
2430 
2431 			/* at this point, we can compute how many words to expect for the transfer */
2432 			transfer.writes_left = transfer.stop - transfer.start + 1;
2433 
2434 			/* reset the checksum */
2435 			transfer.sum = 0;
2436 			if (transfer.hle_enabled)
2437 			{
2438 				transfer.watchdog->adjust(attotime::from_msec(1), transfer.writes_left);
2439 				return 1;
2440 			}
2441 			break;
2442 
2443 		case 5:
2444 			/* accumulate the sum over all data */
2445 			transfer.sum += data;
2446 
2447 			/* if we're out, stop the transfer */
2448 			if (--transfer.writes_left == 0)
2449 			{
2450 				if (LOG_DCS_TRANSFERS)
2451 					logerror("Transfer done, sum = %04X\n", transfer.sum);
2452 				transfer.state = 0;
2453 			}
2454 
2455 			/* handle the HLE case */
2456 			if (transfer.hle_enabled)
2457 			{
2458 				/* write the new data to memory */
2459 				m_sounddata[transfer.start++] = data;
2460 
2461 				/* if we're done, start a timer to send the response words */
2462 				if (transfer.state == 0)
2463 				{
2464 					machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(dcs_audio_device::s2_ack_callback),this), transfer.sum);
2465 					transfer.watchdog->reset();
2466 				}
2467 				return 1;
2468 			}
2469 			break;
2470 	}
2471 	return 0;
2472 }
2473 
2474 
preprocess_write(uint16_t data)2475 int dcs_audio_device::preprocess_write(uint16_t data)
2476 {
2477 	hle_transfer_state &transfer = m_transfer;
2478 	int result;
2479 
2480 	/* if we're not DCS2, skip */
2481 	if (m_sport0_timer == nullptr)
2482 		return 0;
2483 
2484 	/* state 0 - initialization phase */
2485 	if (transfer.dcs_state == 0)
2486 		result = preprocess_stage_1(data);
2487 	else
2488 		result = preprocess_stage_2(data);
2489 
2490 	/* if we did the write, toggle the full/not full state so interrupts are generated */
2491 	if (result && !m_input_empty_cb.isnull())
2492 	{
2493 		if (m_last_input_empty)
2494 			m_input_empty_cb(m_last_input_empty = 0);
2495 		if (!m_last_input_empty)
2496 			m_input_empty_cb(m_last_input_empty = 1);
2497 	}
2498 	return result;
2499 }
2500 
2501 /* Basic DCS system with ADSP-2105 and 2k of SRAM (T-unit, V-unit, Killer Instinct) */
2502 
add_mconfig_dcs(machine_config & config)2503 void dcs_audio_device::add_mconfig_dcs(machine_config &config)
2504 {
2505 	adsp2105_device &dcs(ADSP2105(config, "dcs", XTAL(10'000'000)));
2506 	dcs.sport_tx().set(FUNC(dcs_audio_device::sound_tx_callback)); /* callback for serial transmit */
2507 	dcs.timer_fired().set(FUNC(dcs_audio_device::timer_enable_callback)); /* callback for timer fired */
2508 	dcs.set_addrmap(AS_PROGRAM, &dcs_audio_device::dcs_2k_program_map);
2509 	dcs.set_addrmap(AS_DATA, &dcs_audio_device::dcs_2k_data_map);
2510 
2511 	TIMER(config, "dcs_reg_timer").configure_generic(FUNC(dcs_audio_device::dcs_irq));
2512 	TIMER(config, "dcs_int_timer").configure_generic(FUNC(dcs_audio_device::internal_timer_callback));
2513 
2514 	SPEAKER(config, "mono").front_center();
2515 
2516 	DMADAC(config, "dac").add_route(ALL_OUTPUTS, "mono", 1.0); // AD-1851 16bit mono
2517 }
2518 
2519 DEFINE_DEVICE_TYPE(DCS_AUDIO_2K, dcs_audio_2k_device, "dcs_audio_2k", "DCS Audio 2K")
2520 
2521 //-------------------------------------------------
2522 //  dcs_audio_2k_device - constructor
2523 //-------------------------------------------------
2524 
dcs_audio_2k_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2525 dcs_audio_2k_device::dcs_audio_2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2526 	dcs_audio_device(mconfig, DCS_AUDIO_2K, tag, owner, clock, REV_DCS1)
2527 {
2528 }
2529 
device_add_mconfig(machine_config & config)2530 void dcs_audio_2k_device::device_add_mconfig(machine_config &config)
2531 {
2532 	dcs_audio_device::add_mconfig_dcs(config);
2533 }
2534 
2535 DEFINE_DEVICE_TYPE(DCS_AUDIO_2K_UART, dcs_audio_2k_uart_device, "dcs_audio_2k_uart", "DCS Audio 2K UART")
2536 
2537 //-------------------------------------------------
2538 //  dcs_audio_2k_uart_device - constructor
2539 //-------------------------------------------------
2540 
dcs_audio_2k_uart_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2541 dcs_audio_2k_uart_device::dcs_audio_2k_uart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2542 	dcs_audio_device(mconfig, DCS_AUDIO_2K_UART, tag, owner, clock, REV_DCS1)
2543 {
2544 }
2545 
2546 /* Basic DCS system with ADSP-2105 and 2k of SRAM, using a UART for communications (X-unit) */
device_add_mconfig(machine_config & config)2547 void dcs_audio_2k_uart_device::device_add_mconfig(machine_config &config)
2548 {
2549 	dcs_audio_device::add_mconfig_dcs(config);
2550 	subdevice<adsp21xx_device>("dcs")->set_addrmap(AS_DATA, &dcs_audio_2k_uart_device::dcs_2k_uart_data_map);
2551 }
2552 
2553 DEFINE_DEVICE_TYPE(DCS_AUDIO_8K, dcs_audio_8k_device, "dcs_audio_8k", "DCS Audio 8K")
2554 
2555 //-------------------------------------------------
2556 //  dcs_audio_8k_device - constructor
2557 //-------------------------------------------------
2558 
dcs_audio_8k_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2559 dcs_audio_8k_device::dcs_audio_8k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2560 	dcs_audio_device(mconfig, DCS_AUDIO_8K, tag, owner, clock, REV_DCS1)
2561 {
2562 }
2563 
2564 /* Basic DCS system with ADSP-2105 and 8k of SRAM (Wolf-unit) */
device_add_mconfig(machine_config & config)2565 void dcs_audio_8k_device::device_add_mconfig(machine_config &config)
2566 {
2567 	dcs_audio_device::add_mconfig_dcs(config);
2568 	subdevice<adsp21xx_device>("dcs")->set_addrmap(AS_PROGRAM, &dcs_audio_8k_device::dcs_8k_program_map);
2569 	subdevice<adsp21xx_device>("dcs")->set_addrmap(AS_DATA, &dcs_audio_8k_device::dcs_8k_data_map);
2570 }
2571 
2572 DEFINE_DEVICE_TYPE(DCS_AUDIO_WPC, dcs_audio_wpc_device, "dcs_audio_wpc", "DCS Audio WPC")
2573 
2574 //-------------------------------------------------
2575 //  dcs_audio_wpc_device - constructor
2576 //-------------------------------------------------
2577 
dcs_audio_wpc_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2578 dcs_audio_wpc_device::dcs_audio_wpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2579 	dcs_audio_device(mconfig, DCS_AUDIO_WPC, tag, owner, clock, REV_DCS1P5)
2580 {
2581 }
2582 
device_add_mconfig(machine_config & config)2583 void dcs_audio_wpc_device::device_add_mconfig(machine_config &config)
2584 {
2585 	dcs_audio_device::add_mconfig_dcs(config);
2586 	subdevice<adsp21xx_device>("dcs")->set_addrmap(AS_PROGRAM, &dcs_audio_wpc_device::dcs_wpc_program_map);
2587 	subdevice<adsp21xx_device>("dcs")->set_addrmap(AS_DATA, &dcs_audio_wpc_device::dcs_wpc_data_map);
2588 }
2589 
2590 
2591 //-------------------------------------------------
2592 //  dcs2_audio_device - constructor
2593 //-------------------------------------------------
2594 
dcs2_audio_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)2595 dcs2_audio_device::dcs2_audio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
2596 	dcs_audio_device(mconfig, type, tag, owner, clock, REV_DCS1)
2597 {
2598 }
2599 
add_mconfig_dcs2(machine_config & config)2600 void dcs2_audio_device::add_mconfig_dcs2(machine_config &config)
2601 {
2602 	adsp2115_device &dcs2(ADSP2115(config, "dcs2", XTAL(16'000'000)));
2603 	dcs2.sport_tx().set(FUNC(dcs_audio_device::sound_tx_callback)); /* callback for serial transmit */
2604 	dcs2.timer_fired().set(FUNC(dcs_audio_device::timer_enable_callback)); /* callback for timer fired */
2605 	dcs2.set_addrmap(AS_PROGRAM, &dcs2_audio_device::dcs2_2115_program_map);
2606 	dcs2.set_addrmap(AS_DATA, &dcs2_audio_device::dcs2_2115_data_map);
2607 
2608 	TIMER(config, "dcs_reg_timer").configure_generic(FUNC(dcs_audio_device::dcs_irq));
2609 	TIMER(config, "dcs_sport0_timer").configure_generic(FUNC(dcs_audio_device::sport0_irq));
2610 	TIMER(config, "dcs_int_timer").configure_generic(FUNC(dcs_audio_device::internal_timer_callback));
2611 	TIMER(config, "dcs_hle_timer").configure_generic(FUNC(dcs_audio_device::transfer_watchdog_callback));
2612 
2613 	SPEAKER(config, "lspeaker").front_left();
2614 	SPEAKER(config, "rspeaker").front_right();
2615 
2616 	DMADAC(config, "dac1").add_route(ALL_OUTPUTS, "rspeaker", 1.0);
2617 	DMADAC(config, "dac2").add_route(ALL_OUTPUTS, "lspeaker", 1.0);
2618 }
2619 
2620 DEFINE_DEVICE_TYPE(DCS2_AUDIO_2115, dcs2_audio_2115_device, "dcs2_audio_2115", "DCS2 Audio 2115")
2621 
2622 //-------------------------------------------------
2623 //  dcs2_audio_2115_device - constructor
2624 //-------------------------------------------------
2625 
dcs2_audio_2115_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2626 dcs2_audio_2115_device::dcs2_audio_2115_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2627 	dcs2_audio_device(mconfig, DCS2_AUDIO_2115, tag, owner, clock)
2628 {
2629 }
2630 
device_add_mconfig(machine_config & config)2631 void dcs2_audio_2115_device::device_add_mconfig(machine_config &config)
2632 {
2633 	dcs2_audio_device::add_mconfig_dcs2(config);
2634 }
2635 
2636 DEFINE_DEVICE_TYPE(DCS2_AUDIO_2104, dcs2_audio_2104_device, "dcs2_audio_2104", "DCS2 Audio 2104")
2637 
2638 //-------------------------------------------------
2639 //  dcs2_audio_2104_device - constructor
2640 //-------------------------------------------------
2641 
2642 
dcs2_audio_2104_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2643 dcs2_audio_2104_device::dcs2_audio_2104_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2644 	dcs2_audio_device(mconfig, DCS2_AUDIO_2104, tag, owner, clock)
2645 {
2646 }
2647 
device_add_mconfig(machine_config & config)2648 void dcs2_audio_2104_device::device_add_mconfig(machine_config &config)
2649 {
2650 	dcs2_audio_device::add_mconfig_dcs2(config);
2651 
2652 	adsp2104_device &dcs2(ADSP2104(config.replace(), "dcs2", XTAL(16'000'000)));
2653 	dcs2.sport_tx().set(FUNC(dcs_audio_device::sound_tx_callback)); /* callback for serial transmit */
2654 	dcs2.timer_fired().set(FUNC(dcs_audio_device::timer_enable_callback)); /* callback for timer fired */
2655 	dcs2.set_addrmap(AS_PROGRAM, &dcs2_audio_2104_device::dcs2_2104_program_map);
2656 	dcs2.set_addrmap(AS_DATA, &dcs2_audio_2104_device::dcs2_2104_data_map);
2657 }
2658 
2659 DEFINE_DEVICE_TYPE(DCS2_AUDIO_DSIO, dcs2_audio_dsio_device, "dcs2_audio_dsio", "DCS2 Audio DSIO")
2660 
2661 //-------------------------------------------------
2662 //  dcs2_audio_dsio_device - constructor
2663 //-------------------------------------------------
2664 
dcs2_audio_dsio_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2665 dcs2_audio_dsio_device::dcs2_audio_dsio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2666 	dcs2_audio_device(mconfig, DCS2_AUDIO_DSIO, tag, owner, clock)
2667 {
2668 }
2669 
device_add_mconfig(machine_config & config)2670 void dcs2_audio_dsio_device::device_add_mconfig(machine_config &config)
2671 {
2672 	adsp2181_device &dsio(ADSP2181(config, "dsio", XTAL(32'000'000)));
2673 	dsio.sport_tx().set(FUNC(dcs_audio_device::sound_tx_callback)); /* callback for serial transmit */
2674 	dsio.timer_fired().set(FUNC(dcs_audio_device::timer_enable_callback)); /* callback for timer fired */
2675 	dsio.dmovlay().set(FUNC(dcs_audio_device::dmovlay_callback)); /* callback for adsp 2181 dmovlay instruction */
2676 	dsio.set_addrmap(AS_PROGRAM, &dcs2_audio_dsio_device::dsio_program_map);
2677 	dsio.set_addrmap(AS_DATA, &dcs2_audio_dsio_device::dsio_data_map);
2678 	dsio.set_addrmap(AS_IO, &dcs2_audio_dsio_device::dsio_io_map);
2679 
2680 	ADDRESS_MAP_BANK(config, "data_map_bank").set_map(&dcs2_audio_dsio_device::dsio_rambank_map).set_options(ENDIANNESS_LITTLE, 16, 14, 0x2000);
2681 
2682 	TIMER(config, "dcs_reg_timer").configure_generic(FUNC(dcs_audio_device::dcs_irq));
2683 	TIMER(config, "dcs_int_timer").configure_generic(FUNC(dcs_audio_device::internal_timer_callback));
2684 	TIMER(config, "dcs_sport0_timer").configure_generic(FUNC(dcs_audio_device::sport0_irq)); // roadburn needs this to pass hardware test
2685 
2686 	SPEAKER(config, "lspeaker").front_left();
2687 	SPEAKER(config, "rspeaker").front_right();
2688 
2689 	DMADAC(config, "dac1").add_route(ALL_OUTPUTS, "rspeaker", 1.0);
2690 	DMADAC(config, "dac2").add_route(ALL_OUTPUTS, "lspeaker", 1.0);
2691 }
2692 
2693 
2694 //-------------------------------------------------
2695 //  dcs2_audio_denver_device - constructor
2696 //-------------------------------------------------
dcs2_audio_denver_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)2697 dcs2_audio_denver_device::dcs2_audio_denver_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
2698 	dcs2_audio_device(mconfig, type, tag, owner, clock)
2699 {
2700 }
2701 
device_add_mconfig(machine_config & config)2702 void dcs2_audio_denver_device::device_add_mconfig(machine_config &config)
2703 {
2704 	adsp2181_device &denver(ADSP2181(config, "denver", XTAL(33'333'000)));
2705 	denver.sport_tx().set(FUNC(dcs_audio_device::sound_tx_callback)); /* callback for serial transmit */
2706 	denver.timer_fired().set(FUNC(dcs_audio_device::timer_enable_callback)); /* callback for timer fired */
2707 	denver.dmovlay().set(FUNC(dcs_audio_device::dmovlay_callback)); /* callback for adsp 2181 dmovlay instruction */
2708 	denver.set_addrmap(AS_PROGRAM, &dcs2_audio_denver_device::denver_program_map);
2709 	denver.set_addrmap(AS_DATA, &dcs2_audio_denver_device::denver_data_map);
2710 	denver.set_addrmap(AS_IO, &dcs2_audio_denver_device::denver_io_map);
2711 
2712 	ADDRESS_MAP_BANK(config, "data_map_bank").set_map(&dcs2_audio_denver_device::denver_rambank_map).set_options(ENDIANNESS_LITTLE, 16, 15, 0x2000*2);
2713 
2714 	TIMER(config, "dcs_reg_timer").configure_generic(FUNC(dcs_audio_device::dcs_irq));
2715 	TIMER(config, "dcs_int_timer").configure_generic(FUNC(dcs_audio_device::internal_timer_callback));
2716 	TIMER(config, "dcs_sport0_timer").configure_generic(FUNC(dcs_audio_device::sport0_irq)); // Atlantis driver waits for sport0 rx interrupts
2717 }
2718 
dcs2_audio_denver_5ch_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2719 dcs2_audio_denver_5ch_device::dcs2_audio_denver_5ch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2720 	dcs2_audio_denver_device(mconfig, DCS2_AUDIO_DENVER_5CH, tag, owner, clock)
2721 {
2722 }
2723 
device_add_mconfig(machine_config & config)2724 void dcs2_audio_denver_5ch_device::device_add_mconfig(machine_config &config)
2725 {
2726 	dcs2_audio_denver_device::device_add_mconfig(config);
2727 
2728 	SPEAKER(config, "flspeaker").front_left();
2729 	SPEAKER(config, "frspeaker").front_right();
2730 	SPEAKER(config, "rlspeaker").headrest_left();
2731 	SPEAKER(config, "rrspeaker").headrest_right();
2732 	SPEAKER(config, "subwoofer").backrest();
2733 
2734 	DMADAC(config, "dac1").add_route(ALL_OUTPUTS, "flspeaker", 1.0);
2735 	DMADAC(config, "dac2").add_route(ALL_OUTPUTS, "frspeaker", 1.0);
2736 	DMADAC(config, "dac3").add_route(ALL_OUTPUTS, "rlspeaker", 1.0);
2737 	DMADAC(config, "dac4").add_route(ALL_OUTPUTS, "rrspeaker", 1.0);
2738 	DMADAC(config, "dac5").add_route(ALL_OUTPUTS, "subwoofer", 1.0);
2739 	DMADAC(config, "dac6");
2740 	// Does not produce sound
2741 }
2742 
2743 DEFINE_DEVICE_TYPE(DCS2_AUDIO_DENVER_5CH, dcs2_audio_denver_5ch_device, "dcs2_audio_denver_5ch", "DCS2 Audio Denver 5 Channel")
2744 
dcs2_audio_denver_2ch_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2745 dcs2_audio_denver_2ch_device::dcs2_audio_denver_2ch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2746 	dcs2_audio_denver_device(mconfig, DCS2_AUDIO_DENVER_2CH, tag, owner, clock)
2747 {
2748 }
2749 
device_add_mconfig(machine_config & config)2750 void dcs2_audio_denver_2ch_device::device_add_mconfig(machine_config &config)
2751 {
2752 	dcs2_audio_denver_device::device_add_mconfig(config);
2753 
2754 	SPEAKER(config, "lspeaker").front_left();
2755 	SPEAKER(config, "rspeaker").front_right();
2756 
2757 	DMADAC(config, "dac1").add_route(ALL_OUTPUTS, "rspeaker", 1.0);
2758 	DMADAC(config, "dac2").add_route(ALL_OUTPUTS, "lspeaker", 1.0);
2759 }
2760 
2761 DEFINE_DEVICE_TYPE(DCS2_AUDIO_DENVER_2CH, dcs2_audio_denver_2ch_device, "dcs2_audio_denver_2ch", "DCS2 Audio Denver 2 Channel")
2762