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