~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/mame/machine/qix.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
    Taito Qix hardware
4
 
 
5
 
    driver by John Butler, Ed Mueller, Aaron Giles
6
 
 
7
 
***************************************************************************/
8
 
 
9
 
#include "emu.h"
10
 
#include "cpu/m6800/m6800.h"
11
 
#include "cpu/m6805/m6805.h"
12
 
#include "cpu/m6809/m6809.h"
13
 
#include "sound/sn76496.h"
14
 
#include "includes/qix.h"
15
 
 
16
 
 
17
 
 
18
 
/*************************************
19
 
 *
20
 
 *  Static function prototypes
21
 
 *
22
 
 *************************************/
23
 
 
24
 
static READ8_DEVICE_HANDLER( qixmcu_coin_r );
25
 
static WRITE8_DEVICE_HANDLER( qixmcu_coinctrl_w );
26
 
static WRITE8_DEVICE_HANDLER( qixmcu_coin_w );
27
 
 
28
 
static WRITE8_DEVICE_HANDLER( qix_coinctl_w );
29
 
 
30
 
static WRITE8_DEVICE_HANDLER( slither_76489_0_w );
31
 
static WRITE8_DEVICE_HANDLER( slither_76489_1_w );
32
 
 
33
 
static READ8_DEVICE_HANDLER( slither_trak_lr_r );
34
 
static READ8_DEVICE_HANDLER( slither_trak_ud_r );
35
 
 
36
 
 
37
 
 
38
 
/***************************************************************************
39
 
 
40
 
    Qix has 6 PIAs on board:
41
 
 
42
 
    From the ROM I/O schematic:
43
 
 
44
 
    PIA 0 = U11: (mapped to $9400 on the data CPU)
45
 
        port A = external input (input_port_0)
46
 
        port B = external input (input_port_1) (coin)
47
 
 
48
 
    PIA 1 = U20: (mapped to $9800/$9900 on the data CPU)
49
 
        port A = external input (input_port_2)
50
 
        port B = external input (input_port_3)
51
 
 
52
 
    PIA 2 = U30: (mapped to $9c00 on the data CPU)
53
 
        port A = external input (input_port_4)
54
 
        port B = external output (coin control)
55
 
 
56
 
 
57
 
    From the data/sound processor schematic:
58
 
 
59
 
    PIA 3 = U20: (mapped to $9000 on the data CPU)
60
 
        port A = data CPU to sound CPU communication
61
 
        port B = stereo volume control, 2 4-bit values
62
 
        CA1 = interrupt signal from sound CPU
63
 
        CA2 = interrupt signal to sound CPU
64
 
        CB1 = VS input signal (vertical sync)
65
 
        CB2 = INV output signal (cocktail flip)
66
 
        IRQA = /DINT1 signal
67
 
        IRQB = /DINT1 signal
68
 
 
69
 
    PIA 4 = U8: (mapped to $4000 on the sound CPU)
70
 
        port A = sound CPU to data CPU communication
71
 
        port B = DAC value (port B)
72
 
        CA1 = interrupt signal from data CPU
73
 
        CA2 = interrupt signal to data CPU
74
 
        IRQA = /SINT1 signal
75
 
        IRQB = /SINT1 signal
76
 
 
77
 
    PIA 5 = U7: (never actually used, mapped to $2000 on the sound CPU)
78
 
        port A = unused
79
 
        port B = sound CPU to TMS5220 communication
80
 
        CA1 = interrupt signal from TMS5220
81
 
        CA2 = write signal to TMS5220
82
 
        CB1 = ready signal from TMS5220
83
 
        CB2 = read signal to TMS5220
84
 
        IRQA = /SINT2 signal
85
 
        IRQB = /SINT2 signal
86
 
 
87
 
***************************************************************************/
88
 
 
89
 
const pia6821_interface qix_pia_0_intf =
90
 
