1 /* 2 * $Id: ite_cc.c,v 1.13 1994/04/10 00:43:34 chopps Exp $ 3 */ 4 5 #include "ite.h" 6 #if ! defined (NITE) 7 #define NITE 1 8 #endif 9 #if NITE > 0 10 11 #include <sys/param.h> 12 #include <sys/conf.h> 13 #include <sys/proc.h> 14 #include <sys/ioctl.h> 15 #include <sys/tty.h> 16 #include <sys/systm.h> 17 #include <sys/queue.h> 18 #include <dev/cons.h> 19 20 #include "ite.h" 21 #include <amiga/dev/itevar.h> 22 #include <amiga/dev/iteioctl.h> 23 #include <machine/cpu.h> 24 25 #include <amiga/amiga/cc.h> 26 #include <amiga/dev/grfabs_reg.h> 27 #include <amiga/dev/viewioctl.h> 28 #include <amiga/dev/viewvar.h> 29 30 #include <sys/termios.h> 31 32 extern u_char kernel_font_width, kernel_font_height, kernel_font_baseline; 33 extern short kernel_font_boldsmear; 34 extern u_char kernel_font_lo, kernel_font_hi; 35 extern u_char kernel_font[], kernel_cursor[]; 36 37 /* 38 * This is what ip->priv points to; 39 * it contains local variables for custom-chip ites. 40 */ 41 struct ite_priv { 42 view_t *view; /* the view for this ite. */ 43 u_char **row_ptr; /* array of pointers into the bitmap */ 44 u_long row_bytes; 45 u_long cursor_opt; 46 u_int *column_offset; /* array of offsets for columns */ 47 u_int row_offset; /* the row offset */ 48 u_short width; /* the bitmap width */ 49 u_short underline; /* where the underline goes */ 50 u_short ft_x; /* the font width */ 51 u_short ft_y; /* the font height */ 52 u_char *font_cell[256]; /* the font pointer */ 53 }; 54 typedef struct ite_priv ipriv_t; 55 56 extern struct itesw itesw[]; 57 extern struct ite_softc ite_softc[]; 58 #define IPUNIT(ip) (((u_long)ip-(u_long)ite_softc)/sizeof(struct ite_softc)) 59 60 static void putc8 __P((struct ite_softc *, int, int, int, int)); 61 static void clear8 __P((struct ite_softc *, int, int, int, int)); 62 static void scroll8 __P((struct ite_softc *, int, int, int, int)); 63 static void cursor32 __P((struct ite_softc *, int)); 64 static void scrollbmap __P((bmap_t *, u_short, u_short, u_short, u_short, 65 short, short, u_char)); 66 67 /* patchable */ 68 int ite_default_x = 0; /* def leftedge offset */ 69 int ite_default_y = 0; /* def topedge offset */ 70 int ite_default_width = 640; /* def width */ 71 int ite_default_depth = 2; /* def depth */ 72 #if defined (GRF_NTSC) 73 int ite_default_height = 400; /* def NTSC height */ 74 #elif defined (GRF_PAL) 75 int ite_default_height = 512; /* def PAL height */ 76 #else 77 int ite_default_height = 400; /* def NON-PAL/NTSC height (?) */ 78 #endif 79 80 /* audio bell stuff */ 81 u_int bvolume = 10; 82 u_int bpitch = 660; 83 u_int bmsec = 75; 84 85 static char *bsamplep; 86 static char sample[20] = { 87 0,39,75,103,121,127,121,103,75,39,0, 88 -39,-75,-103,-121,-127,-121,-103,-75,-39 89 }; 90 91 cc_unblank () 92 { 93 } 94 95 void 96 init_bell() 97 { 98 short i; 99 100 if (bsamplep != NULL) 101 return; 102 bsamplep = alloc_chipmem(20); 103 if (bsamplep == NULL) 104 panic("no chipmem for ccbell"); 105 106 bcopy(sample, bsamplep, 20); 107 } 108 109 void 110 cc_bell() 111 { 112 u_int clock; 113 u_int period; 114 u_int count; 115 116 clock = 3579545; /* PAL 3546895 */ 117 118 /* 119 * the number of clock ticks per sample byte must be > 124 120 * ergo bpitch must be < clock / 124*20 121 * i.e. ~1443, 1300 to be safe (PAL etc.). also not zero obviously 122 */ 123 period = clock / (bpitch * 20); 124 count = bmsec * bpitch / 1000; 125 126 play_sample(10, PREP_DMA_MEM(bsamplep), period, bvolume, 0x3, count); 127 } 128 129 130 int 131 ite_newsize(ip, winsz) 132 struct ite_softc *ip; 133 struct itewinsize *winsz; 134 { 135 extern struct view_softc views[]; 136 struct view_size vs; 137 ipriv_t *cci = ip->priv; 138 u_long fbp, i; 139 int error; 140 141 vs.x = winsz->x; 142 vs.y = winsz->y; 143 vs.width = winsz->width; 144 vs.height = winsz->height; 145 vs.depth = winsz->depth; 146 error = viewioctl(IPUNIT(ip), VIOCSSIZE, &vs, 0, -1); 147 148 /* 149 * Reinitialize our structs 150 */ 151 cci->view = views[IPUNIT(ip)].view; 152 153 /* -1 for bold. */ 154 ip->cols = (cci->view->display.width - 1) / ip->ftwidth; 155 ip->rows = cci->view->display.height / ip->ftheight; 156 157 /* 158 * save new values so that future opens use them 159 * this may not be correct when we implement Virtual Consoles 160 */ 161 ite_default_height = cci->view->display.height; 162 ite_default_width = cci->view->display.width; 163 ite_default_x = cci->view->display.x; 164 ite_default_y = cci->view->display.y; 165 ite_default_depth = cci->view->bitmap->depth; 166 167 if (cci->row_ptr) 168 free_chipmem(cci->row_ptr); 169 if (cci->column_offset) 170 free_chipmem(cci->column_offset); 171 172 cci->row_ptr = alloc_chipmem(sizeof(u_char *) * ip->rows); 173 cci->column_offset = alloc_chipmem(sizeof(u_int) * ip->cols); 174 175 if (cci->row_ptr == NULL || cci->column_offset == NULL) 176 panic("no chipmem for itecc data"); 177 178 179 cci->width = cci->view->bitmap->bytes_per_row << 3; 180 cci->underline = ip->ftbaseline + 1; 181 cci->row_offset = cci->view->bitmap->bytes_per_row 182 + cci->view->bitmap->row_mod; 183 cci->ft_x = ip->ftwidth; 184 cci->ft_y = ip->ftheight; 185 186 cci->row_bytes = cci->row_offset * ip->ftheight; 187 188 cci->row_ptr[0] = VDISPLAY_LINE (cci->view, 0, 0); 189 for (i = 1; i < ip->rows; i++) 190 cci->row_ptr[i] = cci->row_ptr[i-1] + cci->row_bytes; 191 192 /* initialize the column offsets */ 193 cci->column_offset[0] = 0; 194 for (i = 1; i < ip->cols; i++) 195 cci->column_offset[i] = cci->column_offset[i - 1] + cci->ft_x; 196 197 /* initialize the font cell pointers */ 198 cci->font_cell[ip->font_lo] = ip->font; 199 for (i=ip->font_lo+1; i<=ip->font_hi; i++) 200 cci->font_cell[i] = cci->font_cell[i-1] + ip->ftheight; 201 202 return (error); 203 } 204 205 /* 206 * view_cnprobe is called when the console is being initialized 207 * i.e. very early. grfconfig() has been called, so this implies 208 * that grfcc_probe() was called as well as view_config() (in view.c) 209 * if we are functioning view_inited will be true. 210 */ 211 212 int 213 view_cnprobe(min) 214 int min; 215 { 216 extern int view_inited; /* in view.c */ 217 return (view_inited ? CN_INTERNAL : CN_DEAD); 218 } 219 220 void 221 view_init(ip) 222 register struct ite_softc *ip; 223 { 224 struct itewinsize wsz; 225 struct itesw *sp; 226 ipriv_t *cci; 227 228 sp = itesw; 229 cci = ip->priv; 230 231 if (cci) 232 return; 233 234 init_bell(); 235 236 ip->font = kernel_font; 237 ip->font_lo = kernel_font_lo; 238 ip->font_hi = kernel_font_hi; 239 ip->ftwidth = kernel_font_width; 240 ip->ftheight = kernel_font_height; 241 ip->ftbaseline = kernel_font_baseline; 242 ip->ftboldsmear = kernel_font_boldsmear; 243 244 /* Find the correct set of rendering routines for this font. */ 245 if (ip->ftwidth > 8) 246 panic("kernel font size not supported"); 247 else { 248 sp->ite_cursor = (void *)cursor32; 249 sp->ite_putc = (void *)putc8; 250 sp->ite_clear = (void *)clear8; 251 sp->ite_scroll = (void *)scroll8; 252 } 253 254 cci = alloc_chipmem(sizeof (*cci)); 255 if (cci == NULL) 256 panic("no memory for console device."); 257 258 ip->priv = cci; 259 cci->cursor_opt = 0; 260 cci->view = NULL; 261 cci->row_ptr = NULL; 262 cci->column_offset = NULL; 263 264 #if 0 265 /* currently the view is permanently open due to grf driver */ 266 if (viewopen(IPUNIT(ip), 0)) 267 panic("cannot get ahold of our view"); 268 #endif 269 wsz.x = ite_default_x; 270 wsz.y = ite_default_y; 271 wsz.width = ite_default_width; 272 wsz.height = ite_default_height; 273 wsz.depth = ite_default_depth; 274 275 ite_newsize (ip, &wsz); 276 XXX_grf_cc_on(IPUNIT(ip)); 277 /* viewioctl(IPUNIT(ip), VIOCDISPLAY, NULL, 0, -1); */ 278 } 279 280 int 281 ite_grf_ioctl (ip, cmd, addr, flag, p) 282 struct ite_softc *ip; 283 caddr_t addr; 284 struct proc *p; 285 { 286 struct winsize ws; 287 struct itewinsize *is; 288 struct itebell *ib; 289 ipriv_t *cci; 290 int error; 291 292 cci = ip->priv; 293 error = 0; 294 295 switch (cmd) { 296 case ITEIOCGWINSZ: 297 is = (struct itewinsize *)addr; 298 is->x = cci->view->display.x; 299 is->y = cci->view->display.y; 300 is->width = cci->view->display.width; 301 is->height = cci->view->display.height; 302 is->depth = cci->view->bitmap->depth; 303 break; 304 case ITEIOCSWINSZ: 305 is = (struct itewinsize *)addr; 306 307 if (ite_newsize(ip, is)) 308 error = ENOMEM; 309 else { 310 ws.ws_row = ip->rows; 311 ws.ws_col = ip->cols; 312 ws.ws_xpixel = cci->view->display.width; 313 ws.ws_ypixel = cci->view->display.height; 314 ite_reset (ip); 315 /* 316 * XXX tell tty about the change 317 * XXX this is messy, but works 318 */ 319 iteioctl(0, TIOCSWINSZ, (caddr_t)&ws, 0, p); 320 } 321 break; 322 case ITEIOCDSPWIN: 323 XXX_grf_cc_on(IPUNIT(ip)); 324 break; 325 case ITEIOCREMWIN: 326 XXX_grf_cc_off(IPUNIT(ip)); 327 break; 328 case ITEIOCGBELL: 329 ib = (struct itebell *)addr; 330 ib->volume = bvolume; 331 ib->pitch = bpitch; 332 ib->msec = bmsec; 333 break; 334 case ITEIOCSBELL: 335 ib = (struct itebell *)addr; 336 /* bounds check */ 337 if (ib->pitch > MAXBPITCH || ib->pitch < MINBPITCH || 338 ib->volume > MAXBVOLUME || ib->msec > MAXBTIME) 339 error = EINVAL; 340 else { 341 bvolume = ib->volume; 342 bpitch = ib->pitch; 343 bmsec = ib->msec; 344 } 345 break; 346 case VIOCSCMAP: 347 case VIOCGCMAP: 348 /* 349 * XXX needs to be fixed when multiple console implemented 350 * XXX watchout for that -1 its not really the kernel talking 351 * XXX these two commands don't use the proc pointer though 352 */ 353 error = viewioctl(0, cmd, addr, flag, -1); 354 break; 355 default: 356 error = -1; 357 break; 358 } 359 return (error); 360 } 361 362 void 363 view_deinit(ip) 364 struct ite_softc *ip; 365 { 366 ip->flags &= ~ITE_INITED; 367 } 368 369 /*** (M<8)-by-N routines ***/ 370 371 static void 372 cursor32(struct ite_softc *ip, int flag) 373 { 374 int cend, ofs, h, cstart, dr_plane; 375 u_char *pl, opclr, opset; 376 ipriv_t *cci; 377 bmap_t *bm; 378 view_t *v; 379 380 cci = ip->priv; 381 v = cci->view; 382 bm = v->bitmap; 383 dr_plane = (bm->depth > 1 ? bm->depth-1 : 0); 384 385 if (flag == END_CURSOROPT) 386 cci->cursor_opt--; 387 else if (flag == START_CURSOROPT) { 388 if (!cci->cursor_opt) 389 cursor32 (ip, ERASE_CURSOR); 390 cci->cursor_opt++; 391 return; /* if we are already opted. */ 392 } 393 394 if (cci->cursor_opt) 395 return; /* if we are still nested. */ 396 /* else we draw the cursor. */ 397 cstart = 0; 398 cend = ip->ftheight-1; 399 pl = VDISPLAY_LINE(v, dr_plane, (ip->cursory * ip->ftheight + cstart)); 400 ofs = (ip->cursorx * ip->ftwidth); 401 402 if (flag != DRAW_CURSOR && flag != END_CURSOROPT) { 403 /* 404 * erase the cursor 405 */ 406 int h; 407 408 if (dr_plane) { 409 for (h = cend; h >= 0; h--) { 410 asm("bfclr %0@{%1:%2}" : : "a" (pl), 411 "d" (ofs), "d" (ip->ftwidth)); 412 pl += cci->row_offset; 413 } 414 } else { 415 for (h = cend; h >= 0; h--) { 416 asm("bfchg %0@{%1:%2}" : : "a" (pl), 417 "d" (ofs), "d" (ip->ftwidth)); 418 pl += cci->row_offset; 419 } 420 } 421 } 422 423 if (flag != DRAW_CURSOR && flag != MOVE_CURSOR && 424 flag != END_CURSOROPT) 425 return; 426 427 /* 428 * draw the cursor 429 */ 430 431 ip->cursorx = MIN(ip->curx, ip->cols-1); 432 ip->cursory = ip->cury; 433 cstart = 0; 434 cend = ip->ftheight-1; 435 pl = VDISPLAY_LINE(v, dr_plane, ip->cursory * ip->ftheight + cstart); 436 ofs = ip->cursorx * ip->ftwidth; 437 438 if (dr_plane) { 439 for (h = cend; h >= 0; h--) { 440 asm("bfset %0@{%1:%2}" : : "a" (pl), 441 "d" (ofs), "d" (ip->ftwidth)); 442 pl += cci->row_offset; 443 } 444 } else { 445 for (h = cend; h >= 0; h--) { 446 asm("bfchg %0@{%1:%2}" : : "a" (pl), 447 "d" (ofs), "d" (ip->ftwidth)); 448 pl += cci->row_offset; 449 } 450 } 451 } 452 453 454 static inline 455 int expbits (int data) 456 { 457 int i, nd = 0; 458 459 if (data & 1) 460 nd |= 0x02; 461 for (i=1; i < 32; i++) { 462 if (data & (1 << i)) 463 nd |= 0x5 << (i-1); 464 } 465 nd &= ~data; 466 return(~nd); 467 } 468 469 470 /* Notes: optimizations given the kernel_font_(width|height) #define'd. 471 * the dbra loops could be elminated and unrolled using height, 472 * the :width in the bfxxx instruction could be made immediate instead 473 * of a data register as it now is. 474 * the underline could be added when the loop is unrolled 475 * 476 * It would look like hell but be very fast.*/ 477 478 static void 479 putc_nm (cci,p,f,co,ro,fw,fh) 480 register ipriv_t *cci; 481 register u_char *p; 482 register u_char *f; 483 register u_int co; 484 register u_int ro; 485 register u_int fw; 486 register u_int fh; 487 { 488 while (fh--) { 489 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 490 "d" (*f++), "a" (p), "d" (co), "d" (fw)); 491 p += ro; 492 } 493 } 494 495 static void 496 putc_in (cci,p,f,co,ro,fw,fh) 497 register ipriv_t *cci; 498 register u_char *p; 499 register u_char *f; 500 register u_int co; 501 register u_int ro; 502 register u_int fw; 503 register u_int fh; 504 { 505 while (fh--) { 506 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 507 "d" (~(*f++)), "a" (p), "d" (co), "d" (fw)); 508 p += ro; 509 } 510 } 511 512 513 static void 514 putc_ul (cci,p,f,co,ro,fw,fh) 515 register ipriv_t *cci; 516 register u_char *p; 517 register u_char *f; 518 register u_int co; 519 register u_int ro; 520 register u_int fw; 521 register u_int fh; 522 { 523 int underline = cci->underline; 524 while (underline--) { 525 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 526 "d" (*f++), "a" (p), "d" (co), "d" (fw)); 527 p += ro; 528 } 529 530 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 531 "d" (expbits(*f++)), "a" (p), "d" (co), "d" (fw)); 532 p += ro; 533 534 underline = fh - cci->underline - 1; 535 while (underline--) { 536 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 537 "d" (*f++), "a" (p), "d" (co), "d" (fw)); 538 p += ro; 539 } 540 } 541 542 543 static void 544 putc_ul_in (cci,p,f,co,ro,fw,fh) 545 register ipriv_t *cci; 546 register u_char *p; 547 register u_char *f; 548 register u_int co; 549 register u_int ro; 550 register u_int fw; 551 register u_int fh; 552 { 553 int underline = cci->underline; 554 while (underline--) { 555 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 556 "d" (~(*f++)), "a" (p), "d" (co), "d" (fw)); 557 p += ro; 558 } 559 560 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 561 "d" (~expbits(*f++)), "a" (p), "d" (co), "d" (fw)); 562 p += ro; 563 564 underline = fh - cci->underline - 1; 565 while (underline--) { 566 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 567 "d" (~(*f++)), "a" (p), "d" (co), "d" (fw)); 568 p += ro; 569 } 570 } 571 572 /* bold */ 573 static void 574 putc_bd (cci,p,f,co,ro,fw,fh) 575 register ipriv_t *cci; 576 register u_char *p; 577 register u_char *f; 578 register u_int co; 579 register u_int ro; 580 register u_int fw; 581 register u_int fh; 582 { 583 u_short ch; 584 585 while (fh--) { 586 ch = *f++; 587 ch |= ch << 1; 588 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 589 "d" (ch), "a" (p), "d" (co), "d" (fw+1)); 590 p += ro; 591 } 592 } 593 594 static void 595 putc_bd_in (cci,p,f,co,ro,fw,fh) 596 register ipriv_t *cci; 597 register u_char *p; 598 register u_char *f; 599 register u_int co; 600 register u_int ro; 601 register u_int fw; 602 register u_int fh; 603 { 604 u_short ch; 605 606 while (fh--) { 607 ch = *f++; 608 ch |= ch << 1; 609 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 610 "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1)); 611 p += ro; 612 } 613 } 614 615 616 static void 617 putc_bd_ul (cci,p,f,co,ro,fw,fh) 618 register ipriv_t *cci; 619 register u_char *p; 620 register u_char *f; 621 register u_int co; 622 register u_int ro; 623 register u_int fw; 624 register u_int fh; 625 { 626 int underline = cci->underline; 627 u_short ch; 628 629 while (underline--) { 630 ch = *f++; 631 ch |= ch << 1; 632 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 633 "d" (ch), "a" (p), "d" (co), "d" (fw+1)); 634 p += ro; 635 } 636 637 ch = *f++; 638 ch |= ch << 1; 639 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 640 "d" (expbits(ch)), "a" (p), "d" (co), "d" (fw+1)); 641 p += ro; 642 643 underline = fh - cci->underline - 1; 644 while (underline--) { 645 ch = *f++; 646 ch |= ch << 1; 647 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 648 "d" (ch), "a" (p), "d" (co), "d" (fw+1)); 649 p += ro; 650 } 651 } 652 653 654 static void 655 putc_bd_ul_in (cci,p,f,co,ro,fw,fh) 656 register ipriv_t *cci; 657 register u_char *p; 658 register u_char *f; 659 register u_int co; 660 register u_int ro; 661 register u_int fw; 662 register u_int fh; 663 { 664 int underline = cci->underline; 665 u_short ch; 666 667 while (underline--) { 668 ch = *f++; 669 ch |= ch << 1; 670 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 671 "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1)); 672 p += ro; 673 } 674 675 ch = *f++; 676 ch |= ch << 1; 677 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 678 "d" (~expbits(ch)), "a" (p), "d" (co), "d" (fw+1)); 679 p += ro; 680 681 underline = fh - cci->underline - 1; 682 while (underline--) { 683 ch = *f++; 684 ch |= ch << 1; 685 asm ("bfins %0,%1@{%2:%3}" : /* no output */ : 686 "d" (~(ch)), "a" (p), "d" (co), "d" (fw+1)); 687 p += ro; 688 } 689 } 690 691 692 typedef void cc_putc_func (); 693 694 cc_putc_func *put_func[ATTR_ALL+1] = { 695 putc_nm, 696 putc_in, 697 putc_ul, 698 putc_ul_in, 699 putc_bd, 700 putc_bd_in, 701 putc_bd_ul, 702 putc_bd_ul_in, 703 /* no support for blink */ 704 putc_nm, 705 putc_in, 706 putc_ul, 707 putc_ul_in, 708 putc_bd, 709 putc_bd_in, 710 putc_bd_ul, 711 putc_bd_ul_in 712 }; 713 714 715 /* FIX: shouldn't this advance the cursor even if the character to 716 be output is not available in the font? -ch */ 717 718 static void 719 putc8(struct ite_softc *ip, int c, int dy, int dx, int mode) 720 { 721 register ipriv_t *cci = (ipriv_t *) ip->priv; 722 if (c < ip->font_lo || c > ip->font_hi) 723 return; 724 725 put_func[mode](cci, 726 cci->row_ptr[dy], 727 cci->font_cell[c], 728 cci->column_offset[dx], 729 cci->row_offset, 730 cci->ft_x, 731 cci->ft_y); 732 } 733 734 static void 735 clear8(struct ite_softc *ip, int sy, int sx, int h, int w) 736 { 737 ipriv_t *cci = (ipriv_t *) ip->priv; 738 view_t *v = cci->view; 739 bmap_t *bm = cci->view->bitmap; 740 741 if ((sx == 0) && (w == ip->cols)) 742 { 743 /* common case: clearing whole lines */ 744 while (h--) 745 { 746 int i; 747 u_char *ptr = cci->row_ptr[sy]; 748 for (i=0; i < ip->ftheight; i++) { 749 bzero(ptr, bm->bytes_per_row); 750 ptr += bm->bytes_per_row + bm->row_mod; /* don't get any smart 751 ideas, becuase this is for 752 interleaved bitmaps */ 753 } 754 sy++; 755 } 756 } 757 else 758 { 759 /* clearing only part of a line */ 760 /* XXX could be optimized MUCH better, but is it worth the trouble? */ 761 while (h--) 762 { 763 u_char *pl = cci->row_ptr[sy]; 764 int ofs = sx * ip->ftwidth; 765 int i, j; 766 for (i = w-1; i >= 0; i--) 767 { 768 u_char *ppl = pl; 769 for (j = ip->ftheight-1; j >= 0; j--) 770 { 771 asm("bfclr %0@{%1:%2}" 772 : : "a" (ppl), "d" (ofs), "d" (ip->ftwidth)); 773 ppl += bm->row_mod + bm->bytes_per_row; 774 } 775 ofs += ip->ftwidth; 776 } 777 sy++; 778 } 779 } 780 } 781 782 /* Note: sx is only relevant for SCROLL_LEFT or SCROLL_RIGHT. */ 783 static void 784 scroll8(ip, sy, sx, count, dir) 785 register struct ite_softc *ip; 786 register int sy; 787 int dir, sx, count; 788 { 789 bmap_t *bm = ((ipriv_t *)ip->priv)->view->bitmap; 790 u_char *pl = ((ipriv_t *)ip->priv)->row_ptr[sy]; 791 792 if (dir == SCROLL_UP) 793 { 794 int dy = sy - count; 795 int height = ip->bottom_margin - sy + 1; 796 int i; 797 798 /*FIX: add scroll bitmap call */ 799 cursor32(ip, ERASE_CURSOR); 800 scrollbmap (bm, 0, dy*ip->ftheight, 801 bm->bytes_per_row >> 3, (ip->bottom_margin-dy+1)*ip->ftheight, 802 0, -(count*ip->ftheight), 0x1); 803 /* if (ip->cursory <= bot || ip->cursory >= dy) { 804 ip->cursory -= count; 805 } */ 806 } 807 else if (dir == SCROLL_DOWN) 808 { 809 int dy = sy + count; 810 int height = ip->bottom_margin - dy + 1; 811 int i; 812 813 /* FIX: add scroll bitmap call */ 814 cursor32(ip, ERASE_CURSOR); 815 scrollbmap (bm, 0, sy*ip->ftheight, 816 bm->bytes_per_row >> 3, (ip->bottom_margin-sy+1)*ip->ftheight, 817 0, count*ip->ftheight, 0x1); 818 /* if (ip->cursory <= bot || ip->cursory >= sy) { 819 ip->cursory += count; 820 } */ 821 } 822 else if (dir == SCROLL_RIGHT) 823 { 824 int sofs = (ip->cols - count) * ip->ftwidth; 825 int dofs = (ip->cols) * ip->ftwidth; 826 int i, j; 827 828 cursor32(ip, ERASE_CURSOR); 829 for (j = ip->ftheight-1; j >= 0; j--) 830 { 831 int sofs2 = sofs, dofs2 = dofs; 832 for (i = (ip->cols - (sx + count))-1; i >= 0; i--) 833 { 834 int t; 835 sofs2 -= ip->ftwidth; 836 dofs2 -= ip->ftwidth; 837 asm("bfextu %1@{%2:%3},%0" 838 : "=d" (t) 839 : "a" (pl), "d" (sofs2), "d" (ip->ftwidth)); 840 asm("bfins %3,%0@{%1:%2}" 841 : : "a" (pl), "d" (dofs2), "d" (ip->ftwidth), "d" (t)); 842 } 843 pl += bm->row_mod + bm->bytes_per_row; 844 } 845 } 846 else /* SCROLL_LEFT */ 847 { 848 int sofs = (sx) * ip->ftwidth; 849 int dofs = (sx - count) * ip->ftwidth; 850 int i, j; 851 852 cursor32(ip, ERASE_CURSOR); 853 for (j = ip->ftheight-1; j >= 0; j--) 854 { 855 int sofs2 = sofs, dofs2 = dofs; 856 for (i = (ip->cols - sx)-1; i >= 0; i--) 857 { 858 int t; 859 asm("bfextu %1@{%2:%3},%0" 860 : "=d" (t) 861 : "a" (pl), "d" (sofs2), "d" (ip->ftwidth)); 862 asm("bfins %3,%0@{%1:%2}" 863 : : "a" (pl), "d" (dofs2), "d" (ip->ftwidth), "d" (t)); 864 sofs2 += ip->ftwidth; 865 dofs2 += ip->ftwidth; 866 } 867 pl += bm->row_mod + bm->bytes_per_row; 868 } 869 } 870 } 871 872 void 873 scrollbmap (bmap_t *bm, u_short x, u_short y, u_short width, u_short height, short dx, short dy, u_char mask) 874 { 875 u_short depth = bm->depth; 876 u_short lwpr = bm->bytes_per_row >> 2; 877 if (dx) { 878 /* FIX: */ panic ("delta x not supported in scroll bitmap yet."); 879 } 880 if (bm->flags & BMF_INTERLEAVED) { 881 height *= depth; 882 depth = 1; 883 } 884 if (dy == 0) { 885 return; 886 } 887 if (dy > 0) { 888 int i; 889 for (i=0; i < depth && mask; i++, mask >>= 1) { 890 if (0x1 & mask) { 891 u_long *pl = (u_long *)bm->plane[i]; 892 u_long *src_y = pl + (lwpr*y); 893 u_long *dest_y = pl + (lwpr*(y+dy)); 894 u_long count = lwpr*(height-dy); 895 u_long *clr_y = src_y; 896 u_long clr_count = dest_y - src_y; 897 u_long bc, cbc; 898 899 src_y += count - 1; 900 dest_y += count - 1; 901 902 bc = count >> 4; 903 count &= 0xf; 904 905 while (bc--) { 906 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 907 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 908 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 909 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 910 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 911 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 912 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 913 *dest_y-- = *src_y--; *dest_y-- = *src_y--; 914 } 915 while (count--) { 916 *dest_y-- = *src_y--; 917 } 918 919 cbc = clr_count >> 4; 920 clr_count &= 0xf; 921 922 while (cbc--) { 923 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 924 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 925 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 926 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 927 } 928 while (clr_count--) { 929 *clr_y++ = 0; 930 } 931 } 932 } 933 } else if (dy < 0) { 934 int i; 935 for (i=0; i < depth && mask; i++, mask >>= 1) { 936 if (0x1 & mask) { 937 u_long *pl = (u_long *)bm->plane[i]; 938 u_long *src_y = pl + (lwpr*(y-dy)); 939 u_long *dest_y = pl + (lwpr*y); 940 long count = lwpr*(height + dy); 941 u_long *clr_y = dest_y + count; 942 u_long clr_count = src_y - dest_y; 943 u_long bc, cbc; 944 945 bc = count >> 4; 946 count &= 0xf; 947 948 while (bc--) { 949 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 950 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 951 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 952 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 953 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 954 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 955 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 956 *dest_y++ = *src_y++; *dest_y++ = *src_y++; 957 } 958 while (count--) { 959 *dest_y++ = *src_y++; 960 } 961 962 cbc = clr_count >> 4; 963 clr_count &= 0xf; 964 965 while (cbc--) { 966 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 967 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 968 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 969 *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; *clr_y++ = 0; 970 } 971 while (clr_count--) { 972 *clr_y++ = 0; 973 } 974 } 975 } 976 } 977 } 978 #endif 979