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