1 #include "../vidhrdw/munchmo.c"
2 
3 /***************************************************************************
4   Munch Mobile
5   (C) 1982 SNK
6 
7   2 Z80s
8   2 AY-8910s
9   15 MHz crystal
10 
11   Known Issues:
12 	- sprite priority problems
13 	- it's unclear if mirroring the videoram chunks is correct behavior
14 	- several unmapped registers
15 	- sustained sounds (when there should be silence)
16 
17 ***************************************************************************/
18 
19 #include "driver.h"
20 #include "cpu/z80/z80.h"
21 #include "vidhrdw/generic.h"
22 
23 
24 extern UINT8 *mnchmobl_vreg;
25 extern UINT8 *mnchmobl_status_vram;
26 extern UINT8 *mnchmobl_sprite_xpos;
27 extern UINT8 *mnchmobl_sprite_attr;
28 extern UINT8 *mnchmobl_sprite_tile;
29 
30 void mnchmobl_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
31 int mnchmobl_vh_start( void );
32 void mnchmobl_vh_stop( void );
33 WRITE_HANDLER( mnchmobl_palette_bank_w );
34 WRITE_HANDLER( mnchmobl_flipscreen_w );
35 READ_HANDLER( mnchmobl_sprite_xpos_r );
36 WRITE_HANDLER( mnchmobl_sprite_xpos_w );
37 READ_HANDLER( mnchmobl_sprite_attr_r );
38 WRITE_HANDLER( mnchmobl_sprite_attr_w );
39 READ_HANDLER( mnchmobl_sprite_tile_r );
40 WRITE_HANDLER( mnchmobl_sprite_tile_w );
41 READ_HANDLER( mnchmobl_videoram_r );
42 WRITE_HANDLER( mnchmobl_videoram_w );
43 void mnchmobl_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
44 
45 
46 /***************************************************************************/
47 
48 static int mnchmobl_nmi_enable = 0;
49 
WRITE_HANDLER(mnchmobl_nmi_enable_w)50 static WRITE_HANDLER( mnchmobl_nmi_enable_w )
51 {
52 	mnchmobl_nmi_enable = data;
53 }
54 
mnchmobl_interrupt(void)55 static int mnchmobl_interrupt( void )
56 {
57 	static int which;
58 	which = !which;
59 	if( which ) return interrupt();
60 	if( mnchmobl_nmi_enable ) return nmi_interrupt();
61 	return ignore_interrupt();
62 }
63 
WRITE_HANDLER(mnchmobl_soundlatch_w)64 WRITE_HANDLER( mnchmobl_soundlatch_w )
65 {
66 	soundlatch_w( offset, data );
67 	cpu_cause_interrupt( 1, Z80_IRQ_INT );
68 }
69 
70 static struct MemoryReadAddress readmem[] =
71 {
72 	{ 0x0000, 0x3fff, MRA_ROM },
73 	{ 0x8000, 0x83ff, MRA_RAM }, /* working RAM */
74 	{ 0xa000, 0xa3ff, MRA_RAM },
75 	{ 0xa400, 0xa7ff, mnchmobl_sprite_xpos_r }, /* mirrored */
76 	{ 0xa800, 0xabff, MRA_RAM },
77 	{ 0xac00, 0xafff, mnchmobl_sprite_tile_r }, /* mirrored */
78 	{ 0xb000, 0xb3ff, MRA_RAM },
79 	{ 0xb400, 0xb7ff, mnchmobl_sprite_attr_r }, /* mirrored */
80 	{ 0xb800, 0xb8ff, MRA_RAM },
81 	{ 0xb900, 0xb9ff, mnchmobl_videoram_r },	/* mirrored */
82 	{ 0xbe02, 0xbe02, input_port_3_r }, /* DSW1 */
83 	{ 0xbe03, 0xbe03, input_port_4_r }, /* DSW2 */
84 	{ 0xbf01, 0xbf01, input_port_0_r }, /* coin, start */
85 	{ 0xbf02, 0xbf02, input_port_1_r }, /* P1 controls */
86 	{ 0xbf03, 0xbf03, input_port_2_r }, /* P2 controls */
87 	{ -1 }
88 };
89 
90 static struct MemoryWriteAddress writemem[] =
91 {
92  	{ 0x0000, 0x3fff, MWA_ROM },
93 	{ 0x8000, 0x83ff, MWA_RAM }, /* working RAM */
94 	{ 0xa000, 0xa3ff, MWA_RAM, &mnchmobl_sprite_xpos },
95 	{ 0xa400, 0xa7ff, mnchmobl_sprite_xpos_w },
96 	{ 0xa800, 0xabff, MWA_RAM, &mnchmobl_sprite_tile },
97 	{ 0xac00, 0xafff, mnchmobl_sprite_tile_w },
98 	{ 0xb000, 0xb3ff, MWA_RAM, &mnchmobl_sprite_attr },
99 	{ 0xb400, 0xb7ff, mnchmobl_sprite_attr_w },
100 	{ 0xb800, 0xb9ff, mnchmobl_videoram_w, &videoram },
101 	{ 0xba00, 0xbbff, MWA_RAM },
102 	{ 0xbc00, 0xbc7f, MWA_RAM, &mnchmobl_status_vram },
103 	{ 0xbe00, 0xbe00, mnchmobl_soundlatch_w },
104 	{ 0xbe01, 0xbe01, mnchmobl_palette_bank_w },
105 	{ 0xbe11, 0xbe11, MWA_RAM }, /* ? */
106 	{ 0xbe21, 0xbe21, MWA_RAM }, /* ? */
107 	{ 0xbe31, 0xbe31, MWA_RAM }, /* ? */
108 	{ 0xbe41, 0xbe41, mnchmobl_flipscreen_w },
109 	{ 0xbe61, 0xbe61, mnchmobl_nmi_enable_w }, /* ENI 1-10C */
110 	{ 0xbf00, 0xbf07, MWA_RAM, &mnchmobl_vreg }, /* MY0 1-8C */
111 	{ -1 }
112 };
113 
114 static struct MemoryReadAddress readmem_sound[] =
115 {
116 	{ 0x0000, 0x1fff, MRA_ROM },
117 	{ 0x2000, 0x2000, soundlatch_r },
118 	{ 0xe000, 0xe7ff, MRA_RAM },
119 	{ -1 }
120 };
121 static struct MemoryWriteAddress writemem_sound[] =
122 {
123 	{ 0x0000, 0x1fff, MWA_ROM },
124 	{ 0x4000, 0x4000, AY8910_write_port_0_w },
125 	{ 0x5000, 0x5000, AY8910_control_port_0_w },
126 	{ 0x6000, 0x6000, AY8910_write_port_1_w },
127 	{ 0x7000, 0x7000, AY8910_control_port_1_w },
128 	{ 0x8000, 0x8000, MWA_NOP }, /* ? */
129 	{ 0xa000, 0xa000, MWA_NOP }, /* ? */
130 	{ 0xc000, 0xc000, MWA_NOP }, /* ? */
131 	{ 0xe000, 0xe7ff, MWA_RAM },
132 	{ -1 }
133 };
134 
135 static struct AY8910interface ay8910_interface =
136 {
137 	2,	/* 2 chips */
138 	1500000,	/* 1.5 MHz? */
139 	{ 50, 50 },
140 	{ 0 },
141 	{ 0 },
142 	{ 0 },
143 	{ 0 }
144 };
145 
146 INPUT_PORTS_START( mnchmobl )
147 	PORT_START
148 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
149 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
150 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) /* service */
151 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
152 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 )
153 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
154 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
155 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
156 
157 	PORT_START /* P1 controls */
158 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_UP | IPF_8WAY )
159 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_DOWN | IPF_8WAY )
160 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_LEFT | IPF_8WAY )
161 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_RIGHT | IPF_8WAY )
162 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_LEFT | IPF_2WAY )
163 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_RIGHT | IPF_2WAY )
164 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
165 
166 	PORT_START /* P2 controls */
167 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_UP | IPF_8WAY | IPF_COCKTAIL )
168 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_DOWN | IPF_8WAY | IPF_COCKTAIL )
169 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_LEFT | IPF_8WAY | IPF_COCKTAIL )
170 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_RIGHT | IPF_8WAY | IPF_COCKTAIL )
171 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_LEFT | IPF_2WAY | IPF_COCKTAIL )
172 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_RIGHT | IPF_2WAY | IPF_COCKTAIL )
173 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
174 
175 	PORT_START	/* DSW1 0xbe02 */
176 	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unknown ) )
177 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
178 	PORT_DIPSETTING(    0x01, DEF_STR( On ) )
179 	PORT_DIPNAME( 0x1e, 0x00, DEF_STR( Coinage ) )
180 	PORT_DIPSETTING(    0x14, DEF_STR( 3C_1C ) )
181 //	PORT_DIPSETTING(    0x12, DEF_STR( 2C_1C ) )
182 	PORT_DIPSETTING(    0x10, DEF_STR( 2C_1C ) )
183 	PORT_DIPSETTING(    0x16, DEF_STR( 3C_2C ) )
184 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
185 //	PORT_DIPSETTING(    0x1e, DEF_STR( 1C_1C ) )
186 //	PORT_DIPSETTING(    0x1c, DEF_STR( 1C_1C ) )
187 //	PORT_DIPSETTING(    0x1a, DEF_STR( 1C_1C ) )
188 //	PORT_DIPSETTING(    0x18, DEF_STR( 1C_1C ) )
189 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
190 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_3C ) )
191 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_4C ) )
192 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_5C ) )
193 	PORT_DIPSETTING(    0x0a, DEF_STR( 1C_6C ) )
194 	PORT_DIPSETTING(    0x0c, DEF_STR( 1C_7C ) )
195 	PORT_DIPSETTING(    0x0e, DEF_STR( 1C_8C ) )
196 	PORT_DIPNAME( 0xe0, 0x00, DEF_STR( Bonus_Life ) )
197 	PORT_DIPSETTING(    0x00, "No Bonus" )
198 	PORT_DIPSETTING(    0x20, "70000" )
199 	PORT_DIPSETTING(    0x40, "60000" )
200 	PORT_DIPSETTING(    0x60, "50000" )
201 	PORT_DIPSETTING(    0x80, "40000" )
202 	PORT_DIPSETTING(    0xa0, "30000" )
203 	PORT_DIPSETTING(    0xc0, "20000" )
204 	PORT_DIPSETTING(    0xe0, "10000" )
205 
206 	PORT_START	/* DSW2 0xbe03 */
207 	PORT_DIPNAME( 0x03, 0x00, "Second Bonus Life" )
208 	PORT_DIPSETTING(    0x00, "No Bonus?" )
209 	PORT_DIPSETTING(    0x01, "100000?" )
210 	PORT_DIPSETTING(    0x02, "40000?" )
211 	PORT_DIPSETTING(    0x03, "30000?" )
212 	PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Lives ) )
213 	PORT_DIPSETTING(    0x00, "1" )
214 	PORT_DIPSETTING(    0x04, "2" )
215 	PORT_DIPSETTING(    0x08, "3" )
216 	PORT_DIPSETTING(    0x0c, "5" )
217 	PORT_DIPNAME( 0x10, 0x00, "Freeze" )
218 	PORT_DIPSETTING(    0x00, DEF_STR( No ) )
219 	PORT_DIPSETTING(    0x10, DEF_STR( Yes ) )
220 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) )
221 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
222 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
223 	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Cabinet ) )
224 	PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
225 	PORT_DIPSETTING(    0x40, DEF_STR( Cocktail ) )
226 	PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
227 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
228 	PORT_DIPSETTING(    0x80, DEF_STR( On ) )
229 INPUT_PORTS_END
230 
231 static struct GfxLayout char_layout =
232 {
233 	8,8,
234 	256,
235 	4,
236 	{ 0, 8, 256*128,256*128+8 },
237 	{ 7,6,5,4,3,2,1,0 },
238 	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
239 	128
240 };
241 
242 static struct GfxLayout tile_layout =
243 {
244 	8,8,
245 	0x100,
246 	4,
247 	{ 8,12,0,4 },
248 	{ 0,0,1,1,2,2,3,3 },
249 	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
250 	128
251 };
252 
253 static struct GfxLayout sprite_layout1 =
254 {
255 	32,32,
256 	128,
257 	3,
258 	{ 0x4000*8,0x2000*8,0 },
259 	{
260 		7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0,
261 		0x8000+7,0x8000+7,0x8000+6,0x8000+6,0x8000+5,0x8000+5,0x8000+4,0x8000+4,
262 		0x8000+3,0x8000+3,0x8000+2,0x8000+2,0x8000+1,0x8000+1,0x8000+0,0x8000+0
263 	},
264 	{
265 		 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
266 		 8*8, 9*8,10*8,11*8,12*8,13*8,14*8,15*8,
267 		16*8,17*8,18*8,19*8,20*8,21*8,22*8,23*8,
268 		24*8,25*8,26*8,27*8,28*8,29*8,30*8,31*8
269 	},
270 	256
271 };
272 
273 static struct GfxLayout sprite_layout2 =
274 {
275 	32,32,
276 	128,
277 	3,
278 	{ 0,0,0 },
279 	{
280 		7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0,
281 		0x8000+7,0x8000+7,0x8000+6,0x8000+6,0x8000+5,0x8000+5,0x8000+4,0x8000+4,
282 		0x8000+3,0x8000+3,0x8000+2,0x8000+2,0x8000+1,0x8000+1,0x8000+0,0x8000+0
283 	},
284 	{
285 		 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
286 		 8*8, 9*8,10*8,11*8,12*8,13*8,14*8,15*8,
287 		16*8,17*8,18*8,19*8,20*8,21*8,22*8,23*8,
288 		24*8,25*8,26*8,27*8,28*8,29*8,30*8,31*8
289 	},
290 	256
291 };
292 
293 static struct GfxDecodeInfo gfxdecodeinfo[] =
294 {
295 	{ REGION_GFX1, 0,      &char_layout,      0,  4 },	/* colors   0- 63 */
296 	{ REGION_GFX2, 0x1000, &tile_layout,     64,  4 },	/* colors  64-127 */
297 	{ REGION_GFX3, 0,      &sprite_layout1, 128, 16 },	/* colors 128-255 */
298 	{ REGION_GFX4, 0,      &sprite_layout2, 128, 16 },	/* colors 128-255 */
299 	{ -1 }
300 };
301 
302 static struct MachineDriver machine_driver_munchmo =
303 {
304 	{
305 		{
306 			CPU_Z80,
307 			3750000, /* ? */
308 			readmem,writemem,0,0,
309 			mnchmobl_interrupt,2
310 		},
311 		{
312 			CPU_Z80 | CPU_AUDIO_CPU,
313 			3750000, /* ? */
314 			readmem_sound,writemem_sound,0,0,
315 			nmi_interrupt,1
316 		}
317 	},
318 	57, DEFAULT_REAL_60HZ_VBLANK_DURATION,	/* frames per second, vblank duration */
319 	1,
320 	0,
321 
322 	/* video hardware */
323 	256+32+32, 256, { 0, 255+32+32,0, 255-16 },
324 	gfxdecodeinfo,
325 	256,256,
326 	mnchmobl_convert_color_prom,
327 
328 	VIDEO_TYPE_RASTER,
329 	0,
330 	mnchmobl_vh_start,
331 	mnchmobl_vh_stop,
332 	mnchmobl_vh_screenrefresh,
333 
334 	/* sound hardware */
335 	0,0,0,0,
336 	{
337 		{
338 			SOUND_AY8910,
339 			&ay8910_interface
340 		}
341 	}
342 };
343 
344 
345 ROM_START( joyfulr )
346 	ROM_REGION( 0x10000, REGION_CPU1 ) /* 64k for CPUA */
347 	ROM_LOAD( "m1j.10e", 0x0000, 0x2000, 0x1fe86e25 )
348 	ROM_LOAD( "m2j.10d", 0x2000, 0x2000, 0xb144b9a6 )
349 
350 	ROM_REGION( 0x10000, REGION_CPU2 ) /* 64k for sound CPU */
351 	ROM_LOAD( "mu.2j",	 0x0000, 0x2000, 0x420adbd4 )
352 
353 	ROM_REGION( 0x2000, REGION_GFX1 | REGIONFLAG_DISPOSE )
354 	ROM_LOAD( "s1.10a",	 0x0000, 0x1000, 0xc0bcc301 )	/* characters */
355 	ROM_LOAD( "s2.10b",	 0x1000, 0x1000, 0x96aa11ca )
356 
357 	ROM_REGION( 0x2000, REGION_GFX2 )
358 	ROM_LOAD( "b1.2c",	 0x0000, 0x1000, 0x8ce3a403 )	/* tile layout */
359 	ROM_LOAD( "b2.2b",	 0x1000, 0x1000, 0x0df28913 )	/* 4x8 tiles */
360 
361 	ROM_REGION( 0x6000, REGION_GFX3 | REGIONFLAG_DISPOSE )
362 	ROM_LOAD( "f1j.1g",	 0x0000, 0x2000, 0x93c3c17e )	/* sprites */
363 	ROM_LOAD( "f2j.3g",	 0x2000, 0x2000, 0xb3fb5bd2 )
364 	ROM_LOAD( "f3j.5g",	 0x4000, 0x2000, 0x772a7527 )
365 
366 	ROM_REGION( 0x2000, REGION_GFX4 | REGIONFLAG_DISPOSE )
367 	ROM_LOAD( "h",		 0x0000, 0x2000, 0x332584de )	/* monochrome sprites */
368 
369 	ROM_REGION( 0x0100, REGION_PROMS )
370 	ROM_LOAD( "a2001.clr", 0x0000, 0x0100, 0x1b16b907 ) /* color prom */
371 ROM_END
372 
373 ROM_START( mnchmobl )
374 	ROM_REGION( 0x10000, REGION_CPU1 ) /* 64k for CPUA */
375 	ROM_LOAD( "m1.10e",	 0x0000, 0x2000, 0xa4bebc6a )
376 	ROM_LOAD( "m2.10d",	 0x2000, 0x2000, 0xf502d466 )
377 
378 	ROM_REGION( 0x10000, REGION_CPU2 ) /* 64k for sound CPU */
379 	ROM_LOAD( "mu.2j",	 0x0000, 0x2000, 0x420adbd4 )
380 
381 	ROM_REGION( 0x2000, REGION_GFX1 | REGIONFLAG_DISPOSE )
382 	ROM_LOAD( "s1.10a",	 0x0000, 0x1000, 0xc0bcc301 )	/* characters */
383 	ROM_LOAD( "s2.10b",	 0x1000, 0x1000, 0x96aa11ca )
384 
385 	ROM_REGION( 0x2000, REGION_GFX2 )
386 	ROM_LOAD( "b1.2c",	 0x0000, 0x1000, 0x8ce3a403 )	/* tile layout */
387 	ROM_LOAD( "b2.2b",	 0x1000, 0x1000, 0x0df28913 )	/* 4x8 tiles */
388 
389 	ROM_REGION( 0x6000, REGION_GFX3 | REGIONFLAG_DISPOSE )
390 	ROM_LOAD( "f1.1g",	 0x0000, 0x2000, 0xb75411d4 )	/* sprites */
391 	ROM_LOAD( "f2.3g",	 0x2000, 0x2000, 0x539a43ba )
392 	ROM_LOAD( "f3.5g",	 0x4000, 0x2000, 0xec996706 )
393 
394 	ROM_REGION( 0x2000, REGION_GFX4 | REGIONFLAG_DISPOSE )
395 	ROM_LOAD( "h",		 0x0000, 0x2000, 0x332584de )	/* monochrome sprites */
396 
397 	ROM_REGION( 0x0100, REGION_PROMS )
398 	ROM_LOAD( "a2001.clr", 0x0000, 0x0100, 0x1b16b907 ) /* color prom */
399 ROM_END
400 
401 
402 GAME( 1983, joyfulr,  0,       munchmo, mnchmobl, 0, ROT270, "SNK", "Joyful Road (US)" )
403 GAME( 1983, mnchmobl, joyfulr, munchmo, mnchmobl, 0, ROT270, "SNK (Centuri license)", "Munch Mobile (Japan)" )
404