1
/***************************************************************************
2
ToaPlan game hardware from 1988-1991
3
------------------------------------
4
***************************************************************************/
7
#include "cpu/z80/z80.h"
8
#include "cpu/m68000/m68000.h"
9
#include "cpu/tms32010/tms32010.h"
10
#include "sound/3812intf.h"
11
#include "includes/toaplan1.h"
17
/* List of possible regions for coinage (for games with unemulated sound CPU) */
19
TOAPLAN1_REGION_JAPAN=0,
21
TOAPLAN1_REGION_WORLD,
25
static const UINT8 toaplan1_coins_for_credit[TOAPLAN1_REGION_OTHER+1][2][4] =
27
{ { 1, 1, 2, 2 }, { 1, 1, 2, 2 } }, /* TOAPLAN1_REGION_JAPAN */
28
{ { 1, 1, 2, 2 }, { 1, 1, 2, 2 } }, /* TOAPLAN1_REGION_US */
29
{ { 1, 2, 3, 4 }, { 1, 1, 1, 1 } }, /* TOAPLAN1_REGION_WORLD */
30
{ { 1, 1, 1, 1 }, { 1, 1, 1, 1 } } /* TOAPLAN1_REGION_OTHER */
33
static const UINT8 toaplan1_credits_for_coin[TOAPLAN1_REGION_OTHER+1][2][4] =
35
{ { 1, 2, 1, 3 }, { 1, 2, 1, 3 } }, /* TOAPLAN1_REGION_JAPAN */
36
{ { 1, 2, 1, 3 }, { 1, 2, 1, 3 } }, /* TOAPLAN1_REGION_US */
37
{ { 1, 1, 1, 1 }, { 2, 3, 4, 6 } }, /* TOAPLAN1_REGION_WORLD */
38
{ { 1, 1, 1, 1 }, { 1, 1, 1, 1 } }, /* TOAPLAN1_REGION_OTHER */
42
INTERRUPT_GEN( toaplan1_interrupt )
44
toaplan1_state *state = device->machine().driver_data<toaplan1_state>();
46
if (state->m_intenable)
47
device_set_input_line(device, 4, HOLD_LINE);
50
WRITE16_HANDLER( toaplan1_intenable_w )
52
if (ACCESSING_BITS_0_7)
54
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
55
state->m_intenable = data & 0xff;
60
WRITE16_HANDLER( demonwld_dsp_addrsel_w )
62
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
64
/* This sets the main CPU RAM address the DSP should */
65
/* read/write, via the DSP IO port 0 */
66
/* Top three bits of data need to be shifted left 9 places */
67
/* to select which memory bank from main CPU address */
69
/* Lower thirteen bits of this data is shifted left one position */
70
/* to move it to an even address word boundary */
72
state->m_main_ram_seg = ((data & 0xe000) << 9);
73
state->m_dsp_addr_w = ((data & 0x1fff) << 1);
74
logerror("DSP PC:%04x IO write %04x (%08x) at port 0\n", cpu_get_previouspc(&space->device()), data, state->m_main_ram_seg + state->m_dsp_addr_w);
77
READ16_HANDLER( demonwld_dsp_r )
79
/* DSP can read data from main CPU RAM via DSP IO port 1 */
81
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
82
address_space *mainspace;
83
UINT16 input_data = 0;
85
switch (state->m_main_ram_seg) {
86
case 0xc00000: mainspace = space->machine().device("maincpu")->memory().space(AS_PROGRAM);
87
input_data = mainspace->read_word(state->m_main_ram_seg + state->m_dsp_addr_w);
89
default: logerror("DSP PC:%04x Warning !!! IO reading from %08x (port 1)\n", cpu_get_previouspc(&space->device()), state->m_main_ram_seg + state->m_dsp_addr_w);
91
logerror("DSP PC:%04x IO read %04x at %08x (port 1)\n", cpu_get_previouspc(&space->device()), input_data, state->m_main_ram_seg + state->m_dsp_addr_w);
95
WRITE16_HANDLER( demonwld_dsp_w )
97
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
98
address_space *mainspace;
100
/* Data written to main CPU RAM via DSP IO port 1 */
101
state->m_dsp_execute = 0;
102
switch (state->m_main_ram_seg) {
103
case 0xc00000: if ((state->m_dsp_addr_w < 3) && (data == 0)) state->m_dsp_execute = 1;
104
mainspace = space->machine().device("maincpu")->memory().space(AS_PROGRAM);
105
mainspace->write_word(state->m_main_ram_seg + state->m_dsp_addr_w, data);
107
default: logerror("DSP PC:%04x Warning !!! IO writing to %08x (port 1)\n", cpu_get_previouspc(&space->device()), state->m_main_ram_seg + state->m_dsp_addr_w);
109
logerror("DSP PC:%04x IO write %04x at %08x (port 1)\n", cpu_get_previouspc(&space->device()), data, state->m_main_ram_seg + state->m_dsp_addr_w);
112
WRITE16_HANDLER( demonwld_dsp_bio_w )
114
/* data 0xffff means inhibit BIO line to DSP and enable */
115
/* communication to main processor */
116
/* Actually only DSP data bit 15 controls this */
117
/* data 0x0000 means set DSP BIO line active and disable */
118
/* communication to main processor*/
120
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
122
logerror("DSP PC:%04x IO write %04x at port 3\n", cpu_get_previouspc(&space->device()), data);
124
state->m_dsp_BIO = CLEAR_LINE;
127
if (state->m_dsp_execute) {
128
logerror("Turning 68000 on\n");
129
cputag_set_input_line(space->machine(), "maincpu", INPUT_LINE_HALT, CLEAR_LINE);
130
state->m_dsp_execute = 0;
132
state->m_dsp_BIO = ASSERT_LINE;
136
READ16_HANDLER ( demonwld_BIO_r )
138
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
140
return state->m_dsp_BIO;
144
static void demonwld_dsp(running_machine &machine, int enable)
146
toaplan1_state *state = machine.driver_data<toaplan1_state>();
148
state->m_dsp_on = enable;
151
logerror("Turning DSP on and 68000 off\n");
152
cputag_set_input_line(machine, "dsp", INPUT_LINE_HALT, CLEAR_LINE);
153
cputag_set_input_line(machine, "dsp", 0, ASSERT_LINE); /* TMS32010 INT */
154
cputag_set_input_line(machine, "maincpu", INPUT_LINE_HALT, ASSERT_LINE);
158
logerror("Turning DSP off\n");
159
cputag_set_input_line(machine, "dsp", 0, CLEAR_LINE); /* TMS32010 INT */
160
cputag_set_input_line(machine, "dsp", INPUT_LINE_HALT, ASSERT_LINE);
164
static void demonwld_restore_dsp(running_machine &machine)
166
toaplan1_state *state = machine.driver_data<toaplan1_state>();
167
demonwld_dsp(machine, state->m_dsp_on);
170
WRITE16_HANDLER( demonwld_dsp_ctrl_w )
173
logerror("68000:%08x Writing %08x to %08x.\n",cpu_get_pc(&space->device()) ,data ,0xe0000a + offset);
176
if (ACCESSING_BITS_0_7)
180
case 0x00: demonwld_dsp(space->machine(), 1); break; /* Enable the INT line to the DSP */
181
case 0x01: demonwld_dsp(space->machine(), 0); break; /* Inhibit the INT line to the DSP */
182
default: logerror("68000:%04x Writing unknown command %08x to %08x\n",cpu_get_previouspc(&space->device()) ,data ,0xe0000a + offset); break;
187
logerror("68000:%04x Writing unknown command %08x to %08x\n",cpu_get_previouspc(&space->device()) ,data ,0xe0000a + offset);
192
READ16_HANDLER( samesame_port_6_word_r )
194
/* Bit 0x80 is secondary CPU (HD647180) ready signal */
195
logerror("PC:%04x Warning !!! IO reading from $14000a\n",cpu_get_previouspc(&space->device()));
196
return (0x80 | input_port_read(space->machine(), "TJUMP")) & 0xff;
199
READ16_HANDLER ( vimana_system_port_r )
201
static const UINT8 vimana_region[16] =
203
TOAPLAN1_REGION_JAPAN, TOAPLAN1_REGION_US , TOAPLAN1_REGION_WORLD, TOAPLAN1_REGION_JAPAN,
204
TOAPLAN1_REGION_JAPAN, TOAPLAN1_REGION_JAPAN, TOAPLAN1_REGION_JAPAN, TOAPLAN1_REGION_US ,
205
TOAPLAN1_REGION_JAPAN, TOAPLAN1_REGION_OTHER, TOAPLAN1_REGION_OTHER, TOAPLAN1_REGION_OTHER,
206
TOAPLAN1_REGION_OTHER, TOAPLAN1_REGION_OTHER, TOAPLAN1_REGION_OTHER, TOAPLAN1_REGION_JAPAN
209
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
210
int data, p, r, d, slot, reg, dsw;
213
d = input_port_read(space->machine(), "DSWA");
214
r = input_port_read(space->machine(), "TJUMP");
215
p = input_port_read(space->machine(), "SYSTEM");
216
state->m_vimana_latch ^= p;
217
data = (state->m_vimana_latch & p);
219
/* simulate the mcu keeping track of credits based on region and coinage settings */
220
/* latch so it doesn't add more than one coin per keypress */
221
if (d & 0x04) /* "test mode" ON */
223
state->m_vimana_coins[0] = state->m_vimana_coins[1] = 0;
224
state->m_vimana_credits = 0;
226
else /* "test mode" OFF */
228
if (data & 0x02) /* TILT */
230
state->m_vimana_coins[0] = state->m_vimana_coins[1] = 0;
231
state->m_vimana_credits = 0;
233
if (data & 0x01) /* SERVICE1 */
235
state->m_vimana_credits++ ;
237
if (data & 0x08) /* COIN1 */
241
if (data & 0x10) /* COIN2 */
248
reg = vimana_region[r];
249
dsw = (d & 0xf0) >> (4 + 2 * slot);
250
state->m_vimana_coins[slot]++;
251
if (state->m_vimana_coins[slot] >= toaplan1_coins_for_credit[reg][slot][dsw])
253
state->m_vimana_credits += toaplan1_credits_for_coin[reg][slot][dsw];
254
state->m_vimana_coins[slot] -= toaplan1_coins_for_credit[reg][slot][dsw];
256
coin_counter_w(space->machine(), slot, 1);
257
coin_counter_w(space->machine(), slot, 0);
260
if (state->m_vimana_credits >= 9)
261
state->m_vimana_credits = 9;
264
coin_lockout_global_w(space->machine(), (state->m_vimana_credits >= 9));
266
state->m_vimana_latch = p;
271
READ16_HANDLER( vimana_mcu_r )
276
case 0: data = 0xff; break;
277
case 1: data = 0x00; break;
280
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
281
data = state->m_vimana_credits;
288
WRITE16_HANDLER( vimana_mcu_w )
295
if (ACCESSING_BITS_0_7)
297
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
298
state->m_vimana_credits = data & 0xff;
299
coin_lockout_global_w(space->machine(), (state->m_vimana_credits >= 9));
305
READ16_HANDLER( toaplan1_shared_r )
307
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
308
return state->m_sharedram[offset] & 0xff;
311
WRITE16_HANDLER( toaplan1_shared_w )
313
if (ACCESSING_BITS_0_7)
315
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
316
state->m_sharedram[offset] = data & 0xff;
321
WRITE16_HANDLER( toaplan1_reset_sound )
323
/* Reset the secondary CPU and sound chip during soft resets */
325
if (ACCESSING_BITS_0_7 && (data == 0))
327
logerror("PC:%04x Resetting Sound CPU and Sound chip (%08x)\n", cpu_get_previouspc(&space->device()), data);
328
devtag_reset(space->machine(), "ymsnd");
329
device_t *audiocpu = space->machine().device("audiocpu");
330
if (audiocpu != NULL && audiocpu->type() == Z80)
331
device_set_input_line(audiocpu, INPUT_LINE_RESET, PULSE_LINE);
336
WRITE8_HANDLER( rallybik_coin_w )
338
toaplan1_state *state = space->machine().driver_data<toaplan1_state>();
341
case 0x08: if (state->m_coin_count) { coin_counter_w(space->machine(), 0, 1); coin_counter_w(space->machine(), 0, 0); } break;
342
case 0x09: if (state->m_coin_count) { coin_counter_w(space->machine(), 2, 1); coin_counter_w(space->machine(), 2, 0); } break;
343
case 0x0a: if (state->m_coin_count) { coin_counter_w(space->machine(), 1, 1); coin_counter_w(space->machine(), 1, 0); } break;
344
case 0x0b: if (state->m_coin_count) { coin_counter_w(space->machine(), 3, 1); coin_counter_w(space->machine(), 3, 0); } break;
345
case 0x0c: coin_lockout_w(space->machine(), 0, 1); coin_lockout_w(space->machine(), 2, 1); break;
346
case 0x0d: coin_lockout_w(space->machine(), 0, 0); coin_lockout_w(space->machine(), 2, 0); break;
347
case 0x0e: coin_lockout_w(space->machine(), 1, 1); coin_lockout_w(space->machine(), 3, 1); break;
348
case 0x0f: coin_lockout_w(space->machine(), 1, 0); coin_lockout_w(space->machine(), 3, 0); state->m_coin_count=1; break;
349
default: logerror("PC:%04x Writing unknown data (%04x) to coin count/lockout port\n",cpu_get_previouspc(&space->device()),data); break;
353
WRITE8_HANDLER( toaplan1_coin_w )
355
logerror("Z80 writing %02x to coin control\n",data);
356
/* This still isnt too clear yet. */
357
/* Coin C has no coin lock ? */
358
/* Are some outputs for lights ? (no space on JAMMA for it though) */
361
case 0xee: coin_counter_w(space->machine(), 1,1); coin_counter_w(space->machine(), 1,0); break; /* Count slot B */
362
case 0xed: coin_counter_w(space->machine(), 0,1); coin_counter_w(space->machine(), 0,0); break; /* Count slot A */
363
/* The following are coin counts after coin-lock active (faulty coin-lock ?) */
364
case 0xe2: coin_counter_w(space->machine(), 1,1); coin_counter_w(space->machine(), 1,0); coin_lockout_w(space->machine(), 1,1); break;
365
case 0xe1: coin_counter_w(space->machine(), 0,1); coin_counter_w(space->machine(), 0,0); coin_lockout_w(space->machine(), 0,1); break;
367
case 0xec: coin_lockout_global_w(space->machine(), 0); break; /* ??? count games played */
368
case 0xe8: break; /* ??? Maximum credits reached with coin/credit ratio */
369
case 0xe4: break; /* ??? Reset coin system */
371
case 0x0c: coin_lockout_global_w(space->machine(), 0); break; /* Unlock all coin slots */
372
case 0x08: coin_lockout_w(space->machine(), 2,0); break; /* Unlock coin slot C */
373
case 0x09: coin_lockout_w(space->machine(), 0,0); break; /* Unlock coin slot A */
374
case 0x0a: coin_lockout_w(space->machine(), 1,0); break; /* Unlock coin slot B */
376
case 0x02: coin_lockout_w(space->machine(), 1,1); break; /* Lock coin slot B */
377
case 0x01: coin_lockout_w(space->machine(), 0,1); break; /* Lock coin slot A */
378
case 0x00: coin_lockout_global_w(space->machine(), 1); break; /* Lock all coin slots */
379
default: logerror("PC:%04x Writing unknown data (%04x) to coin count/lockout port\n",cpu_get_previouspc(&space->device()),data); break;
383
WRITE16_HANDLER( samesame_coin_w )
385
if (ACCESSING_BITS_0_7)
387
toaplan1_coin_w(space, offset, data & 0xff);
389
if (ACCESSING_BITS_8_15 && (data&0xff00))
391
logerror("PC:%04x Writing unknown MSB data (%04x) to coin count/lockout port\n",cpu_get_previouspc(&space->device()),data);
396
MACHINE_RESET( toaplan1 )
398
toaplan1_state *state = machine.driver_data<toaplan1_state>();
400
state->m_intenable = 0;
401
state->m_coin_count = 0;
402
state->m_unk_reset_port = 0;
403
coin_lockout_global_w(machine, 0);
406
void toaplan1_driver_savestate(running_machine &machine)
408
toaplan1_state *state = machine.driver_data<toaplan1_state>();
410
state->save_item(NAME(state->m_intenable));
411
state->save_item(NAME(state->m_coin_count));
412
state->save_item(NAME(state->m_unk_reset_port));
415
MACHINE_RESET( zerowing ) /* Hack for ZeroWing and OutZone. See the video driver */
417
toaplan1_state *state = machine.driver_data<toaplan1_state>();
419
MACHINE_RESET_CALL(toaplan1);
420
state->m_unk_reset_port = 1;
423
MACHINE_RESET( demonwld )
425
toaplan1_state *state = machine.driver_data<toaplan1_state>();
427
MACHINE_RESET_CALL(toaplan1);
428
state->m_dsp_addr_w = 0;
429
state->m_main_ram_seg = 0;
430
state->m_dsp_execute = 0;
433
void demonwld_driver_savestate(running_machine &machine)
435
toaplan1_state *state = machine.driver_data<toaplan1_state>();
437
state->save_item(NAME(state->m_dsp_on));
438
state->save_item(NAME(state->m_dsp_addr_w));
439
state->save_item(NAME(state->m_main_ram_seg));
440
state->save_item(NAME(state->m_dsp_BIO));
441
state->save_item(NAME(state->m_dsp_execute));
442
machine.save().register_postload(save_prepost_delegate(FUNC(demonwld_restore_dsp), &machine));
445
MACHINE_RESET( vimana )
447
toaplan1_state *state = machine.driver_data<toaplan1_state>();
449
MACHINE_RESET_CALL(toaplan1);
450
state->m_vimana_coins[0] = state->m_vimana_coins[1] = 0;
451
state->m_vimana_credits = 0;
452
state->m_vimana_latch = 0;
455
void vimana_driver_savestate(running_machine &machine)
457
toaplan1_state *state = machine.driver_data<toaplan1_state>();
459
state->save_item(NAME(state->m_vimana_coins[0]));
460
state->save_item(NAME(state->m_vimana_coins[1]));
461
state->save_item(NAME(state->m_vimana_credits));
462
state->save_item(NAME(state->m_vimana_latch));