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.1 (Berkeley) 06/11/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 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 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 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 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 246 fbinitlock() 247 { 248 segind = 0; 249 } 250 251 void 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 |= SPHYSIO; 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 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 &= ~SPHYSIO; 299 splx(s); 300 301 /* for 'fbinitlock() o wasureru ukkariyasan'... */ 302 segind = 0; 303 } 304 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 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 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 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 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 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 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 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