{
91
 
        DEVCB_INPUT_PORT("P1"),         /* port A in */
92
 
        DEVCB_INPUT_PORT("COIN"),       /* port B in */
93
 
        DEVCB_NULL,             /* line CA1 in */
94
 
        DEVCB_NULL,             /* line CB1 in */
95
 
        DEVCB_NULL,             /* line CA2 in */
96
 
        DEVCB_NULL,             /* line CB2 in */
97
 
        DEVCB_NULL,             /* port A out */
98
 
        DEVCB_NULL,             /* port B out */
99
 
        DEVCB_NULL,             /* line CA2 out */
100
 
        DEVCB_NULL,             /* port CB2 out */
101
 
        DEVCB_NULL,             /* IRQA */
102
 
        DEVCB_NULL              /* IRQB */
103
 
};
104
 
 
105
 
const pia6821_interface qix_pia_1_intf =
106
 
{
107
 
        DEVCB_INPUT_PORT("SPARE"),      /* port A in */
108
 
        DEVCB_INPUT_PORT("IN0"),        /* port B in */
109
 
        DEVCB_NULL,             /* line CA1 in */
110
 
        DEVCB_NULL,             /* line CB1 in */
111
 
        DEVCB_NULL,             /* line CA2 in */
112
 
        DEVCB_NULL,             /* line CB2 in */
113
 
        DEVCB_NULL,             /* port A out */
114
 
        DEVCB_NULL,             /* port B out */
115
 
        DEVCB_NULL,             /* line CA2 out */
116
 
        DEVCB_NULL,             /* port CB2 out */
117
 
        DEVCB_NULL,             /* IRQA */
118
 
        DEVCB_NULL              /* IRQB */
119
 
};
120
 
 
121
 
const pia6821_interface qix_pia_2_intf =
122
 
{
123
 
        DEVCB_INPUT_PORT("P2"),                         /* port A in */
124
 
        DEVCB_NULL,             /* port B in */
125
 
        DEVCB_NULL,             /* line CA1 in */
126
 
        DEVCB_NULL,             /* line CB1 in */
127
 
        DEVCB_NULL,             /* line CA2 in */
128
 
        DEVCB_NULL,             /* line CB2 in */
129
 
        DEVCB_NULL,             /* port A out */
130
 
        DEVCB_HANDLER(qix_coinctl_w),           /* port B out */
131
 
        DEVCB_NULL,             /* line CA2 out */
132
 
        DEVCB_NULL,             /* port CB2 out */
133
 
        DEVCB_NULL,             /* IRQA */
134
 
        DEVCB_NULL              /* IRQB */
135
 
};
136
 
 
137
 
 
138
 
 
139
 
/***************************************************************************
140
 
 
141
 
    Games with an MCU need to handle coins differently, and provide
142
 
    communication with the MCU
143
 
 
144
 
***************************************************************************/
145
 
 
146
 
const pia6821_interface qixmcu_pia_0_intf =
147
 
{
148
 
        DEVCB_INPUT_PORT("P1"),                 /* port A in */
149
 
        DEVCB_HANDLER(qixmcu_coin_r),   /* port B in */
150
 
        DEVCB_NULL,             /* line CA1 in */
151
 
        DEVCB_NULL,             /* line CB1 in */
152
 
        DEVCB_NULL,             /* line CA2 in */
153
 
        DEVCB_NULL,             /* line CB2 in */
154
 
        DEVCB_NULL,             /* port A out */
155
 
        DEVCB_HANDLER(qixmcu_coin_w),   /* port B out */
156
 
        DEVCB_NULL,             /* line CA2 out */
157
 
        DEVCB_NULL,             /* port CB2 out */
158
 
        DEVCB_NULL,             /* IRQA */
159
 
        DEVCB_NULL              /* IRQB */
160
 
};
161
 
 
162
 
const pia6821_interface qixmcu_pia_2_intf =
163
 
