1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /*************************************************************************
4 
5     ldplayer.c
6 
7     Laserdisc player driver.
8 
9 **************************************************************************/
10 
11 #include "emu.h"
12 
13 #include "cpu/mcs48/mcs48.h"
14 #include "machine/ldpr8210.h"
15 #include "machine/ldv1000.h"
16 
17 #include "ui/uimain.h"
18 
19 #include "emuopts.h"
20 #include "romload.h"
21 #include "speaker.h"
22 #include "screen.h"
23 
24 #include "chd.h"
25 
26 #include "pr8210.lh"
27 
28 #include <cctype>
29 
30 
31 class ldplayer_state : public driver_device
32 {
33 public:
34 	// construction/destruction
ldplayer_state(const machine_config & mconfig,device_type type,const char * tag)35 	ldplayer_state(const machine_config &mconfig, device_type type, const char *tag)
36 		: driver_device(mconfig, type, tag)
37 		, m_screen(*this, "screen")
38 		, m_last_controls(0)
39 		, m_playing(false) { }
40 
41 	void ldplayer_ntsc(machine_config &config);
42 
43 protected:
44 	// device overrides
45 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
46 	virtual void machine_start() override;
47 	virtual void machine_reset() override;
48 
49 	// callback hook
50 	chd_file *get_disc();
51 
52 	// internal helpers
53 	void process_commands();
54 
55 	// derived classes
execute_command(int command)56 	virtual void execute_command(int command) { assert(false); }
57 
58 	// timer IDs
59 	enum
60 	{
61 		TIMER_ID_AUTOPLAY,
62 		TIMER_ID_VSYNC_UPDATE
63 	};
64 
65 	// commands
66 	enum
67 	{
68 		CMD_SCAN_REVERSE,
69 		CMD_STEP_REVERSE,
70 		CMD_SLOW_REVERSE,
71 		CMD_FAST_REVERSE,
72 		CMD_SCAN_FORWARD,
73 		CMD_STEP_FORWARD,
74 		CMD_SLOW_FORWARD,
75 		CMD_FAST_FORWARD,
76 		CMD_PLAY,
77 		CMD_PAUSE,
78 		CMD_FRAME_TOGGLE,
79 		CMD_CHAPTER_TOGGLE,
80 		CMD_CH1_TOGGLE,
81 		CMD_CH2_TOGGLE,
82 		CMD_0,
83 		CMD_1,
84 		CMD_2,
85 		CMD_3,
86 		CMD_4,
87 		CMD_5,
88 		CMD_6,
89 		CMD_7,
90 		CMD_8,
91 		CMD_9,
92 		CMD_SEARCH
93 	};
94 
95 	// internal state
96 	required_device<screen_device> m_screen;
97 	std::string m_filename;
98 	ioport_value m_last_controls;
99 	bool m_playing;
100 };
101 
102 
103 class pr8210_state : public ldplayer_state
104 {
105 public:
106 	// construction/destruction
pr8210_state(const machine_config & mconfig,device_type type,const char * tag)107 	pr8210_state(const machine_config &mconfig, device_type type, const char *tag)
108 		: ldplayer_state(mconfig, type, tag),
109 			m_laserdisc(*this, "laserdisc"),
110 			m_command_buffer_in(0),
111 			m_command_buffer_out(0) { }
112 
113 			void pr8210(machine_config &config);
114 protected:
115 	// device overrides
116 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
117 	virtual void machine_start() override;
118 	virtual void machine_reset() override;
119 
120 	// command execution hook
121 	virtual void execute_command(int command) override;
122 
123 	// internal helpers
124 	inline void add_command(uint8_t command);
125 
126 	// timer IDs
127 	enum
128 	{
129 		TIMER_ID_BIT = 100,
130 		TIMER_ID_BIT_OFF
131 	};
132 
133 	required_device<pioneer_pr8210_device> m_laserdisc;
134 
135 	// internal state
136 	emu_timer *m_bit_timer;
137 	uint32_t m_command_buffer_in;
138 	uint32_t m_command_buffer_out;
139 	uint8_t m_command_buffer[10];
140 };
141 
142 
143 class ldv1000_state : public ldplayer_state
144 {
145 public:
146 	// construction/destruction
ldv1000_state(const machine_config & mconfig,device_type type,const char * tag)147 	ldv1000_state(const machine_config &mconfig, device_type type, const char *tag)
148 		: ldplayer_state(mconfig, type, tag),
149 			m_laserdisc(*this, "laserdisc") { }
150 
151 			void ldv1000(machine_config &config);
152 protected:
153 	required_device<pioneer_ldv1000_device> m_laserdisc;
154 
155 	// command execution hook
156 	virtual void execute_command(int command) override;
157 };
158 
159 
160 
161 /*************************************
162  *
163  *  Disc location
164  *
165  *************************************/
166 
get_disc()167 chd_file *ldplayer_state::get_disc()
168 {
169 	bool found = false;
170 	// open a path to the ROMs and find the first CHD file
171 	file_enumerator path(machine().options().media_path());
172 
173 	// iterate while we get new objects
174 	const osd::directory::entry *dir;
175 	while ((dir = path.next()) != NULL)
176 	{
177 		int length = strlen(dir->name);
178 
179 		// look for files ending in .chd
180 		if (length > 4 &&
181 			dir->name[length - 4] == '.' &&
182 			tolower(dir->name[length - 3]) == 'c' &&
183 			tolower(dir->name[length - 2]) == 'h' &&
184 			tolower(dir->name[length - 1]) == 'd')
185 		{
186 			// open the file itself via our search path
187 			emu_file image_file(machine().options().media_path(), OPEN_FLAG_READ);
188 			osd_file::error filerr = image_file.open(dir->name);
189 			if (filerr == osd_file::error::NONE)
190 			{
191 				std::string fullpath(image_file.fullpath());
192 				image_file.close();
193 
194 				// try to open the CHD
195 
196 				if (machine().rom_load().set_disk_handle("laserdisc", fullpath.c_str()) == CHDERR_NONE)
197 				{
198 					m_filename.assign(dir->name);
199 					found = true;
200 					break;
201 				}
202 			}
203 		}
204 	}
205 
206 	// if we failed, pop a message and exit
207 	if (found == false) {
208 		machine().ui().popup_time(10, "No valid image file found!\n");
209 		return nullptr;
210 	}
211 
212 	return machine().rom_load().get_disk_handle("laserdisc");
213 }
214 
215 
216 
217 /*************************************
218  *
219  *  Timers and sync
220  *
221  *************************************/
222 
process_commands()223 void ldplayer_state::process_commands()
224 {
225 	ioport_value controls = ioport("controls")->read();
226 	int number;
227 
228 	// step backwards
229 	if (!(m_last_controls & 0x01) && (controls & 0x01))
230 		execute_command(CMD_STEP_REVERSE);
231 
232 	// step forwards
233 	if (!(m_last_controls & 0x02) && (controls & 0x02))
234 		execute_command(CMD_STEP_FORWARD);
235 
236 	// scan backwards
237 	if (controls & 0x04)
238 		execute_command(CMD_SCAN_REVERSE);
239 
240 	// scan forwards
241 	if (controls & 0x08)
242 		execute_command(CMD_SCAN_FORWARD);
243 
244 	// slow backwards
245 	if (!(m_last_controls & 0x10) && (controls & 0x10))
246 		execute_command(CMD_SLOW_REVERSE);
247 
248 	// slow forwards
249 	if (!(m_last_controls & 0x20) && (controls & 0x20))
250 		execute_command(CMD_SLOW_FORWARD);
251 
252 	// fast backwards
253 	if (controls & 0x40)
254 		execute_command(CMD_FAST_REVERSE);
255 
256 	// fast forwards
257 	if (controls & 0x80)
258 		execute_command(CMD_FAST_FORWARD);
259 
260 	// play/pause
261 	if (!(m_last_controls & 0x100) && (controls & 0x100))
262 	{
263 		m_playing = !m_playing;
264 		execute_command(m_playing ? CMD_PLAY : CMD_PAUSE);
265 	}
266 
267 	// toggle frame display
268 	if (!(m_last_controls & 0x200) && (controls & 0x200))
269 		execute_command(CMD_FRAME_TOGGLE);
270 
271 	// toggle chapter display
272 	if (!(m_last_controls & 0x400) && (controls & 0x400))
273 		execute_command(CMD_CHAPTER_TOGGLE);
274 
275 	// toggle left channel
276 	if (!(m_last_controls & 0x800) && (controls & 0x800))
277 		execute_command(CMD_CH1_TOGGLE);
278 
279 	// toggle right channel
280 	if (!(m_last_controls & 0x1000) && (controls & 0x1000))
281 		execute_command(CMD_CH2_TOGGLE);
282 
283 	// numbers
284 	for (number = 0; number < 10; number++)
285 		if (!(m_last_controls & (0x10000 << number)) && (controls & (0x10000 << number)))
286 			execute_command(CMD_0 + number);
287 
288 	// enter
289 	if (!(m_last_controls & 0x4000000) && (controls & 0x4000000))
290 		execute_command(CMD_SEARCH);
291 
292 	m_last_controls = controls;
293 }
294 
295 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)296 void ldplayer_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
297 {
298 	switch (id)
299 	{
300 		case TIMER_ID_VSYNC_UPDATE:
301 		{
302 			// handle commands
303 			if (param == 0)
304 				process_commands();
305 
306 			// set a timer to go off on the next VBLANK
307 			int vblank_scanline = m_screen->visible_area().max_y + 1;
308 			attotime target = m_screen->time_until_pos(vblank_scanline);
309 			timer_set(target, TIMER_ID_VSYNC_UPDATE);
310 			break;
311 		}
312 
313 		case TIMER_ID_AUTOPLAY:
314 			// start playing
315 			execute_command(CMD_PLAY);
316 			m_playing = true;
317 			break;
318 	}
319 }
320 
321 
machine_start()322 void ldplayer_state::machine_start()
323 {
324 	// start the vsync timer going
325 	timer_set(attotime::zero, TIMER_ID_VSYNC_UPDATE, 1);
326 }
327 
328 
machine_reset()329 void ldplayer_state::machine_reset()
330 {
331 	// set up a timer to start playing immediately
332 	timer_set(attotime::zero, TIMER_ID_AUTOPLAY);
333 
334 	// indicate the name of the file we opened
335 	popmessage("Opened %s\n", m_filename);
336 }
337 
338 
339 
340 /*************************************
341  *
342  *  PR-8210 implementation
343  *
344  *************************************/
345 
add_command(uint8_t command)346 void pr8210_state::add_command(uint8_t command)
347 {
348 	m_command_buffer[m_command_buffer_in++ % ARRAY_LENGTH(m_command_buffer)] = (command & 0x1f) | 0x20;
349 	m_command_buffer[m_command_buffer_in++ % ARRAY_LENGTH(m_command_buffer)] = 0x00 | 0x20;
350 }
351 
352 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)353 void pr8210_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
354 {
355 	switch (id)
356 	{
357 		case TIMER_ID_BIT:
358 		{
359 			attotime duration = attotime::from_msec(30);
360 			uint8_t bitsleft = param >> 16;
361 			uint8_t data = param;
362 
363 			// if we have bits, process
364 			if (bitsleft != 0)
365 			{
366 				// assert the line and set a timer for deassertion
367 				m_laserdisc->control_w(ASSERT_LINE);
368 				timer_set(attotime::from_usec(250), TIMER_ID_BIT_OFF);
369 
370 				// space 0 bits apart by 1msec, and 1 bits by 2msec
371 				duration = attotime::from_msec((data & 0x80) ? 2 : 1);
372 				data <<= 1;
373 				bitsleft--;
374 			}
375 
376 			// if we're out of bits, queue up the next command
377 			else if (bitsleft == 0 && m_command_buffer_in != m_command_buffer_out)
378 			{
379 				data = m_command_buffer[m_command_buffer_out++ % ARRAY_LENGTH(m_command_buffer)];
380 				bitsleft = 12;
381 			}
382 			m_bit_timer->adjust(duration, (bitsleft << 16) | data);
383 			break;
384 		}
385 
386 		// deassert the control line
387 		case TIMER_ID_BIT_OFF:
388 			m_laserdisc->control_w(CLEAR_LINE);
389 			break;
390 
391 		// others to the parent class
392 		default:
393 			ldplayer_state::device_timer(timer, id, param, ptr);
394 			break;
395 	}
396 }
397 
machine_start()398 void pr8210_state::machine_start()
399 {
400 	ldplayer_state::machine_start();
401 	m_bit_timer = timer_alloc(TIMER_ID_BIT);
402 }
403 
machine_reset()404 void pr8210_state::machine_reset()
405 {
406 	ldplayer_state::machine_reset();
407 	m_bit_timer->adjust(attotime::zero);
408 }
409 
410 
execute_command(int command)411 void pr8210_state::execute_command(int command)
412 {
413 	static const uint8_t digits[10] = { 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, 0x03, 0x13 };
414 
415 	switch (command)
416 	{
417 		case CMD_SCAN_REVERSE:
418 			if (m_command_buffer_in == m_command_buffer_out ||
419 				m_command_buffer_in == (m_command_buffer_out + 1) % ARRAY_LENGTH(m_command_buffer))
420 			{
421 				add_command(0x1c);
422 				m_playing = true;
423 			}
424 			break;
425 
426 		case CMD_STEP_REVERSE:
427 			add_command(0x12);
428 			m_playing = false;
429 			break;
430 
431 		case CMD_SLOW_REVERSE:
432 			add_command(0x02);
433 			m_playing = true;
434 			break;
435 
436 		case CMD_FAST_REVERSE:
437 			if (m_command_buffer_in == m_command_buffer_out ||
438 				m_command_buffer_in == (m_command_buffer_out + 1) % ARRAY_LENGTH(m_command_buffer))
439 			{
440 				add_command(0x0c);
441 				m_playing = true;
442 			}
443 			break;
444 
445 		case CMD_SCAN_FORWARD:
446 			if (m_command_buffer_in == m_command_buffer_out ||
447 				m_command_buffer_in == (m_command_buffer_out + 1) % ARRAY_LENGTH(m_command_buffer))
448 			{
449 				add_command(0x08);
450 				m_playing = true;
451 			}
452 			break;
453 
454 		case CMD_STEP_FORWARD:
455 			add_command(0x04);
456 			m_playing = false;
457 			break;
458 
459 		case CMD_SLOW_FORWARD:
460 			add_command(0x18);
461 			m_playing = true;
462 			break;
463 
464 		case CMD_FAST_FORWARD:
465 			if (m_command_buffer_in == m_command_buffer_out ||
466 				m_command_buffer_in == (m_command_buffer_out + 1) % ARRAY_LENGTH(m_command_buffer))
467 			{
468 				add_command(0x10);
469 				m_playing = true;
470 			}
471 			break;
472 
473 		case CMD_PLAY:
474 			add_command(0x14);
475 			m_playing = true;
476 			break;
477 
478 		case CMD_PAUSE:
479 			add_command(0x0a);
480 			m_playing = false;
481 			break;
482 
483 		case CMD_FRAME_TOGGLE:
484 			add_command(0x0b);
485 			break;
486 
487 		case CMD_CHAPTER_TOGGLE:
488 			add_command(0x06);
489 			break;
490 
491 		case CMD_CH1_TOGGLE:
492 			add_command(0x0e);
493 			break;
494 
495 		case CMD_CH2_TOGGLE:
496 			add_command(0x16);
497 			break;
498 
499 		case CMD_0:
500 		case CMD_1:
501 		case CMD_2:
502 		case CMD_3:
503 		case CMD_4:
504 		case CMD_5:
505 		case CMD_6:
506 		case CMD_7:
507 		case CMD_8:
508 		case CMD_9:
509 			add_command(digits[command - CMD_0]);
510 			break;
511 
512 		case CMD_SEARCH:
513 			add_command(0x1a);
514 			m_playing = false;
515 			break;
516 	}
517 }
518 
519 
520 
521 /*************************************
522  *
523  *  LD-V1000 implementation
524  *
525  *************************************/
526 
execute_command(int command)527 void ldv1000_state::execute_command(int command)
528 {
529 	static const uint8_t digits[10] = { 0x3f, 0x0f, 0x8f, 0x4f, 0x2f, 0xaf, 0x6f, 0x1f, 0x9f, 0x5f };
530 	switch (command)
531 	{
532 		case CMD_SCAN_REVERSE:
533 			m_laserdisc->data_w(0xf8);
534 			m_playing = true;
535 			break;
536 
537 		case CMD_STEP_REVERSE:
538 			m_laserdisc->data_w(0xfe);
539 			m_playing = false;
540 			break;
541 
542 		case CMD_SCAN_FORWARD:
543 			m_laserdisc->data_w(0xf0);
544 			m_playing = true;
545 			break;
546 
547 		case CMD_STEP_FORWARD:
548 			m_laserdisc->data_w(0xf6);
549 			m_playing = false;
550 			break;
551 
552 		case CMD_PLAY:
553 			m_laserdisc->data_w(0xfd);
554 			m_playing = true;
555 			break;
556 
557 		case CMD_PAUSE:
558 			m_laserdisc->data_w(0xa0);
559 			m_playing = false;
560 			break;
561 
562 		case CMD_FRAME_TOGGLE:
563 			m_laserdisc->data_w(0xf1);
564 			break;
565 
566 		case CMD_0:
567 		case CMD_1:
568 		case CMD_2:
569 		case CMD_3:
570 		case CMD_4:
571 		case CMD_5:
572 		case CMD_6:
573 		case CMD_7:
574 		case CMD_8:
575 		case CMD_9:
576 			m_laserdisc->data_w(digits[command - CMD_0]);
577 			break;
578 
579 		case CMD_SEARCH:
580 			m_laserdisc->data_w(0xf7);
581 			m_playing = false;
582 			break;
583 	}
584 }
585 
586 
587 
588 /*************************************
589  *
590  *  Port definitions
591  *
592  *************************************/
593 
594 static INPUT_PORTS_START( ldplayer )
595 	PORT_START("controls")
PORT_CODE(KEYCODE_LEFT)596 	PORT_BIT( 0x0000001, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Step reverse") PORT_CODE(KEYCODE_LEFT)
597 	PORT_BIT( 0x0000002, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Step forward") PORT_CODE(KEYCODE_RIGHT)
598 	PORT_BIT( 0x0000004, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Scan reverse") PORT_CODE(KEYCODE_UP)
599 	PORT_BIT( 0x0000008, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Scan forward") PORT_CODE(KEYCODE_DOWN)
600 	PORT_BIT( 0x0000010, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Slow reverse") PORT_CODE(KEYCODE_OPENBRACE)
601 	PORT_BIT( 0x0000020, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Slow forward") PORT_CODE(KEYCODE_CLOSEBRACE)
602 	PORT_BIT( 0x0000040, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Fast reverse") PORT_CODE(KEYCODE_COMMA)
603 	PORT_BIT( 0x0000080, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Fast forward") PORT_CODE(KEYCODE_STOP)
604 	PORT_BIT( 0x0000100, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Play/Pause") PORT_CODE(KEYCODE_SPACE)
605 	PORT_BIT( 0x0000200, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Toggle frame display") PORT_CODE(KEYCODE_F)
606 	PORT_BIT( 0x0000400, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Toggle chapter display") PORT_CODE(KEYCODE_C)
607 	PORT_BIT( 0x0000800, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Toggle left channel") PORT_CODE(KEYCODE_L)
608 	PORT_BIT( 0x0001000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Toggle right channel") PORT_CODE(KEYCODE_R)
609 	PORT_BIT( 0x0010000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("0") PORT_PLAYER(2) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_0)
610 	PORT_BIT( 0x0020000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("1") PORT_PLAYER(2) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_1)
611 	PORT_BIT( 0x0040000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("2") PORT_PLAYER(2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_2)
612 	PORT_BIT( 0x0080000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("3") PORT_PLAYER(2) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_3)
613 	PORT_BIT( 0x0100000, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("4") PORT_PLAYER(2) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_4)
614 	PORT_BIT( 0x0200000, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("5") PORT_PLAYER(2) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(KEYCODE_5)
615 	PORT_BIT( 0x0400000, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("6") PORT_PLAYER(2) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_6)
616 	PORT_BIT( 0x0800000, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("7") PORT_PLAYER(2) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_7)
617 	PORT_BIT( 0x1000000, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_NAME("8") PORT_PLAYER(2) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_8)
618 	PORT_BIT( 0x2000000, IP_ACTIVE_HIGH, IPT_BUTTON10 ) PORT_NAME("9") PORT_PLAYER(2) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_9)
619 	PORT_BIT( 0x4000000, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_NAME("Enter") PORT_PLAYER(2) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CODE(KEYCODE_ENTER)
620 INPUT_PORTS_END
621 
622 
623 
624 /*************************************
625  *
626  *  Machine drivers
627  *
628  *************************************/
629 
630 void ldplayer_state::ldplayer_ntsc(machine_config &config)
631 {
632 }
633 
634 
ldv1000(machine_config & config)635 void ldv1000_state::ldv1000(machine_config &config)
636 {
637 	ldplayer_ntsc(config);
638 	pioneer_ldv1000_device &laserdisc(PIONEER_LDV1000(config, "laserdisc"));
639 	laserdisc.set_get_disc(FUNC(ldv1000_state::get_disc));
640 	laserdisc.add_ntsc_screen(config, "screen");
641 
642 	SPEAKER(config, "lspeaker").front_left();
643 	SPEAKER(config, "rspeaker").front_right();
644 	laserdisc.add_route(0, "lspeaker", 1.0);
645 	laserdisc.add_route(1, "rspeaker", 1.0);
646 }
647 
648 
pr8210(machine_config & config)649 void pr8210_state::pr8210(machine_config &config)
650 {
651 	ldplayer_ntsc(config);
652 	pioneer_pr8210_device &laserdisc(PIONEER_PR8210(config, "laserdisc"));
653 	laserdisc.set_get_disc(FUNC(pr8210_state::get_disc));
654 	laserdisc.add_ntsc_screen(config, "screen");
655 
656 	SPEAKER(config, "lspeaker").front_left();
657 	SPEAKER(config, "rspeaker").front_right();
658 	laserdisc.add_route(0, "lspeaker", 1.0);
659 	laserdisc.add_route(1, "rspeaker", 1.0);
660 }
661 
662 
663 
664 /*************************************
665  *
666  *  ROM definitions
667  *
668  *************************************/
669 
670 ROM_START( simldv1000 )
671 	DISK_REGION( "laserdisc" )
672 ROM_END
673 
674 
675 ROM_START( simpr8210 )
676 	DISK_REGION( "laserdisc" )
677 ROM_END
678 
679 
680 
681 /*************************************
682  *
683  *  Game drivers
684  *
685  *************************************/
686 
687 GAME( 2008, simldv1000, 0, ldv1000, ldplayer, ldv1000_state, empty_init, ROT0, "MAME", "Pioneer LDV-1000 Simulator", 0 )
688 GAMEL(2008, simpr8210,  0, pr8210,  ldplayer, pr8210_state,  empty_init, ROT0, "MAME", "Pioneer PR-8210 Simulator",  0, layout_pr8210 )
689