1 // license:GPL-2.0+
2 // copyright-holders:Jarek Burczynski
3 /****************************************************************************
4 
5 Wall Crash by Midcoin (c) 1984
6 
7 
8 Driver by Jarek Burczynski
9 2002.12.23
10 
11 
12 
13 
14      DIPSW-8     AY-3-8912                               DIPSW-4
15                                                          DIPSW-4
16 
17                         74s288
18 
19 
20                                                WAC1   WAC2   WAC3
21                                                (2532) (2532) (2532)
22 12.288MHz
23 
24    +------------+        2114  2114  2114  2114
25    + EPOXY WITH +                                +-------+
26    + LS08       +      WAC05  WAC1/52   EMPTY    + SMALL +
27    +LS240, LS245+      (2764) (2764)    SOCKET   + EPOXY +
28    + Z80        +                                +-------+
29    +------------+
30 
31 The bigger Epoxy brick contains three standard 74LSxxx chips and is used as
32 DATA lines decoder for all READS from addresses in range: 0..0x7fff.
33 The pinout (of the whole brick) is 1:1 Z80 and it can be replaced with
34 a plain Z80, given that decoded ROMS are put in place of WAC05 and WAC1/52.
35 
36 The smaller Epoxy contains:
37  5 chips (names sanded off...): 20 pins, 8 pins, 14 pins, 16 pins, 16 pins,
38  1 resistor: 120 Ohm
39  1 probably resistor: measured: 1000 Ohm
40  1 diode: standard 1N4148 (info from HIGHWAYMAN)
41  4 capacitors: 3 same: blue ones probably 10n , 1 smaller 1.3n (measured by HIGHWAYMAN)
42 It's mapped as ROM at 0x6000-0x7fff but is NOT accessed by the CPU.
43 It's also not needed for emulation.
44 
45 
46 Thanks to Dox for donating PCB.
47 Thanks to HIGHWAYMAN for providing info on how to get to these epoxies
48 (heat gun) and for info (very close one) on decoding.
49 
50 ****************************************************************************/
51 
52 #include "emu.h"
53 #include "cpu/z80/z80.h"
54 #include "machine/adc0804.h"
55 #include "sound/ay8910.h"
56 #include "video/resnet.h"
57 #include "emupal.h"
58 #include "screen.h"
59 #include "speaker.h"
60 #include "tilemap.h"
61 
62 
63 class wallc_state : public driver_device
64 {
65 public:
wallc_state(const machine_config & mconfig,device_type type,const char * tag)66 	wallc_state(const machine_config &mconfig, device_type type, const char *tag) :
67 		driver_device(mconfig, type, tag),
68 		m_maincpu(*this, "maincpu"),
69 		m_gfxdecode(*this, "gfxdecode"),
70 		m_videoram(*this, "videoram")
71 	{ }
72 
73 	void sidampkr(machine_config &config);
74 	void unkitpkr(machine_config &config);
75 	void wallc(machine_config &config);
76 	void wallca(machine_config &config);
77 
78 	void init_wallc();
79 	void init_wallca();
80 	void init_sidam();
81 	void init_unkitpkr();
82 
83 protected:
84 	virtual void video_start() override;
85 
86 private:
87 	void unkitpkr_map(address_map &map);
88 	void wallc_map(address_map &map);
89 
90 	required_device<cpu_device> m_maincpu;
91 	required_device<gfxdecode_device> m_gfxdecode;
92 
93 	required_shared_ptr<uint8_t> m_videoram;
94 
95 	tilemap_t *m_bg_tilemap;
96 
97 	bool m_bookkeeping_mode;
98 
99 	void videoram_w(offs_t offset, uint8_t data);
100 	void wallc_coin_counter_w(uint8_t data);
101 	void unkitpkr_out0_w(uint8_t data);
102 	void unkitpkr_out1_w(uint8_t data);
103 	void unkitpkr_out2_w(uint8_t data);
104 
105 	TILE_GET_INFO_MEMBER(get_bg_tile_info);
106 	TILE_GET_INFO_MEMBER(get_bg_tile_info_unkitpkr);
107 	TILE_GET_INFO_MEMBER(get_bg_tile_info_sidampkr);
108 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
109 
110 	void wallc_palette(palette_device &palette) const;
111 	void unkitpkr_palette(palette_device &palette) const;
112 	DECLARE_VIDEO_START(unkitpkr);
113 	DECLARE_VIDEO_START(sidampkr);
114 };
115 
116 
117 
118 /***************************************************************************
119 
120   Convert the color PROMs into a more usable format.
121 
122   Wall Crash has one 32 bytes palette PROM, connected to the RGB output this
123   way:
124 
125   bit 6 -- 330 Ohm resistor --+-- 330 Ohm pulldown resistor -- RED
126   bit 5 -- 220 Ohm resistor --/
127 
128   bit 4 -- NC
129 
130   bit 3 -- 330 Ohm resistor --+-- 330 Ohm pulldown resistor -- GREEN
131   bit 2 -- 220 Ohm resistor --/
132 
133   bit 1 -- 330 Ohm resistor --+--+-- 330 Ohm pulldown resistor -- BLUE
134   bit 0 -- 220 Ohm resistor --/  |
135                                  |
136   bit 7 -+- diode(~655 Ohm)------/
137          \------220 Ohm pullup (+5V) resistor
138 
139 
140 ***************************************************************************/
141 
wallc_palette(palette_device & palette) const142 void wallc_state::wallc_palette(palette_device &palette) const
143 {
144 	uint8_t const *const color_prom = memregion("proms")->base();
145 
146 	static constexpr int resistances_rg[2] = { 330, 220 };
147 	static constexpr int resistances_b[3] = { 655, 330, 220 };
148 
149 	double weights_r[2], weights_g[2], weights_b[3];
150 	compute_resistor_weights(0, 255,    -1.0,
151 			2,  resistances_rg, weights_r,  330,    0,
152 			2,  resistances_rg, weights_g,  330,    0,
153 			3,  resistances_b,  weights_b,  330,    655+220);
154 
155 	for (int i = 0; i < palette.entries(); i++)
156 	{
157 		int bit0, bit1, bit7;
158 
159 		// red component
160 		bit0 = BIT(color_prom[i], 5);
161 		bit1 = BIT(color_prom[i], 6);
162 		int const r = combine_weights(weights_r, bit1, bit0);
163 
164 		// green component
165 		bit0 = BIT(color_prom[i], 2);
166 		bit1 = BIT(color_prom[i], 3);
167 		int const g = combine_weights(weights_g, bit1, bit0);
168 
169 		// blue component
170 		bit0 = BIT(color_prom[i], 0);
171 		bit1 = BIT(color_prom[i], 1);
172 		bit7 = BIT(color_prom[i], 7);
173 		int const b = combine_weights(weights_b, bit7, bit1, bit0);
174 
175 		palette.set_pen_color(i, rgb_t(r, g, b));
176 	}
177 }
178 
unkitpkr_palette(palette_device & palette) const179 void wallc_state::unkitpkr_palette(palette_device &palette) const
180 {
181 	// this pcb has 470 Ohm resistors instead of the expected 330 Ohms.
182 	uint8_t const *const color_prom = memregion("proms")->base();
183 
184 	static constexpr int resistances_rg[2] = { 470, 220 };
185 	static constexpr int resistances_b[3] = { 655, 470, 220 };
186 
187 	double weights_r[2], weights_g[2], weights_b[3];
188 	compute_resistor_weights(0, 255,    -1.0,
189 			2,  resistances_rg, weights_r,  470,    0,
190 			2,  resistances_rg, weights_g,  470,    0,
191 			3,  resistances_b,  weights_b,  470,    655+220);
192 
193 	for (int i = 0; i < palette.entries(); i++)
194 	{
195 		int bit0, bit1, bit7;
196 
197 		// red component
198 		bit0 = BIT(color_prom[i], 5);
199 		bit1 = BIT(color_prom[i], 6);
200 		int const r = combine_weights(weights_r, bit1, bit0);
201 
202 		// green component
203 		bit0 = BIT(color_prom[i], 2);
204 		bit1 = BIT(color_prom[i], 3);
205 		int const g = combine_weights(weights_g, bit1, bit0);
206 
207 		// blue component
208 		bit0 = BIT(color_prom[i], 0);
209 		bit1 = BIT(color_prom[i], 1);
210 		bit7 = BIT(color_prom[i], 7);
211 		int const b = combine_weights(weights_b, bit7, bit1, bit0);
212 
213 		palette.set_pen_color(i, rgb_t(r, g, b));
214 	}
215 }
216 
videoram_w(offs_t offset,uint8_t data)217 void wallc_state::videoram_w(offs_t offset, uint8_t data)
218 {
219 	m_videoram[offset] = data;
220 	m_bg_tilemap->mark_tile_dirty(offset);
221 }
222 
TILE_GET_INFO_MEMBER(wallc_state::get_bg_tile_info)223 TILE_GET_INFO_MEMBER(wallc_state::get_bg_tile_info)
224 {
225 	tileinfo.set(0, m_videoram[tile_index] | 0x100, 1, 0);
226 }
227 
TILE_GET_INFO_MEMBER(wallc_state::get_bg_tile_info_unkitpkr)228 TILE_GET_INFO_MEMBER(wallc_state::get_bg_tile_info_unkitpkr)
229 {
230 	int code = m_videoram[tile_index];
231 
232 	// hack to display "card" graphics in middle of screen outside of bookkeeping mode
233 	if (m_bookkeeping_mode || (tile_index & 0x1f) < 0x08 || (tile_index & 0x1f) >= 0x10)
234 		code |= 0x100;
235 
236 	tileinfo.set(0, code, 1, 0);
237 }
238 
TILE_GET_INFO_MEMBER(wallc_state::get_bg_tile_info_sidampkr)239 TILE_GET_INFO_MEMBER(wallc_state::get_bg_tile_info_sidampkr)
240 {
241 	tileinfo.set(0, m_videoram[tile_index] | 0x100, 0, 0);
242 }
243 
video_start()244 void wallc_state::video_start()
245 {
246 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wallc_state::get_bg_tile_info)), TILEMAP_SCAN_COLS_FLIP_Y, 8, 8, 32, 32);
247 }
248 
VIDEO_START_MEMBER(wallc_state,unkitpkr)249 VIDEO_START_MEMBER(wallc_state, unkitpkr)
250 {
251 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wallc_state::get_bg_tile_info_unkitpkr)), TILEMAP_SCAN_COLS_FLIP_Y, 8, 8, 32, 32);
252 }
253 
VIDEO_START_MEMBER(wallc_state,sidampkr)254 VIDEO_START_MEMBER(wallc_state, sidampkr)
255 {
256 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wallc_state::get_bg_tile_info_sidampkr)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
257 }
258 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)259 uint32_t wallc_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
260 {
261 	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
262 	return 0;
263 }
264 
265 
wallc_coin_counter_w(uint8_t data)266 void wallc_state::wallc_coin_counter_w(uint8_t data)
267 {
268 	machine().bookkeeping().coin_counter_w(0, data & 2);
269 }
270 
271 
unkitpkr_out0_w(uint8_t data)272 void wallc_state::unkitpkr_out0_w(uint8_t data)
273 {
274 }
275 
unkitpkr_out1_w(uint8_t data)276 void wallc_state::unkitpkr_out1_w(uint8_t data)
277 {
278 	machine().bookkeeping().coin_counter_w(0, BIT(data, 4));
279 }
280 
unkitpkr_out2_w(uint8_t data)281 void wallc_state::unkitpkr_out2_w(uint8_t data)
282 {
283 	if (m_bookkeeping_mode != BIT(data, 0))
284 	{
285 		m_bookkeeping_mode = BIT(data, 0);
286 		m_bg_tilemap->mark_all_dirty();
287 	}
288 }
289 
wallc_map(address_map & map)290 void wallc_state::wallc_map(address_map &map)
291 {
292 	map(0x0000, 0x7fff).rom();
293 	map(0x8000, 0x83ff).ram().w(FUNC(wallc_state::videoram_w)).mirror(0xc00).share("videoram");   /* 2114, 2114 */
294 	map(0xa000, 0xa3ff).ram();     /* 2114, 2114 */
295 
296 	map(0xb000, 0xb000).portr("DSW1");
297 	map(0xb200, 0xb200).portr("SYSTEM");
298 	map(0xb400, 0xb400).r("adc", FUNC(adc0804_device::read_and_write));
299 
300 	map(0xb000, 0xb000).nopw();
301 	map(0xb100, 0xb100).w(FUNC(wallc_state::wallc_coin_counter_w));
302 	map(0xb200, 0xb200).nopw();
303 	map(0xb500, 0xb500).w("aysnd", FUNC(ay8912_device::address_w));
304 	map(0xb600, 0xb600).rw("aysnd", FUNC(ay8912_device::data_r), FUNC(ay8912_device::data_w));
305 }
306 
unkitpkr_map(address_map & map)307 void wallc_state::unkitpkr_map(address_map &map)
308 {
309 	map(0x0000, 0x7fff).rom();
310 	map(0x8000, 0x83ff).ram().w(FUNC(wallc_state::videoram_w)).mirror(0xc00).share("videoram");   /* 2114, 2114 */
311 	map(0xa000, 0xa3ff).ram();     /* 2114, 2114 */
312 
313 	map(0xb000, 0xb000).portr("DSW1");
314 	map(0xb100, 0xb100).portr("IN1");
315 	map(0xb200, 0xb200).portr("IN2");
316 	map(0xb300, 0xb300).portr("IN3");
317 	map(0xb500, 0xb5ff).nopr(); // read by memory test routine. left over from some other game
318 
319 	map(0xb000, 0xb000).w(FUNC(wallc_state::unkitpkr_out0_w));
320 	map(0xb100, 0xb100).w(FUNC(wallc_state::unkitpkr_out1_w));
321 	map(0xb200, 0xb200).w(FUNC(wallc_state::unkitpkr_out2_w));
322 	map(0xb500, 0xb500).w("aysnd", FUNC(ay8912_device::address_w));
323 	map(0xb600, 0xb600).rw("aysnd", FUNC(ay8912_device::data_r), FUNC(ay8910_device::data_w));  // Port A = DSW
324 }
325 
326 
327 static INPUT_PORTS_START( wallc )
328 	PORT_START("SYSTEM")    /* b200 */
329 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 )    //Right curve button; select current playfield in test mode
330 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )    //not used ?
331 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )   //service?? plays loud,high-pitched sound
332 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )    //Left curve button; browse playfields in test mode
333 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )  //ok
334 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )  //ok
335 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN3 )  //ok
336 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 ) //ok
337 
338 	PORT_START("DIAL")      /* b400 - player position 8 bit analog input - value read is used as position of the player directly - what type of input is that ? DIAL ?*/
339 	PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(3) PORT_REVERSE PORT_PLAYER(1)
340 
341 	PORT_START("DSW1")      /* b000 */
342 	PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) )            PORT_DIPLOCATION("SW1:1,2")
343 	PORT_DIPSETTING(    0x03, "5" )
344 	PORT_DIPSETTING(    0x02, "4" )
345 	PORT_DIPSETTING(    0x01, "3" )
346 	PORT_DIPSETTING(    0x00, "2" )
347 	PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Bonus_Life) )        PORT_DIPLOCATION("SW1:3,4")
348 	PORT_DIPSETTING(    0x0c, "100K/200K/400K/800K" )
349 	PORT_DIPSETTING(    0x08, "80K/160K/320K/640K" )
350 	PORT_DIPSETTING(    0x04, "60K/120K/240K/480K" )
351 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
352 	PORT_DIPNAME( 0x10, 0x00, "Curve Effect" )          PORT_DIPLOCATION("SW3:1")
353 	PORT_DIPSETTING(    0x10, DEF_STR( Normal ) )
354 	PORT_DIPSETTING(    0x00, "More" )
355 	PORT_DIPNAME( 0x60, 0x60, "Timer Speed" )           PORT_DIPLOCATION("SW3:2,3")
356 	PORT_DIPSETTING(    0x60, "Slow" )
357 	PORT_DIPSETTING(    0x40, DEF_STR( Normal ) )
358 	PORT_DIPSETTING(    0x20, "Fast" )
359 	PORT_DIPSETTING(    0x00, "Super Fast" )
360 	PORT_DIPNAME( 0x80, 0x00, "Service" )               PORT_DIPLOCATION("SW3:4")
361 	PORT_DIPSETTING(    0x80, "Free Play With Level Select" )
362 	PORT_DIPSETTING(    0x00, DEF_STR( Normal ) )
363 
364 	PORT_START("DSW2")      /* b600 */
365 	PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) )           PORT_DIPLOCATION("SW2:1,2")
366 	PORT_DIPSETTING(    0x03, DEF_STR( 2C_1C ) )
367 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
368 	PORT_DIPSETTING(    0x01, DEF_STR( 1C_2C ) )
369 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_5C ) )
370 	PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Coin_B ) )           PORT_DIPLOCATION("SW2:3,4")
371 	PORT_DIPSETTING(    0x0c, DEF_STR( 2C_1C ) )
372 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
373 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_2C ) )
374 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_5C ) )
375 	PORT_DIPNAME( 0x30, 0x00, "Coin C" )                PORT_DIPLOCATION("SW2:5,6")
376 	PORT_DIPSETTING(    0x30, DEF_STR( 2C_1C ) )
377 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
378 	PORT_DIPSETTING(    0x10, DEF_STR( 1C_2C ) )
379 	PORT_DIPSETTING(    0x20, DEF_STR( 1C_5C ) )
380 	PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:7" ) /* Shown as "Unused" in the manual */
381 	PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) /* Shown as "Unused" in the manual */
382 INPUT_PORTS_END
383 
384 static INPUT_PORTS_START( unkitpkr )
385 	PORT_START("DSW1")    /* b000 */
386 	PORT_DIPUNKNOWN_DIPLOC(0x01, 0x01, "SW1:1")
387 	PORT_DIPUNKNOWN_DIPLOC(0x02, 0x02, "SW1:2")
388 	PORT_DIPUNKNOWN_DIPLOC(0x04, 0x04, "SW1:3")
389 	PORT_DIPUNKNOWN_DIPLOC(0x08, 0x08, "SW1:4")
390 	PORT_DIPUNKNOWN_DIPLOC(0x10, 0x10, "SW1:5")
391 	PORT_DIPUNKNOWN_DIPLOC(0x20, 0x20, "SW1:6")
392 	PORT_DIPUNKNOWN_DIPLOC(0x40, 0x40, "SW1:7")
393 	PORT_DIPUNKNOWN_DIPLOC(0x80, 0x80, "SW1:8")
394 
395 	PORT_START("IN1")    /* b100 */
396 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
397 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
398 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) // coin out
399 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
400 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
401 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
402 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
403 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN3 )
404 
405 	PORT_START("IN2")    /* b200 */
406 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
407 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
408 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK )
409 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD1 )
410 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD2 )
411 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_POKER_HOLD3 )
412 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_POKER_HOLD4 )
413 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_POKER_HOLD5 )
414 
415 	PORT_START("IN3")    /* b300 */
416 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
417 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
418 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
419 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
420 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) // ok?
421 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
422 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL )
423 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
424 
425 	PORT_START("DSW2")      /* b600 */
426 	PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) )   PORT_DIPLOCATION("SW2:1,2") // ok
427 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
428 	PORT_DIPSETTING(    0x01, DEF_STR( 1C_2C ) )
429 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_5C ) )
430 	PORT_DIPSETTING(    0x03, "1 Coin/10 Credits" )
431 	PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Coin_B ) )   PORT_DIPLOCATION("SW2:3,4") // ok
432 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
433 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_2C ) )
434 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_5C ) )
435 	PORT_DIPSETTING(    0x0c, "1 Coin/10 Credits" )
436 	PORT_DIPNAME( 0x30, 0x00, "Coin C" )            PORT_DIPLOCATION("SW2:5,6") // ok
437 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
438 	PORT_DIPSETTING(    0x10, DEF_STR( 1C_2C ) )
439 	PORT_DIPSETTING(    0x20, DEF_STR( 1C_5C ) )
440 	PORT_DIPSETTING(    0x30, "1 Coin/10 Credits" )
441 	PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:7" )
442 	PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" )
443 INPUT_PORTS_END
444 
445 static INPUT_PORTS_START( sidampkr )
446 	PORT_INCLUDE(unkitpkr)
447 
448 	PORT_MODIFY("DSW1")    /* b000 */
449 	PORT_DIPNAME( 0x01, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("SW1:1")
450 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
451 	PORT_DIPSETTING(    0x01, DEF_STR( French ) )
452 	PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" )
453 	PORT_DIPNAME( 0x1c, 0x00, "Min/Max Bet" )  PORT_DIPLOCATION("SW1:3,4,5")
454 	PORT_DIPSETTING(   0x00, "Min:1; Max:2" )
455 	PORT_DIPSETTING(   0x04, "Min:1; Max:5" )
456 	PORT_DIPSETTING(   0x08, "Min:1; Max:8" )
457 	PORT_DIPSETTING(   0x0c, "Min:2; Max:10" )
458 	PORT_DIPSETTING(   0x10, "Min:5; Max:15" )
459 	PORT_DIPSETTING(   0x14, "Min:10; Max:20" )
460 	PORT_DIPSETTING(   0x18, "Min:15; Max:30" )
461 	PORT_DIPSETTING(   0x1c, "Min:20; Max:40" )
462 	PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" )
463 	PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW1:7" )
464 	PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )
465 INPUT_PORTS_END
466 
467 static const gfx_layout charlayout =
468 {
469 	8,8,    /* 8*8 characters */
470 	RGN_FRAC(1,3),
471 	3,  /* 3 bits per pixel */
472 	{ RGN_FRAC(0,3),RGN_FRAC(1,3),RGN_FRAC(2,3) }, /* the bitplanes are separated */
473 	{ 7, 6, 5, 4, 3, 2, 1, 0 },
474 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
475 	8*8 /* every char takes 8 consecutive bytes */
476 };
477 
478 static GFXDECODE_START( gfx_wallc )
479 	GFXDECODE_ENTRY( "gfx1", 0     , charlayout, 0, 4 )
480 GFXDECODE_END
481 
482 
init_wallc()483 void wallc_state::init_wallc()
484 {
485 	uint8_t *ROM = memregion("maincpu")->base();
486 
487 	for (uint32_t i = 0; i < 0x2000 * 2; i++)
488 	{
489 		uint8_t c = ROM[ i ] ^ 0x55 ^ 0xff; /* NOTE: this can be shortened but now it fully reflects what the bigger module really does */
490 		c = bitswap<8>(c, 4,2,6,0,7,1,3,5); /* also swapped inside of the bigger module */
491 		ROM[ i ] = c;
492 	}
493 }
494 
init_wallca()495 void wallc_state::init_wallca()
496 {
497 	uint8_t *ROM = memregion("maincpu")->base();
498 
499 	for (uint32_t i = 0; i < 0x4000; i++)
500 	{
501 		uint8_t c;
502 		if (i & 0x100)
503 		{
504 			c = ROM[i] ^ 0x4a;
505 			c = bitswap<8>(c, 4,7,1,3,2,0,5,6);
506 		}
507 		else
508 		{
509 			c = ROM[i] ^ 0xa5;
510 			c = bitswap<8>(c, 0,2,3,6,1,5,7,4);
511 		}
512 
513 		ROM[ i ] = c;
514 	}
515 }
516 
517 
wallc(machine_config & config)518 void wallc_state::wallc(machine_config &config)
519 {
520 	/* basic machine hardware */
521 	Z80(config, m_maincpu, 12.288_MHz_XTAL / 4);  /* 3.072 MHz ? */
522 	m_maincpu->set_addrmap(AS_PROGRAM, &wallc_state::wallc_map);
523 	m_maincpu->set_vblank_int("screen", FUNC(wallc_state::irq0_line_hold));
524 
525 	ADC0804(config, "adc", 640000).vin_callback().set_ioport("DIAL"); // clock not verified
526 
527 	/* video hardware */
528 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
529 	screen.set_refresh_hz(60);
530 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
531 	screen.set_size(32*8, 32*8);
532 	screen.set_visarea(0*8, 32*8-1, 0*8, 32*8-1);
533 	screen.set_screen_update(FUNC(wallc_state::screen_update));
534 	screen.set_palette("palette");
535 
536 	GFXDECODE(config, m_gfxdecode, "palette", gfx_wallc);
537 	PALETTE(config, "palette", FUNC(wallc_state::wallc_palette), 32);
538 
539 	/* sound hardware */
540 	SPEAKER(config, "mono").front_center();
541 	ay8912_device &aysnd(AY8912(config, "aysnd", 12288000 / 8));
542 	aysnd.port_a_read_callback().set_ioport("DSW2");
543 	aysnd.add_route(ALL_OUTPUTS, "mono", 0.30);
544 }
545 
wallca(machine_config & config)546 void wallc_state::wallca(machine_config &config)
547 {
548 	wallc(config);
549 	m_maincpu->set_clock(12_MHz_XTAL / 4);
550 }
551 
unkitpkr(machine_config & config)552 void wallc_state::unkitpkr(machine_config &config)
553 {
554 	wallc(config);
555 	config.device_remove("adc");
556 
557 	m_maincpu->set_addrmap(AS_PROGRAM, &wallc_state::unkitpkr_map);
558 
559 	MCFG_VIDEO_START_OVERRIDE(wallc_state, unkitpkr)
560 	subdevice<palette_device>("palette")->set_init(FUNC(wallc_state::unkitpkr_palette));
561 
562 	/* sound hardware */
563 	subdevice<ay8912_device>("aysnd")->reset_routes().add_route(ALL_OUTPUTS, "mono", 0.50);
564 }
565 
sidampkr(machine_config & config)566 void wallc_state::sidampkr(machine_config &config)
567 {
568 	unkitpkr(config);
569 
570 	MCFG_VIDEO_START_OVERRIDE(wallc_state, sidampkr)
571 }
572 
573 /***************************************************************************
574 
575   Game driver(s)
576 
577 ***************************************************************************/
578 
579 ROM_START( wallc )
580 	ROM_REGION( 0x10000, "maincpu", 0 )
CRC(ab6e472e)581 	ROM_LOAD( "wac05.h7",   0x0000, 0x2000, CRC(ab6e472e) SHA1(a387fec24fb899df349a35d1d3a91e897b074712) )
582 	ROM_LOAD( "wac1-52.h6", 0x2000, 0x2000, CRC(988eaa6d) SHA1(d5e5dbee6e7e0488fdecfb864198c686cbd5d59c) )
583 
584 	ROM_REGION( 0x3000, "gfx1", 0 )
585 	ROM_LOAD( "wc1.e3",     0x0000, 0x1000, CRC(ca5c4b53) SHA1(5d2e14fe81cca4ec7dbe0c98eaa26890fca28e58) )
586 	ROM_LOAD( "wc2.e2",     0x1000, 0x1000, CRC(b7f52a59) SHA1(737e7616d7295762057fbdb69d65c8c1edc773dc) )
587 	ROM_LOAD( "wc3.e1",     0x2000, 0x1000, CRC(f6854b3a) SHA1(bc1e7f785c338c1afa4ab61c07c61397b3de0b01) )
588 
589 	ROM_REGION( 0x0020, "proms", 0 )
590 	ROM_LOAD( "74s288.c2",  0x0000, 0x0020, CRC(83e3e293) SHA1(a98c5e63b688de8d175adb6539e0cdc668f313fd) )
591 ROM_END
592 
593 /* this set uses a different encryption, but the decrypted code is the same */
594 ROM_START( wallca )
595 	ROM_REGION( 0x10000, "maincpu", 0 )
596 	ROM_LOAD( "rom4.rom",     0x0000, 0x2000, CRC(ce43af1b) SHA1(c05419cb4aa57c6187b469573a3787d9123c4a05) )
597 	ROM_LOAD( "rom5.rom",     0x2000, 0x2000, CRC(b789a705) SHA1(2b62b14d1a3ad5eff5b8d502d7891e58379ee820) )
598 
599 	ROM_REGION( 0x3000, "gfx1", 0 )
600 	ROM_LOAD( "rom3.rom",     0x0800, 0x0800, CRC(6634db73) SHA1(fe6104f974495a250e0cd14c0745eec8e44b8d3a) )
601 	ROM_LOAD( "rom2.rom",     0x1800, 0x0800, CRC(79f49c2c) SHA1(485fdba5ebdb4c01306f3ef26c992a513aa6b5dc) )
602 	ROM_LOAD( "rom1.rom",     0x2800, 0x0800, CRC(3884fd4f) SHA1(47254c8828128ac48fc15f05b52fe4d42d4919e7) )
603 
604 	ROM_REGION( 0x0020, "proms", 0 )
605 	ROM_LOAD( "74s288.c2",  0x0000, 0x0020, CRC(83e3e293) SHA1(a98c5e63b688de8d175adb6539e0cdc668f313fd) )
606 ROM_END
607 
608 ROM_START( brkblast )
609 	ROM_REGION( 0x10000, "maincpu", 0 )
610 	ROM_LOAD( "fadesa-r0.6m",     0x0000, 0x4000, CRC(4e96ca15) SHA1(87f1a3538712aa3d6c3713b845679dd42a4ba5a4) )
611 
612 	ROM_REGION( 0x3000, "gfx1", 0 )
613 	ROM_LOAD( "rom3.rom",     0x0800, 0x0800, CRC(6634db73) SHA1(fe6104f974495a250e0cd14c0745eec8e44b8d3a) )
614 	ROM_LOAD( "rom2.rom",     0x1800, 0x0800, CRC(79f49c2c) SHA1(485fdba5ebdb4c01306f3ef26c992a513aa6b5dc) )
615 	ROM_LOAD( "rom1.rom",     0x2800, 0x0800, CRC(3884fd4f) SHA1(47254c8828128ac48fc15f05b52fe4d42d4919e7) )
616 
617 	ROM_REGION( 0x0020, "proms", 0 )
618 	ROM_LOAD( "74s288.c2",  0x0000, 0x0020, CRC(83e3e293) SHA1(a98c5e63b688de8d175adb6539e0cdc668f313fd) )
619 ROM_END
620 
621 
622 /*
623 
624 It uses an epoxy brick like wallc
625 Inside the brick there are:
626 - 74245
627 - 74368
628 - Pal16r4
629 
630 74368 is a tristate not, it's used to:
631 -negate D0 that goes to the CPU if A15 is low
632 -negate D1 that goes to the CPU if A15 is low
633 -negate D2 that goes to the CPU if A15 is low
634 -negate D3 that goes to the CPU if A15 is low
635 
636 -negate cpu clk to feed the pal clk ALWAYS
637 -negate A15 to feed 74245 /EN ALWAYS
638 
639 
640 The 74245 let pass the data unmodified if A15 is high (like wallc)
641 
642 If A15 is low a Pal16r4 kick in
643 this chip can modify D2,D3,D4,D5,D6,D7
644 
645 D0 and D1 are negated from outside to real Z80
646 D2 and D3 are negated after begin modified by the Pal
647 
648 Pal input
649 A1
650 A3
651 A6
652 A15 (Output enable, not in equation)
653 
654 D2
655 D3
656 D4
657 D5  (2 times)
658 D7  (2 times)
659 
660 Pal output
661 D2 (via not to cpu)
662 D3 (via not to cpu)
663 D4 to cpu
664 D5 to cpu
665 D6 to cpu
666 D7 to cpu
667 
668 */
669 
670 ROM_START( sidampkr )
671 	ROM_REGION( 0x10000, "maincpu", 0 )
672 	ROM_LOAD( "11600.0",     0x0000, 0x1000, CRC(88cac4d2) SHA1(a369da3dc80671eeff549077cf2ce860d5f4ea35) )
673 	ROM_LOAD( "11600.1",     0x1000, 0x1000, CRC(96cca320) SHA1(85326f7126c8250a22f35f6eed138051a9ab35cb) )
674 
675 	ROM_REGION( 0x3000, "gfx1", 0 )
676 	ROM_LOAD( "11605.b",     0x0800, 0x0800, CRC(a7800f8a) SHA1(3955e0f71ced6fd759f52d12c0b39ab6aab31ca4) )
677 	ROM_LOAD( "11605.g",     0x1800, 0x0800, CRC(b7bebf1e) SHA1(764536989ba4c4c143a61d4453c3bba547bc630a) )
678 	ROM_LOAD( "11605.r",     0x2800, 0x0800, CRC(4d645b8d) SHA1(d4f8d11c4ef796cf66ebf2e6b8a11247d630951a) )
679 
680 	ROM_REGION( 0x0020, "proms", 0 )
681 	ROM_LOAD( "11607-74.288",  0x0000, 0x0020, CRC(e14bf545) SHA1(5e8c5a9ea6e4842f27a47c1d7224ed294bbaa40b) )
682 ROM_END
683 
684 void wallc_state::init_sidam()
685 {
686 	uint8_t *ROM = memregion("maincpu")->base();
687 
688 	for (int i = 0; i < 0x2000; i++)
689 	{
690 		uint8_t x = ROM[i];
691 		switch(i & 0x4a) // seems correct. Plaintext available in the 0x1150-0x1550 range. First 0x50 of code are very similar if not identical to unkitpkr.
692 		{
693 			case 0x00: x = bitswap<8>(x ^ (BIT(x, 6) ? 0xaf : 0x03), 7, 3, 5, 2, 6, 4, 1, 0); break;
694 			case 0x02: x = bitswap<8>(x ^ 0x77, 4, 6, 2, 5, 3, 7, 1, 0); break;
695 			case 0x08: x = bitswap<8>(x ^ 0x5f, 2, 4, 6, 3, 7, 5, 1, 0); break;
696 			case 0x0a: x = bitswap<8>(x ^ 0xd7, 6, 2, 4, 7, 5, 3, 1, 0); break;
697 			case 0x40: x = bitswap<8>(x ^ (BIT(x, 6) ? 0xaf : 0x03), 7, 3, 5, 2, 6, 4, 1, 0); break;
698 			case 0x42: x = bitswap<8>(x ^ 0xeb, 5, 7, 3, 6, 4, 2, 1, 0); break;
699 			case 0x48: x = bitswap<8>(x ^ (BIT(x, 6) ? 0xbb : 0x03), 3, 5, 7, 4, 2, 6, 1, 0); break;
700 			case 0x4a: x = bitswap<8>(x ^ 0xd7, 6, 2, 4, 7, 5, 3, 1, 0); break;
701 		}
702 
703 		ROM[i] = x;
704 	}
705 }
706 
707 /*
708   Unknown Italian Poker
709   Seems a brute hack of an unknown game.
710 
711   The "conforme alla legge n." string is overwriting the hands table:
712 
713   "CONFORME"   = Royal Flush
714   (blank line) = Straight Flush
715   "ALLA LEGGE" = Four of a Kind
716   (blank line) = Full House
717   "N.904 DEL"  = Flush
718   (blank line) = Straight
719   "17.12.1986" = Three of a Kind
720   (blank line) = Double Pair
721   "........."  = Simple Pair
722 
723   Also the code is hacked/patched to avoid some jumps:
724 
725   00cb: ld a,(hl)
726   00cc: cp c
727   00cd: nop
728   00ce: nop
729   00cf: nop
730 
731   00d2: ld a,(hl)
732   00d3: cp c
733   00d4: nop
734   00d5: nop
735   00d6: nop
736 
737   1866: pop af
738   1867: cp $46
739   1869: nop
740   186a: nop
741   186b: nop
742 
743   Main PCB has a Microchip AY-3-8912A PSG, a 3.6V battery and no ROM numbered 4.
744   A daughterboard contains the Z80 and some RAM.
745 */
746 ROM_START( unkitpkr )
747 	ROM_REGION( 0x8000, "maincpu", 0 )
748 	ROM_LOAD( "1", 0x0000, 0x2000, CRC(82dacf83) SHA1(d2bd4664737aeb968e9e34da74c2654e556c8567) )
749 
750 	ROM_REGION( 0x3000, "gfx1", 0 )
CRC(a359b7aa)751 	ROM_LOAD( "2", 0x0000, 0x1000, CRC(a359b7aa) SHA1(832a0dfd0689f76381f34d2d8419a7f09a6c403a) )
752 	ROM_CONTINUE(  0x0000, 0x1000 ) // first half is empty
753 	ROM_LOAD( "3", 0x1000, 0x1000, CRC(f7d7d48b) SHA1(d9787dcbbfdb5f8f8434d8e688c1ee1e0566969d) )
754 	ROM_CONTINUE(  0x1000, 0x1000 ) // first half is empty
755 	ROM_LOAD( "5", 0x2000, 0x1000, CRC(b3084b49) SHA1(21b2fa41492faf95e66c5765acfdae1685ee8784) )
756 	ROM_CONTINUE(  0x2000, 0x1000 ) // first half is empty
757 
758 	ROM_REGION( 0x0020, "proms", 0 )
759 	ROM_LOAD( "74s288.c2",  0x0000, 0x0020, CRC(83e3e293) SHA1(a98c5e63b688de8d175adb6539e0cdc668f313fd) ) // dumped; matches the wallc bp
760 ROM_END
761 
762 void wallc_state::init_unkitpkr()
763 {
764 	// line swapping is too annoying to handle with ROM_LOAD macros
765 	uint8_t buffer[0x400];
766 	for (int b = 0; b < 0x3000; b += 0x400)
767 	{
768 		uint8_t *gfxrom = memregion("gfx1")->base() + b;
769 		for (int a = 0; a < 0x400; a++)
770 			buffer[a] = gfxrom[(a & 0x03f) | (a & 0x280) >> 1 | (a & 0x140) << 1];
771 		memcpy(gfxrom, &buffer[0], 0x400);
772 	}
773 
774 	m_bookkeeping_mode = false;
775 	save_item(NAME(m_bookkeeping_mode));
776 }
777 
778 
779 //    YEAR  NAME      PARENT  MACHINE   INPUT     STATE        INIT      ROT      COMPANY             FULLNAME                              FLAGS
780 GAME( 1984, wallc,    0,      wallc,    wallc,    wallc_state, init_wallc,    ROT0,   "Midcoin",          "Wall Crash (set 1)",                  MACHINE_SUPPORTS_SAVE )
781 GAME( 1984, wallca,   wallc,  wallca,   wallc,    wallc_state, init_wallca,   ROT0,   "Midcoin",          "Wall Crash (set 2)",                  MACHINE_SUPPORTS_SAVE )
782 GAME( 1984, brkblast, wallc,  wallc,    wallc,    wallc_state, init_wallca,   ROT0,   "bootleg (Fadesa)", "Brick Blast (bootleg of Wall Crash)", MACHINE_SUPPORTS_SAVE ) // Spanish bootleg board, Fadesa stickers / text on various components
783 
784 GAME( 1984, sidampkr, 0,      sidampkr, sidampkr, wallc_state, init_sidam,    ROT270, "Sidam",            "unknown Sidam poker",                 MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) // colors should be verified
785 GAME( 198?, unkitpkr, 0,      unkitpkr, unkitpkr, wallc_state, init_unkitpkr, ROT0,   "<unknown>",        "unknown Italian poker game",          MACHINE_SUPPORTS_SAVE )
786