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