1 // license:BSD-3-Clause
2 // copyright-holders:Zsolt Vasvari, Aaron Giles, R. Belmont, Jonathan Gevaryahu
3 /***************************************************************************
4 
5     Berzerk hardware
6 
7     Driver by Zsolt Vasvari
8     Original sound driver by Alex Judd
9     New sound driver by Aaron Giles, R. Belmont and Lord Nightmare
10 
11 ***************************************************************************/
12 
13 #include "emu.h"
14 #include "audio/exidy.h"
15 
16 #include "cpu/z80/z80.h"
17 #include "machine/74181.h"
18 #include "machine/nvram.h"
19 #include "sound/s14001a.h"
20 #include "video/resnet.h"
21 #include "screen.h"
22 #include "speaker.h"
23 
24 
25 class berzerk_state : public driver_device
26 {
27 public:
berzerk_state(const machine_config & mconfig,device_type type,const char * tag)28 	berzerk_state(const machine_config &mconfig, device_type type, const char *tag) :
29 		driver_device(mconfig, type, tag),
30 		m_maincpu(*this, "maincpu"),
31 		m_s14001a(*this, "speech"),
32 		m_ls181_10c(*this, "ls181_10c"),
33 		m_ls181_12c(*this, "ls181_12c"),
34 		m_custom(*this, "exidy"),
35 		m_screen(*this, "screen"),
36 		m_videoram(*this, "videoram"),
37 		m_colorram(*this, "colorram"),
38 		m_led(*this, "led0")
39 	{ }
40 
41 	void berzerk(machine_config &config);
42 	void frenzy(machine_config &config);
43 
44 	void init_moonwarp();
45 
46 protected:
47 	virtual void machine_start() override;
48 	virtual void machine_reset() override;
49 	virtual void sound_reset() override;
50 	virtual void video_start() override;
51 
52 private:
53 	required_device<cpu_device> m_maincpu;
54 	required_device<s14001a_device> m_s14001a;
55 	required_device<ttl74181_device> m_ls181_10c;
56 	required_device<ttl74181_device> m_ls181_12c;
57 	required_device<exidy_sound_device> m_custom;
58 	required_device<screen_device> m_screen;
59 
60 	required_shared_ptr<uint8_t> m_videoram;
61 	required_shared_ptr<uint8_t> m_colorram;
62 
63 	output_finder<> m_led;
64 
65 	uint8_t m_magicram_control;
66 	uint8_t m_last_shift_data;
67 	uint8_t m_intercept;
68 	emu_timer *m_irq_timer;
69 	emu_timer *m_nmi_timer;
70 	uint8_t m_irq_enabled;
71 	uint8_t m_nmi_enabled;
72 	int m_p1_counter_74ls161;
73 	int m_p1_direction;
74 	int m_p2_counter_74ls161;
75 	int m_p2_direction;
76 
77 	uint8_t led_on_r();
78 	void led_on_w(uint8_t data);
79 	uint8_t led_off_r();
80 	void led_off_w(uint8_t data);
81 	void irq_enable_w(uint8_t data);
82 	void nmi_enable_w(uint8_t data);
83 	void nmi_disable_w(uint8_t data);
84 	uint8_t nmi_enable_r();
85 	uint8_t nmi_disable_r();
86 	void magicram_w(offs_t offset, uint8_t data);
87 	void magicram_control_w(uint8_t data);
88 	uint8_t intercept_v256_r();
89 	void audio_w(offs_t offset, uint8_t data);
90 	uint8_t audio_r(offs_t offset);
91 	uint8_t moonwarp_p1_r();
92 	uint8_t moonwarp_p2_r();
93 
94 	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
95 
96 	TIMER_CALLBACK_MEMBER(irq_callback);
97 	TIMER_CALLBACK_MEMBER(nmi_callback);
98 	void vpos_to_vsync_chain_counter(int vpos, uint8_t *counter, uint8_t *v256);
99 	int vsync_chain_counter_to_vpos(uint8_t counter, uint8_t v256);
100 	void create_irq_timer();
101 	void start_irq_timer();
102 	void create_nmi_timer();
103 	void start_nmi_timer();
104 	void get_pens(rgb_t *pens);
105 	void berzerk_io_map(address_map &map);
106 	void berzerk_map(address_map &map);
107 	void frenzy_map(address_map &map);
108 };
109 
110 
111 #define MASTER_CLOCK                (XTAL(10'000'000))
112 #define MAIN_CPU_CLOCK              (MASTER_CLOCK / 4)
113 #define PIXEL_CLOCK                 (MASTER_CLOCK / 2)
114 #define S14001_CLOCK                (MASTER_CLOCK / 4)
115 #define HTOTAL                      (0x140)
116 #define HBEND                       (0x000)
117 #define HBSTART                     (0x100)
118 #define VTOTAL                      (0x106)
119 #define VBEND                       (0x020)
120 #define VBSTART                     (0x100)
121 #define VCOUNTER_START_NO_VBLANK    (0x020)
122 #define VCOUNTER_START_VBLANK       (0x0da)
123 #define IRQS_PER_FRAME              (2)
124 #define NMIS_PER_FRAME              (8)
125 
126 static const uint8_t irq_trigger_counts[IRQS_PER_FRAME] = { 0x80, 0xda };
127 static const uint8_t irq_trigger_v256s [IRQS_PER_FRAME] = { 0x00, 0x01 };
128 
129 static const uint8_t nmi_trigger_counts[NMIS_PER_FRAME] = { 0x30, 0x50, 0x70, 0x90, 0xb0, 0xd0, 0xf0, 0xf0 };
130 static const uint8_t nmi_trigger_v256s [NMIS_PER_FRAME] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
131 
132 
133 /*************************************
134  *
135  *  LED handling
136  *
137  *************************************/
138 
led_on_r()139 uint8_t berzerk_state::led_on_r()
140 {
141 	m_led = 1;
142 
143 	return 0;
144 }
145 
146 
led_on_w(uint8_t data)147 void berzerk_state::led_on_w(uint8_t data)
148 {
149 	m_led = 1;
150 }
151 
152 
led_off_r()153 uint8_t berzerk_state::led_off_r()
154 {
155 	m_led = 0;
156 
157 	return 0;
158 }
159 
160 
led_off_w(uint8_t data)161 void berzerk_state::led_off_w(uint8_t data)
162 {
163 	m_led = 0;
164 }
165 
166 
167 
168 /*************************************
169  *
170  *  Convert to/from our line counting
171  *  to the hardware's vsync chain
172  *
173  *************************************/
174 
vpos_to_vsync_chain_counter(int vpos,uint8_t * counter,uint8_t * v256)175 void berzerk_state::vpos_to_vsync_chain_counter(int vpos, uint8_t *counter, uint8_t *v256)
176 {
177 	/* convert from a vertical position to the actual values on the vertical sync counters */
178 	*v256 = ((vpos < VBEND) || (vpos >= VBSTART));
179 
180 	if (*v256)
181 	{
182 		int temp = vpos - VBSTART + VCOUNTER_START_VBLANK;
183 
184 		if (temp < 0)
185 			*counter = temp + VTOTAL;
186 		else
187 			*counter = temp;
188 	}
189 	else
190 		*counter = vpos;
191 }
192 
193 
vsync_chain_counter_to_vpos(uint8_t counter,uint8_t v256)194 int berzerk_state::vsync_chain_counter_to_vpos(uint8_t counter, uint8_t v256)
195 {
196 	/* convert from the vertical sync counters to an actual vertical position */
197 	int vpos;
198 
199 	if (v256)
200 	{
201 		vpos = counter - VCOUNTER_START_VBLANK + VBSTART;
202 
203 		if (vpos >= VTOTAL)
204 			vpos = vpos - VTOTAL;
205 	}
206 	else
207 		vpos = counter;
208 
209 	return vpos;
210 }
211 
212 
213 
214 /*************************************
215  *
216  *  IRQ generation
217  *
218  *  There are two IRQ's per frame
219  *
220  *************************************/
221 
irq_enable_w(uint8_t data)222 void berzerk_state::irq_enable_w(uint8_t data)
223 {
224 	m_irq_enabled = data & 0x01;
225 }
226 
227 
TIMER_CALLBACK_MEMBER(berzerk_state::irq_callback)228 TIMER_CALLBACK_MEMBER(berzerk_state::irq_callback)
229 {
230 	int irq_number = param;
231 	uint8_t next_counter;
232 	uint8_t next_v256;
233 	int next_vpos;
234 	int next_irq_number;
235 
236 	/* set the IRQ line if enabled */
237 	if (m_irq_enabled)
238 		m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xfc); // Z80
239 
240 	/* set up for next interrupt */
241 	next_irq_number = (irq_number + 1) % IRQS_PER_FRAME;
242 	next_counter = irq_trigger_counts[next_irq_number];
243 	next_v256 = irq_trigger_v256s[next_irq_number];
244 
245 	next_vpos = vsync_chain_counter_to_vpos(next_counter, next_v256);
246 	m_irq_timer->adjust(m_screen->time_until_pos(next_vpos), next_irq_number);
247 }
248 
249 
create_irq_timer()250 void berzerk_state::create_irq_timer()
251 {
252 	m_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(berzerk_state::irq_callback),this));
253 }
254 
255 
start_irq_timer()256 void berzerk_state::start_irq_timer()
257 {
258 	int vpos = vsync_chain_counter_to_vpos(irq_trigger_counts[0], irq_trigger_v256s[0]);
259 	m_irq_timer->adjust(m_screen->time_until_pos(vpos));
260 }
261 
262 
263 
264 /*************************************
265  *
266  *  NMI generation
267  *
268  *  An NMI is asserted roughly every
269  *  32 scanlines when V16 clocks HI.
270  *  The NMI is cleared 2 pixels later.
271  *  Since this happens so quickly, I am
272  *  not emulating it, just pulse
273  *  the line instead.
274  *
275  *************************************/
276 
nmi_enable_w(uint8_t data)277 void berzerk_state::nmi_enable_w(uint8_t data)
278 {
279 	m_nmi_enabled = 1;
280 }
281 
282 
nmi_disable_w(uint8_t data)283 void berzerk_state::nmi_disable_w(uint8_t data)
284 {
285 	m_nmi_enabled = 0;
286 }
287 
288 
nmi_enable_r()289 uint8_t berzerk_state::nmi_enable_r()
290 {
291 	m_nmi_enabled = 1;
292 
293 	return 0;
294 }
295 
296 
nmi_disable_r()297 uint8_t berzerk_state::nmi_disable_r()
298 {
299 	m_nmi_enabled = 0;
300 
301 	return 0;
302 }
303 
304 
TIMER_CALLBACK_MEMBER(berzerk_state::nmi_callback)305 TIMER_CALLBACK_MEMBER(berzerk_state::nmi_callback)
306 {
307 	int nmi_number = param;
308 	uint8_t next_counter;
309 	uint8_t next_v256;
310 	int next_vpos;
311 	int next_nmi_number;
312 
313 	/* pulse the NMI line if enabled */
314 	if (m_nmi_enabled)
315 		m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
316 
317 	/* set up for next interrupt */
318 	next_nmi_number = (nmi_number + 1) % NMIS_PER_FRAME;
319 	next_counter = nmi_trigger_counts[next_nmi_number];
320 	next_v256 = nmi_trigger_v256s[next_nmi_number];
321 
322 	next_vpos = vsync_chain_counter_to_vpos(next_counter, next_v256);
323 	m_nmi_timer->adjust(m_screen->time_until_pos(next_vpos), next_nmi_number);
324 }
325 
326 
create_nmi_timer()327 void berzerk_state::create_nmi_timer()
328 {
329 	m_nmi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(berzerk_state::nmi_callback),this));
330 }
331 
332 
start_nmi_timer()333 void berzerk_state::start_nmi_timer()
334 {
335 	int vpos = vsync_chain_counter_to_vpos(nmi_trigger_counts[0], nmi_trigger_v256s[0]);
336 	m_nmi_timer->adjust(m_screen->time_until_pos(vpos));
337 }
338 
339 
340 
341 /*************************************
342  *
343  *  Machine setup
344  *
345  *************************************/
346 
machine_start()347 void berzerk_state::machine_start()
348 {
349 	create_irq_timer();
350 	create_nmi_timer();
351 
352 	m_led.resolve();
353 
354 	/* register for state saving */
355 	save_item(NAME(m_magicram_control));
356 	save_item(NAME(m_last_shift_data));
357 	save_item(NAME(m_intercept));
358 	save_item(NAME(m_irq_enabled));
359 	save_item(NAME(m_nmi_enabled));
360 }
361 
362 
363 
364 /*************************************
365  *
366  *  Machine reset
367  *
368  *************************************/
369 
machine_reset()370 void berzerk_state::machine_reset()
371 {
372 	m_irq_enabled = 0;
373 	m_nmi_enabled = 0;
374 	m_led = 0;
375 	m_magicram_control = 0;
376 
377 	start_irq_timer();
378 	start_nmi_timer();
379 }
380 
381 
382 
383 /*************************************
384  *
385  *  Video system
386  *
387  *************************************/
388 
video_start()389 void berzerk_state::video_start()
390 {
391 	m_ls181_10c->mode_w(1);
392 	m_ls181_12c->mode_w(1);
393 }
394 
395 
magicram_w(offs_t offset,uint8_t data)396 void berzerk_state::magicram_w(offs_t offset, uint8_t data)
397 {
398 	uint8_t alu_output;
399 
400 	uint8_t current_video_data = m_videoram[offset];
401 
402 	/* shift data towards LSB.  MSB bits are filled by data from last_shift_data.
403 	   The shifter consists of 5 74153 devices @ 7A, 8A, 9A, 10A and 11A,
404 	   followed by 4 more 153's at 11B, 10B, 9B and 8B, which optionally
405 	   reverse the order of the resulting bits */
406 	uint8_t shift_flop_output = (((uint16_t)m_last_shift_data << 8) | data) >> (m_magicram_control & 0x07);
407 
408 	if (m_magicram_control & 0x08)
409 		shift_flop_output = bitswap<8>(shift_flop_output, 0, 1, 2, 3, 4, 5, 6, 7);
410 
411 	/* collision detection - AND gate output goes to the K pin of the flip-flop,
412 	   while J is LO, therefore, it only resets, never sets */
413 	if (shift_flop_output & current_video_data)
414 		m_intercept = 0;
415 
416 	/* perform ALU step */
417 	m_ls181_12c->input_a_w(shift_flop_output >> 0);
418 	m_ls181_10c->input_a_w(shift_flop_output >> 4);
419 	m_ls181_12c->input_b_w(current_video_data >> 0);
420 	m_ls181_10c->input_b_w(current_video_data >> 4);
421 	m_ls181_12c->select_w(m_magicram_control >> 4);
422 	m_ls181_10c->select_w(m_magicram_control >> 4);
423 
424 	alu_output = m_ls181_10c->function_r() << 4 | m_ls181_12c->function_r();
425 
426 	m_videoram[offset] = alu_output ^ 0xff;
427 
428 	/* save data for next time */
429 	m_last_shift_data = data & 0x7f;
430 }
431 
432 
magicram_control_w(uint8_t data)433 void berzerk_state::magicram_control_w(uint8_t data)
434 {
435 	/* save the control byte, clear the shift data latch,
436 	   and set the intercept flip-flop */
437 	m_magicram_control = data;
438 	m_last_shift_data = 0;
439 	m_intercept = 1;
440 }
441 
442 
intercept_v256_r()443 uint8_t berzerk_state::intercept_v256_r()
444 {
445 	uint8_t counter;
446 	uint8_t v256;
447 
448 	vpos_to_vsync_chain_counter(m_screen->vpos(), &counter, &v256);
449 
450 	return (m_intercept^1) << 7 | v256;
451 }
452 
453 
get_pens(rgb_t * pens)454 void berzerk_state::get_pens(rgb_t *pens)
455 {
456 	static const int resistances_wg[] = { 750, 0 };
457 	static const int resistances_el[] = { static_cast<int>(1.0 / ((1.0 / 750.0) + (1.0 / 360.0))), 0 };
458 
459 	double color_weights[2];
460 
461 	if (ioport("MONITOR_TYPE")->read() == 0)
462 		compute_resistor_weights(0, 0xff, -1.0,
463 									2, resistances_wg, color_weights, 0, 270,
464 									2, resistances_wg, color_weights, 0, 270,
465 									2, resistances_wg, color_weights, 0, 270);
466 	else
467 		compute_resistor_weights(0, 0xff, -1.0,
468 									2, resistances_el, color_weights, 0, 270,
469 									2, resistances_el, color_weights, 0, 270,
470 									2, resistances_el, color_weights, 0, 270);
471 
472 	for (int color = 0; color < 0x10; color++)
473 	{
474 		uint8_t r_bit = (color >> 0) & 0x01;
475 		uint8_t g_bit = (color >> 1) & 0x01;
476 		uint8_t b_bit = (color >> 2) & 0x01;
477 		uint8_t i_bit = (color >> 3) & 0x01;
478 
479 		uint8_t r = combine_weights(color_weights, r_bit & i_bit, r_bit);
480 		uint8_t g = combine_weights(color_weights, g_bit & i_bit, g_bit);
481 		uint8_t b = combine_weights(color_weights, b_bit & i_bit, b_bit);
482 
483 		pens[color] = rgb_t(r, g, b);
484 	}
485 }
486 
487 
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)488 uint32_t berzerk_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
489 {
490 	rgb_t pens[0x10];
491 	get_pens(pens);
492 
493 	for (int offs = 0; offs < m_videoram.bytes(); offs++)
494 	{
495 		uint8_t data = m_videoram[offs];
496 		uint8_t color = m_colorram[((offs >> 2) & 0x07e0) | (offs & 0x001f)];
497 
498 		uint8_t y = offs >> 5;
499 		uint8_t x = offs << 3;
500 
501 		int i;
502 
503 		for (i = 0; i < 4; i++)
504 		{
505 			rgb_t pen = (data & 0x80) ? pens[color >> 4] : rgb_t::black();
506 			bitmap.pix(y, x) = pen;
507 
508 			x++;
509 			data <<= 1;
510 		}
511 
512 		for (; i < 8; i++)
513 		{
514 			rgb_t pen = (data & 0x80) ? pens[color & 0x0f] : rgb_t::black();
515 			bitmap.pix(y, x) = pen;
516 
517 			x++;
518 			data <<= 1;
519 		}
520 	}
521 
522 	return 0;
523 }
524 
525 
526 
527 /*************************************
528  *
529  *  Audio system
530  *
531  *************************************/
532 
audio_w(offs_t offset,uint8_t data)533 void berzerk_state::audio_w(offs_t offset, uint8_t data)
534 {
535 	switch (offset)
536 	{
537 	/* offset 4 writes to the S14001A */
538 	case 4:
539 		switch (data >> 6)
540 		{
541 		/* write data to the S14001 */
542 		case 0:
543 			m_s14001a->data_w(data & 0x3f);
544 
545 			/* clock the chip -- via a 555 timer */
546 			m_s14001a->start_w(1);
547 			m_s14001a->start_w(0);
548 
549 			break;
550 
551 		case 1:
552 		{
553 			/* volume */
554 			m_s14001a->force_update();
555 			m_s14001a->set_output_gain(0, ((data >> 3 & 0xf) + 1) / 16.0);
556 
557 			/* clock control - the first LS161 divides the clock by 9 to 16, the 2nd by 8,
558 			   giving a final clock from 19.5kHz to 34.7kHz */
559 			int clock_divisor = 16 - (data & 0x07);
560 			m_s14001a->set_clock(S14001_CLOCK / clock_divisor / 8);
561 			break;
562 		}
563 
564 		default: break; /* 2 and 3 are not connected */
565 		}
566 
567 		break;
568 
569 	/* offset 6 writes to the sfxcontrol latch */
570 	case 6:
571 		m_custom->sfxctrl_w(data >> 6, data);
572 		break;
573 
574 	/* everything else writes to the 6840 */
575 	default:
576 		m_custom->sh6840_w(offset, data);
577 		break;
578 	}
579 }
580 
581 
audio_r(offs_t offset)582 uint8_t berzerk_state::audio_r(offs_t offset)
583 {
584 	switch (offset)
585 	{
586 	/* offset 4 reads from the S14001A */
587 	case 4:
588 		return (m_s14001a->busy_r()) ? 0xc0 : 0x40;
589 	/* offset 6 is open bus */
590 	case 6:
591 		logerror("attempted read from berzerk audio reg 6 (sfxctrl)!\n");
592 		return 0;
593 	/* everything else reads from the 6840 */
594 	default:
595 		return m_custom->sh6840_r(offset);
596 	}
597 }
598 
599 
600 
sound_reset()601 void berzerk_state::sound_reset()
602 {
603 	/* clears the flip-flop controlling the volume and freq on the speech chip */
604 	audio_w(4, 0x40);
605 }
606 
607 
608 
609 /*************************************
610  *
611  *  Memory handlers
612  *
613  *************************************/
614 
berzerk_map(address_map & map)615 void berzerk_state::berzerk_map(address_map &map)
616 {
617 	map(0x0000, 0x07ff).rom();
618 	map(0x0800, 0x0bff).mirror(0x0400).ram().share("nvram");
619 	map(0x1000, 0x3fff).rom();
620 	map(0x4000, 0x5fff).ram().share("videoram");
621 	map(0x6000, 0x7fff).ram().w(FUNC(berzerk_state::magicram_w)).share("videoram");
622 	map(0x8000, 0x87ff).mirror(0x3800).ram().share("colorram");
623 	map(0xc000, 0xffff).noprw();
624 }
625 
626 
frenzy_map(address_map & map)627 void berzerk_state::frenzy_map(address_map &map)
628 {
629 	map(0x0000, 0x3fff).rom();
630 	map(0x4000, 0x5fff).ram().share("videoram");
631 	map(0x6000, 0x7fff).ram().w(FUNC(berzerk_state::magicram_w)).share("videoram");
632 	map(0x8000, 0x87ff).mirror(0x3800).ram().share("colorram");
633 	map(0xc000, 0xcfff).rom();
634 	map(0xf800, 0xfbff).mirror(0x0400).ram().share("nvram");
635 }
636 
637 
638 
639 /*************************************
640  *
641  *  Port handlers
642  *
643  *************************************/
644 
berzerk_io_map(address_map & map)645 void berzerk_state::berzerk_io_map(address_map &map)
646 {
647 	map.global_mask(0xff);
648 	map(0x00, 0x3f).noprw();
649 	map(0x40, 0x47).rw(FUNC(berzerk_state::audio_r), FUNC(berzerk_state::audio_w));
650 	map(0x48, 0x48).portr("P1").nopw();
651 	map(0x49, 0x49).portr("SYSTEM").nopw();
652 	map(0x4a, 0x4a).portr("P2").nopw();
653 	map(0x4b, 0x4b).nopr().w(FUNC(berzerk_state::magicram_control_w));
654 	map(0x4c, 0x4c).rw(FUNC(berzerk_state::nmi_enable_r), FUNC(berzerk_state::nmi_enable_w));
655 	map(0x4d, 0x4d).rw(FUNC(berzerk_state::nmi_disable_r), FUNC(berzerk_state::nmi_disable_w));
656 	map(0x4e, 0x4e).r(FUNC(berzerk_state::intercept_v256_r)).nopw(); // note reading from here should clear pending frame interrupts, see zfb-1.tiff 74ls74 at 3D pin 13 /CLR
657 	map(0x4f, 0x4f).nopr().w(FUNC(berzerk_state::irq_enable_w));
658 	map(0x50, 0x57).noprw(); /* second sound board, initialized but not used */
659 	map(0x58, 0x5f).noprw();
660 	map(0x60, 0x60).mirror(0x18).portr("F3").nopw();
661 	map(0x61, 0x61).mirror(0x18).portr("F2").nopw();
662 	map(0x62, 0x62).mirror(0x18).portr("F6").nopw();
663 	map(0x63, 0x63).mirror(0x18).portr("F5").nopw();
664 	map(0x64, 0x64).mirror(0x18).portr("F4").nopw();
665 	map(0x65, 0x65).mirror(0x18).portr("SW2").nopw();
666 	map(0x66, 0x66).mirror(0x18).rw(FUNC(berzerk_state::led_off_r), FUNC(berzerk_state::led_off_w));
667 	map(0x67, 0x67).mirror(0x18).rw(FUNC(berzerk_state::led_on_r), FUNC(berzerk_state::led_on_w));
668 	map(0x80, 0xff).noprw();
669 }
670 
671 
672 
673 /*************************************
674  *
675  *  Port definitions
676  *
677  *************************************/
678 
679 #define BERZERK_COINAGE(CHUTE, DIPBANK) \
680 	PORT_DIPNAME( 0x0f, 0x00, "Coin "#CHUTE )  PORT_DIPLOCATION(#DIPBANK":1,2,3,4") \
681 	PORT_DIPSETTING(    0x09, DEF_STR( 2C_1C ) ) \
682 	PORT_DIPSETTING(    0x0d, DEF_STR( 4C_3C ) ) \
683 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) ) \
684 	PORT_DIPSETTING(    0x0e, DEF_STR( 4C_5C ) ) \
685 	PORT_DIPSETTING(    0x0a, DEF_STR( 2C_3C ) ) \
686 	PORT_DIPSETTING(    0x0f, DEF_STR( 4C_7C ) ) \
687 	PORT_DIPSETTING(    0x01, DEF_STR( 1C_2C ) ) \
688 	PORT_DIPSETTING(    0x0b, DEF_STR( 2C_5C ) ) \
689 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_3C ) ) \
690 	PORT_DIPSETTING(    0x0c, DEF_STR( 2C_7C ) ) \
691 	PORT_DIPSETTING(    0x03, DEF_STR( 1C_4C ) ) \
692 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_5C ) ) \
693 	PORT_DIPSETTING(    0x05, DEF_STR( 1C_6C ) ) \
694 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_7C ) ) \
695 	PORT_DIPSETTING(    0x07, "1 Coin/10 Credits" ) \
696 	PORT_DIPSETTING(    0x08, "1 Coin/14 Credits" )
697 
698 
699 static INPUT_PORTS_START( joystick ) // used on all games except moonwarp
700 	PORT_START("P1")
701 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
702 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
703 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
704 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
705 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
706 	PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
707 
708 	PORT_START("P2")
709 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
710 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
711 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
712 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
713 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
714 	PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_UNUSED )
DEF_STR(Cabinet)715 	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Cabinet ) )
716 	PORT_DIPSETTING(    0x80, DEF_STR( Upright ) )
717 	PORT_DIPSETTING(    0x00, DEF_STR( Cocktail ) )
718 INPUT_PORTS_END
719 
720 static INPUT_PORTS_START( common ) // used on all games
721 	PORT_START("SYSTEM")
722 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
723 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
724 	PORT_BIT( 0x1c, IP_ACTIVE_LOW, IPT_UNUSED )
725 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN3 )
726 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
727 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
728 
729 	/* fake port for monitor type */
730 	PORT_START("MONITOR_TYPE")
731 	PORT_CONFNAME( 0x01, 0x00, "Monitor Type" )
732 	PORT_CONFSETTING(    0x00, "Wells-Gardner" )
733 	PORT_CONFSETTING(    0x01, "Electrohome" )
734 	PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
735 
736 	PORT_START("SW2")
737 	/* port for the 'bookkeeping reset' and 'bookkeeping' buttons;
738 	 * The 'bookkeeping reset' button is an actual button on the zpu-1000 and
739 	 * zpu-1001 pcbs, labeled 'S2' or 'SW2'. It is wired to bit 0.
740 	 * * pressing it while high scores are displayed will give a free game
741 	 *   without adding any coin info to the bookkeeping info in nvram.
742 	 * The 'bookkeeping' button is wired to the control panel, usually hidden
743 	 * underneath or only accessible through the coin door. Wired to bit 7.
744 	 * * It displays various bookkeeping statistics when pressed sequentially.
745 	 *   Pressing P1 fire (according to the manual) when stats are displayed
746 	 *   will clear the stat shown on screen.
747 	 */
748 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Free Game (not logged in bookkeeping)")
749 	PORT_BIT( 0x7e, IP_ACTIVE_LOW,  IPT_UNUSED )
750 	PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE2 ) PORT_NAME("Bookkeeping") PORT_CODE(KEYCODE_F1)
751 INPUT_PORTS_END
752 
753 static INPUT_PORTS_START( berzerk )
754 	PORT_INCLUDE( joystick )
755 	PORT_INCLUDE( common )
756 
757 	PORT_START("F2")
758 	PORT_DIPNAME( 0x03, 0x00, "Color Test" ) PORT_CODE(KEYCODE_F5) PORT_TOGGLE PORT_DIPLOCATION("F2:1,2")
759 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
760 	PORT_DIPSETTING(    0x03, DEF_STR( On ) )
761 	PORT_BIT( 0x3c, IP_ACTIVE_LOW,  IPT_UNUSED )
762 	PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("F2:7,8")
763 	PORT_DIPSETTING(    0xc0, "5000 and 10000" )
764 	PORT_DIPSETTING(    0x40, "5000" )
765 	PORT_DIPSETTING(    0x80, "10000" )
766 	PORT_DIPSETTING(    0x00, DEF_STR( None ) )
767 
768 	PORT_START("F3")
769 	PORT_DIPNAME( 0x01, 0x00, "Input Test Mode" ) PORT_CODE(KEYCODE_F2) PORT_TOGGLE PORT_DIPLOCATION("F3:1")
770 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
771 	PORT_DIPSETTING(    0x01, DEF_STR( On ) )
772 	PORT_DIPNAME( 0x02, 0x00, "Crosshair Pattern" ) PORT_CODE(KEYCODE_F4) PORT_TOGGLE PORT_DIPLOCATION("F3:2")
773 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
774 	PORT_DIPSETTING(    0x02, DEF_STR( On ) )
775 	PORT_BIT( 0x3c, IP_ACTIVE_LOW,  IPT_UNUSED )
776 	PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("F3:7,8")
777 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
778 	PORT_DIPSETTING(    0x40, DEF_STR( German ) )
779 	PORT_DIPSETTING(    0x80, DEF_STR( French ) )
780 	PORT_DIPSETTING(    0xc0, DEF_STR( Spanish ) )
781 
782 	PORT_START("F4")
783 	BERZERK_COINAGE(1, F4)
784 	PORT_BIT( 0xf0, IP_ACTIVE_LOW,  IPT_UNUSED )
785 
786 	PORT_START("F5")
787 	BERZERK_COINAGE(2, F5)
788 	PORT_BIT( 0xf0, IP_ACTIVE_LOW,  IPT_UNUSED )
789 
790 	PORT_START("F6")
791 	BERZERK_COINAGE(3, F6)
792 	PORT_BIT( 0xf0, IP_ACTIVE_LOW,  IPT_UNUSED )
793 INPUT_PORTS_END
794 
795 // this set has French speech ROMs, so default the language to French
796 static INPUT_PORTS_START( berzerkf )
797 	PORT_INCLUDE( berzerk )
798 
799 	PORT_MODIFY("F3")
800 	PORT_DIPNAME( 0xc0, 0x80, DEF_STR( Language ) ) PORT_DIPLOCATION("F3:7,8")
801 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
802 	PORT_DIPSETTING(    0x40, DEF_STR( German ) )
803 	PORT_DIPSETTING(    0x80, DEF_STR( French ) )
804 	PORT_DIPSETTING(    0xc0, DEF_STR( Spanish ) )
805 INPUT_PORTS_END
806 
807 // this set has German speech ROMs, so default the language to German
808 static INPUT_PORTS_START( berzerkg )
809 	PORT_INCLUDE( berzerk )
810 
811 	PORT_MODIFY("F3")
812 	PORT_DIPNAME( 0xc0, 0x40, DEF_STR( Language ) ) PORT_DIPLOCATION("F3:7,8")
813 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
814 	PORT_DIPSETTING(    0x40, DEF_STR( German ) )
815 	PORT_DIPSETTING(    0x80, DEF_STR( French ) )
816 	PORT_DIPSETTING(    0xc0, DEF_STR( Spanish ) )
817 INPUT_PORTS_END
818 
819 // this set has a Spanish speech ROM, so default the language to Spanish
820 static INPUT_PORTS_START( berzerks )
821 	PORT_INCLUDE( berzerk )
822 
823 	PORT_MODIFY("F3")
824 	PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Language ) ) PORT_DIPLOCATION("F3:7,8")
825 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
826 	PORT_DIPSETTING(    0x40, DEF_STR( German ) )
827 	PORT_DIPSETTING(    0x80, DEF_STR( French ) )
828 	PORT_DIPSETTING(    0xc0, DEF_STR( Spanish ) )
829 INPUT_PORTS_END
830 
831 static INPUT_PORTS_START( frenzy )
832 	PORT_INCLUDE( joystick )
833 	PORT_INCLUDE( common )
834 
835 	PORT_MODIFY("SYSTEM")
836 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // frenzy lacks coin 3
837 
838 	PORT_START("F2")
839 	/* Bit 0 does some more hardware tests. According to the manual, both bit 0 & 1 must be:
840 	   - ON for Signature Analysis (S.A.)
841 	   - OFF for game operation     */
842 	PORT_DIPNAME( 0x03, 0x00, "Hardware Tests" ) PORT_DIPLOCATION("F2:1,2")
843 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
844 	PORT_DIPSETTING(    0x01, "Color test" )
845 	PORT_DIPSETTING(    0x02, DEF_STR( Unknown ) )
846 	PORT_DIPSETTING(    0x03, "Signature Analysis" )
847 	PORT_DIPNAME( 0x04, 0x00, "Input Test Mode" ) PORT_CODE(KEYCODE_F2) PORT_TOGGLE PORT_DIPLOCATION("F2:3")
848 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
849 	PORT_DIPSETTING(    0x04, DEF_STR( On ) )
850 	PORT_DIPNAME( 0x08, 0x00, "Crosshair Pattern" ) PORT_CODE(KEYCODE_F4) PORT_TOGGLE PORT_DIPLOCATION("F2:4")
851 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
852 	PORT_DIPSETTING(    0x08, DEF_STR( On ) )
853 	PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_DIPLOCATION("F2:5,6,7,8")
854 
855 	PORT_START("F3")
856 	PORT_DIPNAME( 0x0f, 0x03, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("F3:1,2,3,4")
857 	PORT_DIPSETTING(    0x01, "1000" )
858 	PORT_DIPSETTING(    0x02, "2000" )
859 	PORT_DIPSETTING(    0x03, "3000" )
860 	PORT_DIPSETTING(    0x04, "4000" )
861 	PORT_DIPSETTING(    0x05, "5000" )
862 	PORT_DIPSETTING(    0x06, "6000" )
863 	PORT_DIPSETTING(    0x07, "7000" )
864 	PORT_DIPSETTING(    0x08, "8000" )
865 	PORT_DIPSETTING(    0x09, "9000" )
866 	PORT_DIPSETTING(    0x0a, "10000" )
867 	PORT_DIPSETTING(    0x0b, "11000" )
868 	PORT_DIPSETTING(    0x0c, "12000" )
869 	PORT_DIPSETTING(    0x0d, "13000" )
870 	PORT_DIPSETTING(    0x0e, "14000" )
871 	PORT_DIPSETTING(    0x0f, "15000" )
872 	PORT_DIPSETTING(    0x00, DEF_STR( None ) )
873 	PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_DIPLOCATION("F3:5,6")
874 	PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("F3:7,8")
875 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
876 	PORT_DIPSETTING(    0x40, DEF_STR( German ) )
877 	PORT_DIPSETTING(    0x80, DEF_STR( French ) )
878 	PORT_DIPSETTING(    0xc0, DEF_STR( Spanish ) )
879 
880 	/* The following 3 ports use all 8 bits, but I didn't feel like adding all 256 values :-) */
881 	PORT_START("F4")
882 	PORT_DIPNAME( 0xff, 0x01, "Coin Multiplier" ) PORT_DIPLOCATION("F4:1,2,3,4,5,6,7,8")
883 	PORT_DIPSETTING(    0x00, DEF_STR( Free_Play ) )
884 	PORT_DIPSETTING(    0x01, "1" )
885 	PORT_DIPSETTING(    0x02, "2" )
886 	PORT_DIPSETTING(    0x03, "3" )
887 	PORT_DIPSETTING(    0x04, "4" )
888 	PORT_DIPSETTING(    0x05, "5" )
889 	PORT_DIPSETTING(    0x06, "6" )
890 	PORT_DIPSETTING(    0x07, "7" )
891 	PORT_DIPSETTING(    0x08, "8" )
892 	PORT_DIPSETTING(    0x09, "9" )
893 	PORT_DIPSETTING(    0x0a, "10" )
894 	PORT_DIPSETTING(    0x0b, "11" )
895 	PORT_DIPSETTING(    0x0c, "12" )
896 	PORT_DIPSETTING(    0x0d, "13" )
897 	PORT_DIPSETTING(    0x0e, "14" )
898 	PORT_DIPSETTING(    0x0f, "15" )
899 	PORT_DIPSETTING(    0xff, "255" )
900 
901 	PORT_START("F5")
902 	PORT_DIPNAME( 0xff, 0x01, "Coins/Credit A" ) PORT_DIPLOCATION("F5:1,2,3,4,5,6,7,8")
903 	PORT_DIPSETTING(    0x00, "0 (invalid)" ) // Can't insert coins
904 	PORT_DIPSETTING(    0x01, "1" )
905 	PORT_DIPSETTING(    0x02, "2" )
906 	PORT_DIPSETTING(    0x03, "3" )
907 	PORT_DIPSETTING(    0x04, "4" )
908 	PORT_DIPSETTING(    0x05, "5" )
909 	PORT_DIPSETTING(    0x06, "6" )
910 	PORT_DIPSETTING(    0x07, "7" )
911 	PORT_DIPSETTING(    0x08, "8" )
912 	PORT_DIPSETTING(    0x09, "9" )
913 	PORT_DIPSETTING(    0x0a, "10" )
914 	PORT_DIPSETTING(    0x0b, "11" )
915 	PORT_DIPSETTING(    0x0c, "12" )
916 	PORT_DIPSETTING(    0x0d, "13" )
917 	PORT_DIPSETTING(    0x0e, "14" )
918 	PORT_DIPSETTING(    0x0f, "15" )
919 	PORT_DIPSETTING(    0xff, "255" )
920 
921 	PORT_START("F6")
922 	PORT_DIPNAME( 0xff, 0x01, "Coins/Credit B" ) PORT_DIPLOCATION("F6:1,2,3,4,5,6,7,8")
923 	PORT_DIPSETTING(    0x00, "0 (invalid)" ) // Can't insert coins
924 	PORT_DIPSETTING(    0x01, "1" )
925 	PORT_DIPSETTING(    0x02, "2" )
926 	PORT_DIPSETTING(    0x03, "3" )
927 	PORT_DIPSETTING(    0x04, "4" )
928 	PORT_DIPSETTING(    0x05, "5" )
929 	PORT_DIPSETTING(    0x06, "6" )
930 	PORT_DIPSETTING(    0x07, "7" )
931 	PORT_DIPSETTING(    0x08, "8" )
932 	PORT_DIPSETTING(    0x09, "9" )
933 	PORT_DIPSETTING(    0x0a, "10" )
934 	PORT_DIPSETTING(    0x0b, "11" )
935 	PORT_DIPSETTING(    0x0c, "12" )
936 	PORT_DIPSETTING(    0x0d, "13" )
937 	PORT_DIPSETTING(    0x0e, "14" )
938 	PORT_DIPSETTING(    0x0f, "15" )
939 	PORT_DIPSETTING(    0xff, "255" )
940 INPUT_PORTS_END
941 
942 uint8_t berzerk_state::moonwarp_p1_r()
943 {
944 	// This seems to be the same type of dial as the later 'moon war 2' set uses
945 	// see http://www.cityofberwyn.com/schematics/stern/MoonWar_opto.tiff for schematic
946 	// I.e. a 74ls161 counts from 0 to 15 which is the absolute number of bars passed on the quadrature
947 	// one difference is it lacks the strobe input (does it?), which if not active causes
948 	// the dial input to go open bus. This is used in moon war 2 to switch between player 1
949 	// and player 2 dials, which share a single port. moonwarp uses separate ports for the dials.
950 	signed char dialread = ioport("P1_DIAL")->read();
951 	uint8_t ret;
952 	uint8_t buttons = (ioport("P1")->read()&0xe0);
953 	if (dialread < 0) m_p1_direction = 0;
954 	else if (dialread > 0) m_p1_direction = 0x10;
955 	m_p1_counter_74ls161 += abs(dialread);
956 	m_p1_counter_74ls161 &= 0xf;
957 	ret = m_p1_counter_74ls161 | m_p1_direction | buttons;
958 	//fprintf(stderr, "dialread1: %02x, p1_counter_74ls161: %02x, spinner ret is %02x\n", dialread, m_p1_counter_74ls161, ret);
959 	return ret;
960 }
961 
moonwarp_p2_r()962 uint8_t berzerk_state::moonwarp_p2_r()
963 {
964 	// same as above, but for player 2 in cocktail mode
965 	signed char dialread = ioport("P2_DIAL")->read();
966 	uint8_t ret;
967 	uint8_t buttons = (ioport("P2")->read()&0xe0);
968 	if (dialread < 0) m_p2_direction = 0;
969 	else if (dialread > 0) m_p2_direction = 0x10;
970 	m_p2_counter_74ls161 += abs(dialread);
971 	m_p2_counter_74ls161 &= 0xf;
972 	ret = m_p2_counter_74ls161 | m_p2_direction | buttons;
973 	//fprintf(stderr, "dialread2: %02x, p2_counter_74ls161: %02x, spinner ret is %02x\n", dialread, m_p2_counter_74ls161, ret);
974 	return ret;
975 }
976 
977 static INPUT_PORTS_START( moonwarp )
PORT_INCLUDE(common)978 	PORT_INCLUDE( common )
979 
980 	PORT_MODIFY("SYSTEM")
981 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // is wired high for upright harness, low for cocktail; if high, cocktail dipswitch is ignored.
982 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) // Hyper flip button is common for both players in cocktail mode.
983 
984 	PORT_START("P1")
985 	PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_CUSTOM ) // spinner/dial
986 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 )
987 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 )
988 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
989 
990 	PORT_START("P1_DIAL")
991 	PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(4) PORT_RESET
992 
993 	PORT_START("P2")
994 	PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_CUSTOM ) // spinner/dial(cocktail)
995 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_COCKTAIL
996 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL
997 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
998 
999 	PORT_START("P2_DIAL")
1000 	PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(4) PORT_COCKTAIL PORT_RESET
1001 
1002 	PORT_START("F2")
1003 	PORT_DIPNAME( 0x03, 0x00, "Hardware Tests" ) PORT_DIPLOCATION("F2:1,2")
1004 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
1005 	PORT_DIPSETTING(    0x01, "Color test" )
1006 	PORT_DIPSETTING(    0x02, DEF_STR( Unknown ) )
1007 	PORT_DIPSETTING(    0x03, "Signature Analysis" )
1008 	PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F2:3")
1009 	PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
1010 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1011 	PORT_DIPNAME( 0xF8, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("F2:4,5,6,7,8")
1012 	PORT_DIPSETTING(    0x00, "10000" )
1013 	PORT_DIPSETTING(    0x08, "15000" )
1014 	PORT_DIPSETTING(    0x10, "20000" )
1015 	PORT_DIPSETTING(    0x20, "30000" )
1016 	PORT_DIPSETTING(    0x40, "40000" )
1017 	PORT_DIPSETTING(    0x80, "50000" )
1018 	PORT_DIPSETTING(    0x18, "15000 (duplicate)" )
1019 	PORT_DIPSETTING(    0x28, "15000 (duplicate)" )
1020 	PORT_DIPSETTING(    0x30, "20000 (duplicate)" )
1021 	PORT_DIPSETTING(    0x38, "15000 (duplicate)" )
1022 	PORT_DIPSETTING(    0x48, "15000 (duplicate)" )
1023 	PORT_DIPSETTING(    0x50, "20000 (duplicate)" )
1024 	PORT_DIPSETTING(    0x58, "15000 (duplicate)" )
1025 	PORT_DIPSETTING(    0x60, "30000 (duplicate)" )
1026 	PORT_DIPSETTING(    0x68, "15000 (duplicate)" )
1027 	PORT_DIPSETTING(    0x70, "20000 (duplicate)" )
1028 	PORT_DIPSETTING(    0x78, "15000 (duplicate)" )
1029 	PORT_DIPSETTING(    0x88, "15000 (duplicate)" )
1030 	PORT_DIPSETTING(    0x90, "20000 (duplicate)" )
1031 	PORT_DIPSETTING(    0x98, "15000 (duplicate)" )
1032 	PORT_DIPSETTING(    0xa0, "30000 (duplicate)" )
1033 	PORT_DIPSETTING(    0xa8, "15000 (duplicate)" )
1034 	PORT_DIPSETTING(    0xb0, "20000 (duplicate)" )
1035 	PORT_DIPSETTING(    0xb8, "15000 (duplicate)" )
1036 	PORT_DIPSETTING(    0xc0, "40000 (duplicate)" )
1037 	PORT_DIPSETTING(    0xc8, "15000 (duplicate)" )
1038 	PORT_DIPSETTING(    0xd0, "20000 (duplicate)" )
1039 	PORT_DIPSETTING(    0xd8, "15000 (duplicate)" )
1040 	PORT_DIPSETTING(    0xe0, "30000 (duplicate)" )
1041 	PORT_DIPSETTING(    0xe8, "15000 (duplicate)" )
1042 	PORT_DIPSETTING(    0xf0, "20000 (duplicate)" )
1043 	PORT_DIPSETTING(    0xf8, "15000 (duplicate)" )
1044 
1045 	PORT_START("F3")
1046 	PORT_DIPNAME( 0x01, 0x00, "Input Test Mode" ) PORT_CODE(KEYCODE_F2) PORT_TOGGLE PORT_DIPLOCATION("F3:1")
1047 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
1048 	PORT_DIPSETTING(    0x01, DEF_STR( On ) )
1049 	PORT_DIPNAME( 0x02, 0x00, "Crosshair Pattern" ) PORT_CODE(KEYCODE_F4) PORT_TOGGLE PORT_DIPLOCATION("F3:2")
1050 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
1051 	PORT_DIPSETTING(    0x02, DEF_STR( On ) )
1052 	PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F3:3")
1053 	PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
1054 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1055 	PORT_DIPNAME( 0x08, 0x00, "Spinner Orientation" ) PORT_DIPLOCATION("F3:4")
1056 	PORT_DIPSETTING(    0x08, DEF_STR( Reverse ) )
1057 	PORT_DIPSETTING(    0x00, DEF_STR( Standard ) )
1058 	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F3:5")
1059 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
1060 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1061 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F3:6")
1062 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
1063 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1064 	PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("F3:7,8")
1065 	PORT_DIPSETTING(    0x00, DEF_STR( English ) )
1066 	PORT_DIPSETTING(    0x40, DEF_STR( German ) )
1067 	PORT_DIPSETTING(    0x80, DEF_STR( French ) )
1068 	PORT_DIPSETTING(    0xc0, DEF_STR( Spanish ) )
1069 
1070 	PORT_START("F4")
1071 	BERZERK_COINAGE(1, F4)
1072 	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F4:5")
1073 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
1074 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1075 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F4:6")
1076 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
1077 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1078 	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F4:7")
1079 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
1080 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1081 	PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F4:8")
1082 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
1083 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1084 
1085 	PORT_START("F5")
1086 	BERZERK_COINAGE(2, F5)
1087 	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F5:5")
1088 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
1089 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1090 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F5:6")
1091 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
1092 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1093 	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F5:7")
1094 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
1095 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1096 	PORT_DIPNAME( 0x80, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("F5:8")
1097 	PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
1098 	PORT_DIPSETTING(    0x80, DEF_STR( Cocktail ) )
1099 
1100 	PORT_START("F6")
1101 	BERZERK_COINAGE(3, F6)
1102 	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F6:5")
1103 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
1104 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1105 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) PORT_DIPLOCATION("F6:6") // enemy spawn rate?
1106 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
1107 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1108 	PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("F6:7,8") // Difficulty select effectively chooses what level to start on, level 1, 2, 3, or 4 for very easy, easy, normal, and hard. Number here is added to the current level count (base 1) at $43be.
1109 	PORT_DIPSETTING(    0x00, DEF_STR( Very_Easy ) )
1110 	PORT_DIPSETTING(    0x40, DEF_STR( Easy ) )
1111 	PORT_DIPSETTING(    0x80, DEF_STR( Normal ) )
1112 	PORT_DIPSETTING(    0xc0, DEF_STR( Hard ) )
1113 INPUT_PORTS_END
1114 
1115 
1116 /*************************************
1117  *
1118  *  Machine drivers
1119  *
1120  *************************************/
1121 
1122 void berzerk_state::berzerk(machine_config &config)
1123 {
1124 	/* basic machine hardware */
1125 	Z80(config, m_maincpu, MAIN_CPU_CLOCK);
1126 	m_maincpu->set_addrmap(AS_PROGRAM, &berzerk_state::berzerk_map);
1127 	m_maincpu->set_addrmap(AS_IO, &berzerk_state::berzerk_io_map);
1128 
1129 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
1130 
1131 	TTL74181(config, m_ls181_10c);
1132 	TTL74181(config, m_ls181_12c);
1133 
1134 	/* video hardware */
1135 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
1136 	m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);
1137 	m_screen->set_screen_update(FUNC(berzerk_state::screen_update));
1138 
1139 	/* audio hardware */
1140 	SPEAKER(config, "mono").front_center();
1141 
1142 	S14001A(config, m_s14001a, S14001_CLOCK/16/8).add_route(ALL_OUTPUTS, "mono", 1.00); /* placeholder - the clock is software controllable */
1143 	EXIDY(config, m_custom, 0).add_route(ALL_OUTPUTS, "mono", 0.33);
1144 }
1145 
1146 
frenzy(machine_config & config)1147 void berzerk_state::frenzy(machine_config &config)
1148 {
1149 	berzerk(config);
1150 
1151 	/* basic machine hardware */
1152 	m_maincpu->set_addrmap(AS_PROGRAM, &berzerk_state::frenzy_map);
1153 }
1154 
1155 
1156 
1157 /*************************************
1158  *
1159  *  ROM definitions
1160  *
1161  *************************************/
1162 
1163 /*
1164 
1165 Berzerk program labels follow this format:
1166 
1167 BERZERK (C)    <-- ROM socket silkscreened ROM0
1168 RC31 1C
1169 1980 STERN
1170 
1171 So PCB location and silkscreen are as follows as they appear on an actual PCB:
1172 
1173 1C <--> ROM0      1D <--> ROM1
1174 
1175 3C <--> ROM6      3D <--> ROM2
1176 
1177 5C <--> ROM5      5D <--> ROM3
1178 
1179                   6D <--> ROM4
1180 
1181 NOTE: No known set uses ROM6
1182 
1183 Sound ROMs for Berzerk / Frenzy have been found labeled as:
1184 
1185 BERZERK        BERZERK
1186 R VO 1C        R VO 2C
1187 1980  STERN    1980  STERN
1188 
1189 as well as
1190 
1191 E169-1CVO      E169-2CVO
1192 RVO 1C (-9)    RVO 2C (-9)
1193 1982  STERN    1982  STERN
1194 
1195 Both sets of ROMs contain the same data.
1196 
1197 */
1198 
1199 ROM_START( berzerk ) /* All ROMs except 5C were white labels and revision RC31, 5C had a yellow label and is revision RC31A */
1200 	ROM_REGION( 0x10000, "maincpu", 0 )
CRC(ca566dbc)1201 	ROM_LOAD( "berzerk_rc31_1c.rom0.1c",  0x0000, 0x0800, CRC(ca566dbc) SHA1(fae2647f12f1cd82826db61b53b116a5e0c9f995) )
1202 	ROM_LOAD( "berzerk_rc31_1d.rom1.1d",  0x1000, 0x0800, CRC(7ba69fde) SHA1(69af170c4a39a3494dcd180737e5c87b455f9203) )
1203 	ROM_LOAD( "berzerk_rc31_3d.rom2.3d",  0x1800, 0x0800, CRC(a1d5248b) SHA1(a0b7842f6a5f86c16d80d78e7012c78b3ea11d1d) )
1204 	ROM_LOAD( "berzerk_rc31_5d.rom3.5d",  0x2000, 0x0800, CRC(fcaefa95) SHA1(07f849aa39f1e3db938187ffde4a46a588156ddc) )
1205 	ROM_LOAD( "berzerk_rc31_6d.rom4.6d",  0x2800, 0x0800, CRC(1e35b9a0) SHA1(5a5e549ec0e4803ab2d1eac6b3e7171aedf28244) )
1206 	ROM_LOAD( "berzerk_rc31a_5c.rom5.5c", 0x3000, 0x0800, CRC(e0fab8f5) SHA1(31acef9583546671debe768e3d5c695ba1b9f7e0) )
1207 	ROM_FILL(                             0x3800, 0x0800, 0xff ) /* ROM socket ROM6 at 3C is unpopulated */
1208 
1209 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1210 	ROM_LOAD( "berzerk_r_vo_1c.1c", 0x0000, 0x0800, CRC(2cfe825d) SHA1(f12fed8712f20fa8213f606c4049a8144bfea42e) )  /* VSU-1000 board */
1211 	ROM_LOAD( "berzerk_r_vo_2c.2c", 0x0800, 0x0800, CRC(d2b6324e) SHA1(20a6611ad6ec19409ac138bdae7bdfaeab6c47cf) )  /* ditto */
1212 ROM_END
1213 
1214 ROM_START( berzerka )
1215 	ROM_REGION( 0x10000, "maincpu", 0 )
1216 	ROM_LOAD( "berzerk_rc31_1c.rom0.1c", 0x0000, 0x0800, CRC(ca566dbc) SHA1(fae2647f12f1cd82826db61b53b116a5e0c9f995) )
1217 	ROM_LOAD( "berzerk_rc31_1d.rom1.1d", 0x1000, 0x0800, CRC(7ba69fde) SHA1(69af170c4a39a3494dcd180737e5c87b455f9203) )
1218 	ROM_LOAD( "berzerk_rc31_3d.rom2.3d", 0x1800, 0x0800, CRC(a1d5248b) SHA1(a0b7842f6a5f86c16d80d78e7012c78b3ea11d1d) )
1219 	ROM_LOAD( "berzerk_rc31_5d.rom3.5d", 0x2000, 0x0800, CRC(fcaefa95) SHA1(07f849aa39f1e3db938187ffde4a46a588156ddc) )
1220 	ROM_LOAD( "berzerk_rc31_6d.rom4.6d", 0x2800, 0x0800, CRC(1e35b9a0) SHA1(5a5e549ec0e4803ab2d1eac6b3e7171aedf28244) )
1221 	ROM_LOAD( "berzerk_rc31_5c.rom5.5c", 0x3000, 0x0800, CRC(c8c665e5) SHA1(e9eca4b119549e0061384abf52327c14b0d56624) )
1222 	ROM_FILL(                            0x3800, 0x0800, 0xff ) /* ROM socket ROM6 at 3C is unpopulated */
1223 
1224 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1225 	ROM_LOAD( "berzerk_r_vo_1c.1c", 0x0000, 0x0800, CRC(2cfe825d) SHA1(f12fed8712f20fa8213f606c4049a8144bfea42e) )  /* VSU-1000 board */
1226 	ROM_LOAD( "berzerk_r_vo_2c.2c", 0x0800, 0x0800, CRC(d2b6324e) SHA1(20a6611ad6ec19409ac138bdae7bdfaeab6c47cf) )  /* ditto */
1227 ROM_END
1228 
1229 ROM_START( berzerkb )
1230 	ROM_REGION( 0x10000, "maincpu", 0 )
1231 	ROM_LOAD( "berzerk_rc28_1c.rom0.1c", 0x0000, 0x0800, CRC(5b7eb77d) SHA1(8de488e279036fe40d6fb4c0dde16075309342fd) )
1232 	ROM_LOAD( "berzerk_rc28_1d.rom1.1d", 0x1000, 0x0800, CRC(e58c8678) SHA1(a11f08448b457d690b270512c9f02fcf1e41d9e0) )
1233 	ROM_LOAD( "berzerk_rc28_3d.rom2.3d", 0x1800, 0x0800, CRC(705bb339) SHA1(845191df90cd7d80f8fed3d2b69305301d921549) )
1234 	ROM_LOAD( "berzerk_rc28_5d.rom3.5d", 0x2000, 0x0800, CRC(6a1936b4) SHA1(f1635e9d2f25514c35559d2a247c3bc4b4034c19) )
1235 	ROM_LOAD( "berzerk_rc28_6d.rom4.6d", 0x2800, 0x0800, CRC(fa5dce40) SHA1(b3a3ee52bf65bbb3a20f905d3e4ebdf6871dcb5d) )
1236 	ROM_LOAD( "berzerk_rc28_5c.rom5.5c", 0x3000, 0x0800, CRC(2579b9f4) SHA1(890f0237afbb194166eae88c98de81989f408548) )
1237 	ROM_FILL(                            0x3800, 0x0800, 0xff ) /* ROM socket ROM6 at 3C is unpopulated */
1238 
1239 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1240 	ROM_LOAD( "berzerk_r_vo_1c.1c", 0x0000, 0x0800, CRC(2cfe825d) SHA1(f12fed8712f20fa8213f606c4049a8144bfea42e) )  /* VSU-1000 board */
1241 	ROM_LOAD( "berzerk_r_vo_2c.2c", 0x0800, 0x0800, CRC(d2b6324e) SHA1(20a6611ad6ec19409ac138bdae7bdfaeab6c47cf) )  /* ditto */
1242 ROM_END
1243 
1244 ROM_START( berzerkf )
1245 	ROM_REGION( 0x10000, "maincpu", 0 )
1246 	ROM_LOAD( "berzerk_rc31f_1c.rom0.1c", 0x0000, 0x0800, CRC(3ba6e56e) SHA1(f2b02dcdc3fe1de28cace39055a88f6aa0798fd1) )
1247 	ROM_LOAD( "berzerk_rc31f_1d.rom1.1d", 0x1000, 0x0800, CRC(a1de2a3e) SHA1(86ac3717ec26aeb2632583a65de6a0c2e7ea7419) )
1248 	ROM_LOAD( "berzerk_rc31f_3d.rom2.3d", 0x1800, 0x0800, CRC(bc31c478) SHA1(906d0acdee208a0bf714bd06be99321722b531c6) )
1249 	ROM_LOAD( "berzerk_rc31f_5d.rom3.5d", 0x2000, 0x0800, CRC(316192b5) SHA1(50f4ba2b59423a48c1d51fc6e4d9ea098d6f3743) )
1250 	ROM_LOAD( "berzerk_rc31f_6d.rom4.6d", 0x2800, 0x0800, CRC(cd51238c) SHA1(f0b65bdd1f225c151a93ea62812b4bb64969acac) )
1251 	ROM_LOAD( "berzerk_rc31f_5c.rom5.5c", 0x3000, 0x0800, CRC(563b13b6) SHA1(f8d137cd26535efe92780560d2f69f12d3f0fa42) )
1252 	ROM_FILL(                             0x3800, 0x0800, 0xff ) /* ROM socket ROM6 at 3C is unpopulated */
1253 
1254 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1255 	ROM_LOAD( "berzerk_rvof_1c.1c", 0x0000, 0x0800, CRC(d7bfaca2) SHA1(b8c22db0f6e86d90f3c2ac9ff9e9d0ccff314919) ) /* VSU-1000 board */
1256 	ROM_LOAD( "berzerk_rvof_2c.2c", 0x0800, 0x0800, CRC(7bdc3573) SHA1(f346f0ac9813812f2e3fe68ebbf79151975babcb) ) /* ditto */
1257 ROM_END
1258 
1259 ROM_START( berzerkg )
1260 	ROM_REGION( 0x10000, "maincpu", 0 )
1261 	ROM_LOAD( "berzerk_rc32_1c.rom0.1c",  0x0000, 0x0800, CRC(77923a9e) SHA1(3760800b7aa1245f2141897b2406f0f5af5a8d71) ) /* Need to verify all ROM labels for this set */
1262 	ROM_LOAD( "berzerk_rc32_1d.rom1.1d",  0x1000, 0x0800, CRC(19bb3aac) SHA1(11341521fd880d55ea01bceb4a321ec571f0b759) )
1263 	ROM_LOAD( "berzerk_rc32g_3d.rom2.3d", 0x1800, 0x0800, CRC(b0888ff7) SHA1(ac76400482fe37b6c8e309cd9b10855dac86ed24) )
1264 	ROM_LOAD( "berzerk_rc32_5d.rom3.5d",  0x2000, 0x0800, CRC(e23239a9) SHA1(a0505efdee4cb1962243638c641e94983673f70f) )
1265 	ROM_LOAD( "berzerk_rc32g_6d.rom4.6d", 0x2800, 0x0800, CRC(651b31b7) SHA1(890f424a5a73a95af642435c1b0cca78a9413aae) )
1266 	ROM_LOAD( "berzerk_rc32g_5c.rom5.5c", 0x3000, 0x0800, CRC(8a403bba) SHA1(686a9b58a245df6c947d14991a2e4cbaf511e2ca) )
1267 	ROM_FILL(                             0x3800, 0x0800, 0xff ) /* ROM socket ROM6 at 3C is unpopulated */
1268 
1269 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1270 	ROM_LOAD( "berzerk_rvog_1c.1c", 0x0000, 0x0800, CRC(fc1da15f) SHA1(f759a017d9e95acf0e1d35b16d8820acee7d7e3d) ) /* VSU-1000 board */
1271 	ROM_LOAD( "berzerk_rvog_2c.2c", 0x0800, 0x0800, CRC(7f6808fb) SHA1(8a9c43597f924221f68d1b31e033f1dc492cddc5) ) /* ditto */
1272 ROM_END
1273 
1274 ROM_START( berzerks )
1275 	ROM_REGION( 0x10000, "maincpu", 0 )
1276 	ROM_LOAD( "berzerk_rc32_1c.rom0.1c",  0x0000, 0x0800, CRC(77923a9e) SHA1(3760800b7aa1245f2141897b2406f0f5af5a8d71) ) /* Same as the German set */
1277 	ROM_LOAD( "berzerk_rc32_1d.rom1.1d",  0x1000, 0x0800, CRC(19bb3aac) SHA1(11341521fd880d55ea01bceb4a321ec571f0b759) ) /* Same as the German set */
1278 	ROM_LOAD( "berzerk_rc32_3d.rom2.3d",  0x1800, 0x0800, CRC(5423ea87) SHA1(c49f81f0dee4479965023aac15daac10bbbefe65) )
1279 	ROM_LOAD( "berzerk_rc32_5d.rom3.5d",  0x2000, 0x0800, CRC(e23239a9) SHA1(a0505efdee4cb1962243638c641e94983673f70f) ) /* Same as the German set */
1280 	ROM_LOAD( "berzerk_rc32_6d.rom4.6d",  0x2800, 0x0800, CRC(959efd86) SHA1(3401f86ed6202e8790cef00c73af29cc282d322e) )
1281 	ROM_LOAD( "berzerk_rc32s_5c.rom5.5c", 0x3000, 0x0800, CRC(9ad80e4e) SHA1(f79a86dd3dee5d53c2a60eda5b5181816bd73bc3) )
1282 	ROM_FILL(                             0x3800, 0x0800, 0xff ) /* ROM socket ROM6 at 3C is unpopulated */
1283 
1284 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1285 	ROM_LOAD( "berzerk_rvos_1c.1c", 0x0000, 0x0800, CRC(0b51409c) SHA1(75333853a82029f080e3db61441ba6091c1aab55) ) /* VSU-1000 board */
1286 	/* ROM socket 2C is unpopulated */
1287 ROM_END
1288 
1289 
1290 /*
1291 
1292 Frenzy program labels follow this format:
1293 
1294 FRENZY    (c)    <-- ROM socket silkscreened ROM5
1295 RA1 ROM5(10)
1296 1982 STERN
1297 
1298 So PCB location and silkscreen are as follows as they appear on an actual PCB:
1299 
1300                   1D <--> ROM1
1301 
1302 3C <--> ROM6      3D <--> ROM2
1303 
1304 5C <--> ROM5      5D <--> ROM3
1305 
1306                   6D <--> ROM4
1307 
1308 NOTE: No known set uses ROM6 & there is NO socket for a ROM0
1309 
1310 Sound ROMs for Berzerk / Frenzy have been found labeled as:
1311 
1312 BERZERK        BERZERK
1313 R VO 1C        R VO 2C
1314 1980  STERN    1980  STERN
1315 
1316 as well as
1317 
1318 E169-1CVO      E169-2CVO
1319 RVO 1C (-9)    RVO 2C (-9)
1320 1982  STERN    1982  STERN
1321 
1322 Both sets of ROMs contain the same data.
1323 
1324 */
1325 ROM_START( frenzy )
1326 	ROM_REGION( 0x10000, "maincpu", 0 )
1327 	ROM_LOAD( "frenzy_ra1_rom1.1d", 0x0000, 0x1000, CRC(abdd25b8) SHA1(e6a3ab826b51b2c6ddd63d55681848fccad800dd) )
1328 	ROM_LOAD( "frenzy_ra1_rom2.3d", 0x1000, 0x1000, CRC(536e4ae8) SHA1(913385c43b8902d3d3ad2194a3137e19e61c6573) )
1329 	ROM_LOAD( "frenzy_ra1_rom3.5d", 0x2000, 0x1000, CRC(3eb9bc9b) SHA1(1e43e76ae0606a6d41d9006005d6001bdee48694) )
1330 	ROM_LOAD( "frenzy_ra1_rom4.6d", 0x3000, 0x1000, CRC(e1d3133c) SHA1(2af4a9bc2b29735a548ae770f872127bc009cc42) )
1331 	ROM_LOAD( "frenzy_ra1_rom5.5c", 0xc000, 0x1000, CRC(5581a7b1) SHA1(1f633c1c29d3b64f701c601feba26da66a6c6f23) )
1332 
1333 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1334 	ROM_LOAD( "e169-1cvo.1c", 0x0000, 0x0800, CRC(2cfe825d) SHA1(f12fed8712f20fa8213f606c4049a8144bfea42e) ) /* VSU-1000 board */
1335 	ROM_LOAD( "e169-2cvo.2c", 0x0800, 0x0800, CRC(d2b6324e) SHA1(20a6611ad6ec19409ac138bdae7bdfaeab6c47cf) ) /* ditto */
1336 
1337 	ROM_REGION( 0x0020, "proms", 0 )
1338 	ROM_LOAD( "frenzy_decoder_6ea1.6e", 0x0000, 0x0020, CRC(4471ca5d) SHA1(ba8dca2ec076818f8ad8c17b15c77965e36fa05e) ) /* address decoder/ROM select PROM (N82S123N) */
1339 ROM_END
1340 
1341 
1342 /*
1343    The original / prototype version of Moon War runs on Frenzy Hardware.
1344 
1345    The more common version of Moon War runs on modified Super Cobra (galaxian.cpp) hardware and is often called
1346    'Moon War II' because it is the second version, and the ROMs as well as many of the PCBs are labeled as such.
1347 
1348    So far only 2 original boards of this have been found, one with only the sound ROMs on it, and the other
1349    with only the program ROMs on it.  This set is a combination of dumps from those two boards, so there
1350    is a small chance they could be mismatched.
1351 
1352 Sound ROMs for Moon War:
1353 
1354 MOON WAR       MOON WAR
1355 RVO  1C        RVO  2C
1356 1981 STERN     1981 STERN
1357 
1358 NOTE: The BPROM from the sound board set is most likely correct.  The program ROM board reportedly had ORIGINAL program
1359       ROMs transferred over to a standard Frenzy PCB due to damage of the original Moon War PCB.
1360 */
1361 ROM_START( moonwarp )
1362 	ROM_REGION( 0x10000, "maincpu", 0 )
1363 	ROM_LOAD( "1d.bin", 0x0000, 0x1000, CRC(75470634) SHA1(1a811fef39724fd227e06b694841d3dad5659622) )
1364 	ROM_LOAD( "3d.bin", 0x1000, 0x1000, CRC(a9d046dc) SHA1(88afccd09d2809cafd12dd40ab3be77e3707cfc5) )
1365 	ROM_LOAD( "5d.bin", 0x2000, 0x1000, CRC(bf671737) SHA1(cdfae1eb8995c2251813cc5633fc809aa9e6a36f) )
1366 	ROM_LOAD( "6d.bin", 0x3000, 0x1000, CRC(cef2d697) SHA1(5c31c6e7002f0d944b3028d1b804480acf3af042) )
1367 	ROM_LOAD( "5c.bin", 0xc000, 0x1000, CRC(a3d551ab) SHA1(a32352727b5475a6ec6c495c55f01ccd6e024f98) )
1368 
1369 	ROM_REGION( 0x01000, "speech", 0 ) /* voice data */
1370 	ROM_LOAD( "moon_war_rv0_1c.1c", 0x0000, 0x0800, CRC(9e9a653f) SHA1(cf49a38ef343ace271ba1e5dde38bd8b9c0bd876) ) /* VSU-1000 board */
1371 	ROM_LOAD( "moon_war_rv0_2c.2c", 0x0800, 0x0800, CRC(73fd988d) SHA1(08a2aeb4d87eee58e38e4e3f749a95f2308aceb0) ) /* ditto */
1372 
1373 	ROM_REGION( 0x0020, "proms", 0 )
1374 	ROM_LOAD( "n82s123.6e", 0x0000, 0x0020, CRC(4471ca5d) SHA1(ba8dca2ec076818f8ad8c17b15c77965e36fa05e) ) /* address decoder/ROM select PROM - from board with prg ROMs, same as Frenzy */
1375 	ROM_LOAD( "prom.6e",    0x0000, 0x0020, CRC(56bffba3) SHA1(c8e24f6361c50bcb4c9d3f39cdaf4172c2a2b318) ) /* address decoder/ROM select PROM - from the sound ROM only set */
1376 ROM_END
1377 
1378 void berzerk_state::init_moonwarp()
1379 {
1380 	address_space &io = m_maincpu->space(AS_IO);
1381 	io.install_read_handler (0x48, 0x48, read8smo_delegate(*this, FUNC(berzerk_state::moonwarp_p1_r)));
1382 	io.install_read_handler (0x4a, 0x4a, read8smo_delegate(*this, FUNC(berzerk_state::moonwarp_p2_r)));
1383 
1384 	save_item(NAME(m_p1_counter_74ls161));
1385 	save_item(NAME(m_p1_direction));
1386 	save_item(NAME(m_p2_counter_74ls161));
1387 	save_item(NAME(m_p2_direction));
1388 }
1389 
1390 /*************************************
1391  *
1392  *  Game drivers
1393  *
1394  *************************************/
1395 
1396 GAME( 1980, berzerk,  0,       berzerk, berzerk,  berzerk_state, empty_init,    ROT0, "Stern Electronics", "Berzerk (revision RC31A)", MACHINE_SUPPORTS_SAVE )
1397 GAME( 1980, berzerka, berzerk, berzerk, berzerk,  berzerk_state, empty_init,    ROT0, "Stern Electronics", "Berzerk (revision RC31)",  MACHINE_SUPPORTS_SAVE )
1398 GAME( 1980, berzerkb, berzerk, berzerk, berzerk,  berzerk_state, empty_init,    ROT0, "Stern Electronics", "Berzerk (revision RC28)",  MACHINE_SUPPORTS_SAVE )
1399 GAME( 1980, berzerkf, berzerk, berzerk, berzerkf, berzerk_state, empty_init,    ROT0, "Stern Electronics", "Berzerk (French Speech, revision RC31)", MACHINE_SUPPORTS_SAVE )
1400 GAME( 1980, berzerkg, berzerk, berzerk, berzerkg, berzerk_state, empty_init,    ROT0, "Stern Electronics", "Berzerk (German Speech, revision RC32)", MACHINE_SUPPORTS_SAVE )
1401 GAME( 1980, berzerks, berzerk, berzerk, berzerks, berzerk_state, empty_init,    ROT0, "Stern Electronics (Sonic License)", "Berzerk (Spanish Speech, revision RC32)", MACHINE_SUPPORTS_SAVE )
1402 GAME( 1981, frenzy,   0,       frenzy,  frenzy,   berzerk_state, empty_init,    ROT0, "Stern Electronics", "Frenzy (revision RA1)", MACHINE_SUPPORTS_SAVE )
1403 GAME( 1981, moonwarp, 0,       frenzy,  moonwarp, berzerk_state, init_moonwarp, ROT0, "Stern Electronics", "Moon War (prototype on Frenzy hardware)", MACHINE_SUPPORTS_SAVE )
1404