The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/pcvt/pcvt_sup.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999, 2000 Hellmuth Michaelis
    3  *
    4  * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
    5  *
    6  * Copyright (c) 1992, 1993 Brian Dunford-Shore and Scott Turner.
    7  *
    8  * Copyright (C) 1992, 1993 Soeren Schmidt.
    9  *
   10  * All rights reserved.
   11  *
   12  * For the sake of compatibility, portions of this code regarding the
   13  * X server interface are taken from Soeren Schmidt's syscons driver.
   14  *
   15  * Redistribution and use in source and binary forms, with or without
   16  * modification, are permitted provided that the following conditions
   17  * are met:
   18  * 1. Redistributions of source code must retain the above copyright
   19  *    notice, this list of conditions and the following disclaimer.
   20  * 2. Redistributions in binary form must reproduce the above copyright
   21  *    notice, this list of conditions and the following disclaimer in the
   22  *    documentation and/or other materials provided with the distribution.
   23  * 3. All advertising materials mentioning features or use of this software
   24  *    must display the following acknowledgement:
   25  *      This product includes software developed by Hellmuth Michaelis,
   26  *      Brian Dunford-Shore, Joerg Wunsch, Scott Turner and Soeren Schmidt.
   27  * 4. The name authors may not be used to endorse or promote products
   28  *    derived from this software without specific prior written permission.
   29  *
   30  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   31  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   32  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   33  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   34  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   35  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   39  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   40  */
   41 
   42 /*---------------------------------------------------------------------------*
   43  *
   44  *      pcvt_sup.c      VT220 Driver Support Routines
   45  *      ---------------------------------------------
   46  *
   47  *      Last Edit-Date: [Wed Apr  5 17:24:20 2000]
   48  *
   49  * $FreeBSD: releng/6.0/sys/i386/isa/pcvt/pcvt_sup.c 139790 2005-01-06 22:18:23Z imp $
   50  *
   51  *---------------------------------------------------------------------------*/
   52 
   53 #include <i386/isa/pcvt/pcvt_hdr.h>     /* global include */
   54 
   55 #include <sys/resource.h>
   56 
   57 static void vid_cursor ( struct cursorshape *data );
   58 static void vgasetfontattr ( struct vgafontattr *data );
   59 static void vgagetfontattr ( struct vgafontattr *data );
   60 static void vgaloadchar ( struct vgaloadchar *data );
   61 static void vid_getscreen ( struct screeninfo *data, struct cdev *dev );
   62 static void vid_setscreen ( struct screeninfo *data, struct cdev *dev );
   63 static void setchargen ( void );
   64 static void setchargen3 ( void );
   65 static void resetchargen ( void );
   66 static void vgareadpel ( struct vgapel *data, struct cdev *dev );
   67 static void vgawritepel ( struct vgapel *data, struct cdev *dev );
   68 static void vgapcvtid ( struct pcvtid *data );
   69 static void vgapcvtinfo ( struct pcvtinfo *data );
   70 
   71 #ifdef XSERVER
   72 static unsigned char * compute_charset_base ( unsigned fontset );
   73 #endif /* XSERVER */
   74 
   75 static struct callout_handle async_update_ch =
   76     CALLOUT_HANDLE_INITIALIZER(&async_update_ch);
   77 
   78 #if PCVT_SCREENSAVER
   79 static void scrnsv_timedout ( void *arg );
   80 static struct callout_handle scrnsv_timeout_ch =
   81     CALLOUT_HANDLE_INITIALIZER(&scrnsv_timeout_ch);
   82 static u_short *savedscreen = (u_short *)0;     /* ptr to screen contents */
   83 static size_t scrnsv_size = (size_t)-1;         /* size of saved image */
   84 
   85 #ifndef XSERVER
   86 static unsigned scrnsv_timeout = 0;             /* initially off */
   87 static void pcvt_set_scrnsv_tmo ( int timeout );/* else declared global */
   88 #endif /* XSERVER */
   89 
   90 #if PCVT_PRETTYSCRNS
   91 static u_short *scrnsv_current = (u_short *)0;  /* attention char ptr */
   92 static struct callout_handle scrnsv_blink_ch =
   93     CALLOUT_HANDLE_INITIALIZER(&scrnsv_blink_ch);
   94 static void scrnsv_blink ( void * );
   95 static u_short getrand ( void );
   96 #endif /* PCVT_PRETTYSCRNS */
   97 
   98 #endif /* PCVT_SCREENSAVER */
   99 
  100 
  101 /*---------------------------------------------------------------------------*
  102  *      execute vga ioctls
  103  *---------------------------------------------------------------------------*/
  104 int
  105 vgaioctl(struct cdev *dev, int cmd, caddr_t data, int flag)
  106 {
  107         if(minor(dev) >= PCVT_NSCREENS)
  108                 return -1;
  109 
  110 /*
  111  * Some of the commands are not applicable if the vt in question, or the
  112  * current vt is in graphics mode (i.e., the X server acts on it); they
  113  * will cause an EAGAIN (resource temporarily unavailable) to be returned.
  114  */
  115 
  116 #ifdef XSERVER
  117 #define is_dev_grafx vs[minor(dev)].vt_status & VT_GRAFX
  118 #define is_current_grafx vsp->vt_status & VT_GRAFX
  119 #else /* !XSERVER */
  120 #define is_dev_grafx 0
  121 #define is_current_grafx 0
  122 #endif /* XSERVER */
  123 
  124         switch(cmd)
  125         {
  126                 case VGACURSOR:
  127                         if(is_current_grafx)
  128                                 return EAGAIN;
  129                         vid_cursor((struct cursorshape *)data);
  130                         break;
  131 
  132                 case VGALOADCHAR:
  133                         if((adaptor_type != VGA_ADAPTOR) &&
  134                            (adaptor_type != EGA_ADAPTOR))
  135                                 return -1;
  136                         if(is_current_grafx)
  137                                 return EAGAIN;
  138                         vgaloadchar((struct vgaloadchar *)data);
  139                         break;
  140 
  141                 case VGASETFONTATTR:
  142                         if((adaptor_type != VGA_ADAPTOR) &&
  143                            (adaptor_type != EGA_ADAPTOR))
  144                                 return -1;
  145 
  146 #if PCVT_SCREENSAVER
  147                         pcvt_scrnsv_reset();
  148 #endif /* PCVT_SCREENSAVER */
  149 
  150                         vgasetfontattr((struct vgafontattr *)data);
  151                         break;
  152 
  153                 case VGAGETFONTATTR:
  154                         if((adaptor_type != VGA_ADAPTOR) &&
  155                            (adaptor_type != EGA_ADAPTOR))
  156                                 return -1;
  157                         vgagetfontattr((struct vgafontattr *)data);
  158                         break;
  159 
  160                 case VGASETSCREEN:
  161 #if PCVT_SCREENSAVER
  162                         pcvt_scrnsv_reset();
  163 #endif /* PCVT_SCREENSAVER */
  164 
  165                         vid_setscreen((struct screeninfo *)data, dev);
  166                         break;
  167 
  168                 case VGAGETSCREEN:
  169                         vid_getscreen((struct screeninfo *)data, dev);
  170                         break;
  171 
  172                 case VGAREADPEL:
  173                         if(adaptor_type != VGA_ADAPTOR)
  174                                 return -1;
  175                         if(is_dev_grafx)
  176                                 return EAGAIN;
  177                         vgareadpel((struct vgapel *)data, dev);
  178                         break;
  179 
  180                 case VGAWRITEPEL:
  181                         if(adaptor_type != VGA_ADAPTOR)
  182                                 return -1;
  183                         if(is_dev_grafx)
  184                                 return EAGAIN;
  185                         vgawritepel((struct vgapel *)data, dev);
  186                         break;
  187 
  188 #if PCVT_SCREENSAVER
  189                 case VGASCREENSAVER:
  190                         if(is_current_grafx)
  191                                 return EAGAIN;
  192                         pcvt_set_scrnsv_tmo(*(int *)data);
  193                         pcvt_scrnsv_reset();
  194                         break;
  195 #endif /* PCVT_SCREENSAVER */
  196 
  197                 case VGAPCVTID:
  198                         vgapcvtid((struct pcvtid *)data);
  199                         break;
  200 
  201                 case VGAPCVTINFO:
  202                         vgapcvtinfo((struct pcvtinfo *)data);
  203                         break;
  204 
  205                 case VGASETCOLMS:
  206                         if(is_dev_grafx)
  207                                 return EAGAIN;
  208                         if(*(int *)data == 80)
  209                                 (void)vt_col(&vs[minor(dev)], SCR_COL80);
  210                         else if(*(int *)data == 132)
  211                         {
  212                                 if(vt_col(&vs[minor(dev)], SCR_COL132) == 0)
  213                                         return EINVAL; /* not a VGA */
  214                         }
  215                         else
  216                                 return EINVAL;
  217                         break;
  218 
  219 #if 0                   
  220                 case SETSCROLLSIZE:
  221                         reallocate_scrollbuffer(vsp, *(u_short *)data);
  222                         break;
  223 #endif
  224 
  225                 case TIOCSWINSZ:
  226                         /* do nothing here */
  227                         break;
  228 
  229                 default:
  230                         return -1;
  231         }
  232         return 0;
  233 
  234 #undef is_dev_grafx
  235 #undef is_current_grafx
  236 }
  237 
  238 /*---------------------------------------------------------------------------*
  239  *      video ioctl - return driver id
  240  *---------------------------------------------------------------------------*/
  241 static void
  242 vgapcvtid(struct pcvtid *data)
  243 {
  244         snprintf(data->name, sizeof(data->name), "%s", PCVTIDNAME);
  245         data->rmajor    = PCVTIDMAJOR;
  246         data->rminor    = PCVTIDMINOR;
  247 }
  248 
  249 /*---------------------------------------------------------------------------*
  250  *      video ioctl - return driver compile time options data
  251  *---------------------------------------------------------------------------*/
  252 static void
  253 vgapcvtinfo(struct pcvtinfo *data)
  254 {
  255         data->nscreens  = PCVT_NSCREENS;
  256         data->scanset   = PCVT_SCANSET;
  257         data->updatefast= PCVT_UPDATEFAST;
  258         data->updateslow= PCVT_UPDATESLOW;
  259         data->sysbeepf  = PCVT_SYSBEEPF;
  260         data->pcburst   = PCVT_PCBURST;
  261         data->kbd_fifo_sz = PCVT_KBD_FIFO_SZ;
  262 
  263         data->compile_opts = (0
  264 
  265 #if PCVT_VT220KEYB
  266         | CONF_VT220KEYB
  267 #endif
  268 #if PCVT_SCREENSAVER
  269         | CONF_SCREENSAVER
  270 #endif
  271 #if PCVT_PRETTYSCRNS
  272         | CONF_PRETTYSCRNS
  273 #endif
  274 #if PCVT_CTRL_ALT_DEL
  275         | CONF_CTRL_ALT_DEL
  276 #endif
  277 #if PCVT_USEKBDSEC
  278         | CONF_USEKBDSEC
  279 #endif
  280 #if PCVT_24LINESDEF
  281         | CONF_24LINESDEF
  282 #endif
  283 #if PCVT_SHOWKEYS
  284         | CONF_SHOWKEYS
  285 #endif
  286 #if PCVT_NULLCHARS
  287         | CONF_NULLCHARS
  288 #endif
  289 #if PCVT_SETCOLOR
  290         | CONF_SETCOLOR
  291 #endif
  292 #if PCVT_132GENERIC
  293         | CONF_132GENERIC
  294 #endif
  295 #ifdef XSERVER
  296         | CONF_XSERVER
  297 #endif
  298 #if PCVT_INHIBIT_NUMLOCK
  299         | CONF_INHIBIT_NUMLOCK
  300 #endif
  301 #if PCVT_META_ESC
  302         | CONF_META_ESC
  303 #endif
  304 #if PCVT_SLOW_INTERRUPT
  305         | CONF_SLOW_INTERRUPT
  306 #endif
  307 #if PCVT_NO_LED_UPDATE
  308         | CONF_NO_LED_UPDATE
  309 #endif
  310 #if PCVT_GREENSAVER
  311         | CONF_GREENSAVER
  312 #endif
  313 
  314         );
  315 }
  316 
  317 /*---------------------------------------------------------------------------*
  318  *      video ioctl - set cursor appearence
  319  *---------------------------------------------------------------------------*/
  320 static void
  321 vid_cursor(struct cursorshape *data)
  322 {
  323         int screen;
  324         int start;
  325         int end;
  326         int line_height;
  327         int character_set;
  328 
  329         /* for which virtual screen, -1 for current */
  330         screen = data->screen_no;
  331 
  332         if(screen == -1)          /* current ? */
  333                 screen = current_video_screen;
  334         else if(screen > totalscreens - 1)
  335                 screen = totalscreens - 1;
  336         else if(screen < 0)
  337                 screen = 0;
  338 
  339         if(adaptor_type == VGA_ADAPTOR || adaptor_type == EGA_ADAPTOR)
  340         {
  341                 character_set = vs[screen].vga_charset;
  342                 character_set = (character_set < 0) ? 0 :
  343                         ((character_set < totalfonts) ?
  344                          character_set :
  345                          totalfonts-1);
  346 
  347                 line_height = vgacs[character_set].char_scanlines & 0x1F;
  348         }
  349         else if(adaptor_type == MDA_ADAPTOR)
  350         {
  351                 line_height = 14;
  352         }
  353         else
  354         {
  355                 line_height = 8;        /* CGA */
  356         }
  357 
  358         start = (data->start < 0) ? 0 :
  359                 ((data->start > line_height) ? line_height : data->start);
  360 
  361         if((vga_family == VGA_F_TRI) && (start == 0))
  362                 start = 1;
  363 
  364         end = (data->end < 0) ? 0 :
  365                 ((data->end > line_height) ? line_height : data->end);
  366 
  367         vs[screen].cursor_start = start;
  368         vs[screen].cursor_end = end;
  369 
  370         if(screen == current_video_screen)
  371         {
  372                 outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
  373                 outb(addr_6845+1, start);
  374                 outb(addr_6845,CRTC_CUREND);    /* cursor end reg */
  375                 outb(addr_6845+1, end);
  376         }
  377 }
  378 
  379 /*---------------------------------------------------------------------------*
  380  *      ega/vga ioctl - set font attributes
  381  *---------------------------------------------------------------------------*/
  382 static void
  383 vgasetfontattr(struct vgafontattr *data)
  384 {
  385         register int i;
  386         int vga_character_set;
  387         int lines_per_character;
  388         int totscanlines;
  389         int size;
  390 
  391         vga_character_set = data->character_set;
  392         vga_character_set = (vga_character_set < 0) ? 0 :
  393                 ((vga_character_set < totalfonts) ?
  394                 vga_character_set : totalfonts-1);
  395 
  396         vgacs[vga_character_set].loaded = data->font_loaded;
  397 
  398         /* Limit Characters to 32 scanlines doubled */
  399         vgacs[vga_character_set].char_scanlines =
  400                 (data->character_scanlines & 0x1F)
  401                 | 0x40; /* always set bit 9 of line cmp reg */
  402 
  403         if(adaptor_type == EGA_ADAPTOR)
  404                 /* ...and screen height to scan 350 lines */
  405                 vgacs[vga_character_set].scr_scanlines =
  406                 (data->screen_scanlines > 0x5d) ?
  407                 0x5d : data->screen_scanlines;
  408         else
  409                 /* ...and screen height to scan 480 lines */
  410                 vgacs[vga_character_set].scr_scanlines =
  411                 (data->screen_scanlines > 0xdF) ?
  412                 0xdF : data->screen_scanlines;
  413 
  414         lines_per_character =
  415                 (int)(0x1F & vgacs[vga_character_set].char_scanlines)+1;
  416 
  417         totscanlines = 0x101 + (int)vgacs[vga_character_set].scr_scanlines;
  418 
  419         size = data->screen_size;
  420 
  421         if(adaptor_type == EGA_ADAPTOR)
  422         {
  423                 switch(size)
  424                 {
  425                         case SIZ_25ROWS: /* This case is always OK */
  426                                 break;
  427 
  428                         case SIZ_35ROWS:
  429                                 if(totscanlines/lines_per_character >= 35)
  430                                         size = SIZ_35ROWS;
  431                                 else
  432                                         size = SIZ_25ROWS;
  433                                 break;
  434 
  435                         case SIZ_43ROWS:
  436                         default:
  437                                 if(totscanlines/lines_per_character >= 43)
  438                                         size = SIZ_43ROWS;
  439                                 else if(totscanlines/lines_per_character >= 35)
  440                                         size = SIZ_35ROWS;
  441                                 else
  442                                         size = SIZ_25ROWS;
  443                                 break;
  444                 }
  445         }
  446         else
  447         {
  448                 switch(size)
  449                 {
  450                         case SIZ_25ROWS: /* This case is always OK */
  451                                 break;
  452 
  453                         case SIZ_28ROWS:
  454                                 if(totscanlines/lines_per_character >= 28)
  455                                         size = SIZ_28ROWS;
  456                                 else
  457                                         size = SIZ_25ROWS;
  458                                 break;
  459 
  460                         case SIZ_40ROWS:
  461                                 if(totscanlines/lines_per_character >= 40)
  462                                         size = SIZ_40ROWS;
  463                                 else if(totscanlines/lines_per_character >= 28)
  464                                         size = SIZ_28ROWS;
  465                                 else
  466                                         size = SIZ_25ROWS;
  467                                 break;
  468 
  469                         case SIZ_50ROWS:
  470                         default:
  471                                 if(totscanlines/lines_per_character >= 50)
  472                                         size = SIZ_50ROWS;
  473                                 else if(totscanlines/lines_per_character >= 40)
  474                                         size = SIZ_40ROWS;
  475                                 else if(totscanlines/lines_per_character >= 28)
  476                                         size = SIZ_28ROWS;
  477                                 else
  478                                         size = SIZ_25ROWS;
  479                         break;
  480                 }
  481         }
  482 
  483         vgacs[vga_character_set].screen_size = size;
  484 
  485         for (i = 0;i < PCVT_NSCREENS;i++)
  486         {
  487                 if(vga_character_set == vs[i].vga_charset)
  488                         set_charset(&(vs[i]),vga_character_set);
  489         }
  490 
  491 #ifdef XSERVER
  492         switch_screen(current_video_screen, 0, 0);      
  493 #else
  494         vgapage(current_video_screen);
  495 #endif /* XSERVER */
  496 
  497 }
  498 
  499 /*---------------------------------------------------------------------------*
  500  *      ega/vga ioctl - get font attributes
  501  *---------------------------------------------------------------------------*/
  502 static void
  503 vgagetfontattr(struct vgafontattr *data)
  504 {
  505         int vga_character_set;
  506 
  507         vga_character_set = data->character_set;
  508         vga_character_set = (vga_character_set < 0) ? 0 :
  509                 ((vga_character_set < (int)totalfonts) ?
  510                  vga_character_set :
  511                  (int)(totalfonts-1));
  512 
  513         data->character_set = (int)vga_character_set;
  514 
  515         data->font_loaded = (int)vgacs[vga_character_set].loaded;
  516 
  517         data->character_scanlines =
  518                 (int)vgacs[vga_character_set].char_scanlines
  519                 & 0x1f;         /* do not display the overflow bits */
  520 
  521         data->screen_scanlines = (int)vgacs[vga_character_set].scr_scanlines;
  522 
  523         data->screen_size = (int)vgacs[vga_character_set].screen_size;
  524 }
  525 
  526 /*---------------------------------------------------------------------------*
  527  *      ega/vga ioctl - load a character shape into character set
  528  *---------------------------------------------------------------------------*/
  529 static void
  530 vgaloadchar(struct vgaloadchar *data)
  531 {
  532         int vga_character_set;
  533         int character;
  534         int lines_per_character;
  535 
  536         vga_character_set = data->character_set;
  537         vga_character_set = (vga_character_set < 0) ? 0 :
  538                 ((vga_character_set < (int)totalfonts) ?
  539                  vga_character_set : (int)(totalfonts-1));
  540 
  541         character = (data->character < 0) ? 0 :
  542                 ((data->character > 255) ? 255 : data->character);
  543 
  544         lines_per_character = (int)data->character_scanlines;
  545         lines_per_character = (lines_per_character < 0) ? 0 :
  546                 ((lines_per_character > 32) ? 32 : lines_per_character);
  547 
  548         loadchar(vga_character_set,character,lines_per_character,
  549                  data->char_table);
  550 }
  551 
  552 /*---------------------------------------------------------------------------*
  553  *      video ioctl - get screen information
  554  *---------------------------------------------------------------------------*/
  555 static void
  556 vid_getscreen(struct screeninfo *data, struct cdev *dev)
  557 {
  558         int device = minor(dev);
  559         data->adaptor_type = adaptor_type;      /* video adapter installed */
  560         data->monitor_type = color;             /* monitor type installed */
  561         data->totalfonts = totalfonts;          /* no of downloadble fonts */
  562         data->totalscreens = totalscreens;      /* no of virtual screens */
  563         data->screen_no = device;               /* this screen number */
  564         data->current_screen = current_video_screen; /* displayed screen no */
  565         /* screen size */
  566         data->screen_size = vgacs[(vs[device].vga_charset)].screen_size;
  567         /* pure VT mode or HP/VT mode */
  568         data->pure_vt_mode = vs[device].vt_pure_mode;
  569         data->vga_family = vga_family;          /* manufacturer, family */
  570         data->vga_type = vga_type;              /* detected chipset type */
  571         data->vga_132 = can_do_132col;          /* 132 column support */
  572         data->force_24lines = vs[device].force24; /* force 24 lines */
  573 }
  574 
  575 /*---------------------------------------------------------------------------*
  576  *      video ioctl - set screen information
  577  *---------------------------------------------------------------------------*/
  578 static void
  579 vid_setscreen(struct screeninfo *data, struct cdev *dev)
  580 {
  581         int screen;
  582 
  583         if(data->current_screen == -1)
  584         {
  585                 screen = minor(dev);
  586         }
  587         else
  588         {
  589                 if(data->current_screen >= PCVT_NSCREENS)
  590                         return;                                 /* XXXXXX */
  591                 screen = data->current_screen;
  592         }
  593 
  594         vgapage(screen);
  595 
  596 #ifdef XSERVER
  597         {
  598                 int x = spltty(), waitfor = screen + 1;
  599                 /* if the vt is yet to be released by a process, wait here */
  600                 if(vs[screen].vt_status & VT_WAIT_REL)
  601                         (void)usl_vt_ioctl(dev, VT_WAITACTIVE,
  602                                            (caddr_t)&waitfor, 0, 0);
  603                 splx(x);
  604         }
  605         /* make sure the switch really happened */
  606         if(screen != current_video_screen)
  607                 return;         /* XXX should say "EAGAIN" here */
  608 #endif /* XSERVER */
  609 
  610         if((data->screen_size != -1) || (data->force_24lines != -1))
  611         {
  612                 if(data->screen_size == -1)
  613                         data->screen_size =
  614                                 vgacs[(vs[screen].vga_charset)].screen_size;
  615 
  616                 if(data->force_24lines != -1)
  617                 {
  618                         vs[screen].force24 = data->force_24lines;
  619 
  620                         if(vs[screen].force24)
  621                         {
  622                                 swritefkl(2,(u_char *)"FORCE24 ENABLE *",
  623                                           &vs[screen]);
  624                         }
  625                         else
  626                         {
  627                                 swritefkl(2,(u_char *)"FORCE24 ENABLE  ",
  628                                           &vs[screen]);
  629                         }
  630                 }
  631 
  632                 if((data->screen_size == SIZ_25ROWS) ||
  633                    (data->screen_size == SIZ_28ROWS) ||
  634                    (data->screen_size == SIZ_35ROWS) ||
  635                    (data->screen_size == SIZ_40ROWS) ||
  636                    (data->screen_size == SIZ_43ROWS) ||
  637                    (data->screen_size == SIZ_50ROWS))
  638                 {
  639                         if(data->screen_no == -1)
  640                                 set_screen_size(vsp, data->screen_size);
  641                         else
  642                                 set_screen_size(&vs[minor(dev)],
  643                                                 data->screen_size);
  644                 }
  645         }
  646 
  647         if(data->pure_vt_mode != -1)
  648         {
  649                 if((data->pure_vt_mode == M_HPVT) ||
  650                    (data->pure_vt_mode == M_PUREVT))
  651                 {
  652                         if(data->screen_no == -1)
  653                                 set_emulation_mode(vsp, data->pure_vt_mode);
  654                         else
  655                                 set_emulation_mode(&vs[minor(dev)],
  656                                                    data->pure_vt_mode);
  657                 }
  658         }
  659 }
  660 
  661 /*---------------------------------------------------------------------------*
  662  *      set screen size/resolution for a virtual screen
  663  *---------------------------------------------------------------------------*/
  664 void
  665 set_screen_size(struct video_state *svsp, int size)
  666 {
  667         int i;
  668 
  669         for(i = 0; i < totalfonts; i++)
  670         {
  671                 if(vgacs[i].screen_size == size)
  672                 {
  673                         set_charset(svsp, i);
  674                         clr_parms(svsp);        /* escape parameter init */
  675                         svsp->state = STATE_INIT; /* initial state */
  676                         svsp->scrr_beg = 0;     /* start of scrolling region */
  677                         svsp->sc_flag = 0;      /* invalidate saved cursor
  678                                                  * position */
  679                         svsp->transparent = 0;  /* disable control code
  680                                                  * processing */
  681 
  682                         /* Update tty to reflect screen size */
  683 
  684                         if (svsp->vs_tty)
  685                         {
  686                                 svsp->vs_tty->t_winsize.ws_col = svsp->maxcol;
  687                                 svsp->vs_tty->t_winsize.ws_xpixel =
  688                                         (svsp->maxcol == 80)? 720: 1056;
  689                                 svsp->vs_tty->t_winsize.ws_ypixel = 400;
  690                                 svsp->vs_tty->t_winsize.ws_row =
  691                                         svsp->screen_rows;
  692                         }
  693                         /* screen_rows already calculated in set_charset() */
  694                         if(svsp->vt_pure_mode == M_HPVT && svsp->labels_on)
  695                         {
  696                                 if(svsp->which_fkl == SYS_FKL)
  697                                         sw_sfkl(svsp);
  698                                 else if(svsp->which_fkl == USR_FKL)
  699                                         sw_ufkl(svsp);
  700                         }
  701 
  702 
  703                         svsp->scrr_len = svsp->screen_rows;
  704                         svsp->scrr_end = svsp->scrr_len - 1;
  705 
  706                         if (svsp->vs_tty && svsp->vs_tty->t_pgrp) {
  707                                 PGRP_LOCK(svsp->vs_tty->t_pgrp);
  708                                 pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
  709                                 PGRP_UNLOCK(svsp->vs_tty->t_pgrp);
  710                         }
  711 
  712                         reallocate_scrollbuffer(svsp, svsp->scrollback_pages);
  713                         break;
  714                 }
  715         }
  716 }
  717 
  718 /*---------------------------------------------------------------------------*
  719  *      resize the scrollback buffer to the specified number of "pages"
  720  *---------------------------------------------------------------------------*/
  721 void
  722 reallocate_scrollbuffer(struct video_state *svsp, int pages)
  723 {
  724         int s;
  725         u_short *stmp;
  726         
  727         if(pages < 2)
  728                 pages = 2;
  729         if(pages > 50)
  730                 pages = 50;
  731 
  732         s = splhigh();
  733 
  734         if((stmp = (u_short *)malloc(svsp->maxcol * svsp->screen_rows *
  735                         pages * CHR, M_DEVBUF, M_NOWAIT)) == NULL)
  736         {
  737                 splx(s);
  738                 printf("pcvt: reallocate_scrollbuffer, malloc failed\n");
  739                 return;
  740         }
  741 
  742         svsp->max_off = svsp->screen_rows * pages - 1;
  743         
  744         if(svsp->Scrollback)
  745         {
  746                 bcopy(svsp->Scrollback, stmp,
  747                         (min(pages, svsp->scrollback_pages)) *
  748                         svsp->screen_rows * svsp->maxcol * CHR);
  749                 free(svsp->Scrollback, M_DEVBUF);
  750                 svsp->Scrollback = stmp;
  751         }
  752         else
  753         {
  754                 svsp->scr_offset = 0;
  755                 svsp->scrolling = 0;
  756                 svsp->Scrollback = stmp;
  757 
  758                 bcopy(svsp->Crtat, svsp->Scrollback,
  759                         svsp->screen_rows * svsp->maxcol * CHR);
  760 
  761                 svsp->scr_offset = svsp->row;
  762         }
  763 
  764         svsp->scrollback_pages = pages;
  765 
  766         splx(s);
  767 }
  768 
  769 /*---------------------------------------------------------------------------*
  770  *      VGA ioctl - read DAC palette entry
  771  *---------------------------------------------------------------------------*/
  772 static void
  773 vgareadpel(struct vgapel *data, struct cdev *dev)
  774 {
  775         register unsigned vpage = minor(dev);
  776         register unsigned idx = data->idx;
  777 
  778         if(idx >= NVGAPEL)
  779                 return;         /* no such entry */
  780 
  781         /* do not read VGA palette directly, use saved values */
  782         data->r = vs[vpage].palette[idx].r;
  783         data->g = vs[vpage].palette[idx].g;
  784         data->b = vs[vpage].palette[idx].b;
  785 }
  786 
  787 /*---------------------------------------------------------------------------*
  788  *      VGA ioctl - write DAC palette entry
  789  *---------------------------------------------------------------------------*/
  790 static void
  791 vgawritepel(struct vgapel *data, struct cdev *dev)
  792 {
  793         register unsigned vpage = minor(dev);
  794         register unsigned idx = data->idx;
  795 
  796         if(idx >= NVGAPEL)
  797                 return;         /* no such entry */
  798 
  799         /* first, update saved values for this video screen */
  800         vs[vpage].palette[idx].r = data->r;
  801         vs[vpage].palette[idx].g = data->g;
  802         vs[vpage].palette[idx].b = data->b;
  803 
  804         /* if this happens on active screen, update VGA DAC, too */
  805         if(vpage == current_video_screen)
  806                 vgapaletteio(idx, &vs[vpage].palette[idx], 1);
  807 }
  808 
  809 /*---------------------------------------------------------------------------*
  810  *      VGA physical IO - read/write one palette entry
  811  *---------------------------------------------------------------------------*/
  812 void
  813 vgapaletteio(unsigned idx, struct rgb *val, int writeit)
  814 {
  815         if(writeit)
  816         {
  817                 outb(VGA_DAC + 2, idx);
  818                 outb(VGA_DAC + 3, val->r & VGA_PMSK);
  819                 outb(VGA_DAC + 3, val->g & VGA_PMSK);
  820                 outb(VGA_DAC + 3, val->b & VGA_PMSK);
  821         }
  822         else    /* read it */
  823         {
  824                 outb(VGA_DAC + 1, idx);
  825                 val->r = inb(VGA_DAC + 3) & VGA_PMSK;
  826                 val->g = inb(VGA_DAC + 3) & VGA_PMSK;
  827                 val->b = inb(VGA_DAC + 3) & VGA_PMSK;
  828         }
  829 }
  830 
  831 /*---------------------------------------------------------------------------*
  832  *
  833  *      update asynchronous: cursor, cursor pos displ, sys load, keyb scan
  834  *
  835  *      arg is:
  836  *              UPDATE_START = do update; requeue
  837  *              UPDATE_STOP  = suspend updates
  838  *              UPDATE_KERN  = do update for kernel printfs
  839  *
  840  *---------------------------------------------------------------------------*/
  841 void
  842 async_update(void *arg)
  843 {
  844         static int lastpos = 0;
  845         static int counter = PCVT_UPDATESLOW;
  846 
  847 #ifdef XSERVER
  848         /* need a method to suspend the updates */
  849 
  850         if(arg == UPDATE_STOP)
  851         {
  852                 untimeout(async_update, UPDATE_START, async_update_ch);
  853                 return;
  854         }
  855 #endif /* XSERVER */
  856 
  857         /* first check if update is possible */
  858 
  859         if(chargen_access)              /* does no-one load characters? */
  860         {
  861                 goto async_update_exit; /* do not update anything */
  862         }
  863 
  864 #if PCVT_SCREENSAVER
  865         if(reset_screen_saver && (counter == PCVT_UPDATESLOW))
  866         {
  867                 pcvt_scrnsv_reset();    /* yes, do it */
  868                 reset_screen_saver = 0; /* re-init */
  869         }
  870         else if(scrnsv_active)          /* is the screen not blanked? */
  871         {
  872                 goto async_update_exit; /* do not update anything */
  873         }
  874 #endif /* PCVT_SCREENSAVER */
  875 
  876         /*-------------------------------------------------------------------*/
  877         /* this takes place on EVERY virtual screen (if not in X mode etc...)*/
  878         /*-------------------------------------------------------------------*/
  879 
  880         if ( cursor_pos_valid &&
  881             (lastpos != (vsp->Crtat + vsp->cur_offset - Crtat)))
  882         {
  883                 lastpos = vsp->Crtat + vsp->cur_offset - Crtat;
  884                 outb(addr_6845, CRTC_CURSORH);  /* high register */
  885                 outb(addr_6845+1, ((lastpos) >> 8));
  886                 outb(addr_6845, CRTC_CURSORL);  /* low register */
  887                 outb(addr_6845+1, (lastpos));
  888         }
  889 
  890         if (arg == UPDATE_KERN)         /* Magic arg: for kernel printfs */
  891                 return;
  892 
  893         if(--counter)                   /* below is possible update */
  894                 goto async_update_exit; /*  just now and then ..... */
  895         counter = PCVT_UPDATESLOW;      /* caution, see screensaver above !! */
  896 
  897         /*-------------------------------------------------------------------*/
  898         /* this takes place ONLY on screen 0 if in HP mode, labels on, !X    */
  899         /*-------------------------------------------------------------------*/
  900 
  901         /* additional processing for HP necessary ? */
  902 
  903         if((vs[0].vt_pure_mode == M_HPVT) && (vs[0].labels_on))
  904         {
  905                 static volatile u_char buffer[] =
  906                        "System Load: 1min: 0.00 5min: 0.00 15min: 0.00";
  907                 register int tmp, i;
  908 #if PCVT_SHOWKEYS
  909                 extern u_char rawkeybuf[80];
  910 
  911                 if(keyboard_show)
  912                 {
  913                         for(i = 0; i < 80; i++)
  914                         {
  915                                 *((vs[0].Crtat+((vs[0].screen_rows+2)
  916                                         * vs[0].maxcol))+i) =
  917                                  user_attr | rawkeybuf[i];
  918                         }
  919                 }
  920                 else
  921                 {
  922 #endif  /* PCVT_SHOWKEYS */
  923 
  924                 /* display load averages in last line (taken from tty.c) */
  925                         i = 18;
  926                         tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2)
  927                                 >> FSHIFT;
  928                         buffer[i++] =
  929                                 ((((tmp/100)/10) == 0) ?
  930                                  ' ' :
  931                                  ((tmp/100)/10) + '');
  932                         buffer[i++] = ((tmp/100)%10) + '';
  933                         buffer[i++] = '.';
  934                         buffer[i++] = ((tmp%100)/10) + '';
  935                         buffer[i++] = ((tmp%100)%10) + '';
  936                         i += 6;
  937                         tmp = (averunnable.ldavg[1] * 100 + FSCALE / 2)
  938                                 >> FSHIFT;
  939                         buffer[i++] = ((((tmp/100)/10) == 0) ?
  940                                        ' ' :
  941                                        ((tmp/100)/10) + '');
  942                         buffer[i++] = ((tmp/100)%10) + '';
  943                         buffer[i++] = '.';
  944                         buffer[i++] = ((tmp%100)/10) + '';
  945                         buffer[i++] = ((tmp%100)%10) + '';
  946                         i += 7;
  947                         tmp = (averunnable.ldavg[2] * 100 + FSCALE / 2)
  948                                 >> FSHIFT;
  949                         buffer[i++] = ((((tmp/100)/10) == 0) ?
  950                                        ' ' :
  951                                        ((tmp/100)/10) + '');
  952                         buffer[i++] = ((tmp/100)%10) + '';
  953                         buffer[i++] = '.';
  954                         buffer[i++] = ((tmp%100)/10) + '';
  955                         buffer[i++] = ((tmp%100)%10) + '';
  956                         buffer[i] = '\0';
  957 
  958                         for(i = 0; buffer[i]; i++)
  959                         {
  960                                 *((vs[0].Crtat +
  961                                    ((vs[0].screen_rows + 2) * vs[0].maxcol)
  962                                    ) + i
  963                                   ) = user_attr | buffer[i];
  964                         }
  965 
  966 #if PCVT_SHOWKEYS
  967                         for(; i < 77; i++)
  968                         {
  969                                 *((vs[0].Crtat +
  970                                    ((vs[0].screen_rows + 2) * vs[0].maxcol)
  971                                    ) + i
  972                                   ) = user_attr | ' ';
  973                         }
  974 
  975                 }
  976 #endif  /* PCVT_SHOWKEYS */
  977         }
  978 
  979         /*-------------------------------------------------------------------*/
  980         /* this takes place on EVERY screen which is in HP mode, labels on,!X*/
  981         /*-------------------------------------------------------------------*/
  982 
  983         if((vsp->vt_pure_mode == M_HPVT) && (vsp->labels_on))
  984         {
  985                 register int col = vsp->col+1;
  986                 register u_short *p = vsp->Crtat +
  987                                 (vsp->screen_rows * vsp->maxcol);
  988 
  989                 /* update column display between labels */
  990 
  991                 if(vsp->maxcol == SCR_COL132)
  992                 {
  993                         p += (SCR_COL132 - SCR_COL80)/2;
  994 
  995                         if(col >= 100)
  996                         {
  997                                 *(p + LABEL_COLU) = user_attr | '1';
  998                                 col -= 100;
  999                         }
 1000                         else
 1001                         {
 1002                                 *(p + LABEL_COLU) = user_attr | '';
 1003                         }
 1004                 }
 1005                 *(p + LABEL_COLH) = user_attr | ((col/10) + '');
 1006                 *(p + LABEL_COLL) = user_attr | ((col%10) + '');
 1007 
 1008                 /* update row display between labels */
 1009 
 1010                 *(p + LABEL_ROWH) = (user_attr | (((vsp->row+1)/10) + ''));
 1011                 *(p + LABEL_ROWL) = (user_attr | (((vsp->row+1)%10) + ''));
 1012         }
 1013 
 1014 async_update_exit:
 1015 
 1016         if(arg == UPDATE_START)
 1017         {
 1018            async_update_ch = timeout(async_update, UPDATE_START,
 1019                                      PCVT_UPDATEFAST);
 1020         }
 1021 }
 1022 
 1023 /*---------------------------------------------------------------------------*
 1024  *      set character set for virtual screen
 1025  *---------------------------------------------------------------------------*/
 1026 void
 1027 set_charset(struct video_state *svsp, int curvgacs)
 1028 {
 1029         static int sizetab[] = { 25, 28, 35, 40, 43, 50 };
 1030         int oldsize, oldrows, newsize, newrows;
 1031 
 1032         if((curvgacs < 0) || (curvgacs > (NVGAFONTS-1)))
 1033                 return;
 1034 
 1035         svsp->vga_charset = curvgacs;
 1036 
 1037         select_vga_charset(curvgacs);
 1038 
 1039         oldsize = svsp->screen_rowsize;
 1040         oldrows = svsp->screen_rows;
 1041         newsize = sizetab[(vgacs[curvgacs].screen_size)];
 1042         newrows = newsize;
 1043         if (svsp->vt_pure_mode == M_HPVT)
 1044                 newrows -= 3;
 1045         if (newrows == 25 && svsp->force24)
 1046                 newrows = 24;
 1047         if (newrows < oldrows) {
 1048                 int nscroll = svsp->row + 1 - newrows;
 1049 
 1050                 if (svsp->row >= oldrows) /* Sanity check */
 1051                         nscroll = oldrows - newrows;
 1052                 if (nscroll > 0) {
 1053                         /* Scroll up */
 1054                         bcopy (svsp->Crtat + nscroll * svsp->maxcol,
 1055                                svsp->Crtat,
 1056                                newrows * svsp->maxcol * CHR);
 1057                         svsp->row -= nscroll;
 1058                         svsp->cur_offset -= nscroll * svsp->maxcol;
 1059                 }
 1060                 if (newrows < newsize)
 1061                         fillw(user_attr | ' ',
 1062                               svsp->Crtat + newrows * svsp->maxcol,
 1063                               (newsize - newrows) * svsp->maxcol);
 1064         } else if (oldrows < newsize)
 1065                 fillw(user_attr | ' ',
 1066                       svsp->Crtat + oldrows * svsp->maxcol,
 1067                       (newsize - oldrows) * svsp->maxcol);
 1068 
 1069         svsp->screen_rowsize = newsize;
 1070         svsp->screen_rows = newrows;
 1071 
 1072         /* Clip scrolling region */
 1073         if(svsp->scrr_end > svsp->screen_rows - 1)
 1074                 svsp->scrr_end = svsp->screen_rows - 1;
 1075         svsp->scrr_len = svsp->scrr_end - svsp->scrr_beg + 1;
 1076 
 1077         /* Clip cursor pos */
 1078 
 1079         if(svsp->cur_offset > (svsp->scrr_len * svsp->maxcol))
 1080                 svsp->cur_offset = (svsp->scrr_len * svsp->maxcol) + svsp->col;
 1081 }
 1082 
 1083 /*---------------------------------------------------------------------------*
 1084  *      select a vga character set
 1085  *---------------------------------------------------------------------------*/
 1086 void
 1087 select_vga_charset(int vga_charset)
 1088 {
 1089         int first, second;
 1090         int fflag = 0;
 1091         int sflag = 0;
 1092         u_char cmap = 0;
 1093 
 1094         static u_char cmaptaba[] =
 1095                 {0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13};
 1096 
 1097         static u_char cmaptabb[] =
 1098                 {0x00, 0x04, 0x08, 0x0c, 0x20, 0x24, 0x28, 0x2c};
 1099 
 1100         if((adaptor_type != EGA_ADAPTOR) && (adaptor_type != VGA_ADAPTOR))
 1101                 return;
 1102 
 1103         if((vga_charset < 0) || (vga_charset >= totalfonts))
 1104                 return;
 1105 
 1106         if(!vgacs[vga_charset].loaded)
 1107                 return;
 1108 
 1109         /*--------------------------------------------------------------
 1110            find the the first and second charset of a given resolution.
 1111            the first is used for lower 256 and the second (if any) is
 1112            used for the upper 256 entries of a complete 512 entry ega/
 1113            vga charset.
 1114         --------------------------------------------------------------*/
 1115 
 1116         for(first = 0; first < totalfonts; first++)
 1117         {
 1118                 if(!vgacs[first].loaded)
 1119                         continue;
 1120                 if(vgacs[first].screen_size != vgacs[vga_charset].screen_size)
 1121                         continue;
 1122                 if(vgacs[first].char_scanlines !=
 1123                    vgacs[vga_charset].char_scanlines)
 1124                         continue;
 1125                 if(vgacs[first].scr_scanlines !=
 1126                    vgacs[vga_charset].scr_scanlines)
 1127                         continue;
 1128                 fflag = 1;
 1129                 break;
 1130         }
 1131 
 1132         if(fflag != 1)
 1133                 return;
 1134 
 1135         for(second = first+1; second < totalfonts; second++)
 1136         {
 1137                 if(!vgacs[second].loaded)
 1138                         continue;
 1139                 if(vgacs[second].screen_size != vgacs[vga_charset].screen_size)
 1140                         continue;
 1141                 if(vgacs[second].char_scanlines !=
 1142                    vgacs[vga_charset].char_scanlines)
 1143                         continue;
 1144                 if(vgacs[second].scr_scanlines !=
 1145                    vgacs[vga_charset].scr_scanlines)
 1146                         continue;
 1147                 sflag = 1;
 1148                 break;
 1149         }
 1150 
 1151         cmap = cmaptaba[first];
 1152         if(sflag)
 1153         {
 1154                 cmap |= cmaptabb[second];
 1155                 vgacs[first].secondloaded = second;
 1156         }
 1157         else
 1158         {
 1159                 vgacs[first].secondloaded = 0; /*cs 0 can never become a 2nd!*/
 1160         }
 1161 
 1162         if(vsp->wd132col)
 1163         {
 1164                 cmap = (vga_charset & 0x07);
 1165                 cmap |= 0x10;
 1166         }
 1167 
 1168         outb(TS_INDEX, TS_FONTSEL);     /* character map select register */
 1169         outb(TS_DATA, cmap);            /* new char map */
 1170 
 1171         outb(addr_6845, CRTC_MAXROW);   /* max scan line reg */
 1172         outb(addr_6845+1,
 1173                 vgacs[first].char_scanlines); /* scanlines/char */
 1174 
 1175         outb(addr_6845, CRTC_VDE);      /* vert display enable end */
 1176         outb(addr_6845+1,
 1177                 vgacs[first].scr_scanlines);  /* low byte of scr scanlines */
 1178 
 1179         if((color == 0) && (adaptor_type == VGA_ADAPTOR))
 1180         {
 1181                 outb(addr_6845, CRTC_ULOC);     /* underline location reg */
 1182                 outb(addr_6845+1, (vgacs[first].char_scanlines & 0x1F));
 1183         }
 1184 }
 1185 
 1186 /*---------------------------------------------------------------------------*
 1187  *      switch vga-card to load a character set
 1188  *---------------------------------------------------------------------------*/
 1189 static void
 1190 setchargen(void)
 1191 {
 1192         chargen_access = 1;     /* flag we are accessing the chargen ram */
 1193 
 1194         /* program sequencer to access character generator */
 1195 
 1196         outb(TS_INDEX, TS_SYNCRESET);
 1197         outb(TS_DATA, 0x01);    /* synchronous reset */
 1198 
 1199         outb(TS_INDEX, TS_WRPLMASK);
 1200         outb(TS_DATA, 0x04);    /* write to map 2 */
 1201 
 1202         outb(TS_INDEX, TS_MEMMODE);
 1203         outb(TS_DATA, 0x07);    /* sequential addressing */
 1204 
 1205         outb(TS_INDEX, TS_SYNCRESET);
 1206         outb(TS_DATA, 0x03);    /* clear synchronous reset */
 1207 
 1208         /* program graphics controller to access character generator */
 1209 
 1210         outb(GDC_INDEX, GDC_RDPLANESEL);
 1211         outb(GDC_DATA, 0x02);   /* select map 2 for cpu reads */
 1212 
 1213         outb(GDC_INDEX, GDC_MODE);
 1214         outb(GDC_DATA, 0x00);   /* disable odd-even addressing */
 1215 
 1216         outb(GDC_INDEX, GDC_MISC);
 1217         outb(GDC_DATA, 0x00);   /* map starts at 0xA000 */
 1218 }
 1219 
 1220 /*---------------------------------------------------------------------------*
 1221  *      switch vga-card to load a character set to plane 3
 1222  *---------------------------------------------------------------------------*/
 1223 static void
 1224 setchargen3(void)
 1225 {
 1226         chargen_access = 1;     /* flag we are accessing the chargen ram */
 1227 
 1228         /* program sequencer to access character generator */
 1229 
 1230         outb(TS_INDEX, TS_SYNCRESET);
 1231         outb(TS_DATA, 0x01);    /* synchronous reset */
 1232 
 1233         outb(TS_INDEX, TS_WRPLMASK);
 1234         outb(TS_DATA, 0x08);    /* write to map 3 */
 1235 
 1236         outb(TS_INDEX, TS_MEMMODE);
 1237         outb(TS_DATA, 0x07);    /* sequential addressing */
 1238 
 1239         outb(TS_INDEX, TS_SYNCRESET);
 1240         outb(TS_DATA, 0x03);    /* clear synchronous reset */
 1241 
 1242         /* program graphics controller to access character generator */
 1243 
 1244         outb(GDC_INDEX, GDC_RDPLANESEL);
 1245         outb(GDC_DATA, 0x03);   /* select map 3 for cpu reads */
 1246 
 1247         outb(GDC_INDEX, GDC_MODE);
 1248         outb(GDC_DATA, 0x00);   /* disable odd-even addressing */
 1249 
 1250         outb(GDC_INDEX, GDC_MISC);
 1251         outb(GDC_DATA, 0x00);   /* map starts at 0xA000 */
 1252 }
 1253 
 1254 /*---------------------------------------------------------------------------*
 1255  *      switch back vga-card to normal operation
 1256  *---------------------------------------------------------------------------*/
 1257 static void
 1258 resetchargen(void)
 1259 {
 1260         /* program sequencer to access video ram */
 1261 
 1262         outb(TS_INDEX, TS_SYNCRESET);
 1263         outb(TS_DATA, 0x01);    /* synchronous reset */
 1264 
 1265         outb(TS_INDEX, TS_WRPLMASK);
 1266         outb(TS_DATA, 0x03);    /* write to map 0 & 1 */
 1267 
 1268         outb(TS_INDEX, TS_MEMMODE);
 1269         outb(TS_DATA, 0x03);    /* odd-even addressing */
 1270 
 1271         outb(TS_INDEX, TS_SYNCRESET);
 1272         outb(TS_DATA, 0x03);    /* clear synchronous reset */
 1273 
 1274         /* program graphics controller to access character generator */
 1275 
 1276         outb(GDC_INDEX, GDC_RDPLANESEL);
 1277         outb(GDC_DATA, 0x00);   /* select map 0 for cpu reads */
 1278 
 1279         outb(GDC_INDEX, GDC_MODE);
 1280         outb(GDC_DATA, 0x10);   /* enable odd-even addressing */
 1281 
 1282         outb(GDC_INDEX, GDC_MISC);
 1283         if(color)
 1284                 outb(GDC_DATA, 0x0e);   /* map starts at 0xb800 */
 1285         else
 1286                 outb(GDC_DATA, 0x0a);   /* map starts at 0xb000 */
 1287 
 1288         chargen_access = 0;     /* flag we are NOT accessing the chargen ram */
 1289 }
 1290 
 1291 
 1292 /*---------------------------------------------------------------------------*
 1293  *      switch screen off (VGA only)
 1294  *---------------------------------------------------------------------------*/
 1295 void
 1296 vga_screen_off(void)
 1297 {
 1298         unsigned char old;
 1299 
 1300         outb(TS_INDEX, TS_SYNCRESET);
 1301         outb(TS_DATA, 0x01);            /* synchronous reset */
 1302 
 1303         outb(TS_INDEX, TS_MODE);        /* clocking mode reg */
 1304         old = inb(TS_DATA);             /* get current value */
 1305 
 1306         outb(TS_INDEX, TS_MODE);        /* clocking mode reg */
 1307         outb(TS_DATA, (old | 0x20));    /* screen off bit on */
 1308 
 1309         outb(TS_INDEX, TS_SYNCRESET);
 1310         outb(TS_DATA, 0x03);            /* clear synchronous reset */
 1311 }
 1312 
 1313 /*---------------------------------------------------------------------------*
 1314  *      switch screen back on (VGA only)
 1315  *---------------------------------------------------------------------------*/
 1316 void
 1317 vga_screen_on(void)
 1318 {
 1319         unsigned char old;
 1320 
 1321         outb(TS_INDEX, TS_SYNCRESET);
 1322         outb(TS_DATA, 0x01);            /* synchronous reset */
 1323 
 1324         outb(TS_INDEX, TS_MODE);        /* clocking mode reg */
 1325         old = inb(TS_DATA);             /* get current value */
 1326 
 1327         outb(TS_INDEX, TS_MODE);        /* clocking mode reg */
 1328         outb(TS_DATA, (old & ~0x20));   /* screen off bit off */
 1329 
 1330         outb(TS_INDEX, TS_SYNCRESET);
 1331         outb(TS_DATA, 0x03);            /* clear synchronous reset */
 1332 }
 1333 
 1334 /*---------------------------------------------------------------------------*
 1335  *      compute character set base address (in kernel map)
 1336  *---------------------------------------------------------------------------*/
 1337 static unsigned char *
 1338 compute_charset_base(unsigned fontset)
 1339 {
 1340         unsigned char *d = (unsigned char *)Crtat;
 1341 
 1342         static int charset_offset[8] = { 0x0000, 0x4000, 0x8000, 0xC000,
 1343                                          0x2000, 0x6000, 0xA000, 0xE000 };
 1344 
 1345         static int charsetw_offset[8] = { 0x0000, 0x2000, 0x4000, 0x6000,
 1346                                           0x8000, 0xA000, 0xC000, 0xE000 };
 1347 
 1348         switch(adaptor_type)
 1349         {
 1350                 case EGA_ADAPTOR:
 1351                         fontset = (fontset > 3) ? 3 : fontset;
 1352                         break;
 1353 
 1354                 case VGA_ADAPTOR:
 1355                         fontset = (fontset > 7) ? 7 : fontset;
 1356                         break;
 1357 
 1358                 default:
 1359                         return 0;
 1360         }
 1361 
 1362         if(color)
 1363                 d -= (0xB8000 - 0xA0000);       /* Point to 0xA0000 */
 1364         else
 1365                 d -= (0xB0000 - 0xA0000);       /* Point to 0xA0000 */
 1366 
 1367         if(vsp->wd132col)
 1368                 d += charsetw_offset[fontset];  /* Load into Character set n */
 1369         else
 1370                 d += charset_offset[fontset];   /* Load into Character set n */
 1371 
 1372         return d;
 1373 }
 1374 
 1375 /*---------------------------------------------------------------------------*
 1376  *      load a char into ega/vga character generator ram
 1377  *---------------------------------------------------------------------------*/
 1378 void
 1379 loadchar(int fontset, int character, int char_scanlines, u_char *char_table)
 1380 {
 1381         unsigned char *d;
 1382         unsigned char *bak;
 1383         int j, k;
 1384 
 1385         if((d = compute_charset_base(fontset)) == 0)
 1386                 return;
 1387 
 1388         d += (character * 32);          /* 32 bytes per character */
 1389 
 1390         if(vsp->wd132col &&
 1391            (fontset == 1||fontset == 3||fontset == 5||fontset == 7))
 1392                 setchargen3();                  /* access chargen ram */
 1393         else
 1394                 setchargen();                   /* access chargen ram */
 1395 
 1396         for(j = k = 0; j < char_scanlines; j++) /* x bit high characters */
 1397         {
 1398                 *d = char_table[k];
 1399                 d++;
 1400                 k++;
 1401         }
 1402         for(; j < 32; j++)              /* Up to 32 bytes per character image*/
 1403         {
 1404                 *d = 0x00;
 1405                 d++;
 1406         }
 1407 
 1408         resetchargen();                 /* access video ram */
 1409 
 1410         if(saved_charsets[fontset] == 0)
 1411                 saved_charsets[fontset] =
 1412                         (u_char *)malloc(32 * 256, M_DEVBUF, M_WAITOK);
 1413 
 1414         if((bak = saved_charsets[fontset]))
 1415         {
 1416                 /* make a backup copy of this char */
 1417                 bak += (character * 32);
 1418                 bzero(bak, 32);
 1419                 bcopy(char_table, bak, char_scanlines);
 1420         }
 1421 #ifdef DIAGNOSTIC
 1422         else
 1423                 panic("pcvt loadchar: no backup buffer");
 1424 #endif /* DIAGNOSTIC */
 1425 }
 1426 
 1427 /*---------------------------------------------------------------------------*
 1428  *      save/restore character set n to addr b
 1429  *      since there are always backed up copies, we do not save anything here
 1430  *      parameter "b" is totally ignored
 1431  *---------------------------------------------------------------------------*/
 1432 void
 1433 vga_move_charset(unsigned n, unsigned char *b, int save_it)
 1434 {
 1435         unsigned char *d = compute_charset_base(n);
 1436 
 1437         if(save_it)
 1438                 return;
 1439 
 1440         if(saved_charsets[n] == 0)
 1441 #ifdef DIAGNOSTIC
 1442                 panic("pcvt: restoring unbuffered charset");
 1443 #else
 1444                 return;
 1445 #endif
 1446 
 1447 #ifdef DIAGNOSTIC
 1448         if(d == 0)
 1449                 panic("vga_move_charset: wrong adaptor");
 1450 #endif
 1451 
 1452         if(vsp->wd132col && (n == 1||n == 3||n == 5||n == 7))
 1453         {
 1454                 setchargen3();
 1455                 d -= 0x2000;
 1456         }
 1457         else
 1458         {
 1459                 setchargen();
 1460         }
 1461 
 1462         /* PLEASE, leave the following alone using bcopyb, as several   */
 1463         /* chipsets have problems if their memory is accessed with 32   */
 1464         /* or 16 bits wide, don't change this to using bcopy for speed! */
 1465 
 1466         bcopyb(saved_charsets[n], d,
 1467                256 /* chars */ * 32 /* bytes per char */);
 1468 
 1469         resetchargen();
 1470 }
 1471 
 1472 #ifndef XSERVER
 1473 /*---------------------------------------------------------------------------*
 1474  *      switch to virtual screen n (0 ... PCVT_NSCREENS-1)
 1475  *---------------------------------------------------------------------------*/
 1476 void
 1477 vgapage(int n)
 1478 {
 1479         int cols = vsp->maxcol;         /* get current col val */
 1480 
 1481         if(n < 0 || n >= totalscreens)
 1482                 return;
 1483 
 1484         /* video board memory -> kernel memory */
 1485 
 1486         bcopy(vsp->Crtat, vsp->Memory, vsp->screen_rows * vsp->maxcol * CHR);
 1487 
 1488         vsp->Crtat = vsp->Memory;       /* operate in memory now */
 1489 
 1490         /* update global screen pointers/variables */
 1491 
 1492         current_video_screen = n;       /* current screen no */
 1493 
 1494         vsp = &vs[n];                   /* current video state ptr */
 1495 
 1496         /* kernel memory -> video board memory */
 1497 
 1498         bcopy(vsp->Crtat, Crtat, vsp->screen_rows * vsp->maxcol * CHR);
 1499 
 1500         vsp->Crtat = Crtat;             /* operate on screen now */
 1501 
 1502         outb(addr_6845, CRTC_STARTADRH);
 1503         outb(addr_6845+1, 0);
 1504         outb(addr_6845, CRTC_STARTADRL);
 1505         outb(addr_6845+1, 0);
 1506 
 1507         select_vga_charset(vsp->vga_charset);
 1508 
 1509         if(vsp->maxcol != cols)
 1510                 vga_col(vsp, vsp->maxcol);      /* select 80/132 columns */
 1511 
 1512         outb(addr_6845, CRTC_CURSORH);  /* select high register */
 1513         outb(addr_6845+1, vsp->cur_offset >> 8);
 1514         outb(addr_6845, CRTC_CURSORL);  /* select low register */
 1515         outb(addr_6845+1, vsp->cur_offset);
 1516 
 1517         if(vsp->cursor_on)
 1518         {
 1519                 outb(addr_6845, CRTC_CURSTART); /* select high register */
 1520                 outb(addr_6845+1, vsp->cursor_start);
 1521                 outb(addr_6845, CRTC_CUREND);   /* select low register */
 1522                 outb(addr_6845+1, vsp->cursor_end);
 1523         }
 1524         else
 1525         {
 1526                 sw_cursor(0);
 1527         }
 1528 
 1529         if(adaptor_type == VGA_ADAPTOR)
 1530         {
 1531                 unsigned i;
 1532 
 1533                 /* switch VGA DAC palette entries */
 1534 
 1535                 for(i = 0; i < NVGAPEL; i++)
 1536                         vgapaletteio(i, &vsp->palette[i], 1);
 1537         }
 1538 
 1539         update_led();                   /* update led's */
 1540 
 1541         update_hp(vsp);                 /* update fkey labels, if present */
 1542 }
 1543 #endif /* XSERVER */
 1544 
 1545 /*---------------------------------------------------------------------------*
 1546  *      test if it is a vga
 1547  *---------------------------------------------------------------------------*/
 1548 int
 1549 vga_test(void)
 1550 {
 1551         u_char old, new, check;
 1552 
 1553         outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1554         old = inb(addr_6845+1);         /* get current value */
 1555 
 1556         new = old | CURSOR_ON_BIT;      /* set cursor on by setting bit 5 on */
 1557 
 1558         outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1559         outb(addr_6845+1,new);          /* cursor should be on now */
 1560 
 1561         outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1562         check = inb(addr_6845+1);       /* get current value */
 1563 
 1564         if(check != new)
 1565         {
 1566                 outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1567                 outb(addr_6845+1,old);          /* failsafe */
 1568                 return(0);                      /* must be ega */
 1569         }
 1570 
 1571         new = old & ~CURSOR_ON_BIT;     /* turn cursor off by clearing bit 5 */
 1572 
 1573         outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1574         outb(addr_6845+1,new);          /* cursor should be off now */
 1575 
 1576         outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1577         check = inb(addr_6845+1);       /* get current value */
 1578 
 1579         if(check != new)
 1580         {
 1581                 outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1582                 outb(addr_6845+1,old);          /* failsafe */
 1583                 return(0);                      /* must be ega */
 1584         }
 1585 
 1586         outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1587         outb(addr_6845+1,old);          /* failsafe */
 1588 
 1589         return(1);      /* vga */
 1590 }
 1591 
 1592 /*---------------------------------------------------------------------------*
 1593  *      convert upper/lower sixel font array to vga font array
 1594  *---------------------------------------------------------------------------*/
 1595 void
 1596 sixel_vga(struct sixels *sixelp, u_char *vgachar)
 1597 {
 1598         register int i, j;
 1599         register int shift;
 1600         register u_char mask;
 1601 
 1602         for(j = 0; j < 16; j++)
 1603                 vgachar[j] = 0;
 1604 
 1605         mask = 0x01;
 1606         for(j = 0; j < 6; j++)
 1607         {
 1608                 for(i = 0, shift = 7; i < 8; i++, shift--)
 1609                         vgachar[j] |= ((((sixelp->upper[i]) & mask) >> j)
 1610                                        << shift);
 1611                 mask <<= 1;
 1612         }
 1613 
 1614         mask = 0x01;
 1615         for(j = 0; j < 4; j++)
 1616         {
 1617                 for(i = 0, shift = 7; i < 8; i++, shift--)
 1618                         vgachar[j+6] |= ((((sixelp->lower[i]) & mask) >>j)
 1619                                          << shift);
 1620                 mask <<= 1;
 1621         }
 1622 }
 1623 
 1624 /*---------------------------------------------------------------------------*
 1625  *      Expand 8x10 EGA/VGA characters to 8x16 EGA/VGA characters
 1626  *---------------------------------------------------------------------------*/
 1627 void
 1628 vga10_vga16(u_char *invga, u_char *outvga)
 1629 {
 1630         register int i,j;
 1631 
 1632         /*
 1633          * Keep the top and bottom scanlines the same and double every scan
 1634          * line in between.
 1635          */
 1636 
 1637         outvga[0] = invga[0];
 1638         outvga[1] = invga[1];
 1639         outvga[14] = invga[8];
 1640         outvga[15] = invga[9];
 1641 
 1642         for(i = j = 2;i < 8 && j < 14;i++,j += 2)
 1643         {
 1644                 outvga[j]   = invga[i];
 1645                 outvga[j+1] = invga[i];
 1646         }
 1647 }
 1648 
 1649 /*---------------------------------------------------------------------------*
 1650  *      Expand 8x10 EGA/VGA characters to 8x14 EGA/VGA characters
 1651  *---------------------------------------------------------------------------*/
 1652 void
 1653 vga10_vga14(u_char *invga, u_char *outvga)
 1654 {
 1655         register int i;
 1656 
 1657         /*
 1658          * Double the top two and bottom two scanlines and copy everything
 1659          * in between.
 1660          */
 1661 
 1662         outvga[0] = invga[0];
 1663         outvga[1] = invga[0];
 1664         outvga[2] = invga[1];
 1665         outvga[3] = invga[1];
 1666         outvga[10] = invga[8];
 1667         outvga[11] = invga[8];
 1668         outvga[12] = invga[9];
 1669         outvga[13] = invga[9];
 1670 
 1671         for(i = 2;i < 8;i++)
 1672                 outvga[i+2]   = invga[i];
 1673 }
 1674 
 1675 /*---------------------------------------------------------------------------*
 1676  *      Expand 8x10 EGA/VGA characters to 8x10 EGA/VGA characters
 1677  *---------------------------------------------------------------------------*/
 1678 void
 1679 vga10_vga10(u_char *invga, u_char *outvga)
 1680 {
 1681         register int i;
 1682 
 1683         for(i = 0;i < 10;i++)
 1684                 outvga[i]   = invga[i];
 1685 }
 1686 
 1687 /*---------------------------------------------------------------------------*
 1688  *      Contract 8x10 EGA/VGA characters to 8x8 EGA/VGA characters
 1689  *---------------------------------------------------------------------------*/
 1690 void
 1691 vga10_vga8(u_char *invga, u_char *outvga)
 1692 {
 1693         /* Skip scanlines 3 and 7 */
 1694 
 1695         outvga[0] = invga[0];
 1696         outvga[1] = invga[1];
 1697         outvga[2] = invga[2];
 1698         outvga[3] = invga[4];
 1699         outvga[4] = invga[5];
 1700         outvga[5] = invga[6];
 1701         outvga[6] = invga[8];
 1702         outvga[7] = invga[9];
 1703 }
 1704 
 1705 /*---------------------------------------------------------------------------*
 1706  *      disconnect attribute bit 3 from generating intensity
 1707  *      (and use it for a second character set !)
 1708  *---------------------------------------------------------------------------*/
 1709 void
 1710 set_2ndcharset(void)
 1711 {
 1712         if(color)                       /* prepare to access index register! */
 1713                 inb(GN_INPSTAT1C);
 1714         else
 1715                 inb(GN_INPSTAT1M);
 1716 
 1717         /* select color plane enable reg, caution: set ATC access bit ! */
 1718 
 1719         outb(ATC_INDEX, (ATC_COLPLEN | ATC_ACCESS));
 1720         outb(ATC_DATAW, 0x07);          /* disable plane 3 */
 1721 }
 1722 
 1723 #if PCVT_SCREENSAVER
 1724 #if PCVT_PRETTYSCRNS
 1725 
 1726 /*---------------------------------------------------------------------------*
 1727  * produce some kinda random number, had a look into the system library...
 1728  *---------------------------------------------------------------------------*/
 1729 static u_short
 1730 getrand(void)
 1731 {
 1732         static unsigned long seed = 1;
 1733         register u_short res = (u_short)seed;
 1734         seed = seed * 1103515245L + time_second;
 1735         return res;
 1736 }
 1737 
 1738 /*---------------------------------------------------------------------------*
 1739  *      produce "nice" screensaving ....
 1740  *---------------------------------------------------------------------------*/
 1741 static void
 1742 scrnsv_blink(void * arg)
 1743 {
 1744         static struct rgb blink_rgb[8] =
 1745         {
 1746                 {63, 63, 63},   /* white */
 1747                 {0, 63, 42},    /* pale green */
 1748                 {63, 63, 0},    /* yellow */
 1749                 {63, 21, 63},   /* violet */
 1750                 {42, 63, 0},    /* yellow-green */
 1751                 {63, 42, 0},    /* amber */
 1752                 {63, 42, 42},   /* rose */
 1753                 {21, 42, 42}    /* cyan */
 1754         };
 1755         register u_short r = getrand();
 1756         unsigned pos = (r % (scrnsv_size / 2));
 1757 
 1758         *scrnsv_current = /* (0 << 8) + */ ' ';
 1759         scrnsv_current = vsp->Crtat + pos;
 1760         *scrnsv_current = (7 /* LIGHTGRAY */ << 8) + '*';
 1761         if(adaptor_type == VGA_ADAPTOR)
 1762                 vgapaletteio(7 /* LIGHTGRAY */, &blink_rgb[(r >> 4) & 7], 1);
 1763         scrnsv_blink_ch = timeout(scrnsv_blink, NULL, hz);
 1764 }
 1765 
 1766 #endif /* PCVT_PRETTYSCRNS */
 1767 
 1768 /*---------------------------------------------------------------------------*
 1769  *      set timeout time
 1770  *---------------------------------------------------------------------------*/
 1771 #ifndef XSERVER
 1772 static void
 1773 pcvt_set_scrnsv_tmo(int timeout)
 1774 #else
 1775 void
 1776 pcvt_set_scrnsv_tmo(int timeout)
 1777 #endif /* XSERVER */
 1778 {
 1779         int x = splhigh();
 1780 
 1781         if(scrnsv_timeout)
 1782                 untimeout(scrnsv_timedout, NULL, scrnsv_timeout_ch);
 1783 
 1784         scrnsv_timeout = timeout;
 1785         pcvt_scrnsv_reset();            /* sanity */
 1786         splx(x);
 1787         if(timeout == 0 && savedscreen)
 1788         {
 1789                 /* release buffer when screen saver turned off */
 1790                 free(savedscreen, M_TEMP);
 1791                 savedscreen = (u_short *)0;
 1792         }
 1793 }
 1794 
 1795 #if PCVT_GREENSAVER
 1796 /*---------------------------------------------------------------------------*
 1797  *      switch monitor on/off
 1798  *---------------------------------------------------------------------------*/
 1799 static void
 1800 green_saver(int blank)
 1801 {
 1802         u_char val;
 1803 
 1804         if (blank)
 1805         {
 1806                 outb(TS_INDEX, 0x01);
 1807                 val = inb(TS_DATA);
 1808                 outb(TS_INDEX, 0x01);
 1809                 outb(TS_DATA, val | 0x20);
 1810                 outb(addr_6845, 0x17);
 1811                 val = inb(addr_6845 + 1);
 1812                 outb(addr_6845 + 1, val & ~0x80);
 1813         }
 1814         else
 1815         {
 1816                 outb(TS_INDEX, 0x01);
 1817                 val = inb(TS_DATA);
 1818                 outb(TS_INDEX, 0x01);
 1819                 outb(TS_DATA, val & 0xDF);
 1820                 outb(addr_6845, 0x17);
 1821                 val = inb(addr_6845 + 1);
 1822                 outb(addr_6845 + 1, val | 0x80);
 1823         }
 1824 }
 1825 #endif
 1826 
 1827 /*---------------------------------------------------------------------------*
 1828  *      we were timed out
 1829  *---------------------------------------------------------------------------*/
 1830 static void
 1831 scrnsv_timedout(void *arg)
 1832 {
 1833         /* this function is called by timeout() */
 1834         /* raise priority to avoid conflicts with kbd intr */
 1835         int x = spltty();
 1836 
 1837         /*
 1838          * due to some undefined problems with video adaptor RAM
 1839          * access timing, the following has been splitted into
 1840          * two pieces called subsequently with a time difference
 1841          * of 100 millisec
 1842          */
 1843 
 1844         if(++scrnsv_active == 1)
 1845         {
 1846                 register size_t s;
 1847                 /*
 1848                  * first, allocate a buffer
 1849                  * do only if none allocated yet or another size required
 1850                  * this reduces malloc() overhead by avoiding successive
 1851                  * calls to malloc() and free() if they would have requested
 1852                  * the same buffer
 1853                  *
 1854                  * XXX This is inherited from old days where no buffering
 1855                  * happened at all. Meanwhile we should use the standard
 1856                  * screen buffer instead. Any volunteers? :-) [At least,
 1857                  * this code proved to work...]
 1858                  */
 1859 
 1860                 s = sizeof(u_short) * vsp->screen_rowsize * vsp->maxcol;
 1861 
 1862                 if(savedscreen == (u_short *)0 || s != scrnsv_size)
 1863                 {
 1864                         /* really need to allocate */
 1865                         if(savedscreen)
 1866                                 free(savedscreen, M_TEMP);
 1867                         scrnsv_size = s;
 1868                         if((savedscreen =
 1869                             (u_short *)malloc(s, M_TEMP, M_NOWAIT))
 1870                            == (u_short *)0)
 1871                         {
 1872                                 /*
 1873                                  * didn't get the buffer memory,
 1874                                  * turn off screen saver
 1875                                  */
 1876                                 scrnsv_timeout = scrnsv_active = 0;
 1877                                 splx(x);
 1878                                 return;
 1879                         }
 1880                 }
 1881                 /* save current screen */
 1882                 bcopy(vsp->Crtat, savedscreen, scrnsv_size);
 1883 
 1884                 /* on VGA's, make sure palette is set to blank screen */
 1885                 if(adaptor_type == VGA_ADAPTOR)
 1886                 {
 1887                         struct rgb black = {0, 0, 0};
 1888                         vgapaletteio(0 /* BLACK */, &black, 1);
 1889                 }
 1890                 /* prepare for next time... */
 1891                 scrnsv_timeout_ch = timeout(scrnsv_timedout, NULL, hz / 10);
 1892         }
 1893         else
 1894         {
 1895                 /* second call, now blank the screen */
 1896                 /* fill screen with blanks */
 1897                 fillw(/* (BLACK<<8) + */ ' ', vsp->Crtat, scrnsv_size / 2);
 1898 
 1899 #if PCVT_PRETTYSCRNS
 1900                 scrnsv_current = vsp->Crtat;
 1901                 scrnsv_blink_ch = timeout(scrnsv_blink, NULL, hz);
 1902 #endif /* PCVT_PRETTYSCRNS */
 1903 
 1904                 sw_cursor(0);   /* cursor off on mda/cga */
 1905 
 1906 #if PCVT_GREENSAVER
 1907                 green_saver(1);
 1908 #endif
 1909         }
 1910         splx(x);
 1911 }
 1912 
 1913 /*---------------------------------------------------------------------------*
 1914  *      interface to screensaver "subsystem"
 1915  *---------------------------------------------------------------------------*/
 1916 void
 1917 pcvt_scrnsv_reset(void)
 1918 {
 1919         /*
 1920          * to save lotta time with superfluous timeout()/untimeout() calls
 1921          * when having massive output operations, we remember the last
 1922          * second of kernel timer we've rescheduled scrnsv_timedout()
 1923          */
 1924         static long last_schedule = 0L;
 1925         register int x = splhigh();
 1926         int reschedule = 0;
 1927 
 1928         if((scrnsv_active == 1 || scrnsv_timeout) &&
 1929            last_schedule != time_second)
 1930         {
 1931                 last_schedule = time_second;
 1932                 reschedule = 1;
 1933                 untimeout(scrnsv_timedout, NULL, scrnsv_timeout_ch);
 1934         }
 1935         if(scrnsv_active)
 1936         {
 1937 
 1938 #if PCVT_PRETTYSCRNS
 1939                 if(scrnsv_active > 1)
 1940                         untimeout(scrnsv_blink, NULL, scrnsv_blink_ch);
 1941 #endif /* PCVT_PRETTYSCRNS */
 1942 
 1943                 bcopy(savedscreen, vsp->Crtat, scrnsv_size);
 1944                 if(adaptor_type == VGA_ADAPTOR)
 1945                 {
 1946                         /* back up VGA palette info */
 1947                         vgapaletteio(0 /* BLACK */, &vsp->palette[0], 1);
 1948 
 1949 #if PCVT_PRETTYSCRNS
 1950                         vgapaletteio(7 /* LIGHTGRAY */, &vsp->palette[7], 1);
 1951 #endif /* PCVT_PRETTYSCRNS */
 1952 
 1953 #if PCVT_GREENSAVER
 1954                         green_saver(0);
 1955 #endif
 1956                 }
 1957                 scrnsv_active = 0;
 1958 
 1959                 if(vsp->cursor_on)
 1960                         sw_cursor(1);   /* cursor on */
 1961         }
 1962 
 1963         if(reschedule)
 1964         {
 1965                 /* mark next timeout */
 1966                 scrnsv_timeout_ch = timeout(scrnsv_timedout, NULL,
 1967                                             scrnsv_timeout * hz);
 1968         }
 1969         splx(x);
 1970 }
 1971 
 1972 #endif /* PCVT_SCREENSAVER */
 1973 
 1974 /*---------------------------------------------------------------------------*
 1975  *      switch cursor on/off
 1976  *---------------------------------------------------------------------------*/
 1977 void
 1978 sw_cursor(int onoff)
 1979 {
 1980         if(adaptor_type == EGA_ADAPTOR)
 1981         {
 1982                 int start, end;
 1983                 if(onoff)
 1984                 {
 1985                         start = vsp->cursor_start;
 1986                         end = vsp->cursor_end;
 1987                 }
 1988                 else
 1989                 {
 1990                         int cs = vs[current_video_screen].vga_charset;
 1991 
 1992                         cs = (cs < 0) ? 0 : ((cs < totalfonts) ?
 1993                                              cs : totalfonts-1);
 1994 
 1995                         start = (vgacs[cs].char_scanlines & 0x1F) + 1;
 1996                         end = 0;
 1997                 }
 1998                 outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 1999                 outb(addr_6845+1, start);
 2000                 outb(addr_6845,CRTC_CUREND);    /* cursor end reg */
 2001                 outb(addr_6845+1, end);
 2002         }
 2003         else    /* mda, cga, vga */
 2004         {
 2005                 outb(addr_6845,CRTC_CURSTART);  /* cursor start reg */
 2006                 if(onoff)
 2007                         outb(addr_6845+1, vsp->cursor_start);
 2008                 else
 2009                         outb(addr_6845+1, CURSOR_ON_BIT);
 2010         }
 2011 }
 2012 
 2013 /*---------------------------------------------------------------------------*
 2014  *      cold init support, if a mono monitor is attached to a
 2015  *      vga or ega, it comes up with a mda emulation. switch
 2016  *      board to generic ega/vga mode in this case.
 2017  *---------------------------------------------------------------------------*/
 2018 void
 2019 mda2egaorvga(void)
 2020 {
 2021         /*
 2022          * program sequencer to access
 2023          * video ram
 2024          */
 2025 
 2026         /* synchronous reset */
 2027         outb(TS_INDEX, TS_SYNCRESET);
 2028         outb(TS_DATA, 0x01);
 2029 
 2030         /* write to map 0 & 1 */
 2031         outb(TS_INDEX, TS_WRPLMASK);
 2032         outb(TS_DATA, 0x03);
 2033 
 2034         /* odd-even addressing */
 2035         outb(TS_INDEX, TS_MEMMODE);
 2036         outb(TS_DATA, 0x03);
 2037 
 2038         /* clear synchronous reset */
 2039         outb(TS_INDEX, TS_SYNCRESET);
 2040         outb(TS_DATA, 0x03);
 2041 
 2042         /*
 2043          * program graphics controller
 2044          * to access character
 2045          * generator
 2046          */
 2047 
 2048         /* select map 0 for cpu reads */
 2049         outb(GDC_INDEX, GDC_RDPLANESEL);
 2050         outb(GDC_DATA, 0x00);
 2051 
 2052         /* enable odd-even addressing */
 2053         outb(GDC_INDEX, GDC_MODE);
 2054         outb(GDC_DATA, 0x10);
 2055 
 2056         /* map starts at 0xb000 */
 2057         outb(GDC_INDEX, GDC_MISC);
 2058         outb(GDC_DATA, 0x0a);
 2059 }
 2060 
 2061 /* ------------------------- E O F ------------------------------------------*/

Cache object: 043f711287f12e1e9a082e3c57828861


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.