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