1 // license:BSD-3-Clause
2 // copyright-holders:Nathan Woods, Peter Trauner, Angelo Salese
3 /***************************************************************************
4 
5     pc_vga.h
6 
7     PC standard VGA adaptor
8 
9 ***************************************************************************/
10 
11 #ifndef MAME_VIDEO_PC_VGA_H
12 #define MAME_VIDEO_PC_VGA_H
13 
14 #include "screen.h"
15 
16 // ======================> vga_device
17 
18 class vga_device : public device_t, public device_video_interface, public device_palette_interface
19 {
20 	friend class ibm8514a_device;
21 
22 public:
23 	// construction/destruction
24 	vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
25 
26 	virtual void zero();
27 	virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
28 
29 	virtual uint8_t port_03b0_r(offs_t offset);
30 	virtual void port_03b0_w(offs_t offset, uint8_t data);
31 	virtual uint8_t port_03c0_r(offs_t offset);
32 	virtual void port_03c0_w(offs_t offset, uint8_t data);
33 	virtual uint8_t port_03d0_r(offs_t offset);
34 	virtual void port_03d0_w(offs_t offset, uint8_t data);
35 	virtual uint8_t mem_r(offs_t offset);
36 	virtual void mem_w(offs_t offset, uint8_t data);
37 	virtual uint8_t mem_linear_r(offs_t offset);
38 	virtual void mem_linear_w(offs_t offset,uint8_t data);
39 	virtual TIMER_CALLBACK_MEMBER(vblank_timer_cb);
40 
set_offset(uint16_t val)41 	void set_offset(uint16_t val) { vga.crtc.offset = val; }
42 
43 protected:
44 	enum
45 	{
46 		SCREEN_OFF = 0,
47 		TEXT_MODE,
48 		VGA_MODE,
49 		EGA_MODE,
50 		CGA_MODE,
51 		MONO_MODE,
52 		RGB8_MODE,
53 		RGB15_MODE,
54 		RGB16_MODE,
55 		RGB24_MODE,
56 		RGB32_MODE
57 	};
58 
59 	vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
60 
61 	// device-level overrides
62 	virtual void device_start() override;
63 	virtual void device_reset() override;
64 
65 	// device_palette_interface overrides
palette_entries()66 	virtual uint32_t palette_entries() const override { return 0x100; }
67 
68 	void vga_vh_text(bitmap_rgb32 &bitmap, const rectangle &cliprect);
69 	void vga_vh_ega(bitmap_rgb32 &bitmap,  const rectangle &cliprect);
70 	void vga_vh_vga(bitmap_rgb32 &bitmap, const rectangle &cliprect);
71 	void vga_vh_cga(bitmap_rgb32 &bitmap, const rectangle &cliprect);
72 	void vga_vh_mono(bitmap_rgb32 &bitmap, const rectangle &cliprect);
73 	virtual uint8_t pc_vga_choosevideomode();
74 	void recompute_params_clock(int divisor, int xtal);
75 	uint8_t crtc_reg_read(uint8_t index);
76 	virtual void recompute_params();
77 	void crtc_reg_write(uint8_t index, uint8_t data);
78 	void seq_reg_write(uint8_t index, uint8_t data);
79 	uint8_t vga_vblank();
80 	uint8_t vga_crtc_r(offs_t offset);
81 	void vga_crtc_w(offs_t offset, uint8_t data);
82 	uint8_t gc_reg_read(uint8_t index);
83 	void attribute_reg_write(uint8_t index, uint8_t data);
84 	void gc_reg_write(uint8_t index,uint8_t data);
85 	virtual uint16_t offset();
86 	virtual uint32_t start_addr();
87 	inline uint8_t vga_latch_write(int offs, uint8_t data);
rotate_right(uint8_t val)88 	inline uint8_t rotate_right(uint8_t val) { return (val >> vga.gc.rotate_count) | (val << (8 - vga.gc.rotate_count)); }
vga_logical_op(uint8_t data,uint8_t plane,uint8_t mask)89 	inline uint8_t vga_logical_op(uint8_t data, uint8_t plane, uint8_t mask)
90 	{
91 		uint8_t res = 0;
92 
93 		switch (vga.gc.logical_op & 3)
94 		{
95 		case 0: /* NONE */
96 			res = (data & mask) | (vga.gc.latch[plane] & ~mask);
97 			break;
98 		case 1: /* AND */
99 			res = (data | ~mask) & (vga.gc.latch[plane]);
100 			break;
101 		case 2: /* OR */
102 			res = (data & mask) | (vga.gc.latch[plane]);
103 			break;
104 		case 3: /* XOR */
105 			res = (data & mask) ^ (vga.gc.latch[plane]);
106 			break;
107 		}
108 
109 		return res;
110 	}
111 
112 
113 	struct vga_t
114 	{
vga_tvga_t115 		vga_t(device_t &owner) : read_dipswitch(owner) { }
116 
117 		read8smo_delegate read_dipswitch;
118 		struct
119 		{
120 			size_t vram_size;
121 			int seq_regcount;
122 			int crtc_regcount;
123 		} svga_intf;
124 
125 		std::vector<uint8_t> memory;
126 		uint32_t pens[16]; /* the current 16 pens */
127 
128 		uint8_t miscellaneous_output;
129 		uint8_t feature_control;
130 
131 		struct
132 		{
133 			uint8_t index;
134 			uint8_t data[0x100];
135 			uint8_t map_mask;
136 			struct
137 			{
138 				uint8_t A, B;
139 			}char_sel;
140 		} sequencer;
141 
142 		/* An empty comment at the start of the line indicates that register is currently unused */
143 		struct
144 		{
145 			uint8_t index;
146 			uint8_t data[0x100];
147 			uint16_t horz_total;
148 			uint16_t horz_disp_end;
149 	/**/    uint8_t horz_blank_start;
150 	/**/    uint8_t horz_blank_end;
151 	/**/    uint8_t horz_retrace_start;
152 	/**/    uint8_t horz_retrace_skew;
153 	/**/    uint8_t horz_retrace_end;
154 	/**/    uint8_t disp_enable_skew;
155 	/**/    uint8_t evra;
156 			uint16_t vert_total;
157 			uint16_t vert_disp_end;
158 	/**/    uint16_t vert_retrace_start;
159 	/**/    uint8_t vert_retrace_end;
160 			uint16_t vert_blank_start;
161 			uint16_t line_compare;
162 			uint32_t cursor_addr;
163 	/**/    uint8_t byte_panning;
164 			uint8_t preset_row_scan;
165 			uint8_t scan_doubling;
166 			uint8_t maximum_scan_line;
167 			uint8_t cursor_enable;
168 			uint8_t cursor_scan_start;
169 	/**/    uint8_t cursor_skew;
170 			uint8_t cursor_scan_end;
171 			uint32_t start_addr;
172 			uint32_t start_addr_latch;
173 			uint8_t protect_enable;
174 	/**/    uint8_t bandwidth;
175 			uint16_t offset;
176 			uint8_t word_mode;
177 			uint8_t dw;
178 	/**/    uint8_t div4;
179 	/**/    uint8_t underline_loc;
180 			uint16_t vert_blank_end;
181 			uint8_t sync_en;
182 	/**/    uint8_t aw;
183 			uint8_t div2;
184 	/**/    uint8_t sldiv;
185 	/**/    uint8_t map14;
186 	/**/    uint8_t map13;
187 	/**/    uint8_t irq_clear;
188 	/**/    uint8_t irq_disable;
189 			uint8_t no_wrap;
190 		} crtc;
191 
192 		struct
193 		{
194 			uint8_t index;
195 			uint8_t latch[4];
196 			uint8_t set_reset;
197 			uint8_t enable_set_reset;
198 			uint8_t color_compare;
199 			uint8_t logical_op;
200 			uint8_t rotate_count;
201 			uint8_t shift256;
202 			uint8_t shift_reg;
203 			uint8_t read_map_sel;
204 			uint8_t read_mode;
205 			uint8_t write_mode;
206 			uint8_t color_dont_care;
207 			uint8_t bit_mask;
208 			uint8_t alpha_dis;
209 			uint8_t memory_map_sel;
210 			uint8_t host_oe;
211 			uint8_t chain_oe;
212 		} gc;
213 
214 		struct
215 		{
216 			uint8_t index, data[0x15]; int state;
217 			uint8_t prot_bit;
218 			uint8_t pel_shift;
219 			uint8_t pel_shift_latch;
220 		} attribute;
221 
222 		struct {
223 			uint8_t read_index, write_index, mask;
224 			int read;
225 			int state;
226 			uint8_t color[0x300]; /* flat RGB triplets */
227 			int dirty;
228 		} dac;
229 
230 		struct {
231 			uint8_t visible;
232 		} cursor;
233 
234 		/* oak vga */
235 		struct { uint8_t reg; } oak;
236 	} vga;
237 
238 	emu_timer *m_vblank_timer;
239 };
240 
241 
242 // device type definition
DECLARE_DEVICE_TYPE(VGA,vga_device)243 DECLARE_DEVICE_TYPE(VGA, vga_device)
244 
245 // ======================> svga_device
246 
247 class svga_device :  public vga_device
248 {
249 public:
250 	virtual void zero() override;
251 	virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
252 	uint8_t get_video_depth();
253 
254 protected:
255 	// construction/destruction
256 	svga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
257 
258 	void svga_vh_rgb8(bitmap_rgb32 &bitmap, const rectangle &cliprect);
259 	void svga_vh_rgb15(bitmap_rgb32 &bitmap, const rectangle &cliprect);
260 	void svga_vh_rgb16(bitmap_rgb32 &bitmap, const rectangle &cliprect);
261 	void svga_vh_rgb24(bitmap_rgb32 &bitmap, const rectangle &cliprect);
262 	void svga_vh_rgb32(bitmap_rgb32 &bitmap, const rectangle &cliprect);
263 	virtual uint8_t pc_vga_choosevideomode() override;
264 	virtual void device_start() override;
265 	struct
266 	{
267 		uint8_t bank_r,bank_w;
268 		uint8_t rgb8_en;
269 		uint8_t rgb15_en;
270 		uint8_t rgb16_en;
271 		uint8_t rgb24_en;
272 		uint8_t rgb32_en;
273 		uint8_t id;
274 	} svga;
275 };
276 
277 // ======================> ibm8514_device
278 
279 class ibm8514a_device : public device_t
280 {
281 public:
282 	ibm8514a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
283 
set_vga(T && tag)284 	template <typename T> void set_vga(T &&tag) { m_vga.set_tag(std::forward<T>(tag)); }
set_vga_owner()285 	void set_vga_owner() { m_vga.set_tag(DEVICE_SELF); }
286 
287 	void enabled();
288 
is_8514a_enabled()289 	bool is_8514a_enabled() { return ibm8514.enabled; }
is_passthrough_set()290 	bool is_passthrough_set() { return ibm8514.passthrough; }
291 
292 	uint16_t ibm8514_gpstatus_r();
293 	void ibm8514_cmd_w(uint16_t data);
294 	void ibm8514_display_ctrl_w(uint16_t data);
295 	uint16_t ibm8514_line_error_r();
296 	void ibm8514_line_error_w(uint16_t data);
297 	uint8_t ibm8514_status_r(offs_t offset);
298 	void ibm8514_htotal_w(offs_t offset, uint8_t data);
299 	uint16_t ibm8514_substatus_r();
300 	void ibm8514_subcontrol_w(uint16_t data);
301 	uint16_t ibm8514_subcontrol_r();
302 	uint16_t ibm8514_htotal_r();
303 	uint16_t ibm8514_vtotal_r();
304 	void ibm8514_vtotal_w(uint16_t data);
305 	uint16_t ibm8514_vdisp_r();
306 	void ibm8514_vdisp_w(uint16_t data);
307 	uint16_t ibm8514_vsync_r();
308 	void ibm8514_vsync_w(uint16_t data);
309 	uint16_t ibm8514_desty_r();
310 	void ibm8514_desty_w(uint16_t data);
311 	uint16_t ibm8514_destx_r();
312 	void ibm8514_destx_w(uint16_t data);
313 	uint16_t ibm8514_ssv_r();
314 	void ibm8514_ssv_w(uint16_t data);
315 	uint16_t ibm8514_currentx_r();
316 	void ibm8514_currentx_w(uint16_t data);
317 	uint16_t ibm8514_currenty_r();
318 	void ibm8514_currenty_w(uint16_t data);
319 	uint16_t ibm8514_width_r();
320 	void ibm8514_width_w(uint16_t data);
321 	uint16_t ibm8514_fgcolour_r();
322 	void ibm8514_fgcolour_w(uint16_t data);
323 	uint16_t ibm8514_bgcolour_r();
324 	void ibm8514_bgcolour_w(uint16_t data);
325 	uint16_t ibm8514_multifunc_r();
326 	void ibm8514_multifunc_w(uint16_t data);
327 	uint16_t ibm8514_backmix_r();
328 	void ibm8514_backmix_w(uint16_t data);
329 	uint16_t ibm8514_foremix_r();
330 	void ibm8514_foremix_w(uint16_t data);
331 	uint16_t ibm8514_pixel_xfer_r(offs_t offset);
332 	virtual void ibm8514_pixel_xfer_w(offs_t offset, uint16_t data);
333 	uint16_t ibm8514_read_mask_r();
334 	void ibm8514_read_mask_w(uint16_t data);
335 	uint16_t ibm8514_write_mask_r();
336 	void ibm8514_write_mask_w(uint16_t data);
337 	void ibm8514_advfunc_w(uint16_t data);
338 
339 	void ibm8514_wait_draw();
340 	struct
341 	{
342 		uint16_t htotal;  // Horizontal total (9 bits)
343 		uint16_t vtotal;  // Vertical total adjust (3 bits), Vertical total base (9 bit)
344 		uint16_t vdisp;
345 		uint16_t vsync;
346 		uint16_t subctrl;
347 		uint16_t substatus;
348 		uint8_t display_ctrl;
349 		uint16_t ssv;
350 		uint16_t ec0;
351 		uint16_t ec1;
352 		uint16_t ec2;
353 		uint16_t ec3;
354 		bool gpbusy;
355 		bool data_avail;
356 		int16_t dest_x;
357 		int16_t dest_y;
358 		int16_t curr_x;
359 		int16_t curr_y;
360 		int16_t prev_x;
361 		int16_t prev_y;
362 		int16_t line_axial_step;
363 		int16_t line_diagonal_step;
364 		int16_t line_errorterm;
365 		uint16_t current_cmd;
366 		uint16_t src_x;
367 		uint16_t src_y;
368 		int16_t scissors_left;
369 		int16_t scissors_right;
370 		int16_t scissors_top;
371 		int16_t scissors_bottom;
372 		uint16_t rect_width;
373 		uint16_t rect_height;
374 		uint32_t fgcolour;
375 		uint32_t bgcolour;
376 		uint16_t fgmix;
377 		uint16_t bgmix;
378 		uint32_t pixel_xfer;
379 		uint16_t pixel_control;
380 		uint8_t bus_size;
381 		uint8_t multifunc_sel;
382 		uint16_t multifunc_misc;
383 		uint32_t read_mask;
384 		uint32_t write_mask;
385 		uint16_t advfunction_ctrl;
386 		bool enabled;
387 		bool passthrough;
388 
389 		int state;
390 		uint8_t wait_vector_len;
391 		uint8_t wait_vector_dir;
392 		bool wait_vector_draw;
393 		uint8_t wait_vector_count;
394 
395 	} ibm8514;
396 
397 protected:
398 	ibm8514a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
399 
400 	virtual void device_start() override;
401 	void ibm8514_write(uint32_t offset, uint32_t src);
402 	void ibm8514_write_fg(uint32_t offset);
403 	void ibm8514_write_bg(uint32_t offset);
404 
405 	required_device<svga_device> m_vga;  // for pass-through
406 private:
407 	void ibm8514_draw_vector(uint8_t len, uint8_t dir, bool draw);
408 	void ibm8514_wait_draw_ssv();
409 	void ibm8514_draw_ssv(uint8_t data);
410 	void ibm8514_wait_draw_vector();
411 
412 	//uint8_t* m_vram;  // the original 8514/A has it's own VRAM, but most VGA+8514 combination cards will have
413 					// only one set of VRAM, so this will only be needed in standalone 8514/A cards
414 	//uint32_t m_vramsize;
415 };
416 
417 // device type definition
DECLARE_DEVICE_TYPE(IBM8514A,ibm8514a_device)418 DECLARE_DEVICE_TYPE(IBM8514A, ibm8514a_device)
419 
420 
421 class mach8_device : public ibm8514a_device
422 {
423 public:
424 	mach8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
425 
426 	uint16_t mach8_ec0_r();
427 	void mach8_ec0_w(uint16_t data);
428 	uint16_t mach8_ec1_r();
429 	void mach8_ec1_w(uint16_t data);
430 	uint16_t mach8_ec2_r();
431 	void mach8_ec2_w(uint16_t data);
432 	uint16_t mach8_ec3_r();
433 	void mach8_ec3_w(uint16_t data);
434 	uint16_t mach8_ext_fifo_r();
435 	void mach8_linedraw_index_w(uint16_t data);
436 	uint16_t mach8_bresenham_count_r();
437 	void mach8_bresenham_count_w(uint16_t data);
438 	void mach8_linedraw_w(uint16_t data);
439 	uint16_t mach8_linedraw_r();
440 	uint16_t mach8_scratch0_r();
441 	void mach8_scratch0_w(uint16_t data);
442 	uint16_t mach8_scratch1_r();
443 	void mach8_scratch1_w(uint16_t data);
444 	uint16_t mach8_config1_r();
445 	uint16_t mach8_config2_r();
446 	uint16_t mach8_sourcex_r();
447 	uint16_t mach8_sourcey_r();
448 	void mach8_ext_leftscissor_w(uint16_t data);
449 	void mach8_ext_topscissor_w(uint16_t data);
450 	uint16_t mach8_clksel_r() { return mach8.clksel; }
451 	void mach8_crt_pitch_w(uint16_t data);
452 	void mach8_patt_data_w(uint16_t data) { logerror("Mach8: Pattern Data write (unimplemented)\n"); }
453 	void mach8_ge_offset_l_w(uint16_t data);
454 	void mach8_ge_offset_h_w(uint16_t data);
455 	void mach8_ge_pitch_w(uint16_t data);
456 	uint16_t mach8_ge_ext_config_r() { return mach8.ge_ext_config; }
457 	void mach8_ge_ext_config_w(uint16_t data);  // TODO: handle 8-bit I/O
458 	void mach8_scan_x_w(uint16_t data);
459 	void mach8_dp_config_w(uint16_t data);
460 	uint16_t mach8_readonly_r() { return 0; }
461 	void mach8_pixel_xfer_w(offs_t offset, uint16_t data);
462 	void mach8_clksel_w(uint16_t data) { mach8.ati_mode = true; ibm8514.passthrough = data & 0x0001; mach8.clksel = data; }  // read only on the mach8
463 	void mach8_advfunc_w(uint16_t data) { mach8.ati_mode = false; ibm8514_advfunc_w(data); }
464 	uint16_t get_ext_config() { return mach8.ge_ext_config; }
465 	uint16_t offset() { if(mach8.ati_mode) return mach8.ge_pitch; else return 128; }
466 
467 protected:
468 	mach8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
469 	virtual void device_start() override;
470 	struct
471 	{
472 		uint16_t scratch0;
473 		uint16_t scratch1;
474 		uint16_t linedraw;
475 		uint16_t clksel;
476 		uint16_t crt_pitch;
477 		uint16_t dp_config;
478 		uint32_t ge_offset;
479 		uint16_t ge_pitch;
480 		uint16_t ge_ext_config;  // usage varies between the mach8 and mach32 (except for 8514/A monitor alias)
481 		uint16_t scan_x;
482 		bool ati_mode;
483 	} mach8;
484 
485 private:
486 	void mach8_wait_scan();
487 
488 };
489 
490 // device type definition
DECLARE_DEVICE_TYPE(MACH8,mach8_device)491 DECLARE_DEVICE_TYPE(MACH8, mach8_device)
492 
493 
494 // ======================> tseng_vga_device
495 
496 class tseng_vga_device :  public svga_device
497 {
498 public:
499 	// construction/destruction
500 	tseng_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
501 
502 	virtual uint8_t port_03b0_r(offs_t offset) override;
503 	virtual void port_03b0_w(offs_t offset, uint8_t data) override;
504 	virtual uint8_t port_03c0_r(offs_t offset) override;
505 	virtual void port_03c0_w(offs_t offset, uint8_t data) override;
506 	virtual uint8_t port_03d0_r(offs_t offset) override;
507 	virtual void port_03d0_w(offs_t offset, uint8_t data) override;
508 	virtual uint8_t mem_r(offs_t offset) override;
509 	virtual void mem_w(offs_t offset, uint8_t data) override;
510 
511 protected:
512 	virtual void device_start() override;
513 
514 private:
515 	void tseng_define_video_mode();
516 	uint8_t tseng_crtc_reg_read(uint8_t index);
517 	void tseng_crtc_reg_write(uint8_t index, uint8_t data);
518 	uint8_t tseng_seq_reg_read(uint8_t index);
519 	void tseng_seq_reg_write(uint8_t index, uint8_t data);
520 	void tseng_attribute_reg_write(uint8_t index, uint8_t data);
521 
522 	struct
523 	{
524 		uint8_t reg_3d8;
525 		uint8_t dac_ctrl;
526 		uint8_t dac_state;
527 		uint8_t horz_overflow;
528 		uint8_t aux_ctrl;
529 		bool ext_reg_ena;
530 		uint8_t misc1;
531 		uint8_t misc2;
532 	}et4k;
533 
534 };
535 
536 
537 // device type definition
DECLARE_DEVICE_TYPE(TSENG_VGA,tseng_vga_device)538 DECLARE_DEVICE_TYPE(TSENG_VGA, tseng_vga_device)
539 
540 
541 // ======================> ati_vga_device
542 
543 class ati_vga_device : public svga_device
544 {
545 public:
546 	// construction/destruction
547 	ati_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
548 
549 	virtual uint8_t mem_r(offs_t offset) override;
550 	virtual void mem_w(offs_t offset, uint8_t data) override;
551 
552 	// VGA registers
553 	virtual uint8_t port_03c0_r(offs_t offset) override;
554 	uint8_t ati_port_ext_r(offs_t offset);
555 	void ati_port_ext_w(offs_t offset, uint8_t data);
556 
557 	virtual uint16_t offset() override;
558 
559 	mach8_device* get_8514() { return m_8514; }
560 protected:
561 	ati_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
562 
563 	virtual void device_start() override;
564 	virtual void device_add_mconfig(machine_config &config) override;
565 	virtual void ati_define_video_mode();
566 	void set_dot_clock();
567 	struct
568 	{
569 		uint8_t ext_reg[64];
570 		uint8_t ext_reg_select;
571 		uint8_t vga_chip_id;
572 	} ati;
573 
574 private:
575 	mach8_device* m_8514;
576 };
577 
578 // device type definition
DECLARE_DEVICE_TYPE(ATI_VGA,ati_vga_device)579 DECLARE_DEVICE_TYPE(ATI_VGA, ati_vga_device)
580 
581 
582 // ======================> s3_vga_device
583 
584 class s3_vga_device : public ati_vga_device
585 {
586 public:
587 	// construction/destruction
588 	s3_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
589 
590 	virtual uint8_t port_03b0_r(offs_t offset) override;
591 	virtual void port_03b0_w(offs_t offset, uint8_t data) override;
592 	virtual uint8_t port_03c0_r(offs_t offset) override;
593 	virtual void port_03c0_w(offs_t offset, uint8_t data) override;
594 	virtual uint8_t port_03d0_r(offs_t offset) override;
595 	virtual void port_03d0_w(offs_t offset, uint8_t data) override;
596 	virtual uint8_t mem_r(offs_t offset) override;
597 	virtual void mem_w(offs_t offset, uint8_t data) override;
598 
599 	virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
600 
601 	virtual TIMER_CALLBACK_MEMBER(vblank_timer_cb) override;
602 
603 	ibm8514a_device* get_8514() { return m_8514; }
604 
605 protected:
606 	s3_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
607 
608 	// device-level overrides
609 	virtual void device_start() override;
610 	virtual void device_reset() override;
611 	virtual void device_add_mconfig(machine_config &config) override;
612 
613 	struct
614 	{
615 		uint8_t memory_config;
616 		uint8_t ext_misc_ctrl_2;
617 		uint8_t crt_reg_lock;
618 		uint8_t reg_lock1;
619 		uint8_t reg_lock2;
620 		uint8_t enable_8514;
621 		uint8_t enable_s3d;
622 		uint8_t cr3a;
623 		uint8_t cr42;
624 		uint8_t cr43;
625 		uint8_t cr51;
626 		uint8_t cr53;
627 		uint8_t id_high;
628 		uint8_t id_low;
629 		uint8_t revision;
630 		uint8_t id_cr30;
631 		uint32_t strapping;  // power-on strapping bits
632 		uint8_t sr10;   // MCLK PLL
633 		uint8_t sr11;   // MCLK PLL
634 		uint8_t sr12;   // DCLK PLL
635 		uint8_t sr13;   // DCLK PLL
636 		uint8_t sr15;   // CLKSYN control 2
637 		uint8_t sr17;   // CLKSYN test
638 		uint8_t clk_pll_r;  // individual DCLK PLL values
639 		uint8_t clk_pll_m;
640 		uint8_t clk_pll_n;
641 
642 		// data for memory-mapped I/O
643 		uint16_t mmio_9ae8;
644 		uint16_t mmio_bee8;
645 		uint16_t mmio_96e8;
646 
647 		// hardware graphics cursor
648 		uint8_t cursor_mode;
649 		uint16_t cursor_x;
650 		uint16_t cursor_y;
651 		uint16_t cursor_start_addr;
652 		uint8_t cursor_pattern_x;  // cursor pattern origin
653 		uint8_t cursor_pattern_y;
654 		uint8_t cursor_fg[4];
655 		uint8_t cursor_bg[4];
656 		uint8_t cursor_fg_ptr;
657 		uint8_t cursor_bg_ptr;
658 		uint8_t extended_dac_ctrl;
659 	} s3;
660 	virtual uint16_t offset() override;
661 
662 private:
663 	uint8_t s3_crtc_reg_read(uint8_t index);
664 	void s3_define_video_mode(void);
665 	void s3_crtc_reg_write(uint8_t index, uint8_t data);
666 	uint8_t s3_seq_reg_read(uint8_t index);
667 	void s3_seq_reg_write(uint8_t index, uint8_t data);
668 	ibm8514a_device* m_8514;
669 };
670 
671 // device type definition
DECLARE_DEVICE_TYPE(S3_VGA,s3_vga_device)672 DECLARE_DEVICE_TYPE(S3_VGA, s3_vga_device)
673 
674 // ======================> gamtor_vga_device
675 
676 class gamtor_vga_device :  public svga_device
677 {
678 public:
679 	// construction/destruction
680 	gamtor_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
681 
682 
683 	virtual uint8_t port_03b0_r(offs_t offset) override;
684 	virtual void port_03b0_w(offs_t offset, uint8_t data) override;
685 	virtual uint8_t port_03c0_r(offs_t offset) override;
686 	virtual void port_03c0_w(offs_t offset, uint8_t data) override;
687 	virtual uint8_t port_03d0_r(offs_t offset) override;
688 	virtual void port_03d0_w(offs_t offset, uint8_t data) override;
689 	virtual uint8_t mem_r(offs_t offset) override;
690 	virtual void mem_w(offs_t offset, uint8_t data) override;
691 };
692 
693 
694 // device type definition
695 DECLARE_DEVICE_TYPE(GAMTOR_VGA, gamtor_vga_device)
696 
697 /*
698   pega notes (paradise)
699   build in amstrad pc1640
700 
701   ROM_LOAD("40100", 0xc0000, 0x8000, CRC(d2d1f1ae))
702 
703   4 additional dipswitches
704   seems to have emulation modes at register level
705   (mda/hgc lines bit 8 not identical to ega/vga)
706 
707   standard ega/vga dipswitches
708   00000000  320x200
709   00000001  640x200 hanging
710   00000010  640x200 hanging
711   00000011  640x200 hanging
712 
713   00000100  640x350 hanging
714   00000101  640x350 hanging EGA mono
715   00000110  320x200
716   00000111  640x200
717 
718   00001000  640x200
719   00001001  640x200
720   00001010  720x350 partial visible
721   00001011  720x350 partial visible
722 
723   00001100  320x200
724   00001101  320x200
725   00001110  320x200
726   00001111  320x200
727 
728 */
729 
730 /*
731   oak vga (oti 037 chip)
732   (below bios patch needed for running)
733 
734   ROM_LOAD("oakvga.bin", 0xc0000, 0x8000, CRC(318c5f43))
735 */
736 
737 
738 #endif // MAME_VIDEO_PC_VGA_H
739