xref: /csrg-svn/sys/news3400/iop/fb_sub.c (revision 64627)
153887Smckusick /*
263308Sbostic  * Copyright (c) 1992, 1993
363308Sbostic  *	The Regents of the University of California.  All rights reserved.
453887Smckusick  *
553887Smckusick  * This code is derived from software contributed to Berkeley by
653887Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753887Smckusick  *
853887Smckusick  * %sccs.include.redist.c%
953887Smckusick  *
1053887Smckusick  * from: $Hdr: fb_sub.c,v 4.300 91/06/27 20:43:09 root Rel41 $ SONY
1153887Smckusick  *
12*64627Sbostic  *	@(#)fb_sub.c	8.2 (Berkeley) 09/23/93
1353887Smckusick  */
1453887Smckusick 
1553887Smckusick #include "fb.h"
1653887Smckusick #if NFB > 0
1753887Smckusick /*
1853887Smckusick  * Frame buffer driver
1953887Smckusick  */
2053887Smckusick 
2157183Sutashiro #include <sys/types.h>
2257183Sutashiro #include <machine/pte.h>
2357183Sutashiro #include <machine/cpu.h>
2457183Sutashiro #include <machine/param.h>
2553887Smckusick 
2657183Sutashiro #include <sys/param.h>
2757183Sutashiro #include <sys/proc.h>
2857183Sutashiro #include <sys/user.h>
2957183Sutashiro #include <sys/buf.h>
3057183Sutashiro #include <vm/vm.h>
3157183Sutashiro #include <sys/systm.h>
3257183Sutashiro #include <sys/map.h>
3357183Sutashiro #include <sys/uio.h>
3457183Sutashiro #include <sys/kernel.h>
3553887Smckusick 
3657183Sutashiro #include <news3400/iop/framebuf.h>
3757183Sutashiro #include <news3400/iop/fbreg.h>
3853887Smckusick #ifdef CPU_DOUBLE
3953887Smckusick #ifdef IPC_MRX
4053887Smckusick #include "../ipc/newsipc.h"
4153887Smckusick #ifdef mips
4253887Smckusick #define ipc_phys(x)	K0_TT0(x)
4353887Smckusick #define ipc_log(x)	TT0_K0(x)
4453887Smckusick #else /* mips */
4553887Smckusick #define	ipc_phys(x)	(caddr_t)((int)(x) & ~0x80000000)
4653887Smckusick #define	ipc_log(x)	(caddr_t)((int)(x) | 0x80000000)
4753887Smckusick #endif /* mips */
4853887Smckusick #endif /* IPC_MRX */
4953887Smckusick #else /* CPU_DOUBLE */
5053887Smckusick #define ipc_phys(x)	(caddr_t)((int)(x))
5153887Smckusick #define ipc_log(x)	(caddr_t)((int)(x) | 0x80000000)
5253887Smckusick #endif /* CPU_DOUBLE */
5353887Smckusick 
5453887Smckusick #define MAX_FBMAP	3
5553887Smckusick static struct fb_map	fbmap[MAX_FBMAP];
5653887Smckusick 
5753887Smckusick /* bitblt type */
5853887Smckusick #define BLTTYPE(ts, td)	((ts) << 2 | (td))
5953887Smckusick 
6053887Smckusick static lSrcDest	srcdestlist[MAX_BATCHBITBLT];
6153887Smckusick #define MAX_SIZE	(MAX_BATCHBITBLT * sizeof(lSrcDest))
6253887Smckusick 
6353887Smckusick #define ODD_ADDR(x)	(((unsigned)(x))&1)
6453887Smckusick 
6553887Smckusick #define MAXMSEG	4
6653887Smckusick static int	segind;
6753887Smckusick static struct memseg {
6853887Smckusick 	caddr_t		adrs;
6953887Smckusick 	int		len;
7053887Smckusick 	int		rw;
7153887Smckusick 	caddr_t		oadrs;
7253887Smckusick 	int		olen;
7353887Smckusick 	struct fb_map	*map;
7453887Smckusick } mseg[MAXMSEG];
7553887Smckusick 
7653887Smckusick #define BASE(a)	((int)(a) & ~(NBPG - 1))
7753887Smckusick 
7853887Smckusick #ifdef CPU_DOUBLE
COPYIN(src,dst,len,seg)7953887Smckusick COPYIN(src, dst, len, seg)
8053887Smckusick 	caddr_t src;
8153887Smckusick 	caddr_t dst;
8253887Smckusick 	int len;
8353887Smckusick 	int seg;
8453887Smckusick {
8553887Smckusick 
8653887Smckusick 	switch (seg) {
8753887Smckusick 	case UIO_SYSSPACE:
8853887Smckusick 		bcopy(src, dst, len);
8953887Smckusick 		return (0);
9053887Smckusick 	case UIO_USERSPACE:
9153887Smckusick 		return (copyin(src, dst, len));
9253887Smckusick 	default:
9353887Smckusick 		panic("COPYIN: seg");
9453887Smckusick 		/* NOTREACHED */
9553887Smckusick 	}
9653887Smckusick }
9753887Smckusick #endif /* CPU_DOUBLE */
9853887Smckusick 
fbgetmap(addr,len,map)9953887Smckusick fbgetmap(addr, len, map)
10053887Smckusick 	caddr_t addr;
10153887Smckusick 	int len;
10253887Smckusick 	struct fb_map *map;
10353887Smckusick {
10453887Smckusick 	register struct pte *pte;
10553887Smckusick 	register caddr_t *p;
10653887Smckusick 	unsigned v;
10753887Smckusick 	register int npf;
10853887Smckusick 	int o;
10953887Smckusick 
11053887Smckusick 	v = pmax_btop(addr);
11153887Smckusick 	o = (int)addr & PGOFSET;
11253887Smckusick 	npf = btoc(len + o);
11353887Smckusick 	if (npf > NFBMAP)
11453887Smckusick 		return (EINVAL);
11553887Smckusick 
11653887Smckusick 	map->fm_vaddr = addr;
11753887Smckusick 	map->fm_offset = o;
11853887Smckusick 	map->fm_count = len;
11953887Smckusick 
12053887Smckusick #ifdef CPU_DOUBLE
12153887Smckusick 	if (addr >= (caddr_t)KERNBASE) {
12253887Smckusick #ifdef mips
12353887Smckusick 		p = map->fm_addr;
12453887Smckusick 		if (MACH_IS_CACHED(addr)) {
12553887Smckusick 			addr = ptob(v);
12653887Smckusick 			while (--npf >= 0) {
12753887Smckusick 				*p++ = (caddr_t)K0_TT0(addr);
12853887Smckusick 				addr += NBPG;
12953887Smckusick 			}
13053887Smckusick 			return (0);
13153887Smckusick 		}
13253887Smckusick 		if (MACH_IS_MAPPED(addr))
13353887Smckusick 			pte = kvtopte(addr);
13453887Smckusick 		else if (addr >= (caddr_t)&u)
13553887Smckusick 			pte = curproc->p_addr + btop(addr - (caddr_t)&u);
13653887Smckusick 		else
13753887Smckusick 			panic("fbgetmap: bad kernel addr");
13853887Smckusick 		while (--npf >= 0)
13953887Smckusick 			*p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));
14053887Smckusick #else /* mips */
14153887Smckusick 		pte = kvtopte(addr);
14253887Smckusick 		p = map->fm_addr;
14353887Smckusick 		while (--npf >= 0)
14453887Smckusick 			*p++ = (caddr_t)ptob(pte++->pg_pfnum);
14553887Smckusick #endif /* mips */
14653887Smckusick 		return (0);
14753887Smckusick 	}
14853887Smckusick 	pte = vtopte(curproc, v);		/*KU:XXXXXXXXXXXXXXXXXX*/
14953887Smckusick 	p = map->fm_addr;
15053887Smckusick 	while (--npf >= 0) {
15153887Smckusick 		if (pte->pg_pfnum == 0)
15253887Smckusick 			panic("iop zero uentry");
15353887Smckusick #ifdef mips
15453887Smckusick 		*p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));
15553887Smckusick #else
15653887Smckusick 		*p++ = (caddr_t)ptob(pte++->pg_pfnum);
15753887Smckusick #endif
15853887Smckusick 	}
15953887Smckusick 
16053887Smckusick #endif /* CPU_DOUBLE */
16153887Smckusick 	return (0);
16253887Smckusick }
16353887Smckusick 
fblockmem(ad,len,rw,map,seg)16453887Smckusick fblockmem(ad, len, rw, map, seg)
16553887Smckusick 	register caddr_t ad;
16653887Smckusick 	register int len;
16753887Smckusick 	int rw;
16853887Smckusick 	struct fb_map *map;
16953887Smckusick 	int seg;
17053887Smckusick {
17153887Smckusick 	register struct memseg *msp;
17253887Smckusick 
17353887Smckusick 	/* validity check */
17453887Smckusick 	if (len < 0)
17553887Smckusick 		return EFAULT;
17653887Smckusick 	else if (len == 0)
17753887Smckusick 		return 0;
17853887Smckusick 	else if (ad == 0)
17953887Smckusick 		return EFAULT;
18053887Smckusick 	else if (seg == UIO_USERSPACE &&
18153887Smckusick 		 !useracc(ad, len, rw == B_READ ? B_WRITE : B_READ))
18253887Smckusick 		return EFAULT;
18353887Smckusick 	else if (segind >= MAXMSEG)
18453887Smckusick 		return EFAULT;
18553887Smckusick 
18653887Smckusick 	/* insertion sort */
18753887Smckusick 	for (msp = mseg + segind - 1; msp >= mseg; msp--) {
18853887Smckusick 		if (msp->adrs > ad)
18953887Smckusick 			*(msp + 1) = *msp;
19053887Smckusick 		else
19153887Smckusick 			break;
19253887Smckusick 	}
19353887Smckusick 	msp++;
19453887Smckusick #ifdef CPU_SINGLE
19553887Smckusick 	switch (seg) {
19653887Smckusick 	case UIO_SYSSPACE:
19753887Smckusick 		map->fm_vaddr = ad;
19853887Smckusick 		map->fm_offset = 0;
19953887Smckusick 		break;
20053887Smckusick 	case UIO_USERSPACE:
20153887Smckusick 		msp->adrs = (caddr_t)BASE(ad);
20253887Smckusick 		msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;
20353887Smckusick 		break;
20453887Smckusick 	default:
20553887Smckusick 		panic("fblockmem: seg");
20653887Smckusick 		/* NOTREACHED */
20753887Smckusick 	}
20853887Smckusick #else /* CPU_SINGLE */
20953887Smckusick 	msp->adrs = (caddr_t)BASE(ad);
21053887Smckusick 	msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;
21153887Smckusick #endif /* CPU_SINGLE */
21253887Smckusick 	msp->rw = rw;
21353887Smckusick 	msp->oadrs = ad;
21453887Smckusick 	msp->olen = len;
21553887Smckusick 	msp->map = map;
21653887Smckusick 	segind++;
21753887Smckusick 
21853887Smckusick 	return (0);
21953887Smckusick }
22053887Smckusick 
fblocksbitmap(bm,rw,map)22153887Smckusick fblocksbitmap(bm, rw, map)
22253887Smckusick 	register lBitmap *bm;
22353887Smckusick 	int rw;
22453887Smckusick 	struct fb_map *map;
22553887Smckusick {
22653887Smckusick 	register int len;
22753887Smckusick 	register int error = 0;
22853887Smckusick 
22953887Smckusick 	if (bm->depth > 32)
23053887Smckusick 		return EINVAL;
23153887Smckusick 	if (bm->type == BM_FB || bm->type == BM_0 || bm->type == BM_1)
23253887Smckusick 		return 0;
23353887Smckusick 	if (bm->type == BM_MEM)
23453887Smckusick 		len = bm->width * bm->rect.extent.y * bm->depth * sizeof(Word);
23553887Smckusick 	if (len < 0 || len > FB_MAX_IO)
23653887Smckusick 		return(EINVAL);
23753887Smckusick 	error = fblockmem((caddr_t)(bm->base), len, rw, map, UIO_USERSPACE);
23853887Smckusick 	if (error)
23953887Smckusick 		return error;
24053887Smckusick 
24153887Smckusick 	bm->base = (Word *)ipc_phys(map);
24253887Smckusick 	return 0;
24353887Smckusick }
24453887Smckusick 
24553887Smckusick void
fbinitlock()24653887Smckusick fbinitlock()
24753887Smckusick {
24853887Smckusick 	segind = 0;
24953887Smckusick }
25053887Smckusick 
25153887Smckusick void
fbdolock()25253887Smckusick fbdolock()
25353887Smckusick {
25453887Smckusick 	register struct memseg *msp0, *msp1, *mspl;
25553887Smckusick 	register int i, tlen;
25653887Smckusick 
25753887Smckusick 	mspl = mseg + segind;
25853887Smckusick 	for (msp0 = mseg, msp1 = mseg + 1; msp1 < mspl; msp0++, msp1++) {
25953887Smckusick 		if (msp0->adrs + msp0->len > msp1->adrs) {
26053887Smckusick 			tlen = msp1->adrs - msp0->adrs + msp1->len;
26153887Smckusick 			msp1->adrs = msp0->adrs;
26253887Smckusick 			msp1->len = msp0->len > tlen ? msp0->len : tlen;
26353887Smckusick 			msp0->len = 0;
26453887Smckusick 			msp1->rw = (msp0->rw == B_READ || msp1->rw == B_READ) ?
26553887Smckusick 					B_READ : B_WRITE;
26653887Smckusick 		}
26753887Smckusick 	}
26853887Smckusick 
26953887Smckusick 	/* lock */
270*64627Sbostic 	curproc->p_flag |= P_PHYSIO;
27153887Smckusick 	for (i = 0; i < segind; i++)
27253887Smckusick 		if (mseg[i].len && mseg[i].adrs && mseg[i].adrs
27353887Smckusick 		    < (caddr_t)KERNBASE)
27453887Smckusick 			vslock(mseg[i].adrs, mseg[i].len);
27553887Smckusick 
27653887Smckusick 	/* make map */
27753887Smckusick 	for (i = 0; i < segind; i++)
27853887Smckusick 		fbgetmap(mseg[i].oadrs, mseg[i].olen, mseg[i].map);
27953887Smckusick }
28053887Smckusick 
28153887Smckusick void
fbunlock()28253887Smckusick fbunlock()
28353887Smckusick {
28453887Smckusick 	register int i;
28553887Smckusick 	int s = splfb();
28653887Smckusick 
28753887Smckusick 	for (i = 0; i < segind; i++) {
28853887Smckusick 		if (mseg[i].len && mseg[i].adrs && mseg[i].adrs
28953887Smckusick 		    < (caddr_t)KERNBASE) {
29053887Smckusick 			vsunlock(mseg[i].adrs, mseg[i].len, mseg[i].rw);
29153887Smckusick #if defined(mips) && defined(CPU_DOUBLE)
29253887Smckusick 			if (mseg[i].rw == B_READ)
29353887Smckusick 				clean_kudcache(curproc,
29453887Smckusick 					       mseg[i].adrs, mseg[i].len);
29553887Smckusick #endif
29653887Smckusick 		}
29753887Smckusick 	}
298*64627Sbostic 	curproc->p_flag &= ~P_PHYSIO;
29953887Smckusick 	splx(s);
30053887Smckusick 
30153887Smckusick 	/* for 'fbinitlock() o wasureru ukkariyasan'... */
30253887Smckusick 	segind = 0;
30353887Smckusick }
30453887Smckusick 
checkbitmap(bm)30553887Smckusick checkbitmap(bm)
30653887Smckusick 	register lBitmap *bm;
30753887Smckusick {
30853887Smckusick 	if (bm->depth > 32)
30953887Smckusick 		return EINVAL;
31053887Smckusick 
31153887Smckusick 	switch(bm->type) {
31253887Smckusick 	case BM_FB:
31353887Smckusick 	case BM_0:
31453887Smckusick 	case BM_1:
31553887Smckusick 		break;
31653887Smckusick 	case BM_MEM:
31753887Smckusick 		if (ODD_ADDR(bm->base))
31853887Smckusick 			return EINVAL;
31953887Smckusick 		if (bm->width == 0)
32053887Smckusick 			return EINVAL;
32153887Smckusick 		if ((bm->width * bm->rect.extent.y) << 1 > FB_MAX_IO)
32253887Smckusick 			return EINVAL;
32353887Smckusick 		break;
32453887Smckusick 	default:
32553887Smckusick 		return EINVAL;
32653887Smckusick 	}
32753887Smckusick 
32853887Smckusick 	if (bm->rect.extent.x < 0 || bm->rect.extent.y < 0)
32953887Smckusick 		return EINVAL;
33053887Smckusick 	else
33153887Smckusick 		return 0;
33253887Smckusick }
33353887Smckusick 
checkdepth(sbm,dbm)33453887Smckusick checkdepth(sbm, dbm)
33553887Smckusick 	lBitmap	*sbm, *dbm;
33653887Smckusick {
33753887Smckusick 	register int ds = sbm->depth;
33853887Smckusick 	register int dd = dbm->depth;
33953887Smckusick 
34053887Smckusick 	if (ds > 1 && dd > 1 && ds != dd)
34153887Smckusick 		return -1;
34253887Smckusick 	else
34353887Smckusick 		return((ds > 1) << 1 | (dd > 1));
34453887Smckusick }
34553887Smckusick 
34653887Smckusick dobitblt(fbp, sbm, dbm)
34753887Smckusick 	struct fbreg *fbp;
34853887Smckusick 	lBitmap	*sbm, *dbm;
34953887Smckusick {
35053887Smckusick 	register int error;
35153887Smckusick 
35253887Smckusick 	if (error = fblocksbitmap(sbm, B_WRITE, fbmap))
35353887Smckusick 		return error;
35453887Smckusick 	if (error = fblocksbitmap(dbm, B_READ, fbmap + 1))
35553887Smckusick 		return error;
35653887Smckusick 	fbdolock();
35753887Smckusick 	fbstart(fbp, 1);
35853887Smckusick 	fbunlock();
35953887Smckusick 
36053887Smckusick 	/* reset address */
36153887Smckusick 	if (sbm->type == BM_MEM)
36253887Smckusick 		sbm->base =
36353887Smckusick 		    (Word *)((struct fb_map *)ipc_log(sbm->base))->fm_vaddr;
36453887Smckusick 	if (dbm->type == BM_MEM)
36553887Smckusick 		dbm->base =
36653887Smckusick 		    (Word *)((struct fb_map *)ipc_log(dbm->base))->fm_vaddr;
36753887Smckusick 	return 0;
36853887Smckusick }
36953887Smckusick 
fbnbitblt(fbp,cmd)37053887Smckusick fbnbitblt(fbp, cmd)
37153887Smckusick 	register struct fbreg *fbp;
37253887Smckusick 	register lBitblt *cmd;
37353887Smckusick {
37453887Smckusick 	register lBitblt *regcmd;
37553887Smckusick 	register int len, lens, lend;
37653887Smckusick 	register int i;
37753887Smckusick 	int pmask, mode;
37853887Smckusick 	int error = 0;
37953887Smckusick 	int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);
38053887Smckusick 
38153887Smckusick #ifdef CPU_DOUBLE
38253887Smckusick 	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
38353887Smckusick 	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||
38453887Smckusick 	    (blttype == BLTTYPE(BM_1, BM_MEM))) {
38553887Smckusick 		return(mfbnbitblt(fbp, cmd));
38653887Smckusick 		/* NOTREACHED */
38753887Smckusick 	}
38853887Smckusick #endif
38953887Smckusick 
39053887Smckusick 	fbinitlock();
39153887Smckusick 	if (error = checkbitmap(&cmd->srcBitmap))
39253887Smckusick 		return error;
39353887Smckusick 	if (error = checkbitmap(&cmd->destBitmap))
39453887Smckusick 		return error;
39553887Smckusick 	if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)
39653887Smckusick 		return EINVAL;
39753887Smckusick 
39853887Smckusick 	fbp->fb_command = FB_CBITBLT;
39953887Smckusick 	fbp->fb_bitblt = *cmd;
40053887Smckusick 	regcmd = &fbp->fb_bitblt;
40153887Smckusick 
40253887Smckusick 	/* process bitblt command */
40353887Smckusick 	switch (blttype) {
40453887Smckusick 	case BLTTYPE(BM_FB, BM_FB):
40553887Smckusick 	case BLTTYPE(BM_0, BM_FB):
40653887Smckusick 	case BLTTYPE(BM_1, BM_FB):
40753887Smckusick 		fbstart(fbp, 0);
40853887Smckusick 		break;
40953887Smckusick 
41053887Smckusick 	case BLTTYPE(BM_FB, BM_MEM):
41153887Smckusick 	case BLTTYPE(BM_0, BM_MEM):
41253887Smckusick 	case BLTTYPE(BM_1, BM_MEM):
41353887Smckusick 		len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
41453887Smckusick 		if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
41553887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
41653887Smckusick 					      &regcmd->destBitmap);
41753887Smckusick 			return error;
41853887Smckusick 		}
41953887Smckusick 
42053887Smckusick 		/* bitblt each plane */
42153887Smckusick 		regcmd->destBitmap.depth = 1;
42253887Smckusick 		pmask = regcmd->planemask;
42353887Smckusick 		for (i = 0; i < cmd->destBitmap.depth; i++) {
42453887Smckusick 			if (mode == 3)	/* N to N */
42553887Smckusick 				regcmd->planemask = pmask & (1 << i);
42653887Smckusick 
42753887Smckusick 			if (error = dobitblt(fbp, &regcmd->srcBitmap,
42853887Smckusick 						  &regcmd->destBitmap))
42953887Smckusick 				return error;
43053887Smckusick 
43153887Smckusick 			regcmd->destBitmap.base += len >> 1;
43253887Smckusick 			if (mode == 1) {	/* N to N */
43353887Smckusick 				regcmd->planemask >>= 1;
43453887Smckusick 				regcmd->fore_color >>= 1;
43553887Smckusick 				regcmd->aux_color >>= 1;
43653887Smckusick 			}
43753887Smckusick 		}
43853887Smckusick 		break;
43953887Smckusick 
44053887Smckusick 	case BLTTYPE(BM_MEM, BM_FB):
44153887Smckusick 		len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
44253887Smckusick 
44353887Smckusick 		if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {
44453887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
44553887Smckusick 					      &regcmd->destBitmap);
44653887Smckusick 			return error;
44753887Smckusick 		}
44853887Smckusick 
44953887Smckusick 		/* bitblt each plane */
45053887Smckusick 		regcmd->srcBitmap.depth = 1;
45153887Smckusick 		pmask = regcmd->planemask;
45253887Smckusick 		regcmd->fore_color = 0xff;
45353887Smckusick 		regcmd->aux_color = 0;
45453887Smckusick 		if (mode == 2) {	/* N to 1 */
45553887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++)
45653887Smckusick 				if (pmask & (1 << i))
45753887Smckusick 					break;
45853887Smckusick 			if (i >= cmd->srcBitmap.depth)
45953887Smckusick 				return 0;
46053887Smckusick 			regcmd->srcBitmap.base += (len >> 1) * i;
46153887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
46253887Smckusick 					      &regcmd->destBitmap);
46353887Smckusick 			return error;
46453887Smckusick 		}
46553887Smckusick 		/* else (N to N) */
46653887Smckusick 		for (i = 0; i < cmd->srcBitmap.depth; i++) {
46753887Smckusick 			regcmd->planemask = pmask & (1 << i);
46853887Smckusick 			if (error = dobitblt(fbp, &regcmd->srcBitmap,
46953887Smckusick 						  &regcmd->destBitmap))
47053887Smckusick 				return error;
47153887Smckusick 			regcmd->srcBitmap.base += len >> 1;
47253887Smckusick 			regcmd->planemask >>= 1;
47353887Smckusick 		}
47453887Smckusick 		return 0;
47553887Smckusick 
47653887Smckusick 	case BLTTYPE(BM_MEM, BM_MEM):
47753887Smckusick 		lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
47853887Smckusick 		lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
47953887Smckusick 		if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&
48053887Smckusick 		    lend * cmd->destBitmap.depth <= FB_MAX_IO) {
48153887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
48253887Smckusick 					      &regcmd->destBitmap);
48353887Smckusick 			return error;
48453887Smckusick 		}
48553887Smckusick 
48653887Smckusick 		regcmd->srcBitmap.depth = 1;
48753887Smckusick 		regcmd->destBitmap.depth = 1;
48853887Smckusick 		pmask = regcmd->planemask;
48953887Smckusick 		if (mode == 2) {	/* N to 1 */
49053887Smckusick 			regcmd->fore_color = 0xff;
49153887Smckusick 			regcmd->aux_color = 0;
49253887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++)
49353887Smckusick 				if (pmask & (1 << i))
49453887Smckusick 					break;
49553887Smckusick 			if (i >= cmd->srcBitmap.depth)
49653887Smckusick 				return 0;
49753887Smckusick 			regcmd->srcBitmap.base += (lens >> 1) * i;
49853887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
49953887Smckusick 					      &regcmd->destBitmap);
50053887Smckusick 			return error;
50153887Smckusick 		} else if (mode == 1) {	/* 1 to N */
50253887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++) {
50353887Smckusick 				if (error = dobitblt(fbp, &regcmd->srcBitmap,
50453887Smckusick 							  &regcmd->destBitmap))
50553887Smckusick 					return error;
50653887Smckusick 				regcmd->planemask >>= 1;
50753887Smckusick 				regcmd->fore_color >>= 1;
50853887Smckusick 				regcmd->aux_color >>= 1;
50953887Smckusick 				regcmd->destBitmap.base += lend >> 1;
51053887Smckusick 			}
51153887Smckusick 			return 0;
51253887Smckusick 		} else {		/* N to N */
51353887Smckusick 			regcmd->fore_color = 0xff;
51453887Smckusick 			regcmd->aux_color = 0;
51553887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++) {
51653887Smckusick 				if (error = dobitblt(fbp, &regcmd->srcBitmap,
51753887Smckusick 							  &regcmd->destBitmap))
51853887Smckusick 					return error;
51953887Smckusick 				regcmd->srcBitmap.base += lens >> 1;
52053887Smckusick 				regcmd->destBitmap.base += lend >> 1;
52153887Smckusick 				regcmd->planemask >>= 1;
52253887Smckusick 			}
52353887Smckusick 			return 0;
52453887Smckusick 		}
52553887Smckusick 		break;
52653887Smckusick 
52753887Smckusick 	default:
52853887Smckusick 		return EINVAL;
52953887Smckusick 	}
53053887Smckusick 
53153887Smckusick 	return error;
53253887Smckusick }
53353887Smckusick 
53453887Smckusick fbbitblt(fbp, cmd)
53553887Smckusick 	struct fbreg *fbp;
53653887Smckusick 	register sBitblt *cmd;
53753887Smckusick {
53853887Smckusick 	lBitblt lcmd;
53953887Smckusick 	register lBitblt *lcmdp;
54053887Smckusick 
54153887Smckusick 	lcmdp = &lcmd;
54253887Smckusick 
54353887Smckusick 	lcmdp->func = cmd->func;
54453887Smckusick 	lcmdp->transp = cmd->transp;
54553887Smckusick 	lcmdp->fore_color = cmd->fore_color;
54653887Smckusick 	lcmdp->aux_color = cmd->aux_color;
54753887Smckusick 	lcmdp->planemask = cmd->planemask;
54853887Smckusick 	lcmdp->srcBitmap.type = cmd->srcBitmap.type;
54953887Smckusick 	lcmdp->srcBitmap.depth = cmd->srcBitmap.depth;
55053887Smckusick 	lcmdp->srcBitmap.width = cmd->srcBitmap.width;
55153887Smckusick 	lcmdp->srcBitmap.rect.origin.x = cmd->srcBitmap.rect.origin.x;
55253887Smckusick 	lcmdp->srcBitmap.rect.origin.y = cmd->srcBitmap.rect.origin.y;
55353887Smckusick 	lcmdp->srcBitmap.rect.extent.x = cmd->srcBitmap.rect.extent.x;
55453887Smckusick 	lcmdp->srcBitmap.rect.extent.y = cmd->srcBitmap.rect.extent.y;
55553887Smckusick 	lcmdp->srcBitmap.base = cmd->srcBitmap.base;
55653887Smckusick 	lcmdp->srcRect.origin.x = cmd->srcRect.origin.x;
55753887Smckusick 	lcmdp->srcRect.origin.y = cmd->srcRect.origin.y;
55853887Smckusick 	lcmdp->srcRect.extent.x = cmd->srcRect.extent.x;
55953887Smckusick 	lcmdp->srcRect.extent.y = cmd->srcRect.extent.y;
56053887Smckusick 	lcmdp->destBitmap.type = cmd->destBitmap.type;
56153887Smckusick 	lcmdp->destBitmap.depth = cmd->destBitmap.depth;
56253887Smckusick 	lcmdp->destBitmap.width = cmd->destBitmap.width;
56353887Smckusick 	lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
56453887Smckusick 	lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
56553887Smckusick 	lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
56653887Smckusick 	lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
56753887Smckusick 	lcmdp->destBitmap.base = cmd->destBitmap.base;
56853887Smckusick 	lcmdp->destClip.origin.x = cmd->destClip.origin.x;
56953887Smckusick 	lcmdp->destClip.origin.y = cmd->destClip.origin.y;
57053887Smckusick 	lcmdp->destClip.extent.x = cmd->destClip.extent.x;
57153887Smckusick 	lcmdp->destClip.extent.y = cmd->destClip.extent.y;
57253887Smckusick 	lcmdp->destPoint.x = cmd->destPoint.x;
57353887Smckusick 	lcmdp->destPoint.y = cmd->destPoint.y;
57453887Smckusick 	return (fbnbitblt(fbp, lcmdp));
57553887Smckusick }
57653887Smckusick 
57753887Smckusick procbatchbitblt(fbp, mode, cmd)
57853887Smckusick 	struct fbreg *fbp;
57953887Smckusick 	int mode;
58053887Smckusick 	register lBatchBitblt *cmd;
58153887Smckusick {
58253887Smckusick 	register lBatchBitblt *regcmd;
58353887Smckusick 	register int len, lens, lend;
58453887Smckusick 	register int i;
58553887Smckusick 	int pmask;
58653887Smckusick 	int error = 0;
58753887Smckusick 
58853887Smckusick 	regcmd = &fbp->fb_batchbitblt;
58953887Smckusick 	/* process batch bitblt command */
59053887Smckusick 	switch (BLTTYPE(regcmd->srcBitmap.type, regcmd->destBitmap.type)) {
59153887Smckusick 	case BLTTYPE(BM_FB, BM_FB):
59253887Smckusick 	case BLTTYPE(BM_0, BM_FB):
59353887Smckusick 	case BLTTYPE(BM_1, BM_FB):
59453887Smckusick 		fbdolock();
59553887Smckusick 		fbstart(fbp, cmd->nSrcDest);
59653887Smckusick 		fbunlock();
59753887Smckusick 		break;
59853887Smckusick 
59953887Smckusick 	case BLTTYPE(BM_FB, BM_MEM):
60053887Smckusick 	case BLTTYPE(BM_0, BM_MEM):
60153887Smckusick 	case BLTTYPE(BM_1, BM_MEM):
60253887Smckusick 		len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
60353887Smckusick 		if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
60453887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
60553887Smckusick 					      &regcmd->destBitmap);
60653887Smckusick 			return error;
60753887Smckusick 		}
60853887Smckusick 
60953887Smckusick 		/* bitblt each plane */
61053887Smckusick 		regcmd->destBitmap.depth = 1;
61153887Smckusick 		pmask = regcmd->planemask;
61253887Smckusick 		for (i = 0; i < cmd->destBitmap.depth; i++) {
61353887Smckusick 			if (mode == 3)	/* N to N */
61453887Smckusick 				regcmd->planemask = pmask & (1 << i);
61553887Smckusick 
61653887Smckusick 			if (error = dobitblt(fbp, &regcmd->srcBitmap,
61753887Smckusick 						  &regcmd->destBitmap))
61853887Smckusick 				return error;
61953887Smckusick 
62053887Smckusick 			regcmd->destBitmap.base += len >> 1;
62153887Smckusick 			if (mode == 1) {	/* N to N */
62253887Smckusick 				regcmd->planemask >>= 1;
62353887Smckusick 				regcmd->fore_color >>= 1;
62453887Smckusick 				regcmd->aux_color >>= 1;
62553887Smckusick 			}
62653887Smckusick 		}
62753887Smckusick 		break;
62853887Smckusick 
62953887Smckusick 	case BLTTYPE(BM_MEM, BM_FB):
63053887Smckusick 		len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
63153887Smckusick 
63253887Smckusick 		if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {
63353887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
63453887Smckusick 					      &regcmd->destBitmap);
63553887Smckusick 			return error;
63653887Smckusick 		}
63753887Smckusick 
63853887Smckusick 		/* bitblt each plane */
63953887Smckusick 		regcmd->srcBitmap.depth = 1;
64053887Smckusick 		pmask = regcmd->planemask;
64153887Smckusick 		regcmd->fore_color = 0xff;
64253887Smckusick 		regcmd->aux_color = 0;
64353887Smckusick 		if (mode == 2) {	/* N to 1 */
64453887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++)
64553887Smckusick 				if (pmask & (1 << i))
64653887Smckusick 					break;
64753887Smckusick 			if (i >= cmd->srcBitmap.depth)
64853887Smckusick 				return 0;
64953887Smckusick 			regcmd->srcBitmap.base += (len >> 1) * i;
65053887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
65153887Smckusick 					      &regcmd->destBitmap);
65253887Smckusick 			return error;
65353887Smckusick 		}
65453887Smckusick 		/* else (N to N) */
65553887Smckusick 		for (i = 0; i < cmd->srcBitmap.depth; i++) {
65653887Smckusick 			regcmd->planemask = pmask & (1 << i);
65753887Smckusick 			if (error = dobitblt(fbp, &regcmd->srcBitmap,
65853887Smckusick 						  &regcmd->destBitmap))
65953887Smckusick 				return error;
66053887Smckusick 			regcmd->srcBitmap.base += len >> 1;
66153887Smckusick 			regcmd->planemask >>= 1;
66253887Smckusick 		}
66353887Smckusick 		return 0;
66453887Smckusick 
66553887Smckusick 	case BLTTYPE(BM_MEM, BM_MEM):
66653887Smckusick 		lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
66753887Smckusick 		lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
66853887Smckusick 		if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&
66953887Smckusick 		    lend * cmd->destBitmap.depth <= FB_MAX_IO) {
67053887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
67153887Smckusick 					      &regcmd->destBitmap);
67253887Smckusick 			return error;
67353887Smckusick 		}
67453887Smckusick 
67553887Smckusick 		regcmd->srcBitmap.depth = 1;
67653887Smckusick 		regcmd->destBitmap.depth = 1;
67753887Smckusick 		pmask = regcmd->planemask;
67853887Smckusick 		if (mode == 2) {	/* N to 1 */
67953887Smckusick 			regcmd->fore_color = 0xff;
68053887Smckusick 			regcmd->aux_color = 0;
68153887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++)
68253887Smckusick 				if (pmask & (1 << i))
68353887Smckusick 					break;
68453887Smckusick 			if (i >= cmd->srcBitmap.depth)
68553887Smckusick 				return 0;
68653887Smckusick 			regcmd->srcBitmap.base += (lens >> 1) * i;
68753887Smckusick 			error = dobitblt(fbp, &regcmd->srcBitmap,
68853887Smckusick 					      &regcmd->destBitmap);
68953887Smckusick 			return error;
69053887Smckusick 		} else if (mode == 1) {	/* 1 to N */
69153887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++) {
69253887Smckusick 				if (error = dobitblt(fbp, &regcmd->srcBitmap,
69353887Smckusick 							  &regcmd->destBitmap))
69453887Smckusick 					return error;
69553887Smckusick 				regcmd->planemask >>= 1;
69653887Smckusick 				regcmd->fore_color >>= 1;
69753887Smckusick 				regcmd->aux_color >>= 1;
69853887Smckusick 				regcmd->destBitmap.base += lend >> 1;
69953887Smckusick 			}
70053887Smckusick 			return 0;
70153887Smckusick 		} else {		/* N to N */
70253887Smckusick 			regcmd->fore_color = 0xff;
70353887Smckusick 			regcmd->aux_color = 0;
70453887Smckusick 			for (i = 0; i < cmd->srcBitmap.depth; i++) {
70553887Smckusick 				if (error = dobitblt(fbp, &regcmd->srcBitmap,
70653887Smckusick 							  &regcmd->destBitmap))
70753887Smckusick 					return error;
70853887Smckusick 				regcmd->srcBitmap.base += lens >> 1;
70953887Smckusick 				regcmd->destBitmap.base += lend >> 1;
71053887Smckusick 				regcmd->planemask >>= 1;
71153887Smckusick 			}
71253887Smckusick 			return 0;
71353887Smckusick 		}
71453887Smckusick 		break;
71553887Smckusick 
71653887Smckusick 	default:
71753887Smckusick 		return EINVAL;
71853887Smckusick 	}
71953887Smckusick 
72053887Smckusick 	return error;
72153887Smckusick }
72253887Smckusick 
fbnbatchbitblt(fbp,cmd,seg)72353887Smckusick fbnbatchbitblt(fbp, cmd, seg)
72453887Smckusick 	register struct fbreg *fbp;
72553887Smckusick 	register lBatchBitblt *cmd;
72653887Smckusick 	int seg;
72753887Smckusick {
72853887Smckusick 	register int error;
72953887Smckusick 	register int mode;
73053887Smckusick 	register int len;
73153887Smckusick 
73253887Smckusick #ifdef CPU_DOUBLE
73353887Smckusick 	int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);
73453887Smckusick 
73553887Smckusick 	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
73653887Smckusick 	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||
73753887Smckusick 	    (blttype == BLTTYPE(BM_1, BM_MEM))) {
73853887Smckusick 		return(mfbnbatchbitblt(fbp, cmd, seg));
73953887Smckusick 		/* notreached */
74053887Smckusick 	}
74153887Smckusick #endif
74253887Smckusick 
74353887Smckusick 	fbinitlock();
74453887Smckusick 	fbp->fb_command = FB_CBATCHBITBLT;
74553887Smckusick 	fbp->fb_batchbitblt = *cmd;
74653887Smckusick 
74753887Smckusick 	if (error = checkbitmap(&cmd->srcBitmap))
74853887Smckusick 		return error;
74953887Smckusick 	if (error = checkbitmap(&cmd->destBitmap))
75053887Smckusick 		return error;
75153887Smckusick 	if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)
75253887Smckusick 		return EINVAL;
75353887Smckusick 
75453887Smckusick #ifdef CPU_SINGLE
75553887Smckusick 	if ((len = cmd->nSrcDest * sizeof(lSrcDest)) <= 0)
75653887Smckusick 		return EINVAL;
75753887Smckusick 	if (error = fblockmem((caddr_t)cmd->srcDestList,
75853887Smckusick 			      len, B_WRITE, fbmap + 2, seg))
75953887Smckusick 		return error;
76053887Smckusick 	fbp->fb_batchbitblt.srcDestList = (lSrcDest *)ipc_phys(fbmap + 2);
76153887Smckusick 	error = procbatchbitblt(fbp, mode, cmd);
76253887Smckusick #else
76353887Smckusick 	fbp->fb_batchbitblt.srcDestList = (lSrcDest*)ipc_phys(srcdestlist);
76453887Smckusick 	while(cmd->nSrcDest > 0) {
76553887Smckusick 		len = min(cmd->nSrcDest, (MAX_SIZE / sizeof(lSrcDest)));
76653887Smckusick 		error = COPYIN((caddr_t)cmd->srcDestList, (caddr_t)srcdestlist,
76753887Smckusick 				len * sizeof(lSrcDest), seg);
76853887Smckusick 		if (error)
76953887Smckusick 			return error;
77053887Smckusick 		cmd->nSrcDest -= len;
77153887Smckusick 		cmd->srcDestList += len;
77253887Smckusick 		fbp->fb_batchbitblt.nSrcDest = len;
77353887Smckusick 
77453887Smckusick 		if (error = procbatchbitblt(fbp, mode, cmd))
77553887Smckusick 			return error;
77653887Smckusick 	}
77753887Smckusick #endif /* CPU_DOUBLE */
77853887Smckusick 	return error;
77953887Smckusick }
78053887Smckusick 
78153887Smckusick fbbatchbitblt(fbp, cmd)
78253887Smckusick 	struct fbreg *fbp;
78353887Smckusick 	register sBatchBitblt *cmd;
78453887Smckusick {
78553887Smckusick 	lBatchBitblt lcmd;
78653887Smckusick 	register lBatchBitblt *lcmdp;
78753887Smckusick 	static lSrcDest ls[100];
78853887Smckusick 	register lSrcDest *lp;
78953887Smckusick 	register sSrcDest *sp;
79053887Smckusick 	register int ns;
79153887Smckusick 
79253887Smckusick 	lcmdp = &lcmd;
79353887Smckusick 
79453887Smckusick 	lcmdp->func = cmd->func;
79553887Smckusick 	lcmdp->transp = cmd->transp;
79653887Smckusick 	lcmdp->fore_color = cmd->fore_color;
79753887Smckusick 	lcmdp->aux_color = cmd->aux_color;
79853887Smckusick 	lcmdp->planemask = cmd->planemask;
79953887Smckusick 	lcmdp->srcBitmap.type = cmd->srcBitmap.type;
80053887Smckusick 	lcmdp->srcBitmap.depth = cmd->srcBitmap.depth;
80153887Smckusick 	lcmdp->srcBitmap.width = cmd->srcBitmap.width;
80253887Smckusick 	lcmdp->srcBitmap.rect.origin.x = cmd->srcBitmap.rect.origin.x;
80353887Smckusick 	lcmdp->srcBitmap.rect.origin.y = cmd->srcBitmap.rect.origin.y;
80453887Smckusick 	lcmdp->srcBitmap.rect.extent.x = cmd->srcBitmap.rect.extent.x;
80553887Smckusick 	lcmdp->srcBitmap.rect.extent.y = cmd->srcBitmap.rect.extent.y;
80653887Smckusick 	lcmdp->srcBitmap.base = cmd->srcBitmap.base;
80753887Smckusick 	lcmdp->destBitmap.type = cmd->destBitmap.type;
80853887Smckusick 	lcmdp->destBitmap.depth = cmd->destBitmap.depth;
80953887Smckusick 	lcmdp->destBitmap.width = cmd->destBitmap.width;
81053887Smckusick 	lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
81153887Smckusick 	lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
81253887Smckusick 	lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
81353887Smckusick 	lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
81453887Smckusick 	lcmdp->destBitmap.base = cmd->destBitmap.base;
81553887Smckusick 	lcmdp->destClip.origin.x = cmd->destClip.origin.x;
81653887Smckusick 	lcmdp->destClip.origin.y = cmd->destClip.origin.y;
81753887Smckusick 	lcmdp->destClip.extent.x = cmd->destClip.extent.x;
81853887Smckusick 	lcmdp->destClip.extent.y = cmd->destClip.extent.y;
81953887Smckusick 	lcmdp->srcDestList = ls;
82053887Smckusick 	sp = (sSrcDest *)cmd->srcDestList;
82153887Smckusick 	while (cmd->nSrcDest) {
82253887Smckusick 		lcmdp->nSrcDest = ns = min(cmd->nSrcDest, 100);
82353887Smckusick 		cmd->nSrcDest -= ns;
82453887Smckusick 		lp = ls;
82553887Smckusick 		while (ns-- > 0) {
82653887Smckusick 			int error;
82753887Smckusick 			sSrcDest tmp;
82853887Smckusick 
82953887Smckusick 			error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof(tmp));
83053887Smckusick 			if (error)
83153887Smckusick 				return (error);
83253887Smckusick 			lp->srcRect.origin.x = tmp.srcRect.origin.x;
83353887Smckusick 			lp->srcRect.origin.y = tmp.srcRect.origin.y;
83453887Smckusick 			lp->srcRect.extent.x = tmp.srcRect.extent.x;
83553887Smckusick 			lp->srcRect.extent.y = tmp.srcRect.extent.y;
83653887Smckusick 			lp->destPoint.x = tmp.destPoint.x;
83753887Smckusick 			lp->destPoint.y = tmp.destPoint.y;
83853887Smckusick 			lp++;
83953887Smckusick 			sp++;
84053887Smckusick 		}
84153887Smckusick 		fbnbatchbitblt(fbp, lcmdp, UIO_SYSSPACE);
84253887Smckusick 	}
84353887Smckusick }
84453887Smckusick 
fbntilebitblt(fbp,cmd)84553887Smckusick fbntilebitblt(fbp, cmd)
84653887Smckusick 	register struct fbreg *fbp;
84753887Smckusick 	register lTileBitblt *cmd;
84853887Smckusick {
84953887Smckusick 	register lTileBitblt *regcmd;
85053887Smckusick 	register int len, lens, lend;
85153887Smckusick 	register int i;
85253887Smckusick 	int mode;
85353887Smckusick 	int pmask;
85453887Smckusick 	int error;
85553887Smckusick 	int blttype = BLTTYPE(cmd->ptnBitmap.type, cmd->destBitmap.type);
85653887Smckusick 
85753887Smckusick #ifdef CPU_DOUBLE
85853887Smckusick 	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
85953887Smckusick 	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||
86053887Smckusick 	    (blttype == BLTTYPE(BM_1, BM_MEM))) {
86153887Smckusick 		return(mfbntilebitblt(fbp, cmd));
86253887Smckusick 		/* NOTREACHED */
86353887Smckusick 	}
86453887Smckusick #endif
86553887Smckusick 
86653887Smckusick 	if (error = checkbitmap(&cmd->ptnBitmap))
86753887Smckusick 		return error;
86853887Smckusick 	if (error = checkbitmap(&cmd->destBitmap))
86953887Smckusick 		return error;
87053887Smckusick 	if ((mode = checkdepth(&cmd->ptnBitmap, &cmd->destBitmap)) < 0)
87153887Smckusick 		return EINVAL;
87253887Smckusick 
87353887Smckusick 	fbp->fb_command = FB_CTILEBITBLT;
87453887Smckusick 	fbp->fb_tilebitblt = *cmd;
87553887Smckusick 	regcmd = &fbp->fb_tilebitblt;
87653887Smckusick 
87753887Smckusick 	/* process bitblt command */
87853887Smckusick 	switch (blttype) {
87953887Smckusick 	case BLTTYPE(BM_FB, BM_FB):
88053887Smckusick 	case BLTTYPE(BM_0, BM_FB):
88153887Smckusick 	case BLTTYPE(BM_1, BM_FB):
88253887Smckusick 		fbstart(fbp, 0);
88353887Smckusick 		break;
88453887Smckusick 
88553887Smckusick 	case BLTTYPE(BM_FB, BM_MEM):
88653887Smckusick 	case BLTTYPE(BM_0, BM_MEM):
88753887Smckusick 	case BLTTYPE(BM_1, BM_MEM):
88853887Smckusick 		len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
88953887Smckusick 		if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
89053887Smckusick 			error = dobitblt(fbp, &regcmd->ptnBitmap,
89153887Smckusick 					      &regcmd->destBitmap);
89253887Smckusick 			return error;
89353887Smckusick 		}
89453887Smckusick 
89553887Smckusick 		/* bitblt each plane */
89653887Smckusick 		regcmd->destBitmap.depth = 1;
89753887Smckusick 		pmask = regcmd->planemask;
89853887Smckusick 		for (i = 0; i < cmd->destBitmap.depth; i++) {
89953887Smckusick 			if (mode == 3)	/* N to N */
90053887Smckusick 				regcmd->planemask = pmask & (1 << i);
90153887Smckusick 
90253887Smckusick 			if (error = dobitblt(fbp, &regcmd->ptnBitmap,
90353887Smckusick 						  &regcmd->destBitmap))
90453887Smckusick 				return error;
90553887Smckusick 
90653887Smckusick 			regcmd->destBitmap.base += len >> 1;
90753887Smckusick 			if (mode == 1) {	/* N to N */
90853887Smckusick 				regcmd->planemask >>= 1;
90953887Smckusick 				regcmd->fore_color >>= 1;
91053887Smckusick 				regcmd->aux_color >>= 1;
91153887Smckusick 			}
91253887Smckusick 		}
91353887Smckusick 		break;
91453887Smckusick 
91553887Smckusick 	case BLTTYPE(BM_MEM, BM_FB):
91653887Smckusick 		len = cmd->ptnBitmap.width * cmd->ptnBitmap.rect.extent.y << 1;
91753887Smckusick 
91853887Smckusick 		if (len * cmd->ptnBitmap.depth <= FB_MAX_IO) {
91953887Smckusick 			error = dobitblt(fbp, &regcmd->ptnBitmap,
92053887Smckusick 					      &regcmd->destBitmap);
92153887Smckusick 			return error;
92253887Smckusick 		}
92353887Smckusick 
92453887Smckusick 		/* bitblt each plane */
92553887Smckusick 		regcmd->ptnBitmap.depth = 1;
92653887Smckusick 		pmask = regcmd->planemask;
92753887Smckusick 		regcmd->fore_color = 0xff;
92853887Smckusick 		regcmd->aux_color = 0;
92953887Smckusick 		if (mode == 2) {	/* N to 1 */
93053887Smckusick 			for (i = 0; i < cmd->ptnBitmap.depth; i++)
93153887Smckusick 				if (pmask & (1 << i))
93253887Smckusick 					break;
93353887Smckusick 			if (i >= cmd->ptnBitmap.depth)
93453887Smckusick 				return 0;
93553887Smckusick 			regcmd->ptnBitmap.base += (len >> 1) * i;
93653887Smckusick 			error = dobitblt(fbp, &regcmd->ptnBitmap,
93753887Smckusick 					      &regcmd->destBitmap);
93853887Smckusick 			return error;
93953887Smckusick 		}
94053887Smckusick 		/* else (N to N) */
94153887Smckusick 		for (i = 0; i < cmd->ptnBitmap.depth; i++) {
94253887Smckusick 			regcmd->planemask = pmask & (1 << i);
94353887Smckusick 			if (error = dobitblt(fbp, &regcmd->ptnBitmap,
94453887Smckusick 						  &regcmd->destBitmap))
94553887Smckusick 				return error;
94653887Smckusick 			regcmd->ptnBitmap.base += len >> 1;
94753887Smckusick 			regcmd->planemask >>= 1;
94853887Smckusick 		}
94953887Smckusick 		return 0;
95053887Smckusick 
95153887Smckusick 	case BLTTYPE(BM_MEM, BM_MEM):
95253887Smckusick 		lens = cmd->ptnBitmap.width * cmd->ptnBitmap.rect.extent.y << 1;
95353887Smckusick 		lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
95453887Smckusick 		if (lens * cmd->ptnBitmap.depth <= FB_MAX_IO &&
95553887Smckusick 		    lend * cmd->destBitmap.depth <= FB_MAX_IO) {
95653887Smckusick 			error = dobitblt(fbp, &regcmd->ptnBitmap,
95753887Smckusick 					      &regcmd->destBitmap);
95853887Smckusick 			return error;
95953887Smckusick 		}
96053887Smckusick 
96153887Smckusick 		regcmd->ptnBitmap.depth = 1;
96253887Smckusick 		regcmd->destBitmap.depth = 1;
96353887Smckusick 		pmask = regcmd->planemask;
96453887Smckusick 		if (mode == 2) {	/* N to 1 */
96553887Smckusick 			regcmd->fore_color = 0xff;
96653887Smckusick 			regcmd->aux_color = 0;
96753887Smckusick 			for (i = 0; i < cmd->ptnBitmap.depth; i++)
96853887Smckusick 				if (pmask & (1 << i))
96953887Smckusick 					break;
97053887Smckusick 			if (i >= cmd->ptnBitmap.depth)
97153887Smckusick 				return 0;
97253887Smckusick 			regcmd->ptnBitmap.base += (lens >> 1) * i;
97353887Smckusick 			error = dobitblt(fbp, &regcmd->ptnBitmap,
97453887Smckusick 					      &regcmd->destBitmap);
97553887Smckusick 			return error;
97653887Smckusick 		} else if (mode == 1) {	/* 1 to N */
97753887Smckusick 			for (i = 0; i < cmd->ptnBitmap.depth; i++) {
97853887Smckusick 				if (error = dobitblt(fbp, &regcmd->ptnBitmap,
97953887Smckusick 							  &regcmd->destBitmap))
98053887Smckusick 					return error;
98153887Smckusick 				regcmd->planemask >>= 1;
98253887Smckusick 				regcmd->fore_color >>= 1;
98353887Smckusick 				regcmd->aux_color >>= 1;
98453887Smckusick 				regcmd->destBitmap.base += lend >> 1;
98553887Smckusick 			}
98653887Smckusick 			return 0;
98753887Smckusick 		} else {		/* N to N */
98853887Smckusick 			for (i = 0; i < cmd->ptnBitmap.depth; i++) {
98953887Smckusick 				if (error = dobitblt(fbp, &regcmd->ptnBitmap,
99053887Smckusick 							  &regcmd->destBitmap))
99153887Smckusick 					return error;
99253887Smckusick 				regcmd->ptnBitmap.base += lens >> 1;
99353887Smckusick 				regcmd->destBitmap.base += lend >> 1;
99453887Smckusick 				regcmd->planemask >>= 1;
99553887Smckusick 			}
99653887Smckusick 			return 0;
99753887Smckusick 		}
99853887Smckusick 		break;
99953887Smckusick 
100053887Smckusick 	default:
100153887Smckusick 		return EINVAL;
100253887Smckusick 	}
100353887Smckusick 	return error;
100453887Smckusick }
100553887Smckusick 
100653887Smckusick fbtilebitblt(fbp, cmd)
100753887Smckusick 	struct fbreg *fbp;
100853887Smckusick 	register sTileBitblt *cmd;
100953887Smckusick {
101053887Smckusick 	lTileBitblt lcmd;
101153887Smckusick 	register lTileBitblt *lcmdp;
101253887Smckusick 
101353887Smckusick 	lcmdp = &lcmd;
101453887Smckusick 
101553887Smckusick 	lcmdp->func = cmd->func;
101653887Smckusick 	lcmdp->transp = cmd->transp;
101753887Smckusick 	lcmdp->fore_color = cmd->fore_color;
101853887Smckusick 	lcmdp->aux_color = cmd->aux_color;
101953887Smckusick 	lcmdp->planemask = cmd->planemask;
102053887Smckusick 	lcmdp->ptnBitmap.type = cmd->ptnBitmap.type;
102153887Smckusick 	lcmdp->ptnBitmap.depth = cmd->ptnBitmap.depth;
102253887Smckusick 	lcmdp->ptnBitmap.width = cmd->ptnBitmap.width;
102353887Smckusick 	lcmdp->ptnBitmap.rect.origin.x = cmd->ptnBitmap.rect.origin.x;
102453887Smckusick 	lcmdp->ptnBitmap.rect.origin.y = cmd->ptnBitmap.rect.origin.y;
102553887Smckusick 	lcmdp->ptnBitmap.rect.extent.x = cmd->ptnBitmap.rect.extent.x;
102653887Smckusick 	lcmdp->ptnBitmap.rect.extent.y = cmd->ptnBitmap.rect.extent.y;
102753887Smckusick 	lcmdp->ptnBitmap.base = cmd->ptnBitmap.base;
102853887Smckusick 	lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
102953887Smckusick 	lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
103053887Smckusick 	lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
103153887Smckusick 	lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
103253887Smckusick 	lcmdp->refPoint.x = cmd->refPoint.x;
103353887Smckusick 	lcmdp->refPoint.y = cmd->refPoint.y;
103453887Smckusick 	lcmdp->destBitmap.type = cmd->destBitmap.type;
103553887Smckusick 	lcmdp->destBitmap.depth = cmd->destBitmap.depth;
103653887Smckusick 	lcmdp->destBitmap.width = cmd->destBitmap.width;
103753887Smckusick 	lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
103853887Smckusick 	lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
103953887Smckusick 	lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
104053887Smckusick 	lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
104153887Smckusick 	lcmdp->destBitmap.base = cmd->destBitmap.base;
104253887Smckusick 	lcmdp->destClip.origin.x = cmd->destClip.origin.x;
104353887Smckusick 	lcmdp->destClip.origin.y = cmd->destClip.origin.y;
104453887Smckusick 	lcmdp->destClip.extent.x = cmd->destClip.extent.x;
104553887Smckusick 	lcmdp->destClip.extent.y = cmd->destClip.extent.y;
104653887Smckusick 	lcmdp->destRect.origin.x = cmd->destRect.origin.x;
104753887Smckusick 	lcmdp->destRect.origin.y = cmd->destRect.origin.y;
104853887Smckusick 	lcmdp->destRect.extent.x = cmd->destRect.extent.x;
104953887Smckusick 	lcmdp->destRect.extent.y = cmd->destRect.extent.y;
105053887Smckusick 	return (fbntilebitblt(fbp, lcmdp));
105153887Smckusick }
105253887Smckusick 
105353887Smckusick /* ARGSUSED */
105453887Smckusick fbbitblt3(fbp, cmd)
105553887Smckusick 	struct fbreg *fbp;
105653887Smckusick 	sBitblt3 *cmd;
105753887Smckusick {
105853887Smckusick 	return ENXIO;
105953887Smckusick }
106053887Smckusick 
106153887Smckusick /* ARGSUSED */
106253887Smckusick fbnbitblt3(fbp, cmd)
106353887Smckusick 	struct fbreg *fbp;
106453887Smckusick 	lBitblt3 *cmd;
106553887Smckusick {
106653887Smckusick 	return ENXIO;
106753887Smckusick }
106853887Smckusick 
106953887Smckusick fbnpolyline(fbp, cmd, dj, seg)
107053887Smckusick 	struct fbreg *fbp;
107153887Smckusick 	register lPrimLine *cmd;
107253887Smckusick 	int dj;			/* if not zero, disjoint polyline */
107353887Smckusick 	int seg;
107453887Smckusick {
107553887Smckusick 	register int error = 0;
107653887Smckusick 	register int len;
107753887Smckusick 
107853887Smckusick #ifdef CPU_DOUBLE
107953887Smckusick 	if(cmd->drawBM.type == BM_MEM) {
108053887Smckusick 		return(mfbnpolyline(fbp, cmd, dj, seg));
108153887Smckusick 		/* NOTREACHED */
108253887Smckusick 	}
108353887Smckusick #endif
108453887Smckusick 
108553887Smckusick 	fbinitlock();
108653887Smckusick 	fbp->fb_command = dj ? FB_CDJPOLYLINE : FB_CPOLYLINE;
108753887Smckusick 	fbp->fb_polyline = *cmd;
108853887Smckusick 
108953887Smckusick 	if ((cmd->np & 1) && dj)
109053887Smckusick 		return EINVAL;
109153887Smckusick 
109253887Smckusick #ifdef CPU_SINGLE
109353887Smckusick 	if (error = fblocksbitmap(&fbp->fb_polyline.drawBM, B_READ, fbmap))
109453887Smckusick 		return error;
109553887Smckusick 	if ((len = cmd->np * sizeof(lPoint)) <= 0)
109653887Smckusick 		return EINVAL;
109753887Smckusick 	error = fblockmem((caddr_t)cmd->plist, len, B_WRITE, fbmap + 1, seg);
109853887Smckusick 	if (error)
109953887Smckusick 		return error;
110053887Smckusick 	fbp->fb_polyline.plist = (lPoint *)ipc_phys(fbmap + 1);
110153887Smckusick 
110253887Smckusick 	fbdolock();
110353887Smckusick 	fbstart(fbp, 1);
110453887Smckusick 	fbunlock();
110553887Smckusick #else /* CPU_SINGLE */
110653887Smckusick 	fbp->fb_polyline.plist = (lPoint *)ipc_phys(srcdestlist);
110753887Smckusick 	while (cmd->np > 0) {
110853887Smckusick 		len = min(cmd->np, ((MAX_SIZE / sizeof(lPoint)) & ~1));
110953887Smckusick 		fbp->fb_polyline.np = len;
111053887Smckusick 		if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
111153887Smckusick 				   len * sizeof(lPoint), seg)) {
111253887Smckusick 			return error;
111353887Smckusick 		}
111453887Smckusick 		cmd->np -= len;
111553887Smckusick 		cmd->plist += len;
111653887Smckusick 
111753887Smckusick 		if (fbp->fb_polyline.drawBM.type == BM_MEM) {
111853887Smckusick 			if (error = fblocksbitmap(&fbp->fb_polyline.drawBM,
111953887Smckusick 						  B_READ, fbmap)) {
112053887Smckusick 				return error;
112153887Smckusick 			}
112253887Smckusick 			fbdolock();
112353887Smckusick 			fbstart(fbp, 1);
112453887Smckusick 			fbunlock();
112553887Smckusick 		} else if (cmd->np)
112653887Smckusick 			fbstart(fbp, 1);
112753887Smckusick 		else
112853887Smckusick 			fbstart(fbp, 0);
112953887Smckusick 		if (!dj && cmd->np) {
113053887Smckusick 			cmd->np++;
113153887Smckusick 			cmd->plist--;
113253887Smckusick 		}
113353887Smckusick 	}
113453887Smckusick #endif /* CPU_SINGLE */
113553887Smckusick 	return error;
113653887Smckusick }
113753887Smckusick 
113853887Smckusick fbpolyline(fbp, cmd, dj)
113953887Smckusick 	struct fbreg *fbp;
114053887Smckusick 	register sPrimLine *cmd;
114153887Smckusick 	int dj;
114253887Smckusick {
114353887Smckusick 	lPrimLine lcmd;
114453887Smckusick 	register lPrimLine *lcmdp;
114553887Smckusick 	static lPoint 	pl[100];
114653887Smckusick 	register lPoint *lp;
114753887Smckusick 	register sPoint *sp;
114853887Smckusick 	register int	np;
114953887Smckusick 
115053887Smckusick 	lcmdp = &lcmd;
115153887Smckusick 
115253887Smckusick 	lcmdp->func = cmd->func;
115353887Smckusick 	lcmdp->transp = cmd->transp;
115453887Smckusick 	lcmdp->fore_color = cmd->fore_color;
115553887Smckusick 	lcmdp->aux_color = cmd->aux_color;
115653887Smckusick 	lcmdp->planemask = cmd->planemask;
115753887Smckusick 	lcmdp->drawBM.type = cmd->drawBM.type;
115853887Smckusick 	lcmdp->drawBM.depth = cmd->drawBM.depth;
115953887Smckusick 	lcmdp->drawBM.width = cmd->drawBM.width;
116053887Smckusick 	lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
116153887Smckusick 	lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
116253887Smckusick 	lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
116353887Smckusick 	lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
116453887Smckusick 	lcmdp->drawBM.base = cmd->drawBM.base;
116553887Smckusick 	lcmdp->clip.origin.x = cmd->clip.origin.x;
116653887Smckusick 	lcmdp->clip.origin.y = cmd->clip.origin.y;
116753887Smckusick 	lcmdp->clip.extent.x = cmd->clip.extent.x;
116853887Smckusick 	lcmdp->clip.extent.y = cmd->clip.extent.y;
116953887Smckusick 	lcmdp->lptn = cmd->lptn;
117053887Smckusick 	lcmdp->dlpf = cmd->dlpf;
117153887Smckusick 	lcmdp->plist = pl;
117253887Smckusick 	sp = (sPoint *)cmd->plist;
117353887Smckusick 	while (cmd->np) {
117453887Smckusick 		lcmdp->np = np = min(cmd->np, 100);
117553887Smckusick 		cmd->np -= np;
117653887Smckusick 		lp = pl;
117753887Smckusick 		while (np-- > 0) {
117853887Smckusick 			int error;
117953887Smckusick 			sPoint tmp;
118053887Smckusick 
118153887Smckusick 			if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
118253887Smckusick 				return (error);
118353887Smckusick 			lp->x = tmp.x;
118453887Smckusick 			lp->y = tmp.y;
118553887Smckusick 			lp++;
118653887Smckusick 			sp++;
118753887Smckusick 		}
118853887Smckusick 		fbnpolyline(fbp, lcmdp, dj, UIO_SYSSPACE);
118953887Smckusick 	}
119053887Smckusick }
119153887Smckusick 
119253887Smckusick fbnfillscan(fbp, cmd, seg)
119353887Smckusick 	struct fbreg *fbp;
119453887Smckusick 	register lPrimFill *cmd;
119553887Smckusick 	int seg;
119653887Smckusick {
119753887Smckusick 	register int error;
119853887Smckusick 	register int len;
119953887Smckusick 
120053887Smckusick #ifdef CPU_DOUBLE
120153887Smckusick 	int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
120253887Smckusick 
120353887Smckusick 	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
120453887Smckusick 	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||
120553887Smckusick 	    (blttype == BLTTYPE(BM_1, BM_MEM))) {
120653887Smckusick 		return(mfbnfillscan(fbp, cmd, seg));
120753887Smckusick 		/* NOTREACHED */
120853887Smckusick 	}
120953887Smckusick #endif
121053887Smckusick 
121153887Smckusick 	fbinitlock();
121253887Smckusick 	fbp->fb_command = FB_CFILLSCAN;
121353887Smckusick 	fbp->fb_fillscan = *cmd;
121453887Smckusick 
121553887Smckusick #ifdef CPU_SINGLE
121653887Smckusick 	if (error = fblocksbitmap(&fbp->fb_fillscan.ptnBM, B_WRITE, fbmap))
121753887Smckusick 		return error;
121853887Smckusick 	if (error = fblocksbitmap(&fbp->fb_fillscan.drawBM, B_READ, fbmap + 1))
121953887Smckusick 		return error;
122053887Smckusick 	if ((len = cmd->nscan * sizeof(lScanl)) <= 0)
122153887Smckusick 		return EINVAL;
122253887Smckusick 	if (error = fblockmem(cmd->scan, len, B_WRITE, fbmap + 2, seg))
122353887Smckusick 		return error;
122453887Smckusick 	fbp->fb_fillscan.scan = (lScanl *)ipc_phys(fbmap + 2);
122553887Smckusick 
122653887Smckusick 	fbdolock();
122753887Smckusick 	fbstart(fbp, 1);
122853887Smckusick 	fbunlock();
122953887Smckusick #else /* CPU_SINGLE */
123053887Smckusick 	fbp->fb_fillscan.scan = (lScanl *)ipc_phys(srcdestlist);
123153887Smckusick 	while (cmd->nscan > 0) {
123253887Smckusick 		len = min(cmd->nscan, (MAX_SIZE / sizeof(lScanl)));
123353887Smckusick 		fbp->fb_fillscan.nscan = len;
123453887Smckusick 		if (error = COPYIN((caddr_t)cmd->scan, (caddr_t)srcdestlist,
123553887Smckusick 				   len * sizeof(lScanl), seg)) {
123653887Smckusick 			return error;
123753887Smckusick 		}
123853887Smckusick 		cmd->nscan -= len;
123953887Smckusick 		cmd->scan += len;
124053887Smckusick 		if (fbp->fb_fillscan.ptnBM.type == BM_MEM ||
124153887Smckusick 		    fbp->fb_fillscan.drawBM.type == BM_MEM) {
124253887Smckusick 
124353887Smckusick 			if (error = fblocksbitmap(&fbp->fb_fillscan.ptnBM,
124453887Smckusick 						  B_WRITE, fbmap)) {
124553887Smckusick 				return error;
124653887Smckusick 			}
124753887Smckusick 			if (error = fblocksbitmap(&fbp->fb_fillscan.drawBM,
124853887Smckusick 						  B_READ, fbmap + 1)) {
124953887Smckusick 				return error;
125053887Smckusick 			}
125153887Smckusick 
125253887Smckusick 			fbdolock();
125353887Smckusick 			fbstart(fbp, 1);
125453887Smckusick 			fbunlock();
125553887Smckusick 		} else if (cmd->nscan)
125653887Smckusick 			fbstart(fbp, 1);
125753887Smckusick 		else
125853887Smckusick 			fbstart(fbp, 0);
125953887Smckusick 	}
126053887Smckusick #endif /* CPU_SINGLE */
126153887Smckusick 	return error;
126253887Smckusick }
126353887Smckusick 
126453887Smckusick fbfillscan(fbp, cmd)
126553887Smckusick 	struct fbreg *fbp;
126653887Smckusick 	register sPrimFill *cmd;
126753887Smckusick {
126853887Smckusick 	lPrimFill lcmd;
126953887Smckusick 	register lPrimFill *lcmdp;
127053887Smckusick 	static lScanl	ls[100];
127153887Smckusick 	register lScanl	*lp;
127253887Smckusick 	register sScanl	*sp;
127353887Smckusick 	register int	ns;
127453887Smckusick 
127553887Smckusick 	lcmdp = &lcmd;
127653887Smckusick 	lcmdp->func = cmd->func;
127753887Smckusick 	lcmdp->transp = cmd->transp;
127853887Smckusick 	lcmdp->fore_color = cmd->fore_color;
127953887Smckusick 	lcmdp->aux_color = cmd->aux_color;
128053887Smckusick 	lcmdp->planemask = cmd->planemask;
128153887Smckusick 	lcmdp->refPoint.x = cmd->refPoint.x;
128253887Smckusick 	lcmdp->refPoint.y = cmd->refPoint.y;
128353887Smckusick 	lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
128453887Smckusick 	lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
128553887Smckusick 	lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
128653887Smckusick 	lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
128753887Smckusick 	lcmdp->ptnBM.type = cmd->ptnBM.type;
128853887Smckusick 	lcmdp->ptnBM.depth = cmd->ptnBM.depth;
128953887Smckusick 	lcmdp->ptnBM.width = cmd->ptnBM.width;
129053887Smckusick 	lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
129153887Smckusick 	lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
129253887Smckusick 	lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
129353887Smckusick 	lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
129453887Smckusick 	lcmdp->ptnBM.base = cmd->ptnBM.base;
129553887Smckusick 	lcmdp->drawBM.type = cmd->drawBM.type;
129653887Smckusick 	lcmdp->drawBM.depth = cmd->drawBM.depth;
129753887Smckusick 	lcmdp->drawBM.width = cmd->drawBM.width;
129853887Smckusick 	lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
129953887Smckusick 	lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
130053887Smckusick 	lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
130153887Smckusick 	lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
130253887Smckusick 	lcmdp->drawBM.base = cmd->drawBM.base;
130353887Smckusick 	lcmdp->clip.origin.x = cmd->clip.origin.x;
130453887Smckusick 	lcmdp->clip.origin.y = cmd->clip.origin.y;
130553887Smckusick 	lcmdp->clip.extent.x = cmd->clip.extent.x;
130653887Smckusick 	lcmdp->clip.extent.y = cmd->clip.extent.y;
130753887Smckusick 	lcmdp->scan = ls;
130853887Smckusick 	sp = (sScanl *)cmd->scan;
130953887Smckusick 	while (cmd->nscan) {
131053887Smckusick 		lcmdp->nscan = ns = min(cmd->nscan, 100);
131153887Smckusick 		cmd->nscan -= ns;
131253887Smckusick 		lp = ls;
131353887Smckusick 		while (ns-- > 0) {
131453887Smckusick 			int error;
131553887Smckusick 			sScanl tmp;
131653887Smckusick 
131753887Smckusick 			if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
131853887Smckusick 				return (error);
131953887Smckusick 			lp->x0 = tmp.x0;
132053887Smckusick 			lp->x1 = tmp.x1;
132153887Smckusick 			lp->y = tmp.y;
132253887Smckusick 			lp++;
132353887Smckusick 			sp++;
132453887Smckusick 		}
132553887Smckusick 		fbnfillscan(fbp, lcmdp, UIO_SYSSPACE);
132653887Smckusick 	}
132753887Smckusick }
132853887Smckusick 
132953887Smckusick fbnrectangle(fbp, cmd)
133053887Smckusick 	struct fbreg *fbp;
133153887Smckusick 	register lPrimRect *cmd;
133253887Smckusick {
133353887Smckusick 	register int error = 0;
133453887Smckusick 
133553887Smckusick #ifdef CPU_DOUBLE
133653887Smckusick 	int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
133753887Smckusick 
133853887Smckusick 	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
133953887Smckusick 	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||
134053887Smckusick 	    (blttype == BLTTYPE(BM_1, BM_MEM))) {
134153887Smckusick 		return(mfbnrectangle(fbp, cmd));
134253887Smckusick 		/* NOTREACHED */
134353887Smckusick 	}
134453887Smckusick #endif /* CPU_DOUBLE */
134553887Smckusick 
134653887Smckusick 	fbinitlock();
134753887Smckusick 	fbp->fb_command = FB_CRECTANGLE;
134853887Smckusick 	fbp->fb_rectangle = *cmd;
134953887Smckusick 
135053887Smckusick 	if (error = fblocksbitmap(&fbp->fb_rectangle.drawBM, B_READ, fbmap))
135153887Smckusick 		return error;
135253887Smckusick 	if (error = fblocksbitmap(&fbp->fb_rectangle.ptnBM, B_WRITE, fbmap + 1))
135353887Smckusick 		return error;
135453887Smckusick 
135553887Smckusick 	if (fbp->fb_rectangle.drawBM.type == BM_MEM ||
135653887Smckusick 	    fbp->fb_rectangle.ptnBM.type == BM_MEM) {
135753887Smckusick 		fbdolock();
135853887Smckusick 		fbstart(fbp, 1);
135953887Smckusick 		fbunlock();
136053887Smckusick 	} else {
136153887Smckusick 		fbstart(fbp, 0);
136253887Smckusick 	}
136353887Smckusick 
136453887Smckusick 	return error;
136553887Smckusick }
136653887Smckusick 
136753887Smckusick fbrectangle(fbp, cmd)
136853887Smckusick 	struct fbreg *fbp;
136953887Smckusick 	register sPrimRect *cmd;
137053887Smckusick {
137153887Smckusick 	lPrimRect lcmd;
137253887Smckusick 	register lPrimRect *lcmdp;
137353887Smckusick 
137453887Smckusick 	lcmdp = &lcmd;
137553887Smckusick 
137653887Smckusick 	lcmdp->func = cmd->func;
137753887Smckusick 	lcmdp->transp = cmd->transp;
137853887Smckusick 	lcmdp->fore_color = cmd->fore_color;
137953887Smckusick 	lcmdp->aux_color = cmd->aux_color;
138053887Smckusick 	lcmdp->planemask = cmd->planemask;
138153887Smckusick 	lcmdp->rect.origin.x = cmd->rect.origin.x;
138253887Smckusick 	lcmdp->rect.origin.y = cmd->rect.origin.y;
138353887Smckusick 	lcmdp->rect.extent.x = cmd->rect.extent.x;
138453887Smckusick 	lcmdp->rect.extent.y = cmd->rect.extent.y;
138553887Smckusick 	lcmdp->refPoint.x = cmd->refPoint.x;
138653887Smckusick 	lcmdp->refPoint.y = cmd->refPoint.y;
138753887Smckusick 	lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
138853887Smckusick 	lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
138953887Smckusick 	lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
139053887Smckusick 	lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
139153887Smckusick 	lcmdp->ptnBM.type = cmd->ptnBM.type;
139253887Smckusick 	lcmdp->ptnBM.depth = cmd->ptnBM.depth;
139353887Smckusick 	lcmdp->ptnBM.width = cmd->ptnBM.width;
139453887Smckusick 	lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
139553887Smckusick 	lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
139653887Smckusick 	lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
139753887Smckusick 	lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
139853887Smckusick 	lcmdp->ptnBM.base = cmd->ptnBM.base;
139953887Smckusick 	lcmdp->drawBM.type = cmd->drawBM.type;
140053887Smckusick 	lcmdp->drawBM.depth = cmd->drawBM.depth;
140153887Smckusick 	lcmdp->drawBM.width = cmd->drawBM.width;
140253887Smckusick 	lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
140353887Smckusick 	lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
140453887Smckusick 	lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
140553887Smckusick 	lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
140653887Smckusick 	lcmdp->drawBM.base = cmd->drawBM.base;
140753887Smckusick 	lcmdp->clip.origin.x = cmd->clip.origin.x;
140853887Smckusick 	lcmdp->clip.origin.y = cmd->clip.origin.y;
140953887Smckusick 	lcmdp->clip.extent.x = cmd->clip.extent.x;
141053887Smckusick 	lcmdp->clip.extent.y = cmd->clip.extent.y;
141153887Smckusick 	return (fbnrectangle(fbp, lcmdp));
141253887Smckusick }
141353887Smckusick 
fbnpolymarker(fbp,cmd,seg)141453887Smckusick fbnpolymarker(fbp, cmd, seg)
141553887Smckusick 	register struct fbreg *fbp;
141653887Smckusick 	register lPrimMarker *cmd;
141753887Smckusick 	int seg;
141853887Smckusick {
141953887Smckusick 	register int error;
142053887Smckusick 	register int len;
142153887Smckusick 
142253887Smckusick #ifdef CPU_DOUBLE
142353887Smckusick 	int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
142453887Smckusick 
142553887Smckusick 	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
142653887Smckusick 	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||
142753887Smckusick 	    (blttype == BLTTYPE(BM_1, BM_MEM))) {
142853887Smckusick 		return(mfbnpolymarker(fbp, cmd, seg));
142953887Smckusick 		/* NOTREACHED */
143053887Smckusick 	}
143153887Smckusick #endif /* CPU_DOUBLE */
143253887Smckusick 
143353887Smckusick 	fbinitlock();
143453887Smckusick 	fbp->fb_command = FB_CPOLYMARKER;
143553887Smckusick 	fbp->fb_polymarker = *cmd;
143653887Smckusick 
143753887Smckusick #ifdef CPU_SINGLE
143853887Smckusick 	if (error = fblocksbitmap(&fbp->fb_polymarker.ptnBM, B_WRITE, fbmap))
143953887Smckusick 		return error;
144053887Smckusick 	if (error = fblocksbitmap(&fbp->fb_polymarker.drawBM, B_READ, fbmap+1))
144153887Smckusick 		return error;
144253887Smckusick 	if ((len = cmd->np * sizeof(lPoint)) <= 0)
144353887Smckusick 		return EINVAL;
144453887Smckusick 	if (error = fblockmem(cmd->plist, len, B_WRITE, fbmap + 2, seg))
144553887Smckusick 		return error;
144653887Smckusick 	fbp->fb_polymarker.plist = (lPoint *)ipc_phys(fbmap + 2);
144753887Smckusick 
144853887Smckusick 	fbdolock();
144953887Smckusick 	fbstart(fbp, 1);
145053887Smckusick 	fbunlock();
145153887Smckusick #else /* CPU_SINGLE */
145253887Smckusick 	fbp->fb_polymarker.plist = (lPoint *)ipc_phys(srcdestlist);
145353887Smckusick 	while (cmd->np > 0) {
145453887Smckusick 		len = min(cmd->np, (MAX_SIZE / sizeof(lPoint)));
145553887Smckusick 		fbp->fb_polymarker.np = len;
145653887Smckusick 		if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
145753887Smckusick 				   len * sizeof(lPoint), seg)) {
145853887Smckusick 			return error;
145953887Smckusick 		}
146053887Smckusick 		cmd->np -= len;
146153887Smckusick 		cmd->plist += len;
146253887Smckusick 
146353887Smckusick 		if (fbp->fb_polymarker.ptnBM.type == BM_MEM ||
146453887Smckusick 		    fbp->fb_polymarker.drawBM.type == BM_MEM) {
146553887Smckusick 
146653887Smckusick 			if (error = fblocksbitmap(&fbp->fb_polymarker.ptnBM,
146753887Smckusick 						  B_WRITE, fbmap)) {
146853887Smckusick 				return error;
146953887Smckusick 			}
147053887Smckusick 			if (error = fblocksbitmap(&fbp->fb_polymarker.drawBM,
147153887Smckusick 						  B_READ, fbmap + 1)) {
147253887Smckusick 				return error;
147353887Smckusick 			}
147453887Smckusick 
147553887Smckusick 			fbdolock();
147653887Smckusick 			fbstart(fbp, 1);
147753887Smckusick 			fbunlock();
147853887Smckusick 		} else if (cmd->np)
147953887Smckusick 			fbstart(fbp, 1);
148053887Smckusick 		else
148153887Smckusick 			fbstart(fbp, 0);
148253887Smckusick 	}
148353887Smckusick #endif /* CPU_SINGLE */
148453887Smckusick 	return error;
148553887Smckusick }
148653887Smckusick 
148753887Smckusick fbpolymarker(fbp, cmd)
148853887Smckusick 	struct fbreg *fbp;
148953887Smckusick 	register sPrimMarker *cmd;
149053887Smckusick {
149153887Smckusick 	lPrimMarker lcmd;
149253887Smckusick 	register lPrimMarker *lcmdp;
149353887Smckusick 	static lPoint pl[100];
149453887Smckusick 	register lPoint *lp;
149553887Smckusick 	register sPoint *sp;
149653887Smckusick 	register int np;
149753887Smckusick 
149853887Smckusick 	lcmdp = &lcmd;
149953887Smckusick 	lcmdp->func = cmd->func;
150053887Smckusick 	lcmdp->transp = cmd->transp;
150153887Smckusick 	lcmdp->fore_color = cmd->fore_color;
150253887Smckusick 	lcmdp->aux_color = cmd->aux_color;
150353887Smckusick 	lcmdp->planemask = cmd->planemask;
150453887Smckusick 	lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
150553887Smckusick 	lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
150653887Smckusick 	lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
150753887Smckusick 	lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
150853887Smckusick 	lcmdp->ptnBM.type = cmd->ptnBM.type;
150953887Smckusick 	lcmdp->ptnBM.depth = cmd->ptnBM.depth;
151053887Smckusick 	lcmdp->ptnBM.width = cmd->ptnBM.width;
151153887Smckusick 	lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
151253887Smckusick 	lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
151353887Smckusick 	lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
151453887Smckusick 	lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
151553887Smckusick 	lcmdp->ptnBM.base = cmd->ptnBM.base;
151653887Smckusick 	lcmdp->drawBM.type = cmd->drawBM.type;
151753887Smckusick 	lcmdp->drawBM.depth = cmd->drawBM.depth;
151853887Smckusick 	lcmdp->drawBM.width = cmd->drawBM.width;
151953887Smckusick 	lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
152053887Smckusick 	lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
152153887Smckusick 	lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
152253887Smckusick 	lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
152353887Smckusick 	lcmdp->drawBM.base = cmd->drawBM.base;
152453887Smckusick 	lcmdp->clip.origin.x = cmd->clip.origin.x;
152553887Smckusick 	lcmdp->clip.origin.y = cmd->clip.origin.y;
152653887Smckusick 	lcmdp->clip.extent.x = cmd->clip.extent.x;
152753887Smckusick 	lcmdp->clip.extent.y = cmd->clip.extent.y;
152853887Smckusick 	lcmdp->plist = pl;
152953887Smckusick 	sp = (sPoint *)cmd->plist;
153053887Smckusick 	while (cmd->np) {
153153887Smckusick 		lcmdp->np = np = min(cmd->np, 100);
153253887Smckusick 		cmd->np -= np;
153353887Smckusick 		while (np-- > 0) {
153453887Smckusick 			int error;
153553887Smckusick 			sPoint tmp;
153653887Smckusick 
153753887Smckusick 			if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
153853887Smckusick 				return (error);
153953887Smckusick 			lp->x = tmp.x;
154053887Smckusick 			lp->y = tmp.y;
154153887Smckusick 			lp++;
154253887Smckusick 			sp++;
154353887Smckusick 		}
154453887Smckusick 		fbnpolymarker(fbp, lcmdp, UIO_SYSSPACE);
154553887Smckusick 	}
154653887Smckusick }
154753887Smckusick 
fbnpolydot(fbp,cmd,seg)154853887Smckusick fbnpolydot(fbp, cmd, seg)
154953887Smckusick 	register struct fbreg *fbp;
155053887Smckusick 	register lPrimDot *cmd;
155153887Smckusick 	int seg;
155253887Smckusick {
155353887Smckusick 	register int error;
155453887Smckusick 	register int len;
155553887Smckusick 
155653887Smckusick #ifdef CPU_DOUBLE
155753887Smckusick 	if (cmd->drawBM.type == BM_MEM)
155853887Smckusick 		return (mfbnpolydot(fbp, cmd, seg));
155953887Smckusick #endif
156053887Smckusick 
156153887Smckusick 	fbinitlock();
156253887Smckusick 	fbp->fb_command = FB_CPOLYDOT;
156353887Smckusick 	fbp->fb_polydot = *cmd;
156453887Smckusick 
156553887Smckusick #ifdef CPU_SINGLE
156653887Smckusick 	if (error = fblocksbitmap(&fbp->fb_polydot.drawBM, B_READ, fbmap + 1))
156753887Smckusick 		return error;
156853887Smckusick 	if ((len = cmd->np * sizeof(lPoint)) <= 0)
156953887Smckusick 		return EINVAL;
157053887Smckusick 	if (error = fblockmem(cmd->plist, len, B_WRITE, fbmap + 2, seg))
157153887Smckusick 		return error;
157253887Smckusick 	fbp->fb_polydot.plist = (lPoint *)ipc_phys(fbmap + 2);
157353887Smckusick 
157453887Smckusick 	fbdolock();
157553887Smckusick 	fbstart(fbp, 1);
157653887Smckusick 	fbunlock();
157753887Smckusick #else /* CPU_SINGLE */
157853887Smckusick 	fbp->fb_polydot.plist = (lPoint *)ipc_phys(srcdestlist);
157953887Smckusick 	while (cmd->np > 0) {
158053887Smckusick 		len = min(cmd->np, (MAX_SIZE / sizeof(lPoint)));
158153887Smckusick 		fbp->fb_polydot.np = len;
158253887Smckusick 		if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
158353887Smckusick 				   len * sizeof(lPoint), seg)) {
158453887Smckusick 			return error;
158553887Smckusick 		}
158653887Smckusick 		cmd->np -= len;
158753887Smckusick 		cmd->plist += len;
158853887Smckusick 
158953887Smckusick 		if (fbp->fb_polydot.drawBM.type == BM_MEM) {
159053887Smckusick 			if (error = fblocksbitmap(&fbp->fb_polydot.drawBM,
159153887Smckusick 						  B_READ, fbmap + 1)) {
159253887Smckusick 				return error;
159353887Smckusick 			}
159453887Smckusick 
159553887Smckusick 			fbdolock();
159653887Smckusick 			fbstart(fbp, 1);
159753887Smckusick 			fbunlock();
159853887Smckusick 		} else if (cmd->np)
159953887Smckusick 			fbstart(fbp, 1);
160053887Smckusick 		else
160153887Smckusick 			fbstart(fbp, 0);
160253887Smckusick 	}
160353887Smckusick #endif /* CPU_SINGLE */
160453887Smckusick 	return error;
160553887Smckusick }
160653887Smckusick 
160753887Smckusick fbpolydot(fbp, cmd)
160853887Smckusick 	struct fbreg *fbp;
160953887Smckusick 	register sPrimDot *cmd;
161053887Smckusick {
161153887Smckusick 	lPrimDot lcmd;
161253887Smckusick 	register lPrimDot *lcmdp;
161353887Smckusick 	static lPoint	pl[100];
161453887Smckusick 	register lPoint	*lp;
161553887Smckusick 	register sPoint	*sp;
161653887Smckusick 	register int	np;
161753887Smckusick 
161853887Smckusick 	lcmdp = &lcmd;
161953887Smckusick 	lcmdp->func = cmd->func;
162053887Smckusick 	lcmdp->transp = cmd->transp;
162153887Smckusick 	lcmdp->fore_color = cmd->fore_color;
162253887Smckusick 	lcmdp->aux_color = cmd->aux_color;
162353887Smckusick 	lcmdp->planemask = cmd->planemask;
162453887Smckusick 	lcmdp->drawBM.type = cmd->drawBM.type;
162553887Smckusick 	lcmdp->drawBM.depth = cmd->drawBM.depth;
162653887Smckusick 	lcmdp->drawBM.width = cmd->drawBM.width;
162753887Smckusick 	lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
162853887Smckusick 	lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
162953887Smckusick 	lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
163053887Smckusick 	lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
163153887Smckusick 	lcmdp->drawBM.base = cmd->drawBM.base;
163253887Smckusick 	lcmdp->clip.origin.x = cmd->clip.origin.x;
163353887Smckusick 	lcmdp->clip.origin.y = cmd->clip.origin.y;
163453887Smckusick 	lcmdp->clip.extent.x = cmd->clip.extent.x;
163553887Smckusick 	lcmdp->clip.extent.y = cmd->clip.extent.y;
163653887Smckusick 	lcmdp->plist = pl;
163753887Smckusick 	sp = (sPoint *)cmd->plist;
163853887Smckusick 	while (cmd->np) {
163953887Smckusick 		lcmdp->np = np = min(cmd->np, 100);
164053887Smckusick 		cmd->np -= np;
164153887Smckusick 		while (np-- > 0) {
164253887Smckusick 			int error;
164353887Smckusick 			sPoint tmp;
164453887Smckusick 
164553887Smckusick 			if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
164653887Smckusick 				return (error);
164753887Smckusick 			lp->x = tmp.x;
164853887Smckusick 			lp->y = tmp.y;
164953887Smckusick 			lp++;
165053887Smckusick 			sp++;
165153887Smckusick 		}
165253887Smckusick 		fbnpolydot(fbp, lcmdp, UIO_SYSSPACE);
165353887Smckusick 	}
165453887Smckusick }
165553887Smckusick 
fbntext(fbp,cmd)165653887Smckusick fbntext(fbp, cmd)
165753887Smckusick 	register struct fbreg *fbp;
165853887Smckusick 	register lPrimText *cmd;
165953887Smckusick {
166053887Smckusick 	register int error;
166153887Smckusick 
166253887Smckusick #ifdef CPU_DOUBLE
166353887Smckusick 	int blttype = BLTTYPE(cmd->fontBM.type, cmd->drawBM.type);
166453887Smckusick 
166553887Smckusick 	if ((cmd->type == ASCII) &&
166653887Smckusick 	    ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
166753887Smckusick 	     (blttype == BLTTYPE(BM_0, BM_MEM)) ||
166853887Smckusick 	     (blttype == BLTTYPE(BM_1, BM_MEM)))
166953887Smckusick 	) {
167053887Smckusick 		return(mfbntext(fbp, cmd));
167153887Smckusick 		/* NOTREACHED */
167253887Smckusick 	}
167353887Smckusick #endif /* CPU_DOUBLE */
167453887Smckusick 
167553887Smckusick 	fbinitlock();
167653887Smckusick 	fbp->fb_command = FB_CTEXT;
167753887Smckusick 	fbp->fb_text = *cmd;
167853887Smckusick 
167953887Smckusick 
168053887Smckusick 	if (error = fblocksbitmap(&fbp->fb_text.drawBM, B_READ, fbmap))
168153887Smckusick 		return error;
168253887Smckusick 
168353887Smckusick 	if (cmd->type == ASCII) {
168453887Smckusick 		if (error = fblocksbitmap(&fbp->fb_text.fontBM,
168553887Smckusick 					  B_WRITE, fbmap + 1)) {
168653887Smckusick 			return error;
168753887Smckusick 		}
168853887Smckusick 	}
168953887Smckusick 
169053887Smckusick #ifdef CPU_SINGLE
169153887Smckusick 	if (error = fblockmem(cmd->str, cmd->len, B_WRITE, fbmap + 2, UIO_USERSPACE))
169253887Smckusick 		return error;
169353887Smckusick 	fbp->fb_text.str = (unsigned char *)ipc_phys(fbmap + 2);
169453887Smckusick 
169553887Smckusick 	fbdolock();
169653887Smckusick 	fbstart(fbp, 1);
169753887Smckusick 	fbunlock();
169853887Smckusick #else /* CPU_SINGLE */
169953887Smckusick 	fbp->fb_text.str = (unsigned char *)ipc_phys(srcdestlist);
170053887Smckusick 	if (error = COPYIN((caddr_t)cmd->str,
170153887Smckusick 			   (caddr_t)srcdestlist, cmd->len, UIO_USERSPACE)) {
170253887Smckusick 		return error;
170353887Smckusick 	}
170453887Smckusick 
170553887Smckusick 	if (fbp->fb_text.drawBM.type == BM_MEM ||
170653887Smckusick 	    (cmd->type == ASCII && fbp->fb_text.fontBM.type == BM_MEM)) {
170753887Smckusick 		fbdolock();
170853887Smckusick 		fbstart(fbp, 1);
170953887Smckusick 		fbunlock();
171053887Smckusick 	} else
171153887Smckusick 		fbstart(fbp, 0);
171253887Smckusick #endif /* CPU_SINGLE */
171353887Smckusick 	return error;
171453887Smckusick }
171553887Smckusick 
171653887Smckusick fbtext(fbp, cmd)
171753887Smckusick 	struct fbreg *fbp;
171853887Smckusick 	register sPrimText *cmd;
171953887Smckusick {
172053887Smckusick 	lPrimText lcmd;
172153887Smckusick 	register lPrimText *lcmdp;
172253887Smckusick 
172353887Smckusick 	lcmdp = &lcmd;
172453887Smckusick 
172553887Smckusick 	lcmdp->func = cmd->func;
172653887Smckusick 	lcmdp->transp = cmd->transp;
172753887Smckusick 	lcmdp->fore_color = cmd->fore_color;
172853887Smckusick 	lcmdp->aux_color = cmd->aux_color;
172953887Smckusick 	lcmdp->planemask = cmd->planemask;
173053887Smckusick 	lcmdp->type = cmd->type;
173153887Smckusick 	lcmdp->p.x = cmd->p.x;
173253887Smckusick 	lcmdp->p.y = cmd->p.y;
173353887Smckusick 	lcmdp->dx = cmd->dx;
173453887Smckusick 	lcmdp->dy = cmd->dy;
173553887Smckusick 	lcmdp->ex_factor = cmd->ex_factor;
173653887Smckusick 	lcmdp->fp.x = cmd->fp.x;
173753887Smckusick 	lcmdp->fp.y = cmd->fp.y;
173853887Smckusick 	lcmdp->width = cmd->width;
173953887Smckusick 	lcmdp->height = cmd->height;
174053887Smckusick 	lcmdp->column = cmd->column;
174153887Smckusick 	lcmdp->first_chr = cmd->first_chr;
174253887Smckusick 	lcmdp->last_chr = cmd->last_chr;
174353887Smckusick 	lcmdp->fontBM.type = cmd->fontBM.type;
174453887Smckusick 	lcmdp->fontBM.depth = cmd->fontBM.depth;
174553887Smckusick 	lcmdp->fontBM.width = cmd->fontBM.width;
174653887Smckusick 	lcmdp->fontBM.rect.origin.x = cmd->fontBM.rect.origin.x;
174753887Smckusick 	lcmdp->fontBM.rect.origin.y = cmd->fontBM.rect.origin.y;
174853887Smckusick 	lcmdp->fontBM.rect.extent.x = cmd->fontBM.rect.extent.x;
174953887Smckusick 	lcmdp->fontBM.rect.extent.y = cmd->fontBM.rect.extent.y;
175053887Smckusick 	lcmdp->fontBM.base = cmd->fontBM.base;
175153887Smckusick 	lcmdp->drawBM.type = cmd->drawBM.type;
175253887Smckusick 	lcmdp->drawBM.depth = cmd->drawBM.depth;
175353887Smckusick 	lcmdp->drawBM.width = cmd->drawBM.width;
175453887Smckusick 	lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
175553887Smckusick 	lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
175653887Smckusick 	lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
175753887Smckusick 	lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
175853887Smckusick 	lcmdp->drawBM.base = cmd->drawBM.base;
175953887Smckusick 	lcmdp->clip.origin.x = cmd->clip.origin.x;
176053887Smckusick 	lcmdp->clip.origin.y = cmd->clip.origin.y;
176153887Smckusick 	lcmdp->clip.extent.x = cmd->clip.extent.x;
176253887Smckusick 	lcmdp->clip.extent.y = cmd->clip.extent.y;
176353887Smckusick 	lcmdp->len = cmd->len;
176453887Smckusick 	lcmdp->str = cmd->str;
176553887Smckusick 	return (fbntext(fbp, lcmdp));
176653887Smckusick }
176753887Smckusick 
176853887Smckusick fbsetcursor(fbp, data)
176953887Smckusick 	struct fbreg *fbp;
177053887Smckusick 	sCursor	*data;
177153887Smckusick {
177253887Smckusick 	register struct fbreg *fbregp;
177353887Smckusick 
177453887Smckusick 	fbregp = fbp;
177553887Smckusick 
177653887Smckusick 	fbregp->fb_command = FB_CSETCURSOR;
177753887Smckusick 	fbregp->fb_cursor.func = data->func;
177853887Smckusick 	fbregp->fb_cursor.cursor_color = data->cursor_color;
177953887Smckusick 	fbregp->fb_cursor.mask_color = data->mask_color;
178053887Smckusick 	fbregp->fb_cursor.hot.x = data->hot.x;
178153887Smckusick 	fbregp->fb_cursor.hot.y = data->hot.y;
178253887Smckusick 	fbregp->fb_cursor.size.x = data->size.x;
178353887Smckusick 	fbregp->fb_cursor.size.y = data->size.y;
178453887Smckusick 	fbregp->fb_cursor.cursorRect.origin.x = data->cursorRect.origin.x;
178553887Smckusick 	fbregp->fb_cursor.cursorRect.origin.y = data->cursorRect.origin.y;
178653887Smckusick 	fbregp->fb_cursor.cursorRect.extent.x = data->cursorRect.extent.x;
178753887Smckusick 	fbregp->fb_cursor.cursorRect.extent.y = data->cursorRect.extent.y;
178853887Smckusick 	fbregp->fb_cursor.maskRect.origin.x = data->maskRect.origin.x;
178953887Smckusick 	fbregp->fb_cursor.maskRect.origin.y = data->maskRect.origin.y;
179053887Smckusick 	fbregp->fb_cursor.maskRect.extent.x = data->maskRect.extent.x;
179153887Smckusick 	fbregp->fb_cursor.maskRect.extent.y = data->maskRect.extent.y;
179253887Smckusick 	fbregp->fb_cursor.saveRect.origin.x = data->saveRect.origin.x;
179353887Smckusick 	fbregp->fb_cursor.saveRect.origin.y = data->saveRect.origin.y;
179453887Smckusick 	fbregp->fb_cursor.saveRect.extent.x = data->saveRect.extent.x;
179553887Smckusick 	fbregp->fb_cursor.saveRect.extent.y = data->saveRect.extent.y;
179653887Smckusick 	fbregp->fb_cursor.moveArea.origin.x = data->moveArea.origin.x;
179753887Smckusick 	fbregp->fb_cursor.moveArea.origin.y = data->moveArea.origin.y;
179853887Smckusick 	fbregp->fb_cursor.moveArea.extent.x = data->moveArea.extent.x;
179953887Smckusick 	fbregp->fb_cursor.moveArea.extent.y = data->moveArea.extent.y;
180053887Smckusick 	fbstart(fbp, 0);
180153887Smckusick 	return 0;
180253887Smckusick }
180353887Smckusick 
180453887Smckusick fbnsetcursor(fbp, data)
180553887Smckusick 	struct fbreg *fbp;
180653887Smckusick 	lCursor	*data;
180753887Smckusick {
180853887Smckusick 	register struct fbreg *fbregp;
180953887Smckusick 
181053887Smckusick 	fbregp = fbp;
181153887Smckusick 
181253887Smckusick 	fbregp->fb_command = FB_CSETCURSOR;
181353887Smckusick 	fbregp->fb_cursor.func = data->func;
181453887Smckusick 	fbregp->fb_cursor.cursor_color = data->cursor_color;
181553887Smckusick 	fbregp->fb_cursor.mask_color = data->mask_color;
181653887Smckusick 	fbregp->fb_cursor.hot.x = data->hot.x;
181753887Smckusick 	fbregp->fb_cursor.hot.y = data->hot.y;
181853887Smckusick 	fbregp->fb_cursor.size.x = data->size.x;
181953887Smckusick 	fbregp->fb_cursor.size.y = data->size.y;
182053887Smckusick 	fbregp->fb_cursor.cursorRect.origin.x = data->cursorRect.origin.x;
182153887Smckusick 	fbregp->fb_cursor.cursorRect.origin.y = data->cursorRect.origin.y;
182253887Smckusick 	fbregp->fb_cursor.cursorRect.extent.x = data->cursorRect.extent.x;
182353887Smckusick 	fbregp->fb_cursor.cursorRect.extent.y = data->cursorRect.extent.y;
182453887Smckusick 	fbregp->fb_cursor.maskRect.origin.x = data->maskRect.origin.x;
182553887Smckusick 	fbregp->fb_cursor.maskRect.origin.y = data->maskRect.origin.y;
182653887Smckusick 	fbregp->fb_cursor.maskRect.extent.x = data->maskRect.extent.x;
182753887Smckusick 	fbregp->fb_cursor.maskRect.extent.y = data->maskRect.extent.y;
182853887Smckusick 	fbregp->fb_cursor.saveRect.origin.x = data->saveRect.origin.x;
182953887Smckusick 	fbregp->fb_cursor.saveRect.origin.y = data->saveRect.origin.y;
183053887Smckusick 	fbregp->fb_cursor.saveRect.extent.x = data->saveRect.extent.x;
183153887Smckusick 	fbregp->fb_cursor.saveRect.extent.y = data->saveRect.extent.y;
183253887Smckusick 	fbregp->fb_cursor.moveArea.origin.x = data->moveArea.origin.x;
183353887Smckusick 	fbregp->fb_cursor.moveArea.origin.y = data->moveArea.origin.y;
183453887Smckusick 	fbregp->fb_cursor.moveArea.extent.x = data->moveArea.extent.x;
183553887Smckusick 	fbregp->fb_cursor.moveArea.extent.y = data->moveArea.extent.y;
183653887Smckusick 	fbstart(fbp, 0);
183753887Smckusick 	return 0;
183853887Smckusick }
183953887Smckusick 
184053887Smckusick fbgetscrtype(fbp, data)
184153887Smckusick 	struct fbreg *fbp;
184253887Smckusick 	sScrType *data;
184353887Smckusick {
184453887Smckusick 	fbp->fb_command = FB_CGETSCRTYPE;
184553887Smckusick 	fbstart(fbp, 1);
184653887Smckusick 	data->colorwidth = fbp->fb_scrtype.colorwidth;
184753887Smckusick 	data->plane = fbp->fb_scrtype.plane;
184853887Smckusick 	data->bufferrect.origin.x = fbp->fb_scrtype.bufferrect.origin.x;
184953887Smckusick 	data->bufferrect.origin.y = fbp->fb_scrtype.bufferrect.origin.y;
185053887Smckusick 	data->bufferrect.extent.x = fbp->fb_scrtype.bufferrect.extent.x;
185153887Smckusick 	data->bufferrect.extent.y = fbp->fb_scrtype.bufferrect.extent.y;
185253887Smckusick 	data->visiblerect.origin.x = fbp->fb_scrtype.visiblerect.origin.x;
185353887Smckusick 	data->visiblerect.origin.y = fbp->fb_scrtype.visiblerect.origin.y;
185453887Smckusick 	data->visiblerect.extent.x = fbp->fb_scrtype.visiblerect.extent.x;
185553887Smckusick 	data->visiblerect.extent.y = fbp->fb_scrtype.visiblerect.extent.y;
185653887Smckusick 	return 0;
185753887Smckusick }
185853887Smckusick 
185953887Smckusick fbsetxy(fbp, data)
186053887Smckusick 	struct fbreg *fbp;
186153887Smckusick 	sPoint *data;
186253887Smckusick {
186353887Smckusick 	fbp->fb_command = FB_CSETXY;
186453887Smckusick 	fbp->fb_point.x = data->x;
186553887Smckusick 	fbp->fb_point.y = data->y;
186653887Smckusick 	fbstart(fbp, 0);
186753887Smckusick 	return 0;
186853887Smckusick }
186953887Smckusick 
187053887Smckusick fbsetpalette(fbp, data)
187153887Smckusick 	struct fbreg *fbp;
187253887Smckusick 	sPalette *data;
187353887Smckusick {
187453887Smckusick 	lPalette	pal;
187553887Smckusick 
187653887Smckusick 	fbp->fb_command = FB_CSETPALETTE;
187753887Smckusick 	fbp->fb_palette.count = 1;
187853887Smckusick 	*(sPalette *)srcdestlist = *data;
187953887Smckusick #ifdef CPU_SINGLE
188053887Smckusick 	fbmap[0].fm_vaddr = (caddr_t)srcdestlist;
188153887Smckusick 	fbmap[0].fm_offset = 0;
188253887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
188353887Smckusick #else
188453887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
188553887Smckusick #endif
188653887Smckusick 	fbstart(fbp, 0);
188753887Smckusick 	return 0;
188853887Smckusick }
188953887Smckusick 
189053887Smckusick fbnsetpalette(fbp, cmd)
189153887Smckusick 	struct fbreg *fbp;
189253887Smckusick 	lPalette *cmd;
189353887Smckusick {
189453887Smckusick 	register int error;
189553887Smckusick 	register int count;
189653887Smckusick #ifdef CPU_SINGLE
189753887Smckusick 	register int len;
189853887Smckusick #endif
189953887Smckusick 
190053887Smckusick 	fbinitlock();
190153887Smckusick 	fbp->fb_command = FB_CSETPALETTE;
190253887Smckusick #ifdef CPU_SINGLE
190353887Smckusick 	fbp->fb_palette.count = cmd->count;
190453887Smckusick 	if ((len = cmd->count * sizeof(sPalette)) <= 0)
190553887Smckusick 		return EINVAL;
190653887Smckusick 	if (error = fblockmem(cmd->palette, len, B_WRITE, fbmap, UIO_USERSPACE))
190753887Smckusick 		return error;
190853887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
190953887Smckusick 
191053887Smckusick 	fbdolock();
191153887Smckusick 	fbstart(fbp, 1);
191253887Smckusick 	fbunlock();
191353887Smckusick #else /* CPU_SINGLE */
191453887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
191553887Smckusick 	while (cmd->count > 0) {
191653887Smckusick 		count = min(cmd->count, (MAX_SIZE / sizeof(sPalette)));
191753887Smckusick 		fbp->fb_palette.count = count;
191853887Smckusick 		if (error = COPYIN((caddr_t)cmd->palette, (caddr_t)srcdestlist,
191953887Smckusick 				   count * sizeof(sPalette), UIO_USERSPACE)) {
192053887Smckusick 			break;
192153887Smckusick 		}
192253887Smckusick 		cmd->count -= count;
192353887Smckusick 		cmd->palette += count;
192453887Smckusick 
192553887Smckusick 		fbstart(fbp, 0);
192653887Smckusick 	}
192753887Smckusick #endif /* CPU_SINGLE */
192853887Smckusick 	return error;
192953887Smckusick }
193053887Smckusick 
193153887Smckusick fbgetpalette(fbp, data)
193253887Smckusick 	struct fbreg *fbp;
193353887Smckusick 	sPalette *data;
193453887Smckusick {
193553887Smckusick 	lPalette pal;
193653887Smckusick 
193753887Smckusick 	fbp->fb_command = FB_CGETPALETTE;
193853887Smckusick 	fbp->fb_palette.count = 1;
193953887Smckusick 	*(sPalette *)srcdestlist = *data;
194053887Smckusick #ifdef CPU_SINGLE
194153887Smckusick 	fbmap[0].fm_vaddr = (caddr_t)srcdestlist;
194253887Smckusick 	fbmap[0].fm_offset = 0;
194353887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
194453887Smckusick #else
194553887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
194653887Smckusick #endif
194753887Smckusick 	fbstart(fbp, 1);
194853887Smckusick #ifdef mips
194953887Smckusick 	MachFlushDCache((caddr_t)srcdestlist, sizeof (sPalette));
195053887Smckusick 	*data = *(sPalette *)MACH_CACHED_TO_UNCACHED(srcdestlist);
195153887Smckusick #else
195253887Smckusick 	*data = *(sPalette *)srcdestlist;
195353887Smckusick #endif
195453887Smckusick 	return fbp->fb_result;
195553887Smckusick }
195653887Smckusick 
195753887Smckusick fbngetpalette(fbp, cmd)
195853887Smckusick 	struct fbreg *fbp;
195953887Smckusick 	lPalette *cmd;
196053887Smckusick {
196153887Smckusick 	register int error;
196253887Smckusick 	register int count;
196353887Smckusick #ifdef CPU_SINGLE
196453887Smckusick 	register int len;
196553887Smckusick #else
196653887Smckusick 	register int savecount;
196753887Smckusick 	register sPalette *savep;
196853887Smckusick #endif
196953887Smckusick 
197053887Smckusick 	fbinitlock();
197153887Smckusick 	fbp->fb_command = FB_CGETPALETTE;
197253887Smckusick #ifdef CPU_SINGLE
197353887Smckusick 	fbp->fb_palette.count = cmd->count;
197453887Smckusick 	if ((len = cmd->count * sizeof(sPalette)) <= 0)
197553887Smckusick 		return EINVAL;
197653887Smckusick 	if (error = fblockmem(cmd->palette, len, B_WRITE, fbmap, UIO_USERSPACE))
197753887Smckusick 		return error;
197853887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
197953887Smckusick 
198053887Smckusick 	fbdolock();
198153887Smckusick 	fbstart(fbp, 1);
198253887Smckusick 	fbunlock();
198353887Smckusick #else /* CPU_SINGLE */
198453887Smckusick 	savecount = cmd->count;
198553887Smckusick 	savep = cmd->palette;
198653887Smckusick 	fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
198753887Smckusick 	while (cmd->count > 0) {
198853887Smckusick 		count = min(cmd->count, (MAX_SIZE / sizeof(sPalette)));
198953887Smckusick 		fbp->fb_palette.count = count;
199053887Smckusick 		if (error = COPYIN((caddr_t)cmd->palette, (caddr_t)srcdestlist,
199153887Smckusick 				   count * sizeof(sPalette), UIO_USERSPACE)) {
199253887Smckusick 			break;
199353887Smckusick 		}
199453887Smckusick 		fbstart(fbp, 1);
199553887Smckusick #ifdef mips
199653887Smckusick 		MachFlushDCache((caddr_t)srcdestlist, sizeof (sPalette));
199753887Smckusick 		error = copyout((caddr_t)MACH_CACHED_TO_UNCACHED(srcdestlist),
199853887Smckusick 				(caddr_t)cmd->palette,
199953887Smckusick 				count * sizeof(sPalette));
200053887Smckusick #else
200153887Smckusick 		error = copyout((caddr_t)srcdestlist,
200253887Smckusick 				(caddr_t)cmd->palette,
200353887Smckusick 				count * sizeof(sPalette));
200453887Smckusick #endif
200553887Smckusick 		if (error)
200653887Smckusick 			break;
200753887Smckusick 		cmd->count -= count;
200853887Smckusick 		cmd->palette += count;
200953887Smckusick 	}
201053887Smckusick 	cmd->count = savecount;
201153887Smckusick 	cmd->palette = savep;
201253887Smckusick #endif /* CPU_SINGLE */
201353887Smckusick 	return fbp->fb_result;
201453887Smckusick }
201553887Smckusick #endif /* NFB > 0 */
2016