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