{
164
 
        DEVCB_INPUT_PORT("P2"),                         /* port A in */
165
 
        DEVCB_NULL,             /* port B in */
166
 
        DEVCB_NULL,             /* line CA1 in */
167
 
        DEVCB_NULL,             /* line CB1 in */
168
 
        DEVCB_NULL,             /* line CA2 in */
169
 
        DEVCB_NULL,             /* line CB2 in */
170
 
        DEVCB_NULL,             /* port A out */
171
 
        DEVCB_HANDLER(qixmcu_coinctrl_w),       /* port B out */
172
 
        DEVCB_NULL,             /* line CA2 out */
173
 
        DEVCB_NULL,             /* port CB2 out */
174
 
        DEVCB_NULL,             /* IRQA */
175
 
        DEVCB_NULL              /* IRQB */
176
 
};
177
 
 
178
 
 
179
 
 
180
 
/***************************************************************************
181
 
 
182
 
    Slither uses 2 SN76489's for sound instead of the 6802+DAC; these
183
 
    are accessed via the PIAs.
184
 
 
185
 
***************************************************************************/
186
 
 
187
 
const pia6821_interface slither_pia_1_intf =
188
 
{
189
 
        DEVCB_HANDLER(slither_trak_lr_r),       /* port A in */
190
 
        DEVCB_NULL,             /* port B in */
191
 
        DEVCB_NULL,             /* line CA1 in */
192
 
        DEVCB_NULL,             /* line CB1 in */
193
 
        DEVCB_NULL,             /* line CA2 in */
194
 
        DEVCB_NULL,             /* line CB2 in */
195
 
        DEVCB_NULL,             /* port A out */
196
 
        DEVCB_HANDLER(slither_76489_0_w),               /* port B out */
197
 
        DEVCB_NULL,             /* line CA2 out */
198
 
        DEVCB_NULL,             /* port CB2 out */
199
 
        DEVCB_NULL,             /* IRQA */
200
 
        DEVCB_NULL              /* IRQB */
201
 
};
202
 
 
203
 
const pia6821_interface slither_pia_2_intf =
204
 
{
205
 
        DEVCB_HANDLER(slither_trak_ud_r),       /* port A in */
206
 
        DEVCB_NULL,             /* port B in */
207
 
        DEVCB_NULL,             /* line CA1 in */
208
 
        DEVCB_NULL,             /* line CB1 in */
209
 
        DEVCB_NULL,             /* line CA2 in */
210
 
        DEVCB_NULL,             /* line CB2 in */
211
 
        DEVCB_NULL,             /* port A out */
212
 
        DEVCB_HANDLER(slither_76489_1_w),               /* port B out */
213
 
        DEVCB_NULL,             /* line CA2 out */
214
 
        DEVCB_NULL,             /* port CB2 out */
215
 
        DEVCB_NULL,             /* IRQA */
216
 
        DEVCB_NULL              /* IRQB */
217
 
};
218
 
 
219
 
 
220
 
 
221
 
/*************************************
222
 
 *
223
 
 *  Machine initialization
224
 
 *
225
 
 *************************************/
226
 
 
227
 
MACHINE_RESET( qix )
228
 
{
229
 
        qix_state *state = machine.driver_data<qix_state>();
230
 
 
231
 
        /* reset the coin counter register */
232
 
        state->m_coinctrl = 0x00;
233
 
}
234
 
 
235
 
 
236
 
MACHINE_START( qixmcu )
237
 
{
238
 
        qix_state *state = machine.driver_data<qix_state>();
239
 
 
240
 
        /* set up save states */
241
 
        state->save_item(NAME(state->m_68705_port_in));
242
 
        state->save_item(NAME(state->m_coinctrl));
243
 
}
244
 
 
245
 
 
246
 
 
247
 
/*************************************
248
 
 *
249
 
 *  VSYNC change callback
250
 
 *
251
 
 *************************************/
252
 
 
253
 
WRITE_LINE_DEVICE_HANDLER( qix_vsync_changed )
254
 
