1 #include "../vidhrdw/thunderj.c"
2 
3 /***************************************************************************
4 
5 	Thunderjaws
6 
7     driver by Aaron Giles
8 
9 ****************************************************************************/
10 
11 #include "driver.h"
12 #include "machine/atarigen.h"
13 #include "sndhrdw/atarijsa.h"
14 #include "vidhrdw/generic.h"
15 
16 
17 void thunderj_set_alpha_bank(int bank);
18 WRITE_HANDLER( thunderj_playfieldram_w );
19 WRITE_HANDLER( thunderj_playfield2ram_w );
20 WRITE_HANDLER( thunderj_colorram_w );
21 
22 int thunderj_vh_start(void);
23 void thunderj_vh_stop(void);
24 void thunderj_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
25 
26 void thunderj_scanline_update(int scanline);
27 
28 
29 static UINT8 *rts_address;
30 
31 
32 
33 /*************************************
34  *
35  *	Initialization
36  *
37  *************************************/
38 
update_interrupts(void)39 static void update_interrupts(void)
40 {
41 	int newstate = 0;
42 	int newstate2 = 0;
43 
44 	if (atarigen_scanline_int_state)
45 		newstate |= 4, newstate2 |= 4;
46 	if (atarigen_sound_int_state)
47 		newstate |= 6;
48 
49 	if (newstate)
50 		cpu_set_irq_line(0, newstate, ASSERT_LINE);
51 	else
52 		cpu_set_irq_line(0, 7, CLEAR_LINE);
53 
54 	if (newstate2)
55 		cpu_set_irq_line(1, newstate2, ASSERT_LINE);
56 	else
57 		cpu_set_irq_line(1, 7, CLEAR_LINE);
58 }
59 
60 
init_machine(void)61 static void init_machine(void)
62 {
63 	atarigen_eeprom_reset();
64 	atarigen_video_control_reset();
65 	atarigen_interrupt_reset(update_interrupts);
66 	atarigen_scanline_timer_reset(thunderj_scanline_update, 8);
67 	atarijsa_reset();
68 }
69 
70 
71 
72 /*************************************
73  *
74  *	I/O handling
75  *
76  *************************************/
77 
READ_HANDLER(special_port2_r)78 static READ_HANDLER( special_port2_r )
79 {
80 	int result = input_port_2_r(offset);
81 
82 	if (atarigen_sound_to_cpu_ready) result ^= 0x0004;
83 	if (atarigen_cpu_to_sound_ready) result ^= 0x0008;
84 	result ^= 0x0010;
85 
86 	return result;
87 }
88 
89 
WRITE_HANDLER(latch_w)90 static WRITE_HANDLER( latch_w )
91 {
92 	/* reset extra CPU */
93 	if (!(data & 0x00ff0000))
94 	{
95 		/* 0 means hold CPU 2's reset low */
96 		if (data & 1)
97 			cpu_set_reset_line(1,CLEAR_LINE);
98 		else
99 			cpu_set_reset_line(1,ASSERT_LINE);
100 
101 		/* bits 2-5 are the alpha bank */
102 		thunderj_set_alpha_bank((data >> 2) & 7);
103 	}
104 }
105 
106 
107 
108 /*************************************
109  *
110  *	Video Controller Hack
111  *
112  *************************************/
113 
READ_HANDLER(thunderj_video_control_r)114 READ_HANDLER( thunderj_video_control_r )
115 {
116 	/* Sigh. CPU #1 reads the video controller register twice per frame, once at
117 	   the beginning of interrupt and once near the end. It stores these values in a
118 	   table starting at $163484. CPU #2 periodically looks at this table to make
119 	   sure that it is getting interrupts at the appropriate times, and that the
120 	   VBLANK bit is set appropriately. Unfortunately, due to all the cpu_yield()
121 	   calls we make to synchronize the two CPUs, we occasionally get out of time
122 	   and generate the interrupt outside of the tight tolerances CPU #2 expects.
123 
124 	   So we fake it. Returning scanlines $f5 and $f7 alternately provides the
125 	   correct answer that causes CPU #2 to be happy and not aggressively trash
126 	   memory (which is what it does if this interrupt test fails -- see the code
127 	   at $1E56 to see!) */
128 
129 	/* Use these lines to detect when things go south:
130 
131 	if (cpu_readmem24bew_word(0x163482) > 0xfff)
132 		printf("You're screwed!");*/
133 
134 	return atarigen_video_control_r(offset);
135 }
136 
137 
138 
139 /*************************************
140  *
141  *	Main CPU memory handlers
142  *
143  *************************************/
144 
145 static struct MemoryReadAddress main_readmem[] =
146 {
147 	{ 0x000000, 0x09ffff, MRA_ROM },
148 	{ 0x0e0000, 0x0e0fff, atarigen_eeprom_r },
149 	{ 0x160000, 0x16ffff, MRA_BANK1 },
150 	{ 0x260000, 0x26000f, input_port_0_r },
151 	{ 0x260010, 0x260011, input_port_1_r },
152 	{ 0x260012, 0x260013, special_port2_r },
153 	{ 0x260030, 0x260031, atarigen_sound_r },
154 	{ 0x3e0000, 0x3e0fff, paletteram_word_r },
155 	{ 0x3effc0, 0x3effff, thunderj_video_control_r },
156 	{ 0x3f0000, 0x3f5fff, MRA_BANK3 },
157 	{ 0x3f6000, 0x3f7fff, MRA_BANK4 },
158 	{ 0x3f8000, 0x3f8fff, MRA_BANK5 },
159 	{ 0x3f9000, 0x3fffff, MRA_BANK6 },
160 	{ 0x800000, 0x800001, MRA_BANK7 },
161 	{ -1 }  /* end of table */
162 };
163 
164 
165 static struct MemoryWriteAddress main_writemem[] =
166 {
167 	{ 0x000000, 0x09ffff, MWA_ROM },
168 	{ 0x0e0000, 0x0e0fff, atarigen_eeprom_w, &atarigen_eeprom, &atarigen_eeprom_size },
169 	{ 0x160000, 0x16ffff, MWA_BANK1 },
170 	{ 0x1f0000, 0x1fffff, atarigen_eeprom_enable_w },
171 	{ 0x2e0000, 0x2e0001, watchdog_reset_w },
172 	{ 0x360010, 0x360011, latch_w },
173 	{ 0x360020, 0x360021, atarigen_sound_reset_w },
174 	{ 0x360030, 0x360031, atarigen_sound_w },
175 	{ 0x3e0000, 0x3e0fff, atarigen_666_paletteram_w, &paletteram },
176 	{ 0x3effc0, 0x3effff, atarigen_video_control_w, &atarigen_video_control_data },
177 	{ 0x3f0000, 0x3f1fff, thunderj_playfield2ram_w, &atarigen_playfield2ram, &atarigen_playfield2ram_size },
178 	{ 0x3f2000, 0x3f3fff, thunderj_playfieldram_w, &atarigen_playfieldram, &atarigen_playfieldram_size },
179 	{ 0x3f4000, 0x3f5fff, thunderj_colorram_w, &atarigen_playfieldram_color },
180 	{ 0x3f6000, 0x3f7fff, MWA_BANK4, &atarigen_spriteram, &atarigen_spriteram_size },
181 	{ 0x3f8000, 0x3f8fff, MWA_BANK5, &atarigen_alpharam, &atarigen_alpharam_size },
182 	{ 0x3f9000, 0x3fffff, MWA_BANK6 },
183 	{ 0x800000, 0x800001, MWA_BANK7, &rts_address },
184 	{ -1 }  /* end of table */
185 };
186 
187 
188 
189 /*************************************
190  *
191  *	Extra CPU memory handlers
192  *
193  *************************************/
194 
195 static struct MemoryReadAddress extra_readmem[] =
196 {
197 	{ 0x000000, 0x03ffff, MRA_ROM },
198 	{ 0x060000, 0x07ffff, MRA_ROM },
199 	{ 0x160000, 0x16ffff, MRA_BANK1 },
200 	{ 0x260000, 0x26000f, input_port_0_r },
201 	{ 0x260010, 0x260011, input_port_1_r },
202 	{ 0x260012, 0x260013, special_port2_r },
203 	{ 0x260030, 0x260031, atarigen_sound_r },
204 	{ -1 }  /* end of table */
205 };
206 
207 
208 static struct MemoryWriteAddress extra_writemem[] =
209 {
210 	{ 0x000000, 0x03ffff, MWA_ROM },
211 	{ 0x060000, 0x07ffff, MWA_ROM },
212 	{ 0x160000, 0x16ffff, MWA_BANK1 },
213 	{ 0x360000, 0x360001, atarigen_video_int_ack_w },
214 	{ 0x360010, 0x360011, latch_w },
215 	{ 0x360020, 0x360021, atarigen_sound_reset_w },
216 	{ 0x360030, 0x360031, atarigen_sound_w },
217 	{ -1 }  /* end of table */
218 };
219 
220 
221 
222 /*************************************
223  *
224  *	Port definitions
225  *
226  *************************************/
227 
228 INPUT_PORTS_START( thunderj )
229 	PORT_START		/* 260000 */
230 	PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
231 
232 	PORT_START		/* 260010 */
233 	PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
234 	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
235 	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
236 	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
237 	PORT_BIT( 0x0c00, IP_ACTIVE_LOW, IPT_UNUSED )
238 	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER1 )
239 	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER1 )
240 	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER1 )
241 	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER1 )
242 
243 	PORT_START		/* 260012 */
244 	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_VBLANK )
245 	PORT_SERVICE( 0x0002, IP_ACTIVE_LOW )
246 	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED )	/* Input buffer full (@260030) */
247 	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )	/* Output buffer full (@360030) */
248 	PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNUSED )
249 	PORT_BIT( 0x00e0, IP_ACTIVE_LOW, IPT_UNUSED )
250 	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )
251 	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
252 	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
253 	PORT_BIT( 0x0c00, IP_ACTIVE_LOW, IPT_UNUSED )
254 	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER2 )
255 	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER2 )
256 	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER2 )
257 	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER2 )
258 
259 	JSA_II_PORT		/* audio board port */
260 INPUT_PORTS_END
261 
262 
263 
264 /*************************************
265  *
266  *	Graphics definitions
267  *
268  *************************************/
269 
270 static struct GfxLayout anlayout =
271 {
272 	8,8,	/* 8*8 chars */
273 	4096,	/* 4096 chars */
274 	2,		/* 2 bits per pixel */
275 	{ 0, 4 },
276 	{ 0, 1, 2, 3, 8, 9, 10, 11 },
277 	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
278 	8*16	/* every char takes 16 consecutive bytes */
279 };
280 
281 
282 static struct GfxLayout pfmolayout =
283 {
284 	8,8,	/* 8*8 sprites */
285 	32768,	/* 32768 of them */
286 	4,		/* 4 bits per pixel */
287 	{ 3*8*0x40000, 2*8*0x40000, 1*8*0x40000, 0*8*0x40000 },
288 	{ 0, 1, 2, 3, 4, 5, 6, 7 },
289 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
290 	8*8	/* every sprite takes 8 consecutive bytes */
291 };
292 
293 
294 static struct GfxDecodeInfo gfxdecodeinfo[] =
295 {
296 	{ REGION_GFX1, 0, &pfmolayout,  512,  96 },	/* sprites & playfield */
297 	{ REGION_GFX2, 0, &pfmolayout,  256, 112 },	/* sprites & playfield */
298 	{ REGION_GFX3, 0, &anlayout,      0, 512 },	/* characters 8x8 */
299 	{ -1 } /* end of array */
300 };
301 
302 
303 
304 /*************************************
305  *
306  *	Machine driver
307  *
308  *************************************/
309 
310 static struct MachineDriver machine_driver_thunderj =
311 {
312 	/* basic machine hardware */
313 	{
314 		{
315 			CPU_M68000,		/* verified */
316 			ATARI_CLOCK_14MHz/2,
317 			main_readmem,main_writemem,0,0,
318 			ignore_interrupt,1
319 		},
320 		{
321 			CPU_M68000,		/* verified */
322 			ATARI_CLOCK_14MHz/2,
323 			extra_readmem,extra_writemem,0,0,
324 			ignore_interrupt,1
325 		},
326 		JSA_II_CPU
327 	},
328 	60, DEFAULT_REAL_60HZ_VBLANK_DURATION,	/* frames per second, vblank duration */
329 	100,
330 	init_machine,
331 
332 	/* video hardware */
333 	42*8, 30*8, { 0*8, 42*8-1, 0*8, 30*8-1 },
334 	gfxdecodeinfo,
335 	2048, 2048,
336 	0,
337 
338 	VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE | VIDEO_UPDATE_BEFORE_VBLANK,
339 	0,
340 	thunderj_vh_start,
341 	thunderj_vh_stop,
342 	thunderj_vh_screenrefresh,
343 
344 	/* sound hardware */
345 	JSA_II_MONO(REGION_SOUND1),
346 
347 	atarigen_nvram_handler
348 };
349 
350 
351 
352 /*************************************
353  *
354  *	ROM decoding
355  *
356  *************************************/
357 
rom_decode(void)358 static void rom_decode(void)
359 {
360 	int i;
361 
362 	/* invert the graphics bits on the playfield and motion objects */
363 	for (i = 0; i < memory_region_length(REGION_GFX1); i++)
364 		memory_region(REGION_GFX1)[i] ^= 0xff;
365 	for (i = 0; i < memory_region_length(REGION_GFX2); i++)
366 		memory_region(REGION_GFX2)[i] ^= 0xff;
367 
368 	/* copy the shared ROM from region 0 to region 1 */
369 	memcpy(&memory_region(REGION_CPU2)[0x60000], &memory_region(REGION_CPU1)[0x60000], 0x20000);
370 }
371 
372 
373 
374 /*************************************
375  *
376  *	Driver initialization
377  *
378  *************************************/
379 
init_thunderj(void)380 static void init_thunderj(void)
381 {
382 	atarigen_eeprom_default = NULL;
383 
384 	atarijsa_init(2, 3, 2, 0x0002);
385 
386 	/* speed up the 6502 */
387 	atarigen_init_6502_speedup(2, 0x4159, 0x4171);
388 
389 	/* it looks like they jsr to $800000 as some kind of protection */
390 	/* put an RTS there so we don't die */
391 	WRITE_WORD(rts_address, 0x4E75);
392 
393 	/* display messages */
394 	atarigen_show_sound_message();
395 
396 	rom_decode();
397 }
398 
399 
400 
401 /*************************************
402  *
403  *	ROM definition(s)
404  *
405  *************************************/
406 
407 ROM_START( thunderj )
408 	ROM_REGION( 0xa0000, REGION_CPU1 )	/* 10*64k for 68000 code */
409 	ROM_LOAD_EVEN( "2001.14e",   0x00000, 0x10000, 0xf6a71532 )
410 	ROM_LOAD_ODD ( "2002.14c",   0x00000, 0x10000, 0x173ec10d )
411 	ROM_LOAD_EVEN( "2003.15e",   0x20000, 0x10000, 0x6e155469 )
412 	ROM_LOAD_ODD ( "2004.15c",   0x20000, 0x10000, 0xe9ff1e42 )
413 	ROM_LOAD_EVEN( "2005.16e",   0x40000, 0x10000, 0xa40242e7 )
414 	ROM_LOAD_ODD ( "2006.16c",   0x40000, 0x10000, 0xaa18b94c )
415 	ROM_LOAD_EVEN( "1005.15h",   0x60000, 0x10000, 0x05474ebb )
416 	ROM_LOAD_ODD ( "1010.16h",   0x60000, 0x10000, 0xccff21c8 )
417 	ROM_LOAD_EVEN( "1007.17e",   0x80000, 0x10000, 0x9c2a8aba )
418 	ROM_LOAD_ODD ( "1008.17c",   0x80000, 0x10000, 0x22109d16 )
419 
420 	ROM_REGION( 0x80000, REGION_CPU2 )	/* 8*64k for 68000 code */
421 	ROM_LOAD_EVEN( "1011.17l",   0x00000, 0x10000, 0xbbbbca45 )
422 	ROM_LOAD_ODD ( "1012.17n",   0x00000, 0x10000, 0x53e5e638 )
423 
424 	ROM_REGION( 0x14000, REGION_CPU3 )	/* 64k + 16k for 6502 code */
425 	ROM_LOAD( "tjw65snd.bin",  0x10000, 0x4000, 0xd8feb7fb )
426 	ROM_CONTINUE(              0x04000, 0xc000 )
427 
428 	ROM_REGION( 0x100000, REGION_GFX1 | REGIONFLAG_DISPOSE )
429 	ROM_LOAD( "1021.5s",   0x000000, 0x10000, 0xd8432766 )	/* graphics, plane 0 */
430 	ROM_LOAD( "1025.5r",   0x010000, 0x10000, 0x839feed5 )
431 	ROM_LOAD( "1029.3p",   0x020000, 0x10000, 0xfa887662 )
432 	ROM_LOAD( "1033.6p",   0x030000, 0x10000, 0x2addda79 )
433 	ROM_LOAD( "1022.9s",   0x040000, 0x10000, 0xdcf50371 )	/* graphics, plane 1 */
434 	ROM_LOAD( "1026.9r",   0x050000, 0x10000, 0x216e72c8 )
435 	ROM_LOAD( "1030.10s",  0x060000, 0x10000, 0xdc51f606 )
436 	ROM_LOAD( "1034.10r",  0x070000, 0x10000, 0xf8e35516 )
437 	ROM_LOAD( "1023.13s",  0x080000, 0x10000, 0xb6dc3f13 )	/* graphics, plane 2 */
438 	ROM_LOAD( "1027.13r",  0x090000, 0x10000, 0x621cc2ce )
439 	ROM_LOAD( "1031.14s",  0x0a0000, 0x10000, 0x4682ceb5 )
440 	ROM_LOAD( "1035.14r",  0x0b0000, 0x10000, 0x7a0e1b9e )
441 	ROM_LOAD( "1024.17s",  0x0c0000, 0x10000, 0xd84452b5 )	/* graphics, plane 3 */
442 	ROM_LOAD( "1028.17r",  0x0d0000, 0x10000, 0x0cc20245 )
443 	ROM_LOAD( "1032.14p",  0x0e0000, 0x10000, 0xf639161a )
444 	ROM_LOAD( "1036.16p",  0x0f0000, 0x10000, 0xb342443d )
445 
446 	ROM_REGION( 0x100000, REGION_GFX2 | REGIONFLAG_DISPOSE )
447 	ROM_LOAD( "1037.2s",   0x000000, 0x10000, 0x07addba6 )
448 	ROM_LOAD( "1041.2r",   0x010000, 0x10000, 0x1e9c29e4 )
449 	ROM_LOAD( "1045.34s",  0x020000, 0x10000, 0xe7235876 )
450 	ROM_LOAD( "1049.34r",  0x030000, 0x10000, 0xa6eb8265 )
451 	ROM_LOAD( "1038.6s",   0x040000, 0x10000, 0x2ea543f9 )
452 	ROM_LOAD( "1042.6r",   0x050000, 0x10000, 0xefabdc2b )
453 	ROM_LOAD( "1046.7s",   0x060000, 0x10000, 0x6692151f )
454 	ROM_LOAD( "1050.7r",   0x070000, 0x10000, 0xad7bb5f3 )
455 	ROM_LOAD( "1039.11s",  0x080000, 0x10000, 0xcb563a40 )
456 	ROM_LOAD( "1043.11r",  0x090000, 0x10000, 0xb7565eee )
457 	ROM_LOAD( "1047.12s",  0x0a0000, 0x10000, 0x60877136 )
458 	ROM_LOAD( "1051.12r",  0x0b0000, 0x10000, 0xd4715ff0 )
459 	ROM_LOAD( "1040.15s",  0x0c0000, 0x10000, 0x6e910fc2 )
460 	ROM_LOAD( "1044.15r",  0x0d0000, 0x10000, 0xff67a17a )
461 	ROM_LOAD( "1048.16s",  0x0e0000, 0x10000, 0x200d45b3 )
462 	ROM_LOAD( "1052.16r",  0x0f0000, 0x10000, 0x74711ef1 )
463 
464 	ROM_REGION( 0x010000, REGION_GFX3 | REGIONFLAG_DISPOSE )
465 	ROM_LOAD( "1020.4m",   0x000000, 0x10000, 0x65470354 )	/* alphanumerics */
466 
467 	ROM_REGION( 0x40000, REGION_SOUND1 )	/* 256k for ADPCM */
468 	ROM_LOAD( "tj1016.bin",  0x00000, 0x10000, 0xc10bdf73 )
469 	ROM_LOAD( "tj1017.bin",  0x10000, 0x10000, 0x4e5e25e8 )
470 	ROM_LOAD( "tj1018.bin",  0x20000, 0x10000, 0xec81895d )
471 	ROM_LOAD( "tj1019.bin",  0x30000, 0x10000, 0xa4009037 )
472 ROM_END
473 
474 
475 
476 GAME( 1990, thunderj, 0, thunderj, thunderj, thunderj, ROT0, "Atari Games", "ThunderJaws" )
477