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