1 /*******************************************************************************
2  Ninja Kid / Ninjakun Majou no Bouken | (c) 1984 UPL / Taito
3 ********************************************************************************
4  Driver by David Haywood
5  with help from Steph and Phil Stroffolino
6 
7  Last Changes: 5 Mar 2001
8 
9  This driver was started after interest was shown in the game by a poster at
10  various messageboards going under the name of 'ninjakid'  I decided to attempt
11  a driver for this game to gain some experience with Z80 & Multi-processor
12  games.
13 
14 Hold P1 Start after a reset to skip the startup memory tests.
15 
16 Change Log:
17 5 Mar - Added Saved State Support (DJH)
18 8 Jun - Added palette animation, Fixed FG priority. (Uki)
19 9 Jun - Fixed BG scroll handling, Fixed CPU clock.
20 *******************************************************************************/
21 
22 #include "driver.h"
23 #include "vidhrdw/generic.h"
24 #include "cpu/z80/z80.h"
25 #include "state.h"
26 
27 extern WRITE_HANDLER( ninjakid_bg_videoram_w );
28 extern WRITE_HANDLER( ninjakid_fg_videoram_w );
29 extern READ_HANDLER( ninjakid_bg_videoram_r );
30 
31 extern READ_HANDLER( ninjakun_io_8000_r );
32 extern WRITE_HANDLER( ninjakun_io_8000_w );
33 
34 extern VIDEO_START( ninjakid );
35 extern VIDEO_UPDATE( ninjakid );
36 extern WRITE_HANDLER( ninjakun_flipscreen_w );
37 
38 extern WRITE_HANDLER( ninjakun_paletteram_w );
39 
40 /******************************************************************************/
41 
42 static UINT8 *ninjakid_gfx_rom;
43 
READ_HANDLER(ninjakid_shared_rom_r)44 static READ_HANDLER( ninjakid_shared_rom_r ){
45 	return ninjakid_gfx_rom[offset];
46 }
47 
48 /* working RAM is shared, but an address line is inverted */
49 static UINT8 *shareram;
50 
WRITE_HANDLER(shareram_w)51 static WRITE_HANDLER( shareram_w ){
52 	shareram[offset^0x400] = data;
53 }
READ_HANDLER(shareram_r)54 static READ_HANDLER( shareram_r ){
55 	return shareram[offset^0x400];
56 }
57 
58 /*******************************************************************************
59  0xA000 Read / Write Handlers
60 *******************************************************************************/
61 
62 static UINT8 ninjakun_io_a002_ctrl;
63 
READ_HANDLER(ninjakun_io_A002_r)64 static READ_HANDLER( ninjakun_io_A002_r ){
65 	return ninjakun_io_a002_ctrl | readinputport(2); /* vblank */
66 }
67 
WRITE_HANDLER(cpu1_A002_w)68 static WRITE_HANDLER( cpu1_A002_w ){
69 	if( data == 0x80 ) ninjakun_io_a002_ctrl |= 0x04;
70 	if( data == 0x40 ) ninjakun_io_a002_ctrl &= ~0x08;
71 }
72 
WRITE_HANDLER(cpu2_A002_w)73 static WRITE_HANDLER( cpu2_A002_w ){
74 	if( data == 0x40 ) ninjakun_io_a002_ctrl |= 0x08;
75 	if( data == 0x80 ) ninjakun_io_a002_ctrl &= ~0x04;
76 }
77 
78 /*******************************************************************************
79  Memory Maps
80 *******************************************************************************/
81 
MEMORY_READ_START(ninjakid_primary_readmem)82 static MEMORY_READ_START( ninjakid_primary_readmem )
83     { 0x0000, 0x7fff, MRA_ROM },
84 	{ 0x8000, 0x8003, ninjakun_io_8000_r },
85 	{ 0xa000, 0xa000, input_port_0_r },
86 	{ 0xa001, 0xa001, input_port_1_r },
87 	{ 0xa002, 0xa002, ninjakun_io_A002_r },
88 	{ 0xc000, 0xc7ff, MRA_RAM },	/* tilemaps */
89 	{ 0xc800, 0xcfff, ninjakid_bg_videoram_r },
90     { 0xd000, 0xd7ff, MRA_RAM },	/* spriteram */
91     { 0xd800, 0xd9ff, paletteram_r },
92     { 0xe000, 0xe7ff, MRA_RAM },
93 MEMORY_END
94 
95 static MEMORY_WRITE_START( ninjakid_primary_writemem )
96 	{ 0x0000, 0x1fff, MWA_ROM },
97 	{ 0x2000, 0x7fff, MWA_ROM, &ninjakid_gfx_rom },
98 	{ 0x8000, 0x8003, ninjakun_io_8000_w },
99 	{ 0xa002, 0xa002, cpu1_A002_w },
100 	{ 0xa003, 0xa003, ninjakun_flipscreen_w },
101 	{ 0xc000, 0xc7ff, ninjakid_fg_videoram_w, &videoram },
102 	{ 0xc800, 0xcfff, ninjakid_bg_videoram_w },
103 	{ 0xd000, 0xd7ff, MWA_RAM, &spriteram },
104 	{ 0xd800, 0xd9ff, ninjakun_paletteram_w, &paletteram },
105 	{ 0xe000, 0xe7ff, MWA_RAM, &shareram },
106 MEMORY_END
107 
108 static MEMORY_READ_START( ninjakid_secondary_readmem )
109     { 0x0000, 0x1fff, MRA_ROM },
110     { 0x2000, 0x7fff, ninjakid_shared_rom_r },
111 	{ 0x8000, 0x8003, ninjakun_io_8000_r },
112 	{ 0xa000, 0xa000, input_port_0_r },
113 	{ 0xa001, 0xa001, input_port_1_r },
114 	{ 0xa002, 0xa002, ninjakun_io_A002_r },
115 	{ 0xc000, 0xc7ff, videoram_r },		/* tilemaps */
116 	{ 0xc800, 0xcfff, ninjakid_bg_videoram_r },
117     { 0xd000, 0xd7ff, spriteram_r },	/* shareram */
118     { 0xd800, 0xd9ff, paletteram_r },
119     { 0xe000, 0xe7ff, shareram_r },
120 MEMORY_END
121 
122 static MEMORY_WRITE_START( ninjakid_secondary_writemem )
123 	{ 0x0000, 0x1fff, MWA_ROM },
124 	{ 0x8000, 0x8003, ninjakun_io_8000_w },
125 	{ 0xa002, 0xa002, cpu2_A002_w },
126 	{ 0xa003, 0xa003, ninjakun_flipscreen_w },
127 	{ 0xc000, 0xc7ff, ninjakid_fg_videoram_w },
128 	{ 0xc800, 0xcfff, ninjakid_bg_videoram_w },
129 	{ 0xd000, 0xd7ff, spriteram_w },	/* shareram */
130 	{ 0xd800, 0xd9ff, ninjakun_paletteram_w },
131     { 0xe000, 0xe7ff, shareram_w },
132 MEMORY_END
133 
134 /*******************************************************************************
135  GFX Decoding Information
136 *******************************************************************************/
137 
138 static struct GfxLayout tile_layout =
139 {
140 	8,8,	/* tile size */
141 	0x400,	/* number of tiles */
142 	4,		/* bits per pixel */
143 	{ 0, 1, 2, 3 }, /* plane offsets */
144 	{ 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 }, /* x offsets */
145 	{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 }, /* y offsets */
146 	256
147 };
148 
149 static struct GfxLayout sprite_layout =
150 {
151 	16,16,	/* tile size */
152 	0x100,	/* number of tiles */
153 	4,		/* bits per pixel */
154 	{ 0, 1, 2, 3 }, /* plane offsets */
155 	{
156 		0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4,
157 		256+0*4, 256+1*4, 256+2*4, 256+3*4, 256+4*4, 256+5*4, 256+6*4, 256+7*4,
158 	}, /* x offsets */
159 	{
160 		0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,
161 		512+0*32, 512+1*32, 512+2*32, 512+3*32, 512+4*32, 512+5*32, 512+6*32, 512+7*32
162 	}, /* y offsets */
163 	1024
164 };
165 
166 static struct GfxDecodeInfo ninjakid_gfxdecodeinfo[] =
167 {
168 	{ REGION_GFX1, 0, &tile_layout,		0x000, 0x10 },
169 	{ REGION_GFX2, 0, &tile_layout,		0x100, 0x10 },
170 	{ REGION_GFX1, 0, &sprite_layout,	0x200, 0x10 },
171 	{ -1 }
172 };
173 
174 /*******************************************************************************
175  Machine Driver Structure(s)
176 *******************************************************************************/
177 
178 static struct AY8910interface ay8910_interface =
179 {
180 	2,	/* 2 chips */
181 	6000000/2,	/* 3 MHz */
182 	{ 50, 50 }
183 };
184 
185 static MACHINE_DRIVER_START( ninjakid )
186 
187 	/* basic machine hardware */
188 	MDRV_CPU_ADD(Z80, 3000000) /* 3.00MHz */
MDRV_CPU_MEMORY(ninjakid_primary_readmem,ninjakid_primary_writemem)189 	MDRV_CPU_MEMORY(ninjakid_primary_readmem,ninjakid_primary_writemem)
190 	MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
191 
192 	MDRV_CPU_ADD(Z80, 3000000) /* 3.00MHz */
193 	MDRV_CPU_MEMORY(ninjakid_secondary_readmem,ninjakid_secondary_writemem)
194 	MDRV_CPU_VBLANK_INT(irq0_line_hold,4) /* ? */
195 
196 	MDRV_FRAMES_PER_SECOND(60)
197 	MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION)
198 	MDRV_INTERLEAVE(100)	/* 100 CPU slices per frame */
199 
200     /* video hardware */
201 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
202 	MDRV_SCREEN_SIZE(32*8, 32*8)
203 	MDRV_VISIBLE_AREA(0*8, 32*8-1, 4*8, (32-4)*8-1 )
204 	MDRV_GFXDECODE(ninjakid_gfxdecodeinfo)
205 	MDRV_PALETTE_LENGTH(768)
206 
207 	MDRV_VIDEO_START(ninjakid)
208 	MDRV_VIDEO_UPDATE(ninjakid)
209 
210 	/* sound hardware */
211 	MDRV_SOUND_ADD(AY8910, ay8910_interface)
212 MACHINE_DRIVER_END
213 
214 /*******************************************************************************
215  Rom Definitions
216 *******************************************************************************/
217 
218 ROM_START( ninjakun ) /* Original Board? */
219 	ROM_REGION( 0x10000, REGION_CPU1, 0 ) /* Main CPU */
220 	ROM_LOAD( "ninja-1.7a",  0x0000, 0x02000, CRC(1c1dc141) SHA1(423d3ed35e73a8d5bfce075a889b0322b207bd0d) )
221 	ROM_LOAD( "ninja-2.7b",  0x2000, 0x02000, CRC(39cc7d37) SHA1(7f0d0e1e92cb6a57f15eb7fc51a67112f1c5fc8e) )
222 	ROM_LOAD( "ninja-3.7d",  0x4000, 0x02000, CRC(d542bfe3) SHA1(3814d8f5b1acda21438fff4f71670fa653dc7b30) )
223 	ROM_LOAD( "ninja-4.7e",  0x6000, 0x02000, CRC(a57385c6) SHA1(77925a281e64889bfe967c3d42a388529aaf7eb6) )
224 
225 	ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* Secondary CPU */
226 	ROM_LOAD( "ninja-5.7h",  0x0000, 0x02000, CRC(164a42c4) SHA1(16b434b33b76b878514f67c23315d4c6da7bfc9e) )
227 
228 	ROM_REGION( 0x08000, REGION_GFX1, ROMREGION_DISPOSE ) /* Graphics */
229 	ROM_LOAD16_BYTE( "ninja-6.7n",  0x0000, 0x02000, CRC(a74c4297) SHA1(87184d14c67331f2c8a2412e28f31427eddae799) )
230 	ROM_LOAD16_BYTE( "ninja-7.7p",  0x0001, 0x02000, CRC(53a72039) SHA1(d77d608ce9388a8956831369badd88a8eda8e102) )
231 	ROM_LOAD16_BYTE( "ninja-8.7s",  0x4000, 0x02000, CRC(4a99d857) SHA1(6aadb6a5c721a161a5c1bef5569c1e323e380cff) )
232 	ROM_LOAD16_BYTE( "ninja-9.7t",  0x4001, 0x02000, CRC(dede49e4) SHA1(8ce4bc02ec583b3885ca63fb5e2d5dad185fe192) )
233 
234 	ROM_REGION( 0x08000, REGION_GFX2, ROMREGION_DISPOSE ) /* Graphics */
235 	ROM_LOAD16_BYTE( "ninja-10.2c", 0x0000, 0x02000, CRC(0d55664a) SHA1(955a607b4401ce9f3f807d53833a766152b0ef9b) )
236 	ROM_LOAD16_BYTE( "ninja-11.2d", 0x0001, 0x02000, CRC(12ff9597) SHA1(10b572844ab32e3ae54abe3600fecc1a811ac713) )
237 	ROM_LOAD16_BYTE( "ninja-12.4c", 0x4000, 0x02000, CRC(e9b75807) SHA1(cf4c8ac962f785e9de5502df58eab9b3725aaa28) )
238 	ROM_LOAD16_BYTE( "ninja-13.4d", 0x4001, 0x02000, CRC(1760ed2c) SHA1(ee4c8efcce483c8051873714856824a1a1e14b61) )
239 ROM_END
240 
241 /*******************************************************************************
242  Input Ports
243 ********************************************************************************
244  2 Sets of Controls
245  2 Sets of Dipsiwtches
246 *******************************************************************************/
247 
248 INPUT_PORTS_START( ninjakid )
249 	PORT_START	/* 0xa000 */
250 	PORT_BIT( 0x01, IP_ACTIVE_LOW,	IPT_JOYSTICK_LEFT | IPF_2WAY ) /* "XPOS1" */
251 	PORT_BIT( 0x02, IP_ACTIVE_LOW,	IPT_JOYSTICK_RIGHT| IPF_2WAY )
252 	PORT_BIT( 0x04, IP_ACTIVE_LOW,	IPT_BUTTON2 )
253 	PORT_BIT( 0x08, IP_ACTIVE_LOW,	IPT_BUTTON1 )
254 	PORT_BIT( 0x10, IP_ACTIVE_LOW,	IPT_UNKNOWN )
255 	PORT_BIT( 0x20, IP_ACTIVE_LOW,	IPT_START1  )
256 	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
257 	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
258 
259 	PORT_START	/* 0xa001 */
260 	PORT_BIT( 0x01, IP_ACTIVE_LOW,	IPT_JOYSTICK_LEFT | IPF_2WAY | IPF_COCKTAIL) /* "YPOS1" */
261 	PORT_BIT( 0x02, IP_ACTIVE_LOW,	IPT_JOYSTICK_RIGHT| IPF_2WAY | IPF_COCKTAIL)
262 	PORT_BIT( 0x04, IP_ACTIVE_LOW,	IPT_BUTTON2 | IPF_COCKTAIL )
263 	PORT_BIT( 0x08, IP_ACTIVE_LOW,	IPT_BUTTON1 | IPF_COCKTAIL )
264 	PORT_BIT( 0x10, IP_ACTIVE_LOW,	IPT_UNKNOWN )
265 	PORT_BIT( 0x20, IP_ACTIVE_LOW,	IPT_START2  )
266 	PORT_SERVICE( 0x40, IP_ACTIVE_HIGH ) \
267 	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 )
268 
269 	PORT_START	/* 0xa002 */
270 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_VBLANK )
271 
272 	PORT_START /* DSW1 */
273 	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Cabinet ) )
274 	PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
275 	PORT_DIPSETTING(    0x01, DEF_STR( Cocktail ) )
276 	PORT_DIPNAME( 0x06, 0x04, DEF_STR( Lives ) )
277 	PORT_DIPSETTING(    0x02, "2" )
278 	PORT_DIPSETTING(    0x04, "3" )
279 	PORT_DIPSETTING(    0x06, "4" )
280 	PORT_DIPSETTING(    0x00, "5" )
281 	PORT_DIPNAME( 0x08, 0x08, "First Bonus" )
282 	PORT_DIPSETTING(    0x08, "30000" )
283 	PORT_DIPSETTING(    0x00, "40000" )
284 	PORT_DIPNAME( 0x30, 0x30, "Second Bonus" )
285 	PORT_DIPSETTING(    0x00, "No Bonus" )
286 	PORT_DIPSETTING(    0x10, "Every 30000" )
287 	PORT_DIPSETTING(    0x30, "Every 50000" )
288 	PORT_DIPSETTING(    0x20, "Every 70000" )
289 	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Demo_Sounds ) )
290 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
291 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
292 	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Difficulty ) )
293 	PORT_DIPSETTING(    0x80, "Normal" )
294 	PORT_DIPSETTING(    0x00, "Hard"   )
295 
296 	PORT_START /* DSW2 */
297 	PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coinage ) )
298 	PORT_DIPSETTING(    0x04, DEF_STR( 4C_1C ) )
299 	PORT_DIPSETTING(    0x05, DEF_STR( 3C_1C ) )
300 	PORT_DIPSETTING(    0x00, DEF_STR( 4C_2C ) )
301 	PORT_DIPSETTING(    0x06, DEF_STR( 2C_1C ) )
302 	PORT_DIPSETTING(    0x01, DEF_STR( 3C_2C ) )
303 	PORT_DIPSETTING(    0x02, DEF_STR( 2C_2C ) )
304 	PORT_DIPSETTING(    0x07, DEF_STR( 1C_1C ) )
305 	PORT_DIPSETTING(    0x03, DEF_STR( 1C_2C ) )
306 	PORT_DIPNAME( 0x08, 0x08, "High Score Names" )
307 	PORT_DIPSETTING(    0x00, "3 Letters" )
308 	PORT_DIPSETTING(    0x08, "8 Letters" )
309 	PORT_DIPNAME( 0x10, 0x10, "Allow Continue" )
310 	PORT_DIPSETTING(    0x10, DEF_STR( No ) )
311 	PORT_DIPSETTING(    0x00, DEF_STR( Yes ) )
312 	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )/* Probably Unused */
313 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
314 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
315 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Free_Play ) )
316 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
317 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
318 	PORT_DIPNAME( 0x80, 0x80, "Endless Game (If Free Play)" )
319 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
320 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
321 INPUT_PORTS_END
322 
323 /*******************************************************************************
324  Init
325 *******************************************************************************/
326 
327 static DRIVER_INIT( ninjakid )
328 {
329 	/* Save State Stuff */
330 	state_save_register_UINT8 ("NK_Main", 0, "ninjakun_io_a002_ctrl", &ninjakun_io_a002_ctrl, 1);
331 }
332 
333 /*******************************************************************************
334  Game Drivers
335 *******************************************************************************/
336 
337 GAME( 1984, ninjakun, 0, ninjakid, ninjakid, ninjakid, ROT0, "[UPL] (Taito license)", "Ninjakun Majou no Bouken" )
338