{
255
 
        pia6821_device *pia = device->machine().device<pia6821_device>("sndpia0");
256
 
        pia->cb1_w(state);
257
 
}
258
 
 
259
 
 
260
 
 
261
 
/*************************************
262
 
 *
263
 
 *  Zoo Keeper bankswitching
264
 
 *
265
 
 *************************************/
266
 
 
267
 
WRITE8_HANDLER( zookeep_bankswitch_w )
268
 
{
269
 
        memory_set_bank(space->machine(), "bank1", (data >> 2) & 1);
270
 
        /* not necessary, but technically correct */
271
 
        qix_palettebank_w(space, offset, data);
272
 
}
273
 
 
274
 
 
275
 
 
276
 
/*************************************
277
 
 *
278
 
 *  Data CPU FIRQ generation/ack
279
 
 *
280
 
 *************************************/
281
 
 
282
 
WRITE8_HANDLER( qix_data_firq_w )
283
 
{
284
 
        cputag_set_input_line(space->machine(), "maincpu", M6809_FIRQ_LINE, ASSERT_LINE);
285
 
}
286
 
 
287
 
 
288
 
WRITE8_HANDLER( qix_data_firq_ack_w )
289
 
{
290
 
        cputag_set_input_line(space->machine(), "maincpu", M6809_FIRQ_LINE, CLEAR_LINE);
291
 
}
292
 
 
293
 
 
294
 
READ8_HANDLER( qix_data_firq_r )
295
 
{
296
 
        cputag_set_input_line(space->machine(), "maincpu", M6809_FIRQ_LINE, ASSERT_LINE);
297
 
        return 0xff;
298
 
}
299
 
 
300
 
 
301
 
READ8_HANDLER( qix_data_firq_ack_r )
302
 
{
303
 
        cputag_set_input_line(space->machine(), "maincpu", M6809_FIRQ_LINE, CLEAR_LINE);
304
 
        return 0xff;
305
 
}
306
 
 
307
 
 
308
 
 
309
 
/*************************************
310
 
 *
311
 
 *  Video CPU FIRQ generation/ack
312
 
 *
313
 
 *************************************/
314
 
 
315
 
WRITE8_HANDLER( qix_video_firq_w )
316
 
{
317
 
        cputag_set_input_line(space->machine(), "videocpu", M6809_FIRQ_LINE, ASSERT_LINE);
318
 
}
319
 
 
320
 
 
321
 
WRITE8_HANDLER( qix_video_firq_ack_w )
322
 
{
323
 
        cputag_set_input_line(space->machine(), "videocpu", M6809_FIRQ_LINE, CLEAR_LINE);
324
 
}
325
 
 
326
 
 
327
 
READ8_HANDLER( qix_video_firq_r )
328
 
{
329
 
        cputag_set_input_line(space->machine(), "videocpu", M6809_FIRQ_LINE, ASSERT_LINE);
330
 
        return 0xff;
331
 
}
332
 
 
333
 
 
334
 
READ8_HANDLER( qix_video_firq_ack_r )
335
 
{
336
 
        cputag_set_input_line(space->machine(), "videocpu", M6809_FIRQ_LINE, CLEAR_LINE);
337
 
        return 0xff;
338
 
}
339
 
 
340
 
 
341
 
 
342
 
/*************************************
343
 
 *
344
 
 *  68705 Communication
345
 
 *
346
 
 *************************************/
347
 
 
348
 
READ8_DEVICE_HANDLER( qixmcu_coin_r )
349
 
{
350
 
        qix_state *state = device->machine().driver_data<qix_state>();
351
 
 
352
 
        logerror("6809:qixmcu_coin_r = %02X\n", state->m_68705_port_out[0]);
353
 
        return state->m_68705_port_out[0];
354
 
}
355
 
 
356
 
 
357
 
static WRITE8_DEVICE_HANDLER( qixmcu_coin_w )
358
 
