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