1 // license:BSD-3-Clause
2 // copyright-holders:Ryan Holtz
3 /*********************************************************************
4 
5     vino.h
6 
7     Silicon Graphics VINO (Video-In, No Out) controller emulation
8 
9 *********************************************************************/
10 
11 #ifndef MAME_MACHINE_VINO_H
12 #define MAME_MACHINE_VINO_H
13 
14 #pragma once
15 
16 #include "bitmap.h"
17 #include "imagedev/picture.h"
18 #include "imagedev/avivideo.h"
19 
20 class vino_device : public device_t
21 {
22 public:
23 	vino_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
24 
25 	uint32_t read(offs_t offset, uint32_t mem_mask = ~0);
26 	void write(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
27 
i2c_data_out()28 	auto i2c_data_out() { return m_i2c_data_out.bind(); }
i2c_data_in()29 	auto i2c_data_in() { return m_i2c_data_in.bind(); }
i2c_stop()30 	auto i2c_stop() { return m_i2c_stop.bind(); }
interrupt_cb()31 	auto interrupt_cb() { return m_interrupt_cb.bind(); }
32 
set_gio64_space(T && tag,int space)33 	template <typename T> void set_gio64_space(T &&tag, int space) { m_space.set_tag(std::forward<T>(tag), space); }
34 
35 protected:
36 	// device-level overrides
37 	virtual void device_start() override;
38 	virtual void device_reset() override;
39 	virtual void device_add_mconfig(machine_config &config) override;
40 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
41 
42 private:
43 	static constexpr device_timer_id TIMER_FETCH_CHA = 0;
44 	static constexpr device_timer_id TIMER_FETCH_CHB = 1;
45 
46 	enum channel_num_t : uint32_t
47 	{
48 		CHAN_A,
49 		CHAN_B,
50 		CHAN_COUNT
51 	};
52 
53 	enum : u64
54 	{
55 		CTRL_MASK                   = 0x7fffffff,
56 
57 		CTRL_ENDIAN_BIG             = (0 << 0),
58 		CTRL_ENDIAN_LITTLE          = (1 << 0),
59 
60 		CTRL_CHA_FIELD_INT_EN       = (1 << 1),
61 		CTRL_CHA_FIFO_INT_EN        = (1 << 2),
62 		CTRL_CHA_DESC_INT_EN        = (1 << 3),
63 
64 		CTRL_CHB_FIELD_INT_EN       = (1 << 4),
65 		CTRL_CHB_FIFO_INT_EN        = (1 << 5),
66 		CTRL_CHB_DESC_INT_EN        = (1 << 6),
67 
68 		CTRL_CHA_DMA_EN             = (1 << 7),
69 		CTRL_CHA_INTERLEAVE_EN      = (1 << 8),
70 		CTRL_CHA_SYNC_EN            = (1 << 9),
71 		CTRL_CHA_SELECT_PHILIPS     = (0 << 10),
72 		CTRL_CHA_SELECT_D1          = (1 << 10),
73 		CTRL_CHA_COLOR_SPACE_YUV    = (0 << 11),
74 		CTRL_CHA_COLOR_SPACE_RGB    = (1 << 11),
75 		CTRL_CHA_LUMA_ONLY          = (1 << 12),
76 		CTRL_CHA_DECIMATE_EN        = (1 << 13),
77 		CTRL_CHA_DECIMATION_SHIFT   = 14,
78 		CTRL_CHA_DECIMATION_MASK    = 0x7,
79 		CTRL_CHA_DECIMATE_HORIZ_EN  = (1 << 17),
80 		CTRL_CHA_DITHER_EN          = (1 << 18),
81 
82 		CTRL_CHB_DMA_EN             = (1 << 19),
83 		CTRL_CHB_INTERLEAVE_EN      = (1 << 20),
84 		CTRL_CHB_SYNC_EN            = (1 << 21),
85 		CTRL_CHB_SELECT_PHILIPS     = (0 << 22),
86 		CTRL_CHB_SELECT_D1          = (1 << 22),
87 		CTRL_CHB_COLOR_SPACE_YUV    = (0 << 23),
88 		CTRL_CHB_COLOR_SPACE_RGB    = (1 << 23),
89 		CTRL_CHB_LUMA_ONLY          = (1 << 24),
90 		CTRL_CHB_DECIMATE_EN        = (1 << 25),
91 		CTRL_CHB_DECIMATION_SHIFT   = 26,
92 		CTRL_CHB_DECIMATION_MASK    = 0x7,
93 		CTRL_CHB_DECIMATE_HORIZ_EN  = (1 << 29),
94 		CTRL_CHB_DITHER_EN          = (1 << 30),
95 
96 		ISR_CHA_EOF                 = (1 << 0),
97 		ISR_CHA_FIFO                = (1 << 1),
98 		ISR_CHA_DESC                = (1 << 2),
99 		ISR_CHB_EOF                 = (1 << 3),
100 		ISR_CHB_FIFO                = (1 << 4),
101 		ISR_CHB_DESC                = (1 << 5),
102 		ISR_MASK                    = 0x3f,
103 
104 		ALPHA_MASK                  = 0xff,
105 
106 		CLIP_X_SHIFT                = 0,
107 		CLIP_X_MASK                 = 0x03ff,
108 		CLIP_YODD_SHIFT             = 10,
109 		CLIP_YODD_MASK              = 0x01ff,
110 		CLIP_YEVEN_SHIFT            = 19,
111 		CLIP_YEVEN_MASK             = 0x01ff,
112 		CLIP_REG_MASK               = (CLIP_X_MASK << CLIP_X_SHIFT) | (CLIP_YODD_MASK << CLIP_YODD_SHIFT) | (CLIP_YEVEN_MASK << CLIP_YEVEN_SHIFT),
113 
114 		FRAME_RATE_NTSC             = (0 << 0),
115 		FRAME_RATE_PAL              = (1 << 0),
116 		FRAME_RATE_SHIFT            = 1,
117 		FRAME_RATE_MASK             = 0x0fff,
118 		FRAME_RATE_REG_MASK         = 0x1fff,
119 
120 		FIELD_COUNTER_MASK          = 0xffff,
121 		LINE_SIZE_MASK              = 0x0ff8,
122 		LINE_COUNTER_MASK           = 0x0ff8,
123 		PAGE_INDEX_MASK             = 0x0ff8,
124 
125 		DESC_PTR_MASK               = 0xfffffff0,
126 
127 		DESC_VALID_BIT              = (1ULL << 32),
128 		DESC_STOP_BIT               = (1ULL << 31),
129 		DESC_JUMP_BIT               = (1ULL << 30),
130 		DESC_DATA_MASK              = 0x00000000ffffffffULL,
131 
132 		FIFO_MASK                   = 0x03f8,
133 
134 		I2C_CTRL_IDLE               = (0 << 0),
135 		I2C_CTRL_BUSY               = (1 << 0),
136 		I2C_CTRL_FORCE_IDLE         = (0 << 0),
137 		I2C_BUS_DIR_WRITE           = (0 << 1),
138 		I2C_BUS_DIR_READ            = (1 << 1),
139 		I2C_LAST_RELEASE            = (0 << 2),
140 		I2C_LAST_HOLD               = (1 << 2),
141 		I2C_XFER_DONE               = (0 << 4),
142 		I2C_XFER_BUSY               = (1 << 4),
143 		I2C_ACK_RECEIVED            = (0 << 5),
144 		I2C_ACK_NOT_RECEIVED        = (1 << 5),
145 		I2C_BUS_ERROR               = (1 << 7),
146 		I2C_CTRL_MASK               = 0xb7,
147 
148 		I2C_DATA_MASK               = 0xff,
149 	};
150 
151 	enum pixel_format_t : uint8_t
152 	{
153 		FORMAT_RGBA32,
154 		FORMAT_YUV422,
155 		FORMAT_RGBA8,
156 		FORMAT_Y8
157 	};
158 
159 	struct channel_t
160 	{
161 		// Externally-visible state
162 		uint32_t m_alpha;
163 		uint32_t m_clip_start;
164 		uint32_t m_clip_end;
165 		uint32_t m_frame_rate;
166 		uint32_t m_field_counter;
167 		uint32_t m_line_size;
168 		uint32_t m_line_counter;
169 		uint32_t m_page_index;
170 		uint32_t m_next_desc_ptr;
171 		uint32_t m_start_desc_ptr;
172 		uint64_t m_descriptors[4];
173 		uint32_t m_fifo_threshold;
174 		uint32_t m_fifo_gio_ptr;
175 		uint32_t m_fifo_video_ptr;
176 
177 		// Internal state
178 		uint64_t m_fifo[128];
179 		uint32_t m_active_alpha;
180 		uint32_t m_curr_line;
181 		uint16_t m_frame_mask_shift;
182 		uint16_t m_frame_mask_shifter;
183 		uint32_t m_pixel_size;
184 		uint64_t m_next_fifo_word;
185 		uint32_t m_word_pixel_counter;
186 		uint32_t m_decimation;
187 
188 		// Kludges for picture input
189 		uint32_t m_field_width;
190 		uint32_t m_field_height[2];
191 		uint32_t m_field_x;
192 		uint32_t m_field_y;
193 
194 		// Kludges in order to trigger end-of-field
195 		int32_t m_pixels_per_even_field;
196 		int32_t m_pixels_per_odd_field;
197 		int32_t m_field_pixels_remaining[2];
198 		bool m_end_of_field;
199 
200 		emu_timer *m_fetch_timer;
201 	};
202 
203 	void do_dma_transfer(int channel);
204 
205 	//bool decimate(int channel);
206 	bool is_interleaved(int channel);
207 	bool is_even_field(int channel);
208 	void end_of_field(int channel);
209 
210 	void push_fifo(int channel);
211 
212 	void count_pixel(int channel);
213 	void argb_to_yuv(uint32_t argb, int32_t &y, int32_t &u, int32_t &v);
214 	uint32_t yuv_to_abgr(int channel, int32_t y, int32_t u, int32_t v);
215 	bool merge_pixel(int channel, int32_t y, int32_t u, int32_t v, pixel_format_t format);
216 	pixel_format_t get_current_format(int channel);
217 	void process_pixel(int channel, int32_t y, int32_t u, int32_t v);
218 	uint32_t linear_rgb(uint32_t a, uint32_t b, float f);
219 	uint32_t bilinear_pixel(float s, float t);
220 	void input_pixel(int channel, int32_t &y, int32_t &u, int32_t &v);
221 	void fetch_pixel(int channel);
222 	attotime calculate_field_rate(int channel);
223 	attotime calculate_fetch_rate(int channel);
224 
225 	void shift_dma_descriptors(int channel);
226 	void load_dma_descriptors(int channel, uint32_t addr);
227 	void invalidate_dma_descriptors(int channel);
228 
229 	void load_frame_mask_shifter(int channel);
230 
231 	bool line_count_w(int channel, uint32_t data);
232 	void frame_rate_w(int channel, uint32_t data);
233 	bool page_index_w(int channel, uint32_t data);
234 	void next_desc_w(int channel, uint32_t data);
235 	void control_w(uint32_t data);
236 	void interrupts_w(uint32_t new_int);
237 
238 	uint32_t m_rev_id;
239 	uint32_t m_control;
240 	uint32_t m_int_status;
241 	uint32_t m_i2c_ctrl;
242 	uint32_t m_i2c_data;
243 	channel_t m_channels[2];
244 
245 	devcb_write8 m_i2c_data_out;
246 	devcb_read8 m_i2c_data_in;
247 	devcb_write_line m_i2c_stop;
248 	devcb_write_line m_interrupt_cb;
249 
250 	required_device<picture_image_device> m_picture;
251 	required_device<avivideo_image_device> m_avivideo;
252 	required_address_space m_space;
253 
254 	bitmap_argb32 *m_input_bitmap;
255 };
256 
257 DECLARE_DEVICE_TYPE(VINO, vino_device)
258 
259 #endif // MAME_MACHINE_VINO_H
260