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