153931Shibler /*
253931Shibler * Copyright (c) 1991 University of Utah.
3*63151Sbostic * Copyright (c) 1990, 1993
4*63151Sbostic * The Regents of the University of California. 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 *
1357325Shibler * from: Utah $Hdr: ite_hy.c 1.2 92/12/20$
1453931Shibler *
15*63151Sbostic * @(#)ite_hy.c 8.1 (Berkeley) 06/10/93
1653931Shibler */
1753931Shibler
1853931Shibler #include "ite.h"
1953931Shibler #if NITE > 0
2053931Shibler
2156507Sbostic #include <sys/param.h>
2256507Sbostic #include <sys/conf.h>
2356507Sbostic #include <sys/proc.h>
2456507Sbostic #include <sys/ioctl.h>
2556507Sbostic #include <sys/tty.h>
2656507Sbostic #include <sys/systm.h>
2756507Sbostic #include <sys/uio.h>
2853931Shibler
2956507Sbostic #include <hp300/dev/grf_hyreg.h>
3056507Sbostic #include <hp/dev/itereg.h>
3156507Sbostic #include <hp/dev/itevar.h>
3253931Shibler
3356507Sbostic #include <machine/cpu.h>
3453931Shibler
3553931Shibler /* XXX */
3656507Sbostic #include <hp/dev/grfioctl.h>
3756507Sbostic #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
hyper_init(ip)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
hyper_deinit(ip)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
hyper_ite_fontinit(ip)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
10160896Smckusick dp = (u_char *)(getword(ip, getword(ip, FONTROM) + FONTADDR) +
10260896Smckusick ip->regbase) + FONTDATA;
10353931Shibler stride = ip->fbwidth >> 3;
10453931Shibler width = (ip->ftwidth + 7) / 8;
10553931Shibler
10653931Shibler for (c = 0; c < 128; c++) {
10753931Shibler fbmem = (u_char *) FBBASE +
10853931Shibler (ip->fonty + (c / ip->cpl) * ip->ftheight) *
10953931Shibler stride;
11053931Shibler fbmem += (ip->fontx >> 3) + (c % ip->cpl) * width;
11153931Shibler for (l = 0; l < ip->ftheight; l++) {
11253931Shibler for (b = 0; b < width; b++) {
11353931Shibler *fbmem++ = *dp;
11453931Shibler dp += 2;
11553931Shibler }
11653931Shibler fbmem -= width;
11753931Shibler fbmem += stride;
11853931Shibler }
11953931Shibler }
12053931Shibler }
12153931Shibler
hyper_putc(ip,c,dy,dx,mode)12253931Shibler hyper_putc(ip, c, dy, dx, mode)
12353931Shibler register struct ite_softc *ip;
12453931Shibler int c, dy, dx, mode;
12553931Shibler {
12653931Shibler int wmrr = ((mode == ATTR_INV) ? RR_COPYINVERTED : RR_COPY);
12753931Shibler
12853931Shibler hyper_windowmove(ip, charY(ip, c), charX(ip, c),
12953931Shibler dy * ip->ftheight, dx * ip->ftwidth,
13053931Shibler ip->ftheight, ip->ftwidth, wmrr);
13153931Shibler }
13253931Shibler
hyper_cursor(ip,flag)13353931Shibler hyper_cursor(ip, flag)
13453931Shibler register struct ite_softc *ip;
13553931Shibler register int flag;
13653931Shibler {
13753931Shibler if (flag == DRAW_CURSOR)
13853931Shibler draw_cursor(ip)
13953931Shibler else if (flag == MOVE_CURSOR) {
14053931Shibler erase_cursor(ip)
14153931Shibler draw_cursor(ip)
14253931Shibler }
14353931Shibler else
14453931Shibler erase_cursor(ip)
14553931Shibler }
14653931Shibler
hyper_clear(ip,sy,sx,h,w)14753931Shibler hyper_clear(ip, sy, sx, h, w)
14853931Shibler register struct ite_softc *ip;
14953931Shibler register int sy, sx, h, w;
15053931Shibler {
15153931Shibler hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
15253931Shibler sy * ip->ftheight, sx * ip->ftwidth,
15353931Shibler h * ip->ftheight, w * ip->ftwidth,
15453931Shibler RR_CLEAR);
15553931Shibler }
15653931Shibler
hyper_scroll(ip,sy,sx,count,dir)15753931Shibler hyper_scroll(ip, sy, sx, count, dir)
15853931Shibler register struct ite_softc *ip;
15953931Shibler register int sy, count;
16053931Shibler int dir, sx;
16153931Shibler {
16253931Shibler register int dy;
16353931Shibler register int dx = sx;
16453931Shibler register int height = 1;
16553931Shibler register int width = ip->cols;
16653931Shibler
16753931Shibler if (dir == SCROLL_UP) {
16853931Shibler dy = sy - count;
16953931Shibler height = ip->rows - sy;
17053931Shibler }
17153931Shibler else if (dir == SCROLL_DOWN) {
17253931Shibler dy = sy + count;
17353931Shibler height = ip->rows - dy - 1;
17453931Shibler }
17553931Shibler else if (dir == SCROLL_RIGHT) {
17653931Shibler dy = sy;
17753931Shibler dx = sx + count;
17853931Shibler width = ip->cols - dx;
17953931Shibler }
18053931Shibler else {
18153931Shibler dy = sy;
18253931Shibler dx = sx - count;
18353931Shibler width = ip->cols - sx;
18453931Shibler }
18553931Shibler
18653931Shibler hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth,
18753931Shibler dy * ip->ftheight, dx * ip->ftwidth,
18853931Shibler height * ip->ftheight,
18953931Shibler width * ip->ftwidth, RR_COPY);
19053931Shibler }
19153931Shibler
19256507Sbostic #include <hp300/dev/maskbits.h>
19353931Shibler
19453931Shibler /* NOTE:
19553931Shibler * the first element in starttab could be 0xffffffff. making it 0
19653931Shibler * lets us deal with a full first word in the middle loop, rather
19753931Shibler * than having to do the multiple reads and masks that we'd
19853931Shibler * have to do if we thought it was partial.
19953931Shibler */
20053931Shibler int starttab[32] =
20153931Shibler {
20253931Shibler 0x00000000,
20353931Shibler 0x7FFFFFFF,
20453931Shibler 0x3FFFFFFF,
20553931Shibler 0x1FFFFFFF,
20653931Shibler 0x0FFFFFFF,
20753931Shibler 0x07FFFFFF,
20853931Shibler 0x03FFFFFF,
20953931Shibler 0x01FFFFFF,
21053931Shibler 0x00FFFFFF,
21153931Shibler 0x007FFFFF,
21253931Shibler 0x003FFFFF,
21353931Shibler 0x001FFFFF,
21453931Shibler 0x000FFFFF,
21553931Shibler 0x0007FFFF,
21653931Shibler 0x0003FFFF,
21753931Shibler 0x0001FFFF,
21853931Shibler 0x0000FFFF,
21953931Shibler 0x00007FFF,
22053931Shibler 0x00003FFF,
22153931Shibler 0x00001FFF,
22253931Shibler 0x00000FFF,
22353931Shibler 0x000007FF,
22453931Shibler 0x000003FF,
22553931Shibler 0x000001FF,
22653931Shibler 0x000000FF,
22753931Shibler 0x0000007F,
22853931Shibler 0x0000003F,
22953931Shibler 0x0000001F,
23053931Shibler 0x0000000F,
23153931Shibler 0x00000007,
23253931Shibler 0x00000003,
23353931Shibler 0x00000001
23453931Shibler };
23553931Shibler
23653931Shibler int endtab[32] =
23753931Shibler {
23853931Shibler 0x00000000,
23953931Shibler 0x80000000,
24053931Shibler 0xC0000000,
24153931Shibler 0xE0000000,
24253931Shibler 0xF0000000,
24353931Shibler 0xF8000000,
24453931Shibler 0xFC000000,
24553931Shibler 0xFE000000,
24653931Shibler 0xFF000000,
24753931Shibler 0xFF800000,
24853931Shibler 0xFFC00000,
24953931Shibler 0xFFE00000,
25053931Shibler 0xFFF00000,
25153931Shibler 0xFFF80000,
25253931Shibler 0xFFFC0000,
25353931Shibler 0xFFFE0000,
25453931Shibler 0xFFFF0000,
25553931Shibler 0xFFFF8000,
25653931Shibler 0xFFFFC000,
25753931Shibler 0xFFFFE000,
25853931Shibler 0xFFFFF000,
25953931Shibler 0xFFFFF800,
26053931Shibler 0xFFFFFC00,
26153931Shibler 0xFFFFFE00,
26253931Shibler 0xFFFFFF00,
26353931Shibler 0xFFFFFF80,
26453931Shibler 0xFFFFFFC0,
26553931Shibler 0xFFFFFFE0,
26653931Shibler 0xFFFFFFF0,
26753931Shibler 0xFFFFFFF8,
26853931Shibler 0xFFFFFFFC,
26953931Shibler 0xFFFFFFFE
27053931Shibler };
27153931Shibler
27253931Shibler hyper_windowmove(ip, sy, sx, dy, dx, h, w, func)
27353931Shibler struct ite_softc *ip;
27453931Shibler int sy, sx, dy, dx, h, w, func;
27553931Shibler {
27653931Shibler int width; /* add to get to same position in next line */
27753931Shibler
27853931Shibler unsigned int *psrcLine, *pdstLine;
27953931Shibler /* pointers to line with current src and dst */
28053931Shibler register unsigned int *psrc; /* pointer to current src longword */
28153931Shibler register unsigned int *pdst; /* pointer to current dst longword */
28253931Shibler
28353931Shibler /* following used for looping through a line */
28453931Shibler unsigned int startmask, endmask; /* masks for writing ends of dst */
28553931Shibler int nlMiddle; /* whole longwords in dst */
28653931Shibler register int nl; /* temp copy of nlMiddle */
28753931Shibler register unsigned int tmpSrc;
28853931Shibler /* place to store full source word */
28953931Shibler register int xoffSrc; /* offset (>= 0, < 32) from which to
29053931Shibler fetch whole longwords fetched
29153931Shibler in src */
29253931Shibler int nstart; /* number of ragged bits at start of dst */
29353931Shibler int nend; /* number of ragged bits at end of dst */
29453931Shibler int srcStartOver; /* pulling nstart bits from src
29553931Shibler overflows into the next word? */
29653931Shibler
29753931Shibler if (h == 0 || w == 0)
29853931Shibler return;
29953931Shibler
30053931Shibler width = ip->fbwidth >> 5;
30153931Shibler
30253931Shibler if (sy < dy) /* start at last scanline of rectangle */
30353931Shibler {
30453931Shibler psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width);
30553931Shibler pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width);
30653931Shibler width = -width;
30753931Shibler }
30853931Shibler else /* start at first scanline */
30953931Shibler {
31053931Shibler psrcLine = ((unsigned int *) ip->fbbase) + (sy * width);
31153931Shibler pdstLine = ((unsigned int *) ip->fbbase) + (dy * width);
31253931Shibler }
31353931Shibler
31453931Shibler /* x direction doesn't matter for < 1 longword */
31553931Shibler if (w <= 32)
31653931Shibler {
31753931Shibler int srcBit, dstBit; /* bit offset of src and dst */
31853931Shibler
31953931Shibler pdstLine += (dx >> 5);
32053931Shibler psrcLine += (sx >> 5);
32153931Shibler psrc = psrcLine;
32253931Shibler pdst = pdstLine;
32353931Shibler
32453931Shibler srcBit = sx & 0x1f;
32553931Shibler dstBit = dx & 0x1f;
32653931Shibler
32753931Shibler while(h--)
32853931Shibler {
32953931Shibler getandputrop(psrc, srcBit, dstBit, w, pdst, func)
33053931Shibler pdst += width;
33153931Shibler psrc += width;
33253931Shibler }
33353931Shibler }
33453931Shibler else
33553931Shibler {
33653931Shibler maskbits(dx, w, startmask, endmask, nlMiddle)
33753931Shibler if (startmask)
33853931Shibler nstart = 32 - (dx & 0x1f);
33953931Shibler else
34053931Shibler nstart = 0;
34153931Shibler if (endmask)
34253931Shibler nend = (dx + w) & 0x1f;
34353931Shibler else
34453931Shibler nend = 0;
34553931Shibler
34653931Shibler xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
34753931Shibler srcStartOver = ((sx & 0x1f) + nstart) > 31;
34853931Shibler
34953931Shibler if (sx >= dx) /* move left to right */
35053931Shibler {
35153931Shibler pdstLine += (dx >> 5);
35253931Shibler psrcLine += (sx >> 5);
35353931Shibler
35453931Shibler while (h--)
35553931Shibler {
35653931Shibler psrc = psrcLine;
35753931Shibler pdst = pdstLine;
35853931Shibler
35953931Shibler if (startmask)
36053931Shibler {
36153931Shibler getandputrop(psrc, (sx & 0x1f),
36253931Shibler (dx & 0x1f), nstart, pdst, func)
36353931Shibler pdst++;
36453931Shibler if (srcStartOver)
36553931Shibler psrc++;
36653931Shibler }
36753931Shibler
36853931Shibler /* special case for aligned operations */
36953931Shibler if (xoffSrc == 0)
37053931Shibler {
37153931Shibler nl = nlMiddle;
37253931Shibler while (nl--)
37353931Shibler {
37453931Shibler DoRop (*pdst, func, *psrc++, *pdst);
37553931Shibler pdst++;
37653931Shibler }
37753931Shibler }
37853931Shibler else
37953931Shibler {
38053931Shibler nl = nlMiddle + 1;
38153931Shibler while (--nl)
38253931Shibler {
38353931Shibler getunalignedword (psrc, xoffSrc, tmpSrc)
38453931Shibler DoRop (*pdst, func, tmpSrc, *pdst);
38553931Shibler pdst++;
38653931Shibler psrc++;
38753931Shibler }
38853931Shibler }
38953931Shibler
39053931Shibler if (endmask)
39153931Shibler {
39253931Shibler getandputrop0(psrc, xoffSrc, nend, pdst, func);
39353931Shibler }
39453931Shibler
39553931Shibler pdstLine += width;
39653931Shibler psrcLine += width;
39753931Shibler }
39853931Shibler }
39953931Shibler else /* move right to left */
40053931Shibler {
40153931Shibler pdstLine += (dx+w >> 5);
40253931Shibler psrcLine += (sx+w >> 5);
40353931Shibler /* if fetch of last partial bits from source crosses
40453931Shibler a longword boundary, start at the previous longword
40553931Shibler */
40653931Shibler if (xoffSrc + nend >= 32)
40753931Shibler --psrcLine;
40853931Shibler
40953931Shibler while (h--)
41053931Shibler {
41153931Shibler psrc = psrcLine;
41253931Shibler pdst = pdstLine;
41353931Shibler
41453931Shibler if (endmask)
41553931Shibler {
41653931Shibler getandputrop0(psrc, xoffSrc, nend, pdst, func);
41753931Shibler }
41853931Shibler
41953931Shibler nl = nlMiddle + 1;
42053931Shibler while (--nl)
42153931Shibler {
42253931Shibler --psrc;
42353931Shibler --pdst;
42453931Shibler getunalignedword(psrc, xoffSrc, tmpSrc)
42553931Shibler DoRop(*pdst, func, tmpSrc, *pdst);
42653931Shibler }
42753931Shibler
42853931Shibler if (startmask)
42953931Shibler {
43053931Shibler if (srcStartOver)
43153931Shibler --psrc;
43253931Shibler --pdst;
43353931Shibler getandputrop(psrc, (sx & 0x1f),
43453931Shibler (dx & 0x1f), nstart, pdst, func)
43553931Shibler }
43653931Shibler
43753931Shibler pdstLine += width;
43853931Shibler psrcLine += width;
43953931Shibler }
44053931Shibler } /* move right to left */
44153931Shibler }
44253931Shibler }
44353931Shibler #endif
444