xref: /original-bsd/sys/hp300/dev/ite_hy.c (revision 404544c8)
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.1 92/01/22$
14  *
15  *	@(#)ite_hy.c	7.1 (Berkeley) 06/05/92
16  */
17 
18 #include "ite.h"
19 #if NITE > 0
20 
21 #include "param.h"
22 #include "conf.h"
23 #include "proc.h"
24 #include "ioctl.h"
25 #include "tty.h"
26 #include "systm.h"
27 #include "uio.h"
28 
29 #include "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 	hyper_cursor(ip, ERASE_CURSOR);
167 
168 	if (dir == SCROLL_UP) {
169 		dy = sy - count;
170 		height = ip->rows - sy;
171 	}
172 	else if (dir == SCROLL_DOWN) {
173 		dy = sy + count;
174 		height = ip->rows - dy - 1;
175 	}
176 	else if (dir == SCROLL_RIGHT) {
177 		dy = sy;
178 		dx = sx + count;
179 		width = ip->cols - dx;
180 	}
181 	else {
182 		dy = sy;
183 		dx = sx - count;
184 		width = ip->cols - sx;
185 	}
186 
187 	hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
188 			 dy * ip->ftheight, dx * ip->ftwidth,
189 			 height * ip->ftheight,
190 			 width  * ip->ftwidth, RR_COPY);
191 }
192 
193 #include "maskbits.h"
194 
195 /* NOTE:
196  * the first element in starttab could be 0xffffffff.  making it 0
197  * lets us deal with a full first word in the middle loop, rather
198  * than having to do the multiple reads and masks that we'd
199  * have to do if we thought it was partial.
200  */
201 int starttab[32] =
202     {
203 	0x00000000,
204 	0x7FFFFFFF,
205 	0x3FFFFFFF,
206 	0x1FFFFFFF,
207 	0x0FFFFFFF,
208 	0x07FFFFFF,
209 	0x03FFFFFF,
210 	0x01FFFFFF,
211 	0x00FFFFFF,
212 	0x007FFFFF,
213 	0x003FFFFF,
214 	0x001FFFFF,
215 	0x000FFFFF,
216 	0x0007FFFF,
217 	0x0003FFFF,
218 	0x0001FFFF,
219 	0x0000FFFF,
220 	0x00007FFF,
221 	0x00003FFF,
222 	0x00001FFF,
223 	0x00000FFF,
224 	0x000007FF,
225 	0x000003FF,
226 	0x000001FF,
227 	0x000000FF,
228 	0x0000007F,
229 	0x0000003F,
230 	0x0000001F,
231 	0x0000000F,
232 	0x00000007,
233 	0x00000003,
234 	0x00000001
235     };
236 
237 int endtab[32] =
238     {
239 	0x00000000,
240 	0x80000000,
241 	0xC0000000,
242 	0xE0000000,
243 	0xF0000000,
244 	0xF8000000,
245 	0xFC000000,
246 	0xFE000000,
247 	0xFF000000,
248 	0xFF800000,
249 	0xFFC00000,
250 	0xFFE00000,
251 	0xFFF00000,
252 	0xFFF80000,
253 	0xFFFC0000,
254 	0xFFFE0000,
255 	0xFFFF0000,
256 	0xFFFF8000,
257 	0xFFFFC000,
258 	0xFFFFE000,
259 	0xFFFFF000,
260 	0xFFFFF800,
261 	0xFFFFFC00,
262 	0xFFFFFE00,
263 	0xFFFFFF00,
264 	0xFFFFFF80,
265 	0xFFFFFFC0,
266 	0xFFFFFFE0,
267 	0xFFFFFFF0,
268 	0xFFFFFFF8,
269 	0xFFFFFFFC,
270 	0xFFFFFFFE
271     };
272 
273 hyper_windowmove(ip, sy, sx, dy, dx, h, w, func)
274 	struct ite_softc *ip;
275 	int sy, sx, dy, dx, h, w, func;
276 {
277 	int width;		/* add to get to same position in next line */
278 
279 	unsigned int *psrcLine, *pdstLine;
280                                 /* pointers to line with current src and dst */
281 	register unsigned int *psrc;  /* pointer to current src longword */
282 	register unsigned int *pdst;  /* pointer to current dst longword */
283 
284                                 /* following used for looping through a line */
285 	unsigned int startmask, endmask;  /* masks for writing ends of dst */
286 	int nlMiddle;		/* whole longwords in dst */
287 	register int nl;	/* temp copy of nlMiddle */
288 	register unsigned int tmpSrc;
289                                 /* place to store full source word */
290 	register int xoffSrc;	/* offset (>= 0, < 32) from which to
291                                    fetch whole longwords fetched
292                                    in src */
293 	int nstart;		/* number of ragged bits at start of dst */
294 	int nend;		/* number of ragged bits at end of dst */
295 	int srcStartOver;	/* pulling nstart bits from src
296                                    overflows into the next word? */
297 
298 	if (h == 0 || w == 0)
299 		return;
300 
301 	width = ip->fbwidth >> 5;
302 
303 	if (sy < dy) /* start at last scanline of rectangle */
304 	{
305 	    psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width);
306 	    pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width);
307 	    width = -width;
308 	}
309 	else /* start at first scanline */
310 	{
311 	    psrcLine = ((unsigned int *) ip->fbbase) + (sy * width);
312 	    pdstLine = ((unsigned int *) ip->fbbase) + (dy * width);
313 	}
314 
315 	/* x direction doesn't matter for < 1 longword */
316 	if (w <= 32)
317 	{
318 	    int srcBit, dstBit;     /* bit offset of src and dst */
319 
320 	    pdstLine += (dx >> 5);
321 	    psrcLine += (sx >> 5);
322 	    psrc = psrcLine;
323 	    pdst = pdstLine;
324 
325 	    srcBit = sx & 0x1f;
326 	    dstBit = dx & 0x1f;
327 
328 	    while(h--)
329 	    {
330                 getandputrop(psrc, srcBit, dstBit, w, pdst, func)
331 	        pdst += width;
332 		psrc += width;
333 	    }
334 	}
335 	else
336         {
337 	    maskbits(dx, w, startmask, endmask, nlMiddle)
338 	    if (startmask)
339 	      nstart = 32 - (dx & 0x1f);
340 	    else
341 	      nstart = 0;
342 	    if (endmask)
343 	      nend = (dx + w) & 0x1f;
344 	    else
345 	      nend = 0;
346 
347 	    xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
348 	    srcStartOver = ((sx & 0x1f) + nstart) > 31;
349 
350 	    if (sx >= dx) /* move left to right */
351 	    {
352 	        pdstLine += (dx >> 5);
353 		psrcLine += (sx >> 5);
354 
355 		while (h--)
356 		{
357 		    psrc = psrcLine;
358 		    pdst = pdstLine;
359 
360 		    if (startmask)
361 		    {
362 			getandputrop(psrc, (sx & 0x1f),
363 				     (dx & 0x1f), nstart, pdst, func)
364 			    pdst++;
365 			if (srcStartOver)
366 			    psrc++;
367 		    }
368 
369 		    /* special case for aligned operations */
370 		    if (xoffSrc == 0)
371 		    {
372 			nl = nlMiddle;
373 			while (nl--)
374 			{
375 			    DoRop (*pdst, func, *psrc++, *pdst);
376 			    pdst++;
377 			}
378 		    }
379 		    else
380 		    {
381 			nl = nlMiddle + 1;
382 			while (--nl)
383 			{
384 			    getunalignedword (psrc, xoffSrc, tmpSrc)
385 				DoRop (*pdst, func, tmpSrc, *pdst);
386 			    pdst++;
387 			    psrc++;
388 			}
389 		    }
390 
391 		    if (endmask)
392 		    {
393 			getandputrop0(psrc, xoffSrc, nend, pdst, func);
394 		    }
395 
396 		    pdstLine += width;
397 		    psrcLine += width;
398 		}
399 	    }
400 	    else /* move right to left */
401 	    {
402 		pdstLine += (dx+w >> 5);
403 		psrcLine += (sx+w >> 5);
404 		/* if fetch of last partial bits from source crosses
405 		   a longword boundary, start at the previous longword
406 		   */
407 		if (xoffSrc + nend >= 32)
408 		    --psrcLine;
409 
410 		while (h--)
411 		{
412 		    psrc = psrcLine;
413 		    pdst = pdstLine;
414 
415 		    if (endmask)
416 		    {
417 			getandputrop0(psrc, xoffSrc, nend, pdst, func);
418 		    }
419 
420 		    nl = nlMiddle + 1;
421 		    while (--nl)
422 		    {
423 			--psrc;
424 			--pdst;
425 			getunalignedword(psrc, xoffSrc, tmpSrc)
426                         DoRop(*pdst, func, tmpSrc, *pdst);
427 		    }
428 
429 		    if (startmask)
430 		    {
431 			if (srcStartOver)
432 			    --psrc;
433 			--pdst;
434 			getandputrop(psrc, (sx & 0x1f),
435 				     (dx & 0x1f), nstart, pdst, func)
436                     }
437 
438 		    pdstLine += width;
439 		    psrcLine += width;
440 		}
441 	    } /* move right to left */
442 	}
443 }
444 #endif
445