{
359
 
        qix_state *state = device->machine().driver_data<qix_state>();
360
 
 
361
 
        logerror("6809:qixmcu_coin_w = %02X\n", data);
362
 
        /* this is a callback called by pia6821_device::write(), so I don't need to synchronize */
363
 
        /* the CPUs - they have already been synchronized by qix_pia_w() */
364
 
        state->m_68705_port_in[0] = data;
365
 
}
366
 
 
367
 
 
368
 
static WRITE8_DEVICE_HANDLER( qixmcu_coinctrl_w )
369
 
{
370
 
        qix_state *state = device->machine().driver_data<qix_state>();
371
 
 
372
 
        /* if (!(data & 0x04)) */
373
 
        if (data & 0x04)
374
 
        {
375
 
                cputag_set_input_line(device->machine(), "mcu", M68705_IRQ_LINE, ASSERT_LINE);
376
 
                /* temporarily boost the interleave to sync things up */
377
 
                /* note: I'm using 50 because 30 is not enough for space dungeon at game over */
378
 
                device->machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(50));
379
 
        }
380
 
        else
381
 
                cputag_set_input_line(device->machine(), "mcu", M68705_IRQ_LINE, CLEAR_LINE);
382
 
 
383
 
        /* this is a callback called by pia6821_device::write(), so I don't need to synchronize */
384
 
        /* the CPUs - they have already been synchronized by qix_pia_w() */
385
 
        state->m_coinctrl = data;
386
 
        logerror("6809:qixmcu_coinctrl_w = %02X\n", data);
387
 
}
388
 
 
389
 
 
390
 
 
391
 
/*************************************
392
 
 *
393
 
 *  68705 Port Inputs
394
 
 *
395
 
 *************************************/
396
 
 
397
 
READ8_HANDLER( qix_68705_portA_r )
398
 
{
399
 
        qix_state *state = space->machine().driver_data<qix_state>();
400
 
 
401
 
        UINT8 ddr = state->m_68705_ddr[0];
402
 
        UINT8 out = state->m_68705_port_out[0];
403
 
        UINT8 in = state->m_68705_port_in[0];
404
 
        logerror("68705:portA_r = %02X (%02X)\n", (out & ddr) | (in & ~ddr), in);
405
 
        return (out & ddr) | (in & ~ddr);
406
 
}
407
 
 
408
 
 
409
 
READ8_HANDLER( qix_68705_portB_r )
410
 
{
411
 
        qix_state *state = space->machine().driver_data<qix_state>();
412
 
 
413
 
        UINT8 ddr = state->m_68705_ddr[1];
414
 
        UINT8 out = state->m_68705_port_out[1];
415
 
        UINT8 in = (input_port_read(space->machine(), "COIN") & 0x0f) | ((input_port_read(space->machine(), "COIN") & 0x80) >> 3);
416
 
        return (out & ddr) | (in & ~ddr);
417
 
}
418
 
 
419
 
 
420
 
READ8_HANDLER( qix_68705_portC_r )
421
 
{
422
 
        qix_state *state = space->machine().driver_data<qix_state>();
423
 
 
424
 
        UINT8 ddr = state->m_68705_ddr[2];
425
 
        UINT8 out = state->m_68705_port_out[2];
426
 
        UINT8 in = (state->m_coinctrl & 0x08) | ((input_port_read(space->machine(), "COIN") & 0x70) >> 4);
427
 
        return (out & ddr) | (in & ~ddr);
428
 
}
429
 
 
430
 
 
431
 
 
432
 
/*************************************
433
 
 *
434
 
 *  68705 Port Outputs
435
 
 *
436
 
 *************************************/
437
 
 
438
 
WRITE8_HANDLER( qix_68705_portA_w )
439
 
{
440
 
        qix_state *state = space->machine().driver_data<qix_state>();
441
 
 
442
 
        logerror("68705:portA_w = %02X\n", data);
443
 
        state->m_68705_port_out[0] = data;
444
 
}
445
 
 
446
 
 
447
 
WRITE8_HANDLER( qix_68705_portB_w )
448
 
