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.4 (Berkeley) 06/01/93 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) + 102 ip->regbase) + FONTDATA; 103 stride = ip->fbwidth >> 3; 104 width = (ip->ftwidth + 7) / 8; 105 106 for (c = 0; c < 128; c++) { 107 fbmem = (u_char *) FBBASE + 108 (ip->fonty + (c / ip->cpl) * ip->ftheight) * 109 stride; 110 fbmem += (ip->fontx >> 3) + (c % ip->cpl) * width; 111 for (l = 0; l < ip->ftheight; l++) { 112 for (b = 0; b < width; b++) { 113 *fbmem++ = *dp; 114 dp += 2; 115 } 116 fbmem -= width; 117 fbmem += stride; 118 } 119 } 120 } 121 122 hyper_putc(ip, c, dy, dx, mode) 123 register struct ite_softc *ip; 124 int c, dy, dx, mode; 125 { 126 int wmrr = ((mode == ATTR_INV) ? RR_COPYINVERTED : RR_COPY); 127 128 hyper_windowmove(ip, charY(ip, c), charX(ip, c), 129 dy * ip->ftheight, dx * ip->ftwidth, 130 ip->ftheight, ip->ftwidth, wmrr); 131 } 132 133 hyper_cursor(ip, flag) 134 register struct ite_softc *ip; 135 register int flag; 136 { 137 if (flag == DRAW_CURSOR) 138 draw_cursor(ip) 139 else if (flag == MOVE_CURSOR) { 140 erase_cursor(ip) 141 draw_cursor(ip) 142 } 143 else 144 erase_cursor(ip) 145 } 146 147 hyper_clear(ip, sy, sx, h, w) 148 register struct ite_softc *ip; 149 register int sy, sx, h, w; 150 { 151 hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth, 152 sy * ip->ftheight, sx * ip->ftwidth, 153 h * ip->ftheight, w * ip->ftwidth, 154 RR_CLEAR); 155 } 156 157 hyper_scroll(ip, sy, sx, count, dir) 158 register struct ite_softc *ip; 159 register int sy, count; 160 int dir, sx; 161 { 162 register int dy; 163 register int dx = sx; 164 register int height = 1; 165 register int width = ip->cols; 166 167 if (dir == SCROLL_UP) { 168 dy = sy - count; 169 height = ip->rows - sy; 170 } 171 else if (dir == SCROLL_DOWN) { 172 dy = sy + count; 173 height = ip->rows - dy - 1; 174 } 175 else if (dir == SCROLL_RIGHT) { 176 dy = sy; 177 dx = sx + count; 178 width = ip->cols - dx; 179 } 180 else { 181 dy = sy; 182 dx = sx - count; 183 width = ip->cols - sx; 184 } 185 186 hyper_windowmove(ip, sy * ip->ftheight, sx * ip->ftwidth, 187 dy * ip->ftheight, dx * ip->ftwidth, 188 height * ip->ftheight, 189 width * ip->ftwidth, RR_COPY); 190 } 191 192 #include <hp300/dev/maskbits.h> 193 194 /* NOTE: 195 * the first element in starttab could be 0xffffffff. making it 0 196 * lets us deal with a full first word in the middle loop, rather 197 * than having to do the multiple reads and masks that we'd 198 * have to do if we thought it was partial. 199 */ 200 int starttab[32] = 201 { 202 0x00000000, 203 0x7FFFFFFF, 204 0x3FFFFFFF, 205 0x1FFFFFFF, 206 0x0FFFFFFF, 207 0x07FFFFFF, 208 0x03FFFFFF, 209 0x01FFFFFF, 210 0x00FFFFFF, 211 0x007FFFFF, 212 0x003FFFFF, 213 0x001FFFFF, 214 0x000FFFFF, 215 0x0007FFFF, 216 0x0003FFFF, 217 0x0001FFFF, 218 0x0000FFFF, 219 0x00007FFF, 220 0x00003FFF, 221 0x00001FFF, 222 0x00000FFF, 223 0x000007FF, 224 0x000003FF, 225 0x000001FF, 226 0x000000FF, 227 0x0000007F, 228 0x0000003F, 229 0x0000001F, 230 0x0000000F, 231 0x00000007, 232 0x00000003, 233 0x00000001 234 }; 235 236 int endtab[32] = 237 { 238 0x00000000, 239 0x80000000, 240 0xC0000000, 241 0xE0000000, 242 0xF0000000, 243 0xF8000000, 244 0xFC000000, 245 0xFE000000, 246 0xFF000000, 247 0xFF800000, 248 0xFFC00000, 249 0xFFE00000, 250 0xFFF00000, 251 0xFFF80000, 252 0xFFFC0000, 253 0xFFFE0000, 254 0xFFFF0000, 255 0xFFFF8000, 256 0xFFFFC000, 257 0xFFFFE000, 258 0xFFFFF000, 259 0xFFFFF800, 260 0xFFFFFC00, 261 0xFFFFFE00, 262 0xFFFFFF00, 263 0xFFFFFF80, 264 0xFFFFFFC0, 265 0xFFFFFFE0, 266 0xFFFFFFF0, 267 0xFFFFFFF8, 268 0xFFFFFFFC, 269 0xFFFFFFFE 270 }; 271 272 hyper_windowmove(ip, sy, sx, dy, dx, h, w, func) 273 struct ite_softc *ip; 274 int sy, sx, dy, dx, h, w, func; 275 { 276 int width; /* add to get to same position in next line */ 277 278 unsigned int *psrcLine, *pdstLine; 279 /* pointers to line with current src and dst */ 280 register unsigned int *psrc; /* pointer to current src longword */ 281 register unsigned int *pdst; /* pointer to current dst longword */ 282 283 /* following used for looping through a line */ 284 unsigned int startmask, endmask; /* masks for writing ends of dst */ 285 int nlMiddle; /* whole longwords in dst */ 286 register int nl; /* temp copy of nlMiddle */ 287 register unsigned int tmpSrc; 288 /* place to store full source word */ 289 register int xoffSrc; /* offset (>= 0, < 32) from which to 290 fetch whole longwords fetched 291 in src */ 292 int nstart; /* number of ragged bits at start of dst */ 293 int nend; /* number of ragged bits at end of dst */ 294 int srcStartOver; /* pulling nstart bits from src 295 overflows into the next word? */ 296 297 if (h == 0 || w == 0) 298 return; 299 300 width = ip->fbwidth >> 5; 301 302 if (sy < dy) /* start at last scanline of rectangle */ 303 { 304 psrcLine = ((unsigned int *) ip->fbbase) + ((sy+h-1) * width); 305 pdstLine = ((unsigned int *) ip->fbbase) + ((dy+h-1) * width); 306 width = -width; 307 } 308 else /* start at first scanline */ 309 { 310 psrcLine = ((unsigned int *) ip->fbbase) + (sy * width); 311 pdstLine = ((unsigned int *) ip->fbbase) + (dy * width); 312 } 313 314 /* x direction doesn't matter for < 1 longword */ 315 if (w <= 32) 316 { 317 int srcBit, dstBit; /* bit offset of src and dst */ 318 319 pdstLine += (dx >> 5); 320 psrcLine += (sx >> 5); 321 psrc = psrcLine; 322 pdst = pdstLine; 323 324 srcBit = sx & 0x1f; 325 dstBit = dx & 0x1f; 326 327 while(h--) 328 { 329 getandputrop(psrc, srcBit, dstBit, w, pdst, func) 330 pdst += width; 331 psrc += width; 332 } 333 } 334 else 335 { 336 maskbits(dx, w, startmask, endmask, nlMiddle) 337 if (startmask) 338 nstart = 32 - (dx & 0x1f); 339 else 340 nstart = 0; 341 if (endmask) 342 nend = (dx + w) & 0x1f; 343 else 344 nend = 0; 345 346 xoffSrc = ((sx & 0x1f) + nstart) & 0x1f; 347 srcStartOver = ((sx & 0x1f) + nstart) > 31; 348 349 if (sx >= dx) /* move left to right */ 350 { 351 pdstLine += (dx >> 5); 352 psrcLine += (sx >> 5); 353 354 while (h--) 355 { 356 psrc = psrcLine; 357 pdst = pdstLine; 358 359 if (startmask) 360 { 361 getandputrop(psrc, (sx & 0x1f), 362 (dx & 0x1f), nstart, pdst, func) 363 pdst++; 364 if (srcStartOver) 365 psrc++; 366 } 367 368 /* special case for aligned operations */ 369 if (xoffSrc == 0) 370 { 371 nl = nlMiddle; 372 while (nl--) 373 { 374 DoRop (*pdst, func, *psrc++, *pdst); 375 pdst++; 376 } 377 } 378 else 379 { 380 nl = nlMiddle + 1; 381 while (--nl) 382 { 383 getunalignedword (psrc, xoffSrc, tmpSrc) 384 DoRop (*pdst, func, tmpSrc, *pdst); 385 pdst++; 386 psrc++; 387 } 388 } 389 390 if (endmask) 391 { 392 getandputrop0(psrc, xoffSrc, nend, pdst, func); 393 } 394 395 pdstLine += width; 396 psrcLine += width; 397 } 398 } 399 else /* move right to left */ 400 { 401 pdstLine += (dx+w >> 5); 402 psrcLine += (sx+w >> 5); 403 /* if fetch of last partial bits from source crosses 404 a longword boundary, start at the previous longword 405 */ 406 if (xoffSrc + nend >= 32) 407 --psrcLine; 408 409 while (h--) 410 { 411 psrc = psrcLine; 412 pdst = pdstLine; 413 414 if (endmask) 415 { 416 getandputrop0(psrc, xoffSrc, nend, pdst, func); 417 } 418 419 nl = nlMiddle + 1; 420 while (--nl) 421 { 422 --psrc; 423 --pdst; 424 getunalignedword(psrc, xoffSrc, tmpSrc) 425 DoRop(*pdst, func, tmpSrc, *pdst); 426 } 427 428 if (startmask) 429 { 430 if (srcStartOver) 431 --psrc; 432 --pdst; 433 getandputrop(psrc, (sx & 0x1f), 434 (dx & 0x1f), nstart, pdst, func) 435 } 436 437 pdstLine += width; 438 psrcLine += width; 439 } 440 } /* move right to left */ 441 } 442 } 443 #endif 444