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