xref: /csrg-svn/sys/news3400/fb/fb_start.c (revision 55763)
153893Smckusick /*
253893Smckusick  * Copyright (c) 1992 The Regents of the University of California.
353893Smckusick  * All rights reserved.
453893Smckusick  *
553893Smckusick  * This code is derived from software contributed to Berkeley by
653893Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753893Smckusick  *
853893Smckusick  * %sccs.include.redist.c%
953893Smckusick  *
1053893Smckusick  * from: $Hdr: fb_start.c,v 4.300 91/06/27 20:42:40 root Rel41 $ SONY
1153893Smckusick  *
12*55763Sbostic  *	@(#)fb_start.c	7.2 (Berkeley) 07/28/92
1353893Smckusick  */
1453893Smckusick 
1553893Smckusick #include "../include/fix_machine_type.h"
1653893Smckusick 
17*55763Sbostic #include "param.h"
18*55763Sbostic #include "systm.h"
19*55763Sbostic 
2053893Smckusick #ifdef IPC_MRX
2153893Smckusick #include "../../iop/framebuf.h"
2253893Smckusick #include "../../iop/fbreg.h"
2353893Smckusick #include "page.h"
2453893Smckusick #else
2553893Smckusick #include "../iop/framebuf.h"
2653893Smckusick #include "../iop/fbreg.h"
2753893Smckusick #endif
2853893Smckusick 
2953893Smckusick #include "../fb/fbdefs.h"
3053893Smckusick 
3153893Smckusick #ifdef CPU_SINGLE
3253893Smckusick #include "../include/cpu.h"
3353893Smckusick extern struct tty cons;
3453893Smckusick extern int cnstart();
3553893Smckusick #define PRE_EMPT	need_resched()
3653893Smckusick #endif
3753893Smckusick 
3853893Smckusick static struct fbdev	*cfb = 0;
3953893Smckusick static lPoint		mp;
4053893Smckusick #ifdef CPU_SINGLE
4153893Smckusick static int		curs_pending = 0;
4253893Smckusick #endif
4353893Smckusick 
4453893Smckusick extern struct fbdevsw	fbdevsw[];
4553893Smckusick extern int		nfbdev;
4653893Smckusick 
4753893Smckusick #ifdef CPU_SINGLE
4853893Smckusick extern char	*ext_fnt_addr[];
4953893Smckusick extern char	*ext_fnt24_addr[];
5053893Smckusick #else
5153893Smckusick extern char	**ext_fnt_addr;
5253893Smckusick extern char	**ext_fnt24_addr;
5353893Smckusick #endif
5453893Smckusick 
5553893Smckusick static char copyfuncv[MAXPLANE] = {
5653893Smckusick 	BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S,		/* SRC */
5753893Smckusick 	BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S,		/* SRC */
5853893Smckusick 	BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S, BF_S		/* SRC */
5953893Smckusick };
6053893Smckusick 
6153893Smckusick unsigned short fb_color_pallet_def[48] = {	/* define initial color */
6253893Smckusick /*	R,	G,	B	*/
6353893Smckusick 	0,	0,	0,
6453893Smckusick 	0,	0,	0x44,
6553893Smckusick 	0,	0x44,	0,
6653893Smckusick 	0,	0x44,	0x44,
6753893Smckusick 	0x44,	0,	0,
6853893Smckusick 	0x44,	0,	0x44,
6953893Smckusick 	0x44,	0x44,	0,
7053893Smckusick 	0x44,	0x44,	0x44,
7153893Smckusick 	0x88,	0x88,	0x88,
7253893Smckusick 	0,	0,	0xff,
7353893Smckusick 	0,	0xff,	0,
7453893Smckusick 	0,	0xff,	0xff,
7553893Smckusick 	0xff,	0,	0,
7653893Smckusick 	0xff,	0,	0xff,
7753893Smckusick 	0xff,	0xff,	0,
7853893Smckusick 	0xff,	0xff,	0xff
7953893Smckusick };
8053893Smckusick 
8153893Smckusick unsigned short fb_gray_pallet_def[48] = {	/* define initial color */
8253893Smckusick /*	R,	G,	B	*/
8353893Smckusick 	0xff,	0xff,	0xff,
8453893Smckusick 	0xff,	0xff,	0,
8553893Smckusick 	0xff,	0,	0xff,
8653893Smckusick 	0xff,	0,	0,
8753893Smckusick 	0,	0xff,	0xff,
8853893Smckusick 	0,	0xff,	0,
8953893Smckusick 	0,	0,	0xff,
9053893Smckusick 	0x88,	0x88,	0x88,
9153893Smckusick 	0x44,	0x44,	0x44,
9253893Smckusick 	0x44,	0x44,	0,
9353893Smckusick 	0x44,	0,	0x44,
9453893Smckusick 	0x44,	0,	0,
9553893Smckusick 	0,	0x44,	0x44,
9653893Smckusick 	0,	0x44,	0,
9753893Smckusick 	0,	0,	0x44,
9853893Smckusick 	0,	0,	0
9953893Smckusick };
10053893Smckusick 
10153893Smckusick static int bitmap_use;		/* shared variable for bitmap exclusion ctrl */
10253893Smckusick 
10353893Smckusick #ifdef IPC_MRX
10453893Smckusick struct fb_map rommap;
10553893Smckusick #endif
10653893Smckusick 
10753893Smckusick #ifdef CPU_SINGLE
10853893Smckusick void
10953893Smckusick lock_bitmap()
11053893Smckusick {
11153893Smckusick 	int s;
11253893Smckusick 
11353893Smckusick 	/* wait(bitmap_use) */
11453893Smckusick 	s = splbitmap();
11553893Smckusick 	while (bitmap_use & FB_BUSY) {
11653893Smckusick 		bitmap_use |= FB_WANTED;
11753893Smckusick 		sleep((caddr_t)&bitmap_use, FBPRI);
11853893Smckusick 	}
11953893Smckusick 	bitmap_use |= FB_BUSY;
12053893Smckusick 	splx(s);
12153893Smckusick }
12253893Smckusick 
12353893Smckusick void
12453893Smckusick unlock_bitmap()
12553893Smckusick {
12653893Smckusick 	int s;
12753893Smckusick 
12853893Smckusick 	/* signal(bitmap_use) */
12953893Smckusick 	s = splbitmap();
13053893Smckusick 	if (bitmap_use & FB_WANTED)
13153893Smckusick 		wakeup((caddr_t)&bitmap_use);
13253893Smckusick 	bitmap_use &= ~(FB_BUSY|FB_WANTED);
13353893Smckusick 	splx(s);
13453893Smckusick }
13553893Smckusick 
13653893Smckusick lock_bitmap_poll()
13753893Smckusick {
13853893Smckusick 	int s;
13953893Smckusick 
14053893Smckusick 	/* wait(bitmap_use) */
14153893Smckusick 
14253893Smckusick 	s = splbitmap();
14353893Smckusick 	if (bitmap_use & (FB_BUSY|FB_WANTED)) {
14453893Smckusick 		splx(s);
14553893Smckusick 		return (1);
14653893Smckusick 	}
14753893Smckusick 	bitmap_use |= FB_BUSY;
14853893Smckusick 	splx(s);
14953893Smckusick 	return (0);
15053893Smckusick }
15153893Smckusick 
15253893Smckusick void
15353893Smckusick unlock_bitmap_poll()
15453893Smckusick {
15553893Smckusick 	int s;
15653893Smckusick 
15753893Smckusick 	/* signal(bitmap_use) */
15853893Smckusick 	s = splbitmap();
15953893Smckusick 	if (bitmap_use & FB_WANTED)
16053893Smckusick 		wakeup((caddr_t)&bitmap_use);
16153893Smckusick 	bitmap_use &= ~(FB_BUSY|FB_WANTED);
16253893Smckusick 	splx(s);
16353893Smckusick }
16453893Smckusick 
16553893Smckusick bmlockedp()
16653893Smckusick {
16753893Smckusick 	return (bitmap_use & (FB_WANTED|FB_BUSY));
16853893Smckusick }
16953893Smckusick 
17053893Smckusick #ifdef NOTDEF /* KU:XXX not necessary for news3200 */
17153893Smckusick void
17253893Smckusick rop_wait(fb)
17353893Smckusick 	struct fbdev *fb;
17453893Smckusick {
17553893Smckusick 	register int s;
17653893Smckusick 	int i;
17753893Smckusick 
17853893Smckusick 	s = splbitmap();
17953893Smckusick /* KU:XXX trick! */
18053893Smckusick #define in_interrupt()	((caddr_t)&fb < (caddr_t)MACH_CODE_START)
18153893Smckusick 	if (in_interrupt() || (fb->run_flag & FB_WAITING)) {
18253893Smckusick 		splx(s);
18353893Smckusick 		fbbm_rop_wait(fb);
18453893Smckusick 	} else {
18553893Smckusick 		if (fbbm_ioctl(fb, FB_STATUSCHECK, 0) &
18653893Smckusick 		    (FB_STATUS_ROPWAIT|FB_STATUS_ROPEXEC)) {
18753893Smckusick 
18853893Smckusick 			i = FB_INT_ROPDONE;
18953893Smckusick 			fbbm_ioctl(fb, FB_INTENABLE, &i);
19053893Smckusick 
19153893Smckusick 			if (!(fbbm_ioctl(fb, FB_STATUSCHECK, 0) &
19253893Smckusick 			    (FB_STATUS_ROPWAIT|FB_STATUS_ROPEXEC))) {
19353893Smckusick 				i = FB_INT_ROPDONE;
19453893Smckusick 				fbbm_ioctl(fb, FB_INTCLEAR, &i);
19553893Smckusick 			} else {
19653893Smckusick 				fb->run_flag |= FB_WAITING;
19753893Smckusick 				sleep((caddr_t)&fb->run_flag, FBPRI);
19853893Smckusick 			}
19953893Smckusick 		}
20053893Smckusick 		splx(s);
20153893Smckusick 	}
20253893Smckusick }
20353893Smckusick #endif /* NOTDEF */
20453893Smckusick #else /* CPU_SINGLE */
20553893Smckusick #ifdef IPC_MRX
20653893Smckusick struct page {
20753893Smckusick 	char bytes[NBPG];
20853893Smckusick };
20953893Smckusick extern struct page *page_base;
21053893Smckusick extern struct page *page_max;
21153893Smckusick extern struct map pagemap[];
21253893Smckusick extern struct pte_iop page_pt[];
21353893Smckusick extern int mapped_page;
21453893Smckusick 
21553893Smckusick caddr_t
21653893Smckusick fb_map_page(map, n, prot)
21753893Smckusick 	register int *map;
21853893Smckusick 	register int n;
21953893Smckusick 	register int prot;
22053893Smckusick {
22153893Smckusick 	register int x;
22253893Smckusick 	register struct pte_iop *p;
22353893Smckusick 	register struct page *addr;
22453893Smckusick 	register int s = spl7();
22553893Smckusick 	static int last_x, last_n;
22653893Smckusick 
22753893Smckusick 	if (last_n >= n) {
22853893Smckusick 		x = last_x;
22953893Smckusick 	} else {
23053893Smckusick 		rmfree(pagemap, last_n, last_x);
23153893Smckusick 		mapped_page -= last_n;
23253893Smckusick 		last_x = 0;
23353893Smckusick 		last_n = 0;
23453893Smckusick 		if ((x = rmalloc(pagemap, n)) <= 0) {
23553893Smckusick 			splx(s);
23653893Smckusick 			return (NULL);
23753893Smckusick 		}
23853893Smckusick 		mapped_page += n;
23953893Smckusick 		last_x = x;
24053893Smckusick 		last_n = n;
24153893Smckusick 	}
24253893Smckusick 	addr = page_base + x;
24353893Smckusick 	prot |= PG_PAGE;
24453893Smckusick 
24553893Smckusick 	for (p = page_pt + x; n > 0; p++, n--) {
24653893Smckusick 		*(int *)p = prot | *map++;
24753893Smckusick 		tbis((caddr_t)addr);
24853893Smckusick 		addr++;
24953893Smckusick 	}
25053893Smckusick 
25153893Smckusick 	splx(s);
25253893Smckusick 	return ((caddr_t)(page_base + x));
25353893Smckusick }
25453893Smckusick 
25553893Smckusick caddr_t
25653893Smckusick fb_map_page2(map, n, prot)
25753893Smckusick 	register int *map;
25853893Smckusick 	register int n;
25953893Smckusick 	register int prot;
26053893Smckusick {
26153893Smckusick 	register int x;
26253893Smckusick 	register struct pte_iop *p;
26353893Smckusick 	register struct page *addr;
26453893Smckusick 	register int s;
26553893Smckusick 
26653893Smckusick 	if (n == 0)
26753893Smckusick 		return (NULL);
26853893Smckusick 	s = spl7();
26953893Smckusick 	if ((x = rmalloc(pagemap, n)) <= 0) {
27053893Smckusick 		splx(s);
27153893Smckusick 		return (NULL);
27253893Smckusick 	}
27353893Smckusick 	mapped_page += n;
27453893Smckusick 	addr = page_base + x;
27553893Smckusick 	prot |= PG_PAGE;
27653893Smckusick 
27753893Smckusick 	for (p = page_pt + x; n > 0; p++, n--) {
27853893Smckusick 		*(int *)p = prot | (*map++);
27953893Smckusick 		tbis((caddr_t)addr);
28053893Smckusick 		addr++;
28153893Smckusick 	}
28253893Smckusick 
28353893Smckusick 	splx(s);
28453893Smckusick 	return ((caddr_t)(page_base + x));
28553893Smckusick }
28653893Smckusick #endif /* IPC_MRX */
28753893Smckusick #endif /* CPU_SINGLE */
28853893Smckusick 
28953893Smckusick iopmemfbmap(addr, len, map)
29053893Smckusick 	register caddr_t addr;
29153893Smckusick 	register int len;
29253893Smckusick 	register struct fb_map *map;
29353893Smckusick {
29453893Smckusick 	register caddr_t *p;
29553893Smckusick 	register int i;
29653893Smckusick 
29753893Smckusick 	map->fm_vaddr = addr;
29853893Smckusick 	map->fm_offset = (unsigned)addr & CLOFSET;
29953893Smckusick 	map->fm_count = len;
30053893Smckusick 	len += map->fm_offset;
30153893Smckusick 	p = map->fm_addr;
30253893Smckusick 	addr -= map->fm_offset;
30353893Smckusick 
30453893Smckusick 	for (i = 0; i < NFBMAP && len > 0; i++) {
30553893Smckusick 		*p++ = addr;
30653893Smckusick 		addr += CLBYTES;
30753893Smckusick 		len -= CLBYTES;
30853893Smckusick 	}
30953893Smckusick }
31053893Smckusick 
31153893Smckusick int
31253893Smckusick nofunc()
31353893Smckusick {
31453893Smckusick 	return 0;
31553893Smckusick }
31653893Smckusick 
31753893Smckusick int
31853893Smckusick error()
31953893Smckusick {
32053893Smckusick 	return FB_RERROR;
32153893Smckusick }
32253893Smckusick 
32353893Smckusick void
32453893Smckusick checkArea(fb, x, y)
32553893Smckusick 	register struct fbdev *fb;
32653893Smckusick 	register int *x, *y;
32753893Smckusick {
32853893Smckusick 	if (*x < fb->moveArea.origin.x)
32953893Smckusick 		*x = fb->moveArea.origin.x;
33053893Smckusick 	if (*y < fb->moveArea.origin.y)
33153893Smckusick 		*y = fb->moveArea.origin.y;
33253893Smckusick 	if (*x >= (fb->moveArea.origin.x + fb->moveArea.extent.x))
33353893Smckusick 		*x = (fb->moveArea.origin.x + fb->moveArea.extent.x) - 1;
33453893Smckusick 	if (*y >= (fb->moveArea.origin.y + fb->moveArea.extent.y))
33553893Smckusick 		*y = (fb->moveArea.origin.y + fb->moveArea.extent.y) - 1;
33653893Smckusick }
33753893Smckusick 
33853893Smckusick cursorIn(fb, clip)
33953893Smckusick 	register struct fbdev *fb;
34053893Smckusick 	register lRectangle *clip;
34153893Smckusick {
34253893Smckusick 	if (clip == 0)
34353893Smckusick 		return (1);
34453893Smckusick 	if (cfb != fb)
34553893Smckusick 		return (0);
34653893Smckusick 
34753893Smckusick 	return (clip->origin.x < fb->cursorP.x + fb->size.x &&
34853893Smckusick 		clip->origin.x + clip->extent.x > fb->cursorP.x &&
34953893Smckusick 		clip->origin.y < fb->cursorP.y + fb->size.y &&
35053893Smckusick 		clip->origin.y + clip->extent.y > fb->cursorP.y);
35153893Smckusick }
35253893Smckusick 
35353893Smckusick void
35453893Smckusick fbcopy1(src, dst, fv)
35553893Smckusick 	lPoint src;
35653893Smckusick 	lPoint dst;
35753893Smckusick 	char *fv;
35853893Smckusick {
35953893Smckusick 	lRectangle sr, dr;
36053893Smckusick 
36153893Smckusick 	sr.origin = src;
36253893Smckusick 	sr.extent = cfb->size;
36353893Smckusick 	dr.origin = dst;
36453893Smckusick 	if (cliprect2(&sr, &cfb->FrameRect, &dr, &cfb->VisRect)) {
36553893Smckusick 		fbbm_rop_init(cfb, fv);
36653893Smckusick 		fbbm_rop_copy(cfb, &sr, &dr.origin, 1, FB_PLANEALL);
36753893Smckusick 	}
36853893Smckusick }
36953893Smckusick 
37053893Smckusick void
37153893Smckusick fbcopy2(src, dst)
37253893Smckusick 	lPoint src;
37353893Smckusick 	lPoint dst;
37453893Smckusick {
37553893Smckusick 	lRectangle sr, dr;
37653893Smckusick 
37753893Smckusick 	sr.origin = src;
37853893Smckusick 	sr.extent = cfb->size;
37953893Smckusick 	dr.origin = dst;
38053893Smckusick 	if (cliprect2(&sr, &cfb->FrameRect, &dr, &cfb->FrameRect)) {
38153893Smckusick 		fbbm_rop_init(cfb, copyfuncv);
38253893Smckusick 		fbbm_rop_copy(cfb, &sr, &dr.origin, 0, FB_PLANEALL);
38353893Smckusick 	}
38453893Smckusick }
38553893Smckusick 
38653893Smckusick void
38753893Smckusick fbcopy3(src, dst)
38853893Smckusick 	lPoint src;
38953893Smckusick 	lPoint dst;
39053893Smckusick {
39153893Smckusick 	lRectangle sr, dr;
39253893Smckusick 
39353893Smckusick 	sr.origin = src;
39453893Smckusick 	sr.extent = cfb->size;
39553893Smckusick 	dr.origin = dst;
39653893Smckusick 	if (cliprect2(&sr, &cfb->FrameRect, &dr, &cfb->VisRect)) {
39753893Smckusick 		fbbm_rop_init(cfb, copyfuncv);
39853893Smckusick 		fbbm_rop_copy(cfb, &sr, &dr.origin, 0, FB_PLANEALL);
39953893Smckusick 	}
40053893Smckusick }
40153893Smckusick 
40253893Smckusick void
40353893Smckusick cursorOn(fb)
40453893Smckusick 	register struct fbdev *fb;
40553893Smckusick {
40653893Smckusick #ifdef CPU_SINGLE
40753893Smckusick 	int s = splbitmap();
40853893Smckusick #endif
40953893Smckusick 
41053893Smckusick 	if (cfb == fb && fb->cursorShow && !fb->cursorVis) {
41153893Smckusick 		if (fb->hard_cursor) {
41253893Smckusick 			fbbm_cursor_on(fb);
41353893Smckusick 		} else {
41453893Smckusick 			fbcopy2(fb->cursorP, fb->SaveRect.origin);
41553893Smckusick 			fbcopy1(fb->MaskRect.origin, fb->cursorP,
41653893Smckusick 				fb->maskfuncv);
41753893Smckusick 			fbcopy1(fb->CursorRect.origin, fb->cursorP,
41853893Smckusick 				fb->curfuncv);
41953893Smckusick 		}
42053893Smckusick 		fb->cursorVis = 1;
42153893Smckusick 	}
42253893Smckusick #ifdef CPU_SINGLE
42353893Smckusick 	splx(s);
42453893Smckusick #endif
42553893Smckusick }
42653893Smckusick 
42753893Smckusick void
42853893Smckusick cursorOff(fb)
42953893Smckusick 	register struct fbdev *fb;
43053893Smckusick {
43153893Smckusick #ifdef CPU_SINGLE
43253893Smckusick 	int s = splbitmap();
43353893Smckusick #endif
43453893Smckusick 
43553893Smckusick 	if (cfb == fb && fb->cursorShow && fb->cursorVis) {
43653893Smckusick 		if (fb->hard_cursor)
43753893Smckusick 			fbbm_cursor_off(fb);
43853893Smckusick 		else
43953893Smckusick 			fbcopy3(fb->SaveRect.origin, fb->cursorP);
44053893Smckusick 		fb->cursorVis = 0;
44153893Smckusick 	}
44253893Smckusick #ifdef CPU_SINGLE
44353893Smckusick 	splx(s);
44453893Smckusick #endif
44553893Smckusick }
44653893Smckusick 
44753893Smckusick void
44853893Smckusick softCursorCheck(fb, stype, srect, dtype, drect)
44953893Smckusick 	struct fbdev *fb;
45053893Smckusick 	char stype, dtype;
45153893Smckusick 	lRectangle *srect, *drect;
45253893Smckusick {
45353893Smckusick 	if (cfb == fb  && cfb->cursorVis &&
45453893Smckusick 	    ((stype == BM_FB && cursorIn(fb, srect)) ||
45553893Smckusick 	    (dtype == BM_FB && cursorIn(fb, drect))))
45653893Smckusick 		cursorOff(cfb);
45753893Smckusick }
45853893Smckusick 
45953893Smckusick void
46053893Smckusick cursorCheck(fb, stype, srect, dtype, drect)
46153893Smckusick 	struct fbdev *fb;
46253893Smckusick 	char stype, dtype;
46353893Smckusick 	lRectangle *srect, *drect;
46453893Smckusick {
46553893Smckusick 	if (!fb->hard_cursor)
46653893Smckusick 		softCursorCheck(fb, stype, srect, dtype, drect);
46753893Smckusick }
46853893Smckusick 
46953893Smckusick int
47053893Smckusick redrawCursor(fb)
47153893Smckusick 	register struct fbdev *fb;
47253893Smckusick {
47353893Smckusick 	int s;
47453893Smckusick 	lPoint	tmp;
47553893Smckusick 
47653893Smckusick 	if (cfb == fb && fb->cursorSet) {
47753893Smckusick 		s = spl7();
47853893Smckusick 		tmp = mp;
47953893Smckusick 		splx(s);
48053893Smckusick 
48153893Smckusick #ifdef CPU_SINGLE
48253893Smckusick 		s = splbitmap();
48353893Smckusick #endif
48453893Smckusick 		if (fb->cursorP.x != tmp.x || fb->cursorP.y != tmp.y) {
48553893Smckusick 			if (fb->cursorVis) {
48653893Smckusick 				if (! fb->hard_cursor) {
48753893Smckusick 					fbcopy3(fb->SaveRect.origin,
48853893Smckusick 						fb->cursorP);
48953893Smckusick 				}
49053893Smckusick 			}
49153893Smckusick 			fb->cursorP = tmp;
49253893Smckusick 			if (fb->hard_cursor) {
49353893Smckusick 				fbbm_cursor_off(fb);
49453893Smckusick 				fbbm_cursor_move(fb);
49553893Smckusick 			}
49653893Smckusick 			if (fb->cursorVis) {
49753893Smckusick 				if (fb->hard_cursor) {
49853893Smckusick 					fbbm_cursor_on(fb);
49953893Smckusick 				} else {
50053893Smckusick 					fbcopy2(fb->cursorP,
50153893Smckusick 						fb->SaveRect.origin);
50253893Smckusick 					fbcopy1(fb->MaskRect.origin,
50353893Smckusick 						fb->cursorP, fb->maskfuncv);
50453893Smckusick 					fbcopy1(fb->CursorRect.origin,
50553893Smckusick 						fb->cursorP, fb->curfuncv);
50653893Smckusick 				}
50753893Smckusick 			}
50853893Smckusick 		}
50953893Smckusick #ifdef CPU_SINGLE
51053893Smckusick 		splx(s);
51153893Smckusick #endif
51253893Smckusick 	}
51353893Smckusick 	return (0);
51453893Smckusick }
51553893Smckusick 
51653893Smckusick void
51753893Smckusick updateCursor(x, y, flag)
51853893Smckusick 	int *x, *y;
51953893Smckusick 	int flag;
52053893Smckusick {
52153893Smckusick 	int s;
52253893Smckusick 
52353893Smckusick 	if (cfb && cfb->cursorSet) {
52453893Smckusick 		checkArea(cfb, x, y);
52553893Smckusick 		s = spl7();
52653893Smckusick 		mp.x = *x - cfb->hot.x;
52753893Smckusick 		mp.y = *y - cfb->hot.y;
52853893Smckusick 		splx(s);
52953893Smckusick #ifdef CPU_SINGLE
53053893Smckusick 		if (flag || cfb->hard_cursor) {
53153893Smckusick 			curs_pending = 0;
53253893Smckusick 			redrawCursor(cfb);
53353893Smckusick 		} else if (cfb->type == FB_LCDM) {
53453893Smckusick 			if (!lock_bitmap_poll()) {
53553893Smckusick 				curs_pending = 0;
53653893Smckusick 				redrawCursor(cfb);
53753893Smckusick 				unlock_bitmap_poll();
53853893Smckusick 			} else {
53953893Smckusick 				curs_pending = 1;
54053893Smckusick 			}
54153893Smckusick 		}
54253893Smckusick #else
54353893Smckusick 		redrawCursor(cfb);
54453893Smckusick #endif
54553893Smckusick 	}
54653893Smckusick }
54753893Smckusick 
54853893Smckusick setCursor(fb, cursor)
54953893Smckusick 	register struct fbdev *fb;
55053893Smckusick 	register lCursor2  *cursor;
55153893Smckusick {
55253893Smckusick 	register char *fv;
55353893Smckusick 	register int f0, f1, i, color;
55453893Smckusick #ifdef CPU_SINGLE
55553893Smckusick 	register int s = splbitmap();
55653893Smckusick #endif
55753893Smckusick 	int	data;
55853893Smckusick 
55953893Smckusick 	if (cfb == fb) {
56053893Smckusick 		cursorOff(cfb);
56153893Smckusick 		fb->cursorShow = 0;
56253893Smckusick 		fb->cursorP.x += cfb->hot.x;
56353893Smckusick 		fb->cursorP.y += cfb->hot.y;
56453893Smckusick #ifdef CPU_SINGLE
56553893Smckusick 		data = FB_INT_VSYNC;
56653893Smckusick 		fbbm_ioctl(fb, FB_INTCLEAR, &data);
56753893Smckusick #endif
56853893Smckusick 		cfb = NULL;
56953893Smckusick 	}
57053893Smckusick 
57153893Smckusick 	if (cursor) {
57253893Smckusick 		fb->CursorRect = cursor->cursorRect;
57353893Smckusick 		fb->MaskRect = cursor->maskRect;
57453893Smckusick 		fb->SaveRect = cursor->saveRect;
57553893Smckusick 		fb->moveArea = cursor->moveArea;
57653893Smckusick 		fb->hot = cursor->hot;
57753893Smckusick 		fb->size = cursor->size;
57853893Smckusick 
57953893Smckusick 		f0 = 0x4 | ((cursor->func >> 2) & 0x3);
58053893Smckusick 		f1 = 0x4 | (cursor->func & 0x3);
58153893Smckusick 
58253893Smckusick 		i = fb->fbNplane;
58353893Smckusick 		fv = fb->curfuncv;
58453893Smckusick 		color = cursor->cursor_color;
58553893Smckusick 		while (i-- > 0) {
58653893Smckusick 			*fv++ = (color & 1) ? f1 : f0;
58753893Smckusick 			color >>= 1;
58853893Smckusick 		}
58953893Smckusick 
59053893Smckusick 		i = fb->fbNplane;
59153893Smckusick 		fv = fb->maskfuncv;
59253893Smckusick 		color = cursor->mask_color;
59353893Smckusick 		while (i-- > 0) {
59453893Smckusick 			*fv++ = (color & 1) ? f1 : f0;
59553893Smckusick 			color >>= 1;
59653893Smckusick 		}
59753893Smckusick 
59853893Smckusick 		checkArea(fb, &fb->cursorP.x, &fb->cursorP.y);
59953893Smckusick 		fb->cursorP.x -= fb->hot.x;
60053893Smckusick 		fb->cursorP.y -= fb->hot.y;
60153893Smckusick 		fb->cursorSet = 1;
60253893Smckusick 		fb->cursorShow = 0;
60353893Smckusick 		fb->cursorVis = 0;
60453893Smckusick 		if (fb->hard_cursor) {
60553893Smckusick 			fbbm_cursor_off(fb);
60653893Smckusick 			fbbm_cursor_set(fb, cursor->cursor_color, cursor->mask_color);
60753893Smckusick 			fbbm_cursor_move(fb);
60853893Smckusick 		}
60953893Smckusick 	} else {
61053893Smckusick 		fb->cursorP.x = fb->VisRect.extent.x / 2;
61153893Smckusick 		fb->cursorP.y = fb->VisRect.extent.y / 2;
61253893Smckusick 		fb->cursorSet = 0;
61353893Smckusick 		fb->cursorShow = 0;
61453893Smckusick 		fb->cursorVis = 0;
61553893Smckusick 		if (fb->hard_cursor)
61653893Smckusick 			fbbm_cursor_off(fb);
61753893Smckusick 	}
61853893Smckusick #ifdef CPU_SINGLE
61953893Smckusick 	splx(s);
62053893Smckusick #endif
62153893Smckusick 	return (FB_ROK);
62253893Smckusick }
62353893Smckusick 
62453893Smckusick showCursor(fb)
62553893Smckusick 	register struct fbdev *fb;
62653893Smckusick {
62753893Smckusick 	int data;
62853893Smckusick #ifdef CPU_SINGLE
62953893Smckusick 	register int s = splbitmap();
63053893Smckusick #endif
63153893Smckusick 
63253893Smckusick 	if (fb->cursorSet && !fb->cursorShow) {
63353893Smckusick 		if (cfb && cfb != fb) {
63453893Smckusick 			cursorOff(cfb);
63553893Smckusick 			cfb->cursorShow = 0;
63653893Smckusick 		}
63753893Smckusick 		cfb = fb;
63853893Smckusick 		fb->cursorShow = 1;
63953893Smckusick 		mp = fb->cursorP;
64053893Smckusick 		cursorOn(fb);
64153893Smckusick #ifdef CPU_SINGLE
64253893Smckusick 		data = FB_INT_VSYNC;
64353893Smckusick 		fbbm_ioctl(fb, FB_INTENABLE, &data);
64453893Smckusick 		splx(s);
64553893Smckusick #endif
64653893Smckusick 		return (FB_ROK);
64753893Smckusick 	}
64853893Smckusick #ifdef CPU_SINGLE
64953893Smckusick 	splx(s);
65053893Smckusick #endif
65153893Smckusick 	return (FB_RERROR);
65253893Smckusick }
65353893Smckusick 
65453893Smckusick 
65553893Smckusick hideCursor(fb)
65653893Smckusick 	register struct fbdev *fb;
65753893Smckusick {
65853893Smckusick 	int data;
65953893Smckusick #ifdef CPU_SINGLE
66053893Smckusick 	int s = splbitmap();
66153893Smckusick #endif
66253893Smckusick 
66353893Smckusick 	if (cfb == fb) {
66453893Smckusick 		cursorOff(fb);
66553893Smckusick 		fb->cursorShow = 0;
66653893Smckusick #ifdef CPU_SINGLE
66753893Smckusick 		data = FB_INT_VSYNC;
66853893Smckusick 		fbbm_ioctl(fb, FB_INTCLEAR, &data);
66953893Smckusick 		splx(s);
67053893Smckusick #endif
67153893Smckusick 		return (FB_ROK);
67253893Smckusick 	}
67353893Smckusick #ifdef CPU_SINGLE
67453893Smckusick 	splx(s);
67553893Smckusick #endif
67653893Smckusick 	return (FB_RERROR);
67753893Smckusick }
67853893Smckusick 
67953893Smckusick 
68053893Smckusick moveCursor(fb, point)
68153893Smckusick 	struct fbdev *fb;
68253893Smckusick 	lPoint *point;
68353893Smckusick {
68453893Smckusick 	if (cfb == fb) {
68553893Smckusick 		updateCursor(&point->x, &point->y, 1);
68653893Smckusick 		return (FB_ROK);
68753893Smckusick 	}
68853893Smckusick 	return (FB_RERROR);
68953893Smckusick }
69053893Smckusick 
69153893Smckusick #ifdef CPU_SINGLE
69253893Smckusick rop_xint()
69353893Smckusick {
69453893Smckusick 	register struct fbdev *fb;
69553893Smckusick 	register int i;
69653893Smckusick 	register int done = 0;
69753893Smckusick 	int event, data;
69853893Smckusick 	int s = splbitmap();
69953893Smckusick 
70053893Smckusick 	for (i = 0, fb = fbdev; i < nfbdev; i++, fb++) {
70153893Smckusick 		if (fb->type && (event = fbbm_ioctl(fb, FB_INTCHECK, 0))) {
70253893Smckusick #ifdef notyet /* KU:XXX */
70353893Smckusick 			intrcnt[INTR_BITMAP]++;
70453893Smckusick #endif
70553893Smckusick 			done = 1;
70653893Smckusick 			if (event & FB_INT_VSYNC) {
70753893Smckusick 				data = FB_INT_VSYNC;
70853893Smckusick 				fbbm_ioctl(fb, FB_INTCLEAR, &data);
70953893Smckusick 				if (!lock_bitmap_poll()) {
71053893Smckusick 					curs_pending = 0;
71153893Smckusick 					redrawCursor(fb);
71253893Smckusick 					unlock_bitmap_poll();
71353893Smckusick 				} else {
71453893Smckusick 					curs_pending = 1;
71553893Smckusick 				}
71653893Smckusick 				data = FB_INT_VSYNC;
71753893Smckusick 				fbbm_ioctl(fb, FB_INTENABLE, &data);
71853893Smckusick 			}
71953893Smckusick 			if (event & FB_INT_ROPDONE) {
72053893Smckusick 				if(fb->run_flag & FB_WAITING) {
72153893Smckusick 					data = FB_INT_ROPDONE;
72253893Smckusick 					fbbm_ioctl(fb, FB_INTCLEAR, &data);
72353893Smckusick 					if (!(fbbm_ioctl(fb, FB_STATUSCHECK, 0)
72453893Smckusick 					& (FB_STATUS_ROPWAIT|FB_STATUS_ROPEXEC))) {
72553893Smckusick 						fb->run_flag &= ~FB_WAITING;
72653893Smckusick 						wakeup(&(fb->run_flag));
72753893Smckusick 					} else {
72853893Smckusick 						data = FB_INT_ROPDONE|0x100;
72953893Smckusick 						fbbm_ioctl(fb, FB_INTENABLE, &data);
73053893Smckusick 					}
73153893Smckusick 				}
73253893Smckusick 			}
73353893Smckusick 		}
73453893Smckusick 	}
73553893Smckusick 	splx(s);
73653893Smckusick 	return (done);
73753893Smckusick }
73853893Smckusick #endif /* CPU_SINGLE */
73953893Smckusick 
74053893Smckusick cliprect2(sr, sc, dr, dc)
74153893Smckusick 	register lRectangle *sr;
74253893Smckusick 	register lRectangle *sc;
74353893Smckusick 	register lRectangle *dr;
74453893Smckusick 	register lRectangle *dc;
74553893Smckusick {
74653893Smckusick 	register int d;
74753893Smckusick 
74853893Smckusick 	/* src left/right edge */
74953893Smckusick 	if ((d = sr->origin.x - sc->origin.x) < 0) {
75053893Smckusick 		sr->extent.x += d;
75153893Smckusick 		sr->origin.x -= d;
75253893Smckusick 		dr->origin.x -= d;
75353893Smckusick 		d = sr->extent.x - sc->extent.x;
75453893Smckusick 	} else
75553893Smckusick 		d += sr->extent.x - sc->extent.x;
75653893Smckusick 	if (d > 0)
75753893Smckusick 		sr->extent.x -= d;
75853893Smckusick 
75953893Smckusick 	/* src top/bottom edge */
76053893Smckusick 	if ((d = sr->origin.y - sc->origin.y) < 0) {
76153893Smckusick 		sr->extent.y += d;
76253893Smckusick 		sr->origin.y -= d;
76353893Smckusick 		dr->origin.y -= d;
76453893Smckusick 		d = sr->extent.y - sc->extent.y;
76553893Smckusick 	} else
76653893Smckusick 		d += sr->extent.y - sc->extent.y;
76753893Smckusick 	if (d > 0)
76853893Smckusick 		sr->extent.y -= d;
76953893Smckusick 
77053893Smckusick 	if (sr->extent.x <= 0 || sr->extent.y <= 0)
77153893Smckusick 		return (0);
77253893Smckusick 
77353893Smckusick 	/* dst left/right edge */
77453893Smckusick 	if ((d = dr->origin.x - dc->origin.x) < 0) {
77553893Smckusick 		dr->origin.x -= d;
77653893Smckusick 		sr->extent.x += d;
77753893Smckusick 		sr->origin.x -= d;
77853893Smckusick 		d = sr->extent.x - dc->extent.x;
77953893Smckusick 	} else
78053893Smckusick 		d += sr->extent.x - dc->extent.x;
78153893Smckusick 	if (d > 0)
78253893Smckusick 		sr->extent.x -= d;
78353893Smckusick 
78453893Smckusick 	/* dst top/bottom edge */
78553893Smckusick 	if ((d = dr->origin.y - dc->origin.y) < 0) {
78653893Smckusick 		dr->origin.y -= d;
78753893Smckusick 		sr->extent.y += d;
78853893Smckusick 		sr->origin.y -= d;
78953893Smckusick 		d = sr->extent.y - dc->extent.y;
79053893Smckusick 	} else
79153893Smckusick 		d += sr->extent.y - dc->extent.y;
79253893Smckusick 	if (d > 0)
79353893Smckusick 		sr->extent.y -= d;
79453893Smckusick 
79553893Smckusick 	if (sr->extent.x <= 0 || sr->extent.y <= 0)
79653893Smckusick 		return (0);
79753893Smckusick 
79853893Smckusick 	dr->extent = sr->extent;
79953893Smckusick 	return (1);
80053893Smckusick }
80153893Smckusick 
80253893Smckusick cliprect(r, crp, p)
80353893Smckusick 	register lRectangle *r;
80453893Smckusick 	register lRectangle *crp;
80553893Smckusick 	register lRectangle *p;
80653893Smckusick {
80753893Smckusick 	register int d;
80853893Smckusick 
80953893Smckusick 	/* left edge */
81053893Smckusick 	if ((d = r->origin.x - crp->origin.x) < 0) {
81153893Smckusick 		r->extent.x += d;
81253893Smckusick 		r->origin.x -= d;
81353893Smckusick 		if (p) {
81453893Smckusick 			p->extent.x += d;
81553893Smckusick 			p->origin.x -= d;
81653893Smckusick 		}
81753893Smckusick 		d = r->extent.x - crp->extent.x;
81853893Smckusick 	} else
81953893Smckusick 		d += r->extent.x - crp->extent.x;
82053893Smckusick 
82153893Smckusick 	/* right edge */
82253893Smckusick 	if (d > 0) {
82353893Smckusick 		r->extent.x -= d;
82453893Smckusick 		if (p)
82553893Smckusick 			p->extent.x -= d;
82653893Smckusick 	}
82753893Smckusick 
82853893Smckusick 	/* top edge */
82953893Smckusick 	if ((d = r->origin.y - crp->origin.y) < 0) {
83053893Smckusick 		r->extent.y += d;
83153893Smckusick 		r->origin.y -= d;
83253893Smckusick 		if (p) {
83353893Smckusick 			p->extent.y += d;
83453893Smckusick 			p->origin.y -= d;
83553893Smckusick 		}
83653893Smckusick 		d = r->extent.y - crp->extent.y;
83753893Smckusick 	} else
83853893Smckusick 		d += r->extent.y - crp->extent.y;
83953893Smckusick 
84053893Smckusick 	/* bottom edge */
84153893Smckusick 	if (d > 0) {
84253893Smckusick 		r->extent.y -= d;
84353893Smckusick 		if (p)
84453893Smckusick 			p->extent.y -= d;
84553893Smckusick 	}
84653893Smckusick 
84753893Smckusick 	return (r->extent.x > 0 && r->extent.y > 0);
84853893Smckusick }
84953893Smckusick 
85053893Smckusick getclip(fb, bmp, crp)
85153893Smckusick 	struct fbdev *fb;
85253893Smckusick 	lBitmap *bmp;
85353893Smckusick 	lRectangle *crp;
85453893Smckusick {
85553893Smckusick 	/* limit clip rectangle to bitmap rectangle */
85653893Smckusick 	if (!cliprect(crp, &bmp->rect, (lRectangle*)0))
85753893Smckusick 		return (0);
85853893Smckusick 
85953893Smckusick 	/* limit clip rectangle to frame buffer */
86053893Smckusick 	if ((bmp->type == BM_FB) &&
86153893Smckusick 	    !cliprect(crp, &fb->FrameRect, (lRectangle*)0))
86253893Smckusick 		return (0);
86353893Smckusick 	return (1);
86453893Smckusick }
86553893Smckusick 
86653893Smckusick 
86753893Smckusick clipsrc(fb, bmp)
86853893Smckusick 	struct fbdev *fb;
86953893Smckusick 	lBitmap *bmp;
87053893Smckusick {
87153893Smckusick 	/* limit clip rectangle to frame buffer */
87253893Smckusick 	if (bmp->type == BM_FB &&
87353893Smckusick 	    !cliprect(&bmp->rect, &fb->FrameRect, (lRectangle*)0))
87453893Smckusick 		return (0);
87553893Smckusick 	return (1);
87653893Smckusick }
87753893Smckusick 
87853893Smckusick 
87953893Smckusick setrop(fb, func, pmask, fore, aux, trans, sbp, dbp)
88053893Smckusick 	register struct fbdev *fb;
88153893Smckusick 	register unsigned int func;
88253893Smckusick 	int pmask;
88353893Smckusick 	register int fore, aux;
88453893Smckusick 	int trans;
88553893Smckusick 	lBitmap *sbp, *dbp;
88653893Smckusick {
88753893Smckusick 	register char *funcp;
88853893Smckusick 	register int i;
88953893Smckusick 	char tmp[4];
89053893Smckusick 
89153893Smckusick 	/* set plane register */
89253893Smckusick 
89353893Smckusick 	fb->Mode = 0;
89453893Smckusick 	fb->Pmask = pmask;
89553893Smckusick 	fb->func = func;
89653893Smckusick 	fb->fore = fore;
89753893Smckusick 	fb->aux = aux;
89853893Smckusick 	fb->trans = trans;
89953893Smckusick 
90053893Smckusick 	if (sbp->depth > 1)
90153893Smckusick 		fb->Mode |= 2;
90253893Smckusick 
90353893Smckusick 	if (dbp->depth > 1)
90453893Smckusick 		fb->Mode |= 1;
90553893Smckusick 
90653893Smckusick 	/* set rop function register */
90753893Smckusick 	func &= 0xf;
90853893Smckusick 
90953893Smckusick 	tmp[0] = TRANS(trans, (func & 0x0c) | (func>>2));
91053893Smckusick 	tmp[1] = TRANS(trans, (func>>2) | ((func<<2) & 0x0c));
91153893Smckusick 	tmp[2] = TRANS(trans, func);
91253893Smckusick 	tmp[3] = TRANS(trans, (func<<2) & 0x0c | func & 3);
91353893Smckusick 
91453893Smckusick 	funcp = fb->funcvec;
91553893Smckusick 	for (i = fb->fbNplane; --i >= 0;) {
91653893Smckusick 		*funcp++ = tmp[((fore & 1) << 1) | (aux & 1)];
91753893Smckusick 		fore >>= 1; aux >>= 1;
91853893Smckusick 	}
91953893Smckusick 	return (0);
92053893Smckusick }
92153893Smckusick 
92253893Smckusick /*
92353893Smckusick  * bitblt within frame buffer
92453893Smckusick  */
92553893Smckusick 
92653893Smckusick bitblt_fb(fb, sbp, srp, dbp, dpp, crp)
92753893Smckusick 	register struct fbdev *fb;
92853893Smckusick 	register lBitmap *sbp;	/* source bitmap (FB) */
92953893Smckusick 	lRectangle *srp;	/* source rectangle */
93053893Smckusick 	lBitmap *dbp;		/* destination bitmap (FB) */
93153893Smckusick 	lPoint *dpp;		/* destination point */
93253893Smckusick 	lRectangle *crp;	/* clip region in destination */
93353893Smckusick {
93453893Smckusick 	lRectangle sr;
93553893Smckusick 	lRectangle dr;
93653893Smckusick 	register int wplane, i, j;
93753893Smckusick 
93853893Smckusick 	sr = *srp;
93953893Smckusick 	dr.origin = *dpp;
94053893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
94153893Smckusick 		return (0);
94253893Smckusick 
94353893Smckusick 	fbbm_rop_init(fb, fb->funcvec);
94453893Smckusick 
94553893Smckusick 	switch (fb->Mode) {
94653893Smckusick 
94753893Smckusick 	case MODE_1to1:
94853893Smckusick 		fb->Pmask &= 1;
94953893Smckusick 
95053893Smckusick 	case MODE_NtoN:
95153893Smckusick 
95253893Smckusick 		fbbm_rop_copy(fb, &sr, &dr.origin, 0, fb->Pmask);
95353893Smckusick 		break;
95453893Smckusick 
95553893Smckusick 	case MODE_1toN:
95653893Smckusick 		fbbm_rop_copy(fb, &sr, &dr.origin, 1, fb->Pmask);
95753893Smckusick 		break;
95853893Smckusick 
95953893Smckusick 	case MODE_Nto1:
96053893Smckusick 		wplane = 1;
96153893Smckusick 		for (i = 0, j = sbp->depth; i < j; i++) {
96253893Smckusick 			if (fb->Pmask & wplane) {
96353893Smckusick 				fbbm_rop_copy(fb, &sr, &dr.origin, i + 1,
96453893Smckusick 				    fb->Pmask >> 16);
96553893Smckusick 				break;
96653893Smckusick 			}
96753893Smckusick 			wplane <<= 1;
96853893Smckusick 		}
96953893Smckusick 		break;
97053893Smckusick 	default:
97153893Smckusick 		return (-1);
97253893Smckusick 	}
97353893Smckusick 	return (0);
97453893Smckusick }
97553893Smckusick 
97653893Smckusick /*
97753893Smckusick  * bitblt from main memory to frame buffer
97853893Smckusick  */
97953893Smckusick 
98053893Smckusick bitblt_tofb(fb, sbp, srp, dbp, dpp, crp)
98153893Smckusick 	register struct fbdev *fb;
98253893Smckusick 	register lBitmap *sbp;	/* source bitmap (MEM) */
98353893Smckusick 	lRectangle *srp;	/* source rectangle */
98453893Smckusick 	lBitmap *dbp;		/* destination bitmap (FB) */
98553893Smckusick 	lPoint *dpp;		/* destination point */
98653893Smckusick 	lRectangle *crp;	/* clip region in destination */
98753893Smckusick {
98853893Smckusick 	register unsigned p;
98953893Smckusick 	register struct fb_map *smap;
99053893Smckusick 	register int i, n, m;
99153893Smckusick 	lRectangle sr;
99253893Smckusick 	lRectangle dr;
99353893Smckusick 	register int wplane;
99453893Smckusick #ifdef IPC_MRX
99553893Smckusick 	extern struct fb_map rommap;
99653893Smckusick 	register int pages;
99753893Smckusick #endif
99853893Smckusick 
99953893Smckusick 	smap = (struct fb_map*)sbp->base;
100053893Smckusick 
100153893Smckusick 	sr = *srp;
100253893Smckusick 	dr.origin = *dpp;
100353893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
100453893Smckusick 		return (0);
100553893Smckusick 	dr.extent = sr.extent;
100653893Smckusick 
100753893Smckusick 	/* transform source rectangle */
100853893Smckusick 	sr.origin.x -= sbp->rect.origin.x;
100953893Smckusick 	sr.origin.y -= sbp->rect.origin.y;
101053893Smckusick 
101153893Smckusick 	/*
101253893Smckusick 	 * check memory map specification
101353893Smckusick 	 */
101453893Smckusick 	p = smap->fm_offset;
101553893Smckusick #ifdef IPC_MRX
101653893Smckusick 	pages = btoc(smap->fm_offset + smap->fm_count);
101753893Smckusick 	rommap.fm_vaddr = fb_map_page(smap->fm_addr, pages,
101853893Smckusick 		    fb->cache_off ? PG_S|PG_WP|PG_CI : PG_S|PG_WP);
101953893Smckusick 	rommap.fm_offset = 0;
102053893Smckusick 	smap = &rommap;
102153893Smckusick #endif
102253893Smckusick 
102353893Smckusick 	wplane = 1;
102453893Smckusick 
102553893Smckusick 	fbbm_rop_winit(fb);
102653893Smckusick 
102753893Smckusick 	switch (fb->Mode) {
102853893Smckusick 	case MODE_1to1:
102953893Smckusick 		fbbm_rop_write(fb, smap, p, sbp->width,
103053893Smckusick 			       &sr, &dr, fb->Pmask & 0x01);
103153893Smckusick 		break;
103253893Smckusick 	case MODE_1toN:
103353893Smckusick 		fbbm_rop_write(fb, smap, p, sbp->width,
103453893Smckusick 			       &sr, &dr, fb->Pmask);
103553893Smckusick 		break;
103653893Smckusick 	case MODE_Nto1:
103753893Smckusick 		m = sbp->width * sbp->rect.extent.y;
103853893Smckusick 		for (i = 0; i < sbp->depth; i++, wplane <<= 1) {
103953893Smckusick 			if (fb->Pmask & wplane) {
104053893Smckusick 				p += (m * i) << 1;
104153893Smckusick 				fbbm_rop_write(fb, smap, p, sbp->width,
104253893Smckusick 					       &sr, &dr, wplane);
104353893Smckusick 				break;
104453893Smckusick 			}
104553893Smckusick 			wplane <<= 1;
104653893Smckusick 		}
104753893Smckusick 		break;
104853893Smckusick 	case MODE_NtoN:
1049*55763Sbostic 		n = min(sbp->depth, fb->fbNplane);
105053893Smckusick 		m = sbp->width * sbp->rect.extent.y;
105153893Smckusick 		p += (m << 1) * n;
105253893Smckusick 		wplane = 1 << (n - 1);
105353893Smckusick 		for (i = n; i > 0; i--) {
105453893Smckusick 			/* get next plane */
105553893Smckusick 			p -= m << 1;
105653893Smckusick 			if (fb->Pmask & wplane)
105753893Smckusick 				fbbm_rop_write(fb, smap, p, sbp->width,
105853893Smckusick 					       &sr, &dr, wplane);
105953893Smckusick 			/* next plane mask */
106053893Smckusick 			wplane >>= 1;
106153893Smckusick 		}
106253893Smckusick 		break;
106353893Smckusick 	default:
106453893Smckusick 		return (-1);
106553893Smckusick 	}
106653893Smckusick 	return (0);
106753893Smckusick }
106853893Smckusick 
106953893Smckusick /*
107053893Smckusick  * bitblt from frame buffer to main memroy
107153893Smckusick  */
107253893Smckusick 
107353893Smckusick bitblt_tomem(fb, sbp, srp, dbp, dpp, crp)
107453893Smckusick 	struct fbdev *fb;
107553893Smckusick 	lBitmap *sbp;		/* source bitmap (FB) */
107653893Smckusick 	lRectangle *srp;	/* source rectangle */
107753893Smckusick 	lBitmap *dbp;		/* destination bitmap (MEM) */
107853893Smckusick 	lPoint *dpp;		/* destination point */
107953893Smckusick 	lRectangle *crp;	/* clip region in destination */
108053893Smckusick {
108153893Smckusick 	register struct fb_map *dmap;
108253893Smckusick 	register unsigned p;
108353893Smckusick 	register int i, n, m;
108453893Smckusick 	lRectangle sr;
108553893Smckusick 	lRectangle dr;
108653893Smckusick 	int plane;
108753893Smckusick #ifdef IPC_MRX
108853893Smckusick 	extern struct fb_map rommap;
108953893Smckusick 	register int pages;
109053893Smckusick #endif
109153893Smckusick 
109253893Smckusick 	dmap = (struct fb_map*)dbp->base;
109353893Smckusick 
109453893Smckusick 	sr = *srp;
109553893Smckusick 	dr.origin = *dpp;
109653893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
109753893Smckusick 		return (0);
109853893Smckusick 	dr.extent = sr.extent;
109953893Smckusick 
110053893Smckusick 	dr.origin.x -= dbp->rect.origin.x;
110153893Smckusick 	dr.origin.y -= dbp->rect.origin.y;
110253893Smckusick 
110353893Smckusick 	p = dmap->fm_offset;
110453893Smckusick #ifdef IPC_MRX
110553893Smckusick 	pages = btoc(dmap->fm_offset + dmap->fm_count);
110653893Smckusick 	rommap.fm_vaddr = fb_map_page(dmap->fm_addr, pages, PG_S);
110753893Smckusick 	rommap.fm_offset = 0;
110853893Smckusick 	dmap = &rommap;
110953893Smckusick #endif
111053893Smckusick 
111153893Smckusick 	plane = 1;
111253893Smckusick 
111353893Smckusick /*	Wait for rop busy */
111453893Smckusick 
111553893Smckusick 	switch (fb->Mode) {
111653893Smckusick 
111753893Smckusick 	case MODE_1to1:
111853893Smckusick 		if (fb->Pmask & plane)
111953893Smckusick 			fbbm_rop_read(fb, dmap, p, dbp->width,
112053893Smckusick 				      &sr, &dr, 0, 0);
112153893Smckusick 		break;
112253893Smckusick 
112353893Smckusick 	case MODE_1toN:
112453893Smckusick 		m = (dbp->width * dbp->rect.extent.y) << 1;
112553893Smckusick 		for (i = 0; i < dbp->depth; i++) {
112653893Smckusick 			if (fb->Pmask & plane)
112753893Smckusick 				fbbm_rop_read(fb, dmap, p, dbp->width,
112853893Smckusick 					      &sr, &dr, 0, i);
112953893Smckusick 			/* next plane */
113053893Smckusick 			p += m;
113153893Smckusick 			plane <<= 1;
113253893Smckusick 		}
113353893Smckusick 		break;
113453893Smckusick 
113553893Smckusick 	case MODE_Nto1:
113653893Smckusick 		for (i = 0; i < sbp->depth; i++, plane <<= 1) {
113753893Smckusick 			if (fb->Pmask & plane) {
113853893Smckusick 				fbbm_rop_read(fb, dmap, p, dbp->width,
113953893Smckusick 					      &sr, &dr, i, 0);
114053893Smckusick 				break;
114153893Smckusick 			}
114253893Smckusick 		}
114353893Smckusick 		break;
114453893Smckusick 
114553893Smckusick 	case MODE_NtoN:
1146*55763Sbostic 		n = min(dbp->depth, fb->fbNplane);
114753893Smckusick 		m = (dbp->width * dbp->rect.extent.y) << 1;
114853893Smckusick 		for (i = 0; i < n; i++) {
114953893Smckusick 			if (fb->Pmask & plane)
115053893Smckusick 				fbbm_rop_read(fb, dmap, p, dbp->width,
115153893Smckusick 					      &sr, &dr, i, i);
115253893Smckusick 			/* next plane */
115353893Smckusick 			p += m;
115453893Smckusick 			plane <<= 1;
115553893Smckusick 		}
115653893Smckusick 
115753893Smckusick 		break;
115853893Smckusick 
115953893Smckusick 	default:
116053893Smckusick 		return (-1);
116153893Smckusick 	}
116253893Smckusick 
116353893Smckusick 	return (0);
116453893Smckusick }
116553893Smckusick 
116653893Smckusick bitblt_mem(fb, sbp, srp, dbp, dpp, crp)
116753893Smckusick 	struct fbdev *fb;
116853893Smckusick 	register lBitmap *sbp;
116953893Smckusick 	lRectangle *srp;
117053893Smckusick 	register lBitmap *dbp;
117153893Smckusick 	lPoint *dpp;
117253893Smckusick 	lRectangle *crp;
117353893Smckusick {
117453893Smckusick 	register int i;
117553893Smckusick 	register int plane;
117653893Smckusick 	register struct fb_map *smap, *dmap;
117753893Smckusick 	register unsigned int ps, pd;
117853893Smckusick 	lRectangle sr;
117953893Smckusick 	lRectangle dr;
118053893Smckusick #ifdef IPC_MRX
118153893Smckusick 	static struct fb_map drommap;
118253893Smckusick 	int spages, dpages;
118353893Smckusick #endif
118453893Smckusick 
118553893Smckusick 	smap = (struct fb_map*)sbp->base;
118653893Smckusick 	dmap = (struct fb_map*)dbp->base;
118753893Smckusick 
118853893Smckusick 	sr = *srp;
118953893Smckusick 	dr.origin = *dpp;
119053893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
119153893Smckusick 		return (0);
119253893Smckusick 
119353893Smckusick 	/* normalize source/destination coordinates */
119453893Smckusick 	sr.origin.x -= sbp->rect.origin.x;
119553893Smckusick 	sr.origin.y -= sbp->rect.origin.y;
119653893Smckusick 	dr.origin.x -= dbp->rect.origin.x;
119753893Smckusick 	dr.origin.y -= dbp->rect.origin.y;
119853893Smckusick 
119953893Smckusick 	ps = smap->fm_offset;
120053893Smckusick 	pd = dmap->fm_offset;
120153893Smckusick #ifdef IPC_MRX
120253893Smckusick 	spages = btoc(smap->fm_offset + smap->fm_count);
120353893Smckusick 	dpages = btoc(dmap->fm_offset + dmap->fm_count);
120453893Smckusick 	rommap.fm_vaddr = fb_map_page2(smap->fm_addr, spages, PG_S|PG_WP);
120553893Smckusick 	rommap.fm_offset = 0;
120653893Smckusick 	drommap.fm_vaddr = fb_map_page2(dmap->fm_addr, dpages, PG_S);
120753893Smckusick 	drommap.fm_offset = 0;
120853893Smckusick 	smap = &rommap;
120953893Smckusick 	dmap = &drommap;
121053893Smckusick #endif
121153893Smckusick 
121253893Smckusick 	plane = 0x1;	/* plane 0 */
121353893Smckusick 
121453893Smckusick 	switch (fb->Mode) {
121553893Smckusick 
121653893Smckusick 	case MODE_1to1:
121753893Smckusick 		if (fb->Pmask & plane) {
121853893Smckusick 			mem_to_mem(fb->funcvec[0],
121953893Smckusick 				   smap, ps, sbp->width, dmap, pd, dbp->width,
122053893Smckusick 				   &sr, &dr.origin);
122153893Smckusick 		}
122253893Smckusick 		break;
122353893Smckusick 
122453893Smckusick 	case MODE_1toN:
122553893Smckusick 		for (i = 0; i < dbp->depth; i++) {
122653893Smckusick 			if (fb->Pmask & plane) {
122753893Smckusick 				mem_to_mem(fb->funcvec[i],
122853893Smckusick 					   smap, ps, sbp->width,
122953893Smckusick 					   dmap, pd, dbp->width,
123053893Smckusick 					   &sr, &dr.origin);
123153893Smckusick 			}
123253893Smckusick 			pd += (dbp->width * dbp->rect.extent.y) << 1;
123353893Smckusick 			plane <<= 1;
123453893Smckusick 		}
123553893Smckusick 		break;
123653893Smckusick 
123753893Smckusick 	case MODE_Nto1:
123853893Smckusick 		for (i = 0; i < sbp->depth; i++, plane <<= 1) {
123953893Smckusick 			if (fb->Pmask & plane)
124053893Smckusick 				break;
124153893Smckusick 		}
124253893Smckusick 		if (i < sbp->depth) {
124353893Smckusick 			ps += (sbp->width * sbp->rect.extent.y * i) << 1;
124453893Smckusick 			mem_to_mem(fb->funcvec[i],
124553893Smckusick 				   smap, ps, sbp->width, dmap, pd, dbp->width,
124653893Smckusick 				   &sr, &dr.origin);
124753893Smckusick 		}
124853893Smckusick 		break;
124953893Smckusick 
125053893Smckusick 	case MODE_NtoN:
125153893Smckusick 		for (i = 0; i < dbp->depth; i++) {
125253893Smckusick 			if (fb->Pmask & plane) {
125353893Smckusick 				mem_to_mem(fb->funcvec[i],
125453893Smckusick 					   smap, ps, sbp->width,
125553893Smckusick 					   dmap, pd, dbp->width,
125653893Smckusick 					   &sr, &dr.origin);
125753893Smckusick 			}
125853893Smckusick 			ps += (sbp->width * sbp->rect.extent.y) << 1;
125953893Smckusick 			pd += (dbp->width * dbp->rect.extent.y) << 1;
126053893Smckusick 			plane <<= 1;
126153893Smckusick 		}
126253893Smckusick 		break;
126353893Smckusick 
126453893Smckusick 	default:
126553893Smckusick 		return (-1);
126653893Smckusick 	}
126753893Smckusick #ifdef IPC_MRX
126853893Smckusick 	page_unmap(rommap.fm_vaddr, spages);
126953893Smckusick 	page_unmap(drommap.fm_vaddr, dpages);
127053893Smckusick #endif
127153893Smckusick 	return (0);
127253893Smckusick }
127353893Smckusick 
127453893Smckusick bitblt_nop()
127553893Smckusick {
127653893Smckusick 	return (0);
127753893Smckusick }
127853893Smckusick 
127953893Smckusick /*
128053893Smckusick  * bitblt from '0' bitmap to frame buffer
128153893Smckusick  */
128253893Smckusick 
128353893Smckusick bitblt_0tofb(fb, sbp, srp, dbp, dpp, crp)
128453893Smckusick 	register struct fbdev *fb;
128553893Smckusick 	lBitmap *sbp;		/* source bitmap (0) */
128653893Smckusick 	lRectangle *srp;	/* source rectangle */
128753893Smckusick 	lBitmap *dbp;		/* destination bitmap (FB) */
128853893Smckusick 	lPoint *dpp;		/* destination point */
128953893Smckusick 	lRectangle *crp;	/* clip region in destination */
129053893Smckusick {
129153893Smckusick 	lRectangle sr;
129253893Smckusick 	lRectangle dr;
129353893Smckusick 
129453893Smckusick 	sr = *srp;
129553893Smckusick 	dr.origin = *dpp;
129653893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
129753893Smckusick 		return (0);
129853893Smckusick 	dr.extent = sr.extent;
129953893Smckusick 
130053893Smckusick 	switch (fb->Mode) {
130153893Smckusick 
130253893Smckusick 	case MODE_1to1:
130353893Smckusick 	case MODE_Nto1:
130453893Smckusick 		fb->Pmask &= 1;
130553893Smckusick 		break;
130653893Smckusick 	case MODE_1toN:
130753893Smckusick 	case MODE_NtoN:
130853893Smckusick 		break;
130953893Smckusick 
131053893Smckusick 	default:
131153893Smckusick 		return (-1);
131253893Smckusick 	}
131353893Smckusick 
131453893Smckusick 	/*
131553893Smckusick 	 * write data into ROP data register
131653893Smckusick 	 */
131753893Smckusick 
131853893Smckusick 	fbbm_rop_cinit(fb, fb->Pmask, 0);
131953893Smckusick 	fbbm_rop_clear(fb, &dr);
132053893Smckusick 
132153893Smckusick 	return (0);
132253893Smckusick }
132353893Smckusick 
132453893Smckusick /*
132553893Smckusick  * bitblt from '1' bitmap to frame buffer
132653893Smckusick  */
132753893Smckusick 
132853893Smckusick bitblt_1tofb(fb, sbp, srp, dbp, dpp, crp)
132953893Smckusick 	register struct fbdev *fb;
133053893Smckusick 	lBitmap *sbp;		/* source bitmap (1) */
133153893Smckusick 	lRectangle *srp;	/* source rectangle */
133253893Smckusick 	lBitmap *dbp;		/* destination bitmap (FB) */
133353893Smckusick 	lPoint *dpp;		/* destination point */
133453893Smckusick 	lRectangle *crp;	/* clip region in destination */
133553893Smckusick {
133653893Smckusick 	lRectangle sr;
133753893Smckusick 	lRectangle dr;
133853893Smckusick 
133953893Smckusick 	sr = *srp;
134053893Smckusick 	dr.origin = *dpp;
134153893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
134253893Smckusick 		return (0);
134353893Smckusick 	dr.extent = sr.extent;
134453893Smckusick 
134553893Smckusick 	switch (fb->Mode) {
134653893Smckusick 
134753893Smckusick 	case MODE_1to1:
134853893Smckusick 	case MODE_Nto1:
134953893Smckusick 		/* plane mask set */
135053893Smckusick 		fb->Pmask &= 0x1;
135153893Smckusick 		break;
135253893Smckusick 
135353893Smckusick 	case MODE_1toN:
135453893Smckusick 	case MODE_NtoN:
135553893Smckusick 		break;
135653893Smckusick 
135753893Smckusick 	default:
135853893Smckusick 		return (-1);
135953893Smckusick 	}
136053893Smckusick 
136153893Smckusick 	/*
136253893Smckusick 	 * write data into ROP data register
136353893Smckusick 	 */
136453893Smckusick 
136553893Smckusick 	fbbm_rop_cinit(fb, fb->Pmask, 1);
136653893Smckusick 	fbbm_rop_clear(fb, &dr);
136753893Smckusick 
136853893Smckusick 	return (0);
136953893Smckusick }
137053893Smckusick 
137153893Smckusick #ifndef CPU_DOUBLE
137253893Smckusick /*
137353893Smckusick  * bitblt from '0' bitmap to main memory
137453893Smckusick  */
137553893Smckusick 
137653893Smckusick bitblt_0tomem(fb, sbp, srp, dbp, dpp, crp)
137753893Smckusick 	register struct fbdev *fb;
137853893Smckusick 	lBitmap *sbp;		/* source bitmap (0) */
137953893Smckusick 	lRectangle *srp;	/* source rectangle */
138053893Smckusick 	register lBitmap *dbp;	/* destination bitmap (MEM) */
138153893Smckusick 	lPoint *dpp;		/* destination point */
138253893Smckusick 	lRectangle *crp;	/* clip region in destination */
138353893Smckusick {
138453893Smckusick 	register struct fb_map *dmap;
138553893Smckusick 	register unsigned int p;
138653893Smckusick 	register int i, j;
138753893Smckusick 	register int plane;
138853893Smckusick 	lRectangle sr;
138953893Smckusick 	lRectangle dr;
139053893Smckusick 	int skip;
139153893Smckusick 
139253893Smckusick 	dmap = (struct fb_map*)dbp->base;
139353893Smckusick 
139453893Smckusick 	sr = *srp;
139553893Smckusick 	dr.origin = *dpp;
139653893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
139753893Smckusick 		return (0);
139853893Smckusick 	dr.extent = sr.extent;
139953893Smckusick 
140053893Smckusick 	dr.origin.x -= dbp->rect.origin.x;
140153893Smckusick 	dr.origin.y -= dbp->rect.origin.y;
140253893Smckusick 
140353893Smckusick 	p = dmap->fm_offset;
140453893Smckusick 
140553893Smckusick 	plane = 0x1;
140653893Smckusick 
140753893Smckusick 	switch (fb->Mode) {
140853893Smckusick 
140953893Smckusick 	case MODE_1to1:
141053893Smckusick 		if (fb->Pmask & plane)
141153893Smckusick 			mem_clear(fb->funcvec[0], dmap, p, dbp->width, &dr, 0);
141253893Smckusick 		break;
141353893Smckusick 
141453893Smckusick 	case MODE_1toN:
141553893Smckusick 	case MODE_NtoN:
141653893Smckusick 		skip = (dbp->width * dbp->rect.extent.y) << 1;
141753893Smckusick 		for (i = 0, j = dbp->depth; i < j; i++) {
141853893Smckusick 			if (fb->Pmask & plane)
141953893Smckusick 				mem_clear(fb->funcvec[i], dmap, p, dbp->width,
142053893Smckusick 				    &dr, 0);
142153893Smckusick 			/* next plane */
142253893Smckusick 			p += skip;
142353893Smckusick 			plane <<= 1;
142453893Smckusick 		}
142553893Smckusick 		break;
142653893Smckusick 
142753893Smckusick 	case MODE_Nto1:
142853893Smckusick 		for (i = 0, j = sbp->depth; i < j; i++) {
142953893Smckusick 			if (fb->Pmask & plane) {
143053893Smckusick 				mem_clear(fb->funcvec[i], dmap, p, dbp->width,
143153893Smckusick 				    &dr, 0);
143253893Smckusick 				break;
143353893Smckusick 			}
143453893Smckusick 			plane <<= 1;
143553893Smckusick 		}
143653893Smckusick 		break;
143753893Smckusick 
143853893Smckusick 	default:
143953893Smckusick 		return (1);
144053893Smckusick 	}
144153893Smckusick 
144253893Smckusick 	return (0);
144353893Smckusick }
144453893Smckusick 
144553893Smckusick /*
144653893Smckusick  * bitblt from '1' bitmap to main memory
144753893Smckusick  */
144853893Smckusick 
144953893Smckusick bitblt_1tomem(fb, sbp, srp, dbp, dpp, crp)
145053893Smckusick 	register struct fbdev *fb;
145153893Smckusick 	lBitmap *sbp;		/* source bitmap (1) */
145253893Smckusick 	lRectangle *srp;	/* source rectangle */
145353893Smckusick 	register lBitmap *dbp;	/* destination bitmap (MEM) */
145453893Smckusick 	lPoint *dpp;		/* destination point */
145553893Smckusick 	lRectangle *crp;	/* clip region in destination */
145653893Smckusick {
145753893Smckusick 	register struct fb_map *dmap;
145853893Smckusick 	register unsigned p;
145953893Smckusick 	register int i, j;
146053893Smckusick 	register int plane;
146153893Smckusick 	lRectangle sr;
146253893Smckusick 	lRectangle dr;
146353893Smckusick 	int skip;
146453893Smckusick 
146553893Smckusick 	dmap = (struct fb_map*)dbp->base;
146653893Smckusick 
146753893Smckusick 	sr = *srp;
146853893Smckusick 	dr.origin = *dpp;
146953893Smckusick 	if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp))
147053893Smckusick 		return (0);
147153893Smckusick 	dr.extent = sr.extent;
147253893Smckusick 
147353893Smckusick 	dr.origin.x -= dbp->rect.origin.x;
147453893Smckusick 	dr.origin.y -= dbp->rect.origin.y;
147553893Smckusick 
147653893Smckusick 	p = dmap->fm_offset;
147753893Smckusick 
147853893Smckusick 	plane = 0x1;
147953893Smckusick 
148053893Smckusick 	switch (fb->Mode) {
148153893Smckusick 
148253893Smckusick 	case MODE_1to1:
148353893Smckusick 		if (fb->Pmask & plane)
148453893Smckusick 			mem_clear(fb->funcvec[0], dmap, p, dbp->width, &dr, 1);
148553893Smckusick 		break;
148653893Smckusick 
148753893Smckusick 	case MODE_1toN:
148853893Smckusick 	case MODE_NtoN:
148953893Smckusick 		skip = (dbp->width * dbp->rect.extent.y) << 1;
149053893Smckusick 		for (i = 0, j = dbp->depth; i < j; i++) {
149153893Smckusick 			if (fb->Pmask & plane)
149253893Smckusick 				mem_clear(fb->funcvec[i], dmap, p, dbp->width,
149353893Smckusick 				    &dr, 1);
149453893Smckusick 			/* next plane */
149553893Smckusick 			p += skip;
149653893Smckusick 			plane <<= 1;
149753893Smckusick 		}
149853893Smckusick 		break;
149953893Smckusick 
150053893Smckusick 	case MODE_Nto1:
150153893Smckusick 		for (i = 0, j = sbp->depth; i < j; i++) {
150253893Smckusick 			if (fb->Pmask & plane) {
150353893Smckusick 				mem_clear(fb->funcvec[i], dmap, p, dbp->width,
150453893Smckusick 				    &dr, 1);
150553893Smckusick 				break;
150653893Smckusick 			}
150753893Smckusick 			plane <<= 1;
150853893Smckusick 		}
150953893Smckusick 		break;
151053893Smckusick 
151153893Smckusick 	default:
151253893Smckusick 		return (1);
151353893Smckusick 	}
151453893Smckusick 
151553893Smckusick 	return (0);
151653893Smckusick }
151753893Smckusick #endif /* !CPU_DOUBLE */
151853893Smckusick 
151953893Smckusick int
152053893Smckusick (*sel_ropfunc(stype, dtype))()
152153893Smckusick 	int stype;	/* source bitmap type */
152253893Smckusick 	int dtype;	/* dest bitmap type */
152353893Smckusick {
152453893Smckusick 	if (dtype == BM_0)
152553893Smckusick 		return (bitblt_nop);
152653893Smckusick 	if (dtype == BM_1)
152753893Smckusick 		return (bitblt_nop);
152853893Smckusick 
152953893Smckusick #ifdef CPU_DOUBLE
153053893Smckusick 	switch (stype) {
153153893Smckusick 	case BM_FB:
153253893Smckusick 		return (dtype == BM_FB) ? bitblt_fb : bitblt_tomem;
153353893Smckusick 		break;
153453893Smckusick 
153553893Smckusick 	case BM_MEM:
153653893Smckusick 		return (dtype == BM_FB) ? bitblt_tofb : bitblt_mem;
153753893Smckusick 		break;
153853893Smckusick 
153953893Smckusick 	case BM_0:
154053893Smckusick 		return (dtype == BM_FB) ? bitblt_0tofb : bitblt_nop;
154153893Smckusick 		break;
154253893Smckusick 	case BM_1:
154353893Smckusick 		return (dtype == BM_FB) ? bitblt_1tofb : bitblt_nop;
154453893Smckusick 		break;
154553893Smckusick 	}
154653893Smckusick #else /* CPU_DOUBLE */
154753893Smckusick 	switch (stype) {
154853893Smckusick 	case BM_FB:
154953893Smckusick 		return (dtype == BM_FB) ? bitblt_fb : bitblt_tomem;
155053893Smckusick 		break;
155153893Smckusick 
155253893Smckusick 	case BM_MEM:
155353893Smckusick 		return (dtype == BM_FB) ? bitblt_tofb : bitblt_mem;
155453893Smckusick 		break;
155553893Smckusick 
155653893Smckusick 	case BM_0:
155753893Smckusick 		return (dtype == BM_FB) ? bitblt_0tofb : bitblt_0tomem;
155853893Smckusick 		break;
155953893Smckusick 	case BM_1:
156053893Smckusick 		return (dtype == BM_FB) ? bitblt_1tofb : bitblt_1tomem;
156153893Smckusick 		break;
156253893Smckusick 	}
156353893Smckusick #endif /* CPU_DOUBLE */
156453893Smckusick 
156553893Smckusick 	return (bitblt_nop);
156653893Smckusick }
156753893Smckusick 
156853893Smckusick bitbltcmd(fb, cmd)
156953893Smckusick 	register struct fbdev *fb;
157053893Smckusick 	register lBitblt *cmd;
157153893Smckusick {
157253893Smckusick 	lRectangle cr;
157353893Smckusick 	int ret;
157453893Smckusick 
157553893Smckusick 	cr = cmd->destClip;
157653893Smckusick 
157753893Smckusick 	if (!getclip(fb, &cmd->destBitmap, &cr))
157853893Smckusick 		return (0);
157953893Smckusick 	if (!clipsrc(fb, &cmd->srcBitmap))
158053893Smckusick 		return (0);
158153893Smckusick 
158253893Smckusick 	if (setrop(fb, cmd->func, cmd->planemask, cmd->fore_color, cmd->aux_color,
158353893Smckusick 		cmd->transp, &cmd->srcBitmap, &cmd->destBitmap) < 0)
158453893Smckusick 		return (FB_RERROR);
158553893Smckusick 
158653893Smckusick 	cursorCheck(fb, cmd->srcBitmap.type, &cmd->srcRect,
158753893Smckusick 			cmd->destBitmap.type, &cr);
158853893Smckusick 
158953893Smckusick 	ret = (*sel_ropfunc(cmd->srcBitmap.type, cmd->destBitmap.type))
159053893Smckusick 	    (fb, &cmd->srcBitmap, &cmd->srcRect, &cmd->destBitmap, &cmd->destPoint, &cr);
159153893Smckusick 
159253893Smckusick 	cursorOn(fb);
159353893Smckusick 
159453893Smckusick 	return (FB_ROK);
159553893Smckusick }
159653893Smckusick 
159753893Smckusick static
159853893Smckusick batch_bitblt_01tofb(fb, sbp, clip, sdp, n, sw)
159953893Smckusick 	register struct fbdev *fb;
160053893Smckusick 	lBitmap *sbp;	/* source bitmap (MEM) */
160153893Smckusick 	register lRectangle *clip;
160253893Smckusick 	register lSrcDest *sdp;
160353893Smckusick 	register int n;
160453893Smckusick 	int sw;
160553893Smckusick {
160653893Smckusick 	register void (*rop_clear)();
160753893Smckusick 	lRectangle *srect = &sbp->rect;
160853893Smckusick 
160953893Smckusick 	switch (fb->Mode) {
161053893Smckusick 
161153893Smckusick 	case MODE_1to1:
161253893Smckusick 	case MODE_Nto1:
161353893Smckusick 		fb->Pmask &= 1;
161453893Smckusick 		break;
161553893Smckusick 
161653893Smckusick 	case MODE_1toN:
161753893Smckusick 	case MODE_NtoN:
161853893Smckusick 		break;
161953893Smckusick 
162053893Smckusick 	default:
162153893Smckusick 		return (FB_RERROR);
162253893Smckusick 	}
162353893Smckusick 	fbbm_rop_cinit(fb, fb->Pmask, sw);
162453893Smckusick 	rop_clear = fb->fbbm_op->fb_rop_clear;
162553893Smckusick 	while (--n >= 0) {
162653893Smckusick 		lRectangle sr;
162753893Smckusick 		lRectangle dr;
162853893Smckusick 
162953893Smckusick 		sr = sdp->srcRect;
163053893Smckusick 		dr.origin = sdp->destPoint;
163153893Smckusick 		if (cliprect2(&sr, srect, &dr, clip))
163253893Smckusick 			(*rop_clear)(fb, &dr);
163353893Smckusick 		sdp++;
163453893Smckusick 	}
163553893Smckusick 	return (FB_ROK);
163653893Smckusick }
163753893Smckusick 
163853893Smckusick static
163953893Smckusick batch_bitblt_fb(fb, sbp, clip, sdp, n)
164053893Smckusick 	register struct fbdev *fb;
164153893Smckusick 	register lBitmap *sbp;
164253893Smckusick 	register lRectangle *clip;
164353893Smckusick 	register lSrcDest *sdp;
164453893Smckusick 	register int n;
164553893Smckusick {
164653893Smckusick 	register int wplane, i, j;
164753893Smckusick 	lRectangle sr;
164853893Smckusick 	lRectangle dr;
164953893Smckusick 
165053893Smckusick 	fbbm_rop_init(fb, fb->funcvec);
165153893Smckusick 	switch (fb->Mode) {
165253893Smckusick 
165353893Smckusick 	case MODE_1to1:
165453893Smckusick 		fb->Pmask &= 1;
165553893Smckusick 		while (--n >= 0) {
165653893Smckusick 			sr = sdp->srcRect;
165753893Smckusick 			dr.origin = sdp->destPoint;
165853893Smckusick 			if (cliprect2(&sr, &sbp->rect, &dr, clip))
165953893Smckusick 				fbbm_rop_copy(fb, &sr, &dr.origin, 0, fb->Pmask);
166053893Smckusick 			sdp++;
166153893Smckusick 		}
166253893Smckusick 		break;
166353893Smckusick 
166453893Smckusick 	case MODE_NtoN:
166553893Smckusick 		while (--n >= 0) {
166653893Smckusick 			sr = sdp->srcRect;
166753893Smckusick 			dr.origin = sdp->destPoint;
166853893Smckusick 			if (cliprect2(&sr, &sbp->rect, &dr, clip))
166953893Smckusick 				fbbm_rop_copy(fb, &sr, &dr.origin, 0, fb->Pmask);
167053893Smckusick 			sdp++;
167153893Smckusick 		}
167253893Smckusick 		break;
167353893Smckusick 
167453893Smckusick 	case MODE_1toN:
167553893Smckusick 		while (--n >= 0) {
167653893Smckusick 			sr = sdp->srcRect;
167753893Smckusick 			dr.origin = sdp->destPoint;
167853893Smckusick 			if (cliprect2(&sr, &sbp->rect, &dr, clip))
167953893Smckusick 				fbbm_rop_copy(fb, &sr, &dr.origin, 1, fb->Pmask);
168053893Smckusick 			sdp++;
168153893Smckusick 		}
168253893Smckusick 		break;
168353893Smckusick 
168453893Smckusick 	case MODE_Nto1:
168553893Smckusick 		for (; --n >= 0; sdp++) {
168653893Smckusick 			sr = sdp->srcRect;
168753893Smckusick 			dr.origin = sdp->destPoint;
168853893Smckusick 			if (!cliprect2(&sr, &sbp->rect, &dr, clip))
168953893Smckusick 				continue;
169053893Smckusick 			wplane = 1;
169153893Smckusick 			for (i = 0, j = sbp->depth; i < j; i++) {
169253893Smckusick 				if (fb->Pmask & wplane) {
169353893Smckusick 					fbbm_rop_copy(fb, &sr, &dr.origin,
169453893Smckusick 							i + 1, fb->Pmask >> 16);
169553893Smckusick 					break;
169653893Smckusick 				}
169753893Smckusick 				wplane <<= 1;
169853893Smckusick 			}
169953893Smckusick 		}
170053893Smckusick 		break;
170153893Smckusick 
170253893Smckusick 	default:
170353893Smckusick 		return (FB_RERROR);
170453893Smckusick 	}
170553893Smckusick }
170653893Smckusick 
170753893Smckusick static
170853893Smckusick batch_bitblt_tofb(fb, sbp, dbp, crp, sdp, n)
170953893Smckusick 	register struct fbdev *fb;
171053893Smckusick 	register lBitmap *sbp;	/* source bitmap (MEM) */
171153893Smckusick 	lBitmap *dbp;		/* destination bitmap (FB) */
171253893Smckusick 	lRectangle *crp;	/* clip region in destination */
171353893Smckusick 	register lSrcDest *sdp;
171453893Smckusick 	register int n;
171553893Smckusick {
171653893Smckusick 	register unsigned p;
171753893Smckusick 	register struct fb_map *smap;
171853893Smckusick 	register int i, j, m;
171953893Smckusick 	lRectangle sr;
172053893Smckusick 	lRectangle dr;
172153893Smckusick 	register int wplane;
172253893Smckusick #ifdef IPC_MRX
172353893Smckusick 	extern struct fb_map rommap;
172453893Smckusick 	register int pages;
172553893Smckusick #endif
172653893Smckusick 
172753893Smckusick 	fbbm_rop_winit(fb);
172853893Smckusick 	while (--n >= 0) {
172953893Smckusick 		sr = sdp->srcRect;
173053893Smckusick 		dr.origin = sdp->destPoint;
173153893Smckusick 		if (crp && !cliprect2(&sr, &sbp->rect, &dr, crp)) {
173253893Smckusick 			sdp++;
173353893Smckusick 			continue;
173453893Smckusick 		}
173553893Smckusick 		dr.extent = sr.extent;
173653893Smckusick 
173753893Smckusick 		/* transform source rectangle */
173853893Smckusick 		sr.origin.x -= sbp->rect.origin.x;
173953893Smckusick 		sr.origin.y -= sbp->rect.origin.y;
174053893Smckusick 
174153893Smckusick 		/*
174253893Smckusick 		 * check memory map specification
174353893Smckusick 		 */
174453893Smckusick 		smap = (struct fb_map*)sbp->base;
174553893Smckusick 		p = smap->fm_offset;
174653893Smckusick #ifdef IPC_MRX
174753893Smckusick 		pages = btoc(smap->fm_offset + smap->fm_count);
174853893Smckusick 		rommap.fm_vaddr = fb_map_page(smap->fm_addr, pages,
174953893Smckusick 			    fb->cache_off ? PG_S|PG_WP|PG_CI : PG_S|PG_WP);
175053893Smckusick 		rommap.fm_offset = 0;
175153893Smckusick 		smap = &rommap;
175253893Smckusick #endif
175353893Smckusick 
175453893Smckusick 		wplane = 1;
175553893Smckusick 
175653893Smckusick 		switch (fb->Mode) {
175753893Smckusick 		case MODE_1to1:
175853893Smckusick 			fbbm_rop_write(fb, smap, p, sbp->width,
175953893Smckusick 				       &sr, &dr, fb->Pmask & 0x01);
176053893Smckusick 			break;
176153893Smckusick 		case MODE_1toN:
176253893Smckusick 			fbbm_rop_write(fb, smap, p, sbp->width,
176353893Smckusick 				       &sr, &dr, fb->Pmask);
176453893Smckusick 			break;
176553893Smckusick 		case MODE_Nto1:
176653893Smckusick 			m = sbp->width * sbp->rect.extent.y;
176753893Smckusick 			for (i = 0; i < sbp->depth; i++, wplane <<= 1) {
176853893Smckusick 				if (fb->Pmask & wplane) {
176953893Smckusick 					p += (m * i) << 1;
177053893Smckusick 					fbbm_rop_write(fb, smap, p, sbp->width,
177153893Smckusick 						       &sr, &dr, wplane);
177253893Smckusick 					break;
177353893Smckusick 				}
177453893Smckusick 				wplane <<= 1;
177553893Smckusick 			}
177653893Smckusick 			break;
177753893Smckusick 		case MODE_NtoN:
1778*55763Sbostic 			j = min(sbp->depth, fb->fbNplane);
177953893Smckusick 			m = sbp->width * sbp->rect.extent.y;
178053893Smckusick 			p += (m << 1) * j;
178153893Smckusick 			wplane = 1 << (j - 1);
178253893Smckusick 			for (i = j; i > 0; i--) {
178353893Smckusick 				/* get next plane */
178453893Smckusick 				p -= m << 1;
178553893Smckusick 				if (fb->Pmask & wplane)
178653893Smckusick 					fbbm_rop_write(fb, smap, p, sbp->width,
178753893Smckusick 						       &sr, &dr, wplane);
178853893Smckusick 				/* next plane mask */
178953893Smckusick 				wplane >>= 1;
179053893Smckusick 			}
179153893Smckusick 			break;
179253893Smckusick 		default:
179353893Smckusick 			return (-1);
179453893Smckusick 		}
179553893Smckusick 		sdp++;
179653893Smckusick 	}
179753893Smckusick 	return (0);
179853893Smckusick }
179953893Smckusick 
180053893Smckusick batchbitbltcmd(fb, cmd)
180153893Smckusick 	register struct fbdev *fb;
180253893Smckusick 	register lBatchBitblt *cmd;
180353893Smckusick {
180453893Smckusick 	register int n;
180553893Smckusick 	register lSrcDest *sdp;
180653893Smckusick 	register int (*blt)();
180753893Smckusick 	lRectangle cr;
180853893Smckusick #ifdef CPU_SINGLE
180953893Smckusick 	struct fb_map *map;
181053893Smckusick 	unsigned int p;
181153893Smckusick #endif
181253893Smckusick 	int error;
181353893Smckusick 
181453893Smckusick 	if (setrop(fb, cmd->func, cmd->planemask,
181553893Smckusick 	    cmd->fore_color, cmd->aux_color,
181653893Smckusick 	    cmd->transp, &cmd->srcBitmap, &cmd->destBitmap) < 0)
181753893Smckusick 		return (FB_RERROR);
181853893Smckusick 
181953893Smckusick 	cr = cmd->destClip;
182053893Smckusick 
182153893Smckusick 	if (!getclip(fb, &cmd->destBitmap, &cr))
182253893Smckusick 		return (FB_ROK);
182353893Smckusick 	if (!clipsrc(fb, &cmd->srcBitmap))
182453893Smckusick 		return (0);
182553893Smckusick #ifdef CPU_SINGLE
182653893Smckusick 	map = (struct fb_map *)(cmd->srcDestList);
182753893Smckusick 	p = map->fm_offset;
182853893Smckusick 	sdp = (lSrcDest *)TypeAt(map, p);
182953893Smckusick #else
183053893Smckusick 	sdp = cmd->srcDestList;
183153893Smckusick #endif
183253893Smckusick 	n = cmd->nSrcDest;
183353893Smckusick 
183453893Smckusick 	cursorCheck(fb, cmd->srcBitmap.type, &cmd->srcBitmap.rect,
183553893Smckusick 	    cmd->destBitmap.type, &cr);
183653893Smckusick 
183753893Smckusick 	blt = sel_ropfunc(cmd->srcBitmap.type, cmd->destBitmap.type);
183853893Smckusick 	if (blt == bitblt_0tofb || blt == bitblt_1tofb) {
183953893Smckusick 		if (error =
184053893Smckusick 		    batch_bitblt_01tofb(fb, &cmd->srcBitmap, &cr, sdp, n,
184153893Smckusick 		    blt == bitblt_1tofb)) {
184253893Smckusick 			cursorOn(fb);
184353893Smckusick 			return (error);
184453893Smckusick 		}
184553893Smckusick 	} else if (blt == bitblt_fb) {
184653893Smckusick 		if (error =
184753893Smckusick 		    batch_bitblt_fb(fb, &cmd->srcBitmap, &cr, sdp, n)) {
184853893Smckusick 			cursorOn(fb);
184953893Smckusick 			return (error);
185053893Smckusick 		}
185153893Smckusick 	} else if (blt == bitblt_tofb) {
185253893Smckusick 		if (error =
185353893Smckusick 		    batch_bitblt_tofb(fb, &cmd->srcBitmap, &cmd->destBitmap,
185453893Smckusick 		    &cr, sdp, n)) {
185553893Smckusick 			cursorOn(fb);
185653893Smckusick 			return (error);
185753893Smckusick 		}
185853893Smckusick 	} else
185953893Smckusick 		while (--n >= 0) {
186053893Smckusick 			if ((*blt)(fb, &cmd->srcBitmap, &sdp->srcRect,
186153893Smckusick 			    &cmd->destBitmap, &sdp->destPoint, &cr) < 0) {
186253893Smckusick 				cursorOn(fb);
186353893Smckusick 				return (FB_RERROR);
186453893Smckusick 			}
186553893Smckusick 			PRE_EMPT;
186653893Smckusick 			sdp++;
186753893Smckusick 		}
186853893Smckusick 	cursorOn(fb);
186953893Smckusick 	return (FB_ROK);
187053893Smckusick }
187153893Smckusick 
187253893Smckusick tilebitbltcmd(fb, cmd)
187353893Smckusick 	struct fbdev *fb;
187453893Smckusick 	register lTileBitblt *cmd;
187553893Smckusick {
187653893Smckusick 	lRectangle trect, rect, prect;
187753893Smckusick 	lPoint dp;
187853893Smckusick 	register int dx;
187953893Smckusick 	int dy;
188053893Smckusick 	register int offx, offy;
188153893Smckusick 	register int xlen, ylen;
188253893Smckusick 	int first;
188353893Smckusick 	register int (*blt)();
188453893Smckusick 	int t;
188553893Smckusick 
188653893Smckusick 	rect = cmd->destRect;
188753893Smckusick 	prect = cmd->ptnRect;
188853893Smckusick 
188953893Smckusick 	if (prect.extent.x <= 0 || prect.extent.y <= 0)
189053893Smckusick 		return;
189153893Smckusick 
189253893Smckusick 	if (cmd->ptnBitmap.type == BM_FB &&
189353893Smckusick 		!cliprect(&cmd->ptnBitmap.rect, &fb->FrameRect, (lRectangle*)0))
189453893Smckusick 		return;
189553893Smckusick 
189653893Smckusick 	/* clip pattern rectangle */
189753893Smckusick 	if (!cliprect(&prect, &cmd->ptnBitmap.rect, (lRectangle *)0))
189853893Smckusick 		return;
189953893Smckusick 
190053893Smckusick 	if (!getclip(fb, &cmd->destBitmap, &cmd->destClip)) return;
190153893Smckusick 
190253893Smckusick 	if (!cliprect(&rect, &cmd->destClip, (lRectangle *)0))
190353893Smckusick 		return;
190453893Smckusick 
190553893Smckusick 	if (setrop(fb, cmd->func, cmd->planemask, cmd->fore_color, cmd->aux_color,
190653893Smckusick 		cmd->transp, &cmd->ptnBitmap, &cmd->destBitmap) < 0)
190753893Smckusick 		return (FB_RERROR);
190853893Smckusick 
190953893Smckusick 	blt = sel_ropfunc(cmd->ptnBitmap.type, cmd->destBitmap.type);
191053893Smckusick 
191153893Smckusick 	offx = MOD(rect.origin.x - cmd->refPoint.x, prect.extent.x, t);
191253893Smckusick 	offy = MOD(rect.origin.y - cmd->refPoint.y, prect.extent.y, t);
191353893Smckusick 
191453893Smckusick 	dp = rect.origin;
191553893Smckusick 
191653893Smckusick 	trect.origin.x = prect.origin.x + offx;
191753893Smckusick 	trect.origin.y = prect.origin.y + offy;
191853893Smckusick 
191953893Smckusick 	dy = rect.extent.y;
192053893Smckusick 
192153893Smckusick 	cursorCheck(fb, cmd->ptnBitmap.type, &prect, cmd->destBitmap.type, &rect);
192253893Smckusick 
192353893Smckusick 	first = 1;
192453893Smckusick 	while (dy > 0) {
192553893Smckusick 		if (first) {	/* for the first time */
192653893Smckusick 			ylen = prect.extent.y - offy;
1927*55763Sbostic 			ylen = min(ylen, dy);
192853893Smckusick 			trect.extent.y = ylen;
192953893Smckusick 			trect.origin.y = prect.origin.y + offy;
193053893Smckusick 			first = 0;
193153893Smckusick 		} else {
1932*55763Sbostic 			ylen = min(prect.extent.y, dy);
193353893Smckusick 			trect.extent.y = ylen;
193453893Smckusick 			trect.origin.y = prect.origin.y;
193553893Smckusick 		}
193653893Smckusick 
193753893Smckusick 		dp.x = rect.origin.x;
193853893Smckusick 		dx = rect.extent.x;
193953893Smckusick 		xlen = prect.extent.x - offx;
194053893Smckusick 		trect.origin.x = prect.origin.x + offx;
194153893Smckusick 
194253893Smckusick 		if (dx < xlen) {
194353893Smckusick 			trect.extent.x = dx;
194453893Smckusick 			(*blt)(fb, &cmd->ptnBitmap, &trect, &cmd->destBitmap, &dp, (lRectangle *)0);
194553893Smckusick 		} else {
194653893Smckusick 			trect.extent.x = xlen;
194753893Smckusick 			(*blt)(fb, &cmd->ptnBitmap, &trect, &cmd->destBitmap, &dp, (lRectangle *)0);
194853893Smckusick 			dp.x += xlen;
194953893Smckusick 			dx -= xlen;
195053893Smckusick 			trect.origin.x = prect.origin.x;
195153893Smckusick 			while (dx > 0) {
1952*55763Sbostic 				xlen = min(dx, prect.extent.x);
195353893Smckusick 				trect.extent.x = xlen;
195453893Smckusick 				(*blt)(fb, &cmd->ptnBitmap, &trect, &cmd->destBitmap, &dp, (lRectangle *)0);
195553893Smckusick 				dp.x += xlen;
195653893Smckusick 				dx -= xlen;
195753893Smckusick 			}
195853893Smckusick 		}
195953893Smckusick 
196053893Smckusick 		dp.y += ylen;
196153893Smckusick 		dy -= ylen;
196253893Smckusick 	}
196353893Smckusick 
196453893Smckusick 	cursorOn(fb);
196553893Smckusick }
196653893Smckusick 
196753893Smckusick bitblt3cmd(fb, cmd)
196853893Smckusick 	struct fbdev fb;
196953893Smckusick 	lBitblt3 *cmd;
197053893Smckusick {
197153893Smckusick 	return (FB_ROK);
197253893Smckusick }
197353893Smckusick 
197453893Smckusick draw_rectangle(fb, dp)
197553893Smckusick 	struct fbdev *fb;
197653893Smckusick 	lPrimRect *dp;
197753893Smckusick {
197853893Smckusick 	lRectangle trect, rect, prect;
197953893Smckusick 	lPoint p;
198053893Smckusick 	register int dx;
198153893Smckusick 	int dy;
198253893Smckusick 	register int offx, offy;
198353893Smckusick 	register int xlen, ylen;
198453893Smckusick 	int first;
198553893Smckusick 	register int (*blt)();
198653893Smckusick 	int t;
198753893Smckusick 
198853893Smckusick 	rect = dp->rect;
198953893Smckusick 	prect = dp->ptnRect;
199053893Smckusick 
199153893Smckusick 	if (prect.extent.x <= 0 || prect.extent.y <= 0)
199253893Smckusick 		return;
199353893Smckusick 
199453893Smckusick 	if (dp->ptnBM.type == BM_FB &&
199553893Smckusick 		!cliprect(&dp->ptnBM.rect, &fb->FrameRect, (lRectangle*)0))
199653893Smckusick 		return;
199753893Smckusick 
199853893Smckusick 	/* clip pattern rectangle */
199953893Smckusick 	if (!cliprect(&prect, &dp->ptnBM.rect, (lRectangle *)0))
200053893Smckusick 		return;
200153893Smckusick 
200253893Smckusick 	if (!getclip(fb, &dp->drawBM, &dp->clip)) return;
200353893Smckusick 
200453893Smckusick 	if (!cliprect(&rect, &dp->clip, (lRectangle *)0))
200553893Smckusick 		return;
200653893Smckusick 
200753893Smckusick 	if (setrop(fb, dp->func, dp->planemask, dp->fore_color, dp->aux_color,
200853893Smckusick 			dp->transp, &dp->ptnBM, &dp->drawBM) < 0)
200953893Smckusick 		return (FB_RERROR);
201053893Smckusick 
201153893Smckusick 	blt = sel_ropfunc(dp->ptnBM.type, dp->drawBM.type);
201253893Smckusick 
201353893Smckusick 	offx = MOD(rect.origin.x - dp->refPoint.x, prect.extent.x, t);
201453893Smckusick 	offy = MOD(rect.origin.y - dp->refPoint.y, prect.extent.y, t);
201553893Smckusick 
201653893Smckusick 	p = rect.origin;
201753893Smckusick 
201853893Smckusick 	trect.origin.x = prect.origin.x + offx;
201953893Smckusick 	trect.origin.y = prect.origin.y + offy;
202053893Smckusick 
202153893Smckusick 	dy = rect.extent.y;
202253893Smckusick 
202353893Smckusick 	cursorCheck(fb, dp->ptnBM.type, &prect, dp->drawBM.type, &rect);
202453893Smckusick 
202553893Smckusick 	first = 1;
202653893Smckusick 	while (dy > 0) {
202753893Smckusick 		if (first) {	/* for the first time */
202853893Smckusick 			ylen = prect.extent.y - offy;
2029*55763Sbostic 			ylen = min(ylen, dy);
203053893Smckusick 			trect.extent.y = ylen;
203153893Smckusick 			trect.origin.y = prect.origin.y + offy;
203253893Smckusick 			first = 0;
203353893Smckusick 		} else {
2034*55763Sbostic 			ylen = min(prect.extent.y, dy);
203553893Smckusick 			trect.extent.y = ylen;
203653893Smckusick 			trect.origin.y = prect.origin.y;
203753893Smckusick 		}
203853893Smckusick 
203953893Smckusick 		p.x = rect.origin.x;
204053893Smckusick 		dx = rect.extent.x;
204153893Smckusick 		xlen = prect.extent.x - offx;
204253893Smckusick 		trect.origin.x = prect.origin.x + offx;
204353893Smckusick 
204453893Smckusick 		if (dx < xlen) {
204553893Smckusick 			trect.extent.x = dx;
204653893Smckusick 			(*blt)(fb, &dp->ptnBM, &trect, &dp->drawBM, &p, (lRectangle *)0);
204753893Smckusick 		} else {
204853893Smckusick 			trect.extent.x = xlen;
204953893Smckusick 			(*blt)(fb, &dp->ptnBM, &trect, &dp->drawBM, &p, (lRectangle *)0);
205053893Smckusick 			p.x += xlen;
205153893Smckusick 			dx -= xlen;
205253893Smckusick 			trect.origin.x = prect.origin.x;
205353893Smckusick 			while (dx > 0) {
2054*55763Sbostic 				xlen = min(dx, prect.extent.x);
205553893Smckusick 				trect.extent.x = xlen;
205653893Smckusick 				(*blt)(fb, &dp->ptnBM, &trect, &dp->drawBM, &p, (lRectangle *)0);
205753893Smckusick 				p.x += xlen;
205853893Smckusick 				dx -= xlen;
205953893Smckusick 			}
206053893Smckusick 		}
206153893Smckusick 
206253893Smckusick 		p.y += ylen;
206353893Smckusick 		dy -= ylen;
206453893Smckusick 	}
206553893Smckusick 
206653893Smckusick 	cursorOn(fb);
206753893Smckusick }
206853893Smckusick 
206953893Smckusick draw_polymarker(fb, dp)
207053893Smckusick 	struct fbdev *fb;
207153893Smckusick 	register lPrimMarker *dp;
207253893Smckusick {
207353893Smckusick 	register lPoint *ps;
207453893Smckusick 	register int np;
207553893Smckusick 	lRectangle cr;
207653893Smckusick 	register int (*blt)();
207753893Smckusick #ifdef CPU_SINGLE
207853893Smckusick 	struct fb_map *map;
207953893Smckusick 	unsigned int p;
208053893Smckusick #endif
208153893Smckusick 
208253893Smckusick 	cr = dp->clip;
208353893Smckusick 
208453893Smckusick 	if ((dp->drawBM.type == BM_FB) &&
208553893Smckusick 			!getclip(fb, &dp->drawBM, &cr))
208653893Smckusick 		return (FB_ROK);
208753893Smckusick 
208853893Smckusick 	if (dp->ptnBM.type == BM_FB &&
208953893Smckusick 		!cliprect(&dp->ptnBM.rect, &fb->FrameRect, (lRectangle*)0))
209053893Smckusick 		return (FB_ROK);
209153893Smckusick 
209253893Smckusick 	if (setrop(fb, dp->func, dp->planemask, dp->fore_color, dp->aux_color,
209353893Smckusick 			dp->transp, &dp->ptnBM, &dp->drawBM) < 0)
209453893Smckusick 		return (FB_RERROR);
209553893Smckusick 
209653893Smckusick 	blt = sel_ropfunc(dp->ptnBM.type, dp->drawBM.type);
209753893Smckusick 
209853893Smckusick 	cursorCheck(fb, dp->ptnBM.type, &(dp->ptnRect), dp->drawBM.type, &cr);
209953893Smckusick 
210053893Smckusick #ifdef CPU_SINGLE
210153893Smckusick 	map = (struct fb_map *)(dp->plist);
210253893Smckusick 	p = map->fm_offset;
210353893Smckusick 	ps = (lPoint *)TypeAt(map, p);
210453893Smckusick #else
210553893Smckusick 	ps = dp->plist;
210653893Smckusick #endif
210753893Smckusick 	np = dp->np;
210853893Smckusick 	while (--np >= 0) {
210953893Smckusick 		(*blt)(fb, &dp->ptnBM, &dp->ptnRect, &dp->drawBM, ps++, &cr);
211053893Smckusick 		PRE_EMPT;
211153893Smckusick 	}
211253893Smckusick 
211353893Smckusick 	cursorOn(fb);
211453893Smckusick 
211553893Smckusick 	return (FB_ROK);
211653893Smckusick }
211753893Smckusick 
211853893Smckusick static int patternx;
211953893Smckusick static int patterny;
212053893Smckusick static int patternwidth;
212153893Smckusick static lBitmap *pbm;		/* pattern bitmap */
212253893Smckusick static lBitmap *drawbm;		/* drawing bitmap */
212353893Smckusick static int (*blt)();
212453893Smckusick 
212553893Smckusick static
212653893Smckusick fill_line(fb, len, dp, offx, offy)
212753893Smckusick register struct fbdev *fb;
212853893Smckusick register int len;
212953893Smckusick register lPoint *dp;
213053893Smckusick int offx, offy;
213153893Smckusick {
213253893Smckusick 	register int plen;
213353893Smckusick 	static lRectangle srec = { 0, 0, 0, 1 };
213453893Smckusick 
213553893Smckusick 	srec.origin.x = patternx + offx;
213653893Smckusick 	srec.origin.y = patterny + offy;
213753893Smckusick 
213853893Smckusick 	if ((plen = patternwidth - offx) > len) {
213953893Smckusick 		srec.extent.x = len;
214053893Smckusick 		(*blt)(fb, pbm, &srec, drawbm, dp, (lRectangle *)0);
214153893Smckusick 		return;
214253893Smckusick 	}
214353893Smckusick 
214453893Smckusick 	srec.extent.x = plen;
214553893Smckusick 	(*blt)(fb, pbm, &srec, drawbm, dp, (lRectangle *)0);
214653893Smckusick 	dp->x += plen;
214753893Smckusick 	len -= plen;
214853893Smckusick 	srec.origin.x = patternx;
214953893Smckusick 	plen = patternwidth;
215053893Smckusick 
215153893Smckusick 	while (len > 0) {
2152*55763Sbostic 		srec.extent.x = min(plen, len);
215353893Smckusick 		(*blt)(fb, pbm, &srec, drawbm, dp, (lRectangle *)0);
215453893Smckusick 		dp->x += plen;
215553893Smckusick 		len -= plen;
215653893Smckusick 	}
215753893Smckusick }
215853893Smckusick 
215953893Smckusick fill_scan(fb, fdata)
216053893Smckusick 	register struct fbdev *fb;
216153893Smckusick 	register lPrimFill *fdata;
216253893Smckusick {
216353893Smckusick 	register lScanl	*ls;
216453893Smckusick 	int nscan;
216553893Smckusick 	lRectangle clip;
216653893Smckusick 	lRectangle prect;
216753893Smckusick 	register int minx, maxx, miny, maxy;
216853893Smckusick #ifdef CPU_SINGLE
216953893Smckusick 	struct fb_map *map;
217053893Smckusick #endif
217153893Smckusick 	register void (*rop_clear)();
217253893Smckusick 	int (*sel_ropfunc())();
217353893Smckusick 
217453893Smckusick 	if ((nscan = fdata->nscan) <= 0)
217553893Smckusick 		return (FB_RERROR);
217653893Smckusick 
217753893Smckusick 	/* clip pattern rectangle */
217853893Smckusick 	prect = fdata->ptnRect;
217953893Smckusick 	if (!getclip(fb, &fdata->ptnBM, &prect))
218053893Smckusick 		return (0);
218153893Smckusick 
218253893Smckusick 	if (prect.extent.x <= 0 || prect.extent.y <= 0)
218353893Smckusick 		return (FB_RERROR);
218453893Smckusick 
218553893Smckusick 	/* clip clip rectangle */
218653893Smckusick 	clip = fdata->clip;
218753893Smckusick 	if (!getclip(fb, &fdata->drawBM, &clip))
218853893Smckusick 		return (0);
218953893Smckusick 
219053893Smckusick 	if (setrop(fb, fdata->func, fdata->planemask,
219153893Smckusick 	    fdata->fore_color, fdata->aux_color, fdata->transp,
219253893Smckusick 	    &fdata->ptnBM, &fdata->drawBM) < 0)
219353893Smckusick 		return (FB_RERROR);
219453893Smckusick 
219553893Smckusick #ifdef CPU_SINGLE
219653893Smckusick 	map = (struct fb_map *)(fdata->scan);
219753893Smckusick 	ls = (lScanl *)TypeAt(map, map->fm_offset);
219853893Smckusick #else
219953893Smckusick 	ls = fdata->scan;
220053893Smckusick #endif
220153893Smckusick 
220253893Smckusick 	minx = clip.origin.x;
220353893Smckusick 	maxx = minx + clip.extent.x - 1;
220453893Smckusick 	miny = clip.origin.y;
220553893Smckusick 	maxy = miny + clip.extent.y - 1;
220653893Smckusick 
220753893Smckusick 	cursorCheck(fb, fdata->ptnBM.type, &prect, fdata->drawBM.type, &clip);
220853893Smckusick 
220953893Smckusick 	blt = sel_ropfunc(fdata->ptnBM.type, fdata->drawBM.type);
221053893Smckusick 	if (blt == bitblt_1tofb || blt == bitblt_0tofb) {
221153893Smckusick 		lRectangle dr;
221253893Smckusick 
221353893Smckusick 		if (fb->fbbm_op->fb_rop_fillscan != (void (*)())nofunc) {
221453893Smckusick 			fbbm_rop_fillscan(fb, ls, nscan, &clip,
221553893Smckusick 			    blt == bitblt_1tofb);
221653893Smckusick 			goto out;
221753893Smckusick 		}
221853893Smckusick 		dr.extent.y = 1;
221953893Smckusick 		fbbm_rop_cinit(fb, fb->Pmask, blt == bitblt_1tofb);
222053893Smckusick 		rop_clear = fb->fbbm_op->fb_rop_clear;
222153893Smckusick 		while (--nscan >= 0) {
222253893Smckusick 			if ((dr.origin.y = ls->y) >= miny &&
222353893Smckusick 			    dr.origin.y <= maxy) {
2224*55763Sbostic 				dr.origin.x = max(ls->x0, minx);
222553893Smckusick 				if ((dr.extent.x =
2226*55763Sbostic 				    min(ls->x1, maxx) - dr.origin.x + 1) > 0)
222753893Smckusick 					(*rop_clear)(fb, &dr);
222853893Smckusick 			}
222953893Smckusick 			ls++;
223053893Smckusick 		}
223153893Smckusick 	} else {
223253893Smckusick 		int len;
223353893Smckusick 		int refx, refy;
223453893Smckusick 		lPoint dp;
223553893Smckusick 		int sizex, sizey;
223653893Smckusick 		int t;
223753893Smckusick 
223853893Smckusick 		sizex = prect.extent.x;
223953893Smckusick 		sizey = prect.extent.y;
224053893Smckusick 		refx = fdata->refPoint.x;
224153893Smckusick 		refy = fdata->refPoint.y;
224253893Smckusick 
224353893Smckusick 		patternx = prect.origin.x;
224453893Smckusick 		patterny = prect.origin.y;
224553893Smckusick 		patternwidth = sizex;
224653893Smckusick 
224753893Smckusick 		pbm = &fdata->ptnBM;
224853893Smckusick 		drawbm = &fdata->drawBM;
224953893Smckusick 
225053893Smckusick 		while (--nscan >= 0) {
225153893Smckusick 			if ((dp.y = ls->y) >= miny && dp.y <= maxy) {
2252*55763Sbostic 				dp.x = max(ls->x0, minx);
2253*55763Sbostic 				if ((len = min(ls->x1, maxx) - dp.x + 1) > 0)
225453893Smckusick 					fill_line(fb, len, &dp,
225553893Smckusick 					    MOD((dp.x - refx), sizex, t),
225653893Smckusick 					    MOD((dp.y - refy), sizey, t));
225753893Smckusick 			}
225853893Smckusick 			ls++;
225953893Smckusick 		}
226053893Smckusick 	}
226153893Smckusick out:
226253893Smckusick 	cursorOn(fb);
226353893Smckusick 	return (FB_ROK);
226453893Smckusick }
226553893Smckusick 
226653893Smckusick put_string(fb, sdata)
226753893Smckusick 	struct fbdev *fb;
226853893Smckusick 	lPrimText *sdata;
226953893Smckusick {
227053893Smckusick 	register int x, y;
227153893Smckusick 	register int ex_factor = sdata->ex_factor;
227253893Smckusick 	register unsigned c;
227353893Smckusick 	register unsigned char *str;
227453893Smckusick 	int len = sdata->len;
227553893Smckusick 	int flen;
227653893Smckusick 	int i, j, k, l;
227753893Smckusick 	unsigned fchar = sdata->first_chr;
227853893Smckusick 	unsigned lchar = sdata->last_chr;
227953893Smckusick 	lRectangle cr, save;
228053893Smckusick 	register int (*bltfunc)();
228153893Smckusick 	register char *f_addr;		/* font address */
228253893Smckusick 	register char **fnt_addr;
228353893Smckusick 	static struct fb_map rommap;
228453893Smckusick #ifdef CPU_SINGLE
228553893Smckusick 	struct fb_map *map;
228653893Smckusick 	unsigned int p;
228753893Smckusick #endif
228853893Smckusick 
228953893Smckusick 	lBitmap *fontBM;
229053893Smckusick 	lRectangle srec;
229153893Smckusick 	lPoint dp;
229253893Smckusick 
229353893Smckusick 	extern int tmode;	/* in ../bm/vt100if.c */
229453893Smckusick 
229553893Smckusick 	x = sdata->p.x << 16;
229653893Smckusick 	y = sdata->p.y << 16;
229753893Smckusick 
229853893Smckusick 	srec.extent.x = sdata->width;
229953893Smckusick 	srec.extent.y = sdata->height;
230053893Smckusick 
230153893Smckusick 	switch (sdata->type) {
230253893Smckusick 
230353893Smckusick 	case ASCII:
230453893Smckusick 		fontBM = &sdata->fontBM;
230553893Smckusick 
230653893Smckusick 		break;
230753893Smckusick 
230853893Smckusick 	case ROM_ASCII:
230953893Smckusick 	case ROM_CONS:
231053893Smckusick 		if (sdata->width >= 12 && sdata->height >= 24) {
231153893Smckusick 			if (fb->Krom_BM1.type == (char)0xff) {
231253893Smckusick 				fontBM = &fb->Krom_BM0;
231353893Smckusick 				srec.extent.x = fb->Krom_font_extent0.x>>1;
231453893Smckusick 				srec.extent.y = fb->Krom_font_extent0.y;
231553893Smckusick 				fnt_addr = ext_fnt_addr;
231653893Smckusick 			} else {
231753893Smckusick 				fontBM = &fb->Krom_BM1;
231853893Smckusick 				srec.extent.x = fb->Krom_font_extent1.x>>1;
231953893Smckusick 				srec.extent.y = fb->Krom_font_extent1.y;
232053893Smckusick 				fnt_addr = ext_fnt24_addr;
232153893Smckusick 			}
232253893Smckusick 		} else {
232353893Smckusick 			if (fb->Krom_BM0.type == (char)0xff) {
232453893Smckusick 				fontBM = &fb->Krom_BM1;
232553893Smckusick 				srec.extent.x = fb->Krom_font_extent1.x>>1;
232653893Smckusick 				srec.extent.y = fb->Krom_font_extent1.y;
232753893Smckusick 				fnt_addr = ext_fnt24_addr;
232853893Smckusick 			} else {
232953893Smckusick 				fontBM = &fb->Krom_BM0;
233053893Smckusick 				srec.extent.x = fb->Krom_font_extent0.x>>1;
233153893Smckusick 				srec.extent.y = fb->Krom_font_extent0.y;
233253893Smckusick 				fnt_addr = ext_fnt_addr;
233353893Smckusick 			}
233453893Smckusick 		}
233553893Smckusick 
233653893Smckusick 		if (srec.extent.x > sdata->width)
233753893Smckusick 			srec.extent.x = sdata->width;
233853893Smckusick 		if (srec.extent.y > sdata->height)
233953893Smckusick 			srec.extent.y = sdata->height;
234053893Smckusick 		flen = (fontBM->width<<1) * fontBM->rect.extent.y;
234153893Smckusick 		fontBM->base = (Word *)&rommap;
234253893Smckusick 		break;
234353893Smckusick 
234453893Smckusick 	case ROM_KANJI:
234553893Smckusick 		if (sdata->width >= 24 && sdata->height >= 24) {
234653893Smckusick 			if (fb->Krom_BM1.type == (char)0xff) {
234753893Smckusick 				fontBM = &fb->Krom_BM0;
234853893Smckusick 				srec.extent = fb->Krom_font_extent0;
234953893Smckusick 				fnt_addr = ext_fnt_addr;
235053893Smckusick 			} else {
235153893Smckusick 				fontBM = &fb->Krom_BM1;
235253893Smckusick 				srec.extent = fb->Krom_font_extent1;
235353893Smckusick 				fnt_addr = ext_fnt24_addr;
235453893Smckusick 			}
235553893Smckusick 		} else {
235653893Smckusick 			if (fb->Krom_BM0.type == (char)0xff) {
235753893Smckusick 				fontBM = &fb->Krom_BM1;
235853893Smckusick 				srec.extent = fb->Krom_font_extent1;
235953893Smckusick 				fnt_addr = ext_fnt24_addr;
236053893Smckusick 			} else {
236153893Smckusick 				fontBM = &fb->Krom_BM0;
236253893Smckusick 				srec.extent = fb->Krom_font_extent0;
236353893Smckusick 				fnt_addr = ext_fnt_addr;
236453893Smckusick 			}
236553893Smckusick 		}
236653893Smckusick 
236753893Smckusick 		if (srec.extent.x > sdata->width)
236853893Smckusick 			srec.extent.x = sdata->width;
236953893Smckusick 		if (srec.extent.y > sdata->height)
237053893Smckusick 			srec.extent.y = sdata->height;
237153893Smckusick 		save.extent.x = srec.extent.x;
237253893Smckusick 		flen = (fontBM->width<<1) * fontBM->rect.extent.y;
237353893Smckusick 		fontBM->base = (Word *)&rommap;
237453893Smckusick 		break;
237553893Smckusick 
237653893Smckusick 	default:
237753893Smckusick 		return (FB_RERROR);
237853893Smckusick 	}
237953893Smckusick 
238053893Smckusick 	/* get clipping rectangle */
238153893Smckusick 	cr = sdata->clip;
238253893Smckusick 
238353893Smckusick 	if (!getclip(fb, &sdata->drawBM, &cr))
238453893Smckusick 		return (FB_ROK);
238553893Smckusick 
238653893Smckusick 	/* set rop code */
238753893Smckusick 	if (setrop(fb, sdata->func, sdata->planemask,
238853893Smckusick 			sdata->fore_color, sdata->aux_color,
238953893Smckusick 			sdata->transp, fontBM, &sdata->drawBM) < 0)
239053893Smckusick 		return (FB_RERROR);
239153893Smckusick 
239253893Smckusick 	/* select rop function */
239353893Smckusick 	bltfunc = sel_ropfunc(fontBM->type, sdata->drawBM.type);
239453893Smckusick 
239553893Smckusick #ifdef CPU_SINGLE
239653893Smckusick 	map = (struct fb_map *)(sdata->str);
239753893Smckusick 	p = map->fm_offset;
239853893Smckusick 	str = (unsigned char *)TypeAt(map, p);
239953893Smckusick #else
240053893Smckusick 	str = sdata->str;
240153893Smckusick #endif
240253893Smckusick 
240353893Smckusick 	cursorCheck(fb, fontBM->type, &fontBM->rect, sdata->drawBM.type, &cr);
240453893Smckusick 
240553893Smckusick 	switch (sdata->type) {
240653893Smckusick 
240753893Smckusick 	case ASCII:
240853893Smckusick 		if (sdata->column == 0)
240953893Smckusick 			return (FB_RERROR);
241053893Smckusick 		while (len-- > 0) {
241153893Smckusick 			c = *str++;
241253893Smckusick 
241353893Smckusick 			if (c < fchar || c > lchar)
241453893Smckusick 				continue;
241553893Smckusick 
241653893Smckusick 			c -= fchar;
241753893Smckusick 			srec.origin.x = sdata->fp.x
241853893Smckusick 				+ sdata->width * (c % sdata->column);
241953893Smckusick 			srec.origin.y = sdata->fp.y
242053893Smckusick 				+ sdata->height * (c / sdata->column);
242153893Smckusick 			dp.x = x >> 16;
242253893Smckusick 			dp.y = y >> 16;
242353893Smckusick 
242453893Smckusick 			if (ex_factor == 1) {
242553893Smckusick 				(*bltfunc)(fb, fontBM, &srec, &sdata->drawBM,
242653893Smckusick 					&dp, &cr);
242753893Smckusick 			} else {
242853893Smckusick 				srec.extent.x = 1;
242953893Smckusick 
243053893Smckusick 				for (i = 0; i < sdata->width; i++) {
243153893Smckusick 					for (j = 0; j < ex_factor; j++) {
243253893Smckusick 						(*bltfunc)(fb, fontBM, &srec,
243353893Smckusick 							&sdata->drawBM,
243453893Smckusick 							&dp, &cr);
243553893Smckusick 						dp.x++;
243653893Smckusick 						PRE_EMPT;
243753893Smckusick 					}
243853893Smckusick 					srec.origin.x++;
243953893Smckusick 				}
244053893Smckusick 			}
244153893Smckusick 			x += sdata->dx;
244253893Smckusick 			y += sdata->dy;
244353893Smckusick 		}
244453893Smckusick 		break;
244553893Smckusick 
244653893Smckusick 	case ROM_ASCII:
244753893Smckusick 	case ROM_CONS:
244853893Smckusick #ifdef IPC_MRX
244953893Smckusick 		if (fb->type == FB_NWB251)
245053893Smckusick 			fb->cache_off = 1;
245153893Smckusick #endif
245253893Smckusick 		while (len-- > 0) {
245353893Smckusick 			c = *str++;
245453893Smckusick 			dp.x = x >> 16;
245553893Smckusick 			dp.y = y >> 16;
245653893Smckusick 			k = 0;
245753893Smckusick 			srec.origin.x = srec.origin.y = 0;
245853893Smckusick 
245953893Smckusick 			f_addr = 0;
246053893Smckusick 
246153893Smckusick 			if ((c >= 0x20) && (c <= 0x7e)) {
246253893Smckusick 				/*
246353893Smckusick 				 * ASCII char
246453893Smckusick 				 */
246553893Smckusick 				f_addr = fnt_addr[c];
246653893Smckusick 				goto disp;
246753893Smckusick 			}
246853893Smckusick 
246953893Smckusick 			if (sdata->type == ROM_ASCII) {
247053893Smckusick 				if ((c >= 0xa1) && (c <= 0xdf)) {
247153893Smckusick 					/*
247253893Smckusick 					 * KANA char
247353893Smckusick 					 */
247453893Smckusick 					f_addr = fnt_addr[c + 64];
247553893Smckusick 					goto disp;
247653893Smckusick 				}
247753893Smckusick 			}
247853893Smckusick 
247953893Smckusick 			if (sdata->type == ROM_CONS) {
248053893Smckusick #ifdef KM_ASCII
248153893Smckusick 				if (tmode == KM_ASCII) {
248253893Smckusick #endif
248353893Smckusick 					if ((c >= 0xa0) && (c <= 0xff)) {
248453893Smckusick 						/*
248553893Smckusick 						 * ISO char
248653893Smckusick 						 */
248753893Smckusick 						f_addr = fnt_addr[c - 32];
248853893Smckusick 						goto disp;
248953893Smckusick 					}
249053893Smckusick #ifdef KM_ASCII
249153893Smckusick 				} else {
249253893Smckusick 					if ((c >= 0xa1) && (c <= 0xdf)) {
249353893Smckusick 						/*
249453893Smckusick 						 * KANA char
249553893Smckusick 						 */
249653893Smckusick 						f_addr = fnt_addr[c + 64];
249753893Smckusick 						goto disp;
249853893Smckusick 					}
249953893Smckusick 				}
250053893Smckusick #endif
250153893Smckusick 			}
250253893Smckusick 
250353893Smckusick disp:
250453893Smckusick 
250553893Smckusick 			if (f_addr) {
250653893Smckusick 				/*
250753893Smckusick 				 * not ROM font
250853893Smckusick 				 *	(font is in kernel data area)
250953893Smckusick 				 */
251053893Smckusick 				bltfunc = sel_ropfunc(BM_MEM,
251153893Smckusick 						sdata->drawBM.type);
251253893Smckusick 				rommap.fm_vaddr = f_addr;
251353893Smckusick 				rommap.fm_offset = 0;
251453893Smckusick #ifdef IPC_MRX
251553893Smckusick 				iopmemfbmap(f_addr, flen, &rommap);
251653893Smckusick #endif
251753893Smckusick 				k = 1;
251853893Smckusick 				l = fontBM->width;
251953893Smckusick 				fontBM->width = 1;
252053893Smckusick 				save = fontBM->rect;
252153893Smckusick 				fontBM->rect.origin = srec.origin;
252253893Smckusick 				fontBM->rect.extent.x = 12;
252353893Smckusick 			} else if (fontBM->type == BM_MEM) {
252453893Smckusick 				/*
252553893Smckusick 				 * KANJI ROM except pop[cm]fb
252653893Smckusick 				 */
252753893Smckusick 				f_addr = fbbm_Krom_addr(fb, c, &srec);
252853893Smckusick 				rommap.fm_vaddr = f_addr;
252953893Smckusick 				rommap.fm_offset = 0;
253053893Smckusick #ifdef IPC_MRX
253153893Smckusick 				iopmemfbmap(f_addr, flen, &rommap);
253253893Smckusick #endif
253353893Smckusick 			} else {
253453893Smckusick 				/*
253553893Smckusick 				 * XXX
253653893Smckusick 				 * fontBM->type == BM_FB -> fbbm_pop[cm]
253753893Smckusick 				 *
253853893Smckusick 				 * see fbpop[cm]_setup() routine
253953893Smckusick 				 * in fbbm_pop[cm].c
254053893Smckusick 				 */
254153893Smckusick 				bltfunc = sel_ropfunc(fontBM->type,
254253893Smckusick 							sdata->drawBM.type);
254353893Smckusick 
254453893Smckusick 				bzero((caddr_t)fontBM->base,
254553893Smckusick 						sizeof (struct fb_map));
254653893Smckusick 				fbbm_Krom_addr(fb, c, &srec);
254753893Smckusick 				fontBM->rect.origin = srec.origin;
254853893Smckusick 			}
254953893Smckusick 
255053893Smckusick 			if (ex_factor == 1) {
255153893Smckusick 				(*bltfunc)(fb, fontBM, &srec, &sdata->drawBM,
255253893Smckusick 					&dp, &cr);
255353893Smckusick 			} else {
255453893Smckusick 				srec.extent.x = 1;
255553893Smckusick 
255653893Smckusick 				for (i = 0; i < sdata->width; i++) {
255753893Smckusick 
255853893Smckusick 					for (j = 0; j < ex_factor; j++) {
255953893Smckusick 						(*bltfunc)(fb, fontBM, &srec,
256053893Smckusick 							&sdata->drawBM,
256153893Smckusick 							&dp, &cr);
256253893Smckusick 						dp.x++;
256353893Smckusick 					}
256453893Smckusick 					srec.origin.x++;
256553893Smckusick 				}
256653893Smckusick 			}
256753893Smckusick 			PRE_EMPT;
256853893Smckusick 			if (k != 0) {
256953893Smckusick 				fontBM->rect = save;
257053893Smckusick 				fontBM->width = l;
257153893Smckusick 			}
257253893Smckusick 			x += sdata->dx;
257353893Smckusick 			y += sdata->dy;
257453893Smckusick 		}
257553893Smckusick #ifdef IPC_MRX
257653893Smckusick 		fb->cache_off = 0;
257753893Smckusick #endif
257853893Smckusick 
257953893Smckusick 		break;
258053893Smckusick 
258153893Smckusick 	case ROM_KANJI:
258253893Smckusick #ifdef IPC_MRX
258353893Smckusick 		if (fb->type == FB_NWB251)
258453893Smckusick 			fb->cache_off = 1;
258553893Smckusick #endif
258653893Smckusick 		while (len > 1) {
258753893Smckusick 			c = *str++;
258853893Smckusick 			c <<= 8;
258953893Smckusick 			c |= *str++;
259053893Smckusick 			dp.x = x >> 16;
259153893Smckusick 			dp.y = y >> 16;
259253893Smckusick 			srec.origin.x = srec.origin.y = 0;
259353893Smckusick 
259453893Smckusick 			if (fontBM->type == BM_MEM) {
259553893Smckusick 				/*
259653893Smckusick 				 * KANJI ROM except pop[cm]fb
259753893Smckusick 				 */
259853893Smckusick 				f_addr = fbbm_Krom_addr(fb, c, &srec);
259953893Smckusick 				rommap.fm_vaddr = f_addr;
260053893Smckusick 				rommap.fm_offset = 0;
260153893Smckusick #ifdef IPC_MRX
260253893Smckusick 				iopmemfbmap(f_addr, flen, &rommap);
260353893Smckusick #endif
260453893Smckusick 			} else {
260553893Smckusick 				/*
260653893Smckusick 				 * XXX
260753893Smckusick 				 * fontBM->type == BM_FB ---> fbbm_pop[cm]
260853893Smckusick 				 *
260953893Smckusick 				 * see fbpop[cm]_setup() in fbbm_pop[cm].c
261053893Smckusick 				 */
261153893Smckusick 				bzero((caddr_t)fontBM->base,
261253893Smckusick 						sizeof (struct fb_map));
261353893Smckusick 				fbbm_Krom_addr(fb, c, &srec);
261453893Smckusick 				fontBM->rect.origin = srec.origin;
261553893Smckusick 			}
261653893Smckusick 
261753893Smckusick 			if (ex_factor == 1) {
261853893Smckusick 				(*bltfunc)(fb, fontBM, &srec, &sdata->drawBM,
261953893Smckusick 					&dp, &cr);
262053893Smckusick 			} else {
262153893Smckusick 				srec.extent.x = 1;
262253893Smckusick 				for (i = 0; i < sdata->width; i++) {
262353893Smckusick 					for (j = 0; j < ex_factor; j++) {
262453893Smckusick 						(*bltfunc)(fb, fontBM, &srec,
262553893Smckusick 							&sdata->drawBM,
262653893Smckusick 							&dp, &cr);
262753893Smckusick 						dp.x++;
262853893Smckusick 					}
262953893Smckusick 					srec.origin.x++;
263053893Smckusick 				}
263153893Smckusick 				srec.extent.x = save.extent.x;
263253893Smckusick 			}
263353893Smckusick 			PRE_EMPT;
263453893Smckusick 			x += sdata->dx;
263553893Smckusick 			y += sdata->dy;
263653893Smckusick 			len -= 2;
263753893Smckusick 		}
263853893Smckusick #ifdef IPC_MRX
263953893Smckusick 		fb->cache_off = 0;
264053893Smckusick #endif
264153893Smckusick 		break;
264253893Smckusick 
264353893Smckusick 	default:
264453893Smckusick 		cursorOn(fb);
264553893Smckusick 		return (FB_RERROR);
264653893Smckusick 	}
264753893Smckusick 
264853893Smckusick 	cursorOn(fb);
264953893Smckusick 
265053893Smckusick 	return (FB_ROK);
265153893Smckusick }
265253893Smckusick 
265353893Smckusick void
265453893Smckusick linerop(fb, func, fore, aux, trans)
265553893Smckusick 	struct fbdev	*fb;
265653893Smckusick 	register unsigned func;
265753893Smckusick 	register int fore;
265853893Smckusick 	register int aux;
265953893Smckusick 	int trans;
266053893Smckusick {
266153893Smckusick 	register char *funcv;
266253893Smckusick 	register int i;
266353893Smckusick 	char tmp[4];
266453893Smckusick 
266553893Smckusick 	/* set rop function register */
266653893Smckusick 	func &= 0xf;
266753893Smckusick 	tmp[0] = TRANS(trans, (func & 0x0c) | (func >> 2));
266853893Smckusick 	tmp[1] = TRANS(trans, (func >> 2) | ((func << 2) & 0x0c));
266953893Smckusick 	tmp[2] = TRANS(trans, func);
267053893Smckusick 	tmp[3] = TRANS(trans, (func << 2) & 0x0c | func & 3);
267153893Smckusick 
267253893Smckusick 	funcv = fb->funcvec;
267353893Smckusick 	for (i = fb->fbNplane; --i >= 0;) {
267453893Smckusick 		*funcv++ = tmp[((fore & 1) << 1) | (aux & 1)];
267553893Smckusick 		fore >>= 1; aux >>= 1;
267653893Smckusick 	}
267753893Smckusick }
267853893Smckusick 
267953893Smckusick /*
268053893Smckusick  * line clipping routine
268153893Smckusick  *
268253893Smckusick  *	DRAW	visual
268353893Smckusick  *	NODRAW	not visual
268453893Smckusick  */
268553893Smckusick lineclip(p0, p1, r)
268653893Smckusick 	register lPoint *p0;
268753893Smckusick 	register lPoint *p1;
268853893Smckusick 	register lRectangle *r;		/* clipping rectangle */
268953893Smckusick {
269053893Smckusick 	register lPoint *ptmp;
269153893Smckusick 	register int d0, d1, d2, limit;
269253893Smckusick 
269353893Smckusick 	/* sort 2 points by x-coordinate */
269453893Smckusick 	if (p0->x > p1->x) {
269553893Smckusick 		ptmp = p1;
269653893Smckusick 		p1 = p0;
269753893Smckusick 		p0 = ptmp;
269853893Smckusick 	}
269953893Smckusick 	limit = r->origin.x;
270053893Smckusick 	d0 = p1->y - p0->y;
270153893Smckusick 	d1 = p1->x - p0->x;
270253893Smckusick 	if ((d2 = limit - p0->x) > 0) {
270353893Smckusick 		if (p1->x < limit)
270453893Smckusick 			return (NODRAW);
270553893Smckusick 		p0->y += d2 * d0 / d1;
270653893Smckusick 		p0->x = limit;
270753893Smckusick 	}
270853893Smckusick 	limit += r->extent.x - 1;
270953893Smckusick 	if ((d2 = limit - p1->x) < 0) {
271053893Smckusick 		if (p0->x > limit)
271153893Smckusick 			return (NODRAW);
271253893Smckusick 		p1->y += d2 * d0 / d1;
271353893Smckusick 		p1->x = limit;
271453893Smckusick 	}
271553893Smckusick 
271653893Smckusick 	/* sort 2 points by y-coordinate */
271753893Smckusick 	if (p0->y > p1->y) {
271853893Smckusick 		ptmp = p1;
271953893Smckusick 		p1 = p0;
272053893Smckusick 		p0 = ptmp;
272153893Smckusick 	}
272253893Smckusick 	limit = r->origin.y;
272353893Smckusick 	d0 = p1->x - p0->x;
272453893Smckusick 	d1 = p1->y - p0->y;
272553893Smckusick 	if ((d2 = limit - p0->y) > 0) {
272653893Smckusick 		if (p1->y < limit)
272753893Smckusick 			return (NODRAW);
272853893Smckusick 		p0->x += d2 * d0 / d1;
272953893Smckusick 		p0->y = limit;
273053893Smckusick 	}
273153893Smckusick 	limit += r->extent.y - 1;
273253893Smckusick 	if ((d2 = limit - p1->y) < 0) {
273353893Smckusick 		if (p0->y > limit)
273453893Smckusick 			return (NODRAW);
273553893Smckusick 		p1->x += d2 * d0 / d1;
273653893Smckusick 		p1->y = limit;
273753893Smckusick 	}
273853893Smckusick 	return (DRAW);
273953893Smckusick }
274053893Smckusick 
274153893Smckusick #ifndef CPU_DOUBLE
274253893Smckusick /*
274353893Smckusick void
274453893Smckusick point(p, x, s, fp)
274553893Smckusick 	register char *p;
274653893Smckusick 	register int x;
274753893Smckusick 	register int s;
274853893Smckusick 	register char *fp;
274953893Smckusick {
275053893Smckusick 	x = 7 - (x & 7);
275153893Smckusick 	if ((1 << (3 - (((s & 1) << 1) | ((*p >> x) & 1)))) & *fp)
275253893Smckusick 		*p |= (1 << x);
275353893Smckusick 	else
275453893Smckusick 		*p &= ~(1 << x);
275553893Smckusick }
275653893Smckusick */
275753893Smckusick #define point(p, x, s, fp) { \
275853893Smckusick 	int xx = 7 - ((x) & 7); \
275953893Smckusick 	if ((1 << (3 - ((((s) & 1) << 1) | ((*(p) >> xx) & 1)))) & *(fp)) \
276053893Smckusick 		*(p) |= (1 << xx); \
276153893Smckusick 	else \
276253893Smckusick 		*(p) &= ~(1 << xx); \
276353893Smckusick }
276453893Smckusick 
276553893Smckusick mem_vector(fb, p0, p1, mask, dbmp, lpf)
276653893Smckusick 	struct fbdev	*fb;
276753893Smckusick 	lPoint *p0, *p1;
276853893Smckusick 	int mask;		/* plane mask */
276953893Smckusick 	lBitmap *dbmp;		/* drawing bitmap */
277053893Smckusick 	int lpf;		/* if 0, don't draw last point */
277153893Smckusick {
277253893Smckusick 	register struct fb_map *map = (struct fb_map *)dbmp->base;
277353893Smckusick 	register char *funcv = fb->funcvec;		/* rop function */
277453893Smckusick 	int p = (int)map->fm_offset;
277553893Smckusick 	register int pmask;
277653893Smckusick 	register unsigned int pat;
277753893Smckusick 	register int x = p0->x;
277853893Smckusick 	register int y = p0->y;
277953893Smckusick 	register char *fp;
278053893Smckusick 	int width = dbmp->width << 1;
278153893Smckusick 	int lim;
278253893Smckusick 	int size = width * dbmp->rect.extent.y;
278353893Smckusick 	int ddx, ddy;
278453893Smckusick 	int s, d, c;
278553893Smckusick 	int dx = p1->x - x;
278653893Smckusick 	int dy = p1->y - y;
278753893Smckusick 	int i, j;
278853893Smckusick 	int depth = dbmp->depth;
278953893Smckusick 
279053893Smckusick 	/* transformation */
279153893Smckusick 	x -= dbmp->rect.origin.x;
279253893Smckusick 	y -= dbmp->rect.origin.y;
279353893Smckusick 
279453893Smckusick 	pat = fb->pat;
279553893Smckusick 
279653893Smckusick 	ddx = 1;
279753893Smckusick 	ddy = dbmp->width << 1;
279853893Smckusick 	y = (int)p + y * ddy;
279953893Smckusick 
280053893Smckusick 	if (dx == 0)
280153893Smckusick 		ddx = 0;
280253893Smckusick 	else if (dx < 0) {
280353893Smckusick 		dx = -dx;
280453893Smckusick 		ddx = -ddx;
280553893Smckusick 	}
280653893Smckusick 
280753893Smckusick 	if (dy == 0)
280853893Smckusick 		ddy = 0;
280953893Smckusick 	else if (dy < 0) {
281053893Smckusick 		dy = -dy;
281153893Smckusick 		ddy = -ddy;
281253893Smckusick 	}
281353893Smckusick 
281453893Smckusick 	if (dx > dy) {	/* case x */
281553893Smckusick 		lim = dx;
281653893Smckusick 		if (lpf)
281753893Smckusick 			lim++;
281853893Smckusick 
281953893Smckusick 		s = -dx;
282053893Smckusick 		d = dx << 1;
282153893Smckusick 		c = dy << 1;
282253893Smckusick 
282353893Smckusick 		for (i = lim; i > 0; i--) {
282453893Smckusick 			(int)p = y + (x >> 3);
282553893Smckusick 
282653893Smckusick 			pat = (pat << 1) | ((pat & 0x80000000) ? 1: 0);
282753893Smckusick 
282853893Smckusick 			fp = funcv;
282953893Smckusick 			pmask = mask;
283053893Smckusick 
283153893Smckusick 			for (j = depth; j > 0; j--) {
283253893Smckusick 				if (pmask & 1) {
283353893Smckusick 					point(_TypeAt(map, p), x, pat, fp);
283453893Smckusick 				}
283553893Smckusick 
283653893Smckusick 				p += size;
283753893Smckusick 				pmask >>= 1;
283853893Smckusick 				fp++;
283953893Smckusick 			}
284053893Smckusick 
284153893Smckusick 			if ((s += c) >= 0) {
284253893Smckusick 				s -= d;
284353893Smckusick 				y += ddy;
284453893Smckusick 			}
284553893Smckusick 
284653893Smckusick 			x += ddx;
284753893Smckusick 		}
284853893Smckusick 	} else {			/* case y */
284953893Smckusick 		lim = dy;
285053893Smckusick 		if (lpf)
285153893Smckusick 			lim++;
285253893Smckusick 		s = -dy;
285353893Smckusick 		d = dy << 1;
285453893Smckusick 		c = dx << 1;
285553893Smckusick 
285653893Smckusick 		for (i = lim; i > 0; i--) {
285753893Smckusick 			(int)p = y + (x >> 3);
285853893Smckusick 			pat = (pat << 1) | ((pat & 0x80000000) ? 1: 0);
285953893Smckusick 
286053893Smckusick 			fp = funcv;
286153893Smckusick 			pmask = mask;
286253893Smckusick 
286353893Smckusick 			for (j = depth; j > 0; j--) {
286453893Smckusick 				if (pmask & 1) {
286553893Smckusick 					point(_TypeAt(map, p), x, pat, fp);
286653893Smckusick 				}
286753893Smckusick 
286853893Smckusick 				p += size;
286953893Smckusick 				pmask >>= 1;
287053893Smckusick 				fp++;
287153893Smckusick 			}
287253893Smckusick 
287353893Smckusick 			if ((s += c) >= 0) {
287453893Smckusick 				s -= d;
287553893Smckusick 				x += ddx;
287653893Smckusick 			}
287753893Smckusick 
287853893Smckusick 			y += ddy;
287953893Smckusick 		}
288053893Smckusick 	}
288153893Smckusick 
288253893Smckusick 	/* rotate pattern */
288353893Smckusick 	pat = fb->pat;
288453893Smckusick 
288553893Smckusick 	{
288653893Smckusick 		register int tmp;
288753893Smckusick 
288853893Smckusick 		tmp = lim & 31;
288953893Smckusick 		pat = (pat << tmp) | (pat >> (32 - tmp));
289053893Smckusick 	}
289153893Smckusick 
289253893Smckusick 	fb->pat = pat;
289353893Smckusick }
289453893Smckusick #endif /* !CPU_DOUBLE */
289553893Smckusick 
289653893Smckusick /* polyline drawing */
289753893Smckusick draw_polyline(fb, dp)
289853893Smckusick 	struct fbdev *fb;
289953893Smckusick 	register lPrimLine *dp;
290053893Smckusick {
290153893Smckusick 	register lPoint *ps;
290253893Smckusick 	lPoint p0, p1;
290353893Smckusick 	register int np;
290453893Smckusick 	lRectangle clip, *clipp;
290553893Smckusick #ifdef CPU_SINGLE
290653893Smckusick 	struct fb_map *map;
290753893Smckusick 	unsigned int p;
290853893Smckusick #endif
290953893Smckusick 
291053893Smckusick 	/* clip rectangle */
291153893Smckusick 	clip = dp->clip;
291253893Smckusick 
291353893Smckusick 	if (clip.origin.x == -1)
291453893Smckusick 		clipp = 0;
291553893Smckusick 	else {
291653893Smckusick 		clipp = &clip;
291753893Smckusick 		if (!getclip(fb, &dp->drawBM, clipp)) return 0;
291853893Smckusick 	}
291953893Smckusick #ifdef CPU_SINGLE
292053893Smckusick 	map = (struct fb_map *)(dp->plist);
292153893Smckusick 	p = map->fm_offset;
292253893Smckusick 	ps = (lPoint *)TypeAt(map, p);
292353893Smckusick #else
292453893Smckusick 	ps = dp->plist;
292553893Smckusick #endif
292653893Smckusick 	if (dp->drawBM.type == BM_FB) {
292753893Smckusick 
292853893Smckusick 		cursorCheck(fb, ~BM_FB, 0, dp->drawBM.type, clipp);
292953893Smckusick 		fbbm_rop_vect(fb, clipp, dp->func, dp->fore_color,
293053893Smckusick 				dp->aux_color, dp->transp, dp->planemask,
293153893Smckusick 				dp->np, ps, dp->lptn, (dp->dlpf)?1:0, 1);
293253893Smckusick 		cursorOn(fb);
293353893Smckusick 
293453893Smckusick 		return(FB_ROK);
293553893Smckusick 	}
293653893Smckusick #ifndef CPU_DOUBLE
293753893Smckusick 	linerop(fb, dp->func, dp->fore_color, dp->aux_color, dp->transp);
293853893Smckusick 	p0 = *ps++;
293953893Smckusick 	np = dp->np - 1;
294053893Smckusick 	fb->pat = dp->lptn;
294153893Smckusick 	if (clipp) {
294253893Smckusick 		while (--np > 0) {
294353893Smckusick 			p1 = *ps;
294453893Smckusick 			if (lineclip(&p0, &p1, clipp)) {
294553893Smckusick 				mem_vector(fb, &p0, &p1,
294653893Smckusick 					dp->planemask, &dp->drawBM,
294753893Smckusick 					ps->x != p1.x || ps->y != p1.y);
294853893Smckusick 				PRE_EMPT;
294953893Smckusick 			}
295053893Smckusick 			p0 = *ps++;
295153893Smckusick 		}
295253893Smckusick 		p1 = *ps;
295353893Smckusick 		if (lineclip(&p0, &p1, clipp)) {
295453893Smckusick 			mem_vector(fb, &p0, &p1, dp->planemask, &dp->drawBM,
295553893Smckusick 				ps->x != p1.x || ps->y != p1.y || dp->dlpf);
295653893Smckusick 		}
295753893Smckusick 	} else {
295853893Smckusick 		while (--np > 0) {
295953893Smckusick 			p1 = *ps;
296053893Smckusick 			mem_vector(fb, &p0, &p1, dp->planemask, &dp->drawBM, 0);
296153893Smckusick 			PRE_EMPT;
296253893Smckusick 			p0 = *ps++;
296353893Smckusick 		}
296453893Smckusick 		p1 = *ps;
296553893Smckusick 		mem_vector(fb, &p0, &p1, dp->planemask, &dp->drawBM, dp->dlpf);
296653893Smckusick 	}
296753893Smckusick #endif /* !CPU_DOUBLE */
296853893Smckusick 	return (FB_ROK);
296953893Smckusick }
297053893Smckusick 
297153893Smckusick /* disjoint polyline drawing */
297253893Smckusick 
297353893Smckusick draw_dj_polyline(fb, dp)
297453893Smckusick 	struct fbdev *fb;
297553893Smckusick 	register lPrimLine *dp;
297653893Smckusick {
297753893Smckusick 	register lPoint *ps;
297853893Smckusick 	lPoint p0, p1;
297953893Smckusick 	register int np;
298053893Smckusick 	lRectangle clip, *clipp;
298153893Smckusick #ifdef CPU_SINGLE
298253893Smckusick 	struct fb_map *map;
298353893Smckusick 	unsigned int p;
298453893Smckusick #endif
298553893Smckusick 
298653893Smckusick 	int lpf = (dp->dlpf)?1:0;
298753893Smckusick 
298853893Smckusick 	/* clip rectangle */
298953893Smckusick 	clip = dp->clip;
299053893Smckusick 
299153893Smckusick 	if (clip.origin.x == -1)
299253893Smckusick 		clipp = 0;
299353893Smckusick 	else {
299453893Smckusick 		clipp = &clip;
299553893Smckusick 		if(!getclip(fb, &dp->drawBM, clipp)) return (0);
299653893Smckusick 	}
299753893Smckusick #ifdef CPU_SINGLE
299853893Smckusick 	map = (struct fb_map *)(dp->plist);
299953893Smckusick 	p = map->fm_offset;
300053893Smckusick 	ps = (lPoint *)TypeAt(map, p);
300153893Smckusick #else
300253893Smckusick 	ps = dp->plist;
300353893Smckusick #endif
300453893Smckusick 	if (dp->drawBM.type == BM_FB) {
300553893Smckusick 
300653893Smckusick 		cursorCheck(fb, ~BM_FB, 0, dp->drawBM.type, clipp);
300753893Smckusick 		fbbm_rop_vect(fb, clipp, dp->func, dp->fore_color,
300853893Smckusick 				dp->aux_color, dp->transp, dp->planemask,
300953893Smckusick 						dp->np, ps, dp->lptn, lpf, 0);
301053893Smckusick 		cursorOn(fb);
301153893Smckusick 		PRE_EMPT;
301253893Smckusick 
301353893Smckusick 		return (FB_ROK);
301453893Smckusick 	}
301553893Smckusick #ifndef CPU_DOUBLE
301653893Smckusick 	linerop(fb, dp->func, dp->fore_color, dp->aux_color, dp->transp);
301753893Smckusick 	np = dp->np >> 1;
301853893Smckusick 	if (lpf) {
301953893Smckusick 		if (clipp) {
302053893Smckusick 			while (--np >= 0) {
302153893Smckusick 				p0 = *ps++;
302253893Smckusick 				p1 = *ps++;
302353893Smckusick 				fb->pat = dp->lptn;
302453893Smckusick 				if (lineclip(&p0, &p1, clipp)) {
302553893Smckusick 					mem_vector(fb, &p0, &p1,
302653893Smckusick 						dp->planemask, &dp->drawBM, 1);
302753893Smckusick 					PRE_EMPT;
302853893Smckusick 				}
302953893Smckusick 			}
303053893Smckusick 		} else {
303153893Smckusick 			while (--np >= 0) {
303253893Smckusick 				p0 = *ps++;
303353893Smckusick 				p1 = *ps++;
303453893Smckusick 				fb->pat = dp->lptn;
303553893Smckusick 				mem_vector(fb, &p0, &p1,
303653893Smckusick 					dp->planemask, &dp->drawBM, 1);
303753893Smckusick 				PRE_EMPT;
303853893Smckusick 			}
303953893Smckusick 		}
304053893Smckusick 	} else {
304153893Smckusick 		if (clipp) {
304253893Smckusick 			while (--np >= 0) {
304353893Smckusick 				p0 = *ps++;
304453893Smckusick 				p1 = *ps;
304553893Smckusick 				fb->pat = dp->lptn;
304653893Smckusick 				if (lineclip(&p0, &p1, clipp)) {
304753893Smckusick 					mem_vector(fb, &p0, &p1,
304853893Smckusick 						dp->planemask, &dp->drawBM,
304953893Smckusick 						ps->x != p1.x || ps->y != p1.y);
305053893Smckusick 					PRE_EMPT;
305153893Smckusick 				}
305253893Smckusick 				ps++;
305353893Smckusick 			}
305453893Smckusick 		} else {
305553893Smckusick 			while (--np >= 0) {
305653893Smckusick 				p0 = *ps++;
305753893Smckusick 				p1 = *ps++;
305853893Smckusick 				fb->pat = dp->lptn;
305953893Smckusick 				mem_vector(fb, &p0, &p1,
306053893Smckusick 					dp->planemask, &dp->drawBM, 0);
306153893Smckusick 				PRE_EMPT;
306253893Smckusick 			}
306353893Smckusick 		}
306453893Smckusick 	}
306553893Smckusick #endif /* !CPU_DOUBLE */
306653893Smckusick 	return (FB_ROK);
306753893Smckusick }
306853893Smckusick 
306953893Smckusick static lRectangle	dotRect = {{ 0, 0 }, { 1, 1 }};
307053893Smckusick 
307153893Smckusick emulate_polydot(fb, dp)
307253893Smckusick 	struct fbdev *fb;
307353893Smckusick 	register lPrimDot *dp;
307453893Smckusick {
307553893Smckusick 	lPrimMarker marker;
307653893Smckusick 	lPrimMarker *cmdp;
307753893Smckusick 	register lPoint *ps;
307853893Smckusick 	register int np;
307953893Smckusick 	lRectangle cr;
308053893Smckusick 	register int (*blt)();
308153893Smckusick #ifdef CPU_SINGLE
308253893Smckusick 	struct fb_map *map;
308353893Smckusick 	unsigned int p;
308453893Smckusick #endif
308553893Smckusick 
308653893Smckusick 	cmdp = &marker;
308753893Smckusick 
308853893Smckusick 	cmdp->func = dp->func;
308953893Smckusick         cmdp->transp = dp->transp;
309053893Smckusick         cmdp->fore_color = dp->fore_color;
309153893Smckusick         cmdp->aux_color = dp->aux_color;
309253893Smckusick         cmdp->planemask = dp->planemask;
309353893Smckusick         cmdp->ptnRect = dotRect;
309453893Smckusick         cmdp->ptnBM.type = BM_1;
309553893Smckusick         cmdp->ptnBM.depth = 1;
309653893Smckusick         cmdp->ptnBM.rect = dotRect;
309753893Smckusick         cmdp->drawBM = dp->drawBM;
309853893Smckusick         cmdp->clip = dp->clip;
309953893Smckusick         cmdp->np = dp->np;
310053893Smckusick         cmdp->plist = dp->plist;
310153893Smckusick 
310253893Smckusick 	return (draw_polymarker(fb, cmdp));
310353893Smckusick }
310453893Smckusick 
310553893Smckusick #ifndef CPU_DOUBLE
310653893Smckusick mem_dot(fb, p0, mask, dbmp)
310753893Smckusick 	struct fbdev	*fb;
310853893Smckusick 	lPoint		*p0;
310953893Smckusick 	register int	mask;		/* plane mask */
311053893Smckusick 	lBitmap		*dbmp;		/* drawing bitmap */
311153893Smckusick {
311253893Smckusick 	register struct fb_map *map = (struct fb_map *)dbmp->base;
311353893Smckusick 	register char *funcv;	/* rop function */
311453893Smckusick 	register int p = (int)map->fm_offset;
311553893Smckusick 	register int depth;
311653893Smckusick 	int size;
311753893Smckusick 	int x, y;
311853893Smckusick 
311953893Smckusick 	x = p0->x - dbmp->rect.origin.x;
312053893Smckusick 	y = p0->y - dbmp->rect.origin.y;
312153893Smckusick 
312253893Smckusick 	size = (dbmp->width * dbmp->rect.extent.y) << 1;
312353893Smckusick 
312453893Smckusick 	p += y * (dbmp->width << 1) + (x >> 3);
312553893Smckusick 
312653893Smckusick 	funcv = fb->funcvec;
312753893Smckusick 	for (depth = dbmp->depth; --depth >= 0;) {
312853893Smckusick 		if (mask & 1) {
312953893Smckusick 			point(_TypeAt(map, p), x, ~0, funcv);
313053893Smckusick 		}
313153893Smckusick 		p += size;
313253893Smckusick 		mask >>= 1;
313353893Smckusick 		funcv++;
313453893Smckusick 	}
313553893Smckusick }
313653893Smckusick #endif /* !CPU_DOUBLE */
313753893Smckusick 
313853893Smckusick draw_polydot(fb, dp)
313953893Smckusick 	struct fbdev *fb;
314053893Smckusick 	register lPrimDot *dp;
314153893Smckusick {
314253893Smckusick 	register lPoint *ps;
314353893Smckusick 	lRectangle clip, *clipp;
314453893Smckusick 	register int np;
314553893Smckusick #ifdef CPU_SINGLE
314653893Smckusick 	struct fb_map *map;
314753893Smckusick 	unsigned int p;
314853893Smckusick #endif
314953893Smckusick 
315053893Smckusick 	if (fb->fbbm_op->fb_rop_dot == (void (*)())nofunc)
315153893Smckusick 		return (emulate_polydot(fb, dp));
315253893Smckusick 
315353893Smckusick 	/* clip rectangle */
315453893Smckusick 	clip = dp->clip;
315553893Smckusick 
315653893Smckusick 	if (clip.origin.x == -1)
315753893Smckusick 		clipp = 0;
315853893Smckusick 	else {
315953893Smckusick 		clipp = &clip;
316053893Smckusick 		if (!getclip(fb, &dp->drawBM, clipp)) return 0;
316153893Smckusick 	}
316253893Smckusick 
316353893Smckusick #ifdef CPU_SINGLE
316453893Smckusick 	map = (struct fb_map *)(dp->plist);
316553893Smckusick 	p = map->fm_offset;
316653893Smckusick 	ps = (lPoint *)TypeAt(map, p);
316753893Smckusick #else
316853893Smckusick 	ps = dp->plist;
316953893Smckusick #endif
317053893Smckusick 
317153893Smckusick 	if (dp->drawBM.type == BM_FB) {
317253893Smckusick 		cursorCheck(fb, ~BM_FB, 0, dp->drawBM.type, clipp);
317353893Smckusick 		fbbm_rop_dot(fb, clipp, dp->func, dp->fore_color,
317453893Smckusick 				dp->aux_color, dp->transp, dp->planemask,
317553893Smckusick 				dp->np, ps);
317653893Smckusick 		cursorOn(fb);
317753893Smckusick 
317853893Smckusick 		return(FB_ROK);
317953893Smckusick 	}
318053893Smckusick #ifndef CPU_DOUBLE
318153893Smckusick 	linerop(fb, dp->func, dp->fore_color, dp->aux_color, dp->transp);
318253893Smckusick 
318353893Smckusick 	np = dp->np;
318453893Smckusick 	if (clipp) {
318553893Smckusick 		register int x0, y0, x1, y1;
318653893Smckusick 
318753893Smckusick 		x0 = clipp->origin.x;
318853893Smckusick 		y0 = clipp->origin.y;
318953893Smckusick 		x1 = x0 + clipp->extent.x - 1;
319053893Smckusick 		y1 = y0 + clipp->extent.y - 1;
319153893Smckusick 		if (x1 <= 0 || y1 <= 0) return;
319253893Smckusick 
319353893Smckusick 		while (--np >= 0) {
319453893Smckusick 			if ((ps->x >= x0) && (ps->y >= y0) &&
319553893Smckusick 			    (ps->x <= x1) && (ps->y <= y1)) {
319653893Smckusick 				mem_dot(fb, ps, dp->planemask, &dp->drawBM);
319753893Smckusick 				PRE_EMPT;
319853893Smckusick 			}
319953893Smckusick 			ps++;
320053893Smckusick 		}
320153893Smckusick 	} else {
320253893Smckusick 		while (--np >= 0) {
320353893Smckusick 			mem_dot(fb, ps, dp->planemask, &dp->drawBM);
320453893Smckusick 			PRE_EMPT;
320553893Smckusick 			ps++;
320653893Smckusick 		}
320753893Smckusick 	}
320853893Smckusick #endif /* !CPU_DOUBLE */
320953893Smckusick 	return (FB_ROK);
321053893Smckusick }
321153893Smckusick 
321253893Smckusick get_scrtype(fb, cmd)
321353893Smckusick 	register struct fbdev *fb;
321453893Smckusick 	register lScrType *cmd;
321553893Smckusick {
321653893Smckusick 	cmd->colorwidth = fb->Colorwidth;
321753893Smckusick 	cmd->plane = fb->fbNplane;
321853893Smckusick 	cmd->bufferrect = fb->FrameRect;
321953893Smckusick 	cmd->visiblerect = fb->VisRect;
322053893Smckusick 	cmd->type = fb->type;
322153893Smckusick 	cmd->unit = fb->unit;
322253893Smckusick 
322353893Smckusick 	return FB_ROK;
322453893Smckusick }
322553893Smckusick 
322653893Smckusick fbstart(fbaddr, dummy)
322753893Smckusick 	register struct fbreg *fbaddr;
322853893Smckusick 	int dummy;
322953893Smckusick {
323053893Smckusick 	register struct fbdev *fb = &fbdev[fbaddr->fb_device];
323153893Smckusick 	register int s;
323253893Smckusick 
323353893Smckusick 	FB_LOCK;
323453893Smckusick 
323553893Smckusick 	if (!fb) {
323653893Smckusick 		return (FB_RERROR);
323753893Smckusick 	}
323853893Smckusick 
323953893Smckusick 	/* reset dimmer count */
324053893Smckusick 	rst_dimmer_cnt();
324153893Smckusick 
324253893Smckusick 	switch(fbaddr->fb_command) {
324353893Smckusick 	case FB_CPROBE:
324453893Smckusick 		fbaddr->fb_data = search_fbdev(fbaddr->fb_device,
324553893Smckusick 						fbaddr->fb_unit);
324653893Smckusick 		fbaddr->fb_result = FB_ROK;
324753893Smckusick 		break;
324853893Smckusick 	case FB_CATTACH:
324953893Smckusick 		fbaddr->fb_result = get_scrtype(fb, &fbaddr->fb_scrtype);
325053893Smckusick 		break;
325153893Smckusick 	case FB_COPEN:
325253893Smckusick 		fbaddr->fb_result = fbbm_open(fb);
325353893Smckusick 		break;
325453893Smckusick 	case FB_CCLOSE:
325553893Smckusick 		fbaddr->fb_result = fbbm_close(fb);
325653893Smckusick 		break;
325753893Smckusick 	case FB_CSETDIM:
325853893Smckusick 		fbaddr->fb_result = fbbm_set_dimmer(fb, fbaddr->fb_data);
325953893Smckusick 		break;
326053893Smckusick 	case FB_CGETDIM:
326153893Smckusick 		if ((fbaddr->fb_data = fbbm_get_dimmer(fb)) == FB_RERROR)
326253893Smckusick 			fbaddr->fb_result = FB_RERROR;
326353893Smckusick 		else
326453893Smckusick 			fbaddr->fb_result = FB_ROK;
326553893Smckusick 		break;
326653893Smckusick 	case FB_CBITBLT:
326753893Smckusick 		fbaddr->fb_result = bitbltcmd(fb, &fbaddr->fb_bitblt);
326853893Smckusick 		break;
326953893Smckusick 	case FB_CBATCHBITBLT:
327053893Smckusick 		fbaddr->fb_result = batchbitbltcmd(fb, &fbaddr->fb_batchbitblt);
327153893Smckusick 		break;
327253893Smckusick 	case FB_CTILEBITBLT:
327353893Smckusick 		fbaddr->fb_result = tilebitbltcmd(fb, &fbaddr->fb_tilebitblt);
327453893Smckusick 		break;
327553893Smckusick 	case FB_CBITBLT3:
327653893Smckusick 		fbaddr->fb_result = bitblt3cmd(fb, &fbaddr->fb_bitblt3);
327753893Smckusick 		break;
327853893Smckusick 	case FB_CPOLYLINE:
327953893Smckusick 		fbaddr->fb_result = draw_polyline(fb, &fbaddr->fb_polyline);
328053893Smckusick 		break;
328153893Smckusick 	case FB_CDJPOLYLINE:
328253893Smckusick 		fbaddr->fb_result = draw_dj_polyline(fb, &fbaddr->fb_polyline);
328353893Smckusick 		break;
328453893Smckusick 	case FB_CRECTANGLE:
328553893Smckusick 		fbaddr->fb_result = draw_rectangle(fb, &fbaddr->fb_rectangle);
328653893Smckusick 		break;
328753893Smckusick 	case FB_CFILLSCAN:
328853893Smckusick 		fbaddr->fb_result = fill_scan(fb, &fbaddr->fb_fillscan);
328953893Smckusick 		break;
329053893Smckusick 	case FB_CPOLYMARKER:
329153893Smckusick 		fbaddr->fb_result = draw_polymarker(fb, &fbaddr->fb_polymarker);
329253893Smckusick 		break;
329353893Smckusick 	case FB_CTEXT:
329453893Smckusick 		fbaddr->fb_result = put_string(fb, &fbaddr->fb_text);
329553893Smckusick 		break;
329653893Smckusick 	case FB_CPOLYDOT:
329753893Smckusick 		fbaddr->fb_result = draw_polydot(fb, &fbaddr->fb_polydot);
329853893Smckusick 		break;
329953893Smckusick 	case FB_CGETSCRTYPE:
330053893Smckusick 		fbaddr->fb_result = get_scrtype(fb, &fbaddr->fb_scrtype);
330153893Smckusick 		break;
330253893Smckusick 	case FB_CSETPALETTE:
330353893Smckusick 		fbaddr->fb_result = fbbm_set_palette(fb, &fbaddr->fb_palette);
330453893Smckusick 		break;
330553893Smckusick 	case FB_CGETPALETTE:
330653893Smckusick 		fbaddr->fb_result = fbbm_get_palette(fb, &fbaddr->fb_palette);
330753893Smckusick 		break;
330853893Smckusick 	case FB_CSETCURSOR:
330953893Smckusick 		fbaddr->fb_result = setCursor(fb, &fbaddr->fb_cursor);
331053893Smckusick 		break;
331153893Smckusick 	case FB_CUNSETCURSOR:
331253893Smckusick 		fbaddr->fb_result = setCursor(fb, NULL);
331353893Smckusick 		break;
331453893Smckusick 	case FB_CSHOWCURSOR:
331553893Smckusick 		fbaddr->fb_result = showCursor(fb);
331653893Smckusick 		break;
331753893Smckusick 	case FB_CHIDECURSOR:
331853893Smckusick 		fbaddr->fb_result = hideCursor(fb);
331953893Smckusick 		break;
332053893Smckusick 	case FB_CSETXY:
332153893Smckusick 		fbaddr->fb_result = moveCursor(fb, &fbaddr->fb_point);
332253893Smckusick 		break;
332353893Smckusick 	case FB_CAUTODIM:
332453893Smckusick 		if (fbaddr->fb_data)
332553893Smckusick 			auto_dimmer_on(fb);
332653893Smckusick 		else
332753893Smckusick 			auto_dimmer_off(fb);
332853893Smckusick 		fbaddr->fb_result = FB_ROK;
332953893Smckusick 		break;
333053893Smckusick 	case FB_CSETVIDEO:
333153893Smckusick 		fbaddr->fb_result =
333253893Smckusick 			fbbm_ioctl(fb, FB_SETVIDEOCTL, &fbaddr->fb_videoctl);
333353893Smckusick 		break;
333453893Smckusick 	case FB_CGETVIDEO:
333553893Smckusick 		fbaddr->fb_result =
333653893Smckusick 			fbbm_ioctl(fb, FB_GETVIDEOSTATUS, &fbaddr->fb_videostatus);
333753893Smckusick 		break;
333853893Smckusick 	case FB_CSETPMODE:
333953893Smckusick 		fbaddr->fb_result =
334053893Smckusick 			fbbm_ioctl(fb, FB_SETPALETTEMODE, &fbaddr->fb_data);
334153893Smckusick 		break;
334253893Smckusick 	case FB_CGETPMODE:
334353893Smckusick 		fbaddr->fb_result =
334453893Smckusick 			fbbm_ioctl(fb, FB_GETPALETTEMODE, &fbaddr->fb_data);
334553893Smckusick 		break;
334653893Smckusick #ifdef CPU_SINGLE
334753893Smckusick 	case FB_CGETPAGE:
334853893Smckusick 		fbaddr->fb_data = fbbm_get_page(fb, fbaddr->fb_data);
334953893Smckusick 		if (fbaddr->fb_data == -1)
335053893Smckusick 			fbaddr->fb_result = FB_RERROR;
335153893Smckusick 		else
335253893Smckusick 			fbaddr->fb_result = FB_ROK;
335353893Smckusick 		break;
335453893Smckusick #endif
335553893Smckusick 	case FB_CIOCTL:
335653893Smckusick 		fbaddr->fb_fbioctl.request = fbbm_ioctl(fb,
335753893Smckusick 			fbaddr->fb_fbioctl.request, fbaddr->fb_fbioctl.param);
335853893Smckusick 		if (fbaddr->fb_fbioctl.request == -1)
335953893Smckusick 			fbaddr->fb_result = FB_RERROR;
336053893Smckusick 		else
336153893Smckusick 			fbaddr->fb_result = FB_ROK;
336253893Smckusick 		break;
336353893Smckusick 
336453893Smckusick 	default:
336553893Smckusick 		fbaddr->fb_result = FB_RERROR;
336653893Smckusick 		break;
336753893Smckusick 	}
336853893Smckusick 
336953893Smckusick #ifdef CPU_SINGLE
337053893Smckusick 	if (cfb && curs_pending) {
337153893Smckusick 		curs_pending = 0;
337253893Smckusick 		redrawCursor(cfb);
337353893Smckusick 	}
337453893Smckusick #endif
337553893Smckusick 
337653893Smckusick 	FB_UNLOCK;
337753893Smckusick }
3378