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