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