1 /*
2 * Copyright (c) 1991 University of Utah.
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department and Mark Davies of the Department of Computer
9 * Science, Victoria University of Wellington, New Zealand.
10 *
11 * %sccs.include.redist.c%
12 *
13 * from: Utah $Hdr: ite_hy.c 1.2 92/12/20$
14 *
15 * @(#)ite_hy.c 8.1 (Berkeley) 06/10/93
16 */
17
18 #include "ite.h"
19 #if NITE > 0
20
21 #include <sys/param.h>
22 #include <sys/conf.h>
23 #include <sys/proc.h>
24 #include <sys/ioctl.h>
25 #include <sys/tty.h>
26 #include <sys/systm.h>
27 #include <sys/uio.h>
28
29 #include <hp300/dev/grf_hyreg.h>
30 #include <hp/dev/itereg.h>
31 #include <hp/dev/itevar.h>
32
33 #include <machine/cpu.h>
34
35 /* XXX */
36 #include <hp/dev/grfioctl.h>
37 #include <hp/dev/grfvar.h>
38
39 #define REGBASE ((struct hyboxfb *)(ip->regbase))
40 #define WINDOWMOVER hyper_windowmove
41
42 #undef charX
43 #define charX(ip,c) \
44 (((c) % (ip)->cpl) * ((((ip)->ftwidth + 7) / 8) * 8) + (ip)->fontx)
45
hyper_init(ip)46 hyper_init(ip)
47 register struct ite_softc *ip;
48 {
49 int width;
50
51 /* XXX */
52 if (ip->regbase == NULL) {
53 struct grf_softc *gp = ip->grf;
54
55 ip->regbase = gp->g_regkva;
56 ip->fbbase = gp->g_fbkva;
57 ip->fbwidth = gp->g_display.gd_fbwidth;
58 ip->fbheight = gp->g_display.gd_fbheight;
59 ip->dwidth = gp->g_display.gd_dwidth;
60 ip->dheight = gp->g_display.gd_dheight;
61 }
62
63 ite_fontinfo(ip);
64 width = ((ip->ftwidth + 7) / 8) * 8;
65 ip->cpl = (ip->fbwidth - ip->dwidth) / width;
66 ip->cblanky = ip->fonty + ((128 / ip->cpl) +1) * ip->ftheight;
67
68 /*
69 * Clear the framebuffer on all planes.
70 */
71 hyper_windowmove(ip, 0, 0, 0, 0, ip->fbheight, ip->fbwidth, RR_CLEAR);
72
73 hyper_ite_fontinit(ip);
74
75 REGBASE->nblank = 0x05;
76
77 /*
78 * Stash the inverted cursor.
79 */
80 hyper_windowmove(ip, charY(ip, ' '), charX(ip, ' '),
81 ip->cblanky, ip->cblankx, ip->ftheight,
82 ip->ftwidth, RR_COPYINVERTED);
83 }
84
hyper_deinit(ip)85 hyper_deinit(ip)
86 register struct ite_softc *ip;
87 {
88 hyper_windowmove(ip, 0, 0, 0, 0, ip->fbheight, ip->fbwidth, RR_CLEAR);
89
90 REGBASE->nblank = 0x05;
91 ip->flags &= ~ITE_INITED;
92 }
93
hyper_ite_fontinit(ip)94 hyper_ite_fontinit(ip)
95 register struct ite_softc *ip;
96 {
97 register u_char *fbmem, *dp;
98 int c, l, b;
99 int stride, width;
100
101 dp = (u_char *)(getword(ip, getword(ip, FONTROM) + FONTADDR) +
102 ip->regbase) + FONTDATA;
103 stride = ip->fbwidth >> 3;
104 width = (ip->ftwidth + 7) / 8;
105
106 for (c = 0; c < 128; c++) {
107 fbmem = (u_char *) FBBASE +
108 (ip->fonty + (c / ip->cpl) * ip->ftheight) *
109 stride;
110 fbmem += (ip->fontx >> 3) + (c % ip->cpl) * width;
111 for (l = 0; l < ip->ftheight; l++) {
112 for (b = 0; b < width; b++) {
113 *fbmem++ = *dp;
114 dp += 2;
115 }
116 fbmem -= width;
117 fbmem += stride;
118 }
119 }
120 }
121
hyper_putc(ip,c,dy,dx,mode)122 hyper_putc(ip, c, dy, dx, mode)
123 register struct ite_softc *ip;
124 int c, dy, dx, mode;
125 {
126 int wmrr = ((mode == ATTR_INV) ? RR_COPYINVERTED : RR_COPY);
127
128 hyper_windowmove(ip, charY(ip, c), charX(ip, c),
129 dy * ip->ftheight, dx * ip->ftwidth,
130 ip->ftheight, ip->ftwidth, wmrr);
131 }
132
hyper_cursor(ip,flag)133 hyper_cursor(ip, flag)
134 register struct ite_softc *ip;
135 register int flag;
136 {
137 if (flag == DRAW_CURSOR)
138 draw_cursor(ip)
139 else if (flag == MOVE_CURSOR) {
140 erase_cursor(ip)
141 draw_cursor(ip)
142 }
143 else
144 erase_cursor(ip)
145 }
146
hyper_clear(ip,sy,sx,h,w)147 hyper_clear(ip, sy, sx, h, w)
148 register struct ite_softc *ip;
149 register int sy, sx, h, w;
150 {
151 hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
152 sy * ip->ftheight, sx * ip->ftwidth,
153 h * ip->ftheight, w * ip->ftwidth,
154 RR_CLEAR);
155 }
156
hyper_scroll(ip,sy,sx,count,dir)157 hyper_scroll(ip, sy, sx, count, dir)
158 register struct ite_softc *ip;
159 register int sy, count;
160 int dir, sx;
161 {
162 register int dy;
163 register int dx = sx;
164 register int height = 1;
165 register int width = ip->cols;
166
167 if (dir == SCROLL_UP) {
168 dy = sy - count;
169 height = ip->rows - sy;
170 }
171 else if (dir == SCROLL_DOWN) {
172 dy = sy + count;
173 height = ip->rows - dy - 1;
174 }
175 else if (dir == SCROLL_RIGHT) {
176 dy = sy;
177 dx = sx + count;
178 width = ip->cols - dx;
179 }
180 else {
181 dy = sy;
182 dx = sx - count;
183 width = ip->cols - sx;
184 }
185
186 hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
187 dy * ip->ftheight, dx * ip->ftwidth,
188 height * ip->ftheight,
189 width * ip->ftwidth, RR_COPY);
190 }
191
192 #include <hp300/dev/maskbits.h>
193
194 /* NOTE:
195 * the first element in starttab could be 0xffffffff. making it 0
196 * lets us deal with a full first word in the middle loop, rather
197 * than having to do the multiple reads and masks that we'd
198 * have to do if we thought it was partial.
199 */
200 int starttab[32] =
201 {
202 0x00000000,
203 0x7FFFFFFF,
204 0x3FFFFFFF,
205 0x1FFFFFFF,
206 0x0FFFFFFF,
207 0x07FFFFFF,
208 0x03FFFFFF,
209 0x01FFFFFF,
210 0x00FFFFFF,
211 0x007FFFFF,
212 0x003FFFFF,
213 0x001FFFFF,
214 0x000FFFFF,
215 0x0007FFFF,
216 0x0003FFFF,
217 0x0001FFFF,
218 0x0000FFFF,
219 0x00007FFF,
220 0x00003FFF,
221 0x00001FFF,
222 0x00000FFF,
223 0x000007FF,
224 0x000003FF,
225 0x000001FF,
226 0x000000FF,
227 0x0000007F,
228 0x0000003F,
229 0x0000001F,
230 0x0000000F,
231 0x00000007,
232 0x00000003,
233 0x00000001
234 };
235
236 int endtab[32] =
237 {
238 0x00000000,
239 0x80000000,
240 0xC0000000,
241 0xE0000000,
242 0xF0000000,
243 0xF8000000,
244 0xFC000000,
245 0xFE000000,
246 0xFF000000,
247 0xFF800000,
248 0xFFC00000,
249 0xFFE00000,
250 0xFFF00000,
251 0xFFF80000,
252 0xFFFC0000,
253 0xFFFE0000,
254 0xFFFF0000,
255 0xFFFF8000,
256 0xFFFFC000,
257 0xFFFFE000,
258 0xFFFFF000,
259 0xFFFFF800,
260 0xFFFFFC00,
261 0xFFFFFE00,
262 0xFFFFFF00,
263 0xFFFFFF80,
264 0xFFFFFFC0,
265 0xFFFFFFE0,
266 0xFFFFFFF0,
267 0xFFFFFFF8,
268 0xFFFFFFFC,
269 0xFFFFFFFE
270 };
271
272 hyper_windowmove(ip, sy, sx, dy, dx, h, w, func)
273 struct ite_softc *ip;
274 int sy, sx, dy, dx, h, w, func;
275 {
276 int width; /* add to get to same position in next line */
277
278 unsigned int *psrcLine, *pdstLine;
279 /* pointers to line with current src and dst */
280 register unsigned int *psrc; /* pointer to current src longword */
281 register unsigned int *pdst; /* pointer to current dst longword */
282
283 /* following used for looping through a line */
284 unsigned int startmask, endmask; /* masks for writing ends of dst */
285 int nlMiddle; /* whole longwords in dst */
286 register int nl; /* temp copy of nlMiddle */
287 register unsigned int tmpSrc;
288 /* place to store full source word */
289 register int xoffSrc; /* offset (>= 0, < 32) from which to
290 fetch whole longwords fetched
291 in src */
292 int nstart; /* number of ragged bits at start of dst */
293 int nend; /* number of ragged bits at end of dst */
294 int srcStartOver; /* pulling nstart bits from src
295 overflows into the next word? */
296
297 if (h == 0 || w == 0)
298 return;
299
300 width = ip->fbwidth >> 5;
301
302 if (sy < dy) /* start at last scanline of rectangle */
303 {
304 psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width);
305 pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width);
306 width = -width;
307 }
308 else /* start at first scanline */
309 {
310 psrcLine = ((unsigned int *) ip->fbbase) + (sy * width);
311 pdstLine = ((unsigned int *) ip->fbbase) + (dy * width);
312 }
313
314 /* x direction doesn't matter for < 1 longword */
315 if (w <= 32)
316 {
317 int srcBit, dstBit; /* bit offset of src and dst */
318
319 pdstLine += (dx >> 5);
320 psrcLine += (sx >> 5);
321 psrc = psrcLine;
322 pdst = pdstLine;
323
324 srcBit = sx & 0x1f;
325 dstBit = dx & 0x1f;
326
327 while(h--)
328 {
329 getandputrop(psrc, srcBit, dstBit, w, pdst, func)
330 pdst += width;
331 psrc += width;
332 }
333 }
334 else
335 {
336 maskbits(dx, w, startmask, endmask, nlMiddle)
337 if (startmask)
338 nstart = 32 - (dx & 0x1f);
339 else
340 nstart = 0;
341 if (endmask)
342 nend = (dx + w) & 0x1f;
343 else
344 nend = 0;
345
346 xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
347 srcStartOver = ((sx & 0x1f) + nstart) > 31;
348
349 if (sx >= dx) /* move left to right */
350 {
351 pdstLine += (dx >> 5);
352 psrcLine += (sx >> 5);
353
354 while (h--)
355 {
356 psrc = psrcLine;
357 pdst = pdstLine;
358
359 if (startmask)
360 {
361 getandputrop(psrc, (sx & 0x1f),
362 (dx & 0x1f), nstart, pdst, func)
363 pdst++;
364 if (srcStartOver)
365 psrc++;
366 }
367
368 /* special case for aligned operations */
369 if (xoffSrc == 0)
370 {
371 nl = nlMiddle;
372 while (nl--)
373 {
374 DoRop (*pdst, func, *psrc++, *pdst);
375 pdst++;
376 }
377 }
378 else
379 {
380 nl = nlMiddle + 1;
381 while (--nl)
382 {
383 getunalignedword (psrc, xoffSrc, tmpSrc)
384 DoRop (*pdst, func, tmpSrc, *pdst);
385 pdst++;
386 psrc++;
387 }
388 }
389
390 if (endmask)
391 {
392 getandputrop0(psrc, xoffSrc, nend, pdst, func);
393 }
394
395 pdstLine += width;
396 psrcLine += width;
397 }
398 }
399 else /* move right to left */
400 {
401 pdstLine += (dx+w >> 5);
402 psrcLine += (sx+w >> 5);
403 /* if fetch of last partial bits from source crosses
404 a longword boundary, start at the previous longword
405 */
406 if (xoffSrc + nend >= 32)
407 --psrcLine;
408
409 while (h--)
410 {
411 psrc = psrcLine;
412 pdst = pdstLine;
413
414 if (endmask)
415 {
416 getandputrop0(psrc, xoffSrc, nend, pdst, func);
417 }
418
419 nl = nlMiddle + 1;
420 while (--nl)
421 {
422 --psrc;
423 --pdst;
424 getunalignedword(psrc, xoffSrc, tmpSrc)
425 DoRop(*pdst, func, tmpSrc, *pdst);
426 }
427
428 if (startmask)
429 {
430 if (srcStartOver)
431 --psrc;
432 --pdst;
433 getandputrop(psrc, (sx & 0x1f),
434 (dx & 0x1f), nstart, pdst, func)
435 }
436
437 pdstLine += width;
438 psrcLine += width;
439 }
440 } /* move right to left */
441 }
442 }
443 #endif
444