1 /*- 2 * Copyright (c) 2000 Jukka Andberg. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * wscons interface to amiga custom chips. Contains the necessary functions 30 * to render text on bitmapped screens. Uses the functions defined in 31 * grfabs_reg.h for display creation/destruction and low level setup. 32 */ 33 34 #include "amidisplaycc.h" 35 #include "grfcc.h" 36 #include "view.h" 37 38 #if NAMIDISPLAYCC>0 39 40 #include <sys/param.h> 41 #include <sys/types.h> 42 #include <sys/device.h> 43 #include <sys/malloc.h> 44 #include <sys/systm.h> 45 46 #include <sys/conf.h> 47 48 #include <amiga/dev/grfabs_reg.h> 49 #include <amiga/dev/viewioctl.h> 50 #include <amiga/amiga/device.h> 51 #include <dev/wscons/wsconsio.h> 52 #include <dev/rcons/raster.h> 53 #include <dev/wscons/wscons_raster.h> 54 #include <dev/wscons/wsdisplayvar.h> 55 #include <dev/cons.h> 56 57 struct amidisplaycc_softc 58 { 59 struct device dev; 60 }; 61 62 63 /* 64 * Configuration stuff. 65 */ 66 67 static int amidisplaycc_match __P((struct device *, 68 struct cfdata *, 69 void *)); 70 static void amidisplaycc_attach __P((struct device *, 71 struct device *, 72 void *)); 73 74 struct cfattach amidisplaycc_ca = { 75 sizeof(struct amidisplaycc_softc), 76 amidisplaycc_match, 77 amidisplaycc_attach 78 }; 79 80 cons_decl(amidisplaycc_); 81 82 /* end of configuration stuff */ 83 84 /* These can be lowered if you are sure you dont need that much colors. */ 85 #define MAXDEPTH 8 86 #define MAXCOLORS (1<<MAXDEPTH) 87 #define MAXROWS 128 88 89 /* Perform validity checking on parameters on some functions? */ 90 #define PARANOIA 91 92 #define ADJUSTCOLORS 93 94 /* emulops for wscons */ 95 void amidisplaycc_cursor __P(( void *, int, int, int )); 96 int amidisplaycc_mapchar __P(( void *, int, unsigned int * )); 97 void amidisplaycc_putchar __P(( void *, int, int, u_int, long )); 98 void amidisplaycc_copycols __P(( void *, int, int, int, int )); 99 void amidisplaycc_erasecols __P(( void *, int, int, int, long )); 100 void amidisplaycc_copyrows __P(( void *, int, int, int )); 101 void amidisplaycc_eraserows __P(( void *, int, int, long )); 102 int amidisplaycc_alloc_attr __P(( void *, int, int, int, long * )); 103 /* end of emulops for wscons */ 104 105 /* accessops for wscons */ 106 int amidisplaycc_ioctl __P(( void *, u_long, caddr_t, 107 int, struct proc * )); 108 paddr_t amidisplaycc_mmap __P(( void *, off_t, int )); 109 int amidisplaycc_alloc_screen __P(( void *, 110 const struct wsscreen_descr *, 111 void **, int *, int *, long * )); 112 113 void amidisplaycc_free_screen __P(( void *, void * )); 114 int amidisplaycc_show_screen __P(( void *, void *, int, 115 void (*) (void *, int, int), 116 void * )); 117 int amidisplaycc_load_font __P(( void *, void *, 118 struct wsdisplay_font * )); 119 /* end of accessops for wscons */ 120 121 /* 122 * These structures are passed to wscons, and they contain the 123 * display-specific callback functions. 124 */ 125 126 const struct wsdisplay_accessops amidisplaycc_accessops = { 127 amidisplaycc_ioctl, 128 amidisplaycc_mmap, 129 amidisplaycc_alloc_screen, 130 amidisplaycc_free_screen, 131 amidisplaycc_show_screen, 132 amidisplaycc_load_font 133 }; 134 135 const struct wsdisplay_emulops amidisplaycc_emulops = { 136 amidisplaycc_cursor, 137 amidisplaycc_mapchar, 138 amidisplaycc_putchar, 139 amidisplaycc_copycols, 140 amidisplaycc_erasecols, 141 amidisplaycc_copyrows, 142 amidisplaycc_eraserows, 143 amidisplaycc_alloc_attr 144 }; 145 146 /* add some of our own data to the wsscreen_descr */ 147 struct amidisplaycc_screen_descr { 148 struct wsscreen_descr wsdescr; 149 int depth; 150 }; 151 152 /* 153 * List of supported screenmodes. Almost anything can be given here. 154 */ 155 156 #define ADCC_SCREEN(width,height,depth) { {#width "x" #height "x" #depth, width/8, height/8, &amidisplaycc_emulops, 8, 8, WSSCREEN_WSCOLORS|WSSCREEN_REVERSE|WSSCREEN_HILIT|WSSCREEN_UNDERLINE},depth } 157 158 struct amidisplaycc_screen_descr amidisplaycc_screentab[] = { 159 ADCC_SCREEN(640,400,1), 160 ADCC_SCREEN(640,400,2), 161 ADCC_SCREEN(640,400,3), 162 ADCC_SCREEN(640,400,4), 163 164 ADCC_SCREEN(640,200,1), 165 ADCC_SCREEN(640,200,2), 166 ADCC_SCREEN(640,200,3), 167 ADCC_SCREEN(640,200,4), 168 169 ADCC_SCREEN(640,480,1), 170 ADCC_SCREEN(640,480,2), 171 ADCC_SCREEN(640,480,3), 172 ADCC_SCREEN(640,480,4), 173 }; 174 175 #define ADCC_SCREENPTR(index) &amidisplaycc_screentab[index].wsdescr 176 const struct wsscreen_descr *amidisplaycc_screens[] = { 177 ADCC_SCREENPTR(0), 178 ADCC_SCREENPTR(1), 179 ADCC_SCREENPTR(2), 180 ADCC_SCREENPTR(3), 181 ADCC_SCREENPTR(4), 182 ADCC_SCREENPTR(5), 183 ADCC_SCREENPTR(6), 184 ADCC_SCREENPTR(7), 185 ADCC_SCREENPTR(8), 186 ADCC_SCREENPTR(9), 187 ADCC_SCREENPTR(10), 188 ADCC_SCREENPTR(11) 189 }; 190 191 /* 192 * This structure also is passed to wscons. It contains pointers 193 * to the available display modes. 194 */ 195 196 const struct wsscreen_list amidisplaycc_screenlist = { 197 sizeof(amidisplaycc_screens)/sizeof(amidisplaycc_screens[0]), 198 amidisplaycc_screens 199 }; 200 201 /* 202 * Our own screen structure. One will be created for each screen. 203 */ 204 205 struct amidisplaycc_screen 206 { 207 int isconsole; 208 int isvisible; 209 view_t *view; 210 211 int ncols; 212 int nrows; 213 214 /* 215 * For each row store which bitplanes contain 216 * data (just optimisation) 217 */ 218 int rowmasks[MAXROWS]; 219 220 /* Mapping of colors to screen colors. Currently mostly unused. */ 221 int colormap[MAXCOLORS]; 222 223 int fontheight; 224 }; 225 226 typedef struct amidisplaycc_screen adccscr_t; 227 228 /* 229 * Need one statically allocated screen for early init. 230 * The rest are mallocated when needed. 231 */ 232 adccscr_t amidisplaycc_consolescreen; 233 234 235 /* 236 * This gets called at console init to determine the priority of 237 * this console device. 238 * 239 * Of course pointers to this and other functions must present 240 * in constab[] in conf.c for this to work. 241 */ 242 void 243 amidisplaycc_cnprobe(cd) 244 struct consdev *cd; 245 { 246 cd->cn_pri = CN_INTERNAL; 247 248 /* 249 * Yeah, real nice. But if we win the console then the wscons system 250 * does the proper initialization. 251 */ 252 cd->cn_dev = NODEV; 253 } 254 255 /* 256 * This gets called if this device is used as the console. 257 */ 258 void 259 amidisplaycc_cninit(cd) 260 struct consdev *cd; 261 { 262 int x,y; 263 void *cookie; 264 long attr; 265 266 /* Yeah, we got the console! */ 267 268 /* 269 * This will do the basic stuff we also need. 270 */ 271 config_console(); 272 273 /* 274 * Call the init function in grfabs.c if we have 275 * no grfcc to do it. 276 * If grfcc is present it will call grfcc_probe() 277 * during config_console() above. 278 */ 279 #if NGRFCC==0 280 grfcc_probe(); 281 #endif 282 283 #if NVIEW>0 284 viewprobe(); 285 #endif 286 287 /* 288 * Set up wscons to handle the details. 289 * It will then call us back when it needs something 290 * display-specific. It will also set up cn_tab properly, 291 * something which we failed to do at amidisplaycc_cnprobe(). 292 */ 293 294 amidisplaycc_alloc_screen(NULL, &amidisplaycc_screentab[0].wsdescr, 295 &cookie, &x, &y, &attr); 296 wsdisplay_cnattach(&amidisplaycc_screentab[0].wsdescr, 297 cookie, x, y, attr); 298 } 299 300 int 301 amidisplaycc_match(pdp,cfp,auxp) 302 struct device *pdp; 303 struct cfdata *cfp; 304 void *auxp; 305 { 306 char *name = auxp; 307 308 if (matchname("amidisplaycc",name)==0) 309 return (0); 310 311 /* Allow only one of us now. Not sure about that. */ 312 if (cfp->cf_unit != 0) 313 return (0); 314 315 return 1; 316 } 317 318 void 319 amidisplaycc_attach(pdp,dp,auxp) 320 struct device *pdp; 321 struct device *dp; 322 void *auxp; 323 { 324 struct wsemuldisplaydev_attach_args waa; 325 326 /* 327 * Attach only at real configuration time. Console init is done at 328 * the amidisplaycc_cninit function above. 329 */ 330 if (dp) { 331 printf("\n"); 332 333 waa.console = 1; 334 waa.scrdata = &amidisplaycc_screenlist; 335 waa.accessops = &amidisplaycc_accessops; 336 waa.accesscookie = NULL; 337 config_found(dp,&waa,wsemuldisplaydevprint); 338 } 339 } 340 341 342 /* 343 * Color, bgcolor and style are packed into one long attribute. 344 * These macros are used to create/split the attribute 345 */ 346 347 #define MAKEATTR(fg, bg, mode) (((fg)<<16) | ((bg)<<8) | (mode)) 348 #define ATTRFG(attr) (((attr)>>16) & 255) 349 #define ATTRBG(attr) (((attr)>>8) & 255) 350 #define ATTRMO(attr) ((attr) & 255) 351 352 /* 353 * Called by wscons to draw/clear the cursor. 354 * We do this by xorring the block to the screen. 355 * 356 * This simple implementation will break if the screen is modified 357 * under the cursor before clearing it. 358 */ 359 void 360 amidisplaycc_cursor(screen, on, row, col) 361 void *screen; 362 int on; 363 int row; 364 int col; 365 { 366 adccscr_t *scr; 367 u_char *plane; 368 int y; 369 int miny; 370 int maxy; 371 372 scr = screen; 373 374 #ifdef PARANOIA 375 if (row < 0 || col < 0 || row >= scr->nrows || col >= scr->ncols) 376 return; 377 #endif 378 379 miny = row * scr->fontheight; 380 maxy = miny + scr->fontheight; 381 382 for (y = miny ; y < maxy ; y++) { 383 plane = col + VDISPLAY_LINE(scr->view, 0, y); 384 *plane ^= 255; 385 } 386 387 } 388 389 /* 390 * This obviously does something important, don't ask me what. 391 */ 392 int 393 amidisplaycc_mapchar(screen, ch, chp) 394 void *screen; 395 int ch; 396 unsigned int *chp; 397 { 398 if (ch > 0 && ch < 256) { 399 *chp = ch; 400 return (5); 401 } 402 *chp = ' '; 403 return (0); 404 } 405 406 extern unsigned char kernel_font_8x8[]; 407 408 /* Write a character to screen with color / bgcolor / hilite(bold) / 409 * underline / inverse. 410 * Surely could be made faster but I'm not sure if its worth the 411 * effort as scrolling is at least a magnitude slower. 412 */ 413 void 414 amidisplaycc_putchar(screen, row, col, ch, attr) 415 void *screen; 416 int row; 417 int col; 418 u_int ch; 419 long attr; 420 { 421 bmap_t *bitmap; 422 u_char *dst; 423 adccscr_t *scr; 424 u_char *font; 425 u_char f; 426 int j; 427 int fgcolor; 428 int bgcolor; 429 int plane; 430 int depth; 431 int rowsize; 432 int fontoffset; 433 int bmapoffset; 434 int mode; 435 int bold; 436 int underline; 437 438 scr = screen; 439 440 #ifdef PARANOIA 441 if (row < 0 || col < 0 || row >= scr->nrows || col >= scr->ncols) 442 return; 443 #endif 444 445 bitmap = scr->view->bitmap; 446 depth = bitmap->depth; 447 rowsize = bitmap->bytes_per_row + bitmap->row_mod; 448 449 /* Extract the colors from the attribute */ 450 fgcolor = ATTRFG(attr); 451 bgcolor = ATTRBG(attr); 452 mode = ATTRMO(attr); 453 454 /* Translate to screen colors */ 455 fgcolor = scr->colormap[fgcolor]; 456 bgcolor = scr->colormap[bgcolor]; 457 458 if(mode & WSATTR_REVERSE) { 459 j = fgcolor; 460 fgcolor = bgcolor; 461 bgcolor = j; 462 } 463 464 if (mode & WSATTR_HILIT) 465 bold = 1; 466 else 467 bold = 0; 468 469 470 if (mode & WSATTR_UNDERLINE) 471 underline = 1; 472 else 473 underline = 0; 474 475 476 if (ch < 32) 477 ch = 32; 478 if (ch > 255) 479 ch = 255; 480 481 482 fontoffset = scr->fontheight * (ch - 32); 483 bmapoffset = row * scr->fontheight * rowsize + col; 484 485 scr->rowmasks[row] |= fgcolor | bgcolor; 486 487 for (plane = 0 ; plane < depth ; plane++) { 488 dst = bitmap->plane[plane] + bmapoffset; 489 490 if (fgcolor & 1) { 491 if (bgcolor & 1) { 492 /* fg=on bg=on (fill) */ 493 494 for (j = 0 ; j < scr->fontheight ; j++) 495 { 496 *dst = 255; 497 dst += rowsize; 498 } 499 } else { 500 /* fg=on bg=off (normal) */ 501 502 font = &kernel_font_8x8[fontoffset]; 503 for (j = 0 ; j < scr->fontheight ; j++) 504 { 505 f = *(font++); 506 f |= f>>bold; 507 *dst = f; 508 dst += rowsize; 509 } 510 511 /* XXX underline does not recognise baseline */ 512 if (underline) 513 *(dst-rowsize) = 255; 514 } 515 } else { 516 if (bgcolor & 1) { 517 /* fg=off bg=on (inverted) */ 518 519 font = &kernel_font_8x8[fontoffset]; 520 for (j = 0 ; j < scr->fontheight ; j++) { 521 f = *(font++); 522 f |= f>>bold; 523 *dst = ~f; 524 dst += rowsize; 525 } 526 527 /* XXX underline does not recognise baseline */ 528 if (underline) 529 *(dst-rowsize) = 0; 530 } else { 531 /* fg=off bg=off (clear) */ 532 533 for (j = 0 ; j < scr->fontheight ; j++) { 534 *dst = 0; 535 dst += rowsize; 536 } 537 } 538 } 539 fgcolor >>= 1; 540 bgcolor >>= 1; 541 } 542 } 543 544 545 void 546 amidisplaycc_copycols(screen, row, srccol, dstcol, ncols) 547 void *screen; 548 int row; 549 int srccol; 550 int dstcol; 551 int ncols; 552 { 553 bmap_t *bitmap; 554 adccscr_t *scr; 555 int depth; 556 int i; 557 int j; 558 int plane; 559 int rowsize; 560 u_char *buf; 561 562 scr = screen; 563 564 #ifdef PARANOIA 565 if (srccol < 0 || srccol + ncols > scr->ncols || 566 dstcol < 0 || dstcol + ncols > scr->ncols || 567 row < 0 || row >= scr->nrows) 568 return; 569 #endif 570 571 bitmap = scr->view->bitmap; 572 depth = bitmap->depth; 573 rowsize = bitmap->bytes_per_row + bitmap->row_mod; 574 575 for (plane = 0 ; plane < depth ; plane++) { 576 buf = bitmap->plane[plane] + row*scr->fontheight*rowsize; 577 578 for (j = 0 ; j < scr->fontheight ; j++) { 579 580 if (srccol < dstcol) { 581 582 for (i = ncols - 1 ; i >= 0 ; i--) 583 buf[dstcol + i] = buf[srccol + i]; 584 585 } else { 586 587 for (i = 0 ; i < ncols ; i++) 588 buf[dstcol + i] = buf[srccol + i]; 589 590 } 591 buf += rowsize; 592 } 593 } 594 } 595 596 void 597 amidisplaycc_erasecols(screen, row, startcol, ncols, attr) 598 void *screen; 599 int row; 600 int startcol; 601 int ncols; 602 long attr; 603 { 604 bmap_t *bitmap; 605 adccscr_t *scr; 606 u_char *buf; 607 int depth; 608 int j; 609 int plane; 610 int rowsize; 611 int fill; 612 int bgcolor; 613 614 scr = screen; 615 616 #ifdef PARANOIA 617 if (row < 0 || row >= scr->nrows || 618 startcol < 0 || startcol + ncols > scr->ncols) 619 return; 620 #endif 621 622 bitmap = scr->view->bitmap; 623 depth = bitmap->depth; 624 rowsize = bitmap->bytes_per_row + bitmap->row_mod; 625 626 bgcolor = ATTRBG(attr); 627 bgcolor = scr->colormap[bgcolor]; 628 629 for(plane = 0 ; plane < depth ; plane++) { 630 631 fill = (bgcolor & 1) ? 255 : 0; 632 633 buf = bitmap->plane[plane]; 634 buf += row * scr->fontheight * rowsize; 635 buf += startcol; 636 637 for (j = 0 ; j < scr->fontheight ; j++) 638 { 639 memset(buf, fill, ncols); 640 buf += rowsize; 641 } 642 } 643 } 644 645 void 646 amidisplaycc_copyrows(screen, srcrow, dstrow, nrows) 647 void *screen; 648 int srcrow; 649 int dstrow; 650 int nrows; 651 { 652 bmap_t *bitmap; 653 adccscr_t *scr; 654 u_char *src; 655 u_char *dst; 656 657 int depth; 658 int plane; 659 int i; 660 int j; 661 int rowmod; 662 int bytesperrow; 663 int rowsize; 664 int srcmask; 665 int dstmask; 666 int srcbmapoffset; 667 int dstbmapoffset; 668 int copysize; 669 int bmdelta; 670 int rowdelta; 671 int bmwidth; 672 673 scr = screen; 674 675 #ifdef PARANOIA 676 if (srcrow < 0 || srcrow + nrows > scr->nrows || 677 dstrow < 0 || dstrow + nrows > scr->nrows) 678 return; 679 #endif 680 681 bitmap = scr->view->bitmap; 682 depth = bitmap->depth; 683 rowmod = bitmap->row_mod; 684 bytesperrow = bitmap->bytes_per_row; 685 bmwidth = bytesperrow+rowmod; 686 rowsize = bmwidth*scr->fontheight; 687 688 srcbmapoffset = rowsize*srcrow; 689 dstbmapoffset = rowsize*dstrow; 690 691 if (srcrow < dstrow) { 692 /* Move data downwards, need to copy from down to up */ 693 bmdelta = -rowsize; 694 rowdelta = -1; 695 696 srcbmapoffset += rowsize * (nrows - 1); 697 srcrow += nrows - 1; 698 699 dstbmapoffset += rowsize * (nrows - 1); 700 dstrow += nrows - 1; 701 } else { 702 /* Move data upwards, copy up to down */ 703 bmdelta = rowsize; 704 rowdelta = 1; 705 } 706 707 if (rowmod == 0) 708 copysize = rowsize; 709 else 710 copysize = 0; 711 712 for (j = 0 ; j < nrows ; j++) { 713 /* Need to copy only planes that have data on src or dst */ 714 srcmask = scr->rowmasks[srcrow]; 715 dstmask = scr->rowmasks[dstrow]; 716 scr->rowmasks[dstrow] = srcmask; 717 718 for (plane = 0 ; plane < depth ; plane++) { 719 720 if (srcmask & 1) { 721 /* 722 * Source row has data on this 723 * plane, copy it 724 */ 725 726 src = bitmap->plane[plane] + srcbmapoffset; 727 dst = bitmap->plane[plane] + dstbmapoffset; 728 729 if (copysize > 0) { 730 731 /* Do it all */ 732 memcpy(dst,src,copysize); 733 734 } else { 735 736 /* 737 * Data not continuous, 738 * must do in pieces 739 */ 740 for (i=0 ; i < scr->fontheight ; i++) { 741 memcpy(dst, src, bytesperrow); 742 743 src += bmwidth; 744 dst += bmwidth; 745 } 746 } 747 } else if (dstmask & 1) { 748 /* 749 * Source plane is empty, but dest is not. 750 * so all we need to is clear it. 751 */ 752 753 dst = bitmap->plane[plane] + dstbmapoffset; 754 755 if (copysize > 0) { 756 /* Do it all */ 757 bzero(dst, copysize); 758 } else { 759 for (i = 0 ; 760 i < scr->fontheight ; i++) { 761 bzero(dst, bytesperrow); 762 dst += bmwidth; 763 } 764 } 765 } 766 767 srcmask >>= 1; 768 dstmask >>= 1; 769 } 770 srcbmapoffset += bmdelta; 771 dstbmapoffset += bmdelta; 772 773 srcrow += rowdelta; 774 dstrow += rowdelta; 775 } 776 } 777 778 void 779 amidisplaycc_eraserows(screen, row, nrows, attr) 780 void *screen; 781 int row; 782 int nrows; 783 long attr; 784 { 785 bmap_t *bitmap; 786 adccscr_t *scr; 787 int depth; 788 int plane; 789 int j; 790 int bytesperrow; 791 int rowmod; 792 int rowsize; 793 int bmwidth; 794 int bgcolor; 795 int fill; 796 int bmapoffset; 797 int fillsize; 798 u_char *dst; 799 800 scr = screen; 801 802 #ifdef PARANOIA 803 if (row < 0 || row + nrows > scr->nrows) 804 return; 805 #endif 806 807 bitmap = scr->view->bitmap; 808 depth = bitmap->depth; 809 bytesperrow = bitmap->bytes_per_row; 810 rowmod = bitmap->row_mod; 811 bmwidth = bytesperrow + rowmod; 812 rowsize = bmwidth * scr->fontheight; 813 bmapoffset = row * rowsize; 814 815 if (rowmod == 0) 816 fillsize = rowsize * nrows; 817 else 818 fillsize = 0; 819 820 bgcolor = ATTRBG(attr); 821 bgcolor = scr->colormap[bgcolor]; 822 823 for (j = 0 ; j < nrows ; j++) 824 scr->rowmasks[row+j] = bgcolor; 825 826 for (plane = 0 ; plane < depth ; plane++) { 827 dst = bitmap->plane[plane] + bmapoffset; 828 fill = (bgcolor & 1) ? 255 : 0; 829 830 if (fillsize > 0) { 831 /* If the rows are continuous, write them all. */ 832 memset(dst, fill, fillsize); 833 } else { 834 for (j = 0 ; j < scr->fontheight * nrows ; j++) { 835 memset(dst, fill, bytesperrow); 836 dst += bmwidth; 837 } 838 } 839 bgcolor >>= 1; 840 } 841 } 842 843 int 844 amidisplaycc_alloc_attr(screen, fg, bg, flags, attrp) 845 void *screen; 846 int fg; 847 int bg; 848 int flags; 849 long *attrp; 850 { 851 adccscr_t *scr; 852 int maxcolor; 853 int newfg; 854 int newbg; 855 856 scr = screen; 857 maxcolor = (1 << scr->view->bitmap->depth) - 1; 858 859 /* Ensure the colors are displayable. */ 860 newfg = fg & maxcolor; 861 newbg = bg & maxcolor; 862 863 #ifdef ADJUSTCOLORS 864 /* 865 * Hack for low-color screens, if background color is nonzero 866 * but would be displayed as one, adjust it. 867 */ 868 if (bg > 0 && newbg == 0) 869 newbg = maxcolor; 870 871 /* 872 * If foreground and background colors are different but would 873 * display the same fix them by modifying the foreground. 874 */ 875 if (fg != bg && newfg == newbg) { 876 if (newbg > 0) 877 newfg = 0; 878 else 879 newfg = maxcolor; 880 } 881 #endif 882 *attrp = MAKEATTR(newfg, newbg, flags); 883 884 return (0); 885 } 886 887 int 888 amidisplaycc_ioctl(dp, cmd, data, flag, p) 889 void *dp; 890 u_long cmd; 891 caddr_t data; 892 int flag; 893 struct proc *p; 894 { 895 switch (cmd) 896 { 897 case WSDISPLAYIO_GTYPE: 898 *(u_int*)data = WSDISPLAY_TYPE_EGA; /* XXX */ 899 return (0); 900 } 901 902 printf("amidisplaycc_ioctl %lx (grp:'%c' num:%d)\n", 903 (long)cmd, 904 (char)((cmd&0xff00)>>8), 905 (int)(cmd&0xff)); 906 907 /* Yes, think should return -1 if didnt understand. */ 908 return (-1); 909 } 910 911 paddr_t 912 amidisplaycc_mmap(dp, off, prot) 913 void *dp; 914 off_t off; 915 int prot; 916 { 917 return (-1); 918 } 919 920 int 921 amidisplaycc_alloc_screen(dp, screenp, cookiep, curxp, curyp, defattrp) 922 void *dp; 923 const struct wsscreen_descr *screenp; 924 void **cookiep; 925 int *curxp; 926 int *curyp; 927 long *defattrp; 928 { 929 dimen_t dimension; 930 adccscr_t *scr; 931 view_t *view; 932 struct amidisplaycc_screen_descr *adccscreenp; 933 int depth; 934 int maxcolor; 935 int i; 936 int j; 937 938 adccscreenp = (struct amidisplaycc_screen_descr*)screenp; 939 depth = adccscreenp->depth; 940 941 maxcolor = (1 << depth) - 1; 942 943 /* Sanity checks because of fixed buffers */ 944 if (depth > MAXDEPTH || maxcolor >= MAXCOLORS) 945 return (ENOMEM); 946 if (screenp->nrows > MAXROWS) 947 return (ENOMEM); 948 949 dimension.width = screenp->ncols * 8; 950 dimension.height = screenp->nrows * 8; 951 952 view = grf_alloc_view(NULL, &dimension, depth); 953 if (view == NULL) 954 return (ENOMEM); 955 956 /* 957 * First screen gets the statically allocated console screen. 958 * Others are allocated dynamically. 959 */ 960 if (amidisplaycc_consolescreen.isconsole == 0) { 961 scr = &amidisplaycc_consolescreen; 962 scr->isconsole = 1; 963 } else { 964 scr = malloc(sizeof(adccscr_t), M_DEVBUF, M_WAITOK); 965 bzero(scr, sizeof(adccscr_t)); 966 } 967 968 scr->view = view; 969 scr->fontheight = 8; 970 971 scr->ncols = screenp->ncols; 972 scr->nrows = screenp->nrows; 973 974 for (i = 0 ; i < MAXROWS ; i++) 975 scr->rowmasks[i] = 0; 976 977 /* Simple one-to-one mapping for most colors */ 978 for (i = 0 ; i < MAXCOLORS ; i++) 979 scr->colormap[i] = i; 980 981 /* 982 * Arrange the most used pens to quickest colors. 983 * The default color for given depth is (1<<depth)-1. 984 * It is assumed it is used most and it is mapped to 985 * color that can be drawn by writing data to one bitplane 986 * only. 987 * So map colors 3->2, 7->4, 15->8 and so on. 988 * This of course should be reflected on the palette 989 * but currently we don't do any palette management. 990 */ 991 for (i = 2 ; i < MAXCOLORS ; i *= 2) { 992 j = i * 2 - 1; 993 994 if (j < MAXCOLORS) { 995 scr->colormap[i] = j; 996 scr->colormap[j] = i; 997 } 998 } 999 1000 *cookiep = scr; 1001 1002 *curxp = 0; 1003 *curyp = 0; 1004 amidisplaycc_cursor(scr, 1, *curxp, *curyp); 1005 1006 *defattrp = MAKEATTR(maxcolor, 0, 0); 1007 1008 /* Show the console automatically */ 1009 if (scr->isconsole) 1010 grf_display_view(scr->view); 1011 1012 return (0); 1013 } 1014 1015 void 1016 amidisplaycc_free_screen(dp, screen) 1017 void *dp; 1018 void *screen; 1019 { 1020 adccscr_t *scr; 1021 1022 scr = screen; 1023 1024 if (scr == NULL) 1025 return; 1026 1027 if (scr->view) 1028 grf_free_view(scr->view); 1029 scr->view = NULL; 1030 1031 /* Take care not to free the statically allocated console screen */ 1032 if (scr != &amidisplaycc_consolescreen) { 1033 free(scr, M_DEVBUF); 1034 } 1035 } 1036 1037 int 1038 amidisplaycc_show_screen(dp, screen, waitok, cb, cbarg) 1039 void *dp; 1040 void *screen; 1041 int waitok; 1042 void (*cb) (void *, int, int); 1043 void *cbarg; 1044 { 1045 adccscr_t *scr; 1046 1047 scr = screen; 1048 grf_display_view(scr->view); 1049 1050 return (0); 1051 } 1052 1053 /* 1054 * Load a font. Not supported yet. 1055 */ 1056 int 1057 amidisplaycc_load_font(dp, cookie, fontp) 1058 void *dp; 1059 void *cookie; 1060 struct wsdisplay_font *fontp; 1061 { 1062 return (-1); 1063 } 1064 1065 /* 1066 * These dummy functions are here just so that we can compete of 1067 * the console at init. 1068 * If we win the console then the wscons system will provide the 1069 * real ones which in turn will call the apropriate wskbd device. 1070 * These should never be called. 1071 */ 1072 1073 void 1074 amidisplaycc_cnputc(cd,ch) 1075 dev_t cd; 1076 int ch; 1077 { 1078 } 1079 1080 int 1081 amidisplaycc_cngetc(cd) 1082 dev_t cd; 1083 { 1084 return (0); 1085 } 1086 1087 void 1088 amidisplaycc_cnpollc(cd,on) 1089 dev_t cd; 1090 int on; 1091 { 1092 } 1093 1094 #endif /* AMIDISPLAYCC */ 1095 1096 1097 1098 1099