1 /****************************************************************************
2 
3 Operation Wolf  (c) Taito 1987
4 ==============
5 
6 David Graves, Jarek Burczynski
7 C-Chip emulation by Bryan McPhail
8 
9 Sources:        MAME Rastan driver
10             MAME Taito F2 driver
11             Raine source - many thanks to Richard Bush
12               and the Raine Team.
13 
14 Main CPU: MC68000 uses irq 5.
15 Sound   : Z80 & YM2151 & MSM5205
16 
17 
18 Operation Wolf uses similar hardware to Rainbow Islands and Rastan.
19 The screen layout and registers and sprites appear to be identical.
20 
21 
22 Gun Travel
23 ----------
24 
25 Horizontal gun travel maybe could be widened to include more
26 of the status bar (you can shoot enemies underneath it).
27 
28 To keep the input span 0-255 a multiplier (300/256 ?)
29 would be used.
30 
31 
32 TODO
33 ====
34 
35 There are a few unmapped writes for the sound Z80 in the log.
36 
37 Unknown writes to the MSM5205 control addresses
38 
39 Raine source has standard Asuka/Mofflot sprite/tile priority:
40 0x2000 in sprite_ctrl puts all sprites under top bg layer. But
41 Raine simply kludges in this value, failing to read it from a
42 register. So what is controlling priority.
43 
44 
45 ***************************************************************************/
46 
47 #include "driver.h"
48 #include "state.h"
49 #include "vidhrdw/generic.h"
50 #include "vidhrdw/taitoic.h"
51 #include "sndhrdw/taitosnd.h"
52 
53 
54 static data8_t *cchip_ram;
55 static UINT8 adpcm_b[0x08];
56 static UINT8 adpcm_c[0x08];
57 static int opwolf_gun_xoffs, opwolf_gun_yoffs;
58 
59 void opwolf_cchip_init(void);
60 
61 READ16_HANDLER( opwolf_cchip_status_r );
62 READ16_HANDLER( opwolf_cchip_data_r );
63 WRITE16_HANDLER( opwolf_cchip_status_w );
64 WRITE16_HANDLER( opwolf_cchip_data_w );
65 WRITE16_HANDLER( opwolf_cchip_bank_w );
66 WRITE16_HANDLER( rainbow_spritectrl_w );
67 WRITE16_HANDLER( rastan_spriteflip_w );
68 VIDEO_START( opwolf );
69 VIDEO_UPDATE( opwolf );
70 
READ16_HANDLER(cchip_r)71 static READ16_HANDLER( cchip_r )
72 {
73 	return cchip_ram[offset];
74 }
75 
WRITE16_HANDLER(cchip_w)76 static WRITE16_HANDLER( cchip_w )
77 {
78 	cchip_ram[offset] = data &0xff;
79 }
80 
81 /**********************************************************
82 				GAME INPUTS
83 **********************************************************/
84 
READ16_HANDLER(opwolf_lightgun_r)85 static READ16_HANDLER( opwolf_lightgun_r )
86 {
87 	int scaled;
88 
89 	switch (offset)
90 	{
91 		case 0x00:	/* P1X - Have to remap 8 bit input value, into 0-319 visible range */
92 			scaled=(input_port_4_word_r(0,mem_mask) * 320 ) / 256;
93 			return (scaled + 0x15 + opwolf_gun_xoffs);
94 		case 0x01:	/* P1Y */
95 			return (input_port_5_word_r(0,mem_mask) - 0x24 + opwolf_gun_yoffs);
96 	}
97 
98 	return 0xff;
99 }
100 
READ_HANDLER(z80_input1_r)101 static READ_HANDLER( z80_input1_r )
102 {
103 	return input_port_0_word_r(0,0);	/* irrelevant mirror ? */
104 }
105 
READ_HANDLER(z80_input2_r)106 static READ_HANDLER( z80_input2_r )
107 {
108 	return input_port_0_word_r(0,0);	/* needed for coins */
109 }
110 
111 
112 /******************************************************
113 				SOUND
114 ******************************************************/
115 
WRITE_HANDLER(sound_bankswitch_w)116 static WRITE_HANDLER( sound_bankswitch_w )
117 {
118 	cpu_setbank( 10, memory_region(REGION_CPU2) + ((data-1) & 0x03) * 0x4000 + 0x10000 );
119 }
120 
121 /***********************************************************
122              MEMORY STRUCTURES
123 ***********************************************************/
124 
MEMORY_READ16_START(opwolf_readmem)125 static MEMORY_READ16_START( opwolf_readmem )
126     { 0x000000, 0x03ffff, MRA16_ROM },
127 	{ 0x0f0000, 0x0f07ff, opwolf_cchip_data_r },
128 	{ 0x0ff000, 0x0ff7ff, opwolf_cchip_data_r }, /* mirror of cchip read*/
129 	{ 0x0f0802, 0x0f0803, opwolf_cchip_status_r },
130 	{ 0x0ff802, 0x0ff803, opwolf_cchip_status_r }, /* mirror of cchip read*/
131 	{ 0x100000, 0x107fff, MRA16_RAM },	/* RAM */
132 	{ 0x200000, 0x200fff, paletteram16_word_r },
133 	{ 0x380000, 0x380001, input_port_2_word_r },	/* DSW A */
134 	{ 0x380002, 0x380003, input_port_3_word_r },	/* DSW B */
135 	{ 0x3a0000, 0x3a0003, opwolf_lightgun_r },	/* lightgun, read at $11e0/6 */
136 	{ 0x3e0000, 0x3e0001, MRA16_NOP },
137 	{ 0x3e0002, 0x3e0003, taitosound_comm16_msb_r },
138 	{ 0xc00000, 0xc0ffff, PC080SN_word_0_r },
139 	{ 0xd00000, 0xd03fff, PC090OJ_word_0_r },	/* sprite ram */
140 MEMORY_END
141 
142 static MEMORY_WRITE16_START( opwolf_writemem )
143     { 0x000000, 0x03ffff, MWA16_ROM },
144 	{ 0x0ff000, 0x0ff7ff, opwolf_cchip_data_w },
145 	{ 0x0ff802, 0x0ff803, opwolf_cchip_status_w },
146 	{ 0x0ffc00, 0x0ffc01, opwolf_cchip_bank_w },
147 	{ 0x100000, 0x107fff, MWA16_RAM },
148 	{ 0x200000, 0x200fff, paletteram16_xxxxRRRRGGGGBBBB_word_w, &paletteram16 },
149 	{ 0x380000, 0x380003, rainbow_spritectrl_w },	/* usually 0x4, changes when you fire */
150 	{ 0x3c0000, 0x3c0001, MWA16_NOP },	/* watchdog ?? */
151 	{ 0x3e0000, 0x3e0001, taitosound_port16_msb_w },
152 	{ 0x3e0002, 0x3e0003, taitosound_comm16_msb_w },
153 	{ 0xc00000, 0xc0ffff, PC080SN_word_0_w },
154 	{ 0xc10000, 0xc1ffff, MWA16_RAM },	/* error in init code (?) */
155 	{ 0xc20000, 0xc20003, PC080SN_yscroll_word_0_w },
156 	{ 0xc40000, 0xc40003, PC080SN_xscroll_word_0_w },
157 	{ 0xc50000, 0xc50003, PC080SN_ctrl_word_0_w },
158 	{ 0xd00000, 0xd03fff, PC090OJ_word_0_w },	/* sprite ram */
159 MEMORY_END
160 
161 
162 static MEMORY_READ16_START( opwolfb_readmem )
163     { 0x000000, 0x03ffff, MRA16_ROM },
164 	{ 0x0f0008, 0x0f0009, input_port_0_word_r },	/* IN0 */
165 	{ 0x0f000a, 0x0f000b, input_port_1_word_r },	/* IN1 */
166 	{ 0x0ff000, 0x0fffff, cchip_r },
167 	{ 0x100000, 0x107fff, MRA16_RAM },	/* RAM */
168 	{ 0x200000, 0x200fff, paletteram16_word_r },
169 	{ 0x380000, 0x380001, input_port_2_word_r },	/* DSW A */
170     { 0x380002, 0x380003, input_port_3_word_r },	/* DSW B */
171 	{ 0x3a0000, 0x3a0003, opwolf_lightgun_r },	/* lightgun, read at $11e0/6 */
172 	{ 0x3e0000, 0x3e0001, MRA16_NOP },
173 	{ 0x3e0002, 0x3e0003, taitosound_comm16_msb_r },
174 	{ 0xc00000, 0xc0ffff, PC080SN_word_0_r },
175 	{ 0xd00000, 0xd03fff, PC090OJ_word_0_r },	/* sprite ram */
176 MEMORY_END
177 
178 static MEMORY_WRITE16_START( opwolfb_writemem )
179     { 0x000000, 0x03ffff, MWA16_ROM },
180 	{ 0x0ff000, 0x0fffff, cchip_w },
181 	{ 0x100000, 0x107fff, MWA16_RAM },
182 	{ 0x200000, 0x200fff, paletteram16_xxxxRRRRGGGGBBBB_word_w, &paletteram16 },
183 	{ 0x380000, 0x380003, rainbow_spritectrl_w },	/* usually 0x4, changes when you fire */
184 	{ 0x3c0000, 0x3c0001, MWA16_NOP },	/* watchdog ?? */
185 	{ 0x3e0000, 0x3e0001, taitosound_port16_msb_w },
186 	{ 0x3e0002, 0x3e0003, taitosound_comm16_msb_w },
187 	{ 0xc00000, 0xc0ffff, PC080SN_word_0_w },
188 	{ 0xc10000, 0xc1ffff, MWA16_RAM },	/* error in init code (?) */
189 	{ 0xc20000, 0xc20003, PC080SN_yscroll_word_0_w },
190 	{ 0xc40000, 0xc40003, PC080SN_xscroll_word_0_w },
191 	{ 0xc50000, 0xc50003, PC080SN_ctrl_word_0_w },
192 	{ 0xd00000, 0xd03fff, PC090OJ_word_0_w },	/* sprite ram */
193 MEMORY_END
194 
195 /***************************************************************************
196     This extra Z80 substitutes for the c-chip in the bootleg
197  */
198 
199 static MEMORY_READ_START( sub_z80_readmem )
200     { 0x0000, 0x7fff, MRA_ROM },
201 	{ 0x8800, 0x8800, z80_input1_r },	/* read at PC=$637: poked to $c004 */
202 	{ 0x9800, 0x9800, z80_input2_r },	/* read at PC=$631: poked to $c005 */
203 	{ 0xc000, 0xc7ff, MRA_RAM },
204 MEMORY_END
205 
206 static MEMORY_WRITE_START( sub_z80_writemem )
207     { 0x0000, 0x7fff, MWA_ROM },
208 	{ 0x9000, 0x9000, MWA_NOP },	/* unknown write, 0 then 1 each interrupt */
209 	{ 0xa000, 0xa000, MWA_NOP },	/* IRQ acknowledge (unimplemented) */
210 	{ 0xc000, 0xc7ff, MWA_RAM, &cchip_ram },
211 MEMORY_END
212 
213 /***************************************************************************/
214 
215 static MEMORY_READ_START( z80_readmem )
216     { 0x0000, 0x3fff, MRA_ROM },
217 	{ 0x4000, 0x7fff, MRA_BANK10 },
218 	{ 0x8000, 0x8fff, MRA_RAM },
219 	{ 0x9001, 0x9001, YM2151_status_port_0_r },
220 	{ 0x9002, 0x9100, MRA_RAM },
221 	{ 0xa001, 0xa001, taitosound_slave_comm_r },
222 MEMORY_END
223 
224 
225 static int adpcm_pos[2],adpcm_end[2];
226 
227 /*static unsigned char adpcm_d[0x08];
228 0 - start ROM offset LSB
229 1 - start ROM offset MSB
230 2 - end ROM offset LSB
231 3 - end ROM offset MSB
232 start & end need to be multiplied by 16 to get a proper _byte_ address in adpcm ROM
233 4 - always zero write (start trigger ?)
234 5 - different values
235 6 - different values
236 */
237 
MACHINE_INIT(opwolf)238 static MACHINE_INIT( opwolf )
239 {
240 	MSM5205_reset_w(0, 1);
241 	MSM5205_reset_w(1, 1);
242 }
243 
opwolf_msm5205_vck(int chip)244 static void opwolf_msm5205_vck(int chip)
245 {
246 	static int adpcm_data[2] = { -1, -1 };
247 
248 	if (adpcm_data[chip] != -1)
249 	{
250 		MSM5205_data_w(chip, adpcm_data[chip] & 0x0f);
251 		adpcm_data[chip] = -1;
252 		if (adpcm_pos[chip] == adpcm_end[chip])
253 		{
254 			MSM5205_reset_w(chip, 1);
255 		}
256 	}
257 	else
258 	{
259 		adpcm_data[chip] = memory_region(REGION_SOUND1)[adpcm_pos[chip]];
260 		adpcm_pos[chip] = (adpcm_pos[chip] + 1) & 0x7ffff;
261 		MSM5205_data_w(chip, adpcm_data[chip] >> 4);
262 	}
263 }
264 
WRITE_HANDLER(opwolf_adpcm_b_w)265 static WRITE_HANDLER( opwolf_adpcm_b_w )
266 {
267 	int start;
268 	int end;
269 
270 	adpcm_b[offset] = data;
271 
272 	if (offset==0x04) /* trigger ? */
273 	{
274 		start = adpcm_b[0] + adpcm_b[1]*256;
275 		end   = adpcm_b[2] + adpcm_b[3]*256;
276 		start *=16;
277 		end   *=16;
278 		adpcm_pos[0] = start;
279 		adpcm_end[0] = end;
280 		MSM5205_reset_w(0, 0);
281 	}
282 
283 /*  logerror("CPU #1     b00%i-data=%2x   pc=%4x\n",offset,data,activecpu_get_pc() ); */
284 }
285 
286 
WRITE_HANDLER(opwolf_adpcm_c_w)287 static WRITE_HANDLER( opwolf_adpcm_c_w )
288 {
289 	int start;
290 	int end;
291 
292 	adpcm_c[offset] = data;
293 
294 	if (offset==0x04) /* trigger ? */
295 	{
296 		start = adpcm_c[0] + adpcm_c[1]*256;
297 		end   = adpcm_c[2] + adpcm_c[3]*256;
298 		start *=16;
299 		end   *=16;
300 		adpcm_pos[1] = start;
301 		adpcm_end[1] = end;
302 		MSM5205_reset_w(1, 0);
303 	}
304 
305 /*  logerror("CPU #1     c00%i-data=%2x   pc=%4x\n",offset,data,activecpu_get_pc() ); */
306 }
307 
308 
WRITE_HANDLER(opwolf_adpcm_d_w)309 static WRITE_HANDLER( opwolf_adpcm_d_w )
310 {
311 /*   logerror("CPU #1         d00%i-data=%2x   pc=%4x\n",offset,data,activecpu_get_pc() ); */
312 }
313 
WRITE_HANDLER(opwolf_adpcm_e_w)314 static WRITE_HANDLER( opwolf_adpcm_e_w )
315 {
316 /*  logerror("CPU #1         e00%i-data=%2x   pc=%4x\n",offset,data,activecpu_get_pc() ); */
317 }
318 
319 
MEMORY_WRITE_START(z80_writemem)320 static MEMORY_WRITE_START( z80_writemem )
321     { 0x0000, 0x7fff, MWA_ROM },
322 	{ 0x8000, 0x8fff, MWA_RAM },
323 	{ 0x9000, 0x9000, YM2151_register_port_0_w },
324 	{ 0x9001, 0x9001, YM2151_data_port_0_w },
325 	{ 0xa000, 0xa000, taitosound_slave_port_w },
326 	{ 0xa001, 0xa001, taitosound_slave_comm_w },
327 	{ 0xb000, 0xb006, opwolf_adpcm_b_w },
328 	{ 0xc000, 0xc006, opwolf_adpcm_c_w },
329 	{ 0xd000, 0xd000, opwolf_adpcm_d_w },
330 	{ 0xe000, 0xe000, opwolf_adpcm_e_w },
331 MEMORY_END
332 
333 
334 /***********************************************************
335 			 INPUT PORTS, DIPs
336 ***********************************************************/
337 
338 #define TAITO_COINAGE_WORLD_8 \
339 	PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_A ) ) \
340 	PORT_DIPSETTING(    0x00, DEF_STR( 4C_1C ) ) \
341 	PORT_DIPSETTING(    0x10, DEF_STR( 3C_1C ) ) \
342 	PORT_DIPSETTING(    0x20, DEF_STR( 2C_1C ) ) \
343 	PORT_DIPSETTING(    0x30, DEF_STR( 1C_1C ) ) \
344 	PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Coin_B ) ) \
345 	PORT_DIPSETTING(    0xc0, DEF_STR( 1C_2C ) ) \
346 	PORT_DIPSETTING(    0x80, DEF_STR( 1C_3C ) ) \
347 	PORT_DIPSETTING(    0x40, DEF_STR( 1C_4C ) ) \
348 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_6C ) )
349 
350 #define TAITO_DIFFICULTY_8 \
351 	PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) \
352 	PORT_DIPSETTING(    0x02, "Easy" ) \
353 	PORT_DIPSETTING(    0x03, "Medium" ) \
354 	PORT_DIPSETTING(    0x01, "Hard" ) \
355 	PORT_DIPSETTING(    0x00, "Hardest" )
356 
357 INPUT_PORTS_START( opwolf )
358 	PORT_START	/* IN0 */
359 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
360 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
361 	PORT_BIT( 0x04, IP_ACTIVE_LOW,  IPT_UNKNOWN )
362 	PORT_BIT( 0x08, IP_ACTIVE_LOW,  IPT_UNKNOWN )
363 	PORT_BIT( 0x10, IP_ACTIVE_LOW,  IPT_UNKNOWN )
364 	PORT_BIT( 0x20, IP_ACTIVE_LOW,  IPT_UNKNOWN )
365 	PORT_BIT( 0x40, IP_ACTIVE_LOW,  IPT_UNKNOWN )
366 	PORT_BIT( 0x80, IP_ACTIVE_LOW,  IPT_UNKNOWN )
367 
368 	PORT_START	/* IN1 */
369 	PORT_BIT( 0x01, IP_ACTIVE_LOW,  IPT_BUTTON1 )
370 	PORT_BIT( 0x02, IP_ACTIVE_LOW,  IPT_BUTTON2 )
371 	PORT_BIT( 0x04, IP_ACTIVE_LOW,  IPT_SERVICE1 )
372 	PORT_BIT( 0x08, IP_ACTIVE_LOW,  IPT_TILT )
373 	PORT_BIT( 0x10, IP_ACTIVE_LOW,  IPT_START1 )
374 	PORT_BIT( 0x20, IP_ACTIVE_LOW,  IPT_UNKNOWN )
375 	PORT_BIT( 0x40, IP_ACTIVE_LOW,  IPT_UNKNOWN )
376 	PORT_BIT( 0x80, IP_ACTIVE_LOW,  IPT_UNKNOWN )
377 
378 	PORT_START /* DSW A */
379 	PORT_DIPNAME( 0x01, 0x01, "NY Conversion of Upright" )
380 	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
381 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
382 	PORT_DIPNAME( 0x02, 0x00, "Allow Continue" )
383 	PORT_DIPSETTING(    0x02, DEF_STR( No ))
384 	PORT_DIPSETTING(    0x00, DEF_STR( Yes ))
385 	PORT_SERVICE( 0x04, IP_ACTIVE_LOW )
386 	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Demo_Sounds ) )
387 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
388 	PORT_DIPSETTING(    0x08, DEF_STR( On ) )
389 	TAITO_COINAGE_WORLD_8
390 
391 	PORT_START /* DSW B */
392 	TAITO_DIFFICULTY_8
393 	PORT_DIPNAME( 0x0c, 0x0c, "Ammo Magazines at Start" )
394 	PORT_DIPSETTING(    0x00, "4" )
395 	PORT_DIPSETTING(    0x04, "5" )
396 	PORT_DIPSETTING(    0x0c, "6" )
397 	PORT_DIPSETTING(    0x08, "7" )
398 	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unused ) )	/* Manual says all 3 unused */
399 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
400 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
401 	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unused ) )
402 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
403 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
404 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) )
405 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
406 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
407 	PORT_DIPNAME( 0x80, 0x00, "Language" )
408 	PORT_DIPSETTING(    0x80, "Japanese" )
409 	PORT_DIPSETTING(    0x00, "English" )
410 
411 	PORT_START	/* P1X (span allows you to shoot enemies behind status bar) */
412 	PORT_ANALOG( 0xff, 0x80, IPT_LIGHTGUN_X | IPF_PLAYER1, 25, 15, 0x00, 0xff)
413 
414 	PORT_START	/* P1Y (span allows you to be slightly offscreen) */
415 	PORT_ANALOG( 0xff, 0x80, IPT_LIGHTGUN_Y | IPF_PLAYER1, 25, 15, 0x00, 0xff)
416 INPUT_PORTS_END
417 
418 
419 /**************************************************************
420 				GFX DECODING
421 **************************************************************/
422 
423 static struct GfxLayout charlayout =
424 {
425 	8,8,	/* 8*8 characters */
426 	RGN_FRAC(1,1),
427 	4,	/* 4 bits per pixel */
428 	{ 0, 1, 2, 3 },
429 	{ 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
430 	{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
431 	32*8	/* every sprite takes 32 consecutive bytes */
432 };
433 
434 static struct GfxLayout tilelayout =
435 {
436 	16,16,	/* 16*16 sprites */
437 	RGN_FRAC(1,1),
438 	4,	/* 4 bits per pixel */
439 	{ 0, 1, 2, 3 },
440 	{ 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4, 10*4, 11*4, 8*4, 9*4, 14*4, 15*4, 12*4, 13*4 },
441 	{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
442 	128*8	/* every sprite takes 128 consecutive bytes */
443 };
444 
445 static struct GfxLayout charlayout_b =
446 {
447 	8,8,	/* 8*8 characters */
448 	RGN_FRAC(1,1),
449 	4,	/* 4 bits per pixel */
450 	{ 0, 1, 2, 3 },
451 	{ 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 },
452 	{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
453 	32*8	/* every sprite takes 32 consecutive bytes */
454 };
455 
456 static struct GfxLayout tilelayout_b =
457 {
458 	16,16,	/* 16*16 sprites */
459 	RGN_FRAC(1,1),
460 	4,	/* 4 bits per pixel */
461 	{ 0, 1, 2, 3 },
462 	{ 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4, 8*4, 9*4, 10*4, 11*4, 12*4, 13*4, 14*4, 15*4 },
463 	{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
464 	128*8	/* every sprite takes 128 consecutive bytes */
465 };
466 
467 static struct GfxDecodeInfo opwolf_gfxdecodeinfo[] =
468 {
469 	{ REGION_GFX2, 0, &tilelayout,  0, 256 },	/* sprites */
470 	{ REGION_GFX1, 0, &charlayout,  0, 256 },	/* scr tiles */
471 	{ -1 } /* end of array */
472 };
473 
474 static struct GfxDecodeInfo opwolfb_gfxdecodeinfo[] =
475 {
476 	{ REGION_GFX2, 0, &tilelayout_b,  0, 256 },	/* sprites */
477 	{ REGION_GFX1, 0, &charlayout_b,  0, 256 },	/* scr tiles */
478 	{ -1 } /* end of array */
479 };
480 
481 
482 /**************************************************************
483 			     YM2151 (SOUND)
484 **************************************************************/
485 
486 /* handler called by the YM2151 emulator when the internal timers cause an IRQ */
487 
irq_handler(int irq)488 static void irq_handler(int irq)
489 {
490 	cpu_set_irq_line(1,0,irq ? ASSERT_LINE : CLEAR_LINE);
491 }
492 
493 
494 static struct YM2151interface ym2151_interface =
495 {
496 	1,			/* 1 chip */
497 	4000000,	/* 4 MHz ? */
498 	{ YM3012_VOL(50,MIXER_PAN_CENTER,50,MIXER_PAN_CENTER) },
499 	{ irq_handler },
500 	{ sound_bankswitch_w }
501 };
502 
503 
504 static struct MSM5205interface msm5205_interface =
505 {
506 	2,					/* 2 chip             */
507 	384000,				/* 384KHz             */
508 	{ opwolf_msm5205_vck, opwolf_msm5205_vck },/* interrupt function */
509 	{ MSM5205_S48_4B, MSM5205_S48_4B  },	/* 8KHz               */
510 	{ 60, 60 }				/* volume */
511 };
512 
513 
514 /***********************************************************
515 			     MACHINE DRIVERS
516 ***********************************************************/
517 
518 static MACHINE_DRIVER_START( opwolf )
519 
520 	/* basic machine hardware */
521 	MDRV_CPU_ADD(M68000, 12000000 )	/* 12 MHz ??? */
MDRV_CPU_MEMORY(opwolf_readmem,opwolf_writemem)522 	MDRV_CPU_MEMORY(opwolf_readmem,opwolf_writemem)
523 	MDRV_CPU_VBLANK_INT(irq5_line_hold,1)
524 
525 	MDRV_CPU_ADD(Z80, 4000000 )	/* 4 MHz */
526 	MDRV_CPU_MEMORY(z80_readmem,z80_writemem)
527 
528 	MDRV_FRAMES_PER_SECOND(60)
529 	MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
530 	MDRV_INTERLEAVE(10)	/* 10 CPU slices per frame - enough for the sound CPU to read all commands */
531 
532 	MDRV_MACHINE_INIT(opwolf)
533 
534 	/* video hardware */
535 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
536 	MDRV_SCREEN_SIZE(40*8, 32*8)
537 	MDRV_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
538 	MDRV_GFXDECODE(opwolf_gfxdecodeinfo)
539 	MDRV_PALETTE_LENGTH(8192)
540 
541 	MDRV_VIDEO_START(opwolf)
542 	MDRV_VIDEO_UPDATE(opwolf)
543 
544 	/* sound hardware */
545 	MDRV_SOUND_ATTRIBUTES(SOUND_SUPPORTS_STEREO)
546 	MDRV_SOUND_ADD(YM2151, ym2151_interface)
547 	MDRV_SOUND_ADD(MSM5205, msm5205_interface)
548 MACHINE_DRIVER_END
549 
550 
551 static MACHINE_DRIVER_START( opwolfb )
552 
553 	/* basic machine hardware */
554 	MDRV_CPU_ADD(M68000, 12000000)	/* 12 MHz ??? */
555 	MDRV_CPU_MEMORY(opwolf_readmem,opwolf_writemem)
556 	MDRV_CPU_VBLANK_INT(irq5_line_hold,1)
557 
558 	MDRV_CPU_ADD(Z80, 4000000)	/* 4 MHz ??? */
559 	MDRV_CPU_MEMORY(z80_readmem,z80_writemem)
560 
561 	MDRV_CPU_ADD(Z80, 4000000)	/* 4 MHz ??? */
562 	MDRV_CPU_MEMORY(sub_z80_readmem,sub_z80_writemem)
563 	MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
564 
565 	MDRV_FRAMES_PER_SECOND(60)
566 	MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
567 	MDRV_INTERLEAVE(10)	/* 10 CPU slices per frame - enough for the sound CPU to read all commands */
568 
569 	/* video hardware */
570 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
571 	MDRV_SCREEN_SIZE(40*8, 32*8)
572 	MDRV_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
573 	MDRV_GFXDECODE(opwolfb_gfxdecodeinfo)
574 	MDRV_PALETTE_LENGTH(8192)
575 
576 	MDRV_VIDEO_START(opwolf)
577 	MDRV_VIDEO_UPDATE(opwolf)
578 
579 	/* sound hardware */
580 	MDRV_SOUND_ATTRIBUTES(SOUND_SUPPORTS_STEREO)
581 	MDRV_SOUND_ADD(YM2151, ym2151_interface)
582 	MDRV_SOUND_ADD(MSM5205, msm5205_interface)
583 MACHINE_DRIVER_END
584 
585 
586 /***************************************************************************
587 					DRIVERS
588 ***************************************************************************/
589 
590 ROM_START( opwolf )
591 	ROM_REGION( 0x40000, REGION_CPU1, 0 )     /* 256k for 68000 code */
592 	ROM_LOAD16_BYTE( "opwlf.40",  0x00000, 0x10000, CRC(3ffbfe3a) SHA1(e41257e6af18bab4e36267a0c25a6aaa742972d2) )
593 	ROM_LOAD16_BYTE( "opwlf.30",  0x00001, 0x10000, CRC(fdabd8a5) SHA1(866ec6168489024b8d157f2d5b1553d7f6e3d9b7) )
594 	ROM_LOAD16_BYTE( "opwlf.39",  0x20000, 0x10000, CRC(216b4838) SHA1(2851cae00bb3e32e20f35fdab8ed6f149e658363) )
595 	ROM_LOAD16_BYTE( "opwlf.29",  0x20001, 0x10000, CRC(b71bc44c) SHA1(5b404bd7630f01517ab98bda40ca43c11268035a) )
596 
597 	ROM_REGION( 0x20000, REGION_CPU2, 0 )      /* sound cpu */
598 	ROM_LOAD( "opwlf_s.10",  0x00000, 0x04000, CRC(45c7ace3) SHA1(06f7393f6b973b7735c27e8380cb4148650cfc16) )
599 	ROM_CONTINUE(            0x10000, 0x0c000 ) /* banked stuff */
600 
601 	ROM_REGION( 0x80000, REGION_GFX1, ROMREGION_DISPOSE )
602 	ROM_LOAD( "opwlf.13",  0x00000, 0x80000, CRC(f6acdab1) SHA1(716b94ab3fa330ecf22df576f6a9f47a49c7554a) )	/* SCR tiles (8 x 8) */
603 
604 	ROM_REGION( 0x80000, REGION_GFX2, ROMREGION_DISPOSE )
605 	ROM_LOAD( "opwlf.72",  0x00000, 0x80000, CRC(89f889e5) SHA1(1592f6ce4fbb75e33d6ab957e5b90242a7a7a8c4) )	/* Sprites (16 x 16) */
606 
607 	ROM_REGION( 0x80000, REGION_SOUND1, 0 )	/* ADPCM samples */
608 	ROM_LOAD( "opwlf_s.21",   0x00000, 0x80000, CRC(f3e19c64) SHA1(39d48645f776c9c2ade537d959ecc6f9dc6dfa1b) )
609 ROM_END
610 
611 ROM_START( opwolfb )
612 	ROM_REGION( 0x40000, REGION_CPU1, 0 )     /* 256k for 68000 code */
613 	ROM_LOAD16_BYTE( "opwlfb.12",  0x00000, 0x10000, CRC(d87e4405) SHA1(de8a7763acd57293fbbff609e949ecd66c0f9234) )
614 	ROM_LOAD16_BYTE( "opwlfb.10",  0x00001, 0x10000, CRC(9ab6f75c) SHA1(85310258ca005ffb031e8d6b3f43c3d1fc29ef14) )
615 	ROM_LOAD16_BYTE( "opwlfb.13",  0x20000, 0x10000, CRC(61230c6e) SHA1(942764aec0c55ba00df8dbb54e127b73e24192ae) )
616 	ROM_LOAD16_BYTE( "opwlfb.11",  0x20001, 0x10000, CRC(342e318d) SHA1(a52918d16884ca42b2a3b910bc71bfd81b45f1ab) )
617 
618 	ROM_REGION( 0x20000, REGION_CPU2, 0 )      /* sound cpu */
619 	ROM_LOAD( "opwlfb.30",  0x00000, 0x04000, CRC(0669b94c) SHA1(f10894a6fad8ed144a528db696436b58f62ddee4) )
620 	ROM_CONTINUE(           0x10000, 0x04000 ) /* banked stuff */
621 
622 	ROM_REGION( 0x10000, REGION_CPU3, 0 )      /* c-chip substitute Z80 */
623 	ROM_LOAD( "opwlfb.09",   0x00000, 0x08000, CRC(ab27a3dd) SHA1(cf589e7a9ccf3e86020b86f917fb91f3d8ba7512) )
624 
625 	ROM_REGION( 0x80000, REGION_GFX1, ROMREGION_DISPOSE )
626 	ROM_LOAD16_BYTE( "opwlfb.08",   0x00000, 0x10000, CRC(134d294e) SHA1(bd05169dbd761c2944f0ac51c1ec114577777452) )	/* SCR tiles (8 x 8) */
627 	ROM_LOAD16_BYTE( "opwlfb.06",   0x20000, 0x10000, CRC(317d0e66) SHA1(70298c0ef5243f481b18f904be9404527d1d99d5) )
628 	ROM_LOAD16_BYTE( "opwlfb.07",   0x40000, 0x10000, CRC(e1c4095e) SHA1(d5f1d26d6612e78001002f92de670e68e00c6f9e) )
629 	ROM_LOAD16_BYTE( "opwlfb.05",   0x60000, 0x10000, CRC(fd9e72c8) SHA1(7a76f57641c3f0198565cd163188b581253173b2) )
630 	ROM_LOAD16_BYTE( "opwlfb.04",   0x00001, 0x10000, CRC(de0ca98d) SHA1(066e89ec0c64da14bdcd2b337f95c0de5de33c11) )
631 	ROM_LOAD16_BYTE( "opwlfb.02",   0x20001, 0x10000, CRC(6231fdd0) SHA1(1c830c106cf3c94a8d06ed2fff030a5d516ab6d6) )
632 	ROM_LOAD16_BYTE( "opwlfb.03",   0x40001, 0x10000, CRC(ccf8ba80) SHA1(8366f5ef0de885e5241567d1a083d98a8a2875d9) )
633 	ROM_LOAD16_BYTE( "opwlfb.01",   0x60001, 0x10000, CRC(0a65f256) SHA1(4dfcd3cb138a87d002eb65a02f94e33f4d07676d) )
634 
635 	ROM_REGION( 0x80000, REGION_GFX2, ROMREGION_DISPOSE )
636 	ROM_LOAD16_BYTE( "opwlfb.14",   0x00000, 0x10000, CRC(663786eb) SHA1(a25710f6c16158e51d0934f184390a01ff0a614a) )	/* Sprites (16 x 16) */
637 	ROM_LOAD16_BYTE( "opwlfb.15",   0x20000, 0x10000, CRC(315b8aa9) SHA1(4a904e5532421d933e4c401c03c958eb32b15e03) )
638 	ROM_LOAD16_BYTE( "opwlfb.16",   0x40000, 0x10000, CRC(e01099e3) SHA1(4c5391d71978f72c57c140e58a767e138acdce12) )
639 	ROM_LOAD16_BYTE( "opwlfb.17",   0x60000, 0x10000, CRC(56fbe61d) SHA1(0e4dce8ee981bdd851e500fa9dca5d40908e142f) )
640 	ROM_LOAD16_BYTE( "opwlfb.18",   0x00001, 0x10000, CRC(de9ab08e) SHA1(ef674c965f35efaf747f1ddbf9e9164fcceb0c1c) )
641 	ROM_LOAD16_BYTE( "opwlfb.19",   0x20001, 0x10000, CRC(645cf85e) SHA1(91c244c2e238b61c8b2f39e5fa01cc23ebbfe2ce) )
642 	ROM_LOAD16_BYTE( "opwlfb.20",   0x40001, 0x10000, CRC(d80b9cc6) SHA1(b189f35eb206da1ab313620e251e6bb10edeee04) )
643 	ROM_LOAD16_BYTE( "opwlfb.21",   0x60001, 0x10000, CRC(97d25157) SHA1(cfb3f76ed860d90235dc0e32919a5ec3d3e683dd) )
644 
645 	ROM_REGION( 0x80000, REGION_SOUND1, 0 )	/* ADPCM samples (interleaved) */
646 	ROM_LOAD16_BYTE( "opwlfb.29",   0x00000, 0x10000, CRC(05a9eac0) SHA1(26eb1acc65aeb759920b35bcbcac6d6c2789584c) )
647 	ROM_LOAD16_BYTE( "opwlfb.28",   0x20000, 0x10000, CRC(281b2175) SHA1(3789e58da682041226f70eba87b31876cb206906) )
648 	ROM_LOAD16_BYTE( "opwlfb.27",   0x40000, 0x10000, CRC(441211a6) SHA1(82e84ae90765df5f7f6b6f32a2bb52ac40132f8d) )
649 	ROM_LOAD16_BYTE( "opwlfb.26",   0x60000, 0x10000, CRC(86d1d42d) SHA1(9d63e9e35fa51d8e6eac30556ba5a4dca7c14418) )
650 	ROM_LOAD16_BYTE( "opwlfb.25",   0x00001, 0x10000, CRC(85b87f58) SHA1(f26cf4ab8f9d30d1b1ac84be328ca821524b234e) )
651 	ROM_LOAD16_BYTE( "opwlfb.24",   0x20001, 0x10000, CRC(8efc5d4d) SHA1(21068d7fcfe293d99ad9f999d84483bf1a49ec6d) )
652 	ROM_LOAD16_BYTE( "opwlfb.23",   0x40001, 0x10000, CRC(a874c703) SHA1(c9d6074265f5d5028c69c81eaba29fa178943341) )
653 	ROM_LOAD16_BYTE( "opwlfb.22",   0x60001, 0x10000, CRC(9228481f) SHA1(8160f919f5e6a347c915a2bd7488b488fe2401bc) )
654 ROM_END
655 
656 
657 static DRIVER_INIT( opwolf )
658 {
659 	opwolf_cchip_init();
660 
661 	opwolf_gun_xoffs = 0;
662 	opwolf_gun_yoffs = 0;
663 
664 	/* (there are other sound vars that may need saving too) */
665 	state_save_register_UINT8("sound2", 0, "registers", adpcm_b, 8);
666 	state_save_register_UINT8("sound3", 0, "registers", adpcm_c, 8);
667 }
668 
DRIVER_INIT(opwolfb)669 static DRIVER_INIT( opwolfb )
670 {
671 	/* bootleg needs different range of raw gun coords */
672 	opwolf_gun_xoffs = -2;
673 	opwolf_gun_yoffs = 17;
674 
675 	/* (there are other sound vars that may need saving too) */
676 	state_save_register_UINT8("sound2", 0, "registers", adpcm_b, 8);
677 	state_save_register_UINT8("sound3", 0, "registers", adpcm_c, 8);
678 }
679 
680 
681 
682 /*    year  rom       parent    machine   inp       init */
683 GAME( 1987, opwolf,   0,        opwolf,   opwolf,   opwolf,   ROT0, "Taito America Corporation", "Operation Wolf (US)" )
684 GAME( 1987, opwolfb,  opwolf,   opwolfb,  opwolf,   opwolfb,  ROT0, "bootleg", "Operation Bear" )
685