1 // license:BSD-3-Clause
2 // copyright-holders:Phil Stroffolino
3 /*
4 To Do:
5 - redump COP420 internal ROM
6 - get sound working
7 - map and test any remaining input ports
8 
9 Looping
10 (C)1981 Venture Line
11 
12     Main CPU
13         TMS9995
14 
15     COP420 Microcontroller
16         protection
17 
18     Sound CPU
19         TMS9980
20         AY-3-8910
21         TMS5220 (SPEECH)
22 
23 ---------------------------------------------------------------
24 
25 Sky Bumper
26 (C)1982 Venture Line
27 
28     This is a ROM swap for Looping.  There are two 6116's on
29     the CPU board, where there is only one on Looping.
30 
31 ===============================================================
32 
33 LOOPING CHIP PLACEMENT
34 
35 THERE ARE AT LEAST TWO VERSIONS OF THIS GAME
36 VERSION NUMBERS FOR THIS PURPOSE ARE CHOSEN AT RANDOM
37 
38 IC NAME   POSITION   BOARD  TYPE   IC NAME  POSITION  TYPE
39 VER-1                         VER-2
40 ---------------------------------------------------------------
41 LOS-2-7   13A        I/O    2532    SAME    13A       2532
42 LOS-1-1-2 11A         "      "      SAME    11A        "
43 LOS-3-1   13C         "      "      I-O-V2  13C        "
44 
45 VLI1      2A         ROM    2764    VLI-7-1 2A         "
46 VLI3      5A          "      "      VLI-7-2 4A         "
47 VLI9-5    8A          "      "      VLI-4-3 5A         "
48 L056-6    9A          "      "      VLI-8-4 7A         "
49                       "             LO56-5  8A         "
50                       "             LO56-6  9A         "
51                       "             VLI-8-7 10A        "
52                   ON RIBBON CABLE   18S030  11B             color prom?
53                      REAR BD      LOG.1-9-3 6A        2716  tiles
54                                   LOG.3     8A         "    tiles
55 */
56 
57 #include "emu.h"
58 #include "cpu/cop400/cop400.h"
59 #include "cpu/tms9900/tms9995.h"
60 #include "cpu/tms9900/tms9980a.h"
61 #include "machine/74259.h"
62 #include "machine/gen_latch.h"
63 #include "machine/watchdog.h"
64 #include "sound/ay8910.h"
65 #include "sound/dac.h"
66 #include "sound/tms5220.h"
67 #include "video/resnet.h"
68 #include "emupal.h"
69 #include "screen.h"
70 #include "speaker.h"
71 #include "tilemap.h"
72 
73 
74 /*************************************
75  *
76  *  Constants
77  *
78  *************************************/
79 
80 #define MAIN_CPU_CLOCK      (12000000)
81 #define SOUND_CLOCK         (8000000)
82 #define COP_CLOCK           (SOUND_CLOCK/2)     // unknown guess
83 #define TMS_CLOCK           (640000)
84 
85 /* the schematics are very blurry here and don't actually specify the clock
86    values; however, everything else about the sync chain implies the standard
87    18.432MHz master clock, like is used in similar hardware of the time */
88 #define MASTER_CLOCK        (18432000)
89 
90 #define PIXEL_CLOCK         (MASTER_CLOCK/3)
91 
92 #define HTOTAL              (384)
93 #define HBEND               (0)
94 #define HBSTART             (256)
95 
96 #define VTOTAL              (264)
97 #define VBEND               (16)
98 #define VBSTART             (224+16)
99 
100 
101 /*************************************
102  *
103  *  Type definitions
104  *
105  *************************************/
106 
107 class looping_state : public driver_device
108 {
109 public:
looping_state(const machine_config & mconfig,device_type type,const char * tag)110 	looping_state(const machine_config &mconfig, device_type type, const char *tag) :
111 		driver_device(mconfig, type, tag),
112 		m_videoram(*this, "videoram"),
113 		m_colorram(*this, "colorram"),
114 		m_spriteram(*this, "spriteram"),
115 		m_maincpu(*this, "maincpu"),
116 		m_audiocpu(*this, "audiocpu"),
117 		m_aysnd(*this, "aysnd"),
118 		m_tms(*this, "tms"),
119 		m_dac(*this, "dac"),
120 		m_gfxdecode(*this, "gfxdecode"),
121 		m_palette(*this, "palette"),
122 		m_watchdog(*this, "watchdog")
123 	{ }
124 
125 	void looping(machine_config &config);
126 
127 	void init_looping();
128 
129 protected:
130 	virtual void machine_start() override;
131 	virtual void machine_reset() override;
132 	virtual void video_start() override;
133 
134 private:
135 	DECLARE_WRITE_LINE_MEMBER(flip_screen_x_w);
136 	DECLARE_WRITE_LINE_MEMBER(flip_screen_y_w);
137 	void videoram_w(offs_t offset, uint8_t data);
138 	void colorram_w(offs_t offset, uint8_t data);
139 	DECLARE_WRITE_LINE_MEMBER(level2_irq_set);
140 	DECLARE_WRITE_LINE_MEMBER(main_irq_ack_w);
141 	DECLARE_WRITE_LINE_MEMBER(watchdog_w);
142 	DECLARE_WRITE_LINE_MEMBER(souint_clr);
143 	DECLARE_WRITE_LINE_MEMBER(ballon_enable_w);
144 	void out_0_w(uint8_t data);
145 	void out_2_w(uint8_t data);
146 	uint8_t adc_r();
147 	void adc_w(uint8_t data);
148 	DECLARE_WRITE_LINE_MEMBER(plr2_w);
149 	uint8_t cop_unk_r();
150 	DECLARE_READ_LINE_MEMBER(cop_serial_r);
151 	void cop_l_w(uint8_t data);
152 	uint8_t protection_r();
153 	DECLARE_WRITE_LINE_MEMBER(spcint);
154 	void sound_sw(uint8_t data);
155 	DECLARE_WRITE_LINE_MEMBER(ay_enable_w);
156 	DECLARE_WRITE_LINE_MEMBER(speech_enable_w);
157 	TILE_GET_INFO_MEMBER(get_tile_info);
158 	void palette(palette_device &palette) const;
159 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
160 	INTERRUPT_GEN_MEMBER(interrupt);
161 	void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
162 
163 	void io_map(address_map &map);
164 	void map(address_map &map);
165 	void sound_io_map(address_map &map);
166 	void sound_map(address_map &map);
167 
168 	// memory pointers
169 	required_shared_ptr<uint8_t> m_videoram;
170 	required_shared_ptr<uint8_t> m_colorram;
171 	required_shared_ptr<uint8_t> m_spriteram;
172 	uint8_t m_cop_port_l;
173 
174 	// tilemaps
175 	tilemap_t * m_bg_tilemap;
176 
177 	required_device<tms9995_device> m_maincpu;
178 	required_device<cpu_device> m_audiocpu;
179 	required_device<ay8910_device> m_aysnd;
180 	required_device<tms5220_device> m_tms;
181 	required_device<dac_byte_interface> m_dac;
182 	required_device<gfxdecode_device> m_gfxdecode;
183 	required_device<palette_device> m_palette;
184 	required_device<watchdog_timer_device> m_watchdog;
185 };
186 
187 
188 
189 /*************************************
190  *
191  *  Palette conversion
192  *
193  *************************************/
194 
palette(palette_device & palette) const195 void looping_state::palette(palette_device &palette) const
196 {
197 	uint8_t const *const color_prom = memregion("proms")->base();
198 	static constexpr int resistances[3] = { 1000, 470, 220 };
199 
200 	// compute the color output resistor weights
201 	double rweights[3], gweights[3], bweights[2];
202 	compute_resistor_weights(0, 255, -1.0,
203 			3,  &resistances[0], rweights, 470, 0,
204 			3,  &resistances[0], gweights, 470, 0,
205 			2,  &resistances[1], bweights, 470, 0);
206 
207 	// initialize the palette with these colors
208 	for (int i = 0; i < 32; i++)
209 	{
210 		int bit0, bit1, bit2;
211 
212 		// red component
213 		bit0 = BIT(color_prom[i], 0);
214 		bit1 = BIT(color_prom[i], 1);
215 		bit2 = BIT(color_prom[i], 2);
216 		int const r = combine_weights(rweights, bit0, bit1, bit2);
217 
218 		// green component
219 		bit0 = BIT(color_prom[i], 3);
220 		bit1 = BIT(color_prom[i], 4);
221 		bit2 = BIT(color_prom[i], 5);
222 		int const g = combine_weights(gweights, bit0, bit1, bit2);
223 
224 		// blue component
225 		bit0 = BIT(color_prom[i], 6);
226 		bit1 = BIT(color_prom[i], 7);
227 		int const b = combine_weights(bweights, bit0, bit1);
228 
229 		palette.set_pen_color(i, rgb_t(r, g, b));
230 	}
231 }
232 
233 
234 
235 /*************************************
236  *
237  *  Video startup/tilemap config
238  *
239  *************************************/
240 
TILE_GET_INFO_MEMBER(looping_state::get_tile_info)241 TILE_GET_INFO_MEMBER(looping_state::get_tile_info)
242 {
243 	int tile_number = m_videoram[tile_index];
244 	int color = m_colorram[(tile_index & 0x1f) * 2 + 1] & 0x07;
245 	tileinfo.set(0, tile_number, color, 0);
246 }
247 
248 
video_start()249 void looping_state::video_start()
250 {
251 	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(looping_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8,8, 32,32);
252 
253 	m_bg_tilemap->set_scroll_cols(0x20);
254 }
255 
256 
257 
258 /*************************************
259  *
260  *  Video write handlers
261  *
262  *************************************/
263 
WRITE_LINE_MEMBER(looping_state::flip_screen_x_w)264 WRITE_LINE_MEMBER(looping_state::flip_screen_x_w)
265 {
266 	flip_screen_x_set(!state);
267 	m_bg_tilemap->set_scrollx(0, flip_screen() ? 128 : 0);
268 }
269 
270 
WRITE_LINE_MEMBER(looping_state::flip_screen_y_w)271 WRITE_LINE_MEMBER(looping_state::flip_screen_y_w)
272 {
273 	flip_screen_y_set(!state);
274 	m_bg_tilemap->set_scrollx(0, flip_screen() ? 128 : 0);
275 }
276 
277 
videoram_w(offs_t offset,uint8_t data)278 void looping_state::videoram_w(offs_t offset, uint8_t data)
279 {
280 	m_videoram[offset] = data;
281 	m_bg_tilemap->mark_tile_dirty(offset);
282 }
283 
284 
colorram_w(offs_t offset,uint8_t data)285 void looping_state::colorram_w(offs_t offset, uint8_t data)
286 {
287 	m_colorram[offset] = data;
288 
289 	// odd bytes are column color attribute
290 	if (offset & 1)
291 	{
292 		// mark the whole column dirty
293 		offs_t offs = (offset/2);
294 		for (int i = 0; i < 0x20; i++)
295 			m_bg_tilemap->mark_tile_dirty(i * 0x20 + offs);
296 	}
297 
298 	// even bytes are column scroll
299 	else
300 		m_bg_tilemap->set_scrolly(offset/2, data);
301 }
302 
303 
304 
305 /*************************************
306  *
307  *  Video update
308  *
309  *************************************/
310 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)311 void looping_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
312 {
313 	const uint8_t *source;
314 
315 	for (source = m_spriteram; source < m_spriteram + 0x40; source += 4)
316 	{
317 		int sx = source[3];
318 		int sy = 240 - source[0];
319 		int flipx = source[1] & 0x40;
320 		int flipy = source[1] & 0x80;
321 		int code  = source[1] & 0x3f;
322 		int color = source[2];
323 
324 		if (flip_screen_x())
325 		{
326 			sx = 240 - sx;
327 			flipx = !flipx;
328 		}
329 
330 		if (flip_screen_y())
331 		{
332 			sy = 240 - sy;
333 			flipy = !flipy;
334 		}
335 
336 		m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, code, color, flipx, flipy, sx, sy, 0);
337 	}
338 }
339 
340 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)341 uint32_t looping_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
342 {
343 	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
344 
345 	draw_sprites(bitmap, cliprect);
346 	return 0;
347 }
348 
349 
350 
351 /*************************************
352  *
353  *  Machine start/reset
354  *
355  *************************************/
356 
machine_start()357 void looping_state::machine_start()
358 {
359 	save_item(NAME(m_cop_port_l));
360 }
361 
machine_reset()362 void looping_state::machine_reset()
363 {
364 	// Disable auto wait state generation by raising the READY line on reset
365 	m_maincpu->ready_line(ASSERT_LINE);
366 	m_maincpu->reset_line(ASSERT_LINE);
367 
368 	m_cop_port_l = 0;
369 }
370 
371 /*************************************
372  *
373  *  Interrupt handling
374  *
375  *************************************/
376 
INTERRUPT_GEN_MEMBER(looping_state::interrupt)377 INTERRUPT_GEN_MEMBER(looping_state::interrupt)
378 {
379 	m_maincpu->set_input_line(INT_9995_INT1, ASSERT_LINE);
380 }
381 
382 
WRITE_LINE_MEMBER(looping_state::level2_irq_set)383 WRITE_LINE_MEMBER(looping_state::level2_irq_set)
384 {
385 	logerror("Level 2 int = %d\n", state);
386 	if (state == 0)
387 		m_maincpu->set_input_line(INT_9995_INT1, ASSERT_LINE);
388 }
389 
390 
WRITE_LINE_MEMBER(looping_state::main_irq_ack_w)391 WRITE_LINE_MEMBER(looping_state::main_irq_ack_w)
392 {
393 	if (state == 0)
394 		m_maincpu->set_input_line(INT_9995_INT1, CLEAR_LINE);
395 }
396 
WRITE_LINE_MEMBER(looping_state::watchdog_w)397 WRITE_LINE_MEMBER(looping_state::watchdog_w)
398 {
399 	m_watchdog->watchdog_reset();
400 }
401 
402 
WRITE_LINE_MEMBER(looping_state::souint_clr)403 WRITE_LINE_MEMBER(looping_state::souint_clr)
404 {
405 	logerror("Soundint clr = %d\n", state);
406 	if (state == 0)
407 		m_audiocpu->set_input_line(0, CLEAR_LINE);
408 }
409 
410 
WRITE_LINE_MEMBER(looping_state::spcint)411 WRITE_LINE_MEMBER(looping_state::spcint)
412 {
413 	logerror("Speech /int = %d\n", state==ASSERT_LINE? 1:0);
414 	m_audiocpu->set_input_line(INT_9980A_LEVEL4, state==ASSERT_LINE? CLEAR_LINE : ASSERT_LINE);
415 }
416 
417 
418 /*************************************
419  *
420  *  Custom DAC handling
421  *
422  *************************************/
423 
sound_sw(uint8_t data)424 void looping_state::sound_sw(uint8_t data)
425 {
426 	/* this can be improved by adding the missing signals for decay etc. (see schematics)
427 
428 	    0001 = ASOV
429 	    0002 = AVOL2
430 	    0003 = AVOL1
431 	    0004 = ADECAY1
432 	    0005 = ADECAY
433 	    0006 = ASA
434 	    0007 = AFA
435 	*/
436 
437 	m_dac->write(((BIT(~data, 2) << 1) + BIT(~data, 3)) * BIT(~data, 7));
438 }
439 
440 
441 
442 /*************************************
443  *
444  *  Sound controls
445  *
446  *************************************/
447 
WRITE_LINE_MEMBER(looping_state::ay_enable_w)448 WRITE_LINE_MEMBER(looping_state::ay_enable_w)
449 {
450 	for (int output = 0; output < 3; output++)
451 		m_aysnd->set_output_gain(output, state ? 1.0 : 0.0);
452 }
453 
454 
WRITE_LINE_MEMBER(looping_state::speech_enable_w)455 WRITE_LINE_MEMBER(looping_state::speech_enable_w)
456 {
457 	m_tms->set_output_gain(0, state ? 1.0 : 0.0);
458 }
459 
460 
WRITE_LINE_MEMBER(looping_state::ballon_enable_w)461 WRITE_LINE_MEMBER(looping_state::ballon_enable_w)
462 {
463 	osd_printf_debug("ballon_enable_w = %d\n", state);
464 }
465 
466 
467 
468 /*************************************
469  *
470  *  Misc I/O
471  *
472  *************************************/
473 
out_0_w(uint8_t data)474 void looping_state::out_0_w(uint8_t data) { osd_printf_debug("out0 = %02X\n", data); }
out_2_w(uint8_t data)475 void looping_state::out_2_w(uint8_t data) { osd_printf_debug("out2 = %02X\n", data); }
476 
adc_r()477 uint8_t looping_state::adc_r() { osd_printf_debug("%04X:ADC read\n", m_maincpu->pc()); return 0xff; }
adc_w(uint8_t data)478 void looping_state::adc_w(uint8_t data) { osd_printf_debug("%04X:ADC write = %02X\n", m_maincpu->pc(), data); }
479 
WRITE_LINE_MEMBER(looping_state::plr2_w)480 WRITE_LINE_MEMBER(looping_state::plr2_w)
481 {
482 	/* set to 1 after IDLE, cleared to 0 during processing
483 	   is this an LED on the PCB? */
484 }
485 
486 
487 
488 /*************************************
489  *
490  *  Protection
491  *
492  *************************************/
493 
cop_unk_r()494 uint8_t looping_state::cop_unk_r()
495 {
496 	return 1;
497 }
498 
READ_LINE_MEMBER(looping_state::cop_serial_r)499 READ_LINE_MEMBER(looping_state::cop_serial_r)
500 {
501 	return 1;
502 }
503 
cop_l_w(uint8_t data)504 void looping_state::cop_l_w(uint8_t data)
505 {
506 	m_cop_port_l = data;
507 	logerror("%02x  ",data);
508 }
509 
protection_r()510 uint8_t looping_state::protection_r()
511 {
512 //        The code reads ($7002) ($7004) alternately
513 //        The result must change at least once every 10 reads
514 //        A read from ($34b0 + result) must == $01
515 
516 //        Valid values:
517 //            $61 $67
518 //            $B7 $BF
519 //            $DB
520 //            $E1
521 //            $F3 $F7 $FD $FF
522 
523 //        Because they read alternately from different locations,
524 //        it is trivial to bypass the protection.
525 
526 //        cop write alternately $02 $01 $08 $04 in port $102
527 //        cop write randomly fc (unfortunately) but 61,67,b7,bf,db,e1,f3,fd,ff too and only these values
528 
529 	// missing something
530 	if(m_cop_port_l != 0xfc) return m_cop_port_l;
531 	return 0xff;
532 }
533 
534 
535 /*************************************
536  *
537  *  Address maps
538  *
539  *************************************/
540 
map(address_map & map)541 void looping_state::map(address_map &map)
542 {
543 	map(0x0000, 0x7fff).rom();
544 
545 	map(0x9000, 0x93ff).ram().w(FUNC(looping_state::videoram_w)).share(m_videoram);
546 
547 	map(0x9800, 0x983f).mirror(0x0700).ram().w(FUNC(looping_state::colorram_w)).share(m_colorram);
548 	map(0x9840, 0x987f).mirror(0x0700).ram().share(m_spriteram);
549 	map(0x9880, 0x98ff).mirror(0x0700).ram();
550 
551 	map(0xb000, 0xb007).mirror(0x07f8).w("videolatch", FUNC(ls259_device::write_d0));
552 
553 	map(0xe000, 0xefff).ram();
554 	map(0xf800, 0xf800).mirror(0x03fc).portr("P1").w(FUNC(looping_state::out_0_w));                      // /OUT0
555 	map(0xf801, 0xf801).mirror(0x03fc).portr("P2").w("soundlatch", FUNC(generic_latch_8_device::write)); // /OUT1
556 	map(0xf802, 0xf802).mirror(0x03fc).portr("DSW").w(FUNC(looping_state::out_2_w));                     // /OUT2
557 	map(0xf803, 0xf803).mirror(0x03fc).rw(FUNC(looping_state::adc_r), FUNC(looping_state::adc_w));
558 }
559 
io_map(address_map & map)560 void looping_state::io_map(address_map &map)
561 {
562 	map(0x0800, 0x080f).w("mainlatch", FUNC(ls259_device::write_d0));
563 }
564 
565 
566 // complete memory map derived from schematics
sound_map(address_map & map)567 void looping_state::sound_map(address_map &map)
568 {
569 	map.global_mask(0x3fff);
570 	map(0x0000, 0x37ff).rom();
571 	map(0x3800, 0x3bff).ram();
572 	map(0x3c00, 0x3c00).mirror(0x00f4).rw(m_aysnd, FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
573 	map(0x3c01, 0x3c01).mirror(0x00f6).noprw();
574 	map(0x3c02, 0x3c02).mirror(0x00f4).nopr().w(m_aysnd, FUNC(ay8910_device::data_w));
575 	map(0x3e00, 0x3e00).mirror(0x00f4).nopr().w(m_tms, FUNC(tms5220_device::data_w));
576 	map(0x3e01, 0x3e01).mirror(0x00f6).noprw();
577 	map(0x3e02, 0x3e02).mirror(0x00f4).r(m_tms, FUNC(tms5220_device::status_r)).nopw();
578 }
579 
sound_io_map(address_map & map)580 void looping_state::sound_io_map(address_map &map)
581 {
582 	map(0x0000, 0x000f).w("sen0", FUNC(ls259_device::write_d0));
583 	map(0x0010, 0x001f).w("sen1", FUNC(ls259_device::write_d0));
584 }
585 
586 
587 /*************************************
588  *
589  *  Graphics definitions
590  *
591  *************************************/
592 
593 static const gfx_layout sprite_layout =
594 {
595 	16,16,
596 	RGN_FRAC(1,2),
597 	2,
598 	{ RGN_FRAC(1,2), RGN_FRAC(0,2) },
599 	{ STEP8(0,1), STEP8(64,1) },
600 	{ STEP8(0,8), STEP8(128,8) },
601 	8*8*4
602 };
603 
604 
605 static GFXDECODE_START( gfx_looping )
606 	GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x2_planar, 0, 8 )
607 	GFXDECODE_ENTRY( "gfx1", 0, sprite_layout,    0, 8 )
608 GFXDECODE_END
609 
610 
611 /*************************************
612  *
613  *  Machine drivers
614  *
615  *************************************/
616 
looping(machine_config & config)617 void looping_state::looping(machine_config &config)
618 {
619 	// CPU TMS9995, standard variant; no line connections
620 	TMS9995(config, m_maincpu, MAIN_CPU_CLOCK);
621 	m_maincpu->set_addrmap(AS_PROGRAM, &looping_state::map);
622 	m_maincpu->set_addrmap(AS_IO, &looping_state::io_map);
623 	m_maincpu->set_vblank_int("screen", FUNC(looping_state::interrupt));
624 
625 	// CPU TMS9980A for audio subsystem; no line connections
626 	TMS9980A(config, m_audiocpu, SOUND_CLOCK);
627 	m_audiocpu->set_addrmap(AS_PROGRAM, &looping_state::sound_map);
628 	m_audiocpu->set_addrmap(AS_IO, &looping_state::sound_io_map);
629 
630 	cop420_cpu_device &cop(COP420(config, "mcu", COP_CLOCK));
631 	cop.set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false);
632 	cop.write_l().set(FUNC(looping_state::cop_l_w));
633 	cop.read_l().set(FUNC(looping_state::cop_unk_r));
634 	cop.read_g().set(FUNC(looping_state::cop_unk_r));
635 	cop.read_in().set(FUNC(looping_state::cop_unk_r));
636 	cop.read_si().set(FUNC(looping_state::cop_serial_r));
637 
638 	ls259_device &mainlatch(LS259(config, "mainlatch")); // C9 on CPU board
639 	// Q0 = A16
640 	// Q1 = A17
641 	// Q2 = COLOR 9
642 	mainlatch.q_out_cb<3>().set(FUNC(looping_state::plr2_w));
643 	// Q4 = C0
644 	// Q5 = C1
645 	mainlatch.q_out_cb<6>().set(FUNC(looping_state::main_irq_ack_w));
646 	mainlatch.q_out_cb<7>().set(FUNC(looping_state::watchdog_w));
647 
648 	WATCHDOG_TIMER(config, m_watchdog);
649 
650 	// video hardware
651 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
652 	screen.set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);
653 	screen.set_screen_update(FUNC(looping_state::screen_update));
654 	screen.set_palette(m_palette);
655 
656 	GFXDECODE(config, m_gfxdecode, m_palette, gfx_looping);
657 	PALETTE(config, m_palette, FUNC(looping_state::palette), 32);
658 
659 	ls259_device &videolatch(LS259(config, "videolatch")); // E2 on video board
660 	videolatch.q_out_cb<1>().set(FUNC(looping_state::level2_irq_set));
661 	videolatch.q_out_cb<6>().set(FUNC(looping_state::flip_screen_x_w));
662 	videolatch.q_out_cb<7>().set(FUNC(looping_state::flip_screen_y_w));
663 
664 	// sound hardware
665 	SPEAKER(config, "speaker").front_center();
666 
667 	GENERIC_LATCH_8(config, "soundlatch").data_pending_callback().set_inputline(m_audiocpu, INT_9980A_LEVEL2);
668 
669 	AY8910(config, m_aysnd, SOUND_CLOCK/4);
670 	m_aysnd->port_a_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
671 	m_aysnd->add_route(ALL_OUTPUTS, "speaker", 0.2);
672 
673 	TMS5220(config, m_tms, TMS_CLOCK);
674 	m_tms->irq_cb().set(FUNC(looping_state::spcint));
675 	m_tms->add_route(ALL_OUTPUTS, "speaker", 0.5);
676 
677 	DAC_2BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.15); // unknown DAC
678 
679 	ls259_device &sen0(LS259(config, "sen0")); // B3 on sound board
680 	sen0.q_out_cb<0>().set(FUNC(looping_state::souint_clr));
681 	sen0.parallel_out_cb().set(FUNC(looping_state::sound_sw));
682 
683 	ls259_device &sen1(LS259(config, "sen1")); // A1 on sound board with outputs connected to 4016 at B1
684 	sen1.q_out_cb<0>().set(FUNC(looping_state::ay_enable_w));
685 	sen1.q_out_cb<1>().set(FUNC(looping_state::speech_enable_w));
686 	sen1.q_out_cb<2>().set(FUNC(looping_state::ballon_enable_w));
687 }
688 
689 
690 
691 /*************************************
692  *
693  *  Input ports
694  *
695  *************************************/
696 
697 static INPUT_PORTS_START( looping )
698 	PORT_START("P1")
699 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
700 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
701 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Shoot")
702 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
703 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 )
704 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 Accelerate?")
705 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
706 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
707 
708 	PORT_START("P2") // cocktail?
709 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_COCKTAIL
710 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL
711 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
712 	PORT_BIT( 0x18, IP_ACTIVE_LOW, IPT_UNUSED )
713 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL
714 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
715 
716 	PORT_START("DSW")
DEF_STR(Coin_B)717 	PORT_DIPNAME( 0x01, 0x01, DEF_STR( Coin_B ) )
718 	PORT_DIPSETTING(    0x00, DEF_STR( 2C_1C ) )
719 	PORT_DIPSETTING(    0x01, DEF_STR( 1C_1C ) )
720 	PORT_DIPNAME( 0x0e, 0x02, DEF_STR( Coin_A ) )
721 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_1C ) )
722 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_2C ) )
723 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_3C ) )
724 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_4C ) )
725 	PORT_DIPSETTING(    0x0a, DEF_STR( 1C_5C ) )
726 	PORT_DIPSETTING(    0x0c, DEF_STR( 1C_6C ) )
727 	PORT_DIPSETTING(    0x0e, DEF_STR( 1C_7C ) )
728 	PORT_DIPSETTING(    0x00, "1 Coin/10 Credits" )
729 	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )      // Check code at 0x2c00
730 	PORT_DIPSETTING(    0x00, DEF_STR( No ) )
731 	PORT_DIPSETTING(    0x10, DEF_STR( Yes ) )
732 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Lives ) )
733 	PORT_DIPSETTING(    0x00, "3" )
734 	PORT_DIPSETTING(    0x20, "5" )
735 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
736 	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Cabinet ) )
737 	PORT_DIPSETTING(    0x80, DEF_STR( Upright ) )
738 	PORT_DIPSETTING(    0x00, DEF_STR( Cocktail ) )
739 INPUT_PORTS_END
740 
741 // Same as 'looping' but additional "Infinite Lives" Dip Switch
742 static INPUT_PORTS_START( skybump )
743 	PORT_INCLUDE(looping)
744 
745 	PORT_MODIFY("DSW")
746 	PORT_DIPNAME( 0x60, 0x40, DEF_STR( Lives ) )
747 	PORT_DIPSETTING(    0x40, "3" )
748 	PORT_DIPSETTING(    0x60, "5" )
749 	PORT_DIPSETTING(    0x00, "Infinite (Cheat)")
750 //  PORT_DIPSETTING(    0x20, "Infinite (Cheat)")
751 INPUT_PORTS_END
752 
753 
754 
755 /*************************************
756  *
757  *  ROM definitions
758  *
759  *************************************/
760 
761 ROM_START( loopingv )
762 	ROM_REGION( 0x8000, "maincpu", 0 ) // TMS9995 code
763 	ROM_LOAD( "vli3.5a",        0x0000, 0x2000, CRC(1ac3ccdf) SHA1(9d1cde8bd4d0f12eaf06225b3ecc4a5c3e4f0c11) )
764 	ROM_LOAD( "vli1.2a",        0x2000, 0x2000, CRC(97755fd4) SHA1(4a6ef02b0128cd516ff95083a7caaad8f3756f09) )
765 	ROM_LOAD( "l056-6.9a",      0x4000, 0x2000, CRC(548afa52) SHA1(0b88ac7394feede023519c585a4084591eb9661a) )
766 	ROM_LOAD( "vli9-5.8a",      0x6000, 0x2000, CRC(5d122f86) SHA1(d1c66b890142bb4d4648f3edec6567f58107dbf0) )
767 
768 	ROM_REGION( 0x3800, "audiocpu", 0 ) // TMS9980 code
769 	ROM_LOAD( "i-o.13c",        0x0000, 0x0800, CRC(21e9350c) SHA1(f30a180309e373a17569351944f5e7982c3b3f9d) )
770 	ROM_LOAD( "i-o.13a",        0x0800, 0x1000, CRC(1de29f25) SHA1(535acb132266d6137b0610ee9a9b946459ae44af) )
771 	ROM_LOAD( "i-o.11a",        0x2800, 0x1000, CRC(61c74c79) SHA1(9f34d18a919446dd76857b851cea23fc1526f3c2) ) // speech
772 
773 	ROM_REGION( 0x1000, "mcu", 0 ) // COP420 microcontroller code
774 /*
775     ROM_LOAD( "cop.bin",    0x0000, 0x0400, BAD_DUMP CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times, and starting PC is not 0
776     ROM_CONTINUE(           0x0000, 0x0400)
777     ROM_CONTINUE(           0x0000, 0x0400)
778     ROM_CONTINUE(           0x0000, 0x0400)
779 */
780 	ROM_LOAD( "cop.bin",    0x00c2, 0x033e, CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times and shifted
781 	ROM_CONTINUE(           0x0000, 0x00c2)
782 	ROM_CONTINUE(           0x00c2, 0x033e)
783 	ROM_CONTINUE(           0x0000, 0x00c2)
784 	ROM_CONTINUE(           0x00c2, 0x033e)
785 	ROM_CONTINUE(           0x0000, 0x00c2)
786 	ROM_CONTINUE(           0x00c2, 0x033e)
787 	ROM_CONTINUE(           0x0000, 0x00c2)
788 
789 	ROM_REGION( 0x1000, "gfx1", 0 )
790 	ROM_LOAD( "log2.8a",        0x0000, 0x800, CRC(ef3284ac) SHA1(8719c9df8c972a56c306b3c707aaa53092ffa2d6) )
791 	ROM_LOAD( "log1-9-3.6a",    0x0800, 0x800, CRC(c434c14c) SHA1(3669aaf7adc6b250378bcf62eb8e7058f55476ef) )
792 
793 	ROM_REGION( 0x0020, "proms", 0 ) // color prom
794 	ROM_LOAD( "18s030.11b",     0x0000, 0x0020, CRC(6a0c7d87) SHA1(140335d85c67c75b65689d4e76d29863c209cf32) )
795 ROM_END
796 
797 ROM_START( loopingva )
798 	ROM_REGION( 0x8000, "maincpu", 0 ) // TMS9995 code
799 	ROM_LOAD( "vli3.5a",        0x0000, 0x2000, CRC(1ac3ccdf) SHA1(9d1cde8bd4d0f12eaf06225b3ecc4a5c3e4f0c11) )
800 	ROM_LOAD( "vli-4-3",        0x2000, 0x1000, CRC(f32cae2b) SHA1(2c6ef82af438e588b56fd58b95cf969c97bb9a66) )
801 	ROM_LOAD( "vli-8-4",        0x3000, 0x1000, CRC(611e1dbf) SHA1(0ab6669f1dec30c3f7bca49e158e4790a78fa308) )
802 	ROM_LOAD( "l056-6.9a",      0x4000, 0x2000, CRC(548afa52) SHA1(0b88ac7394feede023519c585a4084591eb9661a) )
803 	ROM_LOAD( "vli9-5.8a",      0x6000, 0x2000, CRC(5d122f86) SHA1(d1c66b890142bb4d4648f3edec6567f58107dbf0) )
804 
805 	ROM_REGION( 0x3800, "audiocpu", 0 ) // TMS9980 code
806 	ROM_LOAD( "i-o-v2.13c",     0x0000, 0x0800, CRC(09765ebe) SHA1(93b035c3a94f2f6d5e463256e26b600a4dd5d3ea) )
807 	ROM_LOAD( "i-o.13a",        0x0800, 0x1000, CRC(1de29f25) SHA1(535acb132266d6137b0610ee9a9b946459ae44af) ) // speech
808 	ROM_LOAD( "i-o.11a",        0x2800, 0x1000, CRC(61c74c79) SHA1(9f34d18a919446dd76857b851cea23fc1526f3c2) )
809 
810 	ROM_REGION( 0x1000, "mcu", 0 ) // COP420 microcontroller code
811 /*
812     ROM_LOAD( "cop.bin",    0x0000, 0x0400, BAD_DUMP CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times, and starting PC is not 0
813     ROM_CONTINUE(           0x0000, 0x0400)
814     ROM_CONTINUE(           0x0000, 0x0400)
815     ROM_CONTINUE(           0x0000, 0x0400)
816 */
817 	ROM_LOAD( "cop.bin",    0x00c2, 0x033e, CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times and shifted
818 	ROM_CONTINUE(           0x0000, 0x00c2)
819 	ROM_CONTINUE(           0x00c2, 0x033e)
820 	ROM_CONTINUE(           0x0000, 0x00c2)
821 	ROM_CONTINUE(           0x00c2, 0x033e)
822 	ROM_CONTINUE(           0x0000, 0x00c2)
823 	ROM_CONTINUE(           0x00c2, 0x033e)
824 	ROM_CONTINUE(           0x0000, 0x00c2)
825 
826 	ROM_REGION( 0x1000, "gfx1", 0 )
827 	ROM_LOAD( "log2.8a",        0x0000, 0x800, CRC(ef3284ac) SHA1(8719c9df8c972a56c306b3c707aaa53092ffa2d6) )
828 	ROM_LOAD( "log1-9-3.6a",    0x0800, 0x800, CRC(c434c14c) SHA1(3669aaf7adc6b250378bcf62eb8e7058f55476ef) )
829 
830 	ROM_REGION( 0x0020, "proms", 0 ) // color prom
831 	ROM_LOAD( "18s030.11b",     0x0000, 0x0020, CRC(6a0c7d87) SHA1(140335d85c67c75b65689d4e76d29863c209cf32) )
832 ROM_END
833 
834 ROM_START( looping )
835 	ROM_REGION( 0x8000, "maincpu", 0 ) // TMS9995 code
836 	ROM_LOAD( "loop551.bin",        0x0000, 0x1000, CRC(d6bb6db6) SHA1(074eb3bc101096bfe67c3107f306df829ae38548) )
837 	ROM_LOAD( "loop552.bin",        0x1000, 0x1000, CRC(bc32956d) SHA1(6ef8d76df1d5b1ed52a4057eae2bf4eb394e4c54) )
838 	ROM_LOAD( "loop553.bin",        0x2000, 0x1000, CRC(5f8b9aed) SHA1(32be61788e3d54b23d1663025365b1ab6b96dc91) )
839 	ROM_LOAD( "loop554b.bin",       0x3000, 0x1000, CRC(381a9625) SHA1(07d775125be1f761dad568f8ccce600414a9d15f) )
840 	ROM_LOAD( "loop555.bin",        0x4000, 0x1000, CRC(0ef4c922) SHA1(df6db0897a51aa10e106865a643588d866ef8c4e) )
841 	ROM_LOAD( "loop556.bin",        0x5000, 0x1000, CRC(3419a5d5) SHA1(2b0249c54985ab5e12de17c0e3d62caa0c7575e3) )
842 	ROM_LOAD( "loop557.bin",        0x6000, 0x1000, CRC(d430e287) SHA1(b0edd25ef4d2468cc1f8c10ac49c545a89d398d7) )
843 
844 	ROM_REGION( 0x3800, "audiocpu", 0 ) // TMS9980 code
845 	ROM_LOAD( "loopc13.bin",        0x0000, 0x1000, CRC(ff9ac4ec) SHA1(9f8df94cd79d86fe4c384df1d5d729b58a7ca7a8) )
846 	ROM_LOAD( "loopa13.bin",        0x0800, 0x1000, CRC(1de29f25) SHA1(535acb132266d6137b0610ee9a9b946459ae44af) )
847 	ROM_LOAD( "loopa11.bin",        0x2800, 0x1000, CRC(61c74c79) SHA1(9f34d18a919446dd76857b851cea23fc1526f3c2) ) // speech
848 
849 	ROM_REGION( 0x1000, "mcu", 0 ) // COP420 microcontroller code
850 	// taken from the other sets
851 	ROM_LOAD( "cop.bin",    0x00c2, 0x033e, CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times and shifted
852 	ROM_CONTINUE(           0x0000, 0x00c2)
853 	ROM_CONTINUE(           0x00c2, 0x033e)
854 	ROM_CONTINUE(           0x0000, 0x00c2)
855 	ROM_CONTINUE(           0x00c2, 0x033e)
856 	ROM_CONTINUE(           0x0000, 0x00c2)
857 	ROM_CONTINUE(           0x00c2, 0x033e)
858 	ROM_CONTINUE(           0x0000, 0x00c2)
859 
860 	ROM_REGION( 0x1000, "gfx1", 0 )
861 	ROM_LOAD( "loopaa8.bin",    0x0000, 0x800, CRC(ef3284ac) SHA1(8719c9df8c972a56c306b3c707aaa53092ffa2d6) )
862 	ROM_LOAD( "loopaa6.bin",    0x0800, 0x800, CRC(c434c14c) SHA1(3669aaf7adc6b250378bcf62eb8e7058f55476ef) )
863 
864 	ROM_REGION( 0x0020, "proms", 0 ) // color prom
865 	ROM_LOAD( "loopvp1.bin",        0x0000, 0x0020, CRC(6a0c7d87) SHA1(140335d85c67c75b65689d4e76d29863c209cf32) )
866 ROM_END
867 
868 ROM_START( skybump )
869 	ROM_REGION( 0x8000, "maincpu", 0 ) // TMS9995 code
870 	ROM_LOAD( "cpu.5a",         0x0000, 0x2000, CRC(dca38df0) SHA1(86abe04cbabf81399f842f53668fe7a3f7ed3757) )
871 	ROM_LOAD( "cpu.2a",         0x2000, 0x2000, CRC(6bcc211a) SHA1(245ebae3934df9c3920743a941546d96bb2e7c03) )
872 	ROM_LOAD( "cpu.9a",         0x4000, 0x2000, CRC(c7a50797) SHA1(60aa0a28ba970f12d0a0e538ae1c6807d105855c) )
873 	ROM_LOAD( "cpu.8a",         0x6000, 0x2000, CRC(a718c6f2) SHA1(19afa8c353829232cb96c27b87f13b43166ab6fc) )
874 
875 	ROM_REGION( 0x3800, "audiocpu", 0 ) // TMS9980 code
876 	ROM_LOAD( "snd.13c",        0x0000, 0x0800, CRC(21e9350c) SHA1(f30a180309e373a17569351944f5e7982c3b3f9d) )
877 	ROM_LOAD( "snd.13a",        0x0800, 0x1000, CRC(1de29f25) SHA1(535acb132266d6137b0610ee9a9b946459ae44af) )
878 	ROM_LOAD( "snd.11a",        0x2800, 0x1000, CRC(61c74c79) SHA1(9f34d18a919446dd76857b851cea23fc1526f3c2) )
879 
880 	ROM_REGION( 0x1000, "mcu", 0 ) // COP420 microcontroller code
881 /*
882     ROM_LOAD( "cop.bin",    0x0000, 0x0400, BAD_DUMP CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times, and starting PC is not 0
883     ROM_CONTINUE(           0x0000, 0x0400)
884     ROM_CONTINUE(           0x0000, 0x0400)
885     ROM_CONTINUE(           0x0000, 0x0400)
886 */
887 	ROM_LOAD( "cop.bin",    0x00c2, 0x033e, CRC(bbfd26d5) SHA1(5f78b32b6e7c003841ef5b635084db2cdfebf0e1) ) // overdumped 4 times and shifted
888 	ROM_CONTINUE(           0x0000, 0x00c2)
889 	ROM_CONTINUE(           0x00c2, 0x033e)
890 	ROM_CONTINUE(           0x0000, 0x00c2)
891 	ROM_CONTINUE(           0x00c2, 0x033e)
892 	ROM_CONTINUE(           0x0000, 0x00c2)
893 	ROM_CONTINUE(           0x00c2, 0x033e)
894 	ROM_CONTINUE(           0x0000, 0x00c2)
895 
896 	ROM_REGION( 0x1000, "gfx1", 0 )
897 	ROM_LOAD( "vid.8a",         0x0000, 0x800, CRC(459ccc55) SHA1(747f6789605b48be9e22f779f9e3f6c98ad4e594) )
898 	ROM_LOAD( "vid.6a",         0x0800, 0x800, CRC(12ebbe74) SHA1(0f87c81a45d1bf3b8c6a70ee5e1a014069f67755) )
899 
900 	ROM_REGION( 0x0020, "proms", 0 ) // color prom
901 	ROM_LOAD( "vid.clr",        0x0000, 0x0020, CRC(6a0c7d87) SHA1(140335d85c67c75b65689d4e76d29863c209cf32) )
902 ROM_END
903 
904 
905 
906 /*************************************
907  *
908  *  Driver config
909  *
910  *************************************/
911 
912 void looping_state::init_looping()
913 {
914 	int length = memregion("maincpu")->bytes();
915 	uint8_t *rom = memregion("maincpu")->base();
916 
917 	// bitswap the TMS9995 ROMs
918 	for (int i = 0; i < length; i++)
919 		rom[i] = bitswap<8>(rom[i], 0,1,2,3,4,5,6,7);
920 
921 	// install protection handlers
922 	m_maincpu->space(AS_PROGRAM).install_read_handler(0x7000, 0x7007, read8smo_delegate(*this, FUNC(looping_state::protection_r)));
923 }
924 
925 
926 
927 /*************************************
928  *
929  *  Game drivers
930  *
931  *************************************/
932 
933 GAME( 1982, looping,   0,        looping, looping, looping_state, init_looping, ROT90, "Video Games GmbH", "Looping", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
934 GAME( 1982, loopingv,  looping,  looping, looping, looping_state, init_looping, ROT90, "Video Games GmbH (Venture Line license)", "Looping (Venture Line license, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
935 GAME( 1982, loopingva, looping,  looping, looping, looping_state, init_looping, ROT90, "Video Games GmbH (Venture Line license)", "Looping (Venture Line license, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
936 GAME( 1982, skybump,   0,        looping, skybump, looping_state, init_looping, ROT90, "Venture Line", "Sky Bumper", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
937