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