1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: fb_start.c,v 4.300 91/06/27 20:42:40 root Rel41 $ SONY 11 * 12 * @(#)fb_start.c 7.4 (Berkeley) 03/09/93 13 */ 14 15 #include <sys/param.h> 16 #include <sys/systm.h> 17 18 #ifdef IPC_MRX 19 #include "../../iop/framebuf.h" 20 #include "../../iop/fbreg.h" 21 #include "page.h" 22 #else 23 #include <news3400/iop/framebuf.h> 24 #include <news3400/iop/fbreg.h> 25 #endif 26 27 #include <news3400/fb/fbdefs.h> 28 29 #ifdef CPU_SINGLE 30 #include <machine/cpu.h> 31 extern struct tty cons; 32 extern int cnstart(); 33 #define PRE_EMPT need_resched() 34 #endif 35 36 static struct fbdev *cfb = 0; 37 static lPoint mp; 38 #ifdef CPU_SINGLE 39 static int curs_pending = 0; 40 #endif 41 42 extern struct fbdevsw fbdevsw[]; 43 extern int nfbdev; 44 45 #ifdef CPU_SINGLE 46 extern char *ext_fnt_addr[]; 47 extern char *ext_fnt24_addr[]; 48 #else 49 extern char **ext_fnt_addr; 50 extern char **ext_fnt24_addr; 51 #endif 52 53 static char copyfuncv[MAXPLANE] = { 54 BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, /* SRC */ 55 BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, /* SRC */ 56 BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S /* SRC */ 57 }; 58 59 unsigned short fb_color_pallet_def[48] = { /* define initial color */ 60 /* R, G, B */ 61 0, 0, 0, 62 0, 0, 0x44, 63 0, 0x44, 0, 64 0, 0x44, 0x44, 65 0x44, 0, 0, 66 0x44, 0, 0x44, 67 0x44, 0x44, 0, 68 0x44, 0x44, 0x44, 69 0x88, 0x88, 0x88, 70 0, 0, 0xff, 71 0, 0xff, 0, 72 0, 0xff, 0xff, 73 0xff, 0, 0, 74 0xff, 0, 0xff, 75 0xff, 0xff, 0, 76 0xff, 0xff, 0xff 77 }; 78 79 unsigned short fb_gray_pallet_def[48] = { /* define initial color */ 80 /* R, G, B */ 81 0xff, 0xff, 0xff, 82 0xff, 0xff, 0, 83 0xff, 0, 0xff, 84 0xff, 0, 0, 85 0, 0xff, 0xff, 86 0, 0xff, 0, 87 0, 0, 0xff, 88 0x88, 0x88, 0x88, 89 0x44, 0x44, 0x44, 90 0x44, 0x44, 0, 91 0x44, 0, 0x44, 92 0x44, 0, 0, 93 0, 0x44, 0x44, 94 0, 0x44, 0, 95 0, 0, 0x44, 96 0, 0, 0 97 }; 98 99 static int bitmap_use; /* shared variable for bitmap exclusion ctrl */ 100 101 #ifdef IPC_MRX 102 struct fb_map rommap; 103 #endif 104 105 #ifdef CPU_SINGLE 106 void 107 lock_bitmap() 108 { 109 int s; 110 111 /* wait(bitmap_use) */ 112 s = splbitmap(); 113 while (bitmap_use & FB_BUSY) { 114 bitmap_use |= FB_WANTED; 115 sleep((caddr_t)&bitmap_use, FBPRI); 116 } 117 bitmap_use |= FB_BUSY; 118 splx(s); 119 } 120 121 void 122 unlock_bitmap() 123 { 124 int s; 125 126 /* signal(bitmap_use) */ 127 s = splbitmap(); 128 if (bitmap_use & FB_WANTED) 129 wakeup((caddr_t)&bitmap_use); 130 bitmap_use &= ~(FB_BUSY|FB_WANTED); 131 splx(s); 132 } 133 134 lock_bitmap_poll() 135 { 136 int s; 137 138 /* wait(bitmap_use) */ 139 140 s = splbitmap(); 141 if (bitmap_use & (FB_BUSY|FB_WANTED)) { 142 splx(s); 143 return (1); 144 } 145 bitmap_use |= FB_BUSY; 146 splx(s); 147 return (0); 148 } 149 150 void 151 unlock_bitmap_poll() 152 { 153 int s; 154 155 /* signal(bitmap_use) */ 156 s = splbitmap(); 157 if (bitmap_use & FB_WANTED) 158 wakeup((caddr_t)&bitmap_use); 159 bitmap_use &= ~(FB_BUSY|FB_WANTED); 160 splx(s); 161 } 162 163 bmlockedp() 164 { 165 return (bitmap_use & (FB_WANTED|FB_BUSY)); 166 } 167 168 #ifdef NOTDEF /* KU:XXX not necessary for news3200 */ 169 void 170 rop_wait(fb) 171 struct fbdev *fb; 172 { 173 register int s; 174 int i; 175 176 s = splbitmap(); 177 /* KU:XXX trick! */ 178 #define in_interrupt() ((caddr_t)&fb < (caddr_t)MACH_CODE_START) 179 if (in_interrupt() || (fb->run_flag & FB_WAITING)) { 180 splx(s); 181 fbbm_rop_wait(fb); 182 } else { 183 if (fbbm_ioctl(fb, FB_STATUSCHECK, 0) & 184 (FB_STATUS_ROPWAIT|FB_STATUS_ROPEXEC)) { 185 186 i = FB_INT_ROPDONE; 187 fbbm_ioctl(fb, FB_INTENABLE, &i); 188 189 if (!(fbbm_ioctl(fb, FB_STATUSCHECK, 0) & 190 (FB_STATUS_ROPWAIT|FB_STATUS_ROPEXEC))) { 191 i = FB_INT_ROPDONE; 192 fbbm_ioctl(fb, FB_INTCLEAR, &i); 193 } else { 194 fb->run_flag |= FB_WAITING; 195 sleep((caddr_t)&fb->run_flag, FBPRI); 196 } 197 } 198 splx(s); 199 } 200 } 201 #endif /* NOTDEF */ 202 #else /* CPU_SINGLE */ 203 #ifdef IPC_MRX 204 struct page { 205 char bytes[NBPG]; 206 }; 207 extern struct page *page_base; 208 extern struct page *page_max; 209 extern struct map pagemap[]; 210 extern struct pte_iop page_pt[]; 211 extern int mapped_page; 212 213 caddr_t 214 fb_map_page(map, n, prot) 215 register int *map; 216 register int n; 217 register int prot; 218 { 219 register int x; 220 register struct pte_iop *p; 221 register struct page *addr; 222 register int s = spl7(); 223 static int last_x, last_n; 224 225 if (last_n >= n) { 226 x = last_x; 227 } else { 228 rmfree(pagemap, last_n, last_x); 229 mapped_page -= last_n; 230 last_x = 0; 231 last_n = 0; 232 if ((x = rmalloc(pagemap, n)) <= 0) { 233 splx(s); 234 return (NULL); 235 } 236 mapped_page += n; 237 last_x = x; 238 last_n = n; 239 } 240 addr = page_base + x; 241 prot |= PG_PAGE; 242 243 for (p = page_pt + x; n > 0; p++, n--) { 244 *(int *)p = prot | *map++; 245 tbis((caddr_t)addr); 246 addr++; 247 } 248 249 splx(s); 250 return ((caddr_t)(page_base + x)); 251 } 252 253 caddr_t 254 fb_map_page2(map, n, prot) 255 register int *map; 256 register int n; 257 register int prot; 258 { 259 register int x; 260 register struct pte_iop *p; 261 register struct page *addr; 262 register int s; 263 264 if (n == 0) 265 return (NULL); 266 s = spl7(); 267 if ((x = rmalloc(pagemap, n)) <= 0) { 268 splx(s); 269 return (NULL); 270 } 271 mapped_page += n; 272 addr = page_base + x; 273 prot |= PG_PAGE; 274 275 for (p = page_pt + x; n > 0; p++, n--) { 276 *(int *)p = prot | (*map++); 277 tbis((caddr_t)addr); 278 addr++; 279 } 280 281 splx(s); 282 return ((caddr_t)(page_base + x)); 283 } 284 #endif /* IPC_MRX */ 285 #endif /* CPU_SINGLE */ 286 287 iopmemfbmap(addr, len, map) 288 register caddr_t addr; 289 register int len; 290 register struct fb_map *map; 291 { 292 register caddr_t *p; 293 register int i; 294 295 map->fm_vaddr = addr; 296 map->fm_offset = (unsigned)addr & CLOFSET; 297 map->fm_count = len; 298 len += map->fm_offset; 299 p = map->fm_addr; 300 addr -= map->fm_offset; 301 302 for (i = 0; i < NFBMAP && len > 0; i++) { 303 *p++ = addr; 304 addr += CLBYTES; 305 len -= CLBYTES; 306 } 307 } 308 309 int 310 nofunc() 311 { 312 return 0; 313 } 314 315 int 316 error() 317 { 318 return FB_RERROR; 319 } 320 321 void 322 checkArea(fb, x, y) 323 register struct fbdev *fb; 324 register int *x, *y; 325 { 326 if (*x < fb->moveArea.origin.x) 327 *x = fb->moveArea.origin.x; 328 if (*y < fb->moveArea.origin.y) 329 *y = fb->moveArea.origin.y; 330 if (*x >= (fb->moveArea.origin.x + fb->moveArea.extent.x)) 331 *x = (fb->moveArea.origin.x + fb->moveArea.extent.x) - 1; 332 if (*y >= (fb->moveArea.origin.y + fb->moveArea.extent.y)) 333 *y = (fb->moveArea.origin.y + fb->moveArea.extent.y) - 1; 334 } 335 336 cursorIn(fb, clip) 337 register struct fbdev *fb; 338 register lRectangle *clip; 339 { 340 if (clip == 0) 341 return (1); 342 if (cfb != fb) 343 return (0); 344 345 return (clip->origin.x < fb->cursorP.x + fb->size.x && 346 clip->origin.x + clip->extent.x > fb->cursorP.x && 347 clip->origin.y < fb->cursorP.y + fb->size.y && 348 clip->origin.y + clip->extent.y > fb->cursorP.y); 349 } 350 351 void 352 fbcopy1(src, dst, fv) 353 lPoint src; 354 lPoint dst; 355 char *fv; 356 { 357 lRectangle sr, dr; 358 359 sr.origin = src; 360 sr.extent = cfb->size; 361 dr.origin = dst; 362 if (cliprect2(&sr, &cfb->FrameRect, &dr, &cfb->VisRect)) { 363 fbbm_rop_init(cfb, fv); 364 fbbm_rop_copy(cfb, &sr, &dr.origin, 1, FB_PLANEALL); 365 } 366 } 367 368 void 369 fbcopy2(src, dst) 370 lPoint src; 371 lPoint dst; 372 { 373 lRectangle sr, dr; 374 375 sr.origin = src; 376 sr.extent = cfb->size; 377 dr.origin = dst; 378 if (cliprect2(&sr, &cfb->FrameRect, &dr, &cfb->FrameRect)) { 379 fbbm_rop_init(cfb, copyfuncv); 380 fbbm_rop_copy(cfb, &sr, &dr.origin, 0, FB_PLANEALL); 381 } 382 } 383 384 void 385 fbcopy3(src, dst) 386 lPoint src; 387 lPoint dst; 388 { 389 lRectangle sr, dr; 390 391 sr.origin = src; 392 sr.extent = cfb->size; 393 dr.origin = dst; 394 if (cliprect2(&sr, &cfb->FrameRect, &dr, &cfb->VisRect)) { 395 fbbm_rop_init(cfb, copyfuncv); 396 fbbm_rop_copy(cfb, &sr, &dr.origin, 0, FB_PLANEALL); 397 } 398 } 399 400 void 401 cursorOn(fb) 402 register struct fbdev *fb; 403 { 404 #ifdef CPU_SINGLE 405 int s = splbitmap(); 406 #endif 407 408 if (cfb == fb && fb->cursorShow && !fb->cursorVis) { 409 if (fb->hard_cursor) { 410 fbbm_cursor_on(fb); 411 } else { 412 fbcopy2(fb->cursorP, fb->SaveRect.origin); 413 fbcopy1(fb->MaskRect.origin, fb->cursorP, 414 fb->maskfuncv); 415 fbcopy1(fb->CursorRect.origin, fb->cursorP, 416 fb->curfuncv); 417 } 418 fb->cursorVis = 1; 419 } 420 #ifdef CPU_SINGLE 421 splx(s); 422 #endif 423 } 424 425 void 426 cursorOff(fb) 427 register struct fbdev *fb; 428 { 429 #ifdef CPU_SINGLE 430 int s = splbitmap(); 431 #endif 432 433 if (cfb == fb && fb->cursorShow && fb->cursorVis) { 434 if (fb->hard_cursor) 435 fbbm_cursor_off(fb); 436 else 437 fbcopy3(fb->SaveRect.origin, fb->cursorP); 438 fb->cursorVis = 0; 439 } 440 #ifdef CPU_SINGLE 441 splx(s); 442 #endif 443 } 444 445 void 446 softCursorCheck(fb, stype, srect, dtype, drect) 447 struct fbdev *fb; 448 char stype, dtype; 449 lRectangle *srect, *drect; 450 { 451 if (cfb == fb && cfb->cursorVis && 452 ((stype == BM_FB && cursorIn(fb, srect)) || 453 (dtype == BM_FB && cursorIn(fb, drect)))) 454 cursorOff(cfb); 455 } 456 457 void 458 cursorCheck(fb, stype, srect, dtype, drect) 459 struct fbdev *fb; 460 char stype, dtype; 461 lRectangle *srect, *drect; 462 { 463 if (!fb->hard_cursor) 464 softCursorCheck(fb, stype, srect, dtype, drect); 465 } 466 467 int 468 redrawCursor(fb) 469 register struct fbdev *fb; 470 { 471 int s; 472 lPoint tmp; 473 474 if (cfb == fb && fb->cursorSet) { 475 s = spl7(); 476 tmp = mp; 477 splx(s); 478 479 #ifdef CPU_SINGLE 480 s = splbitmap(); 481 #endif 482 if (fb->cursorP.x != tmp.x || fb->cursorP.y != tmp.y) { 483 if (fb->cursorVis) { 484 if (! fb->hard_cursor) { 485 fbcopy3(fb->SaveRect.origin, 486 fb->cursorP); 487 } 488 } 489 fb->cursorP = tmp; 490 if (fb->hard_cursor) { 491 fbbm_cursor_off(fb); 492 fbbm_cursor_move(fb); 493 } 494 if (fb->cursorVis) { 495 if (fb->hard_cursor) { 496 fbbm_cursor_on(fb); 497 } else { 498 fbcopy2(fb->cursorP, 499 fb->SaveRect.origin); 500 fbcopy1(fb->MaskRect.origin, 501 fb->cursorP, fb->maskfuncv); 502 fbcopy1(fb->CursorRect.origin, 503 fb->cursorP, fb->curfuncv); 504 } 505 } 506 } 507 #ifdef CPU_SINGLE 508 splx(s); 509 #endif 510 } 511 return (0); 512 } 513 514 void 515 updateCursor(x, y, flag) 516 int *x, *y; 517 int flag; 518 { 519 int s; 520 521 if (cfb && cfb->cursorSet) { 522 checkArea(cfb, x, y); 523 s = spl7(); 524 mp.x = *x - cfb->hot.x; 525 mp.y = *y - cfb->hot.y; 526 splx(s); 527 #ifdef CPU_SINGLE 528 if (flag || cfb->hard_cursor) { 529 curs_pending = 0; 530 redrawCursor(cfb); 531 } else if (cfb->type == FB_LCDM) { 532 if (!lock_bitmap_poll()) { 533 curs_pending = 0; 534 redrawCursor(cfb); 535 unlock_bitmap_poll(); 536 } else { 537 curs_pending = 1; 538 } 539 } 540 #else 541 redrawCursor(cfb); 542 #endif 543 } 544 } 545 546 setCursor(fb, cursor) 547 register struct fbdev *fb; 548 register lCursor2 *cursor; 549 { 550 register char *fv; 551 register int f0, f1, i, color; 552 #ifdef CPU_SINGLE 553 register int s = splbitmap(); 554 #endif 555 int data; 556 557 if (cfb == fb) { 558 cursorOff(cfb); 559 fb->cursorShow = 0; 560 fb->cursorP.x += cfb->hot.x; 561 fb->cursorP.y += cfb->hot.y; 562 #ifdef CPU_SINGLE 563 data = FB_INT_VSYNC; 564 fbbm_ioctl(fb, FB_INTCLEAR, &data); 565 #endif 566 cfb = NULL; 567 } 568 569 if (cursor) { 570 fb->CursorRect = cursor->cursorRect; 571 fb->MaskRect = cursor->maskRect; 572 fb->SaveRect = cursor->saveRect; 573 fb->moveArea = cursor->moveArea; 574 fb->hot = cursor->hot; 575 fb->size = cursor->size; 576 577 f0 = 0x4 | ((cursor->func >> 2) & 0x3); 578 f1 = 0x4 | (cursor->func & 0x3); 579 580 i = fb->fbNplane; 581 fv = fb->curfuncv; 582 color = cursor->cursor_color; 583 while (i-- > 0) { 584 *fv++ = (color & 1) ? f1 : f0; 585 color >>= 1; 586 } 587 588 i = fb->fbNplane; 589 fv = fb->maskfuncv; 590 color = cursor->mask_color; 591 while (i-- > 0) { 592 *fv++ = (color & 1) ? f1 : f0; 593 color >>= 1; 594 } 595 596 checkArea(fb, &fb->cursorP.x, &fb->cursorP.y); 597 fb->cursorP.x -= fb->hot.x; 598 fb->cursorP.y -= fb->hot.y; 599 fb->cursorSet = 1; 600 fb->cursorShow = 0; 601 fb->cursorVis = 0; 602 if (fb->hard_cursor) { 603 fbbm_cursor_off(fb); 604 fbbm_cursor_set(fb, cursor->cursor_color, cursor->mask_color); 605 fbbm_cursor_move(fb); 606 } 607 } else { 608 fb->cursorP.x = fb->VisRect.extent.x / 2; 609 fb->cursorP.y = fb->VisRect.extent.y / 2; 610 fb->cursorSet = 0; 611 fb->cursorShow = 0; 612 fb->cursorVis = 0; 613 if (fb->hard_cursor) 614 fbbm_cursor_off(fb); 615 } 616 #ifdef CPU_SINGLE 617 splx(s); 618 #endif 619 return (FB_ROK); 620 } 621 622 showCursor(fb) 623 register struct fbdev *fb; 624 { 625 int data; 626 #ifdef CPU_SINGLE 627 register int s = splbitmap(); 628 #endif 629 630 if (fb->cursorSet && !fb->cursorShow) { 631 if (cfb && cfb != fb) { 632 cursorOff(cfb); 633 cfb->cursorShow = 0; 634 } 635 cfb = fb; 636 fb->cursorShow = 1; 637 mp = fb->cursorP; 638 cursorOn(fb); 639 #ifdef CPU_SINGLE 640 data = FB_INT_VSYNC; 641 fbbm_ioctl(fb, FB_INTENABLE, &data); 642 splx(s); 643 #endif 644 return (FB_ROK); 645 } 646 #ifdef CPU_SINGLE 647 splx(s); 648 #endif 649 return (FB_RERROR); 650 } 651 652 653 hideCursor(fb) 654 register struct fbdev *fb; 655 { 656 int data; 657 #ifdef CPU_SINGLE 658 int s = splbitmap(); 659 #endif 660 661 if (cfb == fb) { 662 cursorOff(fb); 663 fb->cursorShow = 0; 664 #ifdef CPU_SINGLE 665 data = FB_INT_VSYNC; 666 fbbm_ioctl(fb, FB_INTCLEAR, &data); 667 splx(s); 668 #endif 669 return (FB_ROK); 670 } 671 #ifdef CPU_SINGLE 672 splx(s); 673 #endif 674 return (FB_RERROR); 675 } 676 677 678 moveCursor(fb, point) 679 struct fbdev *fb; 680 lPoint *point; 681 { 682 if (cfb == fb) { 683 updateCursor(&point->x, &point->y, 1); 684 return (FB_ROK); 685 } 686 return (FB_RERROR); 687 } 688 689 #ifdef CPU_SINGLE 690 rop_xint() 691 { 692 register struct fbdev *fb; 693 register int i; 694 register int done = 0; 695 int event, data; 696 int s = splbitmap(); 697 698 for (i = 0, fb = fbdev; i < nfbdev; i++, fb++) { 699 if (fb->type && (event = fbbm_ioctl(fb, FB_INTCHECK, 0))) { 700 #ifdef notyet /* KU:XXX */ 701 intrcnt[INTR_BITMAP]++; 702 #endif 703 done = 1; 704 if (event & FB_INT_VSYNC) { 705 data = FB_INT_VSYNC; 706 fbbm_ioctl(fb, FB_INTCLEAR, &data); 707 if (!lock_bitmap_poll()) { 708 curs_pending = 0; 709 redrawCursor(fb); 710 unlock_bitmap_poll(); 711 } else { 712 curs_pending = 1; 713 } 714 data = FB_INT_VSYNC; 715 fbbm_ioctl(fb, FB_INTENABLE, &data); 716 } 717 if (event & FB_INT_ROPDONE) { 718 if(fb->run_flag & FB_WAITING) { 719 data = FB_INT_ROPDONE; 720 fbbm_ioctl(fb, FB_INTCLEAR, &data); 721 if (!(fbbm_ioctl(fb, FB_STATUSCHECK, 0) 722 & (FB_STATUS_ROPWAIT|FB_STATUS_ROPEXEC))) { 723 fb->run_flag &= ~FB_WAITING; 724 wakeup(&(fb->run_flag)); 725 } else { 726 data = FB_INT_ROPDONE|0x100; 727 fbbm_ioctl(fb, FB_INTENABLE, &data); 728 } 729 } 730 } 731 } 732 } 733 splx(s); 734 return (done); 735 } 736 #endif /* CPU_SINGLE */ 737 738 cliprect2(sr, sc, dr, dc) 739 register lRectangle *sr; 740 register lRectangle *sc; 741 register lRectangle *dr; 742 register lRectangle *dc; 743 { 744 register int d; 745 746 /* src left/right edge */ 747 if ((d = sr->origin.x - sc->origin.x) < 0) { 748 sr->extent.x += d; 749 sr->origin.x -= d; 750 dr->origin.x -= d; 751 d = sr->extent.x - sc->extent.x; 752 } else 753 d += sr->extent.x - sc->extent.x; 754 if (d > 0) 755 sr->extent.x -= d; 756 757 /* src top/bottom edge */ 758 if ((d = sr->origin.y - sc->origin.y) < 0) { 759 sr->extent.y += d; 760 sr->origin.y -= d; 761 dr->origin.y -= d; 762 d = sr->extent.y - sc->extent.y; 763 } else 764 d += sr->extent.y - sc->extent.y; 765 if (d > 0) 766 sr->extent.y -= d; 767 768 if (sr->extent.x <= 0 || sr->extent.y <= 0) 769 return (0); 770 771 /* dst left/right edge */ 772 if ((d = dr->origin.x - dc->origin.x) < 0) { 773 dr->origin.x -= d; 774 sr->extent.x += d; 775 sr->origin.x -= d; 776 d = sr->extent.x - dc->extent.x; 777 } else 778 d += sr->extent.x - dc->extent.x; 779 if (d > 0) 780 sr->extent.x -= d; 781 782 /* dst top/bottom edge */ 783 if ((d = dr->origin.y - dc->origin.y) < 0) { 784 dr->origin.y -= d; 785 sr->extent.y += d; 786 sr->origin.y -= d; 787 d = sr->extent.y - dc->extent.y; 788 } else 789 d += sr->extent.y - dc->extent.y; 790 if (d > 0) 791 sr->extent.y -= d; 792 793 if (sr->extent.x <= 0 || sr->extent.y <= 0) 794 return (0); 795 796 dr->extent = sr->extent; 797 return (1); 798 } 799 800 cliprect(r, crp, p) 801 register lRectangle *r; 802 register lRectangle *crp; 803 register lRectangle *p; 804 { 805 register int d; 806 807 /* left edge */ 808 if ((d = r->origin.x - crp->origin.x) < 0) { 809 r->extent.x += d; 810 r->origin.x -= d; 811 if (p) { 812 p->extent.x += d; 813 p->origin.x -= d; 814 } 815 d = r->extent.x - crp->extent.x; 816 } else 817 d += r->extent.x - crp->extent.x; 818 819 /* right edge */ 820 if (d > 0) { 821 r->extent.x -= d; 822 if (p) 823 p->extent.x -= d; 824 } 825 826 /* top edge */ 827 if ((d = r->origin.y - crp->origin.y) < 0) { 828 r->extent.y += d; 829 r->origin.y -= d; 830 if (p) { 831 p->extent.y += d; 832 p->origin.y -= d; 833 } 834 d = r->extent.y - crp->extent.y; 835 } else 836 d += r->extent.y - crp->extent.y; 837 838 /* bottom edge */ 839 if (d > 0) { 840 r->extent.y -= d; 841 if (p) 842 p->extent.y -= d; 843 } 844 845 return (r->extent.x > 0 && r->extent.y > 0); 846 } 847 848 getclip(fb, bmp, crp) 849 struct fbdev *fb; 850 lBitmap *bmp; 851 lRectangle *crp; 852 { 853 /* limit clip rectangle to bitmap rectangle */ 854 if (!cliprect(crp, &bmp->rect, (lRectangle*)0)) 855 return (0); 856 857 /* limit clip rectangle to frame buffer */ 858 if ((bmp->type == BM_FB) && 859 !cliprect(crp, &fb->FrameRect, (lRectangle*)0)) 860 return (0); 861 return (1); 862 } 863 864 865 clipsrc(fb, bmp) 866 struct fbdev *fb; 867 lBitmap *bmp; 868 { 869 /* limit clip rectangle to frame buffer */ 870 if (bmp->type == BM_FB && 871 !cliprect(&bmp->rect, &fb->FrameRect, (lRectangle*)0)) 872 return (0); 873 return (1); 874 } 875 876 877 setrop(fb, func, pmask, fore, aux, trans, sbp, dbp) 878 register struct fbdev *fb; 879 register unsigned int func; 880 int pmask; 881 register int fore, aux; 882 int trans; 883 lBitmap *sbp, *dbp; 884 { 885 register char *funcp; 886 register int i; 887 char tmp[4]; 888 889 /* set plane register */ 890 891 fb->Mode = 0; 892 fb->Pmask = pmask; 893 fb->func = func; 894 fb->fore = fore; 895 fb->aux = aux; 896 fb->trans = trans; 897 898 if (sbp->depth > 1) 899 fb->Mode |= 2; 900 901 if (dbp->depth > 1) 902 fb->Mode |= 1; 903 904 /* set rop function register */ 905 func &= 0xf; 906 907 tmp[0] = TRANS(trans, (func & 0x0c) | (func>>2)); 908 tmp[1] = TRANS(trans, (func>>2) | ((func<<2) & 0x0c)); 909 tmp[2] = TRANS(trans, func); 910 tmp[3] = TRANS(trans, (func<<2) & 0x0c | func & 3); 911 912 funcp = fb->funcvec; 913 for (i = fb->fbNplane; --i >= 0;) { 914 *funcp++ = tmp[((fore & 1) << 1) | (aux & 1)]; 915 fore >>= 1; aux >>= 1; 916 } 917 return (0); 918 } 919 920 /* 921 * bitblt within frame buffer 922 */ 923 924 bitblt_fb(fb, sbp, srp, dbp, dpp, crp) 925 register struct fbdev *fb; 926 register lBitmap *sbp; /* source bitmap (FB) */ 927 lRectangle *srp; /* source rectangle */ 928 lBitmap *dbp; /* destination bitmap (FB) */ 929 lPoint *dpp; /* destination point */ 930 lRectangle *crp; /* clip region in destination */ 931 { 932 lRectangle sr; 933 lRectangle dr; 934 register int wplane, i, j; 935 936 sr = *srp; 937 dr.origin = *dpp; 938 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 939 return (0); 940 941 fbbm_rop_init(fb, fb->funcvec); 942 943 switch (fb->Mode) { 944 945 case MODE_1to1: 946 fb->Pmask &= 1; 947 948 case MODE_NtoN: 949 950 fbbm_rop_copy(fb, &sr, &dr.origin, 0, fb->Pmask); 951 break; 952 953 case MODE_1toN: 954 fbbm_rop_copy(fb, &sr, &dr.origin, 1, fb->Pmask); 955 break; 956 957 case MODE_Nto1: 958 wplane = 1; 959 for (i = 0, j = sbp->depth; i < j; i++) { 960 if (fb->Pmask & wplane) { 961 fbbm_rop_copy(fb, &sr, &dr.origin, i + 1, 962 fb->Pmask >> 16); 963 break; 964 } 965 wplane <<= 1; 966 } 967 break; 968 default: 969 return (-1); 970 } 971 return (0); 972 } 973 974 /* 975 * bitblt from main memory to frame buffer 976 */ 977 978 bitblt_tofb(fb, sbp, srp, dbp, dpp, crp) 979 register struct fbdev *fb; 980 register lBitmap *sbp; /* source bitmap (MEM) */ 981 lRectangle *srp; /* source rectangle */ 982 lBitmap *dbp; /* destination bitmap (FB) */ 983 lPoint *dpp; /* destination point */ 984 lRectangle *crp; /* clip region in destination */ 985 { 986 register unsigned p; 987 register struct fb_map *smap; 988 register int i, n, m; 989 lRectangle sr; 990 lRectangle dr; 991 register int wplane; 992 #ifdef IPC_MRX 993 extern struct fb_map rommap; 994 register int pages; 995 #endif 996 997 smap = (struct fb_map*)sbp->base; 998 999 sr = *srp; 1000 dr.origin = *dpp; 1001 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1002 return (0); 1003 dr.extent = sr.extent; 1004 1005 /* transform source rectangle */ 1006 sr.origin.x -= sbp->rect.origin.x; 1007 sr.origin.y -= sbp->rect.origin.y; 1008 1009 /* 1010 * check memory map specification 1011 */ 1012 p = smap->fm_offset; 1013 #ifdef IPC_MRX 1014 pages = btoc(smap->fm_offset + smap->fm_count); 1015 rommap.fm_vaddr = fb_map_page(smap->fm_addr, pages, 1016 fb->cache_off ? PG_S|PG_WP|PG_CI : PG_S|PG_WP); 1017 rommap.fm_offset = 0; 1018 smap = &rommap; 1019 #endif 1020 1021 wplane = 1; 1022 1023 fbbm_rop_winit(fb); 1024 1025 switch (fb->Mode) { 1026 case MODE_1to1: 1027 fbbm_rop_write(fb, smap, p, sbp->width, 1028 &sr, &dr, fb->Pmask & 0x01); 1029 break; 1030 case MODE_1toN: 1031 fbbm_rop_write(fb, smap, p, sbp->width, 1032 &sr, &dr, fb->Pmask); 1033 break; 1034 case MODE_Nto1: 1035 m = sbp->width * sbp->rect.extent.y; 1036 for (i = 0; i < sbp->depth; i++, wplane <<= 1) { 1037 if (fb->Pmask & wplane) { 1038 p += (m * i) << 1; 1039 fbbm_rop_write(fb, smap, p, sbp->width, 1040 &sr, &dr, wplane); 1041 break; 1042 } 1043 wplane <<= 1; 1044 } 1045 break; 1046 case MODE_NtoN: 1047 n = min(sbp->depth, fb->fbNplane); 1048 m = sbp->width * sbp->rect.extent.y; 1049 p += (m << 1) * n; 1050 wplane = 1 << (n - 1); 1051 for (i = n; i > 0; i--) { 1052 /* get next plane */ 1053 p -= m << 1; 1054 if (fb->Pmask & wplane) 1055 fbbm_rop_write(fb, smap, p, sbp->width, 1056 &sr, &dr, wplane); 1057 /* next plane mask */ 1058 wplane >>= 1; 1059 } 1060 break; 1061 default: 1062 return (-1); 1063 } 1064 return (0); 1065 } 1066 1067 /* 1068 * bitblt from frame buffer to main memroy 1069 */ 1070 1071 bitblt_tomem(fb, sbp, srp, dbp, dpp, crp) 1072 struct fbdev *fb; 1073 lBitmap *sbp; /* source bitmap (FB) */ 1074 lRectangle *srp; /* source rectangle */ 1075 lBitmap *dbp; /* destination bitmap (MEM) */ 1076 lPoint *dpp; /* destination point */ 1077 lRectangle *crp; /* clip region in destination */ 1078 { 1079 register struct fb_map *dmap; 1080 register unsigned p; 1081 register int i, n, m; 1082 lRectangle sr; 1083 lRectangle dr; 1084 int plane; 1085 #ifdef IPC_MRX 1086 extern struct fb_map rommap; 1087 register int pages; 1088 #endif 1089 1090 dmap = (struct fb_map*)dbp->base; 1091 1092 sr = *srp; 1093 dr.origin = *dpp; 1094 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1095 return (0); 1096 dr.extent = sr.extent; 1097 1098 dr.origin.x -= dbp->rect.origin.x; 1099 dr.origin.y -= dbp->rect.origin.y; 1100 1101 p = dmap->fm_offset; 1102 #ifdef IPC_MRX 1103 pages = btoc(dmap->fm_offset + dmap->fm_count); 1104 rommap.fm_vaddr = fb_map_page(dmap->fm_addr, pages, PG_S); 1105 rommap.fm_offset = 0; 1106 dmap = &rommap; 1107 #endif 1108 1109 plane = 1; 1110 1111 /* Wait for rop busy */ 1112 1113 switch (fb->Mode) { 1114 1115 case MODE_1to1: 1116 if (fb->Pmask & plane) 1117 fbbm_rop_read(fb, dmap, p, dbp->width, 1118 &sr, &dr, 0, 0); 1119 break; 1120 1121 case MODE_1toN: 1122 m = (dbp->width * dbp->rect.extent.y) << 1; 1123 for (i = 0; i < dbp->depth; i++) { 1124 if (fb->Pmask & plane) 1125 fbbm_rop_read(fb, dmap, p, dbp->width, 1126 &sr, &dr, 0, i); 1127 /* next plane */ 1128 p += m; 1129 plane <<= 1; 1130 } 1131 break; 1132 1133 case MODE_Nto1: 1134 for (i = 0; i < sbp->depth; i++, plane <<= 1) { 1135 if (fb->Pmask & plane) { 1136 fbbm_rop_read(fb, dmap, p, dbp->width, 1137 &sr, &dr, i, 0); 1138 break; 1139 } 1140 } 1141 break; 1142 1143 case MODE_NtoN: 1144 n = min(dbp->depth, fb->fbNplane); 1145 m = (dbp->width * dbp->rect.extent.y) << 1; 1146 for (i = 0; i < n; i++) { 1147 if (fb->Pmask & plane) 1148 fbbm_rop_read(fb, dmap, p, dbp->width, 1149 &sr, &dr, i, i); 1150 /* next plane */ 1151 p += m; 1152 plane <<= 1; 1153 } 1154 1155 break; 1156 1157 default: 1158 return (-1); 1159 } 1160 1161 return (0); 1162 } 1163 1164 bitblt_mem(fb, sbp, srp, dbp, dpp, crp) 1165 struct fbdev *fb; 1166 register lBitmap *sbp; 1167 lRectangle *srp; 1168 register lBitmap *dbp; 1169 lPoint *dpp; 1170 lRectangle *crp; 1171 { 1172 register int i; 1173 register int plane; 1174 register struct fb_map *smap, *dmap; 1175 register unsigned int ps, pd; 1176 lRectangle sr; 1177 lRectangle dr; 1178 #ifdef IPC_MRX 1179 static struct fb_map drommap; 1180 int spages, dpages; 1181 #endif 1182 1183 smap = (struct fb_map*)sbp->base; 1184 dmap = (struct fb_map*)dbp->base; 1185 1186 sr = *srp; 1187 dr.origin = *dpp; 1188 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1189 return (0); 1190 1191 /* normalize source/destination coordinates */ 1192 sr.origin.x -= sbp->rect.origin.x; 1193 sr.origin.y -= sbp->rect.origin.y; 1194 dr.origin.x -= dbp->rect.origin.x; 1195 dr.origin.y -= dbp->rect.origin.y; 1196 1197 ps = smap->fm_offset; 1198 pd = dmap->fm_offset; 1199 #ifdef IPC_MRX 1200 spages = btoc(smap->fm_offset + smap->fm_count); 1201 dpages = btoc(dmap->fm_offset + dmap->fm_count); 1202 rommap.fm_vaddr = fb_map_page2(smap->fm_addr, spages, PG_S|PG_WP); 1203 rommap.fm_offset = 0; 1204 drommap.fm_vaddr = fb_map_page2(dmap->fm_addr, dpages, PG_S); 1205 drommap.fm_offset = 0; 1206 smap = &rommap; 1207 dmap = &drommap; 1208 #endif 1209 1210 plane = 0x1; /* plane 0 */ 1211 1212 switch (fb->Mode) { 1213 1214 case MODE_1to1: 1215 if (fb->Pmask & plane) { 1216 mem_to_mem(fb->funcvec[0], 1217 smap, ps, sbp->width, dmap, pd, dbp->width, 1218 &sr, &dr.origin); 1219 } 1220 break; 1221 1222 case MODE_1toN: 1223 for (i = 0; i < dbp->depth; i++) { 1224 if (fb->Pmask & plane) { 1225 mem_to_mem(fb->funcvec[i], 1226 smap, ps, sbp->width, 1227 dmap, pd, dbp->width, 1228 &sr, &dr.origin); 1229 } 1230 pd += (dbp->width * dbp->rect.extent.y) << 1; 1231 plane <<= 1; 1232 } 1233 break; 1234 1235 case MODE_Nto1: 1236 for (i = 0; i < sbp->depth; i++, plane <<= 1) { 1237 if (fb->Pmask & plane) 1238 break; 1239 } 1240 if (i < sbp->depth) { 1241 ps += (sbp->width * sbp->rect.extent.y * i) << 1; 1242 mem_to_mem(fb->funcvec[i], 1243 smap, ps, sbp->width, dmap, pd, dbp->width, 1244 &sr, &dr.origin); 1245 } 1246 break; 1247 1248 case MODE_NtoN: 1249 for (i = 0; i < dbp->depth; i++) { 1250 if (fb->Pmask & plane) { 1251 mem_to_mem(fb->funcvec[i], 1252 smap, ps, sbp->width, 1253 dmap, pd, dbp->width, 1254 &sr, &dr.origin); 1255 } 1256 ps += (sbp->width * sbp->rect.extent.y) << 1; 1257 pd += (dbp->width * dbp->rect.extent.y) << 1; 1258 plane <<= 1; 1259 } 1260 break; 1261 1262 default: 1263 return (-1); 1264 } 1265 #ifdef IPC_MRX 1266 page_unmap(rommap.fm_vaddr, spages); 1267 page_unmap(drommap.fm_vaddr, dpages); 1268 #endif 1269 return (0); 1270 } 1271 1272 bitblt_nop() 1273 { 1274 return (0); 1275 } 1276 1277 /* 1278 * bitblt from '0' bitmap to frame buffer 1279 */ 1280 1281 bitblt_0tofb(fb, sbp, srp, dbp, dpp, crp) 1282 register struct fbdev *fb; 1283 lBitmap *sbp; /* source bitmap (0) */ 1284 lRectangle *srp; /* source rectangle */ 1285 lBitmap *dbp; /* destination bitmap (FB) */ 1286 lPoint *dpp; /* destination point */ 1287 lRectangle *crp; /* clip region in destination */ 1288 { 1289 lRectangle sr; 1290 lRectangle dr; 1291 1292 sr = *srp; 1293 dr.origin = *dpp; 1294 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1295 return (0); 1296 dr.extent = sr.extent; 1297 1298 switch (fb->Mode) { 1299 1300 case MODE_1to1: 1301 case MODE_Nto1: 1302 fb->Pmask &= 1; 1303 break; 1304 case MODE_1toN: 1305 case MODE_NtoN: 1306 break; 1307 1308 default: 1309 return (-1); 1310 } 1311 1312 /* 1313 * write data into ROP data register 1314 */ 1315 1316 fbbm_rop_cinit(fb, fb->Pmask, 0); 1317 fbbm_rop_clear(fb, &dr); 1318 1319 return (0); 1320 } 1321 1322 /* 1323 * bitblt from '1' bitmap to frame buffer 1324 */ 1325 1326 bitblt_1tofb(fb, sbp, srp, dbp, dpp, crp) 1327 register struct fbdev *fb; 1328 lBitmap *sbp; /* source bitmap (1) */ 1329 lRectangle *srp; /* source rectangle */ 1330 lBitmap *dbp; /* destination bitmap (FB) */ 1331 lPoint *dpp; /* destination point */ 1332 lRectangle *crp; /* clip region in destination */ 1333 { 1334 lRectangle sr; 1335 lRectangle dr; 1336 1337 sr = *srp; 1338 dr.origin = *dpp; 1339 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1340 return (0); 1341 dr.extent = sr.extent; 1342 1343 switch (fb->Mode) { 1344 1345 case MODE_1to1: 1346 case MODE_Nto1: 1347 /* plane mask set */ 1348 fb->Pmask &= 0x1; 1349 break; 1350 1351 case MODE_1toN: 1352 case MODE_NtoN: 1353 break; 1354 1355 default: 1356 return (-1); 1357 } 1358 1359 /* 1360 * write data into ROP data register 1361 */ 1362 1363 fbbm_rop_cinit(fb, fb->Pmask, 1); 1364 fbbm_rop_clear(fb, &dr); 1365 1366 return (0); 1367 } 1368 1369 #ifndef CPU_DOUBLE 1370 /* 1371 * bitblt from '0' bitmap to main memory 1372 */ 1373 1374 bitblt_0tomem(fb, sbp, srp, dbp, dpp, crp) 1375 register struct fbdev *fb; 1376 lBitmap *sbp; /* source bitmap (0) */ 1377 lRectangle *srp; /* source rectangle */ 1378 register lBitmap *dbp; /* destination bitmap (MEM) */ 1379 lPoint *dpp; /* destination point */ 1380 lRectangle *crp; /* clip region in destination */ 1381 { 1382 register struct fb_map *dmap; 1383 register unsigned int p; 1384 register int i, j; 1385 register int plane; 1386 lRectangle sr; 1387 lRectangle dr; 1388 int skip; 1389 1390 dmap = (struct fb_map*)dbp->base; 1391 1392 sr = *srp; 1393 dr.origin = *dpp; 1394 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1395 return (0); 1396 dr.extent = sr.extent; 1397 1398 dr.origin.x -= dbp->rect.origin.x; 1399 dr.origin.y -= dbp->rect.origin.y; 1400 1401 p = dmap->fm_offset; 1402 1403 plane = 0x1; 1404 1405 switch (fb->Mode) { 1406 1407 case MODE_1to1: 1408 if (fb->Pmask & plane) 1409 mem_clear(fb->funcvec[0], dmap, p, dbp->width, &dr, 0); 1410 break; 1411 1412 case MODE_1toN: 1413 case MODE_NtoN: 1414 skip = (dbp->width * dbp->rect.extent.y) << 1; 1415 for (i = 0, j = dbp->depth; i < j; i++) { 1416 if (fb->Pmask & plane) 1417 mem_clear(fb->funcvec[i], dmap, p, dbp->width, 1418 &dr, 0); 1419 /* next plane */ 1420 p += skip; 1421 plane <<= 1; 1422 } 1423 break; 1424 1425 case MODE_Nto1: 1426 for (i = 0, j = sbp->depth; i < j; i++) { 1427 if (fb->Pmask & plane) { 1428 mem_clear(fb->funcvec[i], dmap, p, dbp->width, 1429 &dr, 0); 1430 break; 1431 } 1432 plane <<= 1; 1433 } 1434 break; 1435 1436 default: 1437 return (1); 1438 } 1439 1440 return (0); 1441 } 1442 1443 /* 1444 * bitblt from '1' bitmap to main memory 1445 */ 1446 1447 bitblt_1tomem(fb, sbp, srp, dbp, dpp, crp) 1448 register struct fbdev *fb; 1449 lBitmap *sbp; /* source bitmap (1) */ 1450 lRectangle *srp; /* source rectangle */ 1451 register lBitmap *dbp; /* destination bitmap (MEM) */ 1452 lPoint *dpp; /* destination point */ 1453 lRectangle *crp; /* clip region in destination */ 1454 { 1455 register struct fb_map *dmap; 1456 register unsigned p; 1457 register int i, j; 1458 register int plane; 1459 lRectangle sr; 1460 lRectangle dr; 1461 int skip; 1462 1463 dmap = (struct fb_map*)dbp->base; 1464 1465 sr = *srp; 1466 dr.origin = *dpp; 1467 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) 1468 return (0); 1469 dr.extent = sr.extent; 1470 1471 dr.origin.x -= dbp->rect.origin.x; 1472 dr.origin.y -= dbp->rect.origin.y; 1473 1474 p = dmap->fm_offset; 1475 1476 plane = 0x1; 1477 1478 switch (fb->Mode) { 1479 1480 case MODE_1to1: 1481 if (fb->Pmask & plane) 1482 mem_clear(fb->funcvec[0], dmap, p, dbp->width, &dr, 1); 1483 break; 1484 1485 case MODE_1toN: 1486 case MODE_NtoN: 1487 skip = (dbp->width * dbp->rect.extent.y) << 1; 1488 for (i = 0, j = dbp->depth; i < j; i++) { 1489 if (fb->Pmask & plane) 1490 mem_clear(fb->funcvec[i], dmap, p, dbp->width, 1491 &dr, 1); 1492 /* next plane */ 1493 p += skip; 1494 plane <<= 1; 1495 } 1496 break; 1497 1498 case MODE_Nto1: 1499 for (i = 0, j = sbp->depth; i < j; i++) { 1500 if (fb->Pmask & plane) { 1501 mem_clear(fb->funcvec[i], dmap, p, dbp->width, 1502 &dr, 1); 1503 break; 1504 } 1505 plane <<= 1; 1506 } 1507 break; 1508 1509 default: 1510 return (1); 1511 } 1512 1513 return (0); 1514 } 1515 #endif /* !CPU_DOUBLE */ 1516 1517 int 1518 (*sel_ropfunc(stype, dtype))() 1519 int stype; /* source bitmap type */ 1520 int dtype; /* dest bitmap type */ 1521 { 1522 if (dtype == BM_0) 1523 return (bitblt_nop); 1524 if (dtype == BM_1) 1525 return (bitblt_nop); 1526 1527 #ifdef CPU_DOUBLE 1528 switch (stype) { 1529 case BM_FB: 1530 return (dtype == BM_FB) ? bitblt_fb : bitblt_tomem; 1531 break; 1532 1533 case BM_MEM: 1534 return (dtype == BM_FB) ? bitblt_tofb : bitblt_mem; 1535 break; 1536 1537 case BM_0: 1538 return (dtype == BM_FB) ? bitblt_0tofb : bitblt_nop; 1539 break; 1540 case BM_1: 1541 return (dtype == BM_FB) ? bitblt_1tofb : bitblt_nop; 1542 break; 1543 } 1544 #else /* CPU_DOUBLE */ 1545 switch (stype) { 1546 case BM_FB: 1547 return (dtype == BM_FB) ? bitblt_fb : bitblt_tomem; 1548 break; 1549 1550 case BM_MEM: 1551 return (dtype == BM_FB) ? bitblt_tofb : bitblt_mem; 1552 break; 1553 1554 case BM_0: 1555 return (dtype == BM_FB) ? bitblt_0tofb : bitblt_0tomem; 1556 break; 1557 case BM_1: 1558 return (dtype == BM_FB) ? bitblt_1tofb : bitblt_1tomem; 1559 break; 1560 } 1561 #endif /* CPU_DOUBLE */ 1562 1563 return (bitblt_nop); 1564 } 1565 1566 bitbltcmd(fb, cmd) 1567 register struct fbdev *fb; 1568 register lBitblt *cmd; 1569 { 1570 lRectangle cr; 1571 int ret; 1572 1573 cr = cmd->destClip; 1574 1575 if (!getclip(fb, &cmd->destBitmap, &cr)) 1576 return (0); 1577 if (!clipsrc(fb, &cmd->srcBitmap)) 1578 return (0); 1579 1580 if (setrop(fb, cmd->func, cmd->planemask, cmd->fore_color, cmd->aux_color, 1581 cmd->transp, &cmd->srcBitmap, &cmd->destBitmap) < 0) 1582 return (FB_RERROR); 1583 1584 cursorCheck(fb, cmd->srcBitmap.type, &cmd->srcRect, 1585 cmd->destBitmap.type, &cr); 1586 1587 ret = (*sel_ropfunc(cmd->srcBitmap.type, cmd->destBitmap.type)) 1588 (fb, &cmd->srcBitmap, &cmd->srcRect, &cmd->destBitmap, &cmd->destPoint, &cr); 1589 1590 cursorOn(fb); 1591 1592 return (FB_ROK); 1593 } 1594 1595 static 1596 batch_bitblt_01tofb(fb, sbp, clip, sdp, n, sw) 1597 register struct fbdev *fb; 1598 lBitmap *sbp; /* source bitmap (MEM) */ 1599 register lRectangle *clip; 1600 register lSrcDest *sdp; 1601 register int n; 1602 int sw; 1603 { 1604 register void (*rop_clear)(); 1605 lRectangle *srect = &sbp->rect; 1606 1607 switch (fb->Mode) { 1608 1609 case MODE_1to1: 1610 case MODE_Nto1: 1611 fb->Pmask &= 1; 1612 break; 1613 1614 case MODE_1toN: 1615 case MODE_NtoN: 1616 break; 1617 1618 default: 1619 return (FB_RERROR); 1620 } 1621 fbbm_rop_cinit(fb, fb->Pmask, sw); 1622 rop_clear = fb->fbbm_op->fb_rop_clear; 1623 while (--n >= 0) { 1624 lRectangle sr; 1625 lRectangle dr; 1626 1627 sr = sdp->srcRect; 1628 dr.origin = sdp->destPoint; 1629 if (cliprect2(&sr, srect, &dr, clip)) 1630 (*rop_clear)(fb, &dr); 1631 sdp++; 1632 } 1633 return (FB_ROK); 1634 } 1635 1636 static 1637 batch_bitblt_fb(fb, sbp, clip, sdp, n) 1638 register struct fbdev *fb; 1639 register lBitmap *sbp; 1640 register lRectangle *clip; 1641 register lSrcDest *sdp; 1642 register int n; 1643 { 1644 register int wplane, i, j; 1645 lRectangle sr; 1646 lRectangle dr; 1647 1648 fbbm_rop_init(fb, fb->funcvec); 1649 switch (fb->Mode) { 1650 1651 case MODE_1to1: 1652 fb->Pmask &= 1; 1653 while (--n >= 0) { 1654 sr = sdp->srcRect; 1655 dr.origin = sdp->destPoint; 1656 if (cliprect2(&sr, &sbp->rect, &dr, clip)) 1657 fbbm_rop_copy(fb, &sr, &dr.origin, 0, fb->Pmask); 1658 sdp++; 1659 } 1660 break; 1661 1662 case MODE_NtoN: 1663 while (--n >= 0) { 1664 sr = sdp->srcRect; 1665 dr.origin = sdp->destPoint; 1666 if (cliprect2(&sr, &sbp->rect, &dr, clip)) 1667 fbbm_rop_copy(fb, &sr, &dr.origin, 0, fb->Pmask); 1668 sdp++; 1669 } 1670 break; 1671 1672 case MODE_1toN: 1673 while (--n >= 0) { 1674 sr = sdp->srcRect; 1675 dr.origin = sdp->destPoint; 1676 if (cliprect2(&sr, &sbp->rect, &dr, clip)) 1677 fbbm_rop_copy(fb, &sr, &dr.origin, 1, fb->Pmask); 1678 sdp++; 1679 } 1680 break; 1681 1682 case MODE_Nto1: 1683 for (; --n >= 0; sdp++) { 1684 sr = sdp->srcRect; 1685 dr.origin = sdp->destPoint; 1686 if (!cliprect2(&sr, &sbp->rect, &dr, clip)) 1687 continue; 1688 wplane = 1; 1689 for (i = 0, j = sbp->depth; i < j; i++) { 1690 if (fb->Pmask & wplane) { 1691 fbbm_rop_copy(fb, &sr, &dr.origin, 1692 i + 1, fb->Pmask >> 16); 1693 break; 1694 } 1695 wplane <<= 1; 1696 } 1697 } 1698 break; 1699 1700 default: 1701 return (FB_RERROR); 1702 } 1703 } 1704 1705 static 1706 batch_bitblt_tofb(fb, sbp, dbp, crp, sdp, n) 1707 register struct fbdev *fb; 1708 register lBitmap *sbp; /* source bitmap (MEM) */ 1709 lBitmap *dbp; /* destination bitmap (FB) */ 1710 lRectangle *crp; /* clip region in destination */ 1711 register lSrcDest *sdp; 1712 register int n; 1713 { 1714 register unsigned p; 1715 register struct fb_map *smap; 1716 register int i, j, m; 1717 lRectangle sr; 1718 lRectangle dr; 1719 register int wplane; 1720 #ifdef IPC_MRX 1721 extern struct fb_map rommap; 1722 register int pages; 1723 #endif 1724 1725 fbbm_rop_winit(fb); 1726 while (--n >= 0) { 1727 sr = sdp->srcRect; 1728 dr.origin = sdp->destPoint; 1729 if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) { 1730 sdp++; 1731 continue; 1732 } 1733 dr.extent = sr.extent; 1734 1735 /* transform source rectangle */ 1736 sr.origin.x -= sbp->rect.origin.x; 1737 sr.origin.y -= sbp->rect.origin.y; 1738 1739 /* 1740 * check memory map specification 1741 */ 1742 smap = (struct fb_map*)sbp->base; 1743 p = smap->fm_offset; 1744 #ifdef IPC_MRX 1745 pages = btoc(smap->fm_offset + smap->fm_count); 1746 rommap.fm_vaddr = fb_map_page(smap->fm_addr, pages, 1747 fb->cache_off ? PG_S|PG_WP|PG_CI : PG_S|PG_WP); 1748 rommap.fm_offset = 0; 1749 smap = &rommap; 1750 #endif 1751 1752 wplane = 1; 1753 1754 switch (fb->Mode) { 1755 case MODE_1to1: 1756 fbbm_rop_write(fb, smap, p, sbp->width, 1757 &sr, &dr, fb->Pmask & 0x01); 1758 break; 1759 case MODE_1toN: 1760 fbbm_rop_write(fb, smap, p, sbp->width, 1761 &sr, &dr, fb->Pmask); 1762 break; 1763 case MODE_Nto1: 1764 m = sbp->width * sbp->rect.extent.y; 1765 for (i = 0; i < sbp->depth; i++, wplane <<= 1) { 1766 if (fb->Pmask & wplane) { 1767 p += (m * i) << 1; 1768 fbbm_rop_write(fb, smap, p, sbp->width, 1769 &sr, &dr, wplane); 1770 break; 1771 } 1772 wplane <<= 1; 1773 } 1774 break; 1775 case MODE_NtoN: 1776 j = min(sbp->depth, fb->fbNplane); 1777 m = sbp->width * sbp->rect.extent.y; 1778 p += (m << 1) * j; 1779 wplane = 1 << (j - 1); 1780 for (i = j; i > 0; i--) { 1781 /* get next plane */ 1782 p -= m << 1; 1783 if (fb->Pmask & wplane) 1784 fbbm_rop_write(fb, smap, p, sbp->width, 1785 &sr, &dr, wplane); 1786 /* next plane mask */ 1787 wplane >>= 1; 1788 } 1789 break; 1790 default: 1791 return (-1); 1792 } 1793 sdp++; 1794 } 1795 return (0); 1796 } 1797 1798 batchbitbltcmd(fb, cmd) 1799 register struct fbdev *fb; 1800 register lBatchBitblt *cmd; 1801 { 1802 register int n; 1803 register lSrcDest *sdp; 1804 register int (*blt)(); 1805 lRectangle cr; 1806 #ifdef CPU_SINGLE 1807 struct fb_map *map; 1808 unsigned int p; 1809 #endif 1810 int error; 1811 1812 if (setrop(fb, cmd->func, cmd->planemask, 1813 cmd->fore_color, cmd->aux_color, 1814 cmd->transp, &cmd->srcBitmap, &cmd->destBitmap) < 0) 1815 return (FB_RERROR); 1816 1817 cr = cmd->destClip; 1818 1819 if (!getclip(fb, &cmd->destBitmap, &cr)) 1820 return (FB_ROK); 1821 if (!clipsrc(fb, &cmd->srcBitmap)) 1822 return (0); 1823 #ifdef CPU_SINGLE 1824 map = (struct fb_map *)(cmd->srcDestList); 1825 p = map->fm_offset; 1826 sdp = (lSrcDest *)TypeAt(map, p); 1827 #else 1828 sdp = cmd->srcDestList; 1829 #endif 1830 n = cmd->nSrcDest; 1831 1832 cursorCheck(fb, cmd->srcBitmap.type, &cmd->srcBitmap.rect, 1833 cmd->destBitmap.type, &cr); 1834 1835 blt = sel_ropfunc(cmd->srcBitmap.type, cmd->destBitmap.type); 1836 if (blt == bitblt_0tofb || blt == bitblt_1tofb) { 1837 if (error = 1838 batch_bitblt_01tofb(fb, &cmd->srcBitmap, &cr, sdp, n, 1839 blt == bitblt_1tofb)) { 1840 cursorOn(fb); 1841 return (error); 1842 } 1843 } else if (blt == bitblt_fb) { 1844 if (error = 1845 batch_bitblt_fb(fb, &cmd->srcBitmap, &cr, sdp, n)) { 1846 cursorOn(fb); 1847 return (error); 1848 } 1849 } else if (blt == bitblt_tofb) { 1850 if (error = 1851 batch_bitblt_tofb(fb, &cmd->srcBitmap, &cmd->destBitmap, 1852 &cr, sdp, n)) { 1853 cursorOn(fb); 1854 return (error); 1855 } 1856 } else 1857 while (--n >= 0) { 1858 if ((*blt)(fb, &cmd->srcBitmap, &sdp->srcRect, 1859 &cmd->destBitmap, &sdp->destPoint, &cr) < 0) { 1860 cursorOn(fb); 1861 return (FB_RERROR); 1862 } 1863 PRE_EMPT; 1864 sdp++; 1865 } 1866 cursorOn(fb); 1867 return (FB_ROK); 1868 } 1869 1870 tilebitbltcmd(fb, cmd) 1871 struct fbdev *fb; 1872 register lTileBitblt *cmd; 1873 { 1874 lRectangle trect, rect, prect; 1875 lPoint dp; 1876 register int dx; 1877 int dy; 1878 register int offx, offy; 1879 register int xlen, ylen; 1880 int first; 1881 register int (*blt)(); 1882 int t; 1883 1884 rect = cmd->destRect; 1885 prect = cmd->ptnRect; 1886 1887 if (prect.extent.x <= 0 || prect.extent.y <= 0) 1888 return; 1889 1890 if (cmd->ptnBitmap.type == BM_FB && 1891 !cliprect(&cmd->ptnBitmap.rect, &fb->FrameRect, (lRectangle*)0)) 1892 return; 1893 1894 /* clip pattern rectangle */ 1895 if (!cliprect(&prect, &cmd->ptnBitmap.rect, (lRectangle *)0)) 1896 return; 1897 1898 if (!getclip(fb, &cmd->destBitmap, &cmd->destClip)) return; 1899 1900 if (!cliprect(&rect, &cmd->destClip, (lRectangle *)0)) 1901 return; 1902 1903 if (setrop(fb, cmd->func, cmd->planemask, cmd->fore_color, cmd->aux_color, 1904 cmd->transp, &cmd->ptnBitmap, &cmd->destBitmap) < 0) 1905 return (FB_RERROR); 1906 1907 blt = sel_ropfunc(cmd->ptnBitmap.type, cmd->destBitmap.type); 1908 1909 offx = MOD(rect.origin.x - cmd->refPoint.x, prect.extent.x, t); 1910 offy = MOD(rect.origin.y - cmd->refPoint.y, prect.extent.y, t); 1911 1912 dp = rect.origin; 1913 1914 trect.origin.x = prect.origin.x + offx; 1915 trect.origin.y = prect.origin.y + offy; 1916 1917 dy = rect.extent.y; 1918 1919 cursorCheck(fb, cmd->ptnBitmap.type, &prect, cmd->destBitmap.type, &rect); 1920 1921 first = 1; 1922 while (dy > 0) { 1923 if (first) { /* for the first time */ 1924 ylen = prect.extent.y - offy; 1925 ylen = min(ylen, dy); 1926 trect.extent.y = ylen; 1927 trect.origin.y = prect.origin.y + offy; 1928 first = 0; 1929 } else { 1930 ylen = min(prect.extent.y, dy); 1931 trect.extent.y = ylen; 1932 trect.origin.y = prect.origin.y; 1933 } 1934 1935 dp.x = rect.origin.x; 1936 dx = rect.extent.x; 1937 xlen = prect.extent.x - offx; 1938 trect.origin.x = prect.origin.x + offx; 1939 1940 if (dx < xlen) { 1941 trect.extent.x = dx; 1942 (*blt)(fb, &cmd->ptnBitmap, &trect, &cmd->destBitmap, &dp, (lRectangle *)0); 1943 } else { 1944 trect.extent.x = xlen; 1945 (*blt)(fb, &cmd->ptnBitmap, &trect, &cmd->destBitmap, &dp, (lRectangle *)0); 1946 dp.x += xlen; 1947 dx -= xlen; 1948 trect.origin.x = prect.origin.x; 1949 while (dx > 0) { 1950 xlen = min(dx, prect.extent.x); 1951 trect.extent.x = xlen; 1952 (*blt)(fb, &cmd->ptnBitmap, &trect, &cmd->destBitmap, &dp, (lRectangle *)0); 1953 dp.x += xlen; 1954 dx -= xlen; 1955 } 1956 } 1957 1958 dp.y += ylen; 1959 dy -= ylen; 1960 } 1961 1962 cursorOn(fb); 1963 } 1964 1965 bitblt3cmd(fb, cmd) 1966 struct fbdev fb; 1967 lBitblt3 *cmd; 1968 { 1969 return (FB_ROK); 1970 } 1971 1972 draw_rectangle(fb, dp) 1973 struct fbdev *fb; 1974 lPrimRect *dp; 1975 { 1976 lRectangle trect, rect, prect; 1977 lPoint p; 1978 register int dx; 1979 int dy; 1980 register int offx, offy; 1981 register int xlen, ylen; 1982 int first; 1983 register int (*blt)(); 1984 int t; 1985 1986 rect = dp->rect; 1987 prect = dp->ptnRect; 1988 1989 if (prect.extent.x <= 0 || prect.extent.y <= 0) 1990 return; 1991 1992 if (dp->ptnBM.type == BM_FB && 1993 !cliprect(&dp->ptnBM.rect, &fb->FrameRect, (lRectangle*)0)) 1994 return; 1995 1996 /* clip pattern rectangle */ 1997 if (!cliprect(&prect, &dp->ptnBM.rect, (lRectangle *)0)) 1998 return; 1999 2000 if (!getclip(fb, &dp->drawBM, &dp->clip)) return; 2001 2002 if (!cliprect(&rect, &dp->clip, (lRectangle *)0)) 2003 return; 2004 2005 if (setrop(fb, dp->func, dp->planemask, dp->fore_color, dp->aux_color, 2006 dp->transp, &dp->ptnBM, &dp->drawBM) < 0) 2007 return (FB_RERROR); 2008 2009 blt = sel_ropfunc(dp->ptnBM.type, dp->drawBM.type); 2010 2011 offx = MOD(rect.origin.x - dp->refPoint.x, prect.extent.x, t); 2012 offy = MOD(rect.origin.y - dp->refPoint.y, prect.extent.y, t); 2013 2014 p = rect.origin; 2015 2016 trect.origin.x = prect.origin.x + offx; 2017 trect.origin.y = prect.origin.y + offy; 2018 2019 dy = rect.extent.y; 2020 2021 cursorCheck(fb, dp->ptnBM.type, &prect, dp->drawBM.type, &rect); 2022 2023 first = 1; 2024 while (dy > 0) { 2025 if (first) { /* for the first time */ 2026 ylen = prect.extent.y - offy; 2027 ylen = min(ylen, dy); 2028 trect.extent.y = ylen; 2029 trect.origin.y = prect.origin.y + offy; 2030 first = 0; 2031 } else { 2032 ylen = min(prect.extent.y, dy); 2033 trect.extent.y = ylen; 2034 trect.origin.y = prect.origin.y; 2035 } 2036 2037 p.x = rect.origin.x; 2038 dx = rect.extent.x; 2039 xlen = prect.extent.x - offx; 2040 trect.origin.x = prect.origin.x + offx; 2041 2042 if (dx < xlen) { 2043 trect.extent.x = dx; 2044 (*blt)(fb, &dp->ptnBM, &trect, &dp->drawBM, &p, (lRectangle *)0); 2045 } else { 2046 trect.extent.x = xlen; 2047 (*blt)(fb, &dp->ptnBM, &trect, &dp->drawBM, &p, (lRectangle *)0); 2048 p.x += xlen; 2049 dx -= xlen; 2050 trect.origin.x = prect.origin.x; 2051 while (dx > 0) { 2052 xlen = min(dx, prect.extent.x); 2053 trect.extent.x = xlen; 2054 (*blt)(fb, &dp->ptnBM, &trect, &dp->drawBM, &p, (lRectangle *)0); 2055 p.x += xlen; 2056 dx -= xlen; 2057 } 2058 } 2059 2060 p.y += ylen; 2061 dy -= ylen; 2062 } 2063 2064 cursorOn(fb); 2065 } 2066 2067 draw_polymarker(fb, dp) 2068 struct fbdev *fb; 2069 register lPrimMarker *dp; 2070 { 2071 register lPoint *ps; 2072 register int np; 2073 lRectangle cr; 2074 register int (*blt)(); 2075 #ifdef CPU_SINGLE 2076 struct fb_map *map; 2077 unsigned int p; 2078 #endif 2079 2080 cr = dp->clip; 2081 2082 if ((dp->drawBM.type == BM_FB) && 2083 !getclip(fb, &dp->drawBM, &cr)) 2084 return (FB_ROK); 2085 2086 if (dp->ptnBM.type == BM_FB && 2087 !cliprect(&dp->ptnBM.rect, &fb->FrameRect, (lRectangle*)0)) 2088 return (FB_ROK); 2089 2090 if (setrop(fb, dp->func, dp->planemask, dp->fore_color, dp->aux_color, 2091 dp->transp, &dp->ptnBM, &dp->drawBM) < 0) 2092 return (FB_RERROR); 2093 2094 blt = sel_ropfunc(dp->ptnBM.type, dp->drawBM.type); 2095 2096 cursorCheck(fb, dp->ptnBM.type, &(dp->ptnRect), dp->drawBM.type, &cr); 2097 2098 #ifdef CPU_SINGLE 2099 map = (struct fb_map *)(dp->plist); 2100 p = map->fm_offset; 2101 ps = (lPoint *)TypeAt(map, p); 2102 #else 2103 ps = dp->plist; 2104 #endif 2105 np = dp->np; 2106 while (--np >= 0) { 2107 (*blt)(fb, &dp->ptnBM, &dp->ptnRect, &dp->drawBM, ps++, &cr); 2108 PRE_EMPT; 2109 } 2110 2111 cursorOn(fb); 2112 2113 return (FB_ROK); 2114 } 2115 2116 static int patternx; 2117 static int patterny; 2118 static int patternwidth; 2119 static lBitmap *pbm; /* pattern bitmap */ 2120 static lBitmap *drawbm; /* drawing bitmap */ 2121 static int (*blt)(); 2122 2123 static 2124 fill_line(fb, len, dp, offx, offy) 2125 register struct fbdev *fb; 2126 register int len; 2127 register lPoint *dp; 2128 int offx, offy; 2129 { 2130 register int plen; 2131 static lRectangle srec = { 0, 0, 0, 1 }; 2132 2133 srec.origin.x = patternx + offx; 2134 srec.origin.y = patterny + offy; 2135 2136 if ((plen = patternwidth - offx) > len) { 2137 srec.extent.x = len; 2138 (*blt)(fb, pbm, &srec, drawbm, dp, (lRectangle *)0); 2139 return; 2140 } 2141 2142 srec.extent.x = plen; 2143 (*blt)(fb, pbm, &srec, drawbm, dp, (lRectangle *)0); 2144 dp->x += plen; 2145 len -= plen; 2146 srec.origin.x = patternx; 2147 plen = patternwidth; 2148 2149 while (len > 0) { 2150 srec.extent.x = min(plen, len); 2151 (*blt)(fb, pbm, &srec, drawbm, dp, (lRectangle *)0); 2152 dp->x += plen; 2153 len -= plen; 2154 } 2155 } 2156 2157 fill_scan(fb, fdata) 2158 register struct fbdev *fb; 2159 register lPrimFill *fdata; 2160 { 2161 register lScanl *ls; 2162 int nscan; 2163 lRectangle clip; 2164 lRectangle prect; 2165 register int minx, maxx, miny, maxy; 2166 #ifdef CPU_SINGLE 2167 struct fb_map *map; 2168 #endif 2169 register void (*rop_clear)(); 2170 int (*sel_ropfunc())(); 2171 2172 if ((nscan = fdata->nscan) <= 0) 2173 return (FB_RERROR); 2174 2175 /* clip pattern rectangle */ 2176 prect = fdata->ptnRect; 2177 if (!getclip(fb, &fdata->ptnBM, &prect)) 2178 return (0); 2179 2180 if (prect.extent.x <= 0 || prect.extent.y <= 0) 2181 return (FB_RERROR); 2182 2183 /* clip clip rectangle */ 2184 clip = fdata->clip; 2185 if (!getclip(fb, &fdata->drawBM, &clip)) 2186 return (0); 2187 2188 if (setrop(fb, fdata->func, fdata->planemask, 2189 fdata->fore_color, fdata->aux_color, fdata->transp, 2190 &fdata->ptnBM, &fdata->drawBM) < 0) 2191 return (FB_RERROR); 2192 2193 #ifdef CPU_SINGLE 2194 map = (struct fb_map *)(fdata->scan); 2195 ls = (lScanl *)TypeAt(map, map->fm_offset); 2196 #else 2197 ls = fdata->scan; 2198 #endif 2199 2200 minx = clip.origin.x; 2201 maxx = minx + clip.extent.x - 1; 2202 miny = clip.origin.y; 2203 maxy = miny + clip.extent.y - 1; 2204 2205 cursorCheck(fb, fdata->ptnBM.type, &prect, fdata->drawBM.type, &clip); 2206 2207 blt = sel_ropfunc(fdata->ptnBM.type, fdata->drawBM.type); 2208 if (blt == bitblt_1tofb || blt == bitblt_0tofb) { 2209 lRectangle dr; 2210 2211 if (fb->fbbm_op->fb_rop_fillscan != (void (*)())nofunc) { 2212 fbbm_rop_fillscan(fb, ls, nscan, &clip, 2213 blt == bitblt_1tofb); 2214 goto out; 2215 } 2216 dr.extent.y = 1; 2217 fbbm_rop_cinit(fb, fb->Pmask, blt == bitblt_1tofb); 2218 rop_clear = fb->fbbm_op->fb_rop_clear; 2219 while (--nscan >= 0) { 2220 if ((dr.origin.y = ls->y) >= miny && 2221 dr.origin.y <= maxy) { 2222 dr.origin.x = max(ls->x0, minx); 2223 if ((dr.extent.x = 2224 min(ls->x1, maxx) - dr.origin.x + 1) > 0) 2225 (*rop_clear)(fb, &dr); 2226 } 2227 ls++; 2228 } 2229 } else { 2230 int len; 2231 int refx, refy; 2232 lPoint dp; 2233 int sizex, sizey; 2234 int t; 2235 2236 sizex = prect.extent.x; 2237 sizey = prect.extent.y; 2238 refx = fdata->refPoint.x; 2239 refy = fdata->refPoint.y; 2240 2241 patternx = prect.origin.x; 2242 patterny = prect.origin.y; 2243 patternwidth = sizex; 2244 2245 pbm = &fdata->ptnBM; 2246 drawbm = &fdata->drawBM; 2247 2248 while (--nscan >= 0) { 2249 if ((dp.y = ls->y) >= miny && dp.y <= maxy) { 2250 dp.x = max(ls->x0, minx); 2251 if ((len = min(ls->x1, maxx) - dp.x + 1) > 0) 2252 fill_line(fb, len, &dp, 2253 MOD((dp.x - refx), sizex, t), 2254 MOD((dp.y - refy), sizey, t)); 2255 } 2256 ls++; 2257 } 2258 } 2259 out: 2260 cursorOn(fb); 2261 return (FB_ROK); 2262 } 2263 2264 put_string(fb, sdata) 2265 struct fbdev *fb; 2266 lPrimText *sdata; 2267 { 2268 register int x, y; 2269 register int ex_factor = sdata->ex_factor; 2270 register unsigned c; 2271 register unsigned char *str; 2272 int len = sdata->len; 2273 int flen; 2274 int i, j, k, l; 2275 unsigned fchar = sdata->first_chr; 2276 unsigned lchar = sdata->last_chr; 2277 lRectangle cr, save; 2278 register int (*bltfunc)(); 2279 register char *f_addr; /* font address */ 2280 register char **fnt_addr; 2281 static struct fb_map rommap; 2282 #ifdef CPU_SINGLE 2283 struct fb_map *map; 2284 unsigned int p; 2285 #endif 2286 2287 lBitmap *fontBM; 2288 lRectangle srec; 2289 lPoint dp; 2290 2291 extern int tmode; /* in ../bm/vt100if.c */ 2292 2293 x = sdata->p.x << 16; 2294 y = sdata->p.y << 16; 2295 2296 srec.extent.x = sdata->width; 2297 srec.extent.y = sdata->height; 2298 2299 switch (sdata->type) { 2300 2301 case ASCII: 2302 fontBM = &sdata->fontBM; 2303 2304 break; 2305 2306 case ROM_ASCII: 2307 case ROM_CONS: 2308 if (sdata->width >= 12 && sdata->height >= 24) { 2309 if (fb->Krom_BM1.type == (char)0xff) { 2310 fontBM = &fb->Krom_BM0; 2311 srec.extent.x = fb->Krom_font_extent0.x>>1; 2312 srec.extent.y = fb->Krom_font_extent0.y; 2313 fnt_addr = ext_fnt_addr; 2314 } else { 2315 fontBM = &fb->Krom_BM1; 2316 srec.extent.x = fb->Krom_font_extent1.x>>1; 2317 srec.extent.y = fb->Krom_font_extent1.y; 2318 fnt_addr = ext_fnt24_addr; 2319 } 2320 } else { 2321 if (fb->Krom_BM0.type == (char)0xff) { 2322 fontBM = &fb->Krom_BM1; 2323 srec.extent.x = fb->Krom_font_extent1.x>>1; 2324 srec.extent.y = fb->Krom_font_extent1.y; 2325 fnt_addr = ext_fnt24_addr; 2326 } else { 2327 fontBM = &fb->Krom_BM0; 2328 srec.extent.x = fb->Krom_font_extent0.x>>1; 2329 srec.extent.y = fb->Krom_font_extent0.y; 2330 fnt_addr = ext_fnt_addr; 2331 } 2332 } 2333 2334 if (srec.extent.x > sdata->width) 2335 srec.extent.x = sdata->width; 2336 if (srec.extent.y > sdata->height) 2337 srec.extent.y = sdata->height; 2338 flen = (fontBM->width<<1) * fontBM->rect.extent.y; 2339 fontBM->base = (Word *)&rommap; 2340 break; 2341 2342 case ROM_KANJI: 2343 if (sdata->width >= 24 && sdata->height >= 24) { 2344 if (fb->Krom_BM1.type == (char)0xff) { 2345 fontBM = &fb->Krom_BM0; 2346 srec.extent = fb->Krom_font_extent0; 2347 fnt_addr = ext_fnt_addr; 2348 } else { 2349 fontBM = &fb->Krom_BM1; 2350 srec.extent = fb->Krom_font_extent1; 2351 fnt_addr = ext_fnt24_addr; 2352 } 2353 } else { 2354 if (fb->Krom_BM0.type == (char)0xff) { 2355 fontBM = &fb->Krom_BM1; 2356 srec.extent = fb->Krom_font_extent1; 2357 fnt_addr = ext_fnt24_addr; 2358 } else { 2359 fontBM = &fb->Krom_BM0; 2360 srec.extent = fb->Krom_font_extent0; 2361 fnt_addr = ext_fnt_addr; 2362 } 2363 } 2364 2365 if (srec.extent.x > sdata->width) 2366 srec.extent.x = sdata->width; 2367 if (srec.extent.y > sdata->height) 2368 srec.extent.y = sdata->height; 2369 save.extent.x = srec.extent.x; 2370 flen = (fontBM->width<<1) * fontBM->rect.extent.y; 2371 fontBM->base = (Word *)&rommap; 2372 break; 2373 2374 default: 2375 return (FB_RERROR); 2376 } 2377 2378 /* get clipping rectangle */ 2379 cr = sdata->clip; 2380 2381 if (!getclip(fb, &sdata->drawBM, &cr)) 2382 return (FB_ROK); 2383 2384 /* set rop code */ 2385 if (setrop(fb, sdata->func, sdata->planemask, 2386 sdata->fore_color, sdata->aux_color, 2387 sdata->transp, fontBM, &sdata->drawBM) < 0) 2388 return (FB_RERROR); 2389 2390 /* select rop function */ 2391 bltfunc = sel_ropfunc(fontBM->type, sdata->drawBM.type); 2392 2393 #ifdef CPU_SINGLE 2394 map = (struct fb_map *)(sdata->str); 2395 p = map->fm_offset; 2396 str = (unsigned char *)TypeAt(map, p); 2397 #else 2398 str = sdata->str; 2399 #endif 2400 2401 cursorCheck(fb, fontBM->type, &fontBM->rect, sdata->drawBM.type, &cr); 2402 2403 switch (sdata->type) { 2404 2405 case ASCII: 2406 if (sdata->column == 0) 2407 return (FB_RERROR); 2408 while (len-- > 0) { 2409 c = *str++; 2410 2411 if (c < fchar || c > lchar) 2412 continue; 2413 2414 c -= fchar; 2415 srec.origin.x = sdata->fp.x 2416 + sdata->width * (c % sdata->column); 2417 srec.origin.y = sdata->fp.y 2418 + sdata->height * (c / sdata->column); 2419 dp.x = x >> 16; 2420 dp.y = y >> 16; 2421 2422 if (ex_factor == 1) { 2423 (*bltfunc)(fb, fontBM, &srec, &sdata->drawBM, 2424 &dp, &cr); 2425 } else { 2426 srec.extent.x = 1; 2427 2428 for (i = 0; i < sdata->width; i++) { 2429 for (j = 0; j < ex_factor; j++) { 2430 (*bltfunc)(fb, fontBM, &srec, 2431 &sdata->drawBM, 2432 &dp, &cr); 2433 dp.x++; 2434 PRE_EMPT; 2435 } 2436 srec.origin.x++; 2437 } 2438 } 2439 x += sdata->dx; 2440 y += sdata->dy; 2441 } 2442 break; 2443 2444 case ROM_ASCII: 2445 case ROM_CONS: 2446 #ifdef IPC_MRX 2447 if (fb->type == FB_NWB251) 2448 fb->cache_off = 1; 2449 #endif 2450 while (len-- > 0) { 2451 c = *str++; 2452 dp.x = x >> 16; 2453 dp.y = y >> 16; 2454 k = 0; 2455 srec.origin.x = srec.origin.y = 0; 2456 2457 f_addr = 0; 2458 2459 if ((c >= 0x20) && (c <= 0x7e)) { 2460 /* 2461 * ASCII char 2462 */ 2463 f_addr = fnt_addr[c]; 2464 goto disp; 2465 } 2466 2467 if (sdata->type == ROM_ASCII) { 2468 if ((c >= 0xa1) && (c <= 0xdf)) { 2469 /* 2470 * KANA char 2471 */ 2472 f_addr = fnt_addr[c + 64]; 2473 goto disp; 2474 } 2475 } 2476 2477 if (sdata->type == ROM_CONS) { 2478 #ifdef KM_ASCII 2479 if (tmode == KM_ASCII) { 2480 #endif 2481 if ((c >= 0xa0) && (c <= 0xff)) { 2482 /* 2483 * ISO char 2484 */ 2485 f_addr = fnt_addr[c - 32]; 2486 goto disp; 2487 } 2488 #ifdef KM_ASCII 2489 } else { 2490 if ((c >= 0xa1) && (c <= 0xdf)) { 2491 /* 2492 * KANA char 2493 */ 2494 f_addr = fnt_addr[c + 64]; 2495 goto disp; 2496 } 2497 } 2498 #endif 2499 } 2500 2501 disp: 2502 2503 if (f_addr) { 2504 /* 2505 * not ROM font 2506 * (font is in kernel data area) 2507 */ 2508 bltfunc = sel_ropfunc(BM_MEM, 2509 sdata->drawBM.type); 2510 rommap.fm_vaddr = f_addr; 2511 rommap.fm_offset = 0; 2512 #ifdef IPC_MRX 2513 iopmemfbmap(f_addr, flen, &rommap); 2514 #endif 2515 k = 1; 2516 l = fontBM->width; 2517 fontBM->width = 1; 2518 save = fontBM->rect; 2519 fontBM->rect.origin = srec.origin; 2520 fontBM->rect.extent.x = 12; 2521 } else if (fontBM->type == BM_MEM) { 2522 /* 2523 * KANJI ROM except pop[cm]fb 2524 */ 2525 f_addr = fbbm_Krom_addr(fb, c, &srec); 2526 rommap.fm_vaddr = f_addr; 2527 rommap.fm_offset = 0; 2528 #ifdef IPC_MRX 2529 iopmemfbmap(f_addr, flen, &rommap); 2530 #endif 2531 } else { 2532 /* 2533 * XXX 2534 * fontBM->type == BM_FB -> fbbm_pop[cm] 2535 * 2536 * see fbpop[cm]_setup() routine 2537 * in fbbm_pop[cm].c 2538 */ 2539 bltfunc = sel_ropfunc(fontBM->type, 2540 sdata->drawBM.type); 2541 2542 bzero((caddr_t)fontBM->base, 2543 sizeof (struct fb_map)); 2544 fbbm_Krom_addr(fb, c, &srec); 2545 fontBM->rect.origin = srec.origin; 2546 } 2547 2548 if (ex_factor == 1) { 2549 (*bltfunc)(fb, fontBM, &srec, &sdata->drawBM, 2550 &dp, &cr); 2551 } else { 2552 srec.extent.x = 1; 2553 2554 for (i = 0; i < sdata->width; i++) { 2555 2556 for (j = 0; j < ex_factor; j++) { 2557 (*bltfunc)(fb, fontBM, &srec, 2558 &sdata->drawBM, 2559 &dp, &cr); 2560 dp.x++; 2561 } 2562 srec.origin.x++; 2563 } 2564 } 2565 PRE_EMPT; 2566 if (k != 0) { 2567 fontBM->rect = save; 2568 fontBM->width = l; 2569 } 2570 x += sdata->dx; 2571 y += sdata->dy; 2572 } 2573 #ifdef IPC_MRX 2574 fb->cache_off = 0; 2575 #endif 2576 2577 break; 2578 2579 case ROM_KANJI: 2580 #ifdef IPC_MRX 2581 if (fb->type == FB_NWB251) 2582 fb->cache_off = 1; 2583 #endif 2584 while (len > 1) { 2585 c = *str++; 2586 c <<= 8; 2587 c |= *str++; 2588 dp.x = x >> 16; 2589 dp.y = y >> 16; 2590 srec.origin.x = srec.origin.y = 0; 2591 2592 if (fontBM->type == BM_MEM) { 2593 /* 2594 * KANJI ROM except pop[cm]fb 2595 */ 2596 f_addr = fbbm_Krom_addr(fb, c, &srec); 2597 rommap.fm_vaddr = f_addr; 2598 rommap.fm_offset = 0; 2599 #ifdef IPC_MRX 2600 iopmemfbmap(f_addr, flen, &rommap); 2601 #endif 2602 } else { 2603 /* 2604 * XXX 2605 * fontBM->type == BM_FB ---> fbbm_pop[cm] 2606 * 2607 * see fbpop[cm]_setup() in fbbm_pop[cm].c 2608 */ 2609 bzero((caddr_t)fontBM->base, 2610 sizeof (struct fb_map)); 2611 fbbm_Krom_addr(fb, c, &srec); 2612 fontBM->rect.origin = srec.origin; 2613 } 2614 2615 if (ex_factor == 1) { 2616 (*bltfunc)(fb, fontBM, &srec, &sdata->drawBM, 2617 &dp, &cr); 2618 } else { 2619 srec.extent.x = 1; 2620 for (i = 0; i < sdata->width; i++) { 2621 for (j = 0; j < ex_factor; j++) { 2622 (*bltfunc)(fb, fontBM, &srec, 2623 &sdata->drawBM, 2624 &dp, &cr); 2625 dp.x++; 2626 } 2627 srec.origin.x++; 2628 } 2629 srec.extent.x = save.extent.x; 2630 } 2631 PRE_EMPT; 2632 x += sdata->dx; 2633 y += sdata->dy; 2634 len -= 2; 2635 } 2636 #ifdef IPC_MRX 2637 fb->cache_off = 0; 2638 #endif 2639 break; 2640 2641 default: 2642 cursorOn(fb); 2643 return (FB_RERROR); 2644 } 2645 2646 cursorOn(fb); 2647 2648 return (FB_ROK); 2649 } 2650 2651 void 2652 linerop(fb, func, fore, aux, trans) 2653 struct fbdev *fb; 2654 register unsigned func; 2655 register int fore; 2656 register int aux; 2657 int trans; 2658 { 2659 register char *funcv; 2660 register int i; 2661 char tmp[4]; 2662 2663 /* set rop function register */ 2664 func &= 0xf; 2665 tmp[0] = TRANS(trans, (func & 0x0c) | (func >> 2)); 2666 tmp[1] = TRANS(trans, (func >> 2) | ((func << 2) & 0x0c)); 2667 tmp[2] = TRANS(trans, func); 2668 tmp[3] = TRANS(trans, (func << 2) & 0x0c | func & 3); 2669 2670 funcv = fb->funcvec; 2671 for (i = fb->fbNplane; --i >= 0;) { 2672 *funcv++ = tmp[((fore & 1) << 1) | (aux & 1)]; 2673 fore >>= 1; aux >>= 1; 2674 } 2675 } 2676 2677 /* 2678 * line clipping routine 2679 * 2680 * DRAW visual 2681 * NODRAW not visual 2682 */ 2683 lineclip(p0, p1, r) 2684 register lPoint *p0; 2685 register lPoint *p1; 2686 register lRectangle *r; /* clipping rectangle */ 2687 { 2688 register lPoint *ptmp; 2689 register int d0, d1, d2, limit; 2690 2691 /* sort 2 points by x-coordinate */ 2692 if (p0->x > p1->x) { 2693 ptmp = p1; 2694 p1 = p0; 2695 p0 = ptmp; 2696 } 2697 limit = r->origin.x; 2698 d0 = p1->y - p0->y; 2699 d1 = p1->x - p0->x; 2700 if ((d2 = limit - p0->x) > 0) { 2701 if (p1->x < limit) 2702 return (NODRAW); 2703 p0->y += d2 * d0 / d1; 2704 p0->x = limit; 2705 } 2706 limit += r->extent.x - 1; 2707 if ((d2 = limit - p1->x) < 0) { 2708 if (p0->x > limit) 2709 return (NODRAW); 2710 p1->y += d2 * d0 / d1; 2711 p1->x = limit; 2712 } 2713 2714 /* sort 2 points by y-coordinate */ 2715 if (p0->y > p1->y) { 2716 ptmp = p1; 2717 p1 = p0; 2718 p0 = ptmp; 2719 } 2720 limit = r->origin.y; 2721 d0 = p1->x - p0->x; 2722 d1 = p1->y - p0->y; 2723 if ((d2 = limit - p0->y) > 0) { 2724 if (p1->y < limit) 2725 return (NODRAW); 2726 p0->x += d2 * d0 / d1; 2727 p0->y = limit; 2728 } 2729 limit += r->extent.y - 1; 2730 if ((d2 = limit - p1->y) < 0) { 2731 if (p0->y > limit) 2732 return (NODRAW); 2733 p1->x += d2 * d0 / d1; 2734 p1->y = limit; 2735 } 2736 return (DRAW); 2737 } 2738 2739 #ifndef CPU_DOUBLE 2740 /* 2741 void 2742 point(p, x, s, fp) 2743 register char *p; 2744 register int x; 2745 register int s; 2746 register char *fp; 2747 { 2748 x = 7 - (x & 7); 2749 if ((1 << (3 - (((s & 1) << 1) | ((*p >> x) & 1)))) & *fp) 2750 *p |= (1 << x); 2751 else 2752 *p &= ~(1 << x); 2753 } 2754 */ 2755 #define point(p, x, s, fp) { \ 2756 int xx = 7 - ((x) & 7); \ 2757 if ((1 << (3 - ((((s) & 1) << 1) | ((*(p) >> xx) & 1)))) & *(fp)) \ 2758 *(p) |= (1 << xx); \ 2759 else \ 2760 *(p) &= ~(1 << xx); \ 2761 } 2762 2763 mem_vector(fb, p0, p1, mask, dbmp, lpf) 2764 struct fbdev *fb; 2765 lPoint *p0, *p1; 2766 int mask; /* plane mask */ 2767 lBitmap *dbmp; /* drawing bitmap */ 2768 int lpf; /* if 0, don't draw last point */ 2769 { 2770 register struct fb_map *map = (struct fb_map *)dbmp->base; 2771 register char *funcv = fb->funcvec; /* rop function */ 2772 int p = (int)map->fm_offset; 2773 register int pmask; 2774 register unsigned int pat; 2775 register int x = p0->x; 2776 register int y = p0->y; 2777 register char *fp; 2778 int width = dbmp->width << 1; 2779 int lim; 2780 int size = width * dbmp->rect.extent.y; 2781 int ddx, ddy; 2782 int s, d, c; 2783 int dx = p1->x - x; 2784 int dy = p1->y - y; 2785 int i, j; 2786 int depth = dbmp->depth; 2787 2788 /* transformation */ 2789 x -= dbmp->rect.origin.x; 2790 y -= dbmp->rect.origin.y; 2791 2792 pat = fb->pat; 2793 2794 ddx = 1; 2795 ddy = dbmp->width << 1; 2796 y = (int)p + y * ddy; 2797 2798 if (dx == 0) 2799 ddx = 0; 2800 else if (dx < 0) { 2801 dx = -dx; 2802 ddx = -ddx; 2803 } 2804 2805 if (dy == 0) 2806 ddy = 0; 2807 else if (dy < 0) { 2808 dy = -dy; 2809 ddy = -ddy; 2810 } 2811 2812 if (dx > dy) { /* case x */ 2813 lim = dx; 2814 if (lpf) 2815 lim++; 2816 2817 s = -dx; 2818 d = dx << 1; 2819 c = dy << 1; 2820 2821 for (i = lim; i > 0; i--) { 2822 (int)p = y + (x >> 3); 2823 2824 pat = (pat << 1) | ((pat & 0x80000000) ? 1: 0); 2825 2826 fp = funcv; 2827 pmask = mask; 2828 2829 for (j = depth; j > 0; j--) { 2830 if (pmask & 1) { 2831 point(_TypeAt(map, p), x, pat, fp); 2832 } 2833 2834 p += size; 2835 pmask >>= 1; 2836 fp++; 2837 } 2838 2839 if ((s += c) >= 0) { 2840 s -= d; 2841 y += ddy; 2842 } 2843 2844 x += ddx; 2845 } 2846 } else { /* case y */ 2847 lim = dy; 2848 if (lpf) 2849 lim++; 2850 s = -dy; 2851 d = dy << 1; 2852 c = dx << 1; 2853 2854 for (i = lim; i > 0; i--) { 2855 (int)p = y + (x >> 3); 2856 pat = (pat << 1) | ((pat & 0x80000000) ? 1: 0); 2857 2858 fp = funcv; 2859 pmask = mask; 2860 2861 for (j = depth; j > 0; j--) { 2862 if (pmask & 1) { 2863 point(_TypeAt(map, p), x, pat, fp); 2864 } 2865 2866 p += size; 2867 pmask >>= 1; 2868 fp++; 2869 } 2870 2871 if ((s += c) >= 0) { 2872 s -= d; 2873 x += ddx; 2874 } 2875 2876 y += ddy; 2877 } 2878 } 2879 2880 /* rotate pattern */ 2881 pat = fb->pat; 2882 2883 { 2884 register int tmp; 2885 2886 tmp = lim & 31; 2887 pat = (pat << tmp) | (pat >> (32 - tmp)); 2888 } 2889 2890 fb->pat = pat; 2891 } 2892 #endif /* !CPU_DOUBLE */ 2893 2894 /* polyline drawing */ 2895 draw_polyline(fb, dp) 2896 struct fbdev *fb; 2897 register lPrimLine *dp; 2898 { 2899 register lPoint *ps; 2900 lPoint p0, p1; 2901 register int np; 2902 lRectangle clip, *clipp; 2903 #ifdef CPU_SINGLE 2904 struct fb_map *map; 2905 unsigned int p; 2906 #endif 2907 2908 /* clip rectangle */ 2909 clip = dp->clip; 2910 2911 if (clip.origin.x == -1) 2912 clipp = 0; 2913 else { 2914 clipp = &clip; 2915 if (!getclip(fb, &dp->drawBM, clipp)) return 0; 2916 } 2917 #ifdef CPU_SINGLE 2918 map = (struct fb_map *)(dp->plist); 2919 p = map->fm_offset; 2920 ps = (lPoint *)TypeAt(map, p); 2921 #else 2922 ps = dp->plist; 2923 #endif 2924 if (dp->drawBM.type == BM_FB) { 2925 2926 cursorCheck(fb, ~BM_FB, 0, dp->drawBM.type, clipp); 2927 fbbm_rop_vect(fb, clipp, dp->func, dp->fore_color, 2928 dp->aux_color, dp->transp, dp->planemask, 2929 dp->np, ps, dp->lptn, (dp->dlpf)?1:0, 1); 2930 cursorOn(fb); 2931 2932 return(FB_ROK); 2933 } 2934 #ifndef CPU_DOUBLE 2935 linerop(fb, dp->func, dp->fore_color, dp->aux_color, dp->transp); 2936 p0 = *ps++; 2937 np = dp->np - 1; 2938 fb->pat = dp->lptn; 2939 if (clipp) { 2940 while (--np > 0) { 2941 p1 = *ps; 2942 if (lineclip(&p0, &p1, clipp)) { 2943 mem_vector(fb, &p0, &p1, 2944 dp->planemask, &dp->drawBM, 2945 ps->x != p1.x || ps->y != p1.y); 2946 PRE_EMPT; 2947 } 2948 p0 = *ps++; 2949 } 2950 p1 = *ps; 2951 if (lineclip(&p0, &p1, clipp)) { 2952 mem_vector(fb, &p0, &p1, dp->planemask, &dp->drawBM, 2953 ps->x != p1.x || ps->y != p1.y || dp->dlpf); 2954 } 2955 } else { 2956 while (--np > 0) { 2957 p1 = *ps; 2958 mem_vector(fb, &p0, &p1, dp->planemask, &dp->drawBM, 0); 2959 PRE_EMPT; 2960 p0 = *ps++; 2961 } 2962 p1 = *ps; 2963 mem_vector(fb, &p0, &p1, dp->planemask, &dp->drawBM, dp->dlpf); 2964 } 2965 #endif /* !CPU_DOUBLE */ 2966 return (FB_ROK); 2967 } 2968 2969 /* disjoint polyline drawing */ 2970 2971 draw_dj_polyline(fb, dp) 2972 struct fbdev *fb; 2973 register lPrimLine *dp; 2974 { 2975 register lPoint *ps; 2976 lPoint p0, p1; 2977 register int np; 2978 lRectangle clip, *clipp; 2979 #ifdef CPU_SINGLE 2980 struct fb_map *map; 2981 unsigned int p; 2982 #endif 2983 2984 int lpf = (dp->dlpf)?1:0; 2985 2986 /* clip rectangle */ 2987 clip = dp->clip; 2988 2989 if (clip.origin.x == -1) 2990 clipp = 0; 2991 else { 2992 clipp = &clip; 2993 if(!getclip(fb, &dp->drawBM, clipp)) return (0); 2994 } 2995 #ifdef CPU_SINGLE 2996 map = (struct fb_map *)(dp->plist); 2997 p = map->fm_offset; 2998 ps = (lPoint *)TypeAt(map, p); 2999 #else 3000 ps = dp->plist; 3001 #endif 3002 if (dp->drawBM.type == BM_FB) { 3003 3004 cursorCheck(fb, ~BM_FB, 0, dp->drawBM.type, clipp); 3005 fbbm_rop_vect(fb, clipp, dp->func, dp->fore_color, 3006 dp->aux_color, dp->transp, dp->planemask, 3007 dp->np, ps, dp->lptn, lpf, 0); 3008 cursorOn(fb); 3009 PRE_EMPT; 3010 3011 return (FB_ROK); 3012 } 3013 #ifndef CPU_DOUBLE 3014 linerop(fb, dp->func, dp->fore_color, dp->aux_color, dp->transp); 3015 np = dp->np >> 1; 3016 if (lpf) { 3017 if (clipp) { 3018 while (--np >= 0) { 3019 p0 = *ps++; 3020 p1 = *ps++; 3021 fb->pat = dp->lptn; 3022 if (lineclip(&p0, &p1, clipp)) { 3023 mem_vector(fb, &p0, &p1, 3024 dp->planemask, &dp->drawBM, 1); 3025 PRE_EMPT; 3026 } 3027 } 3028 } else { 3029 while (--np >= 0) { 3030 p0 = *ps++; 3031 p1 = *ps++; 3032 fb->pat = dp->lptn; 3033 mem_vector(fb, &p0, &p1, 3034 dp->planemask, &dp->drawBM, 1); 3035 PRE_EMPT; 3036 } 3037 } 3038 } else { 3039 if (clipp) { 3040 while (--np >= 0) { 3041 p0 = *ps++; 3042 p1 = *ps; 3043 fb->pat = dp->lptn; 3044 if (lineclip(&p0, &p1, clipp)) { 3045 mem_vector(fb, &p0, &p1, 3046 dp->planemask, &dp->drawBM, 3047 ps->x != p1.x || ps->y != p1.y); 3048 PRE_EMPT; 3049 } 3050 ps++; 3051 } 3052 } else { 3053 while (--np >= 0) { 3054 p0 = *ps++; 3055 p1 = *ps++; 3056 fb->pat = dp->lptn; 3057 mem_vector(fb, &p0, &p1, 3058 dp->planemask, &dp->drawBM, 0); 3059 PRE_EMPT; 3060 } 3061 } 3062 } 3063 #endif /* !CPU_DOUBLE */ 3064 return (FB_ROK); 3065 } 3066 3067 static lRectangle dotRect = {{ 0, 0 }, { 1, 1 }}; 3068 3069 emulate_polydot(fb, dp) 3070 struct fbdev *fb; 3071 register lPrimDot *dp; 3072 { 3073 lPrimMarker marker; 3074 lPrimMarker *cmdp; 3075 register lPoint *ps; 3076 register int np; 3077 lRectangle cr; 3078 register int (*blt)(); 3079 #ifdef CPU_SINGLE 3080 struct fb_map *map; 3081 unsigned int p; 3082 #endif 3083 3084 cmdp = ▮ 3085 3086 cmdp->func = dp->func; 3087 cmdp->transp = dp->transp; 3088 cmdp->fore_color = dp->fore_color; 3089 cmdp->aux_color = dp->aux_color; 3090 cmdp->planemask = dp->planemask; 3091 cmdp->ptnRect = dotRect; 3092 cmdp->ptnBM.type = BM_1; 3093 cmdp->ptnBM.depth = 1; 3094 cmdp->ptnBM.rect = dotRect; 3095 cmdp->drawBM = dp->drawBM; 3096 cmdp->clip = dp->clip; 3097 cmdp->np = dp->np; 3098 cmdp->plist = dp->plist; 3099 3100 return (draw_polymarker(fb, cmdp)); 3101 } 3102 3103 #ifndef CPU_DOUBLE 3104 mem_dot(fb, p0, mask, dbmp) 3105 struct fbdev *fb; 3106 lPoint *p0; 3107 register int mask; /* plane mask */ 3108 lBitmap *dbmp; /* drawing bitmap */ 3109 { 3110 register struct fb_map *map = (struct fb_map *)dbmp->base; 3111 register char *funcv; /* rop function */ 3112 register int p = (int)map->fm_offset; 3113 register int depth; 3114 int size; 3115 int x, y; 3116 3117 x = p0->x - dbmp->rect.origin.x; 3118 y = p0->y - dbmp->rect.origin.y; 3119 3120 size = (dbmp->width * dbmp->rect.extent.y) << 1; 3121 3122 p += y * (dbmp->width << 1) + (x >> 3); 3123 3124 funcv = fb->funcvec; 3125 for (depth = dbmp->depth; --depth >= 0;) { 3126 if (mask & 1) { 3127 point(_TypeAt(map, p), x, ~0, funcv); 3128 } 3129 p += size; 3130 mask >>= 1; 3131 funcv++; 3132 } 3133 } 3134 #endif /* !CPU_DOUBLE */ 3135 3136 draw_polydot(fb, dp) 3137 struct fbdev *fb; 3138 register lPrimDot *dp; 3139 { 3140 register lPoint *ps; 3141 lRectangle clip, *clipp; 3142 register int np; 3143 #ifdef CPU_SINGLE 3144 struct fb_map *map; 3145 unsigned int p; 3146 #endif 3147 3148 if (fb->fbbm_op->fb_rop_dot == (void (*)())nofunc) 3149 return (emulate_polydot(fb, dp)); 3150 3151 /* clip rectangle */ 3152 clip = dp->clip; 3153 3154 if (clip.origin.x == -1) 3155 clipp = 0; 3156 else { 3157 clipp = &clip; 3158 if (!getclip(fb, &dp->drawBM, clipp)) return 0; 3159 } 3160 3161 #ifdef CPU_SINGLE 3162 map = (struct fb_map *)(dp->plist); 3163 p = map->fm_offset; 3164 ps = (lPoint *)TypeAt(map, p); 3165 #else 3166 ps = dp->plist; 3167 #endif 3168 3169 if (dp->drawBM.type == BM_FB) { 3170 cursorCheck(fb, ~BM_FB, 0, dp->drawBM.type, clipp); 3171 fbbm_rop_dot(fb, clipp, dp->func, dp->fore_color, 3172 dp->aux_color, dp->transp, dp->planemask, 3173 dp->np, ps); 3174 cursorOn(fb); 3175 3176 return(FB_ROK); 3177 } 3178 #ifndef CPU_DOUBLE 3179 linerop(fb, dp->func, dp->fore_color, dp->aux_color, dp->transp); 3180 3181 np = dp->np; 3182 if (clipp) { 3183 register int x0, y0, x1, y1; 3184 3185 x0 = clipp->origin.x; 3186 y0 = clipp->origin.y; 3187 x1 = x0 + clipp->extent.x - 1; 3188 y1 = y0 + clipp->extent.y - 1; 3189 if (x1 <= 0 || y1 <= 0) return; 3190 3191 while (--np >= 0) { 3192 if ((ps->x >= x0) && (ps->y >= y0) && 3193 (ps->x <= x1) && (ps->y <= y1)) { 3194 mem_dot(fb, ps, dp->planemask, &dp->drawBM); 3195 PRE_EMPT; 3196 } 3197 ps++; 3198 } 3199 } else { 3200 while (--np >= 0) { 3201 mem_dot(fb, ps, dp->planemask, &dp->drawBM); 3202 PRE_EMPT; 3203 ps++; 3204 } 3205 } 3206 #endif /* !CPU_DOUBLE */ 3207 return (FB_ROK); 3208 } 3209 3210 get_scrtype(fb, cmd) 3211 register struct fbdev *fb; 3212 register lScrType *cmd; 3213 { 3214 cmd->colorwidth = fb->Colorwidth; 3215 cmd->plane = fb->fbNplane; 3216 cmd->bufferrect = fb->FrameRect; 3217 cmd->visiblerect = fb->VisRect; 3218 cmd->type = fb->type; 3219 cmd->unit = fb->unit; 3220 3221 return FB_ROK; 3222 } 3223 3224 fbstart(fbaddr, dummy) 3225 register struct fbreg *fbaddr; 3226 int dummy; 3227 { 3228 register struct fbdev *fb = &fbdev[fbaddr->fb_device]; 3229 register int s; 3230 3231 FB_LOCK; 3232 3233 if (!fb) { 3234 return (FB_RERROR); 3235 } 3236 3237 /* reset dimmer count */ 3238 rst_dimmer_cnt(); 3239 3240 switch(fbaddr->fb_command) { 3241 case FB_CPROBE: 3242 fbaddr->fb_data = search_fbdev(fbaddr->fb_device, 3243 fbaddr->fb_unit); 3244 fbaddr->fb_result = FB_ROK; 3245 break; 3246 case FB_CATTACH: 3247 fbaddr->fb_result = get_scrtype(fb, &fbaddr->fb_scrtype); 3248 break; 3249 case FB_COPEN: 3250 fbaddr->fb_result = fbbm_open(fb); 3251 break; 3252 case FB_CCLOSE: 3253 fbaddr->fb_result = fbbm_close(fb); 3254 break; 3255 case FB_CSETDIM: 3256 fbaddr->fb_result = fbbm_set_dimmer(fb, fbaddr->fb_data); 3257 break; 3258 case FB_CGETDIM: 3259 if ((fbaddr->fb_data = fbbm_get_dimmer(fb)) == FB_RERROR) 3260 fbaddr->fb_result = FB_RERROR; 3261 else 3262 fbaddr->fb_result = FB_ROK; 3263 break; 3264 case FB_CBITBLT: 3265 fbaddr->fb_result = bitbltcmd(fb, &fbaddr->fb_bitblt); 3266 break; 3267 case FB_CBATCHBITBLT: 3268 fbaddr->fb_result = batchbitbltcmd(fb, &fbaddr->fb_batchbitblt); 3269 break; 3270 case FB_CTILEBITBLT: 3271 fbaddr->fb_result = tilebitbltcmd(fb, &fbaddr->fb_tilebitblt); 3272 break; 3273 case FB_CBITBLT3: 3274 fbaddr->fb_result = bitblt3cmd(fb, &fbaddr->fb_bitblt3); 3275 break; 3276 case FB_CPOLYLINE: 3277 fbaddr->fb_result = draw_polyline(fb, &fbaddr->fb_polyline); 3278 break; 3279 case FB_CDJPOLYLINE: 3280 fbaddr->fb_result = draw_dj_polyline(fb, &fbaddr->fb_polyline); 3281 break; 3282 case FB_CRECTANGLE: 3283 fbaddr->fb_result = draw_rectangle(fb, &fbaddr->fb_rectangle); 3284 break; 3285 case FB_CFILLSCAN: 3286 fbaddr->fb_result = fill_scan(fb, &fbaddr->fb_fillscan); 3287 break; 3288 case FB_CPOLYMARKER: 3289 fbaddr->fb_result = draw_polymarker(fb, &fbaddr->fb_polymarker); 3290 break; 3291 case FB_CTEXT: 3292 fbaddr->fb_result = put_string(fb, &fbaddr->fb_text); 3293 break; 3294 case FB_CPOLYDOT: 3295 fbaddr->fb_result = draw_polydot(fb, &fbaddr->fb_polydot); 3296 break; 3297 case FB_CGETSCRTYPE: 3298 fbaddr->fb_result = get_scrtype(fb, &fbaddr->fb_scrtype); 3299 break; 3300 case FB_CSETPALETTE: 3301 fbaddr->fb_result = fbbm_set_palette(fb, &fbaddr->fb_palette); 3302 break; 3303 case FB_CGETPALETTE: 3304 fbaddr->fb_result = fbbm_get_palette(fb, &fbaddr->fb_palette); 3305 break; 3306 case FB_CSETCURSOR: 3307 fbaddr->fb_result = setCursor(fb, &fbaddr->fb_cursor); 3308 break; 3309 case FB_CUNSETCURSOR: 3310 fbaddr->fb_result = setCursor(fb, NULL); 3311 break; 3312 case FB_CSHOWCURSOR: 3313 fbaddr->fb_result = showCursor(fb); 3314 break; 3315 case FB_CHIDECURSOR: 3316 fbaddr->fb_result = hideCursor(fb); 3317 break; 3318 case FB_CSETXY: 3319 fbaddr->fb_result = moveCursor(fb, &fbaddr->fb_point); 3320 break; 3321 case FB_CAUTODIM: 3322 if (fbaddr->fb_data) 3323 auto_dimmer_on(fb); 3324 else 3325 auto_dimmer_off(fb); 3326 fbaddr->fb_result = FB_ROK; 3327 break; 3328 case FB_CSETVIDEO: 3329 fbaddr->fb_result = 3330 fbbm_ioctl(fb, FB_SETVIDEOCTL, &fbaddr->fb_videoctl); 3331 break; 3332 case FB_CGETVIDEO: 3333 fbaddr->fb_result = 3334 fbbm_ioctl(fb, FB_GETVIDEOSTATUS, &fbaddr->fb_videostatus); 3335 break; 3336 case FB_CSETPMODE: 3337 fbaddr->fb_result = 3338 fbbm_ioctl(fb, FB_SETPALETTEMODE, &fbaddr->fb_data); 3339 break; 3340 case FB_CGETPMODE: 3341 fbaddr->fb_result = 3342 fbbm_ioctl(fb, FB_GETPALETTEMODE, &fbaddr->fb_data); 3343 break; 3344 #ifdef CPU_SINGLE 3345 case FB_CGETPAGE: 3346 fbaddr->fb_data = fbbm_get_page(fb, fbaddr->fb_data); 3347 if (fbaddr->fb_data == -1) 3348 fbaddr->fb_result = FB_RERROR; 3349 else 3350 fbaddr->fb_result = FB_ROK; 3351 break; 3352 #endif 3353 case FB_CIOCTL: 3354 fbaddr->fb_fbioctl.request = fbbm_ioctl(fb, 3355 fbaddr->fb_fbioctl.request, fbaddr->fb_fbioctl.param); 3356 if (fbaddr->fb_fbioctl.request == -1) 3357 fbaddr->fb_result = FB_RERROR; 3358 else 3359 fbaddr->fb_result = FB_ROK; 3360 break; 3361 3362 default: 3363 fbaddr->fb_result = FB_RERROR; 3364 break; 3365 } 3366 3367 #ifdef CPU_SINGLE 3368 if (cfb && curs_pending) { 3369 curs_pending = 0; 3370 redrawCursor(cfb); 3371 } 3372 #endif 3373 3374 FB_UNLOCK; 3375 } 3376