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