]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/sgi/screen.c
devarch: restrict i/o port access to 64K, disallow msr 32-bit wrap arround (thanks...
[plan9front.git] / sys / src / 9 / sgi / screen.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8
9 #define Image   IMAGE
10 #include <draw.h>
11 #include <memdraw.h>
12 #include <cursor.h>
13 #include "screen.h"
14
15 /*
16  * Register constant below from XFree86 driver.
17  */ 
18
19 #define DM1_PLANES         0x00000007
20 #define    DM1_NOPLANES    0x00000000
21 #define    DM1_RGBPLANES   0x00000001
22 #define    DM1_RGBAPLANES  0x00000002
23 #define    DM1_OLAYPLANES  0x00000004
24 #define    DM1_PUPPLANES   0x00000005
25 #define    DM1_CIDPLANES   0x00000006
26         
27 #define NPORT_DMODE1_DDMASK      0x00000018
28 #define NPORT_DMODE1_DD4         0x00000000
29 #define NPORT_DMODE1_DD8         0x00000008
30 #define NPORT_DMODE1_DD12        0x00000010
31 #define NPORT_DMODE1_DD24        0x00000018
32 #define NPORT_DMODE1_DSRC        0x00000020
33 #define NPORT_DMODE1_YFLIP       0x00000040
34 #define NPORT_DMODE1_RWPCKD      0x00000080
35 #define NPORT_DMODE1_HDMASK      0x00000300
36 #define NPORT_DMODE1_HD4         0x00000000
37 #define NPORT_DMODE1_HD8         0x00000100
38 #define NPORT_DMODE1_HD12        0x00000200
39 #define NPORT_DMODE1_HD32        0x00000300
40 #define NPORT_DMODE1_RWDBL       0x00000400
41 #define NPORT_DMODE1_ESWAP       0x00000800 /* Endian swap */
42 #define NPORT_DMODE1_CCMASK      0x00007000
43 #define NPORT_DMODE1_CCLT        0x00001000
44 #define NPORT_DMODE1_CCEQ        0x00002000
45 #define NPORT_DMODE1_CCGT        0x00004000
46 #define NPORT_DMODE1_RGBMD       0x00008000
47 #define NPORT_DMODE1_DENAB       0x00010000 /* Dither enable */
48 #define NPORT_DMODE1_FCLR        0x00020000 /* Fast clear */
49 #define NPORT_DMODE1_BENAB       0x00040000 /* Blend enable */
50 #define NPORT_DMODE1_SFMASK      0x00380000
51 #define NPORT_DMODE1_SF0         0x00000000
52 #define NPORT_DMODE1_SF1         0x00080000
53 #define NPORT_DMODE1_SFDC        0x00100000
54 #define NPORT_DMODE1_SFMDC       0x00180000
55 #define NPORT_DMODE1_SFSA        0x00200000
56 #define NPORT_DMODE1_SFMSA       0x00280000
57 #define NPORT_DMODE1_DFMASK      0x01c00000
58 #define NPORT_DMODE1_DF0         0x00000000
59 #define NPORT_DMODE1_DF1         0x00400000
60 #define NPORT_DMODE1_DFSC        0x00800000
61 #define NPORT_DMODE1_DFMSC       0x00c00000
62 #define NPORT_DMODE1_DFSA        0x01000000
63 #define NPORT_DMODE1_DFMSA       0x01400000
64 #define NPORT_DMODE1_BBENAB      0x02000000 /* Back blend enable */
65 #define NPORT_DMODE1_PFENAB      0x04000000 /* Pre-fetch enable */
66 #define NPORT_DMODE1_ABLEND      0x08000000 /* Alpha blend */
67 #define NPORT_DMODE1_LOMASK      0xf0000000
68 #define NPORT_DMODE1_LOZERO      0x00000000
69 #define NPORT_DMODE1_LOAND       0x10000000
70 #define NPORT_DMODE1_LOANDR      0x20000000
71 #define NPORT_DMODE1_LOSRC       0x30000000
72 #define NPORT_DMODE1_LOANDI      0x40000000
73 #define NPORT_DMODE1_LODST       0x50000000
74 #define NPORT_DMODE1_LOXOR       0x60000000
75 #define NPORT_DMODE1_LOOR        0x70000000
76 #define NPORT_DMODE1_LONOR       0x80000000
77 #define NPORT_DMODE1_LOXNOR      0x90000000
78 #define NPORT_DMODE1_LONDST      0xa0000000
79 #define NPORT_DMODE1_LOORR       0xb0000000
80 #define NPORT_DMODE1_LONSRC      0xc0000000
81 #define NPORT_DMODE1_LOORI       0xd0000000
82 #define NPORT_DMODE1_LONAND      0xe0000000
83 #define NPORT_DMODE1_LOONE       0xf0000000
84
85         /* These bits define the graphics opcode being performed. */
86 #define NPORT_DMODE0_OPMASK   0x00000003 /* Opcode mask */
87 #define NPORT_DMODE0_NOP      0x00000000 /* No operation */
88 #define NPORT_DMODE0_RD       0x00000001 /* Read operation */
89 #define NPORT_DMODE0_DRAW     0x00000002 /* Draw operation */
90 #define NPORT_DMODE0_S2S      0x00000003 /* Screen to screen operation */
91
92         /* The following decide what addressing mode(s) are to be used */
93 #define NPORT_DMODE0_AMMASK   0x0000001c /* Address mode mask */
94 #define NPORT_DMODE0_SPAN     0x00000000 /* Spanning address mode */
95 #define NPORT_DMODE0_BLOCK    0x00000004 /* Block address mode */
96 #define NPORT_DMODE0_ILINE    0x00000008 /* Iline address mode */
97 #define NPORT_DMODE0_FLINE    0x0000000c /* Fline address mode */
98 #define NPORT_DMODE0_ALINE    0x00000010 /* Aline address mode */
99 #define NPORT_DMODE0_TLINE    0x00000014 /* Tline address mode */
100 #define NPORT_DMODE0_BLINE    0x00000018 /* Bline address mode */
101
102         /* And now some misc. operation control bits. */
103 #define NPORT_DMODE0_DOSETUP  0x00000020
104 #define NPORT_DMODE0_CHOST    0x00000040
105 #define NPORT_DMODE0_AHOST    0x00000080
106 #define NPORT_DMODE0_STOPX    0x00000100
107 #define NPORT_DMODE0_STOPY    0x00000200
108 #define NPORT_DMODE0_SK1ST    0x00000400
109 #define NPORT_DMODE0_SKLST    0x00000800
110 #define NPORT_DMODE0_ZPENAB   0x00001000
111 #define NPORT_DMODE0_LISPENAB 0x00002000
112 #define NPORT_DMODE0_LISLST   0x00004000
113 #define NPORT_DMODE0_L32      0x00008000
114 #define NPORT_DMODE0_ZOPQ     0x00010000
115 #define NPORT_DMODE0_LISOPQ   0x00020000
116 #define NPORT_DMODE0_SHADE    0x00040000
117 #define NPORT_DMODE0_LRONLY   0x00080000
118 #define NPORT_DMODE0_XYOFF    0x00100000
119 #define NPORT_DMODE0_CLAMP    0x00200000
120 #define NPORT_DMODE0_ENDPF    0x00400000
121 #define NPORT_DMODE0_YSTR     0x00800000
122
123 #define NPORT_LSMODE_REPMASK  0x0000ff00
124 #define NPORT_LSMODE_LENMASK  0x0f000000
125
126 #define NPORT_DMODE_WMASK   0x00000003  /* dataWidth of data being transfered */
127 #define NPORT_DMODE_W4      0x00000000
128 #define NPORT_DMODE_W1      0x00000001
129 #define NPORT_DMODE_W2      0x00000002
130 #define NPORT_DMODE_W3      0x00000003
131 #define NPORT_DMODE_EDPACK  0x00000004
132 #define NPORT_DMODE_ECINC   0x00000008
133 #define NPORT_DMODE_CMASK   0x00000070
134 #define NPORT_DMODE_AMASK   0x00000780
135 #define NPORT_DMODE_AVC2    0x00000000
136 #define NPORT_DMODE_ACMALL  0x00000080
137 #define NPORT_DMODE_ACM0    0x00000100
138 #define NPORT_DMODE_ACM1    0x00000180
139 #define NPORT_DMODE_AXMALL  0x00000200
140 #define NPORT_DMODE_AXM0    0x00000280
141 #define NPORT_DMODE_AXM1    0x00000300
142 #define NPORT_DMODE_ABT     0x00000380
143 #define NPORT_DMODE_AVCC1   0x00000400
144 #define NPORT_DMODE_AVAB1   0x00000480
145 #define NPORT_DMODE_ALG3V0  0x00000500
146 #define NPORT_DMODE_A1562   0x00000580
147 #define NPORT_DMODE_ESACK   0x00000800
148 #define NPORT_DMODE_EASACK  0x00001000
149 #define NPORT_DMODE_CWMASK  0x0003e000
150 #define NPORT_DMODE_CHMASK  0x007c0000
151 #define NPORT_DMODE_CSMASK  0x0f800000
152 #define NPORT_DMODE_SENDIAN 0x10000000
153
154 #define NPORT_SMASKXOFF         4096
155 #define NPORT_SMASKYOFF         4096
156 #define NPORT_CMODE_SM0   0x00000001
157 #define NPORT_CMODE_SM1   0x00000002
158 #define NPORT_CMODE_SM2   0x00000004
159 #define NPORT_CMODE_SM3   0x00000008
160 #define NPORT_CMODE_SM4   0x00000010
161 #define NPORT_CMODE_CMSK  0x00001e00
162
163 #define NPORT_CFG_G32MD   0x00000001
164 #define NPORT_CFG_BWIDTH  0x00000002
165 #define NPORT_CFG_ERCVR   0x00000004
166 #define NPORT_CFG_BDMSK   0x00000078
167 #define NPORT_CFG_BFAINT  0x00000080
168 #define NPORT_CFG_GDMSK   0x00001f00
169 #define NPORT_CFG_GD0     0x00000100
170 #define NPORT_CFG_GD1     0x00000200
171 #define NPORT_CFG_GD2     0x00000400
172 #define NPORT_CFG_GD3     0x00000800
173 #define NPORT_CFG_GD4     0x00001000
174 #define NPORT_CFG_GFAINT  0x00002000
175 #define NPORT_CFG_TOMSK   0x0001C000
176 #define NPORT_CFG_VRMSK   0x000E0000
177 #define NPORT_CFG_FBTYP   0x00100000
178
179 #define NPORT_STAT_VERS   0x00000007
180 #define NPORT_STAT_GBUSY  0x00000008
181 #define NPORT_STAT_BBUSY  0x00000010
182 #define NPORT_STAT_VRINT  0x00000020
183 #define NPORT_STAT_VIDINT 0x00000040
184 #define NPORT_STAT_GLMSK  0x00001f80
185 #define NPORT_STAT_BLMSK  0x0007e000
186 #define NPORT_STAT_BFIRQ  0x00080000
187 #define NPORT_STAT_GFIRQ  0x00100000
188
189 /* Reading/writing VC2 registers. */
190 #define VC2_REGADDR_INDEX      0x00000000
191 #define VC2_REGADDR_IREG       0x00000010
192 #define VC2_REGADDR_RAM        0x00000030
193 #define VC2_PROTOCOL           (NPORT_DMODE_EASACK | 0x00800000 | 0x00040000)
194
195 #define VC2_VLINET_ADDR        0x000
196 #define VC2_VFRAMET_ADDR       0x400
197 #define VC2_CGLYPH_ADDR        0x500
198
199 /* Now the Indexed registers of the VC2. */
200 #define VC2_IREG_VENTRY        0x00
201 #define VC2_IREG_CENTRY        0x01
202 #define VC2_IREG_CURSX         0x02
203 #define VC2_IREG_CURSY         0x03
204 #define VC2_IREG_CCURSX        0x04
205 #define VC2_IREG_DENTRY        0x05
206 #define VC2_IREG_SLEN          0x06
207 #define VC2_IREG_RADDR         0x07
208 #define VC2_IREG_VFPTR         0x08
209 #define VC2_IREG_VLSPTR        0x09
210 #define VC2_IREG_VLIR          0x0a
211 #define VC2_IREG_VLCTR         0x0b
212 #define VC2_IREG_CTPTR         0x0c
213 #define VC2_IREG_WCURSY        0x0d
214 #define VC2_IREG_DFPTR         0x0e
215 #define VC2_IREG_DLTPTR        0x0f
216 #define VC2_IREG_CONTROL       0x10
217 #define VC2_IREG_CONFIG        0x20
218
219 /* VC2 Control register bits */
220 #define VC2_CTRL_EVIRQ     0x0001
221 #define VC2_CTRL_EDISP     0x0002
222 #define VC2_CTRL_EVIDEO    0x0004
223 #define VC2_CTRL_EDIDS     0x0008
224 #define VC2_CTRL_ECURS     0x0010
225 #define VC2_CTRL_EGSYNC    0x0020
226 #define VC2_CTRL_EILACE    0x0040
227 #define VC2_CTRL_ECDISP    0x0080
228 #define VC2_CTRL_ECCURS    0x0100
229 #define VC2_CTRL_ECG64     0x0200
230 #define VC2_CTRL_GLSEL     0x0400
231
232 /* Controlling the color map on Newport. */
233 #define NCMAP_REGADDR_AREG   0x00000000
234 #define NCMAP_REGADDR_ALO    0x00000000         /* address register low  */
235 #define NCMAP_REGADDR_AHI    0x00000010         /* address register high */
236 #define NCMAP_REGADDR_PBUF   0x00000020         /* color palette buffer  */
237 #define NCMAP_REGADDR_CREG   0x00000030         /* command register      */
238 #define NCMAP_REGADDR_SREG   0x00000040         /* color buffer register */
239 #define NCMAP_REGADDR_RREG   0x00000060         /* revision register     */
240 #define NCMAP_PROTOCOL       (0x00008000 | 0x00040000 | 0x00800000)
241
242 /*
243  * DCBMODE register defines:
244  */
245
246 /* Widht of the data being transfered for each DCBDATA[01] word */
247 #define DCB_DATAWIDTH_4 0x0
248 #define DCB_DATAWIDTH_1 0x1
249 #define DCB_DATAWIDTH_2 0x2
250 #define DCB_DATAWIDTH_3 0x3
251
252 /* If set, all of DCBDATA will be moved, otherwise only DATAWIDTH bytes */
253 #define DCB_ENDATAPACK   (1 << 2)
254
255 /* Enables DCBCRS auto increment after each DCB transfer */
256 #define DCB_ENCRSINC     (1 << 3)
257
258 /* shift for accessing the control register select address (DBCCRS, 3 bits) */
259 #define DCB_CRS_SHIFT    4
260
261 /* DCBADDR (4 bits): display bus slave address */
262 #define DCB_ADDR_SHIFT   7
263 #define DCB_VC2          (0 <<  DCB_ADDR_SHIFT)
264 #define DCB_CMAP_ALL     (1 <<  DCB_ADDR_SHIFT)
265 #define DCB_CMAP0        (2 <<  DCB_ADDR_SHIFT)
266 #define DCB_CMAP1        (3 <<  DCB_ADDR_SHIFT)
267 #define DCB_XMAP_ALL     (4 <<  DCB_ADDR_SHIFT)
268 #define DCB_XMAP0        (5 <<  DCB_ADDR_SHIFT)
269 #define DCB_XMAP1        (6 <<  DCB_ADDR_SHIFT)
270 #define DCB_BT445        (7 <<  DCB_ADDR_SHIFT)
271 #define DCB_VCC1         (8 <<  DCB_ADDR_SHIFT)
272 #define DCB_VAB1         (9 <<  DCB_ADDR_SHIFT)
273 #define DCB_LG3_BDVERS0  (10 << DCB_ADDR_SHIFT)
274 #define DCB_LG3_ICS1562  (11 << DCB_ADDR_SHIFT)
275 #define DCB_RESERVED     (15 << DCB_ADDR_SHIFT)
276
277 /* DCB protocol ack types */
278 #define DCB_ENSYNCACK    (1 << 11)
279 #define DCB_ENASYNCACK   (1 << 12)
280
281 #define DCB_CSWIDTH_SHIFT 13
282 #define DCB_CSHOLD_SHIFT  18
283 #define DCB_CSSETUP_SHIFT 23
284
285 /* XMAP9 specific defines */
286 /*   XMAP9 -- registers as seen on the DCBMODE register*/
287 #   define XM9_CRS_CONFIG            (0 << DCB_CRS_SHIFT)
288 #       define XM9_PUPMODE           (1 << 0)
289 #       define XM9_ODD_PIXEL         (1 << 1)
290 #       define XM9_8_BITPLANES       (1 << 2)
291 #       define XM9_SLOW_DCB          (1 << 3)
292 #       define XM9_VIDEO_RGBMAP_MASK (3 << 4)
293 #       define XM9_VIDEO_RGBMAP_M0   (1 << 4)   
294 #       define XM9_VIDEO_RGMPAP_M1   (1 << 5)
295 #       define XM9_VIDEO_RGBMAP_M2   (3 << 4)
296 #       define XM9_EXPRESS_VIDEO     (1 << 6)
297 #       define XM9_VIDEO_OPTION      (1 << 7)
298 #   define XM9_CRS_REVISION          (1 << DCB_CRS_SHIFT)
299 #   define XM9_CRS_FIFO_AVAIL        (2 << DCB_CRS_SHIFT)
300 #       define XM9_FIFO_0_AVAIL      0
301 #       define XM9_FIFO_1_AVAIL      1
302 #       define XM9_FIFO_2_AVAIL      3
303 #       define XM9_FIFO_3_AVAIL      2
304 #       define XM9_FIFO_FULL         XM9_FIFO_0_AVAIL
305 #       define XM9_FIFO_EMPTY        XM9_FIFO_3_AVAIL
306 #   define XM9_CRS_CURS_CMAP_MSB     (3 << DCB_CRS_SHIFT)
307 #   define XM9_CRS_PUP_CMAP_MSB      (4 << DCB_CRS_SHIFT)
308 #   define XM9_CRS_MODE_REG_DATA     (5 << DCB_CRS_SHIFT)
309 #   define XM9_CRS_MODE_REG_INDEX    (7 << DCB_CRS_SHIFT)
310
311
312 #define DCB_CYCLES(setup,hold,width)                \
313                   ((hold << DCB_CSHOLD_SHIFT)  |    \
314                    (setup << DCB_CSSETUP_SHIFT)|    \
315                    (width << DCB_CSWIDTH_SHIFT))
316
317 #define W_DCB_XMAP9_PROTOCOL       DCB_CYCLES (2, 1, 0)
318 #define WSLOW_DCB_XMAP9_PROTOCOL   DCB_CYCLES (5, 5, 0)
319 #define WAYSLOW_DCB_XMAP9_PROTOCOL DCB_CYCLES (12, 12, 0)
320 #define R_DCB_XMAP9_PROTOCOL       DCB_CYCLES (2, 1, 3)
321
322 /* xmap9 mode register layout */
323 #define XM9_MREG_BUF_SEL        (1 << 0)
324 #define XM9_MREG_OVL_BUF_SEL    (1 << 1)        
325 #define XM9_MREG_GAMMA_BYPASS   (1 << 2)
326 #define XM9_MREG_MSB_CMAP       (31 << 3)
327 #define XM9_MREG_PIX_MODE_MASK  (3 << 8)
328 #define XM9_MREG_PIX_MODE_RGB0  (1 << 8)
329 #define XM9_MREG_PIX_MODE_RGB1  (1 << 9)
330 #define XM9_MREG_PIX_MODE_RGB2  (3 << 8)
331 #define XM9_MREG_PIX_SIZE_MASK  (3 << 10)
332 #define XM9_MREG_PIX_SIZE_8BPP  (1 << 10)
333 #define XM9_MREG_PIX_SIZE_12BPP (1 << 11)
334 #define XM9_MREG_PIX_SIZE_24BPP (3 << 10)
335 #define XM9_MREG_VID_MODE_MASK  (3 << 12)
336 #define XM9_MREG_VID_MODE_OVL   (1 << 12)
337 #define XM9_MREG_VID_MODE_UDL   (1 << 13)
338 #define XM9_MREG_VID_MODE_RPL   (3 << 12)
339 #define XM9_MREG_BUF_VID_ALPHA  (1 << 15)
340 #define XM9_MREG_APIX_MODE_MASK (7 << 16)
341 #define XM9_MREG_APIX_MODE_FUDL (1 << 16)
342 #define XM9_MREG_APIX_MODE_FOVL (1 << 17)
343 #define XM9_MREG_APIX_MODE_ODB  (3 << 17)
344 #define XM9_MREG_APIX_MODE_BOTH (7 << 16)
345 #define XM9_MREG_AMSB_CMAP_MASK (31 << 19)
346
347
348 typedef struct Newport Newport;
349 struct Newport
350 {
351         ulong   drawmode1;
352         ulong   drawmode0;
353         ulong   lsmode;
354         ulong   lspattern;
355         ulong   lspatsave;
356         ulong   zpattern;
357         ulong   colorback;
358         ulong   colorvram;
359         ulong   alpharef;
360         ulong   unused0;
361         ulong   smask0x;
362         ulong   smask0y;
363         ulong   _setup;
364         ulong   _stepz;
365         ulong   _lsrestore;
366         ulong   _lssave;
367         ulong   unused1[0x30];
368         ulong   _xstart;
369         ulong   _ystart;
370         ulong   _xend;
371         ulong   _yend;
372         ulong   xsave;
373         ulong   xymode;
374         ulong   bresd;
375         ulong   bress1;
376         ulong   bresoctinc1;
377         ulong   bresoctinc2;
378         ulong   brese1;
379         ulong   bress2;
380         ulong   aweight0;
381         ulong   aweight1;
382         ulong   xstartf;
383         ulong   ystartf;
384         ulong   xendf;
385         ulong   yendf;
386         ulong   xstarti;
387         ulong   xendfi;
388         ulong   xystarti;
389         ulong   xyendi;
390         ulong   xstartendi;
391         ulong   unused2[0x29];
392         ulong   colorred;
393         ulong   coloralpha;
394         ulong   colorgrn;
395         ulong   colorblue;
396         ulong   slopered;
397         ulong   slopealpha;
398         ulong   slopegrn;
399         ulong   slopeblue;
400         ulong   wrmask;
401         ulong   colori;
402         ulong   colorx;
403         ulong   slopered1;
404         ulong   hostrw0;
405         ulong   hostrw1;
406         ulong   dcbmode;
407         ulong   unused3;
408         ulong   dcbdata0;
409         ulong   dcbdata1;
410         ulong   unused4[0x36e];
411         ulong   smask1x;
412         ulong   smask1y;
413         ulong   smask2x;
414         ulong   smask2y;
415         ulong   smask3x;
416         ulong   smask3y;
417         ulong   smask4x;
418         ulong   smask4y;
419         ulong   topscan;
420         ulong   xywin;
421         ulong   clipmode;
422         ulong   unused5;
423         ulong   config;
424         ulong   unused6;
425         ulong   stat;
426         ulong   ustat;
427         ulong   dreset;
428 };
429
430 static Newport *regs = IO(Newport, GIO_NEWPORT);
431 static Newport *regsgo = IO(Newport, GIO_NEWPORT|0x800);
432
433 Memimage *gscreen;
434 static Point curoff;
435
436 static void 
437 vc2set(uchar r, ushort val)
438 {
439         regs->dcbmode = NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX |
440                 NPORT_DMODE_W3 | NPORT_DMODE_ECINC | VC2_PROTOCOL;
441         regs->dcbdata0 = r << 24 | val << 8;
442 }
443
444 static ushort
445 vc2get(uchar r)
446 {
447         regs->dcbmode = NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX |
448                 NPORT_DMODE_W1 | NPORT_DMODE_ECINC | VC2_PROTOCOL;
449         regs->dcbdata0 = r << 24;
450         regs->dcbmode = NPORT_DMODE_AVC2 | VC2_REGADDR_IREG |
451                 NPORT_DMODE_W2 | NPORT_DMODE_ECINC | VC2_PROTOCOL;
452         return regs->dcbdata0 >> 16;
453 }
454
455
456 void
457 cursoron(void)
458 {
459         Point xy;
460         int s;
461
462         xy = addpt(mousexy(), curoff);
463
464         s = splhi();
465         vc2set(VC2_IREG_CURSX, xy.x);
466         vc2set(VC2_IREG_CURSY, xy.y);
467         vc2set(VC2_IREG_CONTROL, vc2get(VC2_IREG_CONTROL) | VC2_CTRL_ECDISP);
468         splx(s);
469 }
470
471 void
472 cursoroff(void)
473 {
474         int s;
475
476         s = splhi();
477         vc2set(VC2_IREG_CONTROL, vc2get(VC2_IREG_CONTROL) & ~VC2_CTRL_ECDISP);
478         splx(s);
479 }
480
481 void
482 setcursor(Cursor *curs)
483 {
484         static uchar mem[(2*32*32)/8];
485         uchar *set, *clr;
486         int i, s;
487
488         memset(mem, 0, sizeof(mem));
489
490         /*
491          * convert to two 32x32 bitmaps
492          */
493         set = mem;
494         clr = mem + (32*32)/8;
495         for(i=0;i<32;i++) {
496                 *set++ = curs->set[i];
497                 *clr++ = curs->clr[i];
498                 if(i & 1){
499                         set += 2;
500                         clr += 2;
501                 }
502         }
503         curoff = addpt(Pt(30,30), curs->offset);
504
505         /*
506          * upload two bytes at a time
507          */
508         s = splhi();
509         vc2set(VC2_IREG_RADDR, vc2get(VC2_IREG_CENTRY));
510         regs->dcbmode = NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
511                 NPORT_DMODE_W2 | VC2_PROTOCOL;
512         for(i = 0; i < sizeof(mem); i += 2){
513                 while(regs->stat & NPORT_STAT_BBUSY)
514                         ;
515                 regs->dcbdata0 = *(ushort*)(&mem[i]) << 16;
516         }
517         splx(s);
518 }       
519
520 static void
521 setmode(void)
522 {
523         while(regs->stat & NPORT_STAT_BBUSY)
524                 ;
525         regs->dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL |
526                 XM9_CRS_CONFIG | NPORT_DMODE_W1);
527         regs->dcbdata0 &= ~((XM9_8_BITPLANES | XM9_PUPMODE)<<24);
528
529         while(regs->stat & NPORT_STAT_BBUSY)
530                 ;
531         regs->dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL |
532                 XM9_CRS_MODE_REG_DATA | NPORT_DMODE_W4);
533         regs->dcbdata0 = (XM9_MREG_PIX_SIZE_24BPP | 
534                 XM9_MREG_PIX_MODE_RGB1 | XM9_MREG_GAMMA_BYPASS);
535
536         while(regs->stat & NPORT_STAT_BBUSY)
537                 ;
538         regs->dcbmode = (DCB_XMAP_ALL | W_DCB_XMAP9_PROTOCOL |
539                 XM9_CRS_MODE_REG_INDEX | NPORT_DMODE_W1);
540         regs->dcbdata0 &= ~(0xFF<<24);
541
542         regs->drawmode1 = DM1_RGBPLANES | 
543                 NPORT_DMODE1_CCLT | NPORT_DMODE1_CCEQ | NPORT_DMODE1_CCGT | NPORT_DMODE1_LOSRC |
544                 NPORT_DMODE1_DD24 | NPORT_DMODE1_RGBMD | NPORT_DMODE1_HD32 | NPORT_DMODE1_RWPCKD;
545 }
546
547 static void
548 arcsoff(void)
549 {
550         if(consuart != nil && consuart->console && strcmp(consuart->name, "arcs") == 0){
551                 consuart = nil;
552                 serialoq = nil;
553         }
554 }
555
556 void
557 flushmemscreen(Rectangle r)
558 {
559         static int modeset = 0;
560         ulong *x0;
561         int s, w;
562
563         if(rectclip(&r, gscreen->r) == 0)
564                 return;
565
566         s = splhi();
567         if(!modeset){
568                 modeset = 1;
569                 arcsoff();
570                 setmode();
571         }
572
573         while(regs->stat & NPORT_STAT_GBUSY)
574                 ;
575
576         regs->drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK | NPORT_DMODE0_CHOST);
577         regs->xystarti = r.min.x << 16 | r.min.y;
578         regs->xyendi = r.max.x-1 << 16 | r.max.y-1;
579
580         x0 = wordaddr(gscreen, r.min); 
581         for(w = r.max.x - r.min.x; r.min.y < r.max.y; r.min.y++){
582                 outl(&regsgo->hostrw0, x0, w);
583                 x0 += gscreen->width;
584         }
585
586         splx(s);
587 }
588
589 void
590 screeninit(void)
591 {
592         enum {
593                 RGBX32 = CHAN4(CRed, 8, CGreen, 8, CBlue, 8, CIgnore, 8),
594         };
595         memimageinit();
596         gscreen = allocmemimage(Rect(0,0,1280,1024), RGBX32);
597         if(gscreen == nil)
598                 panic("screeninit: gscreen == nil");
599         memfillcolor(gscreen, 0xFFFFFFFF);
600         mouseaccelerate(3);
601 }
602
603 uchar*
604 attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen)
605 {
606         *r = gscreen->r;
607         *d = gscreen->depth;
608         *chan = gscreen->chan;
609         *width = gscreen->width;
610
611         /* make devdraw use gscreen->data */
612         *softscreen = 0xa110c;
613         gscreen->data->ref++;
614
615         return gscreen->data->bdata;
616 }
617
618 void
619 getcolor(ulong, ulong *, ulong *, ulong *)
620 {
621 }
622
623 int
624 setcolor(ulong, ulong, ulong, ulong)
625 {
626         return 0;
627 }
628
629 void
630 blankscreen(int)
631 {
632 }
633
634 void
635 mousectl(Cmdbuf *)
636 {
637 }
638
639 /*
640  * sgi mouse protocol
641  *      byte 0 -        Y0 X0 Y7 X7  F  M  R  L
642  *      byte 1 -        X7 X6 X5 X4 X3 X2 X1 X0
643  *      byte 2 -        Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
644  */
645 void
646 sgimouseputc(int c)
647 {
648         static uchar msg[3];
649         static int nb;
650         int dx, dy, newbuttons;
651         static uchar b[] = { 0, 1, 4, 5, 2, 3, 6, 7 };
652         static ulong lasttick;
653         ulong m;
654
655         /* Resynchronize in stream with timing. */
656         m = MACHP(0)->ticks;
657         if(TK2SEC(m - lasttick) > 2)
658                 nb = 0;
659         lasttick = m;
660
661         msg[nb] = c;
662         if(++nb == 3){
663                 nb = 0;
664                 newbuttons = b[msg[0]&7];
665                 dx = (char)msg[1];
666                 dy = -(char)msg[2];
667                 mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
668         }
669 }