{
449
 
        qix_state *state = space->machine().driver_data<qix_state>();
450
 
 
451
 
        state->m_68705_port_out[1] = data;
452
 
        coin_lockout_w(space->machine(), 0, (~data >> 6) & 1);
453
 
        coin_counter_w(space->machine(), 0, (data >> 7) & 1);
454
 
}
455
 
 
456
 
 
457
 
WRITE8_HANDLER( qix_68705_portC_w )
458
 
{
459
 
        qix_state *state = space->machine().driver_data<qix_state>();
460
 
 
461
 
        state->m_68705_port_out[2] = data;
462
 
}
463
 
 
464
 
 
465
 
 
466
 
/*************************************
467
 
 *
468
 
 *  Data CPU PIA 0 synchronization
469
 
 *
470
 
 *************************************/
471
 
 
472
 
static TIMER_CALLBACK( pia_w_callback )
473
 
{
474
 
        pia6821_device *device = (pia6821_device *)ptr;
475
 
        device->write(*memory_nonspecific_space(device->machine()), param >> 8, param & 0xff);
476
 
}
477
 
 
478
 
 
479
 
WRITE8_DEVICE_HANDLER( qix_pia_w )
480
 
{
481
 
        /* make all the CPUs synchronize, and only AFTER that write the command to the PIA */
482
 
        /* otherwise the 68705 will miss commands */
483
 
        device->machine().scheduler().synchronize(FUNC(pia_w_callback), data | (offset << 8), (void *)downcast<pia6821_device *>(device));
484
 
}
485
 
 
486
 
 
487
 
 
488
 
/*************************************
489
 
 *
490
 
 *  Coin I/O for games without coin CPU
491
 
 *
492
 
 *************************************/
493
 
 
494
 
static WRITE8_DEVICE_HANDLER( qix_coinctl_w )
495
 
{
496
 
        coin_lockout_w(device->machine(), 0, (~data >> 2) & 1);
497
 
        coin_counter_w(device->machine(), 0, (data >> 1) & 1);
498
 
}
499
 
 
500
 
 
501
 
 
502
 
/*************************************
503
 
 *
504
 
 *  Slither SN76489 I/O
505
 
 *
506
 
 *************************************/
507
 
 
508
 
static WRITE8_DEVICE_HANDLER( slither_76489_0_w )
509
 
{
510
 
        /* write to the sound chip */
511
 
        sn76496_w(device->machine().device("sn1"), 0, data);
512
 
 
513
 
        /* clock the ready line going back into CB1 */
514
 
        pia6821_device *pia = downcast<pia6821_device *>(device);
515
 
        pia->cb1_w(0);
516
 
        pia->cb1_w(1);
517
 
}
518
 
 
519
 
 
520
 
static WRITE8_DEVICE_HANDLER( slither_76489_1_w )
521
 
{
522
 
        /* write to the sound chip */
523
 
        sn76496_w(device->machine().device("sn2"), 0, data);
524
 
 
525
 
        /* clock the ready line going back into CB1 */
526
 
        pia6821_device *pia = downcast<pia6821_device *>(device);
527
 
        pia->cb1_w(0);
528
 
        pia->cb1_w(1);
529
 
}
530
 
 
531
 
 
532
 
 
533
 
/*************************************
534
 
 *
535
 
 *  Slither trackball I/O
536
 
 *
537
 
 *************************************/
538
 
 
539
 
static READ8_DEVICE_HANDLER( slither_trak_lr_r )
540
 
{
541
 
        qix_state *state = device->machine().driver_data<qix_state>();
542
 
 
543
 
        return input_port_read(device->machine(), state->m_flip ? "AN3" : "AN1");
544
 
}
545
 
 
546
 
 
547
 
static READ8_DEVICE_HANDLER( slither_trak_ud_r )
548
 
{
549
 
        qix_state *state = device->machine().driver_data<qix_state>();
550
 
 
551
 
        return input_port_read(device->machine(), state->m_flip ? "AN2" : "AN0");
552
 
}