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