1 /*************************************************************************
2
3 BattleToads
4
5 driver by Aaron Giles
6
7 **************************************************************************/
8
9 #include "driver.h"
10 #include "cpu/tms34010/tms34010.h"
11 #include "vidhrdw/tlc34076.h"
12 #include "btoads.h"
13
14
15
16 /*************************************
17 *
18 * Global variables
19 *
20 *************************************/
21
22 static data16_t *code_rom;
23 static data16_t *main_speedup;
24
25 static UINT8 main_to_sound_data;
26 static UINT8 main_to_sound_ready;
27
28 static UINT8 sound_to_main_data;
29 static UINT8 sound_to_main_ready;
30 static UINT8 sound_int_state;
31
32
33
34 /*************************************
35 *
36 * Machine init
37 *
38 *************************************/
39
MACHINE_INIT(btoads)40 static MACHINE_INIT( btoads )
41 {
42 tlc34076_reset(6);
43 }
44
45
46
47 /*************************************
48 *
49 * Main -> sound CPU communication
50 *
51 *************************************/
52
delayed_sound_w(int param)53 static void delayed_sound_w(int param)
54 {
55 main_to_sound_data = param;
56 main_to_sound_ready = 1;
57 cpu_triggerint(1);
58
59 /* use a timer to make long transfers faster */
60 timer_set(TIME_IN_USEC(50), 0, 0);
61 }
62
63
WRITE16_HANDLER(main_sound_w)64 static WRITE16_HANDLER( main_sound_w )
65 {
66 if (ACCESSING_LSB)
67 timer_set(TIME_NOW, data & 0xff, delayed_sound_w);
68 }
69
70
READ16_HANDLER(special_port_4_r)71 static READ16_HANDLER( special_port_4_r )
72 {
73 int result = readinputport(4) & ~0x81;
74
75 if (sound_to_main_ready)
76 result |= 0x01;
77 if (main_to_sound_ready)
78 result |= 0x80;
79 return result;
80 }
81
82
READ16_HANDLER(main_sound_r)83 static READ16_HANDLER( main_sound_r )
84 {
85 sound_to_main_ready = 0;
86 return sound_to_main_data;
87 }
88
89
90
91 /*************************************
92 *
93 * Sound -> main CPU communication
94 *
95 *************************************/
96
WRITE_HANDLER(sound_data_w)97 static WRITE_HANDLER( sound_data_w )
98 {
99 sound_to_main_data = data;
100 sound_to_main_ready = 1;
101 }
102
103
READ_HANDLER(sound_data_r)104 static READ_HANDLER( sound_data_r )
105 {
106 main_to_sound_ready = 0;
107 return main_to_sound_data;
108 }
109
110
READ_HANDLER(sound_ready_to_send_r)111 static READ_HANDLER( sound_ready_to_send_r )
112 {
113 return sound_to_main_ready ? 0x00 : 0x80;
114 }
115
116
READ_HANDLER(sound_data_ready_r)117 static READ_HANDLER( sound_data_ready_r )
118 {
119 if (activecpu_get_pc() == 0xd50 && !main_to_sound_ready)
120 cpu_spinuntil_int();
121 return main_to_sound_ready ? 0x00 : 0x80;
122 }
123
124
125
126 /*************************************
127 *
128 * Sound CPU interrupt generation
129 *
130 *************************************/
131
INTERRUPT_GEN(sound_interrupt)132 static INTERRUPT_GEN( sound_interrupt )
133 {
134 if (sound_int_state & 0x80)
135 {
136 cpu_set_irq_line(1, 0, ASSERT_LINE);
137 sound_int_state = 0x00;
138 }
139 }
140
141
WRITE_HANDLER(sound_int_state_w)142 static WRITE_HANDLER( sound_int_state_w )
143 {
144 if (!(sound_int_state & 0x80) && (data & 0x80))
145 cpu_set_irq_line(1, 0, CLEAR_LINE);
146
147 sound_int_state = data;
148 }
149
150
151
152 /*************************************
153 *
154 * Sound CPU BSMT2000 communication
155 *
156 *************************************/
157
READ_HANDLER(bsmt_ready_r)158 static READ_HANDLER( bsmt_ready_r )
159 {
160 return 0x80;
161 }
162
163
WRITE_HANDLER(bsmt2000_port_w)164 static WRITE_HANDLER( bsmt2000_port_w )
165 {
166 UINT16 reg = offset >> 8;
167 UINT16 val = ((offset & 0xff) << 8) | data;
168 BSMT2000_data_0_w(reg, val, 0);
169 }
170
171
172
173 /*************************************
174 *
175 * Speedup hack
176 *
177 *************************************/
178
READ16_HANDLER(main_speedup_r)179 static READ16_HANDLER( main_speedup_r )
180 {
181 int result = *main_speedup;
182 if (activecpu_get_pc() == 0xffd51a50 && result == 0)
183 cpu_spinuntil_int();
184 return result;
185 }
186
187
188
189 /*************************************
190 *
191 * Main CPU memory map
192 *
193 *************************************/
194
MEMORY_READ16_START(main_readmem)195 static MEMORY_READ16_START( main_readmem )
196 { TOBYTE(0x00000000), TOBYTE(0x003fffff), MRA16_RAM },
197 { TOBYTE(0x20000000), TOBYTE(0x2000007f), input_port_0_word_r },
198 { TOBYTE(0x20000080), TOBYTE(0x200000ff), input_port_1_word_r },
199 { TOBYTE(0x20000100), TOBYTE(0x2000017f), input_port_2_word_r },
200 { TOBYTE(0x20000180), TOBYTE(0x200001ff), input_port_3_word_r },
201 { TOBYTE(0x20000200), TOBYTE(0x2000027f), special_port_4_r },
202 { TOBYTE(0x20000280), TOBYTE(0x200002ff), input_port_5_word_r },
203 { TOBYTE(0x20000300), TOBYTE(0x2000037f), btoads_paletteram_r },
204 { TOBYTE(0x20000380), TOBYTE(0x200003ff), main_sound_r },
205 { TOBYTE(0x60000000), TOBYTE(0x6003ffff), MRA16_RAM },
206 { TOBYTE(0xa0000000), TOBYTE(0xa03fffff), btoads_vram_fg_display_r },
207 { TOBYTE(0xa4000000), TOBYTE(0xa43fffff), btoads_vram_fg_draw_r },
208 { TOBYTE(0xa8000000), TOBYTE(0xa87fffff), MRA16_RAM },
209 { TOBYTE(0xb0000000), TOBYTE(0xb03fffff), btoads_vram_bg0_r },
210 { TOBYTE(0xb4000000), TOBYTE(0xb43fffff), btoads_vram_bg1_r },
211 { TOBYTE(0xc0000000), TOBYTE(0xc00003ff), tms34020_io_register_r },
212 { TOBYTE(0xfc000000), TOBYTE(0xffffffff), MRA16_RAM },
213 MEMORY_END
214
215 static MEMORY_WRITE16_START( main_writemem )
216 { TOBYTE(0x00000000), TOBYTE(0x003fffff), MWA16_RAM },
217 { TOBYTE(0x20000000), TOBYTE(0x200000ff), MWA16_RAM, &btoads_sprite_scale },
218 { TOBYTE(0x20000100), TOBYTE(0x2000017f), MWA16_RAM, &btoads_sprite_control },
219 { TOBYTE(0x20000180), TOBYTE(0x200001ff), btoads_display_control_w },
220 { TOBYTE(0x20000200), TOBYTE(0x2000027f), btoads_scroll0_w },
221 { TOBYTE(0x20000280), TOBYTE(0x200002ff), btoads_scroll1_w },
222 { TOBYTE(0x20000300), TOBYTE(0x2000037f), btoads_paletteram_w },
223 { TOBYTE(0x20000380), TOBYTE(0x200003ff), main_sound_w },
224 { TOBYTE(0x20000400), TOBYTE(0x2000047f), btoads_misc_control_w },
225 { TOBYTE(0x40000000), TOBYTE(0x4000000f), MWA16_NOP }, /* watchdog? */
226 { TOBYTE(0x60000000), TOBYTE(0x6003ffff), MWA16_RAM, (data16_t **)&generic_nvram, &generic_nvram_size },
227 { TOBYTE(0xa0000000), TOBYTE(0xa03fffff), btoads_vram_fg_display_w, &btoads_vram_fg0 },
228 { TOBYTE(0xa4000000), TOBYTE(0xa43fffff), btoads_vram_fg_draw_w, &btoads_vram_fg1 },
229 { TOBYTE(0xa8000000), TOBYTE(0xa87fffff), MWA16_RAM, &btoads_vram_fg_data },
230 { TOBYTE(0xa8800000), TOBYTE(0xa8ffffff), MWA16_NOP },
231 { TOBYTE(0xb0000000), TOBYTE(0xb03fffff), btoads_vram_bg0_w, &btoads_vram_bg0 },
232 { TOBYTE(0xb4000000), TOBYTE(0xb43fffff), btoads_vram_bg1_w, &btoads_vram_bg1 },
233 { TOBYTE(0xc0000000), TOBYTE(0xc00003ff), tms34020_io_register_w },
234 { TOBYTE(0xfc000000), TOBYTE(0xffffffff), MWA16_ROM, &code_rom },
235 MEMORY_END
236
237
238
239 /*************************************
240 *
241 * Sound CPU memory map
242 *
243 *************************************/
244
245 static MEMORY_READ_START( sound_readmem )
246 { 0x0000, 0x7fff, MRA_ROM },
247 { 0x8000, 0xffff, MRA_RAM },
248 MEMORY_END
249
250 static MEMORY_WRITE_START( sound_writemem )
251 { 0x0000, 0x7fff, MWA_ROM },
252 { 0x8000, 0xffff, MWA_RAM },
253 MEMORY_END
254
255
256 static PORT_READ_START( sound_readport )
257 { 0x8000, 0x8000, sound_data_r },
258 { 0x8004, 0x8004, sound_data_ready_r },
259 { 0x8005, 0x8005, sound_ready_to_send_r },
260 { 0x8006, 0x8006, bsmt_ready_r },
261 MEMORY_END
262
263 static PORT_WRITE_START( sound_writeport )
264 { 0x0000, 0x7fff, bsmt2000_port_w },
265 { 0x8000, 0x8000, sound_data_w },
266 { 0x8002, 0x8002, sound_int_state_w },
267 MEMORY_END
268
269
270
271 /*************************************
272 *
273 * Input ports
274 *
275 *************************************/
276
277 INPUT_PORTS_START( btoads )
278 PORT_START
279 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER1 )
280 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER1 )
281 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER1 )
282 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER1 )
283 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
284 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
285 PORT_BIT_IMPULSE( 0x0040, IP_ACTIVE_LOW, IPT_COIN1, 2 )
286 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START1 )
287 PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
288
289 PORT_START
290 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER2 )
291 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER2 )
292 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER2 )
293 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER2 )
294 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
295 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
296 PORT_BIT_IMPULSE( 0x0040, IP_ACTIVE_LOW, IPT_COIN2, 2 )
297 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START2 )
298 PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
299
300 PORT_START
301 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER3 )
302 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER3 )
303 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER3 )
304 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER3 )
305 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER3 )
306 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER3 )
307 PORT_BIT_IMPULSE( 0x0040, IP_ACTIVE_LOW, IPT_COIN3, 2 )
308 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START3 )
309 PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
310
311 PORT_START
312 PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
313
314 PORT_START
315 PORT_SERVICE_NO_TOGGLE( 0x0002, IP_ACTIVE_LOW )
316 PORT_BIT( 0xfffd, IP_ACTIVE_LOW, IPT_UNKNOWN )
317
318 PORT_START
319 PORT_DIPNAME( 0x0001, 0x0000, DEF_STR( Demo_Sounds ))
320 PORT_DIPSETTING( 0x0001, DEF_STR( Off ))
321 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
322 PORT_DIPNAME( 0x0002, 0x0000, "Stereo")
323 PORT_DIPSETTING( 0x0002, DEF_STR( Off ))
324 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
325 PORT_DIPNAME( 0x0004, 0x0004, "Common Coin Mech")
326 PORT_DIPSETTING( 0x0004, DEF_STR( Off ))
327 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
328 PORT_DIPNAME( 0x0008, 0x0000, "Three Players")
329 PORT_DIPSETTING( 0x0008, DEF_STR( Off ))
330 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
331 PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Free_Play ))
332 PORT_DIPSETTING( 0x0010, DEF_STR( Off ))
333 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
334 PORT_DIPNAME( 0x0020, 0x0020, "Blood Free Mode")
335 PORT_DIPSETTING( 0x0020, DEF_STR( Off ))
336 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
337 PORT_DIPNAME( 0x0040, 0x0040, "Credit Retention")
338 PORT_DIPSETTING( 0x0040, DEF_STR( Off ))
339 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
340 PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ))
341 PORT_DIPSETTING( 0x0080, DEF_STR( Off ))
342 PORT_DIPSETTING( 0x0000, DEF_STR( On ))
343 PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
344 INPUT_PORTS_END
345
346
347
348 /*************************************
349 *
350 * 34010 configuration
351 *
352 *************************************/
353
354 static struct tms34010_config cpu_config =
355 {
356 0, /* halt on reset */
357 NULL, /* generate interrupt */
358 btoads_to_shiftreg, /* write to shiftreg function */
359 btoads_from_shiftreg, /* read from shiftreg function */
360 0, /* display address changed */
361 0 /* display interrupt callback */
362 };
363
364
365
366 /*************************************
367 *
368 * Sound definitions
369 *
370 *************************************/
371
372 static struct BSMT2000interface bsmt2000_interface =
373 {
374 1,
375 { 24000000 },
376 { 12 },
377 { REGION_SOUND1 },
378 { 100 }
379 };
380
381
382
383 /*************************************
384 *
385 * Machine drivers
386 *
387 *************************************/
388
389 static MACHINE_DRIVER_START( btoads )
390
391 MDRV_CPU_ADD(TMS34020, 40000000/TMS34020_CLOCK_DIVIDER)
MDRV_CPU_CONFIG(cpu_config)392 MDRV_CPU_CONFIG(cpu_config)
393 MDRV_CPU_MEMORY(main_readmem,main_writemem)
394
395 MDRV_CPU_ADD(Z80, 4000000)
396 MDRV_CPU_FLAGS(CPU_16BIT_PORT)
397 MDRV_CPU_MEMORY(sound_readmem,sound_writemem)
398 MDRV_CPU_PORTS(sound_readport,sound_writeport)
399 MDRV_CPU_PERIODIC_INT(sound_interrupt,183)
400
401 MDRV_MACHINE_INIT(btoads)
402 MDRV_FRAMES_PER_SECOND(60)
403 MDRV_VBLANK_DURATION((1000000 * (256 - 224)) / (60 * 256))
404 MDRV_NVRAM_HANDLER(generic_1fill)
405
406 /* video hardware */
407 MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
408 MDRV_SCREEN_SIZE(512,256)
409 MDRV_VISIBLE_AREA(0,511, 0,223)
410 MDRV_PALETTE_LENGTH(256)
411
412 MDRV_VIDEO_START(btoads)
413 MDRV_VIDEO_UPDATE(btoads)
414
415 /* sound hardware */
416 MDRV_SOUND_ATTRIBUTES(SOUND_SUPPORTS_STEREO)
417 MDRV_SOUND_ADD(BSMT2000, bsmt2000_interface)
418 MACHINE_DRIVER_END
419
420
421
422 /*************************************
423 *
424 * ROM definitions
425 *
426 *************************************/
427
428 ROM_START( btoads )
429 ROM_REGION( TOBYTE(0x400000), REGION_CPU1, 0 ) /* 34020 dummy region */
430
431 ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* sound program */
432 ROM_LOAD( "btu102.bin", 0x0000, 0x8000, CRC(a90b911a) SHA1(6ec25161e68df1c9870d48cc2b1f85cd1a49aba9) )
433
434 ROM_REGION16_LE( 0x800000, REGION_USER1, ROMREGION_DISPOSE ) /* 34020 code */
435 ROM_LOAD32_WORD( "btu120.bin", 0x000000, 0x400000, CRC(0dfd1e35) SHA1(733a0a4235bebd598c600f187ed2628f28cf9bd0) )
436 ROM_LOAD32_WORD( "btu121.bin", 0x000002, 0x400000, CRC(df7487e1) SHA1(67151b900767bb2653b5261a98c81ff8827222c3) )
437
438 ROM_REGION( 0x200000, REGION_SOUND1, 0 ) /* BSMT data */
439 ROM_LOAD( "btu109.bin", 0x00000, 0x200000, CRC(d9612ddb) SHA1(f186dfb013e81abf81ba8ac5dc7eb731c1ad82b6) )
440 ROM_END
441
442
443
444 /*************************************
445 *
446 * Driver init
447 *
448 *************************************/
449
450 static DRIVER_INIT( btoads )
451 {
452 /* set up code ROMs */
453 memcpy(code_rom, memory_region(REGION_USER1), memory_region_length(REGION_USER1));
454
455 /* install main CPU speedup */
456 main_speedup = install_mem_read16_handler(0, TOBYTE(0x22410), TOBYTE(0x2241f), main_speedup_r);
457 }
458
459
460
461 /*************************************
462 *
463 * Game drivers
464 *
465 *************************************/
466
467 GAME( 1994, btoads, 0, btoads, btoads, btoads, ROT0, "Rare", "Battle Toads" )
468