1 // license:BSD-3-Clause
2 // copyright-holders:Patrick Mackinlay
3 
4 #ifndef MAME_VIDEO_SGI_RE2_H
5 #define MAME_VIDEO_SGI_RE2_H
6 
7 #pragma once
8 
9 #include "video/sgi_xmap2.h"
10 #include "video/bt45x.h"
11 #include "video/bt431.h"
12 #include "screen.h"
13 
14 class sgi_re2_device : public device_t
15 {
16 public:
17 	sgi_re2_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
18 
out_rdy()19 	auto out_rdy() { return m_rdy_cb.bind(); }
out_drq()20 	auto out_drq() { return m_drq_cb.bind(); }
21 
22 	// device_t overrides
23 	virtual void device_start() override;
24 	virtual void device_reset() override;
25 
26 	u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect);
27 
28 	enum re_register : unsigned
29 	{
30 		// buffered registers (write only unless noted)
31 		REG_ENABRGB   = 0x04, // enable 8 bit rgb (re2 only) (1)
32 		REG_BIGENDIAN = 0x05, // enable big endian mode (1)
33 		REG_FUNC      = 0x06, // raster op function (4)
34 		REG_HADDR     = 0x07, // starting pixel location (2)
35 		REG_NOPUP     = 0x08, // size of uaux (1)
36 		REG_XYFRAC    = 0x09, // initial xyfrac (4)
37 		REG_RGB       = 0x0a, // initial color values (27)
38 		REG_YX        = 0x0b, // initial y and x (22)
39 		REG_PUPDATA   = 0x0c, // pup data (2)
40 		REG_PATL      = 0x0d, // pattern mask low (16)
41 		REG_PATH      = 0x0e, // pattern mask high (16)
42 		REG_DZI       = 0x0f, // delta z integer (24)
43 		REG_DZF       = 0x10, // delta z fraction (14)
44 		REG_DR        = 0x11, // delta red (24)
45 		REG_DG        = 0x12, // delta green (20)
46 		REG_DB        = 0x13, // delta blue (20)
47 		REG_Z         = 0x14, // initial z integer (24)
48 		REG_R         = 0x15, // initial red (23)
49 		REG_G         = 0x16, // initial green (19)
50 		REG_B         = 0x17, // initial blue (19)
51 		REG_STIP      = 0x18, // stipple pattern (16, rw)
52 		REG_STIPCOUNT = 0x19, // stipple repeat (8, rw)
53 		REG_DX        = 0x1a, // delta x (16)
54 		REG_DY        = 0x1b, // delta y (16)
55 		REG_NUMPIX    = 0x1c, // pixel count (11)
56 		REG_X         = 0x1d, // initial x (12)
57 		REG_Y         = 0x1e, // initial y (11)
58 		REG_IR        = 0x1f, // instruction (3)
59 
60 		// unbuffered registers (write only unless noted)
61 		REG_RWDATA    = 0x20, // read/write data (32, rw)
62 		REG_PIXMASK   = 0x21, // pixel mask (24)
63 		REG_AUXMASK   = 0x22, // auxiliary mask (9)
64 		REG_WIDDATA   = 0x23, // window id (4)
65 		REG_UAUXDATA  = 0x24, // uaux data (4)
66 		REG_RWMODE    = 0x25, // read/write mode (3)
67 		REG_READBUF   = 0x26, // buffer select (1)
68 		REG_PIXTYPE   = 0x27, // pixel type (2)
69 		REG_ASELECT   = 0x28, // antialias select (6)
70 		REG_ALIGNPAT  = 0x29, // pattern alignment (1)
71 		REG_ENABPAT   = 0x2a, // enable pattern mask (1)
72 		REG_ENABSTIP  = 0x2b, // enable stipple (1)
73 		REG_ENABDITH  = 0x2c, // enable dithering (1)
74 		REG_ENABWID   = 0x2d, // enable wid check (1)
75 		REG_CURWID    = 0x2e, // current wid (4)
76 		REG_DEPTHFN   = 0x2f, // depth function (4)
77 		REG_REPSTIP   = 0x30, // stipple repeat (8)
78 		REG_ENABLWID  = 0x31, // enable line wid (1)
79 		REG_FBOPTION  = 0x32, // frame buffer option (2)
80 		REG_TOPSCAN   = 0x33, // first row/column (18)
81 		REG_TESTMODE  = 0x34, // ??
82 		REG_TESTDATA  = 0x35, // ??
83 		REG_ZBOPTION  = 0x36, // z buffer option (1)
84 		REG_XZOOM     = 0x37, // x zoom factor (8)
85 		REG_UPACMODE  = 0x38, // packing mode (2)
86 		REG_YMIN      = 0x39, // bottom screen mask (11)
87 		REG_YMAX      = 0x3a, // top screen mask (11)
88 		REG_XMIN      = 0x3b, // left screen mask (12)
89 		REG_XMAX      = 0x3c, // right screen mask (12)
90 		REG_COLORCMP  = 0x3d, // z compare source (1)
91 		REG_MEGOPTION = 0x3e, // vram size (1)
92 	};
93 
94 	enum re_rwmode : unsigned
95 	{
96 		RWMODE_FB   = 0, // frame buffer bitplanes
97 		RWMODE_PUP  = 1, // pup bitplanes
98 		RWMODE_UAUX = 2, // uaux bitplanes
99 		RWMODE_ZB   = 3, // z buffer bitplanes
100 		RWMODE_WID  = 4, // wid bitplanes
101 		RWMODE_FB_P = 6, // frame buffer port
102 		RWMODE_ZB_P = 7, // z buffer port
103 	};
104 
105 	enum re_ir : unsigned
106 	{
107 		IR_SHADED     = 1, // draw shaded span
108 		IR_FLAT       = 2, // draw 1x5 flat span
109 		IR_FLAT4      = 3, // draw 1x20 flat span (megoption=0)
110 		IR_BLOCKWRITE = 3, // 20 pix blkwrt mode (megoption=1)
111 		IR_TOPLINE    = 4, // draw top of antialised line
112 		IR_BOTLINE    = 5, // draw bottom of antialised line
113 		IR_READBUF    = 6, // read buffer
114 		IR_WRITEBUF   = 7, // write buffer
115 	};
116 
117 	u32 reg_r(offs_t offset);
118 	void reg_w(offs_t offset, u32 data);
119 
120 protected:
121 	// state machine
122 	void step(void *ptr = nullptr, int param = 0);
123 	void execute();
124 
125 	// drawing functions
126 	void draw_shaded_span();
127 	void draw_flat_span(unsigned const n);
128 	void read_buffer();
129 	void write_buffer();
130 
131 	// line helpers
set_rdy(bool state)132 	void set_rdy(bool state)
133 	{
134 		if (state != m_rdy)
135 		{
136 			m_rdy = state;
137 			m_rdy_cb(m_rdy);
138 		}
139 	}
set_drq(bool state)140 	void set_drq(bool state)
141 	{
142 		if (state != m_drq)
143 		{
144 			m_drq = state;
145 			m_drq_cb(m_drq);
146 		}
147 	}
148 
149 	// write condition helpers
150 	u32 unpack(u32 data, unsigned const n, u32 const mode) const;
151 	bool wid(unsigned const ir, offs_t const offset);
152 	bool pattern(unsigned const x, unsigned const n) const;
153 
154 	void increment();
155 
vram_w(offs_t const offset,u32 const data,u32 const mem_mask)156 	void vram_w(offs_t const offset, u32 const data, u32 const mem_mask) { m_vram[offset] = (m_vram[offset] & ~mem_mask) | (data & mem_mask & m_vram_mask); }
157 
158 private:
159 	required_device_array<sgi_xmap2_device, 5> m_xmap;
160 	required_device_array<bt431_device, 2> m_cursor;
161 	required_device_array<bt457_device, 3> m_ramdac;
162 	required_ioport m_options_port;
163 
164 	devcb_write_line m_rdy_cb;
165 	devcb_write_line m_drq_cb;
166 
167 	// state machine
168 	emu_timer *m_step;
169 	enum re_state : unsigned
170 	{
171 		IDLE,
172 		EXECUTE,
173 		DMA_R,
174 		DMA_W,
175 	}
176 	m_state;
177 	bool m_ir_pending;
178 
179 	// line state
180 	bool m_rdy;
181 	bool m_drq;
182 
183 	// registers
184 	u32 m_reg[64];
185 
186 	// active command state
187 	bool m_enabrgb;
188 	bool m_bigendian;
189 	u32 m_func[4];
190 	// haddr
191 	bool m_nopup;
192 	// xyfrac
193 	unsigned m_pupdata;
194 	u32 m_pat;
195 	s32 m_dz;
196 	s32 m_dr;
197 	s32 m_dg;
198 	s32 m_db;
199 	s64 m_z;
200 	u32 m_r;
201 	u32 m_g;
202 	u32 m_b;
203 	u16 m_stip;
204 	u8 m_stipcount;
205 	s32 m_dx;
206 	s32 m_dy;
207 	unsigned m_numpix;
208 	u32 m_x;
209 	u32 m_y;
210 	unsigned m_ir;
211 
212 	rectangle m_clip;
213 
214 	std::unique_ptr<u32[]> m_vram;
215 	std::unique_ptr<u32[]> m_dram;
216 	u32 m_vram_mask;
217 	u32 m_dram_mask;
218 };
219 
220 DECLARE_DEVICE_TYPE(SGI_RE2, sgi_re2_device)
221 
222 #endif // MAME_VIDEO_SGI_RE2_H
223