1 /****************************************************************************
2 
3 Wall Crash by Midcoin (c) 1984
4 
5 
6 Driver by Jarek Burczynski
7 2002.12.23
8 
9 
10 
11 
12      DIPSW-8     AY-3-8912                               DIPSW-4
13                                                          DIPSW-4
14 
15 						74s288
16 
17 
18                                                WAC1   WAC2   WAC3
19                                                (2532) (2532) (2532)
20 12.288MHz
21 
22    +------------+        2114  2114  2114  2114
23    + EPOXY WITH +                                +-------+
24    + LS08       +      WAC05  WAC1/52   EMPTY    + SMALL +
25    +LS240, LS245+      (2764) (2764)    SOCKET   + EPOXY +
26    + Z80        +                                +-------+
27    +------------+
28 
29 The bigger Epoxy brick contains three standard 74LSxxx chips and is used as
30 DATA lines decoder for all READS from addresses in range: 0..0x7fff.
31 The pinout (of the whole brick) is 1:1 Z80 and it can be replaced with
32 a plain Z80, given that decoded ROMS are put in place of WAC05 and WAC1/52.
33 
34 The smaller Epoxy contains:
35  5 chips (names sanded off...): 20 pins, 8 pins, 14 pins, 16 pins, 16 pins,
36  1 resistor: 120 Ohm
37  1 probably resistor: measured: 1000 Ohm
38  1 diode: standard 1N4148 (info from HIGHWAYMAN)
39  4 capacitors: 3 same: blue ones probably 10n , 1 smaller 1.3n (measured by HIGHWAYMAN)
40 It's mapped as ROM at 0x6000-0x7fff but is NOT accessed by the CPU.
41 It's also not needed for emulation.
42 
43 
44 Thanks to Dox for donating PCB.
45 Thanks to HIGHWAYMAN for providing info on how to get to these epoxies
46 (heat gun) and for info (very close one) on decoding.
47 
48 ****************************************************************************/
49 
50 #include "driver.h"
51 #include "vidhrdw/generic.h"
52 #include "vidhrdw/res_net.h"
53 
54 static struct tilemap *bg_tilemap;
55 
56 /***************************************************************************
57 
58   Convert the color PROMs into a more useable format.
59 
60   Wall Crash has one 32 bytes palette PROM, connected to the RGB output this
61   way:
62 
63   bit 6 -- 330 ohm resistor --+-- 330 ohm pulldown resistor -- RED
64   bit 5 -- 220 ohm resistor --/
65 
66   bit 4 -- NC
67 
68   bit 3 -- 330 ohm resistor --+-- 330 ohm pulldown resistor -- GREEN
69   bit 2 -- 220 ohm resistor --/
70 
71   bit 1 -- 330 ohm resistor --+--+-- 330 ohm pulldown resistor -- BLUE
72   bit 0 -- 220 ohm resistor --/  |
73                                  |
74   bit 7 -+- diode(~655 Ohm)------/
75          \------220 ohm pullup (+5V) resistor
76 
77 
78 ***************************************************************************/
79 
PALETTE_INIT(wallc)80 static PALETTE_INIT( wallc )
81 {
82 	int i;
83 
84 	const int resistances_rg[2] = { 330, 220 };
85 	const int resistances_b[3] = { 655, 330, 220 };
86 	double weights_r[2], weights_g[2], weights_b[3];
87 
88 	compute_resistor_weights(0,	255,	-1.0,
89 			2,	resistances_rg,	weights_r,	330,	0,
90 			2,	resistances_rg,	weights_g,	330,	0,
91 			3,	resistances_b,	weights_b,	330,	655+220);
92 
93 	for (i = 0;i < Machine->drv->total_colors;i++)
94 	{
95 		int bit0,bit1,bit7,r,g,b;
96 
97 		/* red component */
98 		bit0 = (color_prom[i] >> 5) & 0x01;
99 		bit1 = (color_prom[i] >> 6) & 0x01;
100 		r = combine_2_weights(weights_r, bit1, bit0);
101 
102 		/* green component */
103 		bit0 = (color_prom[i] >> 2) & 0x01;
104 		bit1 = (color_prom[i] >> 3) & 0x01;
105 		g = combine_2_weights(weights_g, bit1, bit0);
106 
107 		/* blue component */
108 		bit0 = (color_prom[i] >> 0) & 0x01;
109 		bit1 = (color_prom[i] >> 1) & 0x01;
110 		bit7 = (color_prom[i] >> 7) & 0x01;
111 		b = combine_3_weights(weights_b, bit7, bit1, bit0);
112 
113 		palette_set_color(i,r,g,b);
114 	}
115 }
116 
WRITE_HANDLER(wallc_videoram_w)117 static WRITE_HANDLER( wallc_videoram_w )
118 {
119 	if (videoram[offset] != data)
120 	{
121 		videoram[offset] = data;
122 		tilemap_mark_tile_dirty(bg_tilemap, offset);
123 	}
124 }
125 
get_bg_tile_info(int tile_index)126 static void get_bg_tile_info(int tile_index)
127 {
128 	int code = videoram[tile_index] + 0x100;
129 	int color = 1;
130 
131 	SET_TILE_INFO(0, code, color, 0)
132 }
133 
VIDEO_START(wallc)134 VIDEO_START( wallc )
135 {
136 	bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_cols_flip_y,
137 		TILEMAP_OPAQUE, 8, 8, 32, 32);
138 
139 	if ( !bg_tilemap )
140 		return 1;
141 
142 	return 0;
143 }
144 
VIDEO_UPDATE(wallc)145 VIDEO_UPDATE( wallc )
146 {
147 	tilemap_draw(bitmap, &Machine->visible_area, bg_tilemap, 0, 0);
148 }
149 
150 static int wcb0=-1;
WRITE_HANDLER(wc_b0)151 static WRITE_HANDLER( wc_b0 )
152 {
153 	if (wcb0!=data)
154 	{
155 		wcb0 = data;
156 		/*logerror("wcb0=%i pc=%4x\n",wcb0, activecpu_get_pc() );*/
157 	}
158 }
159 static int wcb1=-1;
WRITE_HANDLER(wc_b1)160 static WRITE_HANDLER( wc_b1 )
161 {
162 	if (wcb1!=data)
163 	{
164 		wcb1 = data;
165 		/*logerror("wcb1=%i pc=%4x\n",wcb1, activecpu_get_pc() );*/
166 	}
167 }
168 static int wcb2=-1;
WRITE_HANDLER(wc_b2)169 static WRITE_HANDLER( wc_b2 )
170 {
171 	if (wcb2!=data)
172 	{
173 		wcb2 = data;
174 		/*logerror("wcb2=%i pc=%4x\n",wcb2, activecpu_get_pc() );*/
175 	}
176 }
177 
MEMORY_READ_START(readmem)178 static MEMORY_READ_START( readmem )
179 	{ 0x0000, 0x3fff, MRA_ROM },
180 
181 	{ 0x8000, 0x83ff, MRA_RAM },
182 	{ 0x8400, 0x87ff, MRA_RAM }, /* mirror */
183 	{ 0x8800, 0x8bff, MRA_RAM }, /* mirror */
184 	{ 0x8c00, 0x8fff, MRA_RAM }, /* mirror */
185 
186 	{ 0xa000, 0xa3ff, MRA_RAM },
187 
188 	{ 0xb000, 0xb000, input_port_0_r },
189 	{ 0xb200, 0xb200, input_port_1_r },
190 	{ 0xb400, 0xb400, input_port_2_r },
191 	{ 0xb600, 0xb600, input_port_3_r },
192 MEMORY_END
193 
194 
195 static MEMORY_WRITE_START( writemem )
196 	{ 0x0000, 0x7fff, MWA_ROM },
197 
198 	{ 0x8000, 0x83ff, wallc_videoram_w, &videoram },	/* 2114, 2114 */
199 	{ 0x8400, 0x87ff, wallc_videoram_w },	/* mirror */
200 	{ 0x8800, 0x8bff, wallc_videoram_w },	/* mirror */
201 	{ 0x8c00, 0x8fff, wallc_videoram_w },	/* mirror */
202 
203 	{ 0xa000, 0xa3ff, MWA_RAM },		/* 2114, 2114 */
204 
205 	{ 0xb000, 0xb000, wc_b0 }, /*?*/
206 	{ 0xb100, 0xb100, wc_b1 }, /*?*/
207 	{ 0xb200, 0xb200, wc_b2 }, /*?*/
208 
209 	{ 0xb500, 0xb500, AY8910_control_port_0_w },
210 	{ 0xb600, 0xb600, AY8910_write_port_0_w },
211 MEMORY_END
212 
213 
214 INPUT_PORTS_START( wallc )
215 	PORT_START	/* DSW - read from b000 */
216 	PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) )
217 	PORT_DIPSETTING(	0x03, "5" )
218 	PORT_DIPSETTING(	0x02, "4" )
219 	PORT_DIPSETTING(	0x01, "3" )
220 	PORT_DIPSETTING(	0x00, "2" )
221 	PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Bonus_Life) )
222 	PORT_DIPSETTING(	0x0c, "100K/200K/400K/800K" )
223 	PORT_DIPSETTING(	0x08, "80K/160K/320K/640K" )
224 	PORT_DIPSETTING(	0x04, "60K/120K/240K/480K" )
225 	PORT_DIPSETTING(	0x00, DEF_STR( Off ) )
226 	PORT_DIPNAME( 0x10, 0x00, "Curve Effect" )
227 	PORT_DIPSETTING(	0x10, "Normal" )
228 	PORT_DIPSETTING(	0x00, "More" )
229 	PORT_DIPNAME( 0x60, 0x60, "Timer Speed" )
230 	PORT_DIPSETTING(	0x60, "Slow" )
231 	PORT_DIPSETTING(	0x40, "Normal" )
232 	PORT_DIPSETTING(	0x20, "Fast" )
233 	PORT_DIPSETTING(	0x00, "Super Fast" )
234 	PORT_DIPNAME( 0x80, 0x00, "Service" )
235 	PORT_DIPSETTING(	0x80, "Free Play With Level Select" )
236 	PORT_DIPSETTING(	0x00, "Normal" )
237 
238 	PORT_START	/* b200 */
239 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 )	/*Right curve button; select current playfield in test mode*/
240 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )	/*not used ?*/
241 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )	/*service?? plays loud,high-pitched sound*/
242 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )	/*Left curve button; browse playfields in test mode*/
243 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )	/*ok*/
244 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )	/*ok*/
245 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN3 )	/*ok*/
246 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )	/*ok*/
247 
248 	PORT_START	/* b400 - player position 8 bit analog input - value read is used as position of the player directly - what type of input is that ? DIAL ?*/
249 	PORT_ANALOG( 0xff, 0x00, IPT_DIAL | IPF_PLAYER1 | IPF_REVERSE, 50, 3, 0, 0 )
250 
251 	PORT_START	/* b600 - bits 0-5: coinage */
252 	PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) )
253 	PORT_DIPSETTING(    0x03, DEF_STR( 2C_1C ) )
254 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
255 	PORT_DIPSETTING(    0x01, DEF_STR( 1C_2C ) )
256 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_5C ) )
257 	PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Coin_B ) )
258 	PORT_DIPSETTING(    0x0c, DEF_STR( 2C_1C ) )
259 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
260 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_2C ) )
261 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_5C ) )
262 	PORT_DIPNAME( 0x30, 0x00, "Coin C" )
263 	PORT_DIPSETTING(    0x30, DEF_STR( 2C_1C ) )
264 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
265 	PORT_DIPSETTING(    0x10, DEF_STR( 1C_2C ) )
266 	PORT_DIPSETTING(    0x20, DEF_STR( 1C_5C ) )
267 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
268 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
269 INPUT_PORTS_END
270 
271 
272 
273 static struct GfxLayout charlayout =
274 {
275 	8,8,	/* 8*8 characters */
276 	512,	/* 512 characters */
277 	3,	/* 3 bits per pixel */
278 	{ 0, 0x1000*8*1, 0x1000*8*2 }, /* the bitplanes are separated */
279 	{ 7, 6, 5, 4, 3, 2, 1, 0 },
280 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
281 	8*8 /* every char takes 8 consecutive bytes */
282 };
283 
284 static struct GfxDecodeInfo gfxdecodeinfo[] =
285 {
286 	{ REGION_GFX1, 0     , &charlayout, 0, 4 },
287 	{ -1 } /* end of array */
288 };
289 
DRIVER_INIT(wallc)290 static DRIVER_INIT( wallc )
291 {
292 	unsigned char c;
293 	unsigned int i;
294 
295 	data8_t *ROM = memory_region(REGION_CPU1);
296 
297 	for (i=0; i<0x2000*2; i++)
298 	{
299 		c = ROM[ i ] ^ 0x55 ^ 0xff; /* NOTE: this can be shortened but now it fully reflects what the bigger module really does */
300 		c = BITSWAP8(c, 4,2,6,0,7,1,3,5); /* also swapped inside of the bigger module */
301 		ROM[ i ] = c;
302 	}
303 }
304 
305 
306 
307 static struct AY8910interface ay8912_interface =
308 {
309 	1,	/* 1 chip */
310 	12288000 / 8,	/* 1.536 MHz? */
311 	{ 30 },
312 	{ 0 },
313 	{ 0 },
314 	{ 0 },
315 	{ 0 }
316 };
317 
318 
319 static MACHINE_DRIVER_START( wallc )
320 	/* basic machine hardware */
321 	MDRV_CPU_ADD(Z80, 12288000 / 4)	/* 3.072 MHz ? */
322 	MDRV_CPU_MEMORY(readmem,writemem)
323 	MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
324 
325 	MDRV_FRAMES_PER_SECOND(60)
326 	MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION)
327 
328 	/* video hardware */
329 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
330 	MDRV_SCREEN_SIZE(32*8, 32*8)
331 	MDRV_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
332 	MDRV_GFXDECODE(gfxdecodeinfo)
333 	MDRV_PALETTE_LENGTH(32)
334 
335 	MDRV_PALETTE_INIT(wallc)
336 	MDRV_VIDEO_START(wallc)
337 	MDRV_VIDEO_UPDATE(wallc)
338 
339 	/* sound hardware */
340 	MDRV_SOUND_ADD(AY8910, ay8912_interface)
341 MACHINE_DRIVER_END
342 
343 /***************************************************************************
344 
345   Game driver(s)
346 
347 ***************************************************************************/
348 
349 ROM_START( wallc )
350 	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for main CPU */
351 	ROM_LOAD( "wac05.h7",   0x0000, 0x2000, CRC(ab6e472e) SHA1(a387fec24fb899df349a35d1d3a91e897b074712) )
352 	ROM_LOAD( "wac1-52.h6", 0x2000, 0x2000, CRC(988eaa6d) SHA1(d5e5dbee6e7e0488fdecfb864198c686cbd5d59c) )
353 
354 	ROM_REGION( 0x4000, REGION_GFX1, ROMREGION_DISPOSE )
355 	ROM_LOAD( "wc1.e3",		0x0000, 0x1000, CRC(ca5c4b53) SHA1(5d2e14fe81cca4ec7dbe0c98eaa26890fca28e58) )
356 	ROM_LOAD( "wc2.e2",		0x1000, 0x1000, CRC(b7f52a59) SHA1(737e7616d7295762057fbdb69d65c8c1edc773dc) )
357 	ROM_LOAD( "wc3.e1",		0x2000, 0x1000, CRC(f6854b3a) SHA1(bc1e7f785c338c1afa4ab61c07c61397b3de0b01) )
358 
359 	ROM_REGION( 0x0020, REGION_PROMS, 0 )
360 	ROM_LOAD( "74s288.c2",  0x0000, 0x0020, CRC(83e3e293) SHA1(a98c5e63b688de8d175adb6539e0cdc668f313fd) )
361 ROM_END
362 
363 GAME( 1984, wallc, 0,      wallc,  wallc, wallc, ROT0, "Midcoin", "Wall Crash" )
364