1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /*************************************************************************
4 
5     ldpr8210.h
6 
7     Pioneer PR-8210 laserdisc emulation.
8 
9 *************************************************************************/
10 
11 #ifndef MAME_MACHINE_LDPR8210_H
12 #define MAME_MACHINE_LDPR8210_H
13 
14 #pragma once
15 
16 #include "laserdsc.h"
17 #include "cpu/mcs48/mcs48.h"
18 
19 
20 //**************************************************************************
21 //  GLOBAL VARIABLES
22 //**************************************************************************
23 
24 // device type definition
DECLARE_DEVICE_TYPE(PIONEER_PR8210,pioneer_pr8210_device)25 DECLARE_DEVICE_TYPE(PIONEER_PR8210,   pioneer_pr8210_device)
26 DECLARE_DEVICE_TYPE(SIMUTREK_SPECIAL, simutrek_special_device)
27 
28 
29 
30 //**************************************************************************
31 //  TYPE DEFINITIONS
32 //**************************************************************************
33 
34 // ======================> pioneer_pr8210_device
35 
36 // base pr8210 class
37 class pioneer_pr8210_device : public laserdisc_device
38 {
39 public:
40 	// construction/destruction
41 	pioneer_pr8210_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
42 
43 	// input and output
44 	void control_w(uint8_t data);
45 
46 protected:
47 	// timer IDs
48 	enum
49 	{
50 		TID_VSYNC_OFF = TID_FIRST_PLAYER_TIMER,
51 		TID_VBI_DATA_FETCH,
52 		TID_FIRST_SUBCLASS_TIMER
53 	};
54 
55 	pioneer_pr8210_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
56 
57 	// device-level overrides
58 	virtual void device_start() override;
59 	virtual void device_reset() override;
60 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
61 	virtual const tiny_rom_entry *device_rom_region() const override;
62 	virtual void device_add_mconfig(machine_config &config) override;
63 
64 	// subclass overrides
65 	virtual void player_vsync(const vbi_metadata &vbi, int fieldnum, const attotime &curtime) override;
66 	virtual int32_t player_update(const vbi_metadata &vbi, int fieldnum, const attotime &curtime) override;
67 	virtual void player_overlay(bitmap_yuy16 &bitmap) override;
68 
69 	// internal helpers
70 	bool focus_on() const { return !(m_i8049_port1 & 0x08); }
71 	bool spdl_on() const { return !(m_i8049_port1 & 0x10); }
72 	bool laser_on() const { return !(m_i8049_port2 & 0x01); }
73 	virtual bool override_control() const { return false; }
74 	void update_video_squelch() { set_video_squelch((m_i8049_port1 & 0x20) != 0); }
75 	virtual void update_audio_squelch() { set_audio_squelch((m_i8049_port1 & 0x40) || !(m_pia.portb & 0x01), (m_i8049_port1 & 0x40) || !(m_pia.portb & 0x02)); }
76 
77 	// internal read/write handlers
78 	uint8_t i8049_pia_r(offs_t offset);
79 	void i8049_pia_w(offs_t offset, uint8_t data);
80 	uint8_t i8049_bus_r();
81 	void i8049_port1_w(uint8_t data);
82 	void i8049_port2_w(uint8_t data);
83 	int i8049_t0_r();
84 	int i8049_t1_r();
85 
86 	// pioneer PIA subclass
87 	class pioneer_pia
88 	{
89 	public:
90 		uint8_t               frame[7];               // (20-26) 7 characters for the chapter/frame
91 		uint8_t               text[17];               // (20-30) 17 characters for the display
92 		uint8_t               control;                // (40) control lines
93 		uint8_t               latchdisplay;           //   flag: set if the display was latched
94 		uint8_t               portb;                  // (60) port B value (LEDs)
95 		uint8_t               display;                // (80) display enable
96 		uint8_t               porta;                  // (A0) port A value (from serial decoder)
97 		uint8_t               vbi1;                   // (C0) VBI decoding state 1
98 		uint8_t               vbi2;                   // (E0) VBI decoding state 2
99 	};
100 
101 	// internal overlay helpers
102 	void overlay_draw_group(bitmap_yuy16 &bitmap, const uint8_t *text, int count, float xstart);
103 	void overlay_erase(bitmap_yuy16 &bitmap, float xstart, float xend);
104 	void overlay_draw_char(bitmap_yuy16 &bitmap, uint8_t ch, float xstart);
105 
106 	// LED outputs
107 	output_finder<>     m_audio1;
108 	output_finder<>     m_audio2;
109 	output_finder<>     m_clv;
110 	output_finder<>     m_cav;
111 	output_finder<>     m_srev;
112 	output_finder<>     m_sfwd;
113 	output_finder<>     m_play;
114 	output_finder<>     m_step;
115 	output_finder<>     m_pause;
116 	output_finder<>     m_standby;
117 
118 	// internal state
119 	uint8_t             m_control;              // control line state
120 	uint8_t             m_lastcommand;          // last command seen
121 	uint16_t            m_accumulator;          // bit accumulator
122 	attotime            m_lastcommandtime;      // time of the last command
123 	attotime            m_lastbittime;          // time of last bit received
124 	attotime            m_firstbittime;         // time of first bit in command
125 
126 	// low-level emulation data
127 	required_device<i8049_device> m_i8049_cpu;  // 8049 CPU device
128 	attotime            m_slowtrg;              // time of the last SLOW TRG
129 	pioneer_pia         m_pia;                  // PIA state
130 	bool                m_vsync;                // live VSYNC state
131 	uint8_t             m_i8049_port1;          // 8049 port 1 state
132 	uint8_t             m_i8049_port2;          // 8049 port 2 state
133 
134 private:
135 	void pr8210_portmap(address_map &map);
136 };
137 
138 
139 // ======================> simutrek_special_device
140 
141 class simutrek_special_device : public pioneer_pr8210_device
142 {
143 public:
144 	// construction/destruction
145 	simutrek_special_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
146 
147 	// input and output
148 	void data_w(uint8_t data);
ready_r()149 	uint8_t ready_r() const { return !m_data_ready; }
status_r()150 	uint8_t status_r() const { return ((m_i8748_port2 & 0x03) == 0x03) ? ASSERT_LINE : CLEAR_LINE; }
151 
152 	// external controls
153 	void set_external_audio_squelch(int state);
154 
155 protected:
156 	// timer IDs
157 	enum
158 	{
159 		TID_IRQ_OFF = TID_FIRST_SUBCLASS_TIMER,
160 		TID_LATCH_DATA
161 	};
162 
163 	// subclass overrides
164 	virtual void player_vsync(const vbi_metadata &vbi, int fieldnum, const attotime &curtime) override;
165 
166 	// device-level overrides
167 	virtual void device_start() override;
168 	virtual void device_reset() override;
169 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
170 	virtual const tiny_rom_entry *device_rom_region() const override;
171 	virtual void device_add_mconfig(machine_config &config) override;
172 
173 	// internal helpers
override_control()174 	virtual bool override_control() const override { return m_controlthis; }
update_audio_squelch()175 	virtual void update_audio_squelch() override { set_audio_squelch(m_audio_squelch, m_audio_squelch); }
176 
177 private:
178 	// internal read/write handlers
179 	uint8_t i8748_data_r();
180 	uint8_t i8748_port2_r();
181 	void i8748_port2_w(uint8_t data);
182 	int i8748_t0_r();
183 
184 	void simutrek_portmap(address_map &map);
185 
186 	// internal state
187 	required_device<i8748_device> m_i8748_cpu;
188 	uint8_t               m_audio_squelch;            // audio squelch value
189 	uint8_t               m_data;                 // parallel data for simutrek
190 	bool                m_data_ready;               // ready flag for simutrek data
191 	uint8_t               m_i8748_port2;                  // 8748 port 2 state
192 	uint8_t               m_controlnext;          // latch to control next pair of fields
193 	uint8_t               m_controlthis;          // latched value for our control over the current pair of fields
194 };
195 
196 #endif // MAME_MACHINE_LDPR8210_H
197