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