xref: /original-bsd/sys/hp300/dev/ite_hy.c (revision ea3a8ee8)
1 /*
2  * Copyright (c) 1991 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * 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	7.3 (Berkeley) 12/27/92
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 
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 
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 
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) + FONTDATA;
102 	stride = ip->fbwidth >> 3;
103 	width = (ip->ftwidth + 7) / 8;
104 
105 	for (c = 0; c < 128; c++) {
106 		fbmem = (u_char *) FBBASE +
107 			(ip->fonty + (c / ip->cpl) * ip->ftheight) *
108 			stride;
109 		fbmem += (ip->fontx >> 3) + (c % ip->cpl) * width;
110 		for (l = 0; l < ip->ftheight; l++) {
111 			for (b = 0; b < width; b++) {
112 				*fbmem++ = *dp;
113 				dp += 2;
114 			}
115 			fbmem -= width;
116 			fbmem += stride;
117 		}
118 	}
119 }
120 
121 hyper_putc(ip, c, dy, dx, mode)
122 	register struct ite_softc *ip;
123 	int c, dy, dx, mode;
124 {
125         int wmrr = ((mode == ATTR_INV) ? RR_COPYINVERTED : RR_COPY);
126 
127 	hyper_windowmove(ip, charY(ip, c), charX(ip, c),
128 			 dy * ip->ftheight, dx * ip->ftwidth,
129 			 ip->ftheight, ip->ftwidth, wmrr);
130 }
131 
132 hyper_cursor(ip, flag)
133 	register struct ite_softc *ip;
134 	register int flag;
135 {
136 	if (flag == DRAW_CURSOR)
137 		draw_cursor(ip)
138 	else if (flag == MOVE_CURSOR) {
139 		erase_cursor(ip)
140 		draw_cursor(ip)
141 	}
142 	else
143 		erase_cursor(ip)
144 }
145 
146 hyper_clear(ip, sy, sx, h, w)
147 	register struct ite_softc *ip;
148 	register int sy, sx, h, w;
149 {
150 	hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
151 			 sy * ip->ftheight, sx * ip->ftwidth,
152 			 h  * ip->ftheight, w  * ip->ftwidth,
153 			 RR_CLEAR);
154 }
155 
156 hyper_scroll(ip, sy, sx, count, dir)
157         register struct ite_softc *ip;
158         register int sy, count;
159         int dir, sx;
160 {
161 	register int dy;
162 	register int dx = sx;
163 	register int height = 1;
164 	register int width = ip->cols;
165 
166 	if (dir == SCROLL_UP) {
167 		dy = sy - count;
168 		height = ip->rows - sy;
169 	}
170 	else if (dir == SCROLL_DOWN) {
171 		dy = sy + count;
172 		height = ip->rows - dy - 1;
173 	}
174 	else if (dir == SCROLL_RIGHT) {
175 		dy = sy;
176 		dx = sx + count;
177 		width = ip->cols - dx;
178 	}
179 	else {
180 		dy = sy;
181 		dx = sx - count;
182 		width = ip->cols - sx;
183 	}
184 
185 	hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
186 			 dy * ip->ftheight, dx * ip->ftwidth,
187 			 height * ip->ftheight,
188 			 width  * ip->ftwidth, RR_COPY);
189 }
190 
191 #include <hp300/dev/maskbits.h>
192 
193 /* NOTE:
194  * the first element in starttab could be 0xffffffff.  making it 0
195  * lets us deal with a full first word in the middle loop, rather
196  * than having to do the multiple reads and masks that we'd
197  * have to do if we thought it was partial.
198  */
199 int starttab[32] =
200     {
201 	0x00000000,
202 	0x7FFFFFFF,
203 	0x3FFFFFFF,
204 	0x1FFFFFFF,
205 	0x0FFFFFFF,
206 	0x07FFFFFF,
207 	0x03FFFFFF,
208 	0x01FFFFFF,
209 	0x00FFFFFF,
210 	0x007FFFFF,
211 	0x003FFFFF,
212 	0x001FFFFF,
213 	0x000FFFFF,
214 	0x0007FFFF,
215 	0x0003FFFF,
216 	0x0001FFFF,
217 	0x0000FFFF,
218 	0x00007FFF,
219 	0x00003FFF,
220 	0x00001FFF,
221 	0x00000FFF,
222 	0x000007FF,
223 	0x000003FF,
224 	0x000001FF,
225 	0x000000FF,
226 	0x0000007F,
227 	0x0000003F,
228 	0x0000001F,
229 	0x0000000F,
230 	0x00000007,
231 	0x00000003,
232 	0x00000001
233     };
234 
235 int endtab[32] =
236     {
237 	0x00000000,
238 	0x80000000,
239 	0xC0000000,
240 	0xE0000000,
241 	0xF0000000,
242 	0xF8000000,
243 	0xFC000000,
244 	0xFE000000,
245 	0xFF000000,
246 	0xFF800000,
247 	0xFFC00000,
248 	0xFFE00000,
249 	0xFFF00000,
250 	0xFFF80000,
251 	0xFFFC0000,
252 	0xFFFE0000,
253 	0xFFFF0000,
254 	0xFFFF8000,
255 	0xFFFFC000,
256 	0xFFFFE000,
257 	0xFFFFF000,
258 	0xFFFFF800,
259 	0xFFFFFC00,
260 	0xFFFFFE00,
261 	0xFFFFFF00,
262 	0xFFFFFF80,
263 	0xFFFFFFC0,
264 	0xFFFFFFE0,
265 	0xFFFFFFF0,
266 	0xFFFFFFF8,
267 	0xFFFFFFFC,
268 	0xFFFFFFFE
269     };
270 
271 hyper_windowmove(ip, sy, sx, dy, dx, h, w, func)
272 	struct ite_softc *ip;
273 	int sy, sx, dy, dx, h, w, func;
274 {
275 	int width;		/* add to get to same position in next line */
276 
277 	unsigned int *psrcLine, *pdstLine;
278                                 /* pointers to line with current src and dst */
279 	register unsigned int *psrc;  /* pointer to current src longword */
280 	register unsigned int *pdst;  /* pointer to current dst longword */
281 
282                                 /* following used for looping through a line */
283 	unsigned int startmask, endmask;  /* masks for writing ends of dst */
284 	int nlMiddle;		/* whole longwords in dst */
285 	register int nl;	/* temp copy of nlMiddle */
286 	register unsigned int tmpSrc;
287                                 /* place to store full source word */
288 	register int xoffSrc;	/* offset (>= 0, < 32) from which to
289                                    fetch whole longwords fetched
290                                    in src */
291 	int nstart;		/* number of ragged bits at start of dst */
292 	int nend;		/* number of ragged bits at end of dst */
293 	int srcStartOver;	/* pulling nstart bits from src
294                                    overflows into the next word? */
295 
296 	if (h == 0 || w == 0)
297 		return;
298 
299 	width = ip->fbwidth >> 5;
300 
301 	if (sy < dy) /* start at last scanline of rectangle */
302 	{
303 	    psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width);
304 	    pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width);
305 	    width = -width;
306 	}
307 	else /* start at first scanline */
308 	{
309 	    psrcLine = ((unsigned int *) ip->fbbase) + (sy * width);
310 	    pdstLine = ((unsigned int *) ip->fbbase) + (dy * width);
311 	}
312 
313 	/* x direction doesn't matter for < 1 longword */
314 	if (w <= 32)
315 	{
316 	    int srcBit, dstBit;     /* bit offset of src and dst */
317 
318 	    pdstLine += (dx >> 5);
319 	    psrcLine += (sx >> 5);
320 	    psrc = psrcLine;
321 	    pdst = pdstLine;
322 
323 	    srcBit = sx & 0x1f;
324 	    dstBit = dx & 0x1f;
325 
326 	    while(h--)
327 	    {
328                 getandputrop(psrc, srcBit, dstBit, w, pdst, func)
329 	        pdst += width;
330 		psrc += width;
331 	    }
332 	}
333 	else
334         {
335 	    maskbits(dx, w, startmask, endmask, nlMiddle)
336 	    if (startmask)
337 	      nstart = 32 - (dx & 0x1f);
338 	    else
339 	      nstart = 0;
340 	    if (endmask)
341 	      nend = (dx + w) & 0x1f;
342 	    else
343 	      nend = 0;
344 
345 	    xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
346 	    srcStartOver = ((sx & 0x1f) + nstart) > 31;
347 
348 	    if (sx >= dx) /* move left to right */
349 	    {
350 	        pdstLine += (dx >> 5);
351 		psrcLine += (sx >> 5);
352 
353 		while (h--)
354 		{
355 		    psrc = psrcLine;
356 		    pdst = pdstLine;
357 
358 		    if (startmask)
359 		    {
360 			getandputrop(psrc, (sx & 0x1f),
361 				     (dx & 0x1f), nstart, pdst, func)
362 			    pdst++;
363 			if (srcStartOver)
364 			    psrc++;
365 		    }
366 
367 		    /* special case for aligned operations */
368 		    if (xoffSrc == 0)
369 		    {
370 			nl = nlMiddle;
371 			while (nl--)
372 			{
373 			    DoRop (*pdst, func, *psrc++, *pdst);
374 			    pdst++;
375 			}
376 		    }
377 		    else
378 		    {
379 			nl = nlMiddle + 1;
380 			while (--nl)
381 			{
382 			    getunalignedword (psrc, xoffSrc, tmpSrc)
383 				DoRop (*pdst, func, tmpSrc, *pdst);
384 			    pdst++;
385 			    psrc++;
386 			}
387 		    }
388 
389 		    if (endmask)
390 		    {
391 			getandputrop0(psrc, xoffSrc, nend, pdst, func);
392 		    }
393 
394 		    pdstLine += width;
395 		    psrcLine += width;
396 		}
397 	    }
398 	    else /* move right to left */
399 	    {
400 		pdstLine += (dx+w >> 5);
401 		psrcLine += (sx+w >> 5);
402 		/* if fetch of last partial bits from source crosses
403 		   a longword boundary, start at the previous longword
404 		   */
405 		if (xoffSrc + nend >= 32)
406 		    --psrcLine;
407 
408 		while (h--)
409 		{
410 		    psrc = psrcLine;
411 		    pdst = pdstLine;
412 
413 		    if (endmask)
414 		    {
415 			getandputrop0(psrc, xoffSrc, nend, pdst, func);
416 		    }
417 
418 		    nl = nlMiddle + 1;
419 		    while (--nl)
420 		    {
421 			--psrc;
422 			--pdst;
423 			getunalignedword(psrc, xoffSrc, tmpSrc)
424                         DoRop(*pdst, func, tmpSrc, *pdst);
425 		    }
426 
427 		    if (startmask)
428 		    {
429 			if (srcStartOver)
430 			    --psrc;
431 			--pdst;
432 			getandputrop(psrc, (sx & 0x1f),
433 				     (dx & 0x1f), nstart, pdst, func)
434                     }
435 
436 		    pdstLine += width;
437 		    psrcLine += width;
438 		}
439 	    } /* move right to left */
440 	}
441 }
442 #endif
443