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