1 /***************************************************************************
2 ToaPlan game hardware from 1988-1991
3 ------------------------------------
4 ***************************************************************************/
5
6 #include "driver.h"
7 #include "state.h"
8 #include "cpu/m68000/m68000.h"
9 #include "cpu/tms32010/tms32010.h"
10
11 #define CLEAR 0
12 #define ASSERT 1
13
14
15 static int toaplan1_coin_count; /* coin count increments on startup ? , so dont count it */
16 static int toaplan1_intenable;
17 static int demonwld_dsp_BIO;
18
19 static int dsp_execute; /* Demon world */
20 static unsigned int dsp_addr_w, main_ram_seg; /* Demon world */
21 static int credits; /* Vimana */
22 static int latch; /* Vimana */
23
24 int toaplan1_unk_reset_port;
25
26 data8_t *toaplan1_sharedram;
27
28
29
INTERRUPT_GEN(toaplan1_interrupt)30 INTERRUPT_GEN( toaplan1_interrupt )
31 {
32 if (toaplan1_intenable)
33 cpu_set_irq_line(0, 4, HOLD_LINE);
34 }
35
WRITE16_HANDLER(toaplan1_intenable_w)36 WRITE16_HANDLER( toaplan1_intenable_w )
37 {
38 if (ACCESSING_LSB)
39 {
40 toaplan1_intenable = data & 0xff;
41 }
42 }
43
44
READ16_HANDLER(demonwld_dsp_r)45 READ16_HANDLER( demonwld_dsp_r )
46 {
47 /* DSP can read data from main CPU RAM via DSP IO port 1 */
48
49 unsigned int input_data = 0;
50
51 switch (main_ram_seg) {
52 case 0xc00000: input_data = *((data16_t *)&(cpu_bankbase[1][(dsp_addr_w)])); break;
53
54 default: logerror("DSP PC:%04x Warning !!! IO reading from %08x (port 1)\n",activecpu_get_previouspc(),main_ram_seg + dsp_addr_w);
55 }
56 logerror("DSP PC:%04x IO read %04x at %08x (port 1)\n",activecpu_get_previouspc(),input_data,main_ram_seg + dsp_addr_w);
57 return input_data;
58 }
59
WRITE16_HANDLER(demonwld_dsp_w)60 WRITE16_HANDLER( demonwld_dsp_w )
61 {
62 if (offset == 0) {
63 /* This sets the main CPU RAM address the DSP should */
64 /* read/write, via the DSP IO port 0 */
65 /* Top three bits of data need to be shifted left 9 places */
66 /* to select which memory bank from main CPU address */
67 /* space to use */
68 /* Lower thirteen bits of this data is shifted left one position */
69 /* to move it to an even address word boundary */
70
71 dsp_addr_w = ((data & 0x1fff) << 1);
72 main_ram_seg = ((data & 0xe000) << 9);
73 logerror("DSP PC:%04x IO write %04x (%08x) at port 0\n",activecpu_get_previouspc(),data,main_ram_seg + dsp_addr_w);
74 }
75 if (offset == 1) {
76 /* Data written to main CPU RAM via DSP IO port 1*/
77
78 dsp_execute = 0;
79 switch (main_ram_seg) {
80 case 0xc00000: *((data16_t *)&(cpu_bankbase[1][(dsp_addr_w)])) = data;
81 if ((dsp_addr_w < 3) && (data == 0)) dsp_execute = 1; break;
82 default: logerror("DSP PC:%04x Warning !!! IO writing to %08x (port 1)\n",activecpu_get_previouspc(),main_ram_seg + dsp_addr_w);
83 }
84 logerror("DSP PC:%04x IO write %04x at %08x (port 1)\n",activecpu_get_previouspc(),data,main_ram_seg + dsp_addr_w);
85 }
86 if (offset == 3) {
87 /* data 0xffff means inhibit BIO line to DSP and enable */
88 /* communication to main processor */
89 /* Actually only DSP data bit 15 controls this */
90 /* data 0x0000 means set DSP BIO line active and disable */
91 /* communication to main processor*/
92 logerror("DSP PC:%04x IO write %04x at port 3\n",activecpu_get_previouspc(),data);
93 if (data & 0x8000) {
94 demonwld_dsp_BIO = CLEAR_LINE;
95 }
96 if (data == 0) {
97 if (dsp_execute) {
98 logerror("Turning 68000 on\n");
99 timer_suspendcpu(0, CLEAR, SUSPEND_REASON_HALT);
100 dsp_execute = 0;
101 }
102 demonwld_dsp_BIO = ASSERT_LINE;
103 }
104 }
105 }
106
WRITE16_HANDLER(demonwld_dsp_ctrl_w)107 WRITE16_HANDLER( demonwld_dsp_ctrl_w )
108 {
109 #if 0
110 logerror("68000:%08x Writing %08x to %08x.\n",activecpu_get_pc() ,data ,0xe0000a + offset);
111 #endif
112
113 if (ACCESSING_LSB)
114 {
115 switch (data)
116 {
117 case 0x00: /* This means assert the INT line to the DSP */
118 logerror("Turning DSP on and 68000 off\n");
119 timer_suspendcpu(2, CLEAR, SUSPEND_REASON_HALT);
120 cpu_set_irq_line(2, 0, ASSERT_LINE); /* TMS32020 INT */
121 timer_suspendcpu(0, ASSERT, SUSPEND_REASON_HALT);
122 break;
123 case 0x01: /* This means inhibit the INT line to the DSP */
124 logerror("Turning DSP off\n");
125 cpu_set_irq_line(2, 0, CLEAR_LINE); /* TMS32020 INT */
126 timer_suspendcpu(2, ASSERT, SUSPEND_REASON_HALT);
127 break;
128 default: logerror("68000:%04x writing unknown command %08x to %08x\n",activecpu_get_previouspc() ,data ,0xe0000a + offset);
129 }
130 }
131 else
132 {
133 logerror("68000:%04x writing unknown command %08x to %08x\n",activecpu_get_previouspc() ,data ,0xe0000a + offset);
134 }
135 }
136
137
READ16_HANDLER(demonwld_BIO_r)138 READ16_HANDLER ( demonwld_BIO_r )
139 {
140 return demonwld_dsp_BIO;
141 }
142
143
READ16_HANDLER(samesame_port_6_word_r)144 READ16_HANDLER( samesame_port_6_word_r )
145 {
146 /* Bit 0x80 is secondary CPU (HD647180) ready signal */
147 logerror("PC:%04x Warning !!! IO reading from $14000a\n",activecpu_get_previouspc());
148 return (0x80 | input_port_6_word_r(0,0)) & 0xff;
149 }
150
READ16_HANDLER(vimana_input_port_5_word_r)151 READ16_HANDLER( vimana_input_port_5_word_r )
152 {
153 int data, p;
154
155 p = input_port_5_word_r(0,0);
156
157 latch ^= p;
158 data = (latch & p );
159
160 /* simulate the mcu keeping track of credits */
161 /* latch so it doesn't add more than one */
162 /* credit per keypress */
163
164 if (data & 0x18)
165 {
166 credits++ ;
167 }
168
169 latch = p;
170
171 return p & 0xffff;
172 }
173
READ16_HANDLER(vimana_mcu_r)174 READ16_HANDLER( vimana_mcu_r )
175 {
176 int data = 0 ;
177 switch (offset)
178 {
179 case 0: data = 0xff; break;
180 case 1: data = 0; break;
181 case 2: data = credits; break;
182 }
183 return data & 0xff;
184 }
WRITE16_HANDLER(vimana_mcu_w)185 WRITE16_HANDLER( vimana_mcu_w )
186 {
187 switch (offset)
188 {
189 case 0: break;
190 case 1: break;
191 case 2: if (ACCESSING_LSB) credits = data & 0xff; break;
192 }
193 }
194
READ16_HANDLER(toaplan1_shared_r)195 READ16_HANDLER( toaplan1_shared_r )
196 {
197 return toaplan1_sharedram[offset] & 0xff;
198 }
199
WRITE16_HANDLER(toaplan1_shared_w)200 WRITE16_HANDLER( toaplan1_shared_w )
201 {
202 if (ACCESSING_LSB)
203 {
204 toaplan1_sharedram[offset] = data & 0xff;
205 }
206 }
207
WRITE16_HANDLER(toaplan1_reset_sound)208 WRITE16_HANDLER( toaplan1_reset_sound )
209 {
210 /* Reset the secondary CPU and sound chip during soft resets */
211
212 if (ACCESSING_LSB && (data == 0))
213 {
214 logerror("PC:%04x Resetting Sound CPU and Sound chip (%08x)\n",activecpu_get_previouspc(),data);
215 if (Machine->drv->sound[0].sound_type == SOUND_YM3812)
216 YM3812_sh_reset();
217 if (Machine->drv->cpu[1].cpu_type == CPU_Z80)
218 cpu_set_reset_line(1,PULSE_LINE);
219 }
220 }
221
MACHINE_INIT(toaplan1)222 MACHINE_INIT( toaplan1 )
223 {
224 toaplan1_intenable = 0;
225 toaplan1_coin_count = 0;
226 toaplan1_unk_reset_port = 0;
227 coin_lockout_global_w(0);
228 state_save_register_INT32("toaplan1", 0, "Int_enable", &toaplan1_intenable, 1);
229 state_save_register_INT32("toaplan1", 0, "Coin_counter", &toaplan1_coin_count, 1);
230 }
231
MACHINE_INIT(zerozone)232 MACHINE_INIT( zerozone ) /* Hack for ZeroWing and OutZone. See the video driver */
233 {
234 machine_init_toaplan1();
235 toaplan1_unk_reset_port = 1;
236 }
237
MACHINE_INIT(demonwld)238 MACHINE_INIT( demonwld )
239 {
240 dsp_addr_w = 0;
241 dsp_execute = 0;
242 main_ram_seg = 0;
243 state_save_register_INT32("demonwld", 0, "DSP_execute", &dsp_execute, 1);
244 state_save_register_UINT32("demonwld", 0, "DSP_out_addr", &dsp_addr_w, 1);
245 state_save_register_UINT32("demonwld", 0, "DSP_to_68K_RAM_bank", &main_ram_seg, 1);
246 machine_init_toaplan1();
247 }
248
MACHINE_INIT(vimana)249 MACHINE_INIT( vimana )
250 {
251 credits = 0;
252 latch = 0;
253 state_save_register_INT32("vimana", 0, "Credits count", &credits, 1);
254 state_save_register_INT32("vimana", 0, "MCU_latch", &latch, 1);
255 machine_init_toaplan1();
256 }
257
WRITE_HANDLER(rallybik_coin_w)258 WRITE_HANDLER( rallybik_coin_w )
259 {
260 switch (data) {
261 case 0x08: if (toaplan1_coin_count) { coin_counter_w(0,1); coin_counter_w(0,0); } break;
262 case 0x09: if (toaplan1_coin_count) { coin_counter_w(2,1); coin_counter_w(2,0); } break;
263 case 0x0a: if (toaplan1_coin_count) { coin_counter_w(1,1); coin_counter_w(1,0); } break;
264 case 0x0b: if (toaplan1_coin_count) { coin_counter_w(3,1); coin_counter_w(3,0); } break;
265 case 0x0c: coin_lockout_w(0,1); coin_lockout_w(2,1); break;
266 case 0x0d: coin_lockout_w(0,0); coin_lockout_w(2,0); break;
267 case 0x0e: coin_lockout_w(1,1); coin_lockout_w(3,1); break;
268 case 0x0f: coin_lockout_w(1,0); coin_lockout_w(3,0); toaplan1_coin_count=1; break;
269 default: logerror("PC:%04x Writing unknown data (%04x) to coin count/lockout port\n",activecpu_get_previouspc(),data); break;
270 }
271 }
272
WRITE_HANDLER(toaplan1_coin_w)273 WRITE_HANDLER( toaplan1_coin_w )
274 {
275 logerror("Z80 writing %02x to coin control\n",data);
276 /* This still isnt too clear yet. */
277 /* Coin C has no coin lock ? */
278 /* Are some outputs for lights ? (no space on JAMMA for it though) */
279
280 switch (data) {
281 case 0xee: coin_counter_w(1,1); coin_counter_w(1,0); break; /* Count slot B */
282 case 0xed: coin_counter_w(0,1); coin_counter_w(0,0); break; /* Count slot A */
283 /* The following are coin counts after coin-lock active (faulty coin-lock ?) */
284 case 0xe2: coin_counter_w(1,1); coin_counter_w(1,0); coin_lockout_w(1,1); break;
285 case 0xe1: coin_counter_w(0,1); coin_counter_w(0,0); coin_lockout_w(0,1); break;
286
287 case 0xec: coin_lockout_global_w(0); break; /* ??? count games played */
288 case 0xe8: break; /* ??? Maximum credits reached with coin/credit ratio */
289 case 0xe4: break; /* ??? Reset coin system */
290
291 case 0x0c: coin_lockout_global_w(0); break; /* Unlock all coin slots */
292 case 0x08: coin_lockout_w(2,0); break; /* Unlock coin slot C */
293 case 0x09: coin_lockout_w(0,0); break; /* Unlock coin slot A */
294 case 0x0a: coin_lockout_w(1,0); break; /* Unlock coin slot B */
295
296 case 0x02: coin_lockout_w(1,1); break; /* Lock coin slot B */
297 case 0x01: coin_lockout_w(0,1); break; /* Lock coin slot A */
298 case 0x00: coin_lockout_global_w(1); break; /* Lock all coin slots */
299 default: logerror("PC:%04x Writing unknown data (%04x) to coin count/lockout port\n",activecpu_get_previouspc(),data); break;
300 }
301 }
302
WRITE16_HANDLER(samesame_coin_w)303 WRITE16_HANDLER( samesame_coin_w )
304 {
305 if (ACCESSING_LSB)
306 {
307 toaplan1_coin_w(offset, data & 0xff);
308 }
309 if (ACCESSING_MSB && (data&0xff00))
310 {
311 logerror("PC:%04x Writing unknown MSB data (%04x) to coin count/lockout port\n",activecpu_get_previouspc(),data);
312 }
313 }
314