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