1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7 *
8 * %sccs.include.redist.c%
9 *
10 * from: $Hdr: fb_sub.c,v 4.300 91/06/27 20:43:09 root Rel41 $ SONY
11 *
12 * @(#)fb_sub.c 8.2 (Berkeley) 09/23/93
13 */
14
15 #include "fb.h"
16 #if NFB > 0
17 /*
18 * Frame buffer driver
19 */
20
21 #include <sys/types.h>
22 #include <machine/pte.h>
23 #include <machine/cpu.h>
24 #include <machine/param.h>
25
26 #include <sys/param.h>
27 #include <sys/proc.h>
28 #include <sys/user.h>
29 #include <sys/buf.h>
30 #include <vm/vm.h>
31 #include <sys/systm.h>
32 #include <sys/map.h>
33 #include <sys/uio.h>
34 #include <sys/kernel.h>
35
36 #include <news3400/iop/framebuf.h>
37 #include <news3400/iop/fbreg.h>
38 #ifdef CPU_DOUBLE
39 #ifdef IPC_MRX
40 #include "../ipc/newsipc.h"
41 #ifdef mips
42 #define ipc_phys(x) K0_TT0(x)
43 #define ipc_log(x) TT0_K0(x)
44 #else /* mips */
45 #define ipc_phys(x) (caddr_t)((int)(x) & ~0x80000000)
46 #define ipc_log(x) (caddr_t)((int)(x) | 0x80000000)
47 #endif /* mips */
48 #endif /* IPC_MRX */
49 #else /* CPU_DOUBLE */
50 #define ipc_phys(x) (caddr_t)((int)(x))
51 #define ipc_log(x) (caddr_t)((int)(x) | 0x80000000)
52 #endif /* CPU_DOUBLE */
53
54 #define MAX_FBMAP 3
55 static struct fb_map fbmap[MAX_FBMAP];
56
57 /* bitblt type */
58 #define BLTTYPE(ts, td) ((ts) << 2 | (td))
59
60 static lSrcDest srcdestlist[MAX_BATCHBITBLT];
61 #define MAX_SIZE (MAX_BATCHBITBLT * sizeof(lSrcDest))
62
63 #define ODD_ADDR(x) (((unsigned)(x))&1)
64
65 #define MAXMSEG 4
66 static int segind;
67 static struct memseg {
68 caddr_t adrs;
69 int len;
70 int rw;
71 caddr_t oadrs;
72 int olen;
73 struct fb_map *map;
74 } mseg[MAXMSEG];
75
76 #define BASE(a) ((int)(a) & ~(NBPG - 1))
77
78 #ifdef CPU_DOUBLE
COPYIN(src,dst,len,seg)79 COPYIN(src, dst, len, seg)
80 caddr_t src;
81 caddr_t dst;
82 int len;
83 int seg;
84 {
85
86 switch (seg) {
87 case UIO_SYSSPACE:
88 bcopy(src, dst, len);
89 return (0);
90 case UIO_USERSPACE:
91 return (copyin(src, dst, len));
92 default:
93 panic("COPYIN: seg");
94 /* NOTREACHED */
95 }
96 }
97 #endif /* CPU_DOUBLE */
98
fbgetmap(addr,len,map)99 fbgetmap(addr, len, map)
100 caddr_t addr;
101 int len;
102 struct fb_map *map;
103 {
104 register struct pte *pte;
105 register caddr_t *p;
106 unsigned v;
107 register int npf;
108 int o;
109
110 v = pmax_btop(addr);
111 o = (int)addr & PGOFSET;
112 npf = btoc(len + o);
113 if (npf > NFBMAP)
114 return (EINVAL);
115
116 map->fm_vaddr = addr;
117 map->fm_offset = o;
118 map->fm_count = len;
119
120 #ifdef CPU_DOUBLE
121 if (addr >= (caddr_t)KERNBASE) {
122 #ifdef mips
123 p = map->fm_addr;
124 if (MACH_IS_CACHED(addr)) {
125 addr = ptob(v);
126 while (--npf >= 0) {
127 *p++ = (caddr_t)K0_TT0(addr);
128 addr += NBPG;
129 }
130 return (0);
131 }
132 if (MACH_IS_MAPPED(addr))
133 pte = kvtopte(addr);
134 else if (addr >= (caddr_t)&u)
135 pte = curproc->p_addr + btop(addr - (caddr_t)&u);
136 else
137 panic("fbgetmap: bad kernel addr");
138 while (--npf >= 0)
139 *p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));
140 #else /* mips */
141 pte = kvtopte(addr);
142 p = map->fm_addr;
143 while (--npf >= 0)
144 *p++ = (caddr_t)ptob(pte++->pg_pfnum);
145 #endif /* mips */
146 return (0);
147 }
148 pte = vtopte(curproc, v); /*KU:XXXXXXXXXXXXXXXXXX*/
149 p = map->fm_addr;
150 while (--npf >= 0) {
151 if (pte->pg_pfnum == 0)
152 panic("iop zero uentry");
153 #ifdef mips
154 *p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));
155 #else
156 *p++ = (caddr_t)ptob(pte++->pg_pfnum);
157 #endif
158 }
159
160 #endif /* CPU_DOUBLE */
161 return (0);
162 }
163
fblockmem(ad,len,rw,map,seg)164 fblockmem(ad, len, rw, map, seg)
165 register caddr_t ad;
166 register int len;
167 int rw;
168 struct fb_map *map;
169 int seg;
170 {
171 register struct memseg *msp;
172
173 /* validity check */
174 if (len < 0)
175 return EFAULT;
176 else if (len == 0)
177 return 0;
178 else if (ad == 0)
179 return EFAULT;
180 else if (seg == UIO_USERSPACE &&
181 !useracc(ad, len, rw == B_READ ? B_WRITE : B_READ))
182 return EFAULT;
183 else if (segind >= MAXMSEG)
184 return EFAULT;
185
186 /* insertion sort */
187 for (msp = mseg + segind - 1; msp >= mseg; msp--) {
188 if (msp->adrs > ad)
189 *(msp + 1) = *msp;
190 else
191 break;
192 }
193 msp++;
194 #ifdef CPU_SINGLE
195 switch (seg) {
196 case UIO_SYSSPACE:
197 map->fm_vaddr = ad;
198 map->fm_offset = 0;
199 break;
200 case UIO_USERSPACE:
201 msp->adrs = (caddr_t)BASE(ad);
202 msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;
203 break;
204 default:
205 panic("fblockmem: seg");
206 /* NOTREACHED */
207 }
208 #else /* CPU_SINGLE */
209 msp->adrs = (caddr_t)BASE(ad);
210 msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;
211 #endif /* CPU_SINGLE */
212 msp->rw = rw;
213 msp->oadrs = ad;
214 msp->olen = len;
215 msp->map = map;
216 segind++;
217
218 return (0);
219 }
220
fblocksbitmap(bm,rw,map)221 fblocksbitmap(bm, rw, map)
222 register lBitmap *bm;
223 int rw;
224 struct fb_map *map;
225 {
226 register int len;
227 register int error = 0;
228
229 if (bm->depth > 32)
230 return EINVAL;
231 if (bm->type == BM_FB || bm->type == BM_0 || bm->type == BM_1)
232 return 0;
233 if (bm->type == BM_MEM)
234 len = bm->width * bm->rect.extent.y * bm->depth * sizeof(Word);
235 if (len < 0 || len > FB_MAX_IO)
236 return(EINVAL);
237 error = fblockmem((caddr_t)(bm->base), len, rw, map, UIO_USERSPACE);
238 if (error)
239 return error;
240
241 bm->base = (Word *)ipc_phys(map);
242 return 0;
243 }
244
245 void
fbinitlock()246 fbinitlock()
247 {
248 segind = 0;
249 }
250
251 void
fbdolock()252 fbdolock()
253 {
254 register struct memseg *msp0, *msp1, *mspl;
255 register int i, tlen;
256
257 mspl = mseg + segind;
258 for (msp0 = mseg, msp1 = mseg + 1; msp1 < mspl; msp0++, msp1++) {
259 if (msp0->adrs + msp0->len > msp1->adrs) {
260 tlen = msp1->adrs - msp0->adrs + msp1->len;
261 msp1->adrs = msp0->adrs;
262 msp1->len = msp0->len > tlen ? msp0->len : tlen;
263 msp0->len = 0;
264 msp1->rw = (msp0->rw == B_READ || msp1->rw == B_READ) ?
265 B_READ : B_WRITE;
266 }
267 }
268
269 /* lock */
270 curproc->p_flag |= P_PHYSIO;
271 for (i = 0; i < segind; i++)
272 if (mseg[i].len && mseg[i].adrs && mseg[i].adrs
273 < (caddr_t)KERNBASE)
274 vslock(mseg[i].adrs, mseg[i].len);
275
276 /* make map */
277 for (i = 0; i < segind; i++)
278 fbgetmap(mseg[i].oadrs, mseg[i].olen, mseg[i].map);
279 }
280
281 void
fbunlock()282 fbunlock()
283 {
284 register int i;
285 int s = splfb();
286
287 for (i = 0; i < segind; i++) {
288 if (mseg[i].len && mseg[i].adrs && mseg[i].adrs
289 < (caddr_t)KERNBASE) {
290 vsunlock(mseg[i].adrs, mseg[i].len, mseg[i].rw);
291 #if defined(mips) && defined(CPU_DOUBLE)
292 if (mseg[i].rw == B_READ)
293 clean_kudcache(curproc,
294 mseg[i].adrs, mseg[i].len);
295 #endif
296 }
297 }
298 curproc->p_flag &= ~P_PHYSIO;
299 splx(s);
300
301 /* for 'fbinitlock() o wasureru ukkariyasan'... */
302 segind = 0;
303 }
304
checkbitmap(bm)305 checkbitmap(bm)
306 register lBitmap *bm;
307 {
308 if (bm->depth > 32)
309 return EINVAL;
310
311 switch(bm->type) {
312 case BM_FB:
313 case BM_0:
314 case BM_1:
315 break;
316 case BM_MEM:
317 if (ODD_ADDR(bm->base))
318 return EINVAL;
319 if (bm->width == 0)
320 return EINVAL;
321 if ((bm->width * bm->rect.extent.y) << 1 > FB_MAX_IO)
322 return EINVAL;
323 break;
324 default:
325 return EINVAL;
326 }
327
328 if (bm->rect.extent.x < 0 || bm->rect.extent.y < 0)
329 return EINVAL;
330 else
331 return 0;
332 }
333
checkdepth(sbm,dbm)334 checkdepth(sbm, dbm)
335 lBitmap *sbm, *dbm;
336 {
337 register int ds = sbm->depth;
338 register int dd = dbm->depth;
339
340 if (ds > 1 && dd > 1 && ds != dd)
341 return -1;
342 else
343 return((ds > 1) << 1 | (dd > 1));
344 }
345
346 dobitblt(fbp, sbm, dbm)
347 struct fbreg *fbp;
348 lBitmap *sbm, *dbm;
349 {
350 register int error;
351
352 if (error = fblocksbitmap(sbm, B_WRITE, fbmap))
353 return error;
354 if (error = fblocksbitmap(dbm, B_READ, fbmap + 1))
355 return error;
356 fbdolock();
357 fbstart(fbp, 1);
358 fbunlock();
359
360 /* reset address */
361 if (sbm->type == BM_MEM)
362 sbm->base =
363 (Word *)((struct fb_map *)ipc_log(sbm->base))->fm_vaddr;
364 if (dbm->type == BM_MEM)
365 dbm->base =
366 (Word *)((struct fb_map *)ipc_log(dbm->base))->fm_vaddr;
367 return 0;
368 }
369
fbnbitblt(fbp,cmd)370 fbnbitblt(fbp, cmd)
371 register struct fbreg *fbp;
372 register lBitblt *cmd;
373 {
374 register lBitblt *regcmd;
375 register int len, lens, lend;
376 register int i;
377 int pmask, mode;
378 int error = 0;
379 int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);
380
381 #ifdef CPU_DOUBLE
382 if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
383 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
384 (blttype == BLTTYPE(BM_1, BM_MEM))) {
385 return(mfbnbitblt(fbp, cmd));
386 /* NOTREACHED */
387 }
388 #endif
389
390 fbinitlock();
391 if (error = checkbitmap(&cmd->srcBitmap))
392 return error;
393 if (error = checkbitmap(&cmd->destBitmap))
394 return error;
395 if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)
396 return EINVAL;
397
398 fbp->fb_command = FB_CBITBLT;
399 fbp->fb_bitblt = *cmd;
400 regcmd = &fbp->fb_bitblt;
401
402 /* process bitblt command */
403 switch (blttype) {
404 case BLTTYPE(BM_FB, BM_FB):
405 case BLTTYPE(BM_0, BM_FB):
406 case BLTTYPE(BM_1, BM_FB):
407 fbstart(fbp, 0);
408 break;
409
410 case BLTTYPE(BM_FB, BM_MEM):
411 case BLTTYPE(BM_0, BM_MEM):
412 case BLTTYPE(BM_1, BM_MEM):
413 len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
414 if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
415 error = dobitblt(fbp, ®cmd->srcBitmap,
416 ®cmd->destBitmap);
417 return error;
418 }
419
420 /* bitblt each plane */
421 regcmd->destBitmap.depth = 1;
422 pmask = regcmd->planemask;
423 for (i = 0; i < cmd->destBitmap.depth; i++) {
424 if (mode == 3) /* N to N */
425 regcmd->planemask = pmask & (1 << i);
426
427 if (error = dobitblt(fbp, ®cmd->srcBitmap,
428 ®cmd->destBitmap))
429 return error;
430
431 regcmd->destBitmap.base += len >> 1;
432 if (mode == 1) { /* N to N */
433 regcmd->planemask >>= 1;
434 regcmd->fore_color >>= 1;
435 regcmd->aux_color >>= 1;
436 }
437 }
438 break;
439
440 case BLTTYPE(BM_MEM, BM_FB):
441 len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
442
443 if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {
444 error = dobitblt(fbp, ®cmd->srcBitmap,
445 ®cmd->destBitmap);
446 return error;
447 }
448
449 /* bitblt each plane */
450 regcmd->srcBitmap.depth = 1;
451 pmask = regcmd->planemask;
452 regcmd->fore_color = 0xff;
453 regcmd->aux_color = 0;
454 if (mode == 2) { /* N to 1 */
455 for (i = 0; i < cmd->srcBitmap.depth; i++)
456 if (pmask & (1 << i))
457 break;
458 if (i >= cmd->srcBitmap.depth)
459 return 0;
460 regcmd->srcBitmap.base += (len >> 1) * i;
461 error = dobitblt(fbp, ®cmd->srcBitmap,
462 ®cmd->destBitmap);
463 return error;
464 }
465 /* else (N to N) */
466 for (i = 0; i < cmd->srcBitmap.depth; i++) {
467 regcmd->planemask = pmask & (1 << i);
468 if (error = dobitblt(fbp, ®cmd->srcBitmap,
469 ®cmd->destBitmap))
470 return error;
471 regcmd->srcBitmap.base += len >> 1;
472 regcmd->planemask >>= 1;
473 }
474 return 0;
475
476 case BLTTYPE(BM_MEM, BM_MEM):
477 lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
478 lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
479 if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&
480 lend * cmd->destBitmap.depth <= FB_MAX_IO) {
481 error = dobitblt(fbp, ®cmd->srcBitmap,
482 ®cmd->destBitmap);
483 return error;
484 }
485
486 regcmd->srcBitmap.depth = 1;
487 regcmd->destBitmap.depth = 1;
488 pmask = regcmd->planemask;
489 if (mode == 2) { /* N to 1 */
490 regcmd->fore_color = 0xff;
491 regcmd->aux_color = 0;
492 for (i = 0; i < cmd->srcBitmap.depth; i++)
493 if (pmask & (1 << i))
494 break;
495 if (i >= cmd->srcBitmap.depth)
496 return 0;
497 regcmd->srcBitmap.base += (lens >> 1) * i;
498 error = dobitblt(fbp, ®cmd->srcBitmap,
499 ®cmd->destBitmap);
500 return error;
501 } else if (mode == 1) { /* 1 to N */
502 for (i = 0; i < cmd->srcBitmap.depth; i++) {
503 if (error = dobitblt(fbp, ®cmd->srcBitmap,
504 ®cmd->destBitmap))
505 return error;
506 regcmd->planemask >>= 1;
507 regcmd->fore_color >>= 1;
508 regcmd->aux_color >>= 1;
509 regcmd->destBitmap.base += lend >> 1;
510 }
511 return 0;
512 } else { /* N to N */
513 regcmd->fore_color = 0xff;
514 regcmd->aux_color = 0;
515 for (i = 0; i < cmd->srcBitmap.depth; i++) {
516 if (error = dobitblt(fbp, ®cmd->srcBitmap,
517 ®cmd->destBitmap))
518 return error;
519 regcmd->srcBitmap.base += lens >> 1;
520 regcmd->destBitmap.base += lend >> 1;
521 regcmd->planemask >>= 1;
522 }
523 return 0;
524 }
525 break;
526
527 default:
528 return EINVAL;
529 }
530
531 return error;
532 }
533
534 fbbitblt(fbp, cmd)
535 struct fbreg *fbp;
536 register sBitblt *cmd;
537 {
538 lBitblt lcmd;
539 register lBitblt *lcmdp;
540
541 lcmdp = &lcmd;
542
543 lcmdp->func = cmd->func;
544 lcmdp->transp = cmd->transp;
545 lcmdp->fore_color = cmd->fore_color;
546 lcmdp->aux_color = cmd->aux_color;
547 lcmdp->planemask = cmd->planemask;
548 lcmdp->srcBitmap.type = cmd->srcBitmap.type;
549 lcmdp->srcBitmap.depth = cmd->srcBitmap.depth;
550 lcmdp->srcBitmap.width = cmd->srcBitmap.width;
551 lcmdp->srcBitmap.rect.origin.x = cmd->srcBitmap.rect.origin.x;
552 lcmdp->srcBitmap.rect.origin.y = cmd->srcBitmap.rect.origin.y;
553 lcmdp->srcBitmap.rect.extent.x = cmd->srcBitmap.rect.extent.x;
554 lcmdp->srcBitmap.rect.extent.y = cmd->srcBitmap.rect.extent.y;
555 lcmdp->srcBitmap.base = cmd->srcBitmap.base;
556 lcmdp->srcRect.origin.x = cmd->srcRect.origin.x;
557 lcmdp->srcRect.origin.y = cmd->srcRect.origin.y;
558 lcmdp->srcRect.extent.x = cmd->srcRect.extent.x;
559 lcmdp->srcRect.extent.y = cmd->srcRect.extent.y;
560 lcmdp->destBitmap.type = cmd->destBitmap.type;
561 lcmdp->destBitmap.depth = cmd->destBitmap.depth;
562 lcmdp->destBitmap.width = cmd->destBitmap.width;
563 lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
564 lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
565 lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
566 lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
567 lcmdp->destBitmap.base = cmd->destBitmap.base;
568 lcmdp->destClip.origin.x = cmd->destClip.origin.x;
569 lcmdp->destClip.origin.y = cmd->destClip.origin.y;
570 lcmdp->destClip.extent.x = cmd->destClip.extent.x;
571 lcmdp->destClip.extent.y = cmd->destClip.extent.y;
572 lcmdp->destPoint.x = cmd->destPoint.x;
573 lcmdp->destPoint.y = cmd->destPoint.y;
574 return (fbnbitblt(fbp, lcmdp));
575 }
576
577 procbatchbitblt(fbp, mode, cmd)
578 struct fbreg *fbp;
579 int mode;
580 register lBatchBitblt *cmd;
581 {
582 register lBatchBitblt *regcmd;
583 register int len, lens, lend;
584 register int i;
585 int pmask;
586 int error = 0;
587
588 regcmd = &fbp->fb_batchbitblt;
589 /* process batch bitblt command */
590 switch (BLTTYPE(regcmd->srcBitmap.type, regcmd->destBitmap.type)) {
591 case BLTTYPE(BM_FB, BM_FB):
592 case BLTTYPE(BM_0, BM_FB):
593 case BLTTYPE(BM_1, BM_FB):
594 fbdolock();
595 fbstart(fbp, cmd->nSrcDest);
596 fbunlock();
597 break;
598
599 case BLTTYPE(BM_FB, BM_MEM):
600 case BLTTYPE(BM_0, BM_MEM):
601 case BLTTYPE(BM_1, BM_MEM):
602 len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
603 if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
604 error = dobitblt(fbp, ®cmd->srcBitmap,
605 ®cmd->destBitmap);
606 return error;
607 }
608
609 /* bitblt each plane */
610 regcmd->destBitmap.depth = 1;
611 pmask = regcmd->planemask;
612 for (i = 0; i < cmd->destBitmap.depth; i++) {
613 if (mode == 3) /* N to N */
614 regcmd->planemask = pmask & (1 << i);
615
616 if (error = dobitblt(fbp, ®cmd->srcBitmap,
617 ®cmd->destBitmap))
618 return error;
619
620 regcmd->destBitmap.base += len >> 1;
621 if (mode == 1) { /* N to N */
622 regcmd->planemask >>= 1;
623 regcmd->fore_color >>= 1;
624 regcmd->aux_color >>= 1;
625 }
626 }
627 break;
628
629 case BLTTYPE(BM_MEM, BM_FB):
630 len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
631
632 if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {
633 error = dobitblt(fbp, ®cmd->srcBitmap,
634 ®cmd->destBitmap);
635 return error;
636 }
637
638 /* bitblt each plane */
639 regcmd->srcBitmap.depth = 1;
640 pmask = regcmd->planemask;
641 regcmd->fore_color = 0xff;
642 regcmd->aux_color = 0;
643 if (mode == 2) { /* N to 1 */
644 for (i = 0; i < cmd->srcBitmap.depth; i++)
645 if (pmask & (1 << i))
646 break;
647 if (i >= cmd->srcBitmap.depth)
648 return 0;
649 regcmd->srcBitmap.base += (len >> 1) * i;
650 error = dobitblt(fbp, ®cmd->srcBitmap,
651 ®cmd->destBitmap);
652 return error;
653 }
654 /* else (N to N) */
655 for (i = 0; i < cmd->srcBitmap.depth; i++) {
656 regcmd->planemask = pmask & (1 << i);
657 if (error = dobitblt(fbp, ®cmd->srcBitmap,
658 ®cmd->destBitmap))
659 return error;
660 regcmd->srcBitmap.base += len >> 1;
661 regcmd->planemask >>= 1;
662 }
663 return 0;
664
665 case BLTTYPE(BM_MEM, BM_MEM):
666 lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;
667 lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
668 if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&
669 lend * cmd->destBitmap.depth <= FB_MAX_IO) {
670 error = dobitblt(fbp, ®cmd->srcBitmap,
671 ®cmd->destBitmap);
672 return error;
673 }
674
675 regcmd->srcBitmap.depth = 1;
676 regcmd->destBitmap.depth = 1;
677 pmask = regcmd->planemask;
678 if (mode == 2) { /* N to 1 */
679 regcmd->fore_color = 0xff;
680 regcmd->aux_color = 0;
681 for (i = 0; i < cmd->srcBitmap.depth; i++)
682 if (pmask & (1 << i))
683 break;
684 if (i >= cmd->srcBitmap.depth)
685 return 0;
686 regcmd->srcBitmap.base += (lens >> 1) * i;
687 error = dobitblt(fbp, ®cmd->srcBitmap,
688 ®cmd->destBitmap);
689 return error;
690 } else if (mode == 1) { /* 1 to N */
691 for (i = 0; i < cmd->srcBitmap.depth; i++) {
692 if (error = dobitblt(fbp, ®cmd->srcBitmap,
693 ®cmd->destBitmap))
694 return error;
695 regcmd->planemask >>= 1;
696 regcmd->fore_color >>= 1;
697 regcmd->aux_color >>= 1;
698 regcmd->destBitmap.base += lend >> 1;
699 }
700 return 0;
701 } else { /* N to N */
702 regcmd->fore_color = 0xff;
703 regcmd->aux_color = 0;
704 for (i = 0; i < cmd->srcBitmap.depth; i++) {
705 if (error = dobitblt(fbp, ®cmd->srcBitmap,
706 ®cmd->destBitmap))
707 return error;
708 regcmd->srcBitmap.base += lens >> 1;
709 regcmd->destBitmap.base += lend >> 1;
710 regcmd->planemask >>= 1;
711 }
712 return 0;
713 }
714 break;
715
716 default:
717 return EINVAL;
718 }
719
720 return error;
721 }
722
fbnbatchbitblt(fbp,cmd,seg)723 fbnbatchbitblt(fbp, cmd, seg)
724 register struct fbreg *fbp;
725 register lBatchBitblt *cmd;
726 int seg;
727 {
728 register int error;
729 register int mode;
730 register int len;
731
732 #ifdef CPU_DOUBLE
733 int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);
734
735 if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
736 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
737 (blttype == BLTTYPE(BM_1, BM_MEM))) {
738 return(mfbnbatchbitblt(fbp, cmd, seg));
739 /* notreached */
740 }
741 #endif
742
743 fbinitlock();
744 fbp->fb_command = FB_CBATCHBITBLT;
745 fbp->fb_batchbitblt = *cmd;
746
747 if (error = checkbitmap(&cmd->srcBitmap))
748 return error;
749 if (error = checkbitmap(&cmd->destBitmap))
750 return error;
751 if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)
752 return EINVAL;
753
754 #ifdef CPU_SINGLE
755 if ((len = cmd->nSrcDest * sizeof(lSrcDest)) <= 0)
756 return EINVAL;
757 if (error = fblockmem((caddr_t)cmd->srcDestList,
758 len, B_WRITE, fbmap + 2, seg))
759 return error;
760 fbp->fb_batchbitblt.srcDestList = (lSrcDest *)ipc_phys(fbmap + 2);
761 error = procbatchbitblt(fbp, mode, cmd);
762 #else
763 fbp->fb_batchbitblt.srcDestList = (lSrcDest*)ipc_phys(srcdestlist);
764 while(cmd->nSrcDest > 0) {
765 len = min(cmd->nSrcDest, (MAX_SIZE / sizeof(lSrcDest)));
766 error = COPYIN((caddr_t)cmd->srcDestList, (caddr_t)srcdestlist,
767 len * sizeof(lSrcDest), seg);
768 if (error)
769 return error;
770 cmd->nSrcDest -= len;
771 cmd->srcDestList += len;
772 fbp->fb_batchbitblt.nSrcDest = len;
773
774 if (error = procbatchbitblt(fbp, mode, cmd))
775 return error;
776 }
777 #endif /* CPU_DOUBLE */
778 return error;
779 }
780
781 fbbatchbitblt(fbp, cmd)
782 struct fbreg *fbp;
783 register sBatchBitblt *cmd;
784 {
785 lBatchBitblt lcmd;
786 register lBatchBitblt *lcmdp;
787 static lSrcDest ls[100];
788 register lSrcDest *lp;
789 register sSrcDest *sp;
790 register int ns;
791
792 lcmdp = &lcmd;
793
794 lcmdp->func = cmd->func;
795 lcmdp->transp = cmd->transp;
796 lcmdp->fore_color = cmd->fore_color;
797 lcmdp->aux_color = cmd->aux_color;
798 lcmdp->planemask = cmd->planemask;
799 lcmdp->srcBitmap.type = cmd->srcBitmap.type;
800 lcmdp->srcBitmap.depth = cmd->srcBitmap.depth;
801 lcmdp->srcBitmap.width = cmd->srcBitmap.width;
802 lcmdp->srcBitmap.rect.origin.x = cmd->srcBitmap.rect.origin.x;
803 lcmdp->srcBitmap.rect.origin.y = cmd->srcBitmap.rect.origin.y;
804 lcmdp->srcBitmap.rect.extent.x = cmd->srcBitmap.rect.extent.x;
805 lcmdp->srcBitmap.rect.extent.y = cmd->srcBitmap.rect.extent.y;
806 lcmdp->srcBitmap.base = cmd->srcBitmap.base;
807 lcmdp->destBitmap.type = cmd->destBitmap.type;
808 lcmdp->destBitmap.depth = cmd->destBitmap.depth;
809 lcmdp->destBitmap.width = cmd->destBitmap.width;
810 lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
811 lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
812 lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
813 lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
814 lcmdp->destBitmap.base = cmd->destBitmap.base;
815 lcmdp->destClip.origin.x = cmd->destClip.origin.x;
816 lcmdp->destClip.origin.y = cmd->destClip.origin.y;
817 lcmdp->destClip.extent.x = cmd->destClip.extent.x;
818 lcmdp->destClip.extent.y = cmd->destClip.extent.y;
819 lcmdp->srcDestList = ls;
820 sp = (sSrcDest *)cmd->srcDestList;
821 while (cmd->nSrcDest) {
822 lcmdp->nSrcDest = ns = min(cmd->nSrcDest, 100);
823 cmd->nSrcDest -= ns;
824 lp = ls;
825 while (ns-- > 0) {
826 int error;
827 sSrcDest tmp;
828
829 error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof(tmp));
830 if (error)
831 return (error);
832 lp->srcRect.origin.x = tmp.srcRect.origin.x;
833 lp->srcRect.origin.y = tmp.srcRect.origin.y;
834 lp->srcRect.extent.x = tmp.srcRect.extent.x;
835 lp->srcRect.extent.y = tmp.srcRect.extent.y;
836 lp->destPoint.x = tmp.destPoint.x;
837 lp->destPoint.y = tmp.destPoint.y;
838 lp++;
839 sp++;
840 }
841 fbnbatchbitblt(fbp, lcmdp, UIO_SYSSPACE);
842 }
843 }
844
fbntilebitblt(fbp,cmd)845 fbntilebitblt(fbp, cmd)
846 register struct fbreg *fbp;
847 register lTileBitblt *cmd;
848 {
849 register lTileBitblt *regcmd;
850 register int len, lens, lend;
851 register int i;
852 int mode;
853 int pmask;
854 int error;
855 int blttype = BLTTYPE(cmd->ptnBitmap.type, cmd->destBitmap.type);
856
857 #ifdef CPU_DOUBLE
858 if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
859 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
860 (blttype == BLTTYPE(BM_1, BM_MEM))) {
861 return(mfbntilebitblt(fbp, cmd));
862 /* NOTREACHED */
863 }
864 #endif
865
866 if (error = checkbitmap(&cmd->ptnBitmap))
867 return error;
868 if (error = checkbitmap(&cmd->destBitmap))
869 return error;
870 if ((mode = checkdepth(&cmd->ptnBitmap, &cmd->destBitmap)) < 0)
871 return EINVAL;
872
873 fbp->fb_command = FB_CTILEBITBLT;
874 fbp->fb_tilebitblt = *cmd;
875 regcmd = &fbp->fb_tilebitblt;
876
877 /* process bitblt command */
878 switch (blttype) {
879 case BLTTYPE(BM_FB, BM_FB):
880 case BLTTYPE(BM_0, BM_FB):
881 case BLTTYPE(BM_1, BM_FB):
882 fbstart(fbp, 0);
883 break;
884
885 case BLTTYPE(BM_FB, BM_MEM):
886 case BLTTYPE(BM_0, BM_MEM):
887 case BLTTYPE(BM_1, BM_MEM):
888 len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
889 if (len * cmd->destBitmap.depth <= FB_MAX_IO) {
890 error = dobitblt(fbp, ®cmd->ptnBitmap,
891 ®cmd->destBitmap);
892 return error;
893 }
894
895 /* bitblt each plane */
896 regcmd->destBitmap.depth = 1;
897 pmask = regcmd->planemask;
898 for (i = 0; i < cmd->destBitmap.depth; i++) {
899 if (mode == 3) /* N to N */
900 regcmd->planemask = pmask & (1 << i);
901
902 if (error = dobitblt(fbp, ®cmd->ptnBitmap,
903 ®cmd->destBitmap))
904 return error;
905
906 regcmd->destBitmap.base += len >> 1;
907 if (mode == 1) { /* N to N */
908 regcmd->planemask >>= 1;
909 regcmd->fore_color >>= 1;
910 regcmd->aux_color >>= 1;
911 }
912 }
913 break;
914
915 case BLTTYPE(BM_MEM, BM_FB):
916 len = cmd->ptnBitmap.width * cmd->ptnBitmap.rect.extent.y << 1;
917
918 if (len * cmd->ptnBitmap.depth <= FB_MAX_IO) {
919 error = dobitblt(fbp, ®cmd->ptnBitmap,
920 ®cmd->destBitmap);
921 return error;
922 }
923
924 /* bitblt each plane */
925 regcmd->ptnBitmap.depth = 1;
926 pmask = regcmd->planemask;
927 regcmd->fore_color = 0xff;
928 regcmd->aux_color = 0;
929 if (mode == 2) { /* N to 1 */
930 for (i = 0; i < cmd->ptnBitmap.depth; i++)
931 if (pmask & (1 << i))
932 break;
933 if (i >= cmd->ptnBitmap.depth)
934 return 0;
935 regcmd->ptnBitmap.base += (len >> 1) * i;
936 error = dobitblt(fbp, ®cmd->ptnBitmap,
937 ®cmd->destBitmap);
938 return error;
939 }
940 /* else (N to N) */
941 for (i = 0; i < cmd->ptnBitmap.depth; i++) {
942 regcmd->planemask = pmask & (1 << i);
943 if (error = dobitblt(fbp, ®cmd->ptnBitmap,
944 ®cmd->destBitmap))
945 return error;
946 regcmd->ptnBitmap.base += len >> 1;
947 regcmd->planemask >>= 1;
948 }
949 return 0;
950
951 case BLTTYPE(BM_MEM, BM_MEM):
952 lens = cmd->ptnBitmap.width * cmd->ptnBitmap.rect.extent.y << 1;
953 lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;
954 if (lens * cmd->ptnBitmap.depth <= FB_MAX_IO &&
955 lend * cmd->destBitmap.depth <= FB_MAX_IO) {
956 error = dobitblt(fbp, ®cmd->ptnBitmap,
957 ®cmd->destBitmap);
958 return error;
959 }
960
961 regcmd->ptnBitmap.depth = 1;
962 regcmd->destBitmap.depth = 1;
963 pmask = regcmd->planemask;
964 if (mode == 2) { /* N to 1 */
965 regcmd->fore_color = 0xff;
966 regcmd->aux_color = 0;
967 for (i = 0; i < cmd->ptnBitmap.depth; i++)
968 if (pmask & (1 << i))
969 break;
970 if (i >= cmd->ptnBitmap.depth)
971 return 0;
972 regcmd->ptnBitmap.base += (lens >> 1) * i;
973 error = dobitblt(fbp, ®cmd->ptnBitmap,
974 ®cmd->destBitmap);
975 return error;
976 } else if (mode == 1) { /* 1 to N */
977 for (i = 0; i < cmd->ptnBitmap.depth; i++) {
978 if (error = dobitblt(fbp, ®cmd->ptnBitmap,
979 ®cmd->destBitmap))
980 return error;
981 regcmd->planemask >>= 1;
982 regcmd->fore_color >>= 1;
983 regcmd->aux_color >>= 1;
984 regcmd->destBitmap.base += lend >> 1;
985 }
986 return 0;
987 } else { /* N to N */
988 for (i = 0; i < cmd->ptnBitmap.depth; i++) {
989 if (error = dobitblt(fbp, ®cmd->ptnBitmap,
990 ®cmd->destBitmap))
991 return error;
992 regcmd->ptnBitmap.base += lens >> 1;
993 regcmd->destBitmap.base += lend >> 1;
994 regcmd->planemask >>= 1;
995 }
996 return 0;
997 }
998 break;
999
1000 default:
1001 return EINVAL;
1002 }
1003 return error;
1004 }
1005
1006 fbtilebitblt(fbp, cmd)
1007 struct fbreg *fbp;
1008 register sTileBitblt *cmd;
1009 {
1010 lTileBitblt lcmd;
1011 register lTileBitblt *lcmdp;
1012
1013 lcmdp = &lcmd;
1014
1015 lcmdp->func = cmd->func;
1016 lcmdp->transp = cmd->transp;
1017 lcmdp->fore_color = cmd->fore_color;
1018 lcmdp->aux_color = cmd->aux_color;
1019 lcmdp->planemask = cmd->planemask;
1020 lcmdp->ptnBitmap.type = cmd->ptnBitmap.type;
1021 lcmdp->ptnBitmap.depth = cmd->ptnBitmap.depth;
1022 lcmdp->ptnBitmap.width = cmd->ptnBitmap.width;
1023 lcmdp->ptnBitmap.rect.origin.x = cmd->ptnBitmap.rect.origin.x;
1024 lcmdp->ptnBitmap.rect.origin.y = cmd->ptnBitmap.rect.origin.y;
1025 lcmdp->ptnBitmap.rect.extent.x = cmd->ptnBitmap.rect.extent.x;
1026 lcmdp->ptnBitmap.rect.extent.y = cmd->ptnBitmap.rect.extent.y;
1027 lcmdp->ptnBitmap.base = cmd->ptnBitmap.base;
1028 lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
1029 lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
1030 lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
1031 lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
1032 lcmdp->refPoint.x = cmd->refPoint.x;
1033 lcmdp->refPoint.y = cmd->refPoint.y;
1034 lcmdp->destBitmap.type = cmd->destBitmap.type;
1035 lcmdp->destBitmap.depth = cmd->destBitmap.depth;
1036 lcmdp->destBitmap.width = cmd->destBitmap.width;
1037 lcmdp->destBitmap.rect.origin.x = cmd->destBitmap.rect.origin.x;
1038 lcmdp->destBitmap.rect.origin.y = cmd->destBitmap.rect.origin.y;
1039 lcmdp->destBitmap.rect.extent.x = cmd->destBitmap.rect.extent.x;
1040 lcmdp->destBitmap.rect.extent.y = cmd->destBitmap.rect.extent.y;
1041 lcmdp->destBitmap.base = cmd->destBitmap.base;
1042 lcmdp->destClip.origin.x = cmd->destClip.origin.x;
1043 lcmdp->destClip.origin.y = cmd->destClip.origin.y;
1044 lcmdp->destClip.extent.x = cmd->destClip.extent.x;
1045 lcmdp->destClip.extent.y = cmd->destClip.extent.y;
1046 lcmdp->destRect.origin.x = cmd->destRect.origin.x;
1047 lcmdp->destRect.origin.y = cmd->destRect.origin.y;
1048 lcmdp->destRect.extent.x = cmd->destRect.extent.x;
1049 lcmdp->destRect.extent.y = cmd->destRect.extent.y;
1050 return (fbntilebitblt(fbp, lcmdp));
1051 }
1052
1053 /* ARGSUSED */
1054 fbbitblt3(fbp, cmd)
1055 struct fbreg *fbp;
1056 sBitblt3 *cmd;
1057 {
1058 return ENXIO;
1059 }
1060
1061 /* ARGSUSED */
1062 fbnbitblt3(fbp, cmd)
1063 struct fbreg *fbp;
1064 lBitblt3 *cmd;
1065 {
1066 return ENXIO;
1067 }
1068
1069 fbnpolyline(fbp, cmd, dj, seg)
1070 struct fbreg *fbp;
1071 register lPrimLine *cmd;
1072 int dj; /* if not zero, disjoint polyline */
1073 int seg;
1074 {
1075 register int error = 0;
1076 register int len;
1077
1078 #ifdef CPU_DOUBLE
1079 if(cmd->drawBM.type == BM_MEM) {
1080 return(mfbnpolyline(fbp, cmd, dj, seg));
1081 /* NOTREACHED */
1082 }
1083 #endif
1084
1085 fbinitlock();
1086 fbp->fb_command = dj ? FB_CDJPOLYLINE : FB_CPOLYLINE;
1087 fbp->fb_polyline = *cmd;
1088
1089 if ((cmd->np & 1) && dj)
1090 return EINVAL;
1091
1092 #ifdef CPU_SINGLE
1093 if (error = fblocksbitmap(&fbp->fb_polyline.drawBM, B_READ, fbmap))
1094 return error;
1095 if ((len = cmd->np * sizeof(lPoint)) <= 0)
1096 return EINVAL;
1097 error = fblockmem((caddr_t)cmd->plist, len, B_WRITE, fbmap + 1, seg);
1098 if (error)
1099 return error;
1100 fbp->fb_polyline.plist = (lPoint *)ipc_phys(fbmap + 1);
1101
1102 fbdolock();
1103 fbstart(fbp, 1);
1104 fbunlock();
1105 #else /* CPU_SINGLE */
1106 fbp->fb_polyline.plist = (lPoint *)ipc_phys(srcdestlist);
1107 while (cmd->np > 0) {
1108 len = min(cmd->np, ((MAX_SIZE / sizeof(lPoint)) & ~1));
1109 fbp->fb_polyline.np = len;
1110 if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
1111 len * sizeof(lPoint), seg)) {
1112 return error;
1113 }
1114 cmd->np -= len;
1115 cmd->plist += len;
1116
1117 if (fbp->fb_polyline.drawBM.type == BM_MEM) {
1118 if (error = fblocksbitmap(&fbp->fb_polyline.drawBM,
1119 B_READ, fbmap)) {
1120 return error;
1121 }
1122 fbdolock();
1123 fbstart(fbp, 1);
1124 fbunlock();
1125 } else if (cmd->np)
1126 fbstart(fbp, 1);
1127 else
1128 fbstart(fbp, 0);
1129 if (!dj && cmd->np) {
1130 cmd->np++;
1131 cmd->plist--;
1132 }
1133 }
1134 #endif /* CPU_SINGLE */
1135 return error;
1136 }
1137
1138 fbpolyline(fbp, cmd, dj)
1139 struct fbreg *fbp;
1140 register sPrimLine *cmd;
1141 int dj;
1142 {
1143 lPrimLine lcmd;
1144 register lPrimLine *lcmdp;
1145 static lPoint pl[100];
1146 register lPoint *lp;
1147 register sPoint *sp;
1148 register int np;
1149
1150 lcmdp = &lcmd;
1151
1152 lcmdp->func = cmd->func;
1153 lcmdp->transp = cmd->transp;
1154 lcmdp->fore_color = cmd->fore_color;
1155 lcmdp->aux_color = cmd->aux_color;
1156 lcmdp->planemask = cmd->planemask;
1157 lcmdp->drawBM.type = cmd->drawBM.type;
1158 lcmdp->drawBM.depth = cmd->drawBM.depth;
1159 lcmdp->drawBM.width = cmd->drawBM.width;
1160 lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
1161 lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
1162 lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
1163 lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
1164 lcmdp->drawBM.base = cmd->drawBM.base;
1165 lcmdp->clip.origin.x = cmd->clip.origin.x;
1166 lcmdp->clip.origin.y = cmd->clip.origin.y;
1167 lcmdp->clip.extent.x = cmd->clip.extent.x;
1168 lcmdp->clip.extent.y = cmd->clip.extent.y;
1169 lcmdp->lptn = cmd->lptn;
1170 lcmdp->dlpf = cmd->dlpf;
1171 lcmdp->plist = pl;
1172 sp = (sPoint *)cmd->plist;
1173 while (cmd->np) {
1174 lcmdp->np = np = min(cmd->np, 100);
1175 cmd->np -= np;
1176 lp = pl;
1177 while (np-- > 0) {
1178 int error;
1179 sPoint tmp;
1180
1181 if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
1182 return (error);
1183 lp->x = tmp.x;
1184 lp->y = tmp.y;
1185 lp++;
1186 sp++;
1187 }
1188 fbnpolyline(fbp, lcmdp, dj, UIO_SYSSPACE);
1189 }
1190 }
1191
1192 fbnfillscan(fbp, cmd, seg)
1193 struct fbreg *fbp;
1194 register lPrimFill *cmd;
1195 int seg;
1196 {
1197 register int error;
1198 register int len;
1199
1200 #ifdef CPU_DOUBLE
1201 int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
1202
1203 if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
1204 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
1205 (blttype == BLTTYPE(BM_1, BM_MEM))) {
1206 return(mfbnfillscan(fbp, cmd, seg));
1207 /* NOTREACHED */
1208 }
1209 #endif
1210
1211 fbinitlock();
1212 fbp->fb_command = FB_CFILLSCAN;
1213 fbp->fb_fillscan = *cmd;
1214
1215 #ifdef CPU_SINGLE
1216 if (error = fblocksbitmap(&fbp->fb_fillscan.ptnBM, B_WRITE, fbmap))
1217 return error;
1218 if (error = fblocksbitmap(&fbp->fb_fillscan.drawBM, B_READ, fbmap + 1))
1219 return error;
1220 if ((len = cmd->nscan * sizeof(lScanl)) <= 0)
1221 return EINVAL;
1222 if (error = fblockmem(cmd->scan, len, B_WRITE, fbmap + 2, seg))
1223 return error;
1224 fbp->fb_fillscan.scan = (lScanl *)ipc_phys(fbmap + 2);
1225
1226 fbdolock();
1227 fbstart(fbp, 1);
1228 fbunlock();
1229 #else /* CPU_SINGLE */
1230 fbp->fb_fillscan.scan = (lScanl *)ipc_phys(srcdestlist);
1231 while (cmd->nscan > 0) {
1232 len = min(cmd->nscan, (MAX_SIZE / sizeof(lScanl)));
1233 fbp->fb_fillscan.nscan = len;
1234 if (error = COPYIN((caddr_t)cmd->scan, (caddr_t)srcdestlist,
1235 len * sizeof(lScanl), seg)) {
1236 return error;
1237 }
1238 cmd->nscan -= len;
1239 cmd->scan += len;
1240 if (fbp->fb_fillscan.ptnBM.type == BM_MEM ||
1241 fbp->fb_fillscan.drawBM.type == BM_MEM) {
1242
1243 if (error = fblocksbitmap(&fbp->fb_fillscan.ptnBM,
1244 B_WRITE, fbmap)) {
1245 return error;
1246 }
1247 if (error = fblocksbitmap(&fbp->fb_fillscan.drawBM,
1248 B_READ, fbmap + 1)) {
1249 return error;
1250 }
1251
1252 fbdolock();
1253 fbstart(fbp, 1);
1254 fbunlock();
1255 } else if (cmd->nscan)
1256 fbstart(fbp, 1);
1257 else
1258 fbstart(fbp, 0);
1259 }
1260 #endif /* CPU_SINGLE */
1261 return error;
1262 }
1263
1264 fbfillscan(fbp, cmd)
1265 struct fbreg *fbp;
1266 register sPrimFill *cmd;
1267 {
1268 lPrimFill lcmd;
1269 register lPrimFill *lcmdp;
1270 static lScanl ls[100];
1271 register lScanl *lp;
1272 register sScanl *sp;
1273 register int ns;
1274
1275 lcmdp = &lcmd;
1276 lcmdp->func = cmd->func;
1277 lcmdp->transp = cmd->transp;
1278 lcmdp->fore_color = cmd->fore_color;
1279 lcmdp->aux_color = cmd->aux_color;
1280 lcmdp->planemask = cmd->planemask;
1281 lcmdp->refPoint.x = cmd->refPoint.x;
1282 lcmdp->refPoint.y = cmd->refPoint.y;
1283 lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
1284 lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
1285 lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
1286 lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
1287 lcmdp->ptnBM.type = cmd->ptnBM.type;
1288 lcmdp->ptnBM.depth = cmd->ptnBM.depth;
1289 lcmdp->ptnBM.width = cmd->ptnBM.width;
1290 lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
1291 lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
1292 lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
1293 lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
1294 lcmdp->ptnBM.base = cmd->ptnBM.base;
1295 lcmdp->drawBM.type = cmd->drawBM.type;
1296 lcmdp->drawBM.depth = cmd->drawBM.depth;
1297 lcmdp->drawBM.width = cmd->drawBM.width;
1298 lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
1299 lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
1300 lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
1301 lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
1302 lcmdp->drawBM.base = cmd->drawBM.base;
1303 lcmdp->clip.origin.x = cmd->clip.origin.x;
1304 lcmdp->clip.origin.y = cmd->clip.origin.y;
1305 lcmdp->clip.extent.x = cmd->clip.extent.x;
1306 lcmdp->clip.extent.y = cmd->clip.extent.y;
1307 lcmdp->scan = ls;
1308 sp = (sScanl *)cmd->scan;
1309 while (cmd->nscan) {
1310 lcmdp->nscan = ns = min(cmd->nscan, 100);
1311 cmd->nscan -= ns;
1312 lp = ls;
1313 while (ns-- > 0) {
1314 int error;
1315 sScanl tmp;
1316
1317 if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
1318 return (error);
1319 lp->x0 = tmp.x0;
1320 lp->x1 = tmp.x1;
1321 lp->y = tmp.y;
1322 lp++;
1323 sp++;
1324 }
1325 fbnfillscan(fbp, lcmdp, UIO_SYSSPACE);
1326 }
1327 }
1328
1329 fbnrectangle(fbp, cmd)
1330 struct fbreg *fbp;
1331 register lPrimRect *cmd;
1332 {
1333 register int error = 0;
1334
1335 #ifdef CPU_DOUBLE
1336 int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
1337
1338 if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
1339 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
1340 (blttype == BLTTYPE(BM_1, BM_MEM))) {
1341 return(mfbnrectangle(fbp, cmd));
1342 /* NOTREACHED */
1343 }
1344 #endif /* CPU_DOUBLE */
1345
1346 fbinitlock();
1347 fbp->fb_command = FB_CRECTANGLE;
1348 fbp->fb_rectangle = *cmd;
1349
1350 if (error = fblocksbitmap(&fbp->fb_rectangle.drawBM, B_READ, fbmap))
1351 return error;
1352 if (error = fblocksbitmap(&fbp->fb_rectangle.ptnBM, B_WRITE, fbmap + 1))
1353 return error;
1354
1355 if (fbp->fb_rectangle.drawBM.type == BM_MEM ||
1356 fbp->fb_rectangle.ptnBM.type == BM_MEM) {
1357 fbdolock();
1358 fbstart(fbp, 1);
1359 fbunlock();
1360 } else {
1361 fbstart(fbp, 0);
1362 }
1363
1364 return error;
1365 }
1366
1367 fbrectangle(fbp, cmd)
1368 struct fbreg *fbp;
1369 register sPrimRect *cmd;
1370 {
1371 lPrimRect lcmd;
1372 register lPrimRect *lcmdp;
1373
1374 lcmdp = &lcmd;
1375
1376 lcmdp->func = cmd->func;
1377 lcmdp->transp = cmd->transp;
1378 lcmdp->fore_color = cmd->fore_color;
1379 lcmdp->aux_color = cmd->aux_color;
1380 lcmdp->planemask = cmd->planemask;
1381 lcmdp->rect.origin.x = cmd->rect.origin.x;
1382 lcmdp->rect.origin.y = cmd->rect.origin.y;
1383 lcmdp->rect.extent.x = cmd->rect.extent.x;
1384 lcmdp->rect.extent.y = cmd->rect.extent.y;
1385 lcmdp->refPoint.x = cmd->refPoint.x;
1386 lcmdp->refPoint.y = cmd->refPoint.y;
1387 lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
1388 lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
1389 lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
1390 lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
1391 lcmdp->ptnBM.type = cmd->ptnBM.type;
1392 lcmdp->ptnBM.depth = cmd->ptnBM.depth;
1393 lcmdp->ptnBM.width = cmd->ptnBM.width;
1394 lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
1395 lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
1396 lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
1397 lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
1398 lcmdp->ptnBM.base = cmd->ptnBM.base;
1399 lcmdp->drawBM.type = cmd->drawBM.type;
1400 lcmdp->drawBM.depth = cmd->drawBM.depth;
1401 lcmdp->drawBM.width = cmd->drawBM.width;
1402 lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
1403 lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
1404 lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
1405 lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
1406 lcmdp->drawBM.base = cmd->drawBM.base;
1407 lcmdp->clip.origin.x = cmd->clip.origin.x;
1408 lcmdp->clip.origin.y = cmd->clip.origin.y;
1409 lcmdp->clip.extent.x = cmd->clip.extent.x;
1410 lcmdp->clip.extent.y = cmd->clip.extent.y;
1411 return (fbnrectangle(fbp, lcmdp));
1412 }
1413
fbnpolymarker(fbp,cmd,seg)1414 fbnpolymarker(fbp, cmd, seg)
1415 register struct fbreg *fbp;
1416 register lPrimMarker *cmd;
1417 int seg;
1418 {
1419 register int error;
1420 register int len;
1421
1422 #ifdef CPU_DOUBLE
1423 int blttype = BLTTYPE(cmd->ptnBM.type, cmd->drawBM.type);
1424
1425 if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
1426 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
1427 (blttype == BLTTYPE(BM_1, BM_MEM))) {
1428 return(mfbnpolymarker(fbp, cmd, seg));
1429 /* NOTREACHED */
1430 }
1431 #endif /* CPU_DOUBLE */
1432
1433 fbinitlock();
1434 fbp->fb_command = FB_CPOLYMARKER;
1435 fbp->fb_polymarker = *cmd;
1436
1437 #ifdef CPU_SINGLE
1438 if (error = fblocksbitmap(&fbp->fb_polymarker.ptnBM, B_WRITE, fbmap))
1439 return error;
1440 if (error = fblocksbitmap(&fbp->fb_polymarker.drawBM, B_READ, fbmap+1))
1441 return error;
1442 if ((len = cmd->np * sizeof(lPoint)) <= 0)
1443 return EINVAL;
1444 if (error = fblockmem(cmd->plist, len, B_WRITE, fbmap + 2, seg))
1445 return error;
1446 fbp->fb_polymarker.plist = (lPoint *)ipc_phys(fbmap + 2);
1447
1448 fbdolock();
1449 fbstart(fbp, 1);
1450 fbunlock();
1451 #else /* CPU_SINGLE */
1452 fbp->fb_polymarker.plist = (lPoint *)ipc_phys(srcdestlist);
1453 while (cmd->np > 0) {
1454 len = min(cmd->np, (MAX_SIZE / sizeof(lPoint)));
1455 fbp->fb_polymarker.np = len;
1456 if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
1457 len * sizeof(lPoint), seg)) {
1458 return error;
1459 }
1460 cmd->np -= len;
1461 cmd->plist += len;
1462
1463 if (fbp->fb_polymarker.ptnBM.type == BM_MEM ||
1464 fbp->fb_polymarker.drawBM.type == BM_MEM) {
1465
1466 if (error = fblocksbitmap(&fbp->fb_polymarker.ptnBM,
1467 B_WRITE, fbmap)) {
1468 return error;
1469 }
1470 if (error = fblocksbitmap(&fbp->fb_polymarker.drawBM,
1471 B_READ, fbmap + 1)) {
1472 return error;
1473 }
1474
1475 fbdolock();
1476 fbstart(fbp, 1);
1477 fbunlock();
1478 } else if (cmd->np)
1479 fbstart(fbp, 1);
1480 else
1481 fbstart(fbp, 0);
1482 }
1483 #endif /* CPU_SINGLE */
1484 return error;
1485 }
1486
1487 fbpolymarker(fbp, cmd)
1488 struct fbreg *fbp;
1489 register sPrimMarker *cmd;
1490 {
1491 lPrimMarker lcmd;
1492 register lPrimMarker *lcmdp;
1493 static lPoint pl[100];
1494 register lPoint *lp;
1495 register sPoint *sp;
1496 register int np;
1497
1498 lcmdp = &lcmd;
1499 lcmdp->func = cmd->func;
1500 lcmdp->transp = cmd->transp;
1501 lcmdp->fore_color = cmd->fore_color;
1502 lcmdp->aux_color = cmd->aux_color;
1503 lcmdp->planemask = cmd->planemask;
1504 lcmdp->ptnRect.origin.x = cmd->ptnRect.origin.x;
1505 lcmdp->ptnRect.origin.y = cmd->ptnRect.origin.y;
1506 lcmdp->ptnRect.extent.x = cmd->ptnRect.extent.x;
1507 lcmdp->ptnRect.extent.y = cmd->ptnRect.extent.y;
1508 lcmdp->ptnBM.type = cmd->ptnBM.type;
1509 lcmdp->ptnBM.depth = cmd->ptnBM.depth;
1510 lcmdp->ptnBM.width = cmd->ptnBM.width;
1511 lcmdp->ptnBM.rect.origin.x = cmd->ptnBM.rect.origin.x;
1512 lcmdp->ptnBM.rect.origin.y = cmd->ptnBM.rect.origin.y;
1513 lcmdp->ptnBM.rect.extent.x = cmd->ptnBM.rect.extent.x;
1514 lcmdp->ptnBM.rect.extent.y = cmd->ptnBM.rect.extent.y;
1515 lcmdp->ptnBM.base = cmd->ptnBM.base;
1516 lcmdp->drawBM.type = cmd->drawBM.type;
1517 lcmdp->drawBM.depth = cmd->drawBM.depth;
1518 lcmdp->drawBM.width = cmd->drawBM.width;
1519 lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
1520 lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
1521 lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
1522 lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
1523 lcmdp->drawBM.base = cmd->drawBM.base;
1524 lcmdp->clip.origin.x = cmd->clip.origin.x;
1525 lcmdp->clip.origin.y = cmd->clip.origin.y;
1526 lcmdp->clip.extent.x = cmd->clip.extent.x;
1527 lcmdp->clip.extent.y = cmd->clip.extent.y;
1528 lcmdp->plist = pl;
1529 sp = (sPoint *)cmd->plist;
1530 while (cmd->np) {
1531 lcmdp->np = np = min(cmd->np, 100);
1532 cmd->np -= np;
1533 while (np-- > 0) {
1534 int error;
1535 sPoint tmp;
1536
1537 if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
1538 return (error);
1539 lp->x = tmp.x;
1540 lp->y = tmp.y;
1541 lp++;
1542 sp++;
1543 }
1544 fbnpolymarker(fbp, lcmdp, UIO_SYSSPACE);
1545 }
1546 }
1547
fbnpolydot(fbp,cmd,seg)1548 fbnpolydot(fbp, cmd, seg)
1549 register struct fbreg *fbp;
1550 register lPrimDot *cmd;
1551 int seg;
1552 {
1553 register int error;
1554 register int len;
1555
1556 #ifdef CPU_DOUBLE
1557 if (cmd->drawBM.type == BM_MEM)
1558 return (mfbnpolydot(fbp, cmd, seg));
1559 #endif
1560
1561 fbinitlock();
1562 fbp->fb_command = FB_CPOLYDOT;
1563 fbp->fb_polydot = *cmd;
1564
1565 #ifdef CPU_SINGLE
1566 if (error = fblocksbitmap(&fbp->fb_polydot.drawBM, B_READ, fbmap + 1))
1567 return error;
1568 if ((len = cmd->np * sizeof(lPoint)) <= 0)
1569 return EINVAL;
1570 if (error = fblockmem(cmd->plist, len, B_WRITE, fbmap + 2, seg))
1571 return error;
1572 fbp->fb_polydot.plist = (lPoint *)ipc_phys(fbmap + 2);
1573
1574 fbdolock();
1575 fbstart(fbp, 1);
1576 fbunlock();
1577 #else /* CPU_SINGLE */
1578 fbp->fb_polydot.plist = (lPoint *)ipc_phys(srcdestlist);
1579 while (cmd->np > 0) {
1580 len = min(cmd->np, (MAX_SIZE / sizeof(lPoint)));
1581 fbp->fb_polydot.np = len;
1582 if (error = COPYIN((caddr_t)cmd->plist, (caddr_t)srcdestlist,
1583 len * sizeof(lPoint), seg)) {
1584 return error;
1585 }
1586 cmd->np -= len;
1587 cmd->plist += len;
1588
1589 if (fbp->fb_polydot.drawBM.type == BM_MEM) {
1590 if (error = fblocksbitmap(&fbp->fb_polydot.drawBM,
1591 B_READ, fbmap + 1)) {
1592 return error;
1593 }
1594
1595 fbdolock();
1596 fbstart(fbp, 1);
1597 fbunlock();
1598 } else if (cmd->np)
1599 fbstart(fbp, 1);
1600 else
1601 fbstart(fbp, 0);
1602 }
1603 #endif /* CPU_SINGLE */
1604 return error;
1605 }
1606
1607 fbpolydot(fbp, cmd)
1608 struct fbreg *fbp;
1609 register sPrimDot *cmd;
1610 {
1611 lPrimDot lcmd;
1612 register lPrimDot *lcmdp;
1613 static lPoint pl[100];
1614 register lPoint *lp;
1615 register sPoint *sp;
1616 register int np;
1617
1618 lcmdp = &lcmd;
1619 lcmdp->func = cmd->func;
1620 lcmdp->transp = cmd->transp;
1621 lcmdp->fore_color = cmd->fore_color;
1622 lcmdp->aux_color = cmd->aux_color;
1623 lcmdp->planemask = cmd->planemask;
1624 lcmdp->drawBM.type = cmd->drawBM.type;
1625 lcmdp->drawBM.depth = cmd->drawBM.depth;
1626 lcmdp->drawBM.width = cmd->drawBM.width;
1627 lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
1628 lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
1629 lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
1630 lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
1631 lcmdp->drawBM.base = cmd->drawBM.base;
1632 lcmdp->clip.origin.x = cmd->clip.origin.x;
1633 lcmdp->clip.origin.y = cmd->clip.origin.y;
1634 lcmdp->clip.extent.x = cmd->clip.extent.x;
1635 lcmdp->clip.extent.y = cmd->clip.extent.y;
1636 lcmdp->plist = pl;
1637 sp = (sPoint *)cmd->plist;
1638 while (cmd->np) {
1639 lcmdp->np = np = min(cmd->np, 100);
1640 cmd->np -= np;
1641 while (np-- > 0) {
1642 int error;
1643 sPoint tmp;
1644
1645 if (error = copyin((caddr_t)sp, (caddr_t)&tmp, sizeof (tmp)))
1646 return (error);
1647 lp->x = tmp.x;
1648 lp->y = tmp.y;
1649 lp++;
1650 sp++;
1651 }
1652 fbnpolydot(fbp, lcmdp, UIO_SYSSPACE);
1653 }
1654 }
1655
fbntext(fbp,cmd)1656 fbntext(fbp, cmd)
1657 register struct fbreg *fbp;
1658 register lPrimText *cmd;
1659 {
1660 register int error;
1661
1662 #ifdef CPU_DOUBLE
1663 int blttype = BLTTYPE(cmd->fontBM.type, cmd->drawBM.type);
1664
1665 if ((cmd->type == ASCII) &&
1666 ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||
1667 (blttype == BLTTYPE(BM_0, BM_MEM)) ||
1668 (blttype == BLTTYPE(BM_1, BM_MEM)))
1669 ) {
1670 return(mfbntext(fbp, cmd));
1671 /* NOTREACHED */
1672 }
1673 #endif /* CPU_DOUBLE */
1674
1675 fbinitlock();
1676 fbp->fb_command = FB_CTEXT;
1677 fbp->fb_text = *cmd;
1678
1679
1680 if (error = fblocksbitmap(&fbp->fb_text.drawBM, B_READ, fbmap))
1681 return error;
1682
1683 if (cmd->type == ASCII) {
1684 if (error = fblocksbitmap(&fbp->fb_text.fontBM,
1685 B_WRITE, fbmap + 1)) {
1686 return error;
1687 }
1688 }
1689
1690 #ifdef CPU_SINGLE
1691 if (error = fblockmem(cmd->str, cmd->len, B_WRITE, fbmap + 2, UIO_USERSPACE))
1692 return error;
1693 fbp->fb_text.str = (unsigned char *)ipc_phys(fbmap + 2);
1694
1695 fbdolock();
1696 fbstart(fbp, 1);
1697 fbunlock();
1698 #else /* CPU_SINGLE */
1699 fbp->fb_text.str = (unsigned char *)ipc_phys(srcdestlist);
1700 if (error = COPYIN((caddr_t)cmd->str,
1701 (caddr_t)srcdestlist, cmd->len, UIO_USERSPACE)) {
1702 return error;
1703 }
1704
1705 if (fbp->fb_text.drawBM.type == BM_MEM ||
1706 (cmd->type == ASCII && fbp->fb_text.fontBM.type == BM_MEM)) {
1707 fbdolock();
1708 fbstart(fbp, 1);
1709 fbunlock();
1710 } else
1711 fbstart(fbp, 0);
1712 #endif /* CPU_SINGLE */
1713 return error;
1714 }
1715
1716 fbtext(fbp, cmd)
1717 struct fbreg *fbp;
1718 register sPrimText *cmd;
1719 {
1720 lPrimText lcmd;
1721 register lPrimText *lcmdp;
1722
1723 lcmdp = &lcmd;
1724
1725 lcmdp->func = cmd->func;
1726 lcmdp->transp = cmd->transp;
1727 lcmdp->fore_color = cmd->fore_color;
1728 lcmdp->aux_color = cmd->aux_color;
1729 lcmdp->planemask = cmd->planemask;
1730 lcmdp->type = cmd->type;
1731 lcmdp->p.x = cmd->p.x;
1732 lcmdp->p.y = cmd->p.y;
1733 lcmdp->dx = cmd->dx;
1734 lcmdp->dy = cmd->dy;
1735 lcmdp->ex_factor = cmd->ex_factor;
1736 lcmdp->fp.x = cmd->fp.x;
1737 lcmdp->fp.y = cmd->fp.y;
1738 lcmdp->width = cmd->width;
1739 lcmdp->height = cmd->height;
1740 lcmdp->column = cmd->column;
1741 lcmdp->first_chr = cmd->first_chr;
1742 lcmdp->last_chr = cmd->last_chr;
1743 lcmdp->fontBM.type = cmd->fontBM.type;
1744 lcmdp->fontBM.depth = cmd->fontBM.depth;
1745 lcmdp->fontBM.width = cmd->fontBM.width;
1746 lcmdp->fontBM.rect.origin.x = cmd->fontBM.rect.origin.x;
1747 lcmdp->fontBM.rect.origin.y = cmd->fontBM.rect.origin.y;
1748 lcmdp->fontBM.rect.extent.x = cmd->fontBM.rect.extent.x;
1749 lcmdp->fontBM.rect.extent.y = cmd->fontBM.rect.extent.y;
1750 lcmdp->fontBM.base = cmd->fontBM.base;
1751 lcmdp->drawBM.type = cmd->drawBM.type;
1752 lcmdp->drawBM.depth = cmd->drawBM.depth;
1753 lcmdp->drawBM.width = cmd->drawBM.width;
1754 lcmdp->drawBM.rect.origin.x = cmd->drawBM.rect.origin.x;
1755 lcmdp->drawBM.rect.origin.y = cmd->drawBM.rect.origin.y;
1756 lcmdp->drawBM.rect.extent.x = cmd->drawBM.rect.extent.x;
1757 lcmdp->drawBM.rect.extent.y = cmd->drawBM.rect.extent.y;
1758 lcmdp->drawBM.base = cmd->drawBM.base;
1759 lcmdp->clip.origin.x = cmd->clip.origin.x;
1760 lcmdp->clip.origin.y = cmd->clip.origin.y;
1761 lcmdp->clip.extent.x = cmd->clip.extent.x;
1762 lcmdp->clip.extent.y = cmd->clip.extent.y;
1763 lcmdp->len = cmd->len;
1764 lcmdp->str = cmd->str;
1765 return (fbntext(fbp, lcmdp));
1766 }
1767
1768 fbsetcursor(fbp, data)
1769 struct fbreg *fbp;
1770 sCursor *data;
1771 {
1772 register struct fbreg *fbregp;
1773
1774 fbregp = fbp;
1775
1776 fbregp->fb_command = FB_CSETCURSOR;
1777 fbregp->fb_cursor.func = data->func;
1778 fbregp->fb_cursor.cursor_color = data->cursor_color;
1779 fbregp->fb_cursor.mask_color = data->mask_color;
1780 fbregp->fb_cursor.hot.x = data->hot.x;
1781 fbregp->fb_cursor.hot.y = data->hot.y;
1782 fbregp->fb_cursor.size.x = data->size.x;
1783 fbregp->fb_cursor.size.y = data->size.y;
1784 fbregp->fb_cursor.cursorRect.origin.x = data->cursorRect.origin.x;
1785 fbregp->fb_cursor.cursorRect.origin.y = data->cursorRect.origin.y;
1786 fbregp->fb_cursor.cursorRect.extent.x = data->cursorRect.extent.x;
1787 fbregp->fb_cursor.cursorRect.extent.y = data->cursorRect.extent.y;
1788 fbregp->fb_cursor.maskRect.origin.x = data->maskRect.origin.x;
1789 fbregp->fb_cursor.maskRect.origin.y = data->maskRect.origin.y;
1790 fbregp->fb_cursor.maskRect.extent.x = data->maskRect.extent.x;
1791 fbregp->fb_cursor.maskRect.extent.y = data->maskRect.extent.y;
1792 fbregp->fb_cursor.saveRect.origin.x = data->saveRect.origin.x;
1793 fbregp->fb_cursor.saveRect.origin.y = data->saveRect.origin.y;
1794 fbregp->fb_cursor.saveRect.extent.x = data->saveRect.extent.x;
1795 fbregp->fb_cursor.saveRect.extent.y = data->saveRect.extent.y;
1796 fbregp->fb_cursor.moveArea.origin.x = data->moveArea.origin.x;
1797 fbregp->fb_cursor.moveArea.origin.y = data->moveArea.origin.y;
1798 fbregp->fb_cursor.moveArea.extent.x = data->moveArea.extent.x;
1799 fbregp->fb_cursor.moveArea.extent.y = data->moveArea.extent.y;
1800 fbstart(fbp, 0);
1801 return 0;
1802 }
1803
1804 fbnsetcursor(fbp, data)
1805 struct fbreg *fbp;
1806 lCursor *data;
1807 {
1808 register struct fbreg *fbregp;
1809
1810 fbregp = fbp;
1811
1812 fbregp->fb_command = FB_CSETCURSOR;
1813 fbregp->fb_cursor.func = data->func;
1814 fbregp->fb_cursor.cursor_color = data->cursor_color;
1815 fbregp->fb_cursor.mask_color = data->mask_color;
1816 fbregp->fb_cursor.hot.x = data->hot.x;
1817 fbregp->fb_cursor.hot.y = data->hot.y;
1818 fbregp->fb_cursor.size.x = data->size.x;
1819 fbregp->fb_cursor.size.y = data->size.y;
1820 fbregp->fb_cursor.cursorRect.origin.x = data->cursorRect.origin.x;
1821 fbregp->fb_cursor.cursorRect.origin.y = data->cursorRect.origin.y;
1822 fbregp->fb_cursor.cursorRect.extent.x = data->cursorRect.extent.x;
1823 fbregp->fb_cursor.cursorRect.extent.y = data->cursorRect.extent.y;
1824 fbregp->fb_cursor.maskRect.origin.x = data->maskRect.origin.x;
1825 fbregp->fb_cursor.maskRect.origin.y = data->maskRect.origin.y;
1826 fbregp->fb_cursor.maskRect.extent.x = data->maskRect.extent.x;
1827 fbregp->fb_cursor.maskRect.extent.y = data->maskRect.extent.y;
1828 fbregp->fb_cursor.saveRect.origin.x = data->saveRect.origin.x;
1829 fbregp->fb_cursor.saveRect.origin.y = data->saveRect.origin.y;
1830 fbregp->fb_cursor.saveRect.extent.x = data->saveRect.extent.x;
1831 fbregp->fb_cursor.saveRect.extent.y = data->saveRect.extent.y;
1832 fbregp->fb_cursor.moveArea.origin.x = data->moveArea.origin.x;
1833 fbregp->fb_cursor.moveArea.origin.y = data->moveArea.origin.y;
1834 fbregp->fb_cursor.moveArea.extent.x = data->moveArea.extent.x;
1835 fbregp->fb_cursor.moveArea.extent.y = data->moveArea.extent.y;
1836 fbstart(fbp, 0);
1837 return 0;
1838 }
1839
1840 fbgetscrtype(fbp, data)
1841 struct fbreg *fbp;
1842 sScrType *data;
1843 {
1844 fbp->fb_command = FB_CGETSCRTYPE;
1845 fbstart(fbp, 1);
1846 data->colorwidth = fbp->fb_scrtype.colorwidth;
1847 data->plane = fbp->fb_scrtype.plane;
1848 data->bufferrect.origin.x = fbp->fb_scrtype.bufferrect.origin.x;
1849 data->bufferrect.origin.y = fbp->fb_scrtype.bufferrect.origin.y;
1850 data->bufferrect.extent.x = fbp->fb_scrtype.bufferrect.extent.x;
1851 data->bufferrect.extent.y = fbp->fb_scrtype.bufferrect.extent.y;
1852 data->visiblerect.origin.x = fbp->fb_scrtype.visiblerect.origin.x;
1853 data->visiblerect.origin.y = fbp->fb_scrtype.visiblerect.origin.y;
1854 data->visiblerect.extent.x = fbp->fb_scrtype.visiblerect.extent.x;
1855 data->visiblerect.extent.y = fbp->fb_scrtype.visiblerect.extent.y;
1856 return 0;
1857 }
1858
1859 fbsetxy(fbp, data)
1860 struct fbreg *fbp;
1861 sPoint *data;
1862 {
1863 fbp->fb_command = FB_CSETXY;
1864 fbp->fb_point.x = data->x;
1865 fbp->fb_point.y = data->y;
1866 fbstart(fbp, 0);
1867 return 0;
1868 }
1869
1870 fbsetpalette(fbp, data)
1871 struct fbreg *fbp;
1872 sPalette *data;
1873 {
1874 lPalette pal;
1875
1876 fbp->fb_command = FB_CSETPALETTE;
1877 fbp->fb_palette.count = 1;
1878 *(sPalette *)srcdestlist = *data;
1879 #ifdef CPU_SINGLE
1880 fbmap[0].fm_vaddr = (caddr_t)srcdestlist;
1881 fbmap[0].fm_offset = 0;
1882 fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
1883 #else
1884 fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
1885 #endif
1886 fbstart(fbp, 0);
1887 return 0;
1888 }
1889
1890 fbnsetpalette(fbp, cmd)
1891 struct fbreg *fbp;
1892 lPalette *cmd;
1893 {
1894 register int error;
1895 register int count;
1896 #ifdef CPU_SINGLE
1897 register int len;
1898 #endif
1899
1900 fbinitlock();
1901 fbp->fb_command = FB_CSETPALETTE;
1902 #ifdef CPU_SINGLE
1903 fbp->fb_palette.count = cmd->count;
1904 if ((len = cmd->count * sizeof(sPalette)) <= 0)
1905 return EINVAL;
1906 if (error = fblockmem(cmd->palette, len, B_WRITE, fbmap, UIO_USERSPACE))
1907 return error;
1908 fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
1909
1910 fbdolock();
1911 fbstart(fbp, 1);
1912 fbunlock();
1913 #else /* CPU_SINGLE */
1914 fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
1915 while (cmd->count > 0) {
1916 count = min(cmd->count, (MAX_SIZE / sizeof(sPalette)));
1917 fbp->fb_palette.count = count;
1918 if (error = COPYIN((caddr_t)cmd->palette, (caddr_t)srcdestlist,
1919 count * sizeof(sPalette), UIO_USERSPACE)) {
1920 break;
1921 }
1922 cmd->count -= count;
1923 cmd->palette += count;
1924
1925 fbstart(fbp, 0);
1926 }
1927 #endif /* CPU_SINGLE */
1928 return error;
1929 }
1930
1931 fbgetpalette(fbp, data)
1932 struct fbreg *fbp;
1933 sPalette *data;
1934 {
1935 lPalette pal;
1936
1937 fbp->fb_command = FB_CGETPALETTE;
1938 fbp->fb_palette.count = 1;
1939 *(sPalette *)srcdestlist = *data;
1940 #ifdef CPU_SINGLE
1941 fbmap[0].fm_vaddr = (caddr_t)srcdestlist;
1942 fbmap[0].fm_offset = 0;
1943 fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
1944 #else
1945 fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
1946 #endif
1947 fbstart(fbp, 1);
1948 #ifdef mips
1949 MachFlushDCache((caddr_t)srcdestlist, sizeof (sPalette));
1950 *data = *(sPalette *)MACH_CACHED_TO_UNCACHED(srcdestlist);
1951 #else
1952 *data = *(sPalette *)srcdestlist;
1953 #endif
1954 return fbp->fb_result;
1955 }
1956
1957 fbngetpalette(fbp, cmd)
1958 struct fbreg *fbp;
1959 lPalette *cmd;
1960 {
1961 register int error;
1962 register int count;
1963 #ifdef CPU_SINGLE
1964 register int len;
1965 #else
1966 register int savecount;
1967 register sPalette *savep;
1968 #endif
1969
1970 fbinitlock();
1971 fbp->fb_command = FB_CGETPALETTE;
1972 #ifdef CPU_SINGLE
1973 fbp->fb_palette.count = cmd->count;
1974 if ((len = cmd->count * sizeof(sPalette)) <= 0)
1975 return EINVAL;
1976 if (error = fblockmem(cmd->palette, len, B_WRITE, fbmap, UIO_USERSPACE))
1977 return error;
1978 fbp->fb_palette.palette = (sPalette *)ipc_phys(fbmap);
1979
1980 fbdolock();
1981 fbstart(fbp, 1);
1982 fbunlock();
1983 #else /* CPU_SINGLE */
1984 savecount = cmd->count;
1985 savep = cmd->palette;
1986 fbp->fb_palette.palette = (sPalette *)ipc_phys(srcdestlist);
1987 while (cmd->count > 0) {
1988 count = min(cmd->count, (MAX_SIZE / sizeof(sPalette)));
1989 fbp->fb_palette.count = count;
1990 if (error = COPYIN((caddr_t)cmd->palette, (caddr_t)srcdestlist,
1991 count * sizeof(sPalette), UIO_USERSPACE)) {
1992 break;
1993 }
1994 fbstart(fbp, 1);
1995 #ifdef mips
1996 MachFlushDCache((caddr_t)srcdestlist, sizeof (sPalette));
1997 error = copyout((caddr_t)MACH_CACHED_TO_UNCACHED(srcdestlist),
1998 (caddr_t)cmd->palette,
1999 count * sizeof(sPalette));
2000 #else
2001 error = copyout((caddr_t)srcdestlist,
2002 (caddr_t)cmd->palette,
2003 count * sizeof(sPalette));
2004 #endif
2005 if (error)
2006 break;
2007 cmd->count -= count;
2008 cmd->palette += count;
2009 }
2010 cmd->count = savecount;
2011 cmd->palette = savep;
2012 #endif /* CPU_SINGLE */
2013 return fbp->fb_result;
2014 }
2015 #endif /* NFB > 0 */
2016