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