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