1 /*
2 
3   Malzak
4 
5   Driver by Reip, Barry Rodewald
6   SAA 5050 display code "borrowed" from the Philips 2000T/2000M driver in MESS
7 
8   Basic memory map
9 
10 	0x0000 - 0x0fff | S2650 code [malzak.5, malzak.4, malzak.2 (data only)]
11 	0x1000 - 0x13ff | Work RAM
12 	0x1400 - 0x14ff | S2636 #1 video
13 	0x1500 - 0x15ff | S2636 #2 video
14 	0x1600 - 0x16ff | Playfield gfx
15 	0x1700 - 0x17ff | Work RAM - contains hiscore table, coin count
16 	0x1800 - 0x1fff | SAA 5050 video RAM
17 
18   TODO - I/O ports (0x00 for sprite->background collisions)
19          sound (2x SN76477)
20 		 playfield graphics may be banked, tiles above 0x1f are incorrect
21 		 sprite->sprite collision aren't quite perfect
22 		   (you can often fly through flying missiles)
23 
24 */
25 
26 #include "driver.h"
27 #include "vidhrdw/generic.h"
28 #include "vidhrdw/s2636.h"
29 #include "cpu/s2650/s2650.h"
30 
31 #define SAA5050_VBLANK 2500
32 
33 
34 extern int temp_x,temp_y;
35 
36 extern unsigned char* saa5050_vidram;  /* Video RAM for SAA 5050 */
37 extern unsigned char* malzak_s2636_1_ram;  /* Video RAM for S2636 #1 */
38 extern unsigned char* malzak_s2636_2_ram;  /* Video RAM for S2636 #2 */
39 extern unsigned char s2636_1_dirty[4];
40 extern unsigned char s2636_2_dirty[4];
41 
42 /* in vidhrdw/malzak.c*/
43 VIDEO_START( malzak );
44 VIDEO_UPDATE( malzak );
45 WRITE_HANDLER( playfield_w );
46 
READ_HANDLER(malzak_s2636_1_r)47 READ_HANDLER( malzak_s2636_1_r )
48 {
49 	return malzak_s2636_1_ram[offset];
50 }
51 
READ_HANDLER(malzak_s2636_2_r)52 READ_HANDLER( malzak_s2636_2_r )
53 {
54 	return malzak_s2636_2_ram[offset];
55 }
56 
WRITE_HANDLER(malzak_s2636_1_w)57 WRITE_HANDLER( malzak_s2636_1_w )
58 {
59 	s2636_w(malzak_s2636_1_ram,offset,data,s2636_1_dirty);
60 }
61 
WRITE_HANDLER(malzak_s2636_2_w)62 WRITE_HANDLER( malzak_s2636_2_w )
63 {
64 	s2636_w(malzak_s2636_2_ram,offset,data,s2636_2_dirty);
65 }
66 
67 
READ_HANDLER(saa5050_r)68 static READ_HANDLER( saa5050_r )
69 {
70 	return saa5050_vidram[offset];
71 }
72 
WRITE_HANDLER(saa5050_w)73 static WRITE_HANDLER( saa5050_w )
74 {
75 	saa5050_vidram[offset] = data;
76 }
77 
READ_HANDLER(fake_VRLE_r)78 static READ_HANDLER( fake_VRLE_r )
79 {
80 	return (malzak_s2636_1_ram[0xcb] & 0x3f) + (cpu_getvblank()*0x40);
81 }
82 
READ_HANDLER(ram_mirror_r)83 static READ_HANDLER( ram_mirror_r )
84 {
85 	return cpu_readmem16(0x1000+offset);
86 }
87 
WRITE_HANDLER(ram_mirror_w)88 static WRITE_HANDLER( ram_mirror_w )
89 {
90 	cpu_writemem16(0x1000+offset,data);
91 }
92 
93 
MEMORY_READ_START(readmem)94 static MEMORY_READ_START( readmem )
95 	{ 0x0000, 0x0fff, MRA_ROM },
96 	{ 0x1000, 0x10ff, MRA_RAM },
97 	{ 0x1100, 0x11ff, MRA_RAM },
98 	{ 0x1200, 0x12ff, MRA_RAM },
99 	{ 0x1300, 0x13ff, MRA_RAM },
100 	{ 0x14cb, 0x14cb, fake_VRLE_r },
101 	{ 0x1400, 0x14ff, malzak_s2636_1_r },
102 	{ 0x1500, 0x15ff, malzak_s2636_2_r },
103 	{ 0x1600, 0x16ff, MRA_RAM },
104 	{ 0x1700, 0x17ff, MRA_RAM },
105 	{ 0x1800, 0x1fff, saa5050_r },  /* SAA 5050 video RAM*/
106 	{ 0x2000, 0x2fff, MRA_ROM },
107 	{ 0x3000, 0x3fff, ram_mirror_r },
108 	{ 0x4000, 0x4fff, MRA_ROM },
109 	{ 0x5000, 0x5fff, ram_mirror_r },
110 
111 MEMORY_END
112 
113 
114 static MEMORY_WRITE_START( writemem )
115 	{ 0x0000, 0x0fff, MWA_ROM },
116 	{ 0x1000, 0x10ff, MWA_RAM },
117 	{ 0x1100, 0x11ff, MWA_RAM },
118 	{ 0x1200, 0x12ff, MWA_RAM },
119 	{ 0x1300, 0x13ff, MWA_RAM },
120 	{ 0x1400, 0x14ff, malzak_s2636_1_w }, /* S2636 offset $CB bit 40 tested as collision ?*/
121 	{ 0x1500, 0x15ff, malzak_s2636_2_w },
122 	{ 0x1600, 0x16ff, playfield_w },
123 	{ 0x1600, 0x16ff, MWA_RAM },
124 	{ 0x1700, 0x17ff, MWA_RAM },
125 	{ 0x1800, 0x1fff, saa5050_w },  /* SAA 5050 video RAM*/
126 	{ 0x2000, 0x2fff, MWA_ROM },
127 	{ 0x3000, 0x3fff, ram_mirror_w },
128 	{ 0x4000, 0x4fff, MWA_ROM },
129 	{ 0x5000, 0x5dff, ram_mirror_w },
130 
131 MEMORY_END
132 
133 static READ_HANDLER( s2650_data_r )
134 {
135 	usrintf_showmessage("S2650 data port read");
136 	return 0xff;
137 }
138 
WRITE_HANDLER(port40_w)139 static WRITE_HANDLER( port40_w )
140 {
141 /*	usrintf_showmessage("S2650 [0x%04x]: port 0x40 write: 0x%02x",cpunum_get_pc_byte(0),data);*/
142 /*	if(data & 0x01)*/
143 /*		irqenable = 1;*/
144 /*	else*/
145 /*		irqenable = 0;*/
146 }
147 
WRITE_HANDLER(port60_w)148 static WRITE_HANDLER( port60_w )
149 {
150 	temp_x = data;
151 }
152 
WRITE_HANDLER(portc0_w)153 static WRITE_HANDLER( portc0_w )
154 {
155 	temp_y = data;
156 }
157 
READ_HANDLER(collision_r)158 static READ_HANDLER( collision_r )
159 {
160 	/* High 4 bits seem to refer to the row affected.*/
161 	static int counter;
162 
163 	if(++counter > 15)
164 		counter = 0;
165 	return 0xd0 + counter;
166 }
167 
PORT_READ_START(readport)168 static PORT_READ_START( readport )
169 	{ 0x00, 0x00, collision_r }, /* returns where a collision can occur.*/
170     { 0x80, 0x80, input_port_0_r },  /*controls*/
171 	{ S2650_DATA_PORT, S2650_DATA_PORT, s2650_data_r },  /* read upon death*/
172     { S2650_SENSE_PORT, S2650_SENSE_PORT, input_port_3_r },
173 PORT_END
174 
175 static PORT_WRITE_START( writeport )
176 	{ 0x40, 0x40, port40_w },  /* possibly sound codes for dual SN76477s*/
177 	{ 0x60, 0x60, port60_w },  /* possibly playfield scroll X offset*/
178 	{ 0xa0, 0xa0, MWA_NOP },  /* echoes I/O port read from port 0x80*/
179 	{ 0xc0, 0xc0, portc0_w },  /* possibly playfield scroll Y offset*/
180 PORT_END
181 
182 INPUT_PORTS_START( malzak )
183 
184 	/* Malzak has a stick (not sure if it's 4-way or 8-way),
185 	   and only one button (firing and bomb dropping on the same button) */
186 
187 	PORT_START /* I/O port 0x80 */
188 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
189 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
190 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 )
191 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START2 )
192 	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )
193 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT  )
194 	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT  )
195 	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP    )
196 
197     PORT_START
198 /*	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ) )*/
199 /*	PORT_DIPSETTING(    0x00, "3" )*/
200 /*	PORT_DIPSETTING(    0x01, "4" )*/
201 /*    PORT_DIPNAME( 0x02, 0x00, "Lightning Speed" )*/
202 /*	PORT_DIPSETTING(    0x00, "Slow" )*/
203 /*	PORT_DIPSETTING(    0x02, "Fast" )*/
204 /*	PORT_DIPNAME( 0x1C, 0x04, DEF_STR( Coinage ) )*/
205 /*	PORT_DIPSETTING(	0x00, DEF_STR( 2C_1C ) )*/
206 /*	PORT_DIPSETTING(	0x04, DEF_STR( 1C_1C ) )*/
207 /*	PORT_DIPSETTING(	0x08, DEF_STR( 1C_2C ) )*/
208 /*	PORT_DIPSETTING(	0x0C, DEF_STR( 1C_3C ) )*/
209 /*	PORT_DIPSETTING(	0x10, DEF_STR( 1C_4C ) )*/
210 /*	PORT_DIPSETTING(	0x14, DEF_STR( 1C_5C ) )*/
211 /*	PORT_DIPSETTING(	0x18, DEF_STR( 1C_6C ) )*/
212 /*	PORT_DIPSETTING(	0x1C, DEF_STR( 1C_7C ) )*/
213 /*	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Bonus_Life ) )*/
214 /*	PORT_DIPSETTING(    0x00, "1000" )*/
215 /*	PORT_DIPSETTING(    0x20, "1500" )*/
216   /*  PORT_DIPNAME( 0x40, 0x00, "Extended Play" )*/
217 /*	PORT_DIPSETTING(    0x00, DEF_STR( No ) )*/
218 /*	PORT_DIPSETTING(    0x40, DEF_STR( Yes ) )*/
219 
220 	PORT_START
221 /*	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN3 )*/
222 /*	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )*/
223 /*	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )*/
224 /*	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )*/
225 /*	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )*/
226 /*	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT  | IPF_4WAY )*/
227 /*	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN  | IPF_4WAY )*/
228 /*	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP  | IPF_4WAY )*/
229 
230 	PORT_START	/* SENSE */
231 	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_VBLANK )
232 
233 INPUT_PORTS_END
234 
235 static struct GfxLayout charlayout =
236 {
237 	16,16,
238 	RGN_FRAC(1,1),
239 	1,
240 	{ 0 },
241 	{ 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 },
242 	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16,
243 	  8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16 },
244 /*	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },*/
245 	16*16
246 /*	8*8*/
247 };
248 
249 static struct GfxLayout s2636_character10 =
250 {
251 	8,10,
252 	5,
253 	1,
254 	{ 0 },
255 	{ 0,1,2,3,4,5,6,7 },
256    	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 },
257 	8*16
258 };
259 
260 static struct GfxLayout saa5050_charlayout =
261 {
262 	6, 10,
263 	256,
264 	1,
265 	{ 0 },
266 	{ 2, 3, 4, 5, 6, 7 },
267 	{ 0*8, 1*8, 2*8, 3*8, 4*8,
268 	  5*8, 6*8, 7*8, 8*8, 9*8 },
269 	8 * 10
270 };
271 
272 static struct GfxLayout saa5050_hilayout =
273 {
274 	6, 10,
275 	256,
276 	1,
277 	{ 0 },
278 	{ 2, 3, 4, 5, 6, 7 },
279 	{ 0*8, 0*8, 1*8, 1*8, 2*8,
280 	  2*8, 3*8, 3*8, 4*8, 4*8 },
281 	8 * 10
282 };
283 
284 static struct GfxLayout saa5050_lolayout =
285 {
286 	6, 10,
287 	256,
288 	1,
289 	{ 0 },
290 	{ 2, 3, 4, 5, 6, 7 },
291 	{ 5*8, 5*8, 6*8, 6*8, 7*8,
292 	  7*8, 8*8, 8*8, 9*8, 9*8 },
293 	8 * 10
294 };
295 
296 static unsigned char saa5050_palette[8 * 3] =
297 {
298 	0x00, 0x00, 0x00,	/* black */
299 	0xff, 0x00, 0x00,	/* red */
300 	0x00, 0xff, 0x00,	/* green */
301 	0xff, 0xff, 0x00,	/* yellow */
302 	0x00, 0x00, 0xff,	/* blue */
303 	0xff, 0x00, 0xff,	/* magenta */
304 	0x00, 0xff, 0xff,	/* cyan */
305 	0xff, 0xff, 0xff	/* white */
306 };
307 
308 /* bgnd, fgnd */
309 static	unsigned	short	saa5050_colortable[64 * 2] =
310 {
311 	0,1, 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7,
312 	1,0, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7,
313 	2,0, 2,1, 2,2, 2,3, 2,4, 2,5, 2,6, 2,7,
314 	3,0, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7,
315 	4,0, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7,
316 	5,0, 5,1, 5,2, 5,3, 5,4, 5,5, 5,6, 5,7,
317 	6,0, 6,1, 6,2, 6,3, 6,4, 6,5, 6,6, 6,7,
318 	7,0, 7,1, 7,2, 7,3, 7,4, 7,5, 7,6, 7,7
319 };
320 
321 /*add s2636 decodes here (i.e. from zac2650) and maybe re-arrange them*/
322 static struct GfxDecodeInfo malzak_gfxdecodeinfo[] =
323 {
324 	{ REGION_GFX1, 0, &charlayout,  0, 16 },
325   	{ REGION_CPU1, 0x0000, &s2636_character10, 0, 8 },	/* s2636 #1  */
326 	{ REGION_CPU1, 0x0000, &s2636_character10, 0, 8 },	/* s2636 #2  */
327 	{ REGION_GFX2, 0x0000, &saa5050_charlayout, 0, 128},
328 	{ REGION_GFX2, 0x0000, &saa5050_hilayout, 0, 128},
329 	{ REGION_GFX2, 0x0000, &saa5050_lolayout, 0, 128},
330 	{ -1 } /* end of array */
331 };
332 
333 static int val = -1;
334 
INTERRUPT_GEN(malzak_interrupt)335 static INTERRUPT_GEN( malzak_interrupt )
336 {
337 /*	if(irqenable != 0)*/
338 /*		cpu_set_irq_line_and_vector(0,0,HOLD_LINE,0x0300);*/
339 }
340 
PALETTE_INIT(malzak)341 static PALETTE_INIT( malzak )
342 {
343 	palette_set_colors(0, saa5050_palette, sizeof(saa5050_palette) / 3);
344 	memcpy(colortable, saa5050_colortable, sizeof (saa5050_colortable));
345 }
346 
347 
MACHINE_INIT(malzak)348 MACHINE_INIT(malzak)
349 {
350 	val++;
351 	log_cb(RETRO_LOG_DEBUG, LOGPRE "val = %X\n",val);
352 }
353 
354 static struct SN76477interface sn76477_intf =
355 {  /* probably not correct */
356 	2,	/* 2 chips */
357 	{ 25,25 },  /* mixing level   pin description		 */
358 	{ 0,0	/* N/C */},		/*	4  noise_res		 */
359 	{ 0,0	/* N/C */},		/*	5  filter_res		 */
360 	{ 0,0	/* N/C */},		/*	6  filter_cap		 */
361 	{ 0,0	/* N/C */},		/*	7  decay_res		 */
362 	{ 0,0	/* N/C */},		/*	8  attack_decay_cap  */
363 	{ RES_K(100),RES_K(100) },		/* 10  attack_res		 */
364 	{ RES_K(56), RES_K(56)  },		/* 11  amplitude_res	 */
365 	{ RES_K(10), RES_K(10)  },		/* 12  feedback_res 	 */
366 	{ 0,0	/* N/C */},		/* 16  vco_voltage		 */
367 	{ CAP_U(0.1),CAP_U(0.1) },		/* 17  vco_cap			 */
368 	{ RES_K(8.2),RES_K(8.2) },		/* 18  vco_res			 */
369 	{ 5.0, 5.0		 },		/* 19  pitch_voltage	 */
370 	{ RES_K(120), RES_K(120) },		/* 20  slf_res			 */
371 	{ CAP_U(1.0),CAP_U(1.0) },		/* 21  slf_cap			 */
372 	{ 0,0	/* N/C */},		/* 23  oneshot_cap		 */
373 	{ 0,0	/* N/C */}		/* 24  oneshot_res		 */
374 };
375 
376 
377 static MACHINE_DRIVER_START( malzak )
378 
379 	/* basic machine hardware */
380 	MDRV_CPU_ADD(S2650, 3800000/4/3)
381 	MDRV_CPU_MEMORY(readmem,writemem)
382 	MDRV_CPU_PORTS(readport,writeport)
383 /*	MDRV_CPU_VBLANK_INT(malzak_interrupt,1)*/
384 
385 	MDRV_FRAMES_PER_SECOND(50)
386 	MDRV_VBLANK_DURATION(SAA5050_VBLANK)
387 
388 	/* video hardware */
389 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
390 	MDRV_SCREEN_SIZE(240, 240)
391 	MDRV_VISIBLE_AREA(0, 239, 0, 239)
392 	MDRV_GFXDECODE(malzak_gfxdecodeinfo)
393 	MDRV_PALETTE_LENGTH(16)
394 	MDRV_PALETTE_INIT(malzak)
395 	MDRV_COLORTABLE_LENGTH(128)
396 
397 	MDRV_MACHINE_INIT(malzak)
398 
399 	MDRV_VIDEO_START(malzak)
400 	MDRV_VIDEO_UPDATE(malzak)
401 
402 	/* sound hardware */
403 	MDRV_SOUND_ADD(SN76477,sn76477_intf);
404 
405 MACHINE_DRIVER_END
406 
407 ROM_START( malzak )
408 	ROM_REGION( 0x8000, REGION_CPU1, 0 )
409 	ROM_LOAD( "malzak.5",     0x0000, 0x0800, CRC(75355c98) SHA1(7036ed5d9ee38585b1a6bc204d410d5fb5ddd81f) )
410 	ROM_CONTINUE( 0x2000, 0x0800 )
411 	ROM_LOAD( "malzak.4",     0x0800, 0x0400, CRC(744c81e3) SHA1(c08d6df3cf2808a5f99d8247fc19a59be88121a9) )
412 	ROM_CONTINUE( 0x4000, 0x0c00 )
413 	ROM_LOAD( "malzak.2",     0x0c00, 0x0800, CRC(2a12ad67) SHA1(f89a50b62311a170004c061abd8dedc3ebd84748) )
414 	ROM_LOAD( "malzak.3",     0x4400, 0x0800, CRC(b947229e) SHA1(37b88b5aa91a483fcfe60a9bdd67a66f6378c487) )
415 
416 	ROM_REGION(0x0800, REGION_USER1, 0)
417 
418 	ROM_REGION( 0x0800, REGION_GFX1, ROMREGION_DISPOSE )
419 	ROM_LOAD( "malzak.1",     0x0000, 0x0800, CRC(74d5ff7b) SHA1(cae326370dc83b86542f9d070e2dc91b1b833356) )
420 
421 	ROM_REGION(0x01000, REGION_GFX2,0) /* internal character set?*/
422 	ROM_LOAD("p2000.chr", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e))
423 
424 ROM_END
425 
426 GAMEX( 19??, malzak,   0,       malzak, malzak, 0,        ROT0, "Kitronix", "Malzak", GAME_NOT_WORKING | GAME_NO_SOUND )
427