xref: /original-bsd/sys/hp300/dev/ite_hy.c (revision 3705696b)
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 
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) +
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 
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 
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 
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 
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