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