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