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.2 92/12/20$ 14 * 15 * @(#)ite_hy.c 7.3 (Berkeley) 12/27/92 16 */ 17 18 #include "ite.h" 19 #if NITE > 0 20 21 #include <sys/param.h> 22 #include <sys/conf.h> 23 #include <sys/proc.h> 24 #include <sys/ioctl.h> 25 #include <sys/tty.h> 26 #include <sys/systm.h> 27 #include <sys/uio.h> 28 29 #include <hp300/dev/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 if (dir == SCROLL_UP) { 167 dy = sy - count; 168 height = ip->rows - sy; 169 } 170 else if (dir == SCROLL_DOWN) { 171 dy = sy + count; 172 height = ip->rows - dy - 1; 173 } 174 else if (dir == SCROLL_RIGHT) { 175 dy = sy; 176 dx = sx + count; 177 width = ip->cols - dx; 178 } 179 else { 180 dy = sy; 181 dx = sx - count; 182 width = ip->cols - sx; 183 } 184 185 hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth, 186 dy * ip->ftheight, dx * ip->ftwidth, 187 height * ip->ftheight, 188 width * ip->ftwidth, RR_COPY); 189 } 190 191 #include <hp300/dev/maskbits.h> 192 193 /* NOTE: 194 * the first element in starttab could be 0xffffffff. making it 0 195 * lets us deal with a full first word in the middle loop, rather 196 * than having to do the multiple reads and masks that we'd 197 * have to do if we thought it was partial. 198 */ 199 int starttab[32] = 200 { 201 0x00000000, 202 0x7FFFFFFF, 203 0x3FFFFFFF, 204 0x1FFFFFFF, 205 0x0FFFFFFF, 206 0x07FFFFFF, 207 0x03FFFFFF, 208 0x01FFFFFF, 209 0x00FFFFFF, 210 0x007FFFFF, 211 0x003FFFFF, 212 0x001FFFFF, 213 0x000FFFFF, 214 0x0007FFFF, 215 0x0003FFFF, 216 0x0001FFFF, 217 0x0000FFFF, 218 0x00007FFF, 219 0x00003FFF, 220 0x00001FFF, 221 0x00000FFF, 222 0x000007FF, 223 0x000003FF, 224 0x000001FF, 225 0x000000FF, 226 0x0000007F, 227 0x0000003F, 228 0x0000001F, 229 0x0000000F, 230 0x00000007, 231 0x00000003, 232 0x00000001 233 }; 234 235 int endtab[32] = 236 { 237 0x00000000, 238 0x80000000, 239 0xC0000000, 240 0xE0000000, 241 0xF0000000, 242 0xF8000000, 243 0xFC000000, 244 0xFE000000, 245 0xFF000000, 246 0xFF800000, 247 0xFFC00000, 248 0xFFE00000, 249 0xFFF00000, 250 0xFFF80000, 251 0xFFFC0000, 252 0xFFFE0000, 253 0xFFFF0000, 254 0xFFFF8000, 255 0xFFFFC000, 256 0xFFFFE000, 257 0xFFFFF000, 258 0xFFFFF800, 259 0xFFFFFC00, 260 0xFFFFFE00, 261 0xFFFFFF00, 262 0xFFFFFF80, 263 0xFFFFFFC0, 264 0xFFFFFFE0, 265 0xFFFFFFF0, 266 0xFFFFFFF8, 267 0xFFFFFFFC, 268 0xFFFFFFFE 269 }; 270 271 hyper_windowmove(ip, sy, sx, dy, dx, h, w, func) 272 struct ite_softc *ip; 273 int sy, sx, dy, dx, h, w, func; 274 { 275 int width; /* add to get to same position in next line */ 276 277 unsigned int *psrcLine, *pdstLine; 278 /* pointers to line with current src and dst */ 279 register unsigned int *psrc; /* pointer to current src longword */ 280 register unsigned int *pdst; /* pointer to current dst longword */ 281 282 /* following used for looping through a line */ 283 unsigned int startmask, endmask; /* masks for writing ends of dst */ 284 int nlMiddle; /* whole longwords in dst */ 285 register int nl; /* temp copy of nlMiddle */ 286 register unsigned int tmpSrc; 287 /* place to store full source word */ 288 register int xoffSrc; /* offset (>= 0, < 32) from which to 289 fetch whole longwords fetched 290 in src */ 291 int nstart; /* number of ragged bits at start of dst */ 292 int nend; /* number of ragged bits at end of dst */ 293 int srcStartOver; /* pulling nstart bits from src 294 overflows into the next word? */ 295 296 if (h == 0 || w == 0) 297 return; 298 299 width = ip->fbwidth >> 5; 300 301 if (sy < dy) /* start at last scanline of rectangle */ 302 { 303 psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width); 304 pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width); 305 width = -width; 306 } 307 else /* start at first scanline */ 308 { 309 psrcLine = ((unsigned int *) ip->fbbase) + (sy * width); 310 pdstLine = ((unsigned int *) ip->fbbase) + (dy * width); 311 } 312 313 /* x direction doesn't matter for < 1 longword */ 314 if (w <= 32) 315 { 316 int srcBit, dstBit; /* bit offset of src and dst */ 317 318 pdstLine += (dx >> 5); 319 psrcLine += (sx >> 5); 320 psrc = psrcLine; 321 pdst = pdstLine; 322 323 srcBit = sx & 0x1f; 324 dstBit = dx & 0x1f; 325 326 while(h--) 327 { 328 getandputrop(psrc, srcBit, dstBit, w, pdst, func) 329 pdst += width; 330 psrc += width; 331 } 332 } 333 else 334 { 335 maskbits(dx, w, startmask, endmask, nlMiddle) 336 if (startmask) 337 nstart = 32 - (dx & 0x1f); 338 else 339 nstart = 0; 340 if (endmask) 341 nend = (dx + w) & 0x1f; 342 else 343 nend = 0; 344 345 xoffSrc = ((sx & 0x1f) + nstart) & 0x1f; 346 srcStartOver = ((sx & 0x1f) + nstart) > 31; 347 348 if (sx >= dx) /* move left to right */ 349 { 350 pdstLine += (dx >> 5); 351 psrcLine += (sx >> 5); 352 353 while (h--) 354 { 355 psrc = psrcLine; 356 pdst = pdstLine; 357 358 if (startmask) 359 { 360 getandputrop(psrc, (sx & 0x1f), 361 (dx & 0x1f), nstart, pdst, func) 362 pdst++; 363 if (srcStartOver) 364 psrc++; 365 } 366 367 /* special case for aligned operations */ 368 if (xoffSrc == 0) 369 { 370 nl = nlMiddle; 371 while (nl--) 372 { 373 DoRop (*pdst, func, *psrc++, *pdst); 374 pdst++; 375 } 376 } 377 else 378 { 379 nl = nlMiddle + 1; 380 while (--nl) 381 { 382 getunalignedword (psrc, xoffSrc, tmpSrc) 383 DoRop (*pdst, func, tmpSrc, *pdst); 384 pdst++; 385 psrc++; 386 } 387 } 388 389 if (endmask) 390 { 391 getandputrop0(psrc, xoffSrc, nend, pdst, func); 392 } 393 394 pdstLine += width; 395 psrcLine += width; 396 } 397 } 398 else /* move right to left */ 399 { 400 pdstLine += (dx+w >> 5); 401 psrcLine += (sx+w >> 5); 402 /* if fetch of last partial bits from source crosses 403 a longword boundary, start at the previous longword 404 */ 405 if (xoffSrc + nend >= 32) 406 --psrcLine; 407 408 while (h--) 409 { 410 psrc = psrcLine; 411 pdst = pdstLine; 412 413 if (endmask) 414 { 415 getandputrop0(psrc, xoffSrc, nend, pdst, func); 416 } 417 418 nl = nlMiddle + 1; 419 while (--nl) 420 { 421 --psrc; 422 --pdst; 423 getunalignedword(psrc, xoffSrc, tmpSrc) 424 DoRop(*pdst, func, tmpSrc, *pdst); 425 } 426 427 if (startmask) 428 { 429 if (srcStartOver) 430 --psrc; 431 --pdst; 432 getandputrop(psrc, (sx & 0x1f), 433 (dx & 0x1f), nstart, pdst, func) 434 } 435 436 pdstLine += width; 437 psrcLine += width; 438 } 439 } /* move right to left */ 440 } 441 } 442 #endif 443