xref: /csrg-svn/sys/hp300/dev/ite_hy.c (revision 56507)
153931Shibler /*
253931Shibler  * Copyright (c) 1991 University of Utah.
353931Shibler  * Copyright (c) 1990 The Regents of the University of California.
453931Shibler  * All rights reserved.
553931Shibler  *
653931Shibler  * This code is derived from software contributed to Berkeley by
753931Shibler  * the Systems Programming Group of the University of Utah Computer
853931Shibler  * Science Department and Mark Davies of the Department of Computer
953931Shibler  * Science, Victoria University of Wellington, New Zealand.
1053931Shibler  *
1153931Shibler  * %sccs.include.redist.c%
1253931Shibler  *
1353931Shibler  * from: Utah $Hdr: ite_hy.c 1.1 92/01/22$
1453931Shibler  *
15*56507Sbostic  *	@(#)ite_hy.c	7.2 (Berkeley) 10/11/92
1653931Shibler  */
1753931Shibler 
1853931Shibler #include "ite.h"
1953931Shibler #if NITE > 0
2053931Shibler 
21*56507Sbostic #include <sys/param.h>
22*56507Sbostic #include <sys/conf.h>
23*56507Sbostic #include <sys/proc.h>
24*56507Sbostic #include <sys/ioctl.h>
25*56507Sbostic #include <sys/tty.h>
26*56507Sbostic #include <sys/systm.h>
27*56507Sbostic #include <sys/uio.h>
2853931Shibler 
29*56507Sbostic #include <hp300/dev/grf_hyreg.h>
30*56507Sbostic #include <hp/dev/itereg.h>
31*56507Sbostic #include <hp/dev/itevar.h>
3253931Shibler 
33*56507Sbostic #include <machine/cpu.h>
3453931Shibler 
3553931Shibler /* XXX */
36*56507Sbostic #include <hp/dev/grfioctl.h>
37*56507Sbostic #include <hp/dev/grfvar.h>
3853931Shibler 
3953931Shibler #define REGBASE	    	((struct hyboxfb *)(ip->regbase))
4053931Shibler #define WINDOWMOVER 	hyper_windowmove
4153931Shibler 
4253931Shibler #undef charX
4353931Shibler #define	charX(ip,c)	\
4453931Shibler 	(((c) % (ip)->cpl) * ((((ip)->ftwidth + 7) / 8) * 8) + (ip)->fontx)
4553931Shibler 
4653931Shibler hyper_init(ip)
4753931Shibler 	register struct ite_softc *ip;
4853931Shibler {
4953931Shibler 	int width;
5053931Shibler 
5153931Shibler 	/* XXX */
5253931Shibler 	if (ip->regbase == NULL) {
5353931Shibler 		struct grf_softc *gp = ip->grf;
5453931Shibler 
5553931Shibler 		ip->regbase = gp->g_regkva;
5653931Shibler 		ip->fbbase = gp->g_fbkva;
5753931Shibler 		ip->fbwidth = gp->g_display.gd_fbwidth;
5853931Shibler 		ip->fbheight = gp->g_display.gd_fbheight;
5953931Shibler 		ip->dwidth = gp->g_display.gd_dwidth;
6053931Shibler 		ip->dheight = gp->g_display.gd_dheight;
6153931Shibler 	}
6253931Shibler 
6353931Shibler 	ite_fontinfo(ip);
6453931Shibler 	width = ((ip->ftwidth + 7) / 8) * 8;
6553931Shibler 	ip->cpl      = (ip->fbwidth - ip->dwidth) / width;
6653931Shibler 	ip->cblanky  = ip->fonty + ((128 / ip->cpl) +1) * ip->ftheight;
6753931Shibler 
6853931Shibler 	/*
6953931Shibler 	 * Clear the framebuffer on all planes.
7053931Shibler 	 */
7153931Shibler 	hyper_windowmove(ip, 0, 0, 0, 0, ip->fbheight, ip->fbwidth, RR_CLEAR);
7253931Shibler 
7353931Shibler 	hyper_ite_fontinit(ip);
7453931Shibler 
7553931Shibler 	REGBASE->nblank = 0x05;
7653931Shibler 
7753931Shibler 	/*
7853931Shibler 	 * Stash the inverted cursor.
7953931Shibler 	 */
8053931Shibler 	hyper_windowmove(ip, charY(ip, ' '), charX(ip, ' '),
8153931Shibler 			 ip->cblanky, ip->cblankx, ip->ftheight,
8253931Shibler 			 ip->ftwidth, RR_COPYINVERTED);
8353931Shibler }
8453931Shibler 
8553931Shibler hyper_deinit(ip)
8653931Shibler 	register struct ite_softc *ip;
8753931Shibler {
8853931Shibler 	hyper_windowmove(ip, 0, 0, 0, 0, ip->fbheight, ip->fbwidth, RR_CLEAR);
8953931Shibler 
9053931Shibler 	REGBASE->nblank = 0x05;
9153931Shibler    	ip->flags &= ~ITE_INITED;
9253931Shibler }
9353931Shibler 
9453931Shibler hyper_ite_fontinit(ip)
9553931Shibler 	register struct ite_softc *ip;
9653931Shibler {
9753931Shibler 	register u_char *fbmem, *dp;
9853931Shibler 	int c, l, b;
9953931Shibler 	int stride, width;
10053931Shibler 
10153931Shibler 	dp = (u_char *)getword(ip, getword(ip, FONTROM) + FONTADDR) + FONTDATA;
10253931Shibler 	stride = ip->fbwidth >> 3;
10353931Shibler 	width = (ip->ftwidth + 7) / 8;
10453931Shibler 
10553931Shibler 	for (c = 0; c < 128; c++) {
10653931Shibler 		fbmem = (u_char *) FBBASE +
10753931Shibler 			(ip->fonty + (c / ip->cpl) * ip->ftheight) *
10853931Shibler 			stride;
10953931Shibler 		fbmem += (ip->fontx >> 3) + (c % ip->cpl) * width;
11053931Shibler 		for (l = 0; l < ip->ftheight; l++) {
11153931Shibler 			for (b = 0; b < width; b++) {
11253931Shibler 				*fbmem++ = *dp;
11353931Shibler 				dp += 2;
11453931Shibler 			}
11553931Shibler 			fbmem -= width;
11653931Shibler 			fbmem += stride;
11753931Shibler 		}
11853931Shibler 	}
11953931Shibler }
12053931Shibler 
12153931Shibler hyper_putc(ip, c, dy, dx, mode)
12253931Shibler 	register struct ite_softc *ip;
12353931Shibler 	int c, dy, dx, mode;
12453931Shibler {
12553931Shibler         int wmrr = ((mode == ATTR_INV) ? RR_COPYINVERTED : RR_COPY);
12653931Shibler 
12753931Shibler 	hyper_windowmove(ip, charY(ip, c), charX(ip, c),
12853931Shibler 			 dy * ip->ftheight, dx * ip->ftwidth,
12953931Shibler 			 ip->ftheight, ip->ftwidth, wmrr);
13053931Shibler }
13153931Shibler 
13253931Shibler hyper_cursor(ip, flag)
13353931Shibler 	register struct ite_softc *ip;
13453931Shibler 	register int flag;
13553931Shibler {
13653931Shibler 	if (flag == DRAW_CURSOR)
13753931Shibler 		draw_cursor(ip)
13853931Shibler 	else if (flag == MOVE_CURSOR) {
13953931Shibler 		erase_cursor(ip)
14053931Shibler 		draw_cursor(ip)
14153931Shibler 	}
14253931Shibler 	else
14353931Shibler 		erase_cursor(ip)
14453931Shibler }
14553931Shibler 
14653931Shibler hyper_clear(ip, sy, sx, h, w)
14753931Shibler 	register struct ite_softc *ip;
14853931Shibler 	register int sy, sx, h, w;
14953931Shibler {
15053931Shibler 	hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
15153931Shibler 			 sy * ip->ftheight, sx * ip->ftwidth,
15253931Shibler 			 h  * ip->ftheight, w  * ip->ftwidth,
15353931Shibler 			 RR_CLEAR);
15453931Shibler }
15553931Shibler 
15653931Shibler hyper_scroll(ip, sy, sx, count, dir)
15753931Shibler         register struct ite_softc *ip;
15853931Shibler         register int sy, count;
15953931Shibler         int dir, sx;
16053931Shibler {
16153931Shibler 	register int dy;
16253931Shibler 	register int dx = sx;
16353931Shibler 	register int height = 1;
16453931Shibler 	register int width = ip->cols;
16553931Shibler 
16653931Shibler 	hyper_cursor(ip, ERASE_CURSOR);
16753931Shibler 
16853931Shibler 	if (dir == SCROLL_UP) {
16953931Shibler 		dy = sy - count;
17053931Shibler 		height = ip->rows - sy;
17153931Shibler 	}
17253931Shibler 	else if (dir == SCROLL_DOWN) {
17353931Shibler 		dy = sy + count;
17453931Shibler 		height = ip->rows - dy - 1;
17553931Shibler 	}
17653931Shibler 	else if (dir == SCROLL_RIGHT) {
17753931Shibler 		dy = sy;
17853931Shibler 		dx = sx + count;
17953931Shibler 		width = ip->cols - dx;
18053931Shibler 	}
18153931Shibler 	else {
18253931Shibler 		dy = sy;
18353931Shibler 		dx = sx - count;
18453931Shibler 		width = ip->cols - sx;
18553931Shibler 	}
18653931Shibler 
18753931Shibler 	hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
18853931Shibler 			 dy * ip->ftheight, dx * ip->ftwidth,
18953931Shibler 			 height * ip->ftheight,
19053931Shibler 			 width  * ip->ftwidth, RR_COPY);
19153931Shibler }
19253931Shibler 
193*56507Sbostic #include <hp300/dev/maskbits.h>
19453931Shibler 
19553931Shibler /* NOTE:
19653931Shibler  * the first element in starttab could be 0xffffffff.  making it 0
19753931Shibler  * lets us deal with a full first word in the middle loop, rather
19853931Shibler  * than having to do the multiple reads and masks that we'd
19953931Shibler  * have to do if we thought it was partial.
20053931Shibler  */
20153931Shibler int starttab[32] =
20253931Shibler     {
20353931Shibler 	0x00000000,
20453931Shibler 	0x7FFFFFFF,
20553931Shibler 	0x3FFFFFFF,
20653931Shibler 	0x1FFFFFFF,
20753931Shibler 	0x0FFFFFFF,
20853931Shibler 	0x07FFFFFF,
20953931Shibler 	0x03FFFFFF,
21053931Shibler 	0x01FFFFFF,
21153931Shibler 	0x00FFFFFF,
21253931Shibler 	0x007FFFFF,
21353931Shibler 	0x003FFFFF,
21453931Shibler 	0x001FFFFF,
21553931Shibler 	0x000FFFFF,
21653931Shibler 	0x0007FFFF,
21753931Shibler 	0x0003FFFF,
21853931Shibler 	0x0001FFFF,
21953931Shibler 	0x0000FFFF,
22053931Shibler 	0x00007FFF,
22153931Shibler 	0x00003FFF,
22253931Shibler 	0x00001FFF,
22353931Shibler 	0x00000FFF,
22453931Shibler 	0x000007FF,
22553931Shibler 	0x000003FF,
22653931Shibler 	0x000001FF,
22753931Shibler 	0x000000FF,
22853931Shibler 	0x0000007F,
22953931Shibler 	0x0000003F,
23053931Shibler 	0x0000001F,
23153931Shibler 	0x0000000F,
23253931Shibler 	0x00000007,
23353931Shibler 	0x00000003,
23453931Shibler 	0x00000001
23553931Shibler     };
23653931Shibler 
23753931Shibler int endtab[32] =
23853931Shibler     {
23953931Shibler 	0x00000000,
24053931Shibler 	0x80000000,
24153931Shibler 	0xC0000000,
24253931Shibler 	0xE0000000,
24353931Shibler 	0xF0000000,
24453931Shibler 	0xF8000000,
24553931Shibler 	0xFC000000,
24653931Shibler 	0xFE000000,
24753931Shibler 	0xFF000000,
24853931Shibler 	0xFF800000,
24953931Shibler 	0xFFC00000,
25053931Shibler 	0xFFE00000,
25153931Shibler 	0xFFF00000,
25253931Shibler 	0xFFF80000,
25353931Shibler 	0xFFFC0000,
25453931Shibler 	0xFFFE0000,
25553931Shibler 	0xFFFF0000,
25653931Shibler 	0xFFFF8000,
25753931Shibler 	0xFFFFC000,
25853931Shibler 	0xFFFFE000,
25953931Shibler 	0xFFFFF000,
26053931Shibler 	0xFFFFF800,
26153931Shibler 	0xFFFFFC00,
26253931Shibler 	0xFFFFFE00,
26353931Shibler 	0xFFFFFF00,
26453931Shibler 	0xFFFFFF80,
26553931Shibler 	0xFFFFFFC0,
26653931Shibler 	0xFFFFFFE0,
26753931Shibler 	0xFFFFFFF0,
26853931Shibler 	0xFFFFFFF8,
26953931Shibler 	0xFFFFFFFC,
27053931Shibler 	0xFFFFFFFE
27153931Shibler     };
27253931Shibler 
27353931Shibler hyper_windowmove(ip, sy, sx, dy, dx, h, w, func)
27453931Shibler 	struct ite_softc *ip;
27553931Shibler 	int sy, sx, dy, dx, h, w, func;
27653931Shibler {
27753931Shibler 	int width;		/* add to get to same position in next line */
27853931Shibler 
27953931Shibler 	unsigned int *psrcLine, *pdstLine;
28053931Shibler                                 /* pointers to line with current src and dst */
28153931Shibler 	register unsigned int *psrc;  /* pointer to current src longword */
28253931Shibler 	register unsigned int *pdst;  /* pointer to current dst longword */
28353931Shibler 
28453931Shibler                                 /* following used for looping through a line */
28553931Shibler 	unsigned int startmask, endmask;  /* masks for writing ends of dst */
28653931Shibler 	int nlMiddle;		/* whole longwords in dst */
28753931Shibler 	register int nl;	/* temp copy of nlMiddle */
28853931Shibler 	register unsigned int tmpSrc;
28953931Shibler                                 /* place to store full source word */
29053931Shibler 	register int xoffSrc;	/* offset (>= 0, < 32) from which to
29153931Shibler                                    fetch whole longwords fetched
29253931Shibler                                    in src */
29353931Shibler 	int nstart;		/* number of ragged bits at start of dst */
29453931Shibler 	int nend;		/* number of ragged bits at end of dst */
29553931Shibler 	int srcStartOver;	/* pulling nstart bits from src
29653931Shibler                                    overflows into the next word? */
29753931Shibler 
29853931Shibler 	if (h == 0 || w == 0)
29953931Shibler 		return;
30053931Shibler 
30153931Shibler 	width = ip->fbwidth >> 5;
30253931Shibler 
30353931Shibler 	if (sy < dy) /* start at last scanline of rectangle */
30453931Shibler 	{
30553931Shibler 	    psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width);
30653931Shibler 	    pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width);
30753931Shibler 	    width = -width;
30853931Shibler 	}
30953931Shibler 	else /* start at first scanline */
31053931Shibler 	{
31153931Shibler 	    psrcLine = ((unsigned int *) ip->fbbase) + (sy * width);
31253931Shibler 	    pdstLine = ((unsigned int *) ip->fbbase) + (dy * width);
31353931Shibler 	}
31453931Shibler 
31553931Shibler 	/* x direction doesn't matter for < 1 longword */
31653931Shibler 	if (w <= 32)
31753931Shibler 	{
31853931Shibler 	    int srcBit, dstBit;     /* bit offset of src and dst */
31953931Shibler 
32053931Shibler 	    pdstLine += (dx >> 5);
32153931Shibler 	    psrcLine += (sx >> 5);
32253931Shibler 	    psrc = psrcLine;
32353931Shibler 	    pdst = pdstLine;
32453931Shibler 
32553931Shibler 	    srcBit = sx & 0x1f;
32653931Shibler 	    dstBit = dx & 0x1f;
32753931Shibler 
32853931Shibler 	    while(h--)
32953931Shibler 	    {
33053931Shibler                 getandputrop(psrc, srcBit, dstBit, w, pdst, func)
33153931Shibler 	        pdst += width;
33253931Shibler 		psrc += width;
33353931Shibler 	    }
33453931Shibler 	}
33553931Shibler 	else
33653931Shibler         {
33753931Shibler 	    maskbits(dx, w, startmask, endmask, nlMiddle)
33853931Shibler 	    if (startmask)
33953931Shibler 	      nstart = 32 - (dx & 0x1f);
34053931Shibler 	    else
34153931Shibler 	      nstart = 0;
34253931Shibler 	    if (endmask)
34353931Shibler 	      nend = (dx + w) & 0x1f;
34453931Shibler 	    else
34553931Shibler 	      nend = 0;
34653931Shibler 
34753931Shibler 	    xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
34853931Shibler 	    srcStartOver = ((sx & 0x1f) + nstart) > 31;
34953931Shibler 
35053931Shibler 	    if (sx >= dx) /* move left to right */
35153931Shibler 	    {
35253931Shibler 	        pdstLine += (dx >> 5);
35353931Shibler 		psrcLine += (sx >> 5);
35453931Shibler 
35553931Shibler 		while (h--)
35653931Shibler 		{
35753931Shibler 		    psrc = psrcLine;
35853931Shibler 		    pdst = pdstLine;
35953931Shibler 
36053931Shibler 		    if (startmask)
36153931Shibler 		    {
36253931Shibler 			getandputrop(psrc, (sx & 0x1f),
36353931Shibler 				     (dx & 0x1f), nstart, pdst, func)
36453931Shibler 			    pdst++;
36553931Shibler 			if (srcStartOver)
36653931Shibler 			    psrc++;
36753931Shibler 		    }
36853931Shibler 
36953931Shibler 		    /* special case for aligned operations */
37053931Shibler 		    if (xoffSrc == 0)
37153931Shibler 		    {
37253931Shibler 			nl = nlMiddle;
37353931Shibler 			while (nl--)
37453931Shibler 			{
37553931Shibler 			    DoRop (*pdst, func, *psrc++, *pdst);
37653931Shibler 			    pdst++;
37753931Shibler 			}
37853931Shibler 		    }
37953931Shibler 		    else
38053931Shibler 		    {
38153931Shibler 			nl = nlMiddle + 1;
38253931Shibler 			while (--nl)
38353931Shibler 			{
38453931Shibler 			    getunalignedword (psrc, xoffSrc, tmpSrc)
38553931Shibler 				DoRop (*pdst, func, tmpSrc, *pdst);
38653931Shibler 			    pdst++;
38753931Shibler 			    psrc++;
38853931Shibler 			}
38953931Shibler 		    }
39053931Shibler 
39153931Shibler 		    if (endmask)
39253931Shibler 		    {
39353931Shibler 			getandputrop0(psrc, xoffSrc, nend, pdst, func);
39453931Shibler 		    }
39553931Shibler 
39653931Shibler 		    pdstLine += width;
39753931Shibler 		    psrcLine += width;
39853931Shibler 		}
39953931Shibler 	    }
40053931Shibler 	    else /* move right to left */
40153931Shibler 	    {
40253931Shibler 		pdstLine += (dx+w >> 5);
40353931Shibler 		psrcLine += (sx+w >> 5);
40453931Shibler 		/* if fetch of last partial bits from source crosses
40553931Shibler 		   a longword boundary, start at the previous longword
40653931Shibler 		   */
40753931Shibler 		if (xoffSrc + nend >= 32)
40853931Shibler 		    --psrcLine;
40953931Shibler 
41053931Shibler 		while (h--)
41153931Shibler 		{
41253931Shibler 		    psrc = psrcLine;
41353931Shibler 		    pdst = pdstLine;
41453931Shibler 
41553931Shibler 		    if (endmask)
41653931Shibler 		    {
41753931Shibler 			getandputrop0(psrc, xoffSrc, nend, pdst, func);
41853931Shibler 		    }
41953931Shibler 
42053931Shibler 		    nl = nlMiddle + 1;
42153931Shibler 		    while (--nl)
42253931Shibler 		    {
42353931Shibler 			--psrc;
42453931Shibler 			--pdst;
42553931Shibler 			getunalignedword(psrc, xoffSrc, tmpSrc)
42653931Shibler                         DoRop(*pdst, func, tmpSrc, *pdst);
42753931Shibler 		    }
42853931Shibler 
42953931Shibler 		    if (startmask)
43053931Shibler 		    {
43153931Shibler 			if (srcStartOver)
43253931Shibler 			    --psrc;
43353931Shibler 			--pdst;
43453931Shibler 			getandputrop(psrc, (sx & 0x1f),
43553931Shibler 				     (dx & 0x1f), nstart, pdst, func)
43653931Shibler                     }
43753931Shibler 
43853931Shibler 		    pdstLine += width;
43953931Shibler 		    psrcLine += width;
44053931Shibler 		}
44153931Shibler 	    } /* move right to left */
44253931Shibler 	}
44353931Shibler }
44453931Shibler #endif
445