1
/***************************************************************************
5
This chip is used as an interface to up to 4 other custom chips.
6
It signals IRQs to the custom MCUs when writes happen, and generates
7
NMIs to the controlling CPU to drive reads based on a clock.
9
SD0-SD7 are data I/O lines connecting to the controlling CPU
10
SEL selects either control (1) or data (0), usually connected to
11
an address line of the controlling CPU
12
/NMI is an NMI signal line for the controlling CPU
14
ID0-ID7 are data I/O lines connecting to the other custom chips
15
/IO1-/IO4 are IRQ signal lines for each custom chip
34
[1] on polepos, galaga, xevious, and bosco: connected to K3 of the 51xx
35
on bosco and xevious, connected to R8 of the 50xx
40
Galaga 51XX ---- ---- 54XX
41
Bosconian (CPU board) 51XX ---- 50XX 54XX
42
Bosconian (Video board) 50XX 52XX ---- ----
43
Xevious 51XX ---- 50XX 54XX
44
Dig Dug 51XX 53XX ---- ----
45
Pole Position / PP II 51XX 53XX 52XX 54XX
49
control = 10(000), data = FF at startup
50
control = 71(011), read 3, control = 10
51
control = A1(101), write 4, control = 10
52
control = A8(101), write 12, control = 10
55
control = 10 at startup
56
control = A1(101), write 6, control = 10
57
control = 71(011), read 3, control = 10
58
control = 64(011), write 1, control = 10
59
control = 74(011), read 4, control = 10
60
control = 68(011), write 7, control = 10
63
control = 10(000), data = 10 at startup
64
control = A1(101), write 3, control = 10
65
control = 71(011), read 3, control = 10
66
control = D2(110), read 2, control = 10
69
control = 10(000), data = FF at startup
70
control = C8(110), write 17, control = 10
71
control = 61(011), write 1, control = 10
72
control = 71(011), read 3, control = 10
73
control = 94(100), read 4, control = 10
74
control = 64(011), write 1, control = 10
75
control = 84(100), write 5, control = 10
78
control = 34(001), write 1, control = 10
80
***************************************************************************/
83
#include "machine/namco06.h"
84
#include "machine/namco50.h"
85
#include "machine/namco51.h"
86
#include "machine/namco53.h"
87
#include "audio/namco52.h"
88
#include "audio/namco54.h"
92
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
96
typedef struct _namco_06xx_state namco_06xx_state;
97
struct _namco_06xx_state
100
emu_timer *m_nmi_timer;
101
cpu_device *m_nmicpu;
102
device_t *m_device[4];
103
read8_device_func m_read[4];
104
void (*m_readreq[4])(device_t *device);
105
write8_device_func m_write[4];
108
INLINE namco_06xx_state *get_safe_token(device_t *device)
110
assert(device != NULL);
111
assert(device->type() == NAMCO_06XX);
113
return (namco_06xx_state *)downcast<legacy_device_base *>(device)->token();
118
static TIMER_CALLBACK( nmi_generate )
120
namco_06xx_state *state = get_safe_token((device_t *)ptr);
122
if (!state->m_nmicpu->suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
124
LOG(("NMI cpu '%s'\n",state->m_nmicpu->tag()));
126
device_set_input_line(state->m_nmicpu, INPUT_LINE_NMI, PULSE_LINE);
129
LOG(("NMI not generated because cpu '%s' is suspended\n",state->m_nmicpu->tag()));
133
READ8_DEVICE_HANDLER( namco_06xx_data_r )
135
namco_06xx_state *state = get_safe_token(device);
139
LOG(("%s: 06XX '%s' read offset %d\n",device->machine().describe_context(),device->tag(),offset));
141
if (!(state->m_control & 0x10))
143
logerror("%s: 06XX '%s' read in write mode %02x\n",device->machine().describe_context(),device->tag(),state->m_control);
147
for (devnum = 0; devnum < 4; devnum++)
148
if ((state->m_control & (1 << devnum)) && state->m_read[devnum] != NULL)
149
result &= (*state->m_read[devnum])(state->m_device[devnum], 0);
155
WRITE8_DEVICE_HANDLER( namco_06xx_data_w )
157
namco_06xx_state *state = get_safe_token(device);
160
LOG(("%s: 06XX '%s' write offset %d = %02x\n",device->machine().describe_context(),device->tag(),offset,data));
162
if (state->m_control & 0x10)
164
logerror("%s: 06XX '%s' write in read mode %02x\n",device->machine().describe_context(),device->tag(),state->m_control);
168
for (devnum = 0; devnum < 4; devnum++)
169
if ((state->m_control & (1 << devnum)) && state->m_write[devnum] != NULL)
170
(*state->m_write[devnum])(state->m_device[devnum], 0, data);
174
READ8_DEVICE_HANDLER( namco_06xx_ctrl_r )
176
namco_06xx_state *state = get_safe_token(device);
177
LOG(("%s: 06XX '%s' ctrl_r\n",device->machine().describe_context(),device->tag()));
178
return state->m_control;
181
WRITE8_DEVICE_HANDLER( namco_06xx_ctrl_w )
183
namco_06xx_state *state = get_safe_token(device);
186
LOG(("%s: 06XX '%s' control %02x\n",device->machine().describe_context(),device->tag(),data));
188
state->m_control = data;
190
if ((state->m_control & 0x0f) == 0)
192
LOG(("disabling nmi generate timer\n"));
193
state->m_nmi_timer->adjust(attotime::never);
197
LOG(("setting nmi generate timer to 200us\n"));
199
// this timing is critical. Due to a bug, Bosconian will stop responding to
200
// inputs if a transfer terminates at the wrong time.
201
// On the other hand, the time cannot be too short otherwise the 54XX will
202
// not have enough time to process the incoming controls.
203
state->m_nmi_timer->adjust(attotime::from_usec(200), 0, attotime::from_usec(200));
205
if (state->m_control & 0x10)
206
for (devnum = 0; devnum < 4; devnum++)
207
if ((state->m_control & (1 << devnum)) && state->m_readreq[devnum] != NULL)
208
(*state->m_readreq[devnum])(state->m_device[devnum]);
213
/***************************************************************************
215
***************************************************************************/
217
/*-------------------------------------------------
218
device start callback
219
-------------------------------------------------*/
221
static DEVICE_START( namco_06xx )
223
const namco_06xx_config *config = (const namco_06xx_config *)downcast<const legacy_device_base *>(device)->inline_config();
224
namco_06xx_state *state = get_safe_token(device);
227
assert(config != NULL);
229
/* resolve our CPU */
230
state->m_nmicpu = device->machine().device<cpu_device>(config->nmicpu);
231
assert(state->m_nmicpu != NULL);
233
/* resolve our devices */
234
state->m_device[0] = (config->chip0 != NULL) ? device->machine().device(config->chip0) : NULL;
235
assert(state->m_device[0] != NULL || config->chip0 == NULL);
236
state->m_device[1] = (config->chip1 != NULL) ? device->machine().device(config->chip1) : NULL;
237
assert(state->m_device[1] != NULL || config->chip1 == NULL);
238
state->m_device[2] = (config->chip2 != NULL) ? device->machine().device(config->chip2) : NULL;
239
assert(state->m_device[2] != NULL || config->chip2 == NULL);
240
state->m_device[3] = (config->chip3 != NULL) ? device->machine().device(config->chip3) : NULL;
241
assert(state->m_device[3] != NULL || config->chip3 == NULL);
243
/* loop over devices and set their read/write handlers */
244
for (devnum = 0; devnum < 4; devnum++)
245
if (state->m_device[devnum] != NULL)
247
device_type type = state->m_device[devnum]->type();
249
if (type == NAMCO_50XX)
251
state->m_read[devnum] = namco_50xx_read;
252
state->m_readreq[devnum] = namco_50xx_read_request;
253
state->m_write[devnum] = namco_50xx_write;
255
else if (type == NAMCO_51XX)
257
state->m_read[devnum] = namco_51xx_read;
258
state->m_write[devnum] = namco_51xx_write;
260
else if (type == NAMCO_52XX)
261
state->m_write[devnum] = namco_52xx_write;
262
else if (type == NAMCO_53XX)
264
state->m_read[devnum] = namco_53xx_read;
265
state->m_readreq[devnum] = namco_53xx_read_request;
267
else if (type == NAMCO_54XX)
268
state->m_write[devnum] = namco_54xx_write;
270
fatalerror("Unknown device type %s connected to Namco 06xx", state->m_device[devnum]->name());
273
/* allocate a timer */
274
state->m_nmi_timer = device->machine().scheduler().timer_alloc(FUNC(nmi_generate), (void *)device);
276
device->save_item(NAME(state->m_control));
280
/*-------------------------------------------------
281
device reset callback
282
-------------------------------------------------*/
284
static DEVICE_RESET( namco_06xx )
286
namco_06xx_state *state = get_safe_token(device);
287
state->m_control = 0;
291
/*-------------------------------------------------
293
-------------------------------------------------*/
295
static const char DEVTEMPLATE_SOURCE[] = __FILE__;
297
#define DEVTEMPLATE_ID(p,s) p##namco_06xx##s
298
#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET | DT_HAS_INLINE_CONFIG
299
#define DEVTEMPLATE_NAME "Namco 06xx"
300
#define DEVTEMPLATE_FAMILY "Namco I/O"
301
#define DEVTEMPLATE_SHORTNAME "namco06xx"
302
#include "devtempl.h"
305
DEFINE_LEGACY_DEVICE(NAMCO_06XX, namco_06xx);