1 // license:GPL-2.0+
2 // copyright-holders:Peter Trauner
3 /******************************************************************************
4 watara supervision handheld
5
6 PeT mess@utanet.at in december 2000
7 ******************************************************************************/
8
9 #include "emu.h"
10 #include "includes/svision.h"
11 #include "screen.h"
12 #include "softlist.h"
13 #include "speaker.h"
14
15 #include "svision.lh"
16
17
18 #define MAKE8_RGB32(red3, green3, blue2) ( ( (red3)<<(16+5)) | ( (green3)<<(8+5)) | ( (blue2)<<(0+6)) )
19 #define MAKE9_RGB32(red3, green3, blue3) ( ( (red3)<<(16+5)) | ( (green3)<<(8+5)) | ( (blue3)<<(0+5)) )
20 #define MAKE12_RGB32(red4, green4, blue4) ( ( (red4)<<(16+4)) | ((green4)<<(8+4)) | ((blue4)<<(0+4)) )
21 #define MAKE24_RGB32(red8, green8, blue8) ( (((red8)&0xf8)<<16) | (((green8)&0xf8)<<8) | (((blue8)&0xf8)) )
22
23
TIMER_CALLBACK_MEMBER(svision_state::svision_pet_timer)24 TIMER_CALLBACK_MEMBER(svision_state::svision_pet_timer)
25 {
26 switch (m_pet.state)
27 {
28 case 0x00:
29 if (m_joy2.found())
30 {
31 m_pet.input = m_joy2->read();
32 }
33 /* fall through */
34
35 case 0x02: case 0x04: case 0x06: case 0x08:
36 case 0x0a: case 0x0c: case 0x0e:
37 m_pet.clock = m_pet.state & 2;
38 m_pet.data = m_pet.input & 1;
39 m_pet.input >>= 1;
40 m_pet.state++;
41 break;
42
43 case 0x1f:
44 m_pet.state = 0;
45 break;
46
47 default:
48 m_pet.state++;
49 break;
50 }
51 }
52
TIMER_DEVICE_CALLBACK_MEMBER(svision_state::svision_pet_timer_dev)53 TIMER_DEVICE_CALLBACK_MEMBER(svision_state::svision_pet_timer_dev)
54 {
55 svision_pet_timer(ptr,param);
56 }
57
WRITE_LINE_MEMBER(svision_state::sound_irq_w)58 WRITE_LINE_MEMBER(svision_state::sound_irq_w)
59 {
60 m_dma_finished = true;
61 check_irq();
62 }
63
check_irq()64 void svision_state::check_irq()
65 {
66 bool irq = m_svision.timer_shot && BIT(m_reg[BANK], 1);
67 irq = irq || (m_dma_finished && BIT(m_reg[BANK], 2));
68
69 m_maincpu->set_input_line(M65C02_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE);
70 }
71
TIMER_CALLBACK_MEMBER(svision_state::svision_timer)72 TIMER_CALLBACK_MEMBER(svision_state::svision_timer)
73 {
74 m_svision.timer_shot = true;
75 m_svision.timer1->enable(false);
76 check_irq();
77 }
78
svision_r(offs_t offset)79 uint8_t svision_state::svision_r(offs_t offset)
80 {
81 int data = m_reg[offset];
82 switch (offset)
83 {
84 case 0x20:
85 return m_joy->read();
86
87 case 0x21:
88 data &= ~0xf;
89 data |= m_reg[0x22] & 0xf;
90 if (m_pet.on)
91 {
92 if (!m_pet.clock)
93 {
94 data &= ~4;
95 }
96 if (!m_pet.data)
97 {
98 data &= ~8;
99 }
100 }
101 break;
102
103 case 0x27:
104 data &= ~3;
105 if (m_svision.timer_shot)
106 {
107 data |= 1;
108 }
109 if (m_dma_finished)
110 {
111 data |= 2;
112 }
113 break;
114
115 case 0x24:
116 m_svision.timer_shot = false;
117 check_irq();
118 break;
119
120 case 0x25:
121 m_dma_finished = false;
122 check_irq();
123 break;
124
125 default:
126 logerror("%.6f svision read %04x %02x\n", machine().time().as_double(),offset,data);
127 break;
128 }
129
130 return data;
131 }
132
svision_w(offs_t offset,uint8_t data)133 void svision_state::svision_w(offs_t offset, uint8_t data)
134 {
135 m_reg[offset] = data;
136
137 switch (offset)
138 {
139 case 0x02:
140 case 0x03:
141 break;
142
143 case 0x26: /* bits 5,6 memory management for a000? */
144 {
145 logerror("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
146 int bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
147 m_bank1->set_base(m_cart_rom->base() + (bank * 0x4000));
148 check_irq();
149 break;
150 }
151
152 case 0x23: /* delta hero irq routine write */
153 {
154 int delay = (data == 0) ? 0x100 : data;
155 delay *= (BIT(m_reg[BANK], 4)) ? 0x4000 : 0x100;
156 m_svision.timer1->enable(true);
157 m_svision.timer1->reset(m_maincpu->cycles_to_attotime(delay));
158 break;
159 }
160
161 case 0x10: case 0x11: case 0x12: case 0x13:
162 m_sound->soundport_w(0, offset & 3, data);
163 break;
164
165 case 0x14: case 0x15: case 0x16: case 0x17:
166 m_sound->soundport_w(1, offset & 3, data);
167 break;
168
169 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c:
170 m_sound->sounddma_w(offset - 0x18, data);
171 break;
172
173 case 0x28: case 0x29: case 0x2a:
174 m_sound->noise_w(offset - 0x28, data);
175 break;
176
177 default:
178 logerror("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
179 break;
180 }
181 }
182
tvlink_r(offs_t offset)183 uint8_t svision_state::tvlink_r(offs_t offset)
184 {
185 switch(offset)
186 {
187 default:
188 if (offset >= 0x800 && offset < 0x840)
189 {
190 /* strange effects when modifying palette */
191 return svision_r(offset);
192 }
193 else
194 {
195 return svision_r(offset);
196 }
197 }
198 }
199
tvlink_w(offs_t offset,uint8_t data)200 void svision_state::tvlink_w(offs_t offset, uint8_t data)
201 {
202 switch (offset)
203 {
204 case 0x0e:
205 m_reg[offset] = data;
206 m_tvlink.palette_on = data & 1;
207 if (m_tvlink.palette_on)
208 {
209 // hack, normally initialising with palette from ram
210 m_tvlink.palette[0] = MAKE12_RGB32(163/16,172/16,115/16); // these are the tron colors messured from screenshot
211 m_tvlink.palette[1] = MAKE12_RGB32(163/16,155/16,153/16);
212 m_tvlink.palette[2] = MAKE12_RGB32(77/16,125/16,73/16);
213 m_tvlink.palette[3] = MAKE12_RGB32(59/16,24/16,20/16);
214 }
215 else
216 {
217 // cleaner to use colors from compile time palette, or compose from "fixed" palette values
218 m_tvlink.palette[0]=MAKE12_RGB32(0,0,0);
219 m_tvlink.palette[1]=MAKE12_RGB32(5*16/256,18*16/256,9*16/256);
220 m_tvlink.palette[2]=MAKE12_RGB32(48*16/256,76*16/256,100*16/256);
221 m_tvlink.palette[3]=MAKE12_RGB32(190*16/256,190*16/256,190*16/256);
222 }
223 break;
224 default:
225 svision_w(offset,data);
226 if (offset >= 0x800 && offset < 0x840)
227 {
228 if (offset == 0x803 && data == 0x07)
229 {
230 /* tron hack */
231 m_reg[0x0804] = 0x00;
232 m_reg[0x0805] = 0x01;
233 m_reg[0x0806] = 0x00;
234 m_reg[0x0807] = 0x00;
235 }
236 uint16_t c = m_reg[0x800] | (m_reg[0x804] << 8);
237 m_tvlink.palette[0] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
238 c = m_reg[0x801] | (m_reg[0x805] << 8);
239 m_tvlink.palette[1] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
240 c = m_reg[0x802] | (m_reg[0x806]<<8);
241 m_tvlink.palette[2]=MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
242 c = m_reg[0x803] | (m_reg[0x807]<<8);
243 m_tvlink.palette[3]=MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
244 /* writes to palette effect video color immediately */
245 /* some writes modify other registers, */
246 /* encoding therefor not known (rgb8 or rgb9) */
247 }
248 }
249 }
250
svision_mem(address_map & map)251 void svision_state::svision_mem(address_map &map)
252 {
253 map(0x0000, 0x1fff).ram();
254 map(0x2000, 0x3fff).rw(FUNC(svision_state::svision_r), FUNC(svision_state::svision_w)).share(m_reg);
255 map(0x4000, 0x5fff).ram().share(m_videoram);
256 map(0x6000, 0x7fff).noprw();
257 map(0x8000, 0xbfff).bankr(m_bank1);
258 map(0xc000, 0xffff).bankr(m_bank2);
259 }
260
tvlink_mem(address_map & map)261 void svision_state::tvlink_mem(address_map &map)
262 {
263 map(0x0000, 0x1fff).ram();
264 map(0x2000, 0x3fff).rw(FUNC(svision_state::tvlink_r), FUNC(svision_state::tvlink_w)).share(m_reg);
265 map(0x4000, 0x5fff).ram().share(m_videoram);
266 map(0x6000, 0x7fff).noprw();
267 map(0x8000, 0xbfff).bankr(m_bank1);
268 map(0xc000, 0xffff).bankr(m_bank2);
269 }
270
271 static INPUT_PORTS_START( svision )
272 PORT_START("JOY")
273 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT)
274 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
275 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
276 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
277 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("B")
278 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("A")
279 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select")
280 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start/Pause")
281 INPUT_PORTS_END
282
283 static INPUT_PORTS_START( svisions )
284 PORT_START("JOY")
285 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1)
286 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
287 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
288 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
289 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("B") PORT_PLAYER(1)
290 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("A") PORT_PLAYER(1)
291 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select") PORT_PLAYER(1)
292 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START) PORT_NAME("Start/Pause") PORT_PLAYER(1)
293 PORT_START("JOY2")
294 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(2)
295 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
296 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
297 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
298 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("2nd B") PORT_PLAYER(2)
299 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("2nd A") PORT_PLAYER(2)
300 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("2nd Select") PORT_PLAYER(2)
301 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START) PORT_NAME("2nd Start/Pause") PORT_PLAYER(2)
302 INPUT_PORTS_END
303
304 // most games contain their graphics in roms, and have hardware to draw complete rectangular objects
305
306 // palette in red, green, blue triples
307 static constexpr rgb_t svision_pens[] =
308 {
309 #if 0
310 // greens grabbed from a scan of a handheld in its best adjustment for contrast
311 { 86, 121, 86 },
312 { 81, 115, 90 },
313 { 74, 107, 101 },
314 { 54, 78, 85 }
315 #else
316 // grabbed from chris covell's black white pics
317 { 0xe0, 0xe0, 0xe0 },
318 { 0xb9, 0xb9, 0xb9 },
319 { 0x54, 0x54, 0x54 },
320 { 0x12, 0x12, 0x12 }
321 #endif
322 };
323
324 // palette in RGB triplets
325 static constexpr rgb_t svisionp_pens[] =
326 {
327 // pal
328 { 1, 1, 3 },
329 { 5, 18, 9 },
330 { 48, 76, 100 },
331 { 190, 190, 190 }
332 };
333
334 // palette in RGB triplets
335 static constexpr rgb_t svisionn_pens[] =
336 {
337 { 0, 0, 0 },
338 { 188, 242, 244 }, // darker
339 { 129, 204, 255 },
340 { 245, 249, 248 }
341 };
342
svision_palette(palette_device & palette) const343 void svision_state::svision_palette(palette_device &palette) const
344 {
345 palette.set_pen_colors(0, svision_pens);
346 }
svisionn_palette(palette_device & palette) const347 void svision_state::svisionn_palette(palette_device &palette) const
348 {
349 palette.set_pen_colors(0, svisionn_pens);
350 }
svisionp_palette(palette_device & palette) const351 void svision_state::svisionp_palette(palette_device &palette) const
352 {
353 palette.set_pen_colors(0, svisionp_pens);
354 }
355
screen_update_svision(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)356 uint32_t svision_state::screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
357 {
358 if (BIT(m_reg[BANK], 3))
359 {
360 int j = m_reg[XPOS] / 4 + m_reg[YPOS] * 0x30;
361 for (int y = 0; y < 160; y++)
362 {
363 const int start_x = 3 - (m_reg[XPOS] & 3);
364 const int end_x = std::min(163, m_reg[XSIZE] | 3);
365 uint16_t *line = &bitmap.pix(y, start_x);
366 for (int x = start_x, i = 0; x < end_x; x+=4, i++)
367 {
368 uint8_t b = m_videoram[j+i];
369 for (int pix = 0; pix < 4; pix++)
370 {
371 *line = b & 3;
372 b >>= 2;
373 line++;
374 }
375 }
376 j += 0x30;
377 if (j >= 0x1fe0)
378 j = 0; //sssnake
379 }
380 }
381 else
382 {
383 bitmap.plot_box(3, 0, 162, 159, 0);
384 }
385 return 0;
386 }
387
screen_update_tvlink(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)388 uint32_t svision_state::screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
389 {
390 if (BIT(m_reg[BANK], 3))
391 {
392 int j = m_reg[XPOS] / 4 + m_reg[YPOS] * 0x30;
393 for (int y = 0; y < 160; y++)
394 {
395 const int start_x = 3 - (m_reg[XPOS] & 3);
396 const int end_x = std::min(163, m_reg[XSIZE] | 3);
397 uint32_t *line = &bitmap.pix(y, start_x);
398 for (int x = start_x, i = 0; x < end_x; x += 4, i++)
399 {
400 uint8_t b = m_videoram[j + i];
401 for (int pix = 0; pix < 4; pix++)
402 {
403 *line = m_tvlink.palette[b & 3];
404 b >>= 2;
405 line++;
406 }
407 }
408 j += 0x30;
409 if (j >= 0x1fe0)
410 j = 0; //sssnake
411 }
412 }
413 else
414 {
415 bitmap.plot_box(3, 0, 162, 159, m_palette->pen(0));
416 }
417 return 0;
418 }
419
WRITE_LINE_MEMBER(svision_state::frame_int_w)420 WRITE_LINE_MEMBER(svision_state::frame_int_w)
421 {
422 if (!state)
423 return;
424
425 if (BIT(m_reg[BANK], 0))
426 m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
427
428 m_sound->sound_decrement();
429 }
430
init_svision()431 void svision_state::init_svision()
432 {
433 m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this));
434 m_dma_finished = false;
435 m_pet.on = false;
436 }
437
init_svisions()438 void svision_state::init_svisions()
439 {
440 m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this));
441 m_dma_finished = false;
442 m_pet.on = true;
443 m_pet.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_pet_timer),this));
444 }
445
DEVICE_IMAGE_LOAD_MEMBER(svision_state::cart_load)446 DEVICE_IMAGE_LOAD_MEMBER( svision_state::cart_load )
447 {
448 uint32_t size = m_cart->common_get_size("rom");
449
450 if (size > 0x80000)
451 {
452 image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
453 return image_init_result::FAIL;
454 }
455
456 m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
457 m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom");
458
459 return image_init_result::PASS;
460 }
461
machine_start()462 void svision_state::machine_start()
463 {
464 std::string region_tag(m_cart->tag());
465 region_tag.append(GENERIC_ROM_REGION_TAG);
466 m_cart_rom = memregion(region_tag.c_str());
467
468 if (m_cart_rom)
469 {
470 int num_banks = m_cart_rom->bytes() / 0x4000;
471 m_bank1->set_base(m_cart_rom->base());
472 m_bank2->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000); // bank2 is set to the last bank
473 }
474 }
475
machine_reset()476 void svision_state::machine_reset()
477 {
478 m_svision.timer_shot = false;
479 m_dma_finished = false;
480 }
481
482
MACHINE_RESET_MEMBER(svision_state,tvlink)483 MACHINE_RESET_MEMBER(svision_state,tvlink)
484 {
485 svision_state::machine_reset();
486 m_tvlink.palette_on = false;
487
488 memset(m_reg + 0x800, 0xff, 0x40); // normally done from m_tvlink microcontroller
489 m_reg[0x82a] = 0xdf;
490
491 m_tvlink.palette[0] = MAKE24_RGB32(svisionp_pens[0].r(), svisionp_pens[0].g(), svisionp_pens[0].b());
492 m_tvlink.palette[1] = MAKE24_RGB32(svisionp_pens[1].r(), svisionp_pens[1].g(), svisionp_pens[1].b());
493 m_tvlink.palette[2] = MAKE24_RGB32(svisionp_pens[2].r(), svisionp_pens[2].g(), svisionp_pens[2].b());
494 m_tvlink.palette[3] = MAKE24_RGB32(svisionp_pens[3].r(), svisionp_pens[3].g(), svisionp_pens[3].b());
495 }
496
svision_base(machine_config & config)497 void svision_state::svision_base(machine_config &config)
498 {
499 config.set_default_layout(layout_svision);
500
501 SPEAKER(config, "lspeaker").front_left();
502 SPEAKER(config, "rspeaker").front_right();
503 SVISION_SND(config, m_sound, 4000000, m_maincpu, m_bank1);
504 m_sound->add_route(0, "lspeaker", 0.50);
505 m_sound->add_route(1, "rspeaker", 0.50);
506 m_sound->irq_cb().set(FUNC(svision_state::sound_irq_w));
507
508 GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "svision_cart", "bin,ws,sv");
509 m_cart->set_must_be_loaded(true);
510 m_cart->set_device_load(FUNC(svision_state::cart_load));
511
512 SOFTWARE_LIST(config, "cart_list").set_original("svision");
513 }
514
svision(machine_config & config)515 void svision_state::svision(machine_config &config)
516 {
517 svision_base(config);
518
519 M65C02(config, m_maincpu, 4000000);
520 m_maincpu->set_addrmap(AS_PROGRAM, &svision_state::svision_mem);
521
522 SCREEN(config, m_screen, SCREEN_TYPE_LCD);
523 m_screen->set_refresh_hz(61);
524 m_screen->set_size(3+160+3, 160);
525 m_screen->set_visarea(3+0, 3+160-1, 0, 160-1);
526 m_screen->set_screen_update(FUNC(svision_state::screen_update_svision));
527 m_screen->set_palette(m_palette);
528 m_screen->screen_vblank().set(FUNC(svision_state::frame_int_w));
529
530 PALETTE(config, m_palette, FUNC(svision_state::svision_palette), ARRAY_LENGTH(svision_pens));
531 }
532
svisions(machine_config & config)533 void svision_state::svisions(machine_config &config)
534 {
535 svision(config);
536 TIMER(config, "pet_timer").configure_periodic(FUNC(svision_state::svision_pet_timer_dev), attotime::from_seconds(8));
537 }
538
svisionp(machine_config & config)539 void svision_state::svisionp(machine_config &config)
540 {
541 svision(config);
542
543 m_maincpu->set_clock(4430000);
544 m_screen->set_refresh(HZ_TO_ATTOSECONDS(50));
545 m_palette->set_init(FUNC(svision_state::svisionp_palette));
546 }
547
svisionn(machine_config & config)548 void svision_state::svisionn(machine_config &config)
549 {
550 svision(config);
551 m_maincpu->set_clock(3560000/*?*/);
552 m_screen->set_refresh(HZ_TO_ATTOSECONDS(60));
553 m_palette->set_init(FUNC(svision_state::svisionn_palette));
554 }
555
tvlinkp(machine_config & config)556 void svision_state::tvlinkp(machine_config &config)
557 {
558 svisionp(config);
559 m_maincpu->set_addrmap(AS_PROGRAM, &svision_state::tvlink_mem);
560
561 m_screen->set_no_palette();
562 m_screen->set_screen_update(FUNC(svision_state::screen_update_tvlink));
563
564 MCFG_MACHINE_RESET_OVERRIDE(svision_state, tvlink)
565 }
566
567 ROM_START(svision)
568 ROM_REGION(0x80000, "maincpu", ROMREGION_ERASE00)
569 ROM_END
570
571 /***************************************************************************
572
573 Game driver(s)
574
575 ***************************************************************************/
576
577 #define rom_svisions rom_svision
578 #define rom_svisionn rom_svision
579 #define rom_svisionp rom_svision
580 #define rom_tvlinkp rom_svision
581
582 // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
583 // marketed under a ton of firms and names
584 CONS(1992, svision, 0, 0, svision, svision, svision_state, init_svision, "Watara", "Super Vision", 0 )
585 // svdual 2 connected via communication port
586 CONS( 1992, svisions, svision, 0, svisions, svisions, svision_state, init_svisions, "Watara", "Super Vision (PeT Communication Simulation)", 0 )
587
588 CONS( 1993, svisionp, svision, 0, svisionp, svision, svision_state, init_svision, "Watara", "Super Vision (PAL TV Link Colored)", 0 )
589 CONS( 1993, svisionn, svision, 0, svisionn, svision, svision_state, init_svision, "Watara", "Super Vision (NTSC TV Link Colored)", 0 )
590 // svtvlink (2 supervisions)
591 // tvlink (pad supervision simulated)
592 CONS( 199?, tvlinkp, svision, 0, tvlinkp, svision, svision_state, init_svision, "Watara", "TV Link PAL", 0 )
593