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