LCOV - code coverage report
Current view: top level - dev/ic - vga.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 532 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: vga.c,v 1.69 2017/06/17 19:20:30 fcambus Exp $ */
       2             : /* $NetBSD: vga.c,v 1.28.2.1 2000/06/30 16:27:47 simonb Exp $ */
       3             : 
       4             : /*-
       5             :   * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
       6             :   * Copyright (c) 1992-1998 Søren Schmidt
       7             :   * All rights reserved.
       8             :   *
       9             :   * Redistribution and use in source and binary forms, with or without
      10             :   * modification, are permitted provided that the following conditions
      11             :   * are met:
      12             :   * 1. Redistributions of source code must retain the above copyright
      13             :   *    notice, this list of conditions and the following disclaimer as
      14             :   *    the first lines of this file unmodified.
      15             :   * 2. Redistributions in binary form must reproduce the above copyright
      16             :   *    notice, this list of conditions and the following disclaimer in the
      17             :   *    documentation and/or other materials provided with the distribution.
      18             :   * 3. The name of the author may not be used to endorse or promote products
      19             :   *    derived from this software without specific prior written permission.
      20             :   *
      21             :   * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
      22             :   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      23             :   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      24             :   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
      25             :   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      26             :   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      30             :   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :   *
      32             :   */
      33             : /*
      34             :  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
      35             :  * All rights reserved.
      36             :  *
      37             :  * Author: Chris G. Demetriou
      38             :  * 
      39             :  * Permission to use, copy, modify and distribute this software and
      40             :  * its documentation is hereby granted, provided that both the copyright
      41             :  * notice and this permission notice appear in all copies of the
      42             :  * software, derivative works or modified versions, and any portions
      43             :  * thereof, and that both notices appear in supporting documentation.
      44             :  * 
      45             :  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
      46             :  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
      47             :  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
      48             :  * 
      49             :  * Carnegie Mellon requests users of this software to return to
      50             :  *
      51             :  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
      52             :  *  School of Computer Science
      53             :  *  Carnegie Mellon University
      54             :  *  Pittsburgh PA 15213-3890
      55             :  *
      56             :  * any improvements or extensions that they make and grant Carnegie the
      57             :  * rights to redistribute these changes.
      58             :  */
      59             : 
      60             : #include "vga.h"
      61             : 
      62             : #include <sys/param.h>
      63             : #include <sys/systm.h>
      64             : #include <sys/kernel.h>
      65             : #include <sys/device.h>
      66             : #include <sys/malloc.h>
      67             : #include <sys/queue.h>
      68             : #include <machine/bus.h>
      69             : 
      70             : #include <dev/ic/mc6845reg.h>
      71             : #include <dev/ic/pcdisplayvar.h>
      72             : #include <dev/ic/vgareg.h>
      73             : 
      74             : #include <dev/wscons/wsdisplayvar.h>
      75             : #include <dev/wscons/wsconsio.h>
      76             : #include <dev/wscons/unicode.h>
      77             : 
      78             : #include <dev/ic/vgavar.h>
      79             : #include <dev/ic/pcdisplay.h>
      80             : 
      81             : static struct vgafont {
      82             :         char name[WSFONT_NAME_SIZE];
      83             :         int height;
      84             :         int encoding;
      85             : #ifdef notyet
      86             :         int firstchar, numchars;
      87             : #endif
      88             :         int slot;
      89             :         void *fontdata;
      90             : } vga_builtinfont = {
      91             :         .name = "builtin",
      92             :         .height = 16,
      93             :         .encoding = WSDISPLAY_FONTENC_IBM,
      94             : #ifdef notyet
      95             :         .firstchar = 0,
      96             :         .numchars = 256,
      97             : #endif
      98             :         .slot = 0,
      99             :         .fontdata = NULL
     100             : };
     101             : 
     102             : int vgaconsole, vga_console_type, vga_console_attached;
     103             : struct vgascreen vga_console_screen;
     104             : struct vga_config vga_console_vc;
     105             : 
     106             : int     vga_selectfont(struct vga_config *, struct vgascreen *,
     107             :     const char *, const char *);
     108             : void    vga_init_screen(struct vga_config *, struct vgascreen *,
     109             :     const struct wsscreen_descr *, int, long *);
     110             : void    vga_init(struct vga_config *, bus_space_tag_t, bus_space_tag_t);
     111             : void    vga_setfont(struct vga_config *, struct vgascreen *);
     112             : void    vga_pick_monitor_type(struct vga_config *);
     113             : 
     114             : int     vga_mapchar(void *, int, unsigned int *);
     115             : int     vga_putchar(void *, int, int, u_int, long);
     116             : int     vga_alloc_attr(void *, int, int, int, long *);
     117             : int     vga_copyrows(void *, int, int, int);
     118             : void    vga_unpack_attr(void *, long, int *, int *, int *);
     119             : 
     120             : static const struct wsdisplay_emulops vga_emulops = {
     121             :         pcdisplay_cursor,
     122             :         vga_mapchar,
     123             :         vga_putchar,
     124             :         pcdisplay_copycols,
     125             :         pcdisplay_erasecols,
     126             :         vga_copyrows,
     127             :         pcdisplay_eraserows,
     128             :         vga_alloc_attr,
     129             :         vga_unpack_attr
     130             : };
     131             : 
     132             : /*
     133             :  * translate WS(=ANSI) color codes to standard pc ones
     134             :  */
     135             : static const unsigned char fgansitopc[] = {
     136             : #ifdef __alpha__
     137             :         /*
     138             :          * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
     139             :          * XXX We should probably not bother with this
     140             :          * XXX (reinitialize the palette registers).
     141             :          */
     142             :         FG_BLACK, FG_BLUE, FG_GREEN, FG_CYAN, FG_RED,
     143             :         FG_MAGENTA, FG_BROWN, FG_LIGHTGREY
     144             : #else
     145             :         FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
     146             :         FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
     147             : #endif
     148             : }, bgansitopc[] = {
     149             : #ifdef __alpha__
     150             :         BG_BLACK, BG_BLUE, BG_GREEN, BG_CYAN, BG_RED,
     151             :         BG_MAGENTA, BG_BROWN, BG_LIGHTGREY
     152             : #else
     153             :         BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
     154             :         BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
     155             : #endif
     156             : };
     157             : 
     158             : /*
     159             :  * translate standard pc color codes to WS(=ANSI) ones
     160             :  */
     161             : static const u_int8_t pctoansi[] = {
     162             : #ifdef __alpha__
     163             :         WSCOL_BLACK, WSCOL_RED, WSCOL_GREEN, WSCOL_BROWN,
     164             :         WSCOL_BLUE, WSCOL_MAGENTA, WSCOL_CYAN, WSCOL_WHITE
     165             : #else
     166             :         WSCOL_BLACK, WSCOL_BLUE, WSCOL_GREEN, WSCOL_CYAN,
     167             :         WSCOL_RED, WSCOL_MAGENTA, WSCOL_BROWN, WSCOL_WHITE
     168             : #endif
     169             : };
     170             : 
     171             : 
     172             : const struct wsscreen_descr vga_stdscreen = {
     173             :         "80x25", 80, 25,
     174             :         &vga_emulops,
     175             :         8, 16,
     176             :         WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
     177             : }, vga_stdscreen_mono = {
     178             :         "80x25", 80, 25,
     179             :         &vga_emulops,
     180             :         8, 16,
     181             :         WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
     182             : }, vga_stdscreen_bf = {
     183             :         "80x25bf", 80, 25,
     184             :         &vga_emulops,
     185             :         8, 16,
     186             :         WSSCREEN_WSCOLORS | WSSCREEN_BLINK
     187             : }, vga_40lscreen = {
     188             :         "80x40", 80, 40,
     189             :         &vga_emulops,
     190             :         8, 10,
     191             :         WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
     192             : }, vga_40lscreen_mono = {
     193             :         "80x40", 80, 40,
     194             :         &vga_emulops,
     195             :         8, 10,
     196             :         WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
     197             : }, vga_40lscreen_bf = {
     198             :         "80x40bf", 80, 40,
     199             :         &vga_emulops,
     200             :         8, 10,
     201             :         WSSCREEN_WSCOLORS | WSSCREEN_BLINK
     202             : }, vga_50lscreen = {
     203             :         "80x50", 80, 50,
     204             :         &vga_emulops,
     205             :         8, 8,
     206             :         WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
     207             : }, vga_50lscreen_mono = {
     208             :         "80x50", 80, 50,
     209             :         &vga_emulops,
     210             :         8, 8,
     211             :         WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
     212             : }, vga_50lscreen_bf = {
     213             :         "80x50bf", 80, 50,
     214             :         &vga_emulops,
     215             :         8, 8,
     216             :         WSSCREEN_WSCOLORS | WSSCREEN_BLINK
     217             : };
     218             : 
     219             : #define VGA_SCREEN_CANTWOFONTS(type) (!((type)->capabilities & WSSCREEN_HILIT))
     220             : 
     221             : const struct wsscreen_descr *_vga_scrlist[] = {
     222             :         &vga_stdscreen,
     223             :         &vga_stdscreen_bf,
     224             :         &vga_40lscreen,
     225             :         &vga_40lscreen_bf,
     226             :         &vga_50lscreen,
     227             :         &vga_50lscreen_bf,
     228             :         /* XXX other formats, graphics screen? */
     229             : }, *_vga_scrlist_mono[] = {
     230             :         &vga_stdscreen_mono,
     231             :         &vga_40lscreen_mono,
     232             :         &vga_50lscreen_mono,
     233             :         /* XXX other formats, graphics screen? */
     234             : };
     235             : 
     236             : const struct wsscreen_list vga_screenlist = {
     237             :         sizeof(_vga_scrlist) / sizeof(struct wsscreen_descr *),
     238             :         _vga_scrlist
     239             : }, vga_screenlist_mono = {
     240             :         sizeof(_vga_scrlist_mono) / sizeof(struct wsscreen_descr *),
     241             :         _vga_scrlist_mono
     242             : };
     243             : 
     244             : int     vga_ioctl(void *, u_long, caddr_t, int, struct proc *);
     245             : paddr_t vga_mmap(void *, off_t, int);
     246             : int     vga_alloc_screen(void *, const struct wsscreen_descr *,
     247             :                          void **, int *, int *, long *);
     248             : void    vga_free_screen(void *, void *);
     249             : int     vga_show_screen(void *, void *, int,
     250             :                         void (*) (void *, int, int), void *);
     251             : int     vga_load_font(void *, void *, struct wsdisplay_font *);
     252             : int     vga_list_font(void *, struct wsdisplay_font *);
     253             : void    vga_scrollback(void *, void *, int);
     254             : void    vga_burner(void *v, u_int on, u_int flags);
     255             : int     vga_getchar(void *, int, int, struct wsdisplay_charcell *);
     256             : 
     257             : void vga_doswitch(struct vga_config *);
     258             : 
     259             : const struct wsdisplay_accessops vga_accessops = {
     260             :         .ioctl = vga_ioctl,
     261             :         .mmap = vga_mmap,
     262             :         .alloc_screen = vga_alloc_screen,
     263             :         .free_screen = vga_free_screen,
     264             :         .show_screen = vga_show_screen,
     265             :         .load_font = vga_load_font,
     266             :         .list_font = vga_list_font,
     267             :         .scrollback = vga_scrollback,
     268             :         .getchar = vga_getchar,
     269             :         .burn_screen = vga_burner
     270             : };
     271             : 
     272             : /*
     273             :  * The following functions implement back-end configuration grabbing
     274             :  * and attachment.
     275             :  */
     276             : int
     277           0 : vga_common_probe(bus_space_tag_t iot, bus_space_tag_t memt)
     278             : {
     279           0 :         bus_space_handle_t ioh_vga, ioh_6845, memh;
     280             :         u_int8_t regval;
     281             :         u_int16_t vgadata;
     282             :         int gotio_vga, gotio_6845, gotmem, mono, rv;
     283             :         int dispoffset;
     284             : 
     285             :         gotio_vga = gotio_6845 = gotmem = rv = 0;
     286             : 
     287           0 :         if (bus_space_map(iot, 0x3c0, 0x10, 0, &ioh_vga))
     288             :                 goto bad;
     289             :         gotio_vga = 1;
     290             : 
     291             :         /* read "misc output register" */
     292           0 :         regval = bus_space_read_1(iot, ioh_vga, 0xc);
     293           0 :         mono = !(regval & 1);
     294             : 
     295           0 :         if (bus_space_map(iot, (mono ? 0x3b0 : 0x3d0), 0x10, 0, &ioh_6845))
     296             :                 goto bad;
     297             :         gotio_6845 = 1;
     298             : 
     299           0 :         if (bus_space_map(memt, 0xa0000, 0x20000, 0, &memh))
     300             :                 goto bad;
     301             :         gotmem = 1;
     302             : 
     303           0 :         dispoffset = (mono ? 0x10000 : 0x18000);
     304             : 
     305           0 :         vgadata = bus_space_read_2(memt, memh, dispoffset);
     306           0 :         bus_space_write_2(memt, memh, dispoffset, 0xa55a);
     307           0 :         if (bus_space_read_2(memt, memh, dispoffset) != 0xa55a)
     308             :                 goto bad;
     309           0 :         bus_space_write_2(memt, memh, dispoffset, vgadata);
     310             : 
     311             :         /*
     312             :          * check if this is really a VGA
     313             :          * (try to write "Color Select" register as XFree86 does)
     314             :          * XXX check before if at least EGA?
     315             :          */
     316             :         /* reset state */
     317           0 :         (void) bus_space_read_1(iot, ioh_6845, 10);
     318           0 :         bus_space_write_1(iot, ioh_vga, VGA_ATC_INDEX,
     319             :                           20 | 0x20); /* colselect | enable */
     320           0 :         regval = bus_space_read_1(iot, ioh_vga, VGA_ATC_DATAR);
     321             :         /* toggle the implemented bits */
     322           0 :         bus_space_write_1(iot, ioh_vga, VGA_ATC_DATAW, regval ^ 0x0f);
     323           0 :         bus_space_write_1(iot, ioh_vga, VGA_ATC_INDEX,
     324             :                           20 | 0x20);
     325             :         /* read back */
     326           0 :         if (bus_space_read_1(iot, ioh_vga, VGA_ATC_DATAR) != (regval ^ 0x0f))
     327             :                 goto bad;
     328             :         /* restore contents */
     329           0 :         bus_space_write_1(iot, ioh_vga, VGA_ATC_DATAW, regval);
     330             : 
     331           0 :         rv = 1;
     332             : bad:
     333           0 :         if (gotio_vga)
     334           0 :                 bus_space_unmap(iot, ioh_vga, 0x10);
     335           0 :         if (gotio_6845)
     336           0 :                 bus_space_unmap(iot, ioh_6845, 0x10);
     337           0 :         if (gotmem)
     338           0 :                 bus_space_unmap(memt, memh, 0x20000);
     339             : 
     340           0 :         return (rv);
     341           0 : }
     342             : 
     343             : /*
     344             :  * We want at least ASCII 32..127 be present in the
     345             :  * first font slot.
     346             :  */
     347             : int
     348           0 : vga_selectfont(struct vga_config *vc, struct vgascreen *scr, const char *name1,
     349             :     const char *name2) /* NULL: take first found */
     350             : {
     351           0 :         const struct wsscreen_descr *type = scr->pcs.type;
     352             :         struct vgafont *f1, *f2;
     353             :         int i;
     354             : 
     355             :         f1 = f2 = 0;
     356             : 
     357           0 :         for (i = 0; i < VGA_MAXFONT; i++) {
     358           0 :                 struct vgafont *f = vc->vc_fonts[i];
     359           0 :                 if (!f || f->height != type->fontheight)
     360           0 :                         continue;
     361           0 :                 if (!f1 && (!name1 || !*name1 ||
     362           0 :                      !strncmp(name1, f->name, WSFONT_NAME_SIZE))) {
     363             :                         f1 = f;
     364           0 :                         continue;
     365             :                 }
     366           0 :                 if (!f2 &&
     367           0 :                     VGA_SCREEN_CANTWOFONTS(type) &&
     368           0 :                     (!name2 || !*name2 ||
     369           0 :                      !strncmp(name2, f->name, WSFONT_NAME_SIZE))) {
     370             :                         f2 = f;
     371           0 :                         continue;
     372             :                 }
     373           0 :         }
     374             : 
     375             :         /*
     376             :          * The request fails if no primary font was found,
     377             :          * or if a second font was requested but not found.
     378             :          */
     379           0 :         if (f1 && (!name2 || !*name2 || f2)) {
     380             : #ifdef VGAFONTDEBUG
     381             :                 if (scr != &vga_console_screen || vga_console_attached) {
     382             :                         printf("vga (%s): font1=%s (slot %d)", type->name,
     383             :                                f1->name, f1->slot);
     384             :                         if (f2)
     385             :                                 printf(", font2=%s (slot %d)",
     386             :                                        f2->name, f2->slot);
     387             :                         printf("\n");
     388             :                 }
     389             : #endif
     390           0 :                 scr->fontset1 = f1;
     391           0 :                 scr->fontset2 = f2;
     392           0 :                 return (0);
     393             :         }
     394           0 :         return (ENXIO);
     395           0 : }
     396             : 
     397             : void
     398           0 : vga_init_screen(struct vga_config *vc, struct vgascreen *scr,
     399             :     const struct wsscreen_descr *type, int existing, long *attrp)
     400             : {
     401             :         int cpos;
     402             :         int res;
     403             : 
     404           0 :         scr->cfg = vc;
     405           0 :         scr->pcs.hdl = (struct pcdisplay_handle *)&vc->hdl;
     406           0 :         scr->pcs.type = type;
     407           0 :         scr->pcs.active = 0;
     408           0 :         scr->mindispoffset = 0;
     409           0 :         scr->maxdispoffset = 0x8000 - type->nrows * type->ncols * 2;
     410             : 
     411           0 :         if (existing) {
     412           0 :                 cpos = vga_6845_read(&vc->hdl, cursorh) << 8;
     413           0 :                 cpos |= vga_6845_read(&vc->hdl, cursorl);
     414             : 
     415             :                 /* make sure we have a valid cursor position */
     416           0 :                 if (cpos < 0 || cpos >= type->nrows * type->ncols)
     417           0 :                         cpos = 0;
     418             : 
     419           0 :                 scr->pcs.dispoffset = vga_6845_read(&vc->hdl, startadrh) << 9;
     420           0 :                 scr->pcs.dispoffset |= vga_6845_read(&vc->hdl, startadrl) << 1;
     421             : 
     422             :                 /* make sure we have a valid memory offset */
     423           0 :                 if (scr->pcs.dispoffset < scr->mindispoffset ||
     424           0 :                     scr->pcs.dispoffset > scr->maxdispoffset)
     425           0 :                         scr->pcs.dispoffset = scr->mindispoffset;
     426             :         } else {
     427             :                 cpos = 0;
     428           0 :                 scr->pcs.dispoffset = scr->mindispoffset;
     429             :         }
     430           0 :         scr->pcs.visibleoffset = scr->pcs.dispoffset;
     431           0 :         scr->vga_rollover = 0;
     432             : 
     433           0 :         scr->pcs.vc_crow = cpos / type->ncols;
     434           0 :         scr->pcs.vc_ccol = cpos % type->ncols;
     435           0 :         pcdisplay_cursor_init(&scr->pcs, existing);
     436             : 
     437             : #ifdef __alpha__
     438             :         if (!vc->hdl.vh_mono)
     439             :                 /*
     440             :                  * DEC firmware uses a blue background.
     441             :                  */
     442             :                 res = vga_alloc_attr(scr, WSCOL_WHITE, WSCOL_BLUE,
     443             :                                      WSATTR_WSCOLORS, attrp);
     444             :         else
     445             : #endif
     446           0 :         res = vga_alloc_attr(scr, 0, 0, 0, attrp);
     447             : #ifdef DIAGNOSTIC
     448           0 :         if (res)
     449           0 :                 panic("vga_init_screen: attribute botch");
     450             : #endif
     451             : 
     452           0 :         scr->pcs.mem = NULL;
     453             : 
     454           0 :         scr->fontset1 = scr->fontset2 = 0;
     455           0 :         if (vga_selectfont(vc, scr, 0, 0)) {
     456           0 :                 if (scr == &vga_console_screen)
     457           0 :                         panic("vga_init_screen: no font");
     458             :                 else
     459           0 :                         printf("vga_init_screen: no font\n");
     460           0 :         }
     461             : 
     462           0 :         vc->nscreens++;
     463           0 :         LIST_INSERT_HEAD(&vc->screens, scr, next);
     464           0 : }
     465             : 
     466             : void
     467           0 : vga_init(struct vga_config *vc, bus_space_tag_t iot, bus_space_tag_t memt)
     468             : {
     469           0 :         struct vga_handle *vh = &vc->hdl;
     470             :         u_int8_t mor;
     471             :         int i;
     472             : 
     473           0 :         vh->vh_iot = iot;
     474           0 :         vh->vh_memt = memt;
     475             : 
     476           0 :         if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
     477           0 :                 panic("vga_common_setup: can't map vga i/o");
     478             : 
     479             :         /* read "misc output register" */
     480           0 :         mor = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, 0xc);
     481           0 :         vh->vh_mono = !(mor & 1);
     482             : 
     483           0 :         if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0,
     484           0 :                           &vh->vh_ioh_6845))
     485           0 :                 panic("vga_common_setup: can't map 6845 i/o");
     486             : 
     487           0 :         if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
     488           0 :                 panic("vga_common_setup: can't map mem space");
     489             : 
     490           0 :         if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
     491           0 :                                 (vh->vh_mono ? 0x10000 : 0x18000), 0x8000,
     492           0 :                                 &vh->vh_memh))
     493           0 :                 panic("vga_common_setup: mem subrange failed");
     494             : 
     495             : #ifdef __alpha__
     496             :         vga_pick_monitor_type(vc);
     497             : #endif
     498             : 
     499           0 :         vc->nscreens = 0;
     500           0 :         LIST_INIT(&vc->screens);
     501           0 :         vc->active = NULL;
     502             : #ifdef __alpha__
     503             :         if (vc->custom_list.screens != NULL)
     504             :                 vc->currenttype = vc->custom_list.screens[0];
     505             :         else
     506             : #endif
     507           0 :                 vc->currenttype =
     508           0 :                     vh->vh_mono ? &vga_stdscreen_mono : &vga_stdscreen;
     509             : 
     510           0 :         vc->vc_fonts[0] = &vga_builtinfont;
     511           0 :         for (i = 1; i < VGA_MAXFONT; i++)
     512           0 :                 vc->vc_fonts[i] = NULL;
     513             : 
     514           0 :         vc->currentfontset1 = vc->currentfontset2 = 0;
     515             : 
     516           0 :         vga_save_palette(vc);
     517           0 : }
     518             : 
     519             : struct vga_config *
     520           0 : vga_common_attach(struct device *self, bus_space_tag_t iot,
     521             :     bus_space_tag_t memt, int type)
     522             : {
     523           0 :         return vga_extended_attach(self, iot, memt, type, NULL);
     524             : }
     525             : 
     526             : struct vga_config *
     527           0 : vga_extended_attach(struct device *self, bus_space_tag_t iot,
     528             :     bus_space_tag_t memt, int type, paddr_t (*map)(void *, off_t, int))
     529             : {
     530             :         int console;
     531             :         struct vga_config *vc;
     532           0 :         struct wsemuldisplaydev_attach_args aa;
     533             : 
     534           0 :         console = vga_is_console(iot, type);
     535           0 :         if (console)
     536           0 :                 vga_console_attached = 1;
     537             : 
     538           0 :         if (type == -1)
     539           0 :                 return NULL;
     540             : 
     541           0 :         if (console) {
     542             :                 vc = &vga_console_vc;
     543           0 :         } else {
     544           0 :                 vc = malloc(sizeof(*vc), M_DEVBUF, M_NOWAIT | M_ZERO);
     545           0 :                 if (vc == NULL)
     546           0 :                         return NULL;
     547           0 :                 vga_init(vc, iot, memt);
     548             :         }
     549             : 
     550           0 :         vc->vc_softc = self;
     551           0 :         vc->vc_type = type;
     552           0 :         vc->vc_mmap = map;
     553             : 
     554           0 :         aa.console = console;
     555             : #ifdef __alpha__
     556             :         if (vc->custom_list.screens != NULL)
     557             :                 aa.scrdata = &vc->custom_list;
     558             :         else
     559             : #endif
     560           0 :                 aa.scrdata =
     561           0 :                     vc->hdl.vh_mono ? &vga_screenlist_mono : &vga_screenlist;
     562             : 
     563           0 :         aa.accessops = &vga_accessops;
     564           0 :         aa.accesscookie = vc;
     565           0 :         aa.defaultscreens = 0;
     566             : 
     567           0 :         config_found_sm(self, &aa, wsemuldisplaydevprint,
     568             :             wsemuldisplaydevsubmatch);
     569             : 
     570           0 :         return vc;
     571           0 : }
     572             : 
     573             : int
     574           0 : vga_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, int type, int check)
     575             : {
     576           0 :         long defattr;
     577             :         const struct wsscreen_descr *scr;
     578             : 
     579           0 :         if (check && !vga_common_probe(iot, memt))
     580           0 :                 return (ENXIO);
     581             : 
     582             :         /* set up bus-independent VGA configuration */
     583           0 :         vga_init(&vga_console_vc, iot, memt);
     584           0 :         scr = vga_console_vc.currenttype;
     585           0 :         vga_init_screen(&vga_console_vc, &vga_console_screen, scr, 1, &defattr);
     586             : 
     587           0 :         vga_console_screen.pcs.active = 1;
     588           0 :         vga_console_vc.active = &vga_console_screen;
     589             : 
     590           0 :         wsdisplay_cnattach(scr, &vga_console_screen,
     591           0 :                            vga_console_screen.pcs.vc_ccol,
     592           0 :                            vga_console_screen.pcs.vc_crow,
     593           0 :                            defattr);
     594             : 
     595           0 :         vgaconsole = 1;
     596           0 :         vga_console_type = type;
     597           0 :         return (0);
     598           0 : }
     599             : 
     600             : int
     601           0 : vga_is_console(bus_space_tag_t iot, int type)
     602             : {
     603           0 :         if (vgaconsole &&
     604           0 :             !vga_console_attached &&
     605           0 :             iot == vga_console_vc.hdl.vh_iot &&
     606           0 :             (vga_console_type == -1 || (type == vga_console_type)))
     607           0 :                 return (1);
     608           0 :         return (0);
     609           0 : }
     610             : 
     611             : int
     612           0 : vga_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
     613             : {
     614           0 :         struct vga_config *vc = v;
     615             :         int mode;
     616             : #if NVGA_PCI > 0
     617             :         int error;
     618             : 
     619           0 :         if (vc->vc_type == WSDISPLAY_TYPE_PCIVGA &&
     620           0 :             (error = vga_pci_ioctl(v, cmd, data, flag, p)) != ENOTTY)
     621           0 :                 return (error);
     622             : #endif
     623             : 
     624           0 :         switch (cmd) {
     625             :         case WSDISPLAYIO_GTYPE:
     626           0 :                 *(int *)data = vc->vc_type;
     627             :                 /* XXX should get detailed hardware information here */
     628           0 :                 break;
     629             : 
     630             :         case WSDISPLAYIO_SMODE:
     631           0 :                 mode = *(u_int *)data;
     632           0 :                 if (mode == WSDISPLAYIO_MODE_EMUL) {
     633           0 :                         vga_restore_fonts(vc);
     634           0 :                         vga_restore_palette(vc);
     635           0 :                 }
     636             :                 break;
     637             : 
     638             :         case WSDISPLAYIO_GVIDEO:
     639             :         case WSDISPLAYIO_SVIDEO:
     640             :                 break;
     641             : 
     642             :         case WSDISPLAYIO_GINFO:
     643             :         case WSDISPLAYIO_GETCMAP:
     644             :         case WSDISPLAYIO_PUTCMAP:
     645             :         case WSDISPLAYIO_GCURPOS:
     646             :         case WSDISPLAYIO_SCURPOS:
     647             :         case WSDISPLAYIO_GCURMAX:
     648             :         case WSDISPLAYIO_GCURSOR:
     649             :         case WSDISPLAYIO_SCURSOR:
     650             :         default:
     651             :                 /* NONE of these operations are by the generic VGA driver. */
     652           0 :                 return ENOTTY;
     653             :         }
     654             : 
     655           0 :         return (0);
     656           0 : }
     657             : 
     658             : paddr_t
     659           0 : vga_mmap(void *v, off_t offset, int prot)
     660             : {
     661           0 :         struct vga_config *vc = v;
     662             : 
     663           0 :         if (vc->vc_mmap != NULL)
     664           0 :                 return (*vc->vc_mmap)(v, offset, prot);
     665             : 
     666           0 :         return (paddr_t)-1;
     667           0 : }
     668             : 
     669             : int
     670           0 : vga_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
     671             :     int *curxp, int *curyp, long *defattrp)
     672             : {
     673           0 :         struct vga_config *vc = v;
     674             :         struct vgascreen *scr;
     675             : 
     676           0 :         if (vc->nscreens == 1) {
     677             :                 /*
     678             :                  * When allocating the second screen, get backing store
     679             :                  * for the first one too.
     680             :                  * XXX We could be more clever and use video RAM.
     681             :                  */
     682           0 :                 scr = LIST_FIRST(&vc->screens);
     683           0 :                 scr->pcs.mem = mallocarray(scr->pcs.type->ncols,
     684           0 :                     scr->pcs.type->nrows * 2, M_DEVBUF, M_WAITOK);
     685           0 :         }
     686             : 
     687           0 :         scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK);
     688           0 :         vga_init_screen(vc, scr, type, vc->nscreens == 0, defattrp);
     689             : 
     690           0 :         if (vc->nscreens == 1) {
     691           0 :                 scr->pcs.active = 1;
     692           0 :                 vc->active = scr;
     693           0 :                 vc->currenttype = type;
     694           0 :         } else {
     695           0 :                 scr->pcs.mem = mallocarray(type->ncols,
     696           0 :                     type->nrows * 2, M_DEVBUF, M_WAITOK);
     697           0 :                 pcdisplay_eraserows(&scr->pcs, 0, type->nrows, *defattrp);
     698             :         }
     699             : 
     700           0 :         *cookiep = scr;
     701           0 :         *curxp = scr->pcs.vc_ccol;
     702           0 :         *curyp = scr->pcs.vc_crow;
     703             : 
     704           0 :         return (0);
     705             : }
     706             : 
     707             : void
     708           0 : vga_free_screen(void *v, void *cookie)
     709             : {
     710           0 :         struct vgascreen *vs = cookie;
     711           0 :         struct vga_config *vc = vs->cfg;
     712             : 
     713           0 :         LIST_REMOVE(vs, next);
     714           0 :         vc->nscreens--;
     715           0 :         if (vs != &vga_console_screen) {
     716             :                 /*
     717             :                  * deallocating the one but last screen
     718             :                  * removes backing store for the last one
     719             :                  */
     720           0 :                 if (vc->nscreens == 1)
     721           0 :                         free(LIST_FIRST(&vc->screens)->pcs.mem, M_DEVBUF, 0);
     722             : 
     723             :                 /* Last screen has no backing store */
     724           0 :                 if (vc->nscreens != 0)
     725           0 :                         free(vs->pcs.mem, M_DEVBUF, 0);
     726             : 
     727           0 :                 free(vs, M_DEVBUF, sizeof *vs);
     728             :         } else
     729           0 :                 panic("vga_free_screen: console");
     730             : 
     731           0 :         if (vc->active == vs)
     732           0 :                 vc->active = NULL;
     733           0 : }
     734             : 
     735             : void
     736           0 : vga_setfont(struct vga_config *vc, struct vgascreen *scr)
     737             : {
     738             :         int fontslot1, fontslot2;
     739             : 
     740           0 :         fontslot1 = (scr->fontset1 ? scr->fontset1->slot : 0);
     741           0 :         fontslot2 = (scr->fontset2 ? scr->fontset2->slot : fontslot1);
     742           0 :         if (vc->currentfontset1 != fontslot1 ||
     743           0 :             vc->currentfontset2 != fontslot2) {
     744           0 :                 vga_setfontset(&vc->hdl, fontslot1, fontslot2);
     745           0 :                 vc->currentfontset1 = fontslot1;
     746           0 :                 vc->currentfontset2 = fontslot2;
     747           0 :         }
     748           0 : }
     749             : 
     750             : int
     751           0 : vga_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
     752             :     void *cbarg)
     753             : {
     754           0 :         struct vgascreen *scr = cookie, *oldscr;
     755           0 :         struct vga_config *vc = scr->cfg;
     756             : 
     757           0 :         oldscr = vc->active; /* can be NULL! */
     758           0 :         if (scr == oldscr) {
     759           0 :                 return (0);
     760             :         }
     761             : 
     762           0 :         vc->wantedscreen = cookie;
     763           0 :         vc->switchcb = cb;
     764           0 :         vc->switchcbarg = cbarg;
     765           0 :         if (cb) {
     766           0 :                 timeout_set(&vc->vc_switch_timeout,
     767           0 :                     (void(*)(void *))vga_doswitch, vc);
     768           0 :                 timeout_add(&vc->vc_switch_timeout, 0);
     769           0 :                 return (EAGAIN);
     770             :         }
     771             : 
     772           0 :         vga_doswitch(vc);
     773           0 :         return (0);
     774           0 : }
     775             : 
     776             : void
     777           0 : vga_doswitch(struct vga_config *vc)
     778             : {
     779             :         struct vgascreen *scr, *oldscr;
     780           0 :         struct vga_handle *vh = &vc->hdl;
     781             :         const struct wsscreen_descr *type;
     782             :         int s;
     783             : 
     784           0 :         scr = vc->wantedscreen;
     785           0 :         if (!scr) {
     786           0 :                 printf("vga_doswitch: disappeared\n");
     787           0 :                 (*vc->switchcb)(vc->switchcbarg, EIO, 0);
     788           0 :                 return;
     789             :         }
     790             : 
     791           0 :         type = scr->pcs.type;
     792           0 :         oldscr = vc->active; /* can be NULL! */
     793           0 :         if (scr == oldscr)
     794           0 :                 return;
     795           0 :         s = spltty();
     796             : #ifdef DIAGNOSTIC
     797           0 :         if (oldscr) {
     798           0 :                 if (!oldscr->pcs.active)
     799           0 :                         panic("vga_show_screen: not active");
     800           0 :                 if (oldscr->pcs.type != vc->currenttype)
     801           0 :                         panic("vga_show_screen: bad type");
     802             :         }
     803           0 :         if (scr->pcs.active)
     804           0 :                 panic("vga_show_screen: active");
     805             : #endif
     806             : 
     807           0 :         scr->vga_rollover = 0;
     808             : 
     809           0 :         if (oldscr) {
     810           0 :                 const struct wsscreen_descr *oldtype = oldscr->pcs.type;
     811             : 
     812           0 :                 oldscr->pcs.active = 0;
     813           0 :                 bus_space_read_region_2(vh->vh_memt, vh->vh_memh,
     814             :                                         oldscr->pcs.dispoffset, oldscr->pcs.mem,
     815             :                                         oldtype->ncols * oldtype->nrows);
     816           0 :         }
     817             : 
     818           0 :         if (vc->currenttype != type) {
     819           0 :                 vga_setscreentype(vh, type);
     820           0 :                 vc->currenttype = type;
     821           0 :         }
     822             : 
     823           0 :         vga_setfont(vc, scr);
     824           0 :         vga_restore_palette(vc);
     825             : 
     826           0 :         scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
     827           0 :         if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
     828           0 :                 vga_6845_write(vh, startadrh, scr->pcs.dispoffset >> 9);
     829           0 :                 vga_6845_write(vh, startadrl, scr->pcs.dispoffset >> 1);
     830           0 :         }
     831             : 
     832           0 :         bus_space_write_region_2(vh->vh_memt, vh->vh_memh,
     833             :                                 scr->pcs.dispoffset, scr->pcs.mem,
     834             :                                 type->ncols * type->nrows);
     835           0 :         scr->pcs.active = 1;
     836           0 :         splx(s);
     837             : 
     838           0 :         vc->active = scr;
     839             : 
     840           0 :         pcdisplay_cursor_reset(&scr->pcs);
     841           0 :         pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron,
     842           0 :                          scr->pcs.vc_crow, scr->pcs.vc_ccol);
     843             : 
     844           0 :         vc->wantedscreen = 0;
     845           0 :         if (vc->switchcb)
     846           0 :                 (*vc->switchcb)(vc->switchcbarg, 0, 0);
     847           0 : }
     848             : 
     849             : int
     850           0 : vga_load_font(void *v, void *cookie, struct wsdisplay_font *data)
     851             : {
     852           0 :         struct vga_config *vc = v;
     853           0 :         struct vgascreen *scr = cookie;
     854             :         char *name2;
     855             :         int res, slot;
     856             :         struct vgafont *f;
     857             : 
     858           0 :         if (data->data == NULL) {
     859           0 :                 if (scr == NULL)
     860           0 :                         return EINVAL;
     861             : 
     862           0 :                 if ((name2 = data->name) != NULL) {
     863           0 :                         while (*name2 && *name2 != ',')
     864           0 :                                 name2++;
     865           0 :                         if (*name2)
     866           0 :                                 *name2++ = '\0';
     867             :                 }
     868           0 :                 res = vga_selectfont(vc, scr, data->name, name2);
     869           0 :                 if (res == 0)
     870           0 :                         vga_setfont(vc, scr);
     871           0 :                 return (res);
     872             :         }
     873             : 
     874           0 :         if (data->fontwidth != 8 || data->stride != 1)
     875           0 :                 return (EINVAL); /* XXX 1 byte per line */
     876           0 :         if (data->firstchar != 0 || data->numchars != 256)
     877           0 :                 return (EINVAL);
     878             : 
     879           0 :         if (data->index < 0) {
     880           0 :                 for (slot = 0; slot < VGA_MAXFONT; slot++)
     881           0 :                         if (!vc->vc_fonts[slot])
     882             :                                 break;
     883             :         } else
     884             :                 slot = data->index;
     885             : 
     886           0 :         if (slot >= VGA_MAXFONT)
     887           0 :                 return (ENOSPC);
     888             : 
     889           0 :         if (vc->vc_fonts[slot] != NULL)
     890           0 :                 return (EEXIST);
     891           0 :         f = malloc(sizeof(struct vgafont), M_DEVBUF, M_WAITOK | M_CANFAIL);
     892           0 :         if (f == NULL)
     893           0 :                 return (ENOMEM);
     894           0 :         strlcpy(f->name, data->name, sizeof(f->name));
     895           0 :         f->height = data->fontheight;
     896           0 :         f->encoding = data->encoding;
     897             : #ifdef notyet
     898             :         f->firstchar = data->firstchar;
     899             :         f->numchars = data->numchars;
     900             : #endif
     901             : #ifdef VGAFONTDEBUG
     902             :         printf("vga: load %s (8x%d, enc %d) font to slot %d\n", f->name,
     903             :                f->height, f->encoding, slot);
     904             : #endif
     905           0 :         vga_loadchars(&vc->hdl, slot, 0, 256, f->height, data->data);
     906           0 :         f->slot = slot;
     907           0 :         f->fontdata = data->data;
     908           0 :         vc->vc_fonts[slot] = f;
     909           0 :         data->cookie = f;
     910           0 :         data->index = slot;
     911             : 
     912           0 :         return (0);
     913           0 : }
     914             : 
     915             : int
     916           0 : vga_list_font(void *v, struct wsdisplay_font *data)
     917             : {
     918           0 :         struct vga_config *vc = v;
     919             :         struct vgafont *f;
     920             : 
     921           0 :         if (data->index < 0 || data->index >= VGA_MAXFONT)
     922           0 :                 return EINVAL;
     923             : 
     924           0 :         if ((f = vc->vc_fonts[data->index]) == NULL)
     925           0 :                 return EINVAL;
     926             : 
     927           0 :         strlcpy(data->name, f->name, sizeof data->name);
     928             : #ifdef notyet
     929             :         data->firstchar = f->firstchar;
     930             :         data->numchars = f->numchars;
     931             : #else
     932           0 :         data->firstchar = 0;
     933           0 :         data->numchars = 256;
     934             : #endif
     935           0 :         data->encoding = f->encoding;
     936           0 :         data->fontwidth = 8;
     937           0 :         data->fontheight = f->height;
     938           0 :         data->stride = 1;
     939           0 :         data->bitorder = data->byteorder = WSDISPLAY_FONTORDER_L2R;
     940             : 
     941           0 :         return (0);
     942           0 : }
     943             : 
     944             : void
     945           0 : vga_scrollback(void *v, void *cookie, int lines)
     946             : {
     947           0 :         struct vga_config *vc = v;
     948           0 :         struct vgascreen *scr = cookie;
     949           0 :         struct vga_handle *vh = &vc->hdl;
     950             : 
     951           0 :         if (lines == 0) {
     952           0 :                 if (scr->pcs.visibleoffset == scr->pcs.dispoffset)
     953           0 :                         return;
     954             : 
     955           0 :                 scr->pcs.visibleoffset = scr->pcs.dispoffset;     /* reset */
     956           0 :         }
     957             :         else {
     958             :                 int vga_scr_end;
     959           0 :                 int margin = scr->pcs.type->ncols * 2;
     960             :                 int ul, we, p, st;
     961             : 
     962           0 :                 vga_scr_end = (scr->pcs.dispoffset + scr->pcs.type->ncols *
     963           0 :                     scr->pcs.type->nrows * 2);
     964           0 :                 if (scr->vga_rollover > vga_scr_end + margin) {
     965             :                         ul = vga_scr_end;
     966           0 :                         we = scr->vga_rollover + scr->pcs.type->ncols * 2;
     967           0 :                 } else {
     968             :                         ul = 0;
     969             :                         we = 0x8000;
     970             :                 }
     971           0 :                 p = (scr->pcs.visibleoffset - ul + we) % we + lines *
     972           0 :                     (scr->pcs.type->ncols * 2);
     973           0 :                 st = (scr->pcs.dispoffset - ul + we) % we;
     974           0 :                 if (p < margin)
     975           0 :                         p = 0;
     976           0 :                 if (p > st - margin)
     977           0 :                         p = st;
     978           0 :                 scr->pcs.visibleoffset = (p + ul) % we;
     979             :         }
     980             :         
     981             :         /* update visible position */
     982           0 :         vga_6845_write(vh, startadrh, scr->pcs.visibleoffset >> 9);
     983           0 :         vga_6845_write(vh, startadrl, scr->pcs.visibleoffset >> 1);
     984           0 : }
     985             : 
     986             : int
     987           0 : vga_alloc_attr(void *id, int fg, int bg, int flags, long *attrp)
     988             : {
     989           0 :         struct vgascreen *scr = id;
     990           0 :         struct vga_config *vc = scr->cfg;
     991             : 
     992           0 :         if (vc->hdl.vh_mono) {
     993           0 :                 if (flags & WSATTR_WSCOLORS)
     994           0 :                         return (EINVAL);
     995           0 :                 if (flags & WSATTR_REVERSE)
     996           0 :                         *attrp = 0x70;
     997             :                 else
     998           0 :                         *attrp = 0x07;
     999           0 :                 if (flags & WSATTR_UNDERLINE)
    1000           0 :                         *attrp |= FG_UNDERLINE;
    1001           0 :                 if (flags & WSATTR_HILIT)
    1002           0 :                         *attrp |= FG_INTENSE;
    1003             :         } else {
    1004           0 :                 if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE))
    1005           0 :                         return (EINVAL);
    1006           0 :                 if (flags & WSATTR_WSCOLORS)
    1007           0 :                         *attrp = fgansitopc[fg & 7] | bgansitopc[bg & 7];
    1008             :                 else
    1009           0 :                         *attrp = 7;
    1010           0 :                 if ((flags & WSATTR_HILIT) || (fg & 8) || (bg & 8))
    1011           0 :                         *attrp += 8;
    1012             :         }
    1013           0 :         if (flags & WSATTR_BLINK)
    1014           0 :                 *attrp |= FG_BLINK;
    1015           0 :         return (0);
    1016           0 : }
    1017             : 
    1018             : void
    1019           0 : vga_unpack_attr(void *id, long attr, int *fg, int *bg, int *ul)
    1020             : {
    1021           0 :         struct vgascreen *scr = id;
    1022           0 :         struct vga_config *vc = scr->cfg;
    1023             : 
    1024           0 :         if (vc->hdl.vh_mono) {
    1025           0 :                 *fg = (attr & 0x07) == 0x07 ? WSCOL_WHITE : WSCOL_BLACK;
    1026           0 :                 *bg = attr & 0x70 ? WSCOL_WHITE : WSCOL_BLACK;
    1027           0 :                 if (ul != NULL)
    1028           0 :                         *ul = *fg != WSCOL_WHITE && (attr & 0x01) ? 1 : 0;
    1029             :         } else {
    1030           0 :                 *fg = pctoansi[attr & 0x07];
    1031           0 :                 *bg = pctoansi[(attr & 0x70) >> 4];
    1032           0 :                 if (ul != NULL)
    1033           0 :                         *ul = 0;
    1034             :         }
    1035           0 :         if (attr & FG_INTENSE)
    1036           0 :                 *fg += 8;
    1037           0 : }
    1038             : 
    1039             : int
    1040           0 : vga_copyrows(void *id, int srcrow, int dstrow, int nrows)
    1041             : {
    1042           0 :         struct vgascreen *scr = id;
    1043           0 :         bus_space_tag_t memt = scr->pcs.hdl->ph_memt;
    1044           0 :         bus_space_handle_t memh = scr->pcs.hdl->ph_memh;
    1045           0 :         int ncols = scr->pcs.type->ncols;
    1046             :         bus_size_t srcoff, dstoff;
    1047             :         int s;
    1048             : 
    1049           0 :         srcoff = srcrow * ncols + 0;
    1050           0 :         dstoff = dstrow * ncols + 0;
    1051             : 
    1052           0 :         s = spltty();
    1053           0 :         if (scr->pcs.active) {
    1054           0 :                 if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) {
    1055             : #ifdef PCDISPLAY_SOFTCURSOR
    1056             :                         int cursoron = scr->pcs.cursoron;
    1057             : 
    1058             :                         /* NOTE this assumes pcdisplay_cursor() never fails */
    1059             :                         if (cursoron)
    1060             :                                 pcdisplay_cursor(&scr->pcs, 0,
    1061             :                                     scr->pcs.vc_crow, scr->pcs.vc_ccol);
    1062             : #endif
    1063             :                         /* scroll up whole screen */
    1064           0 :                         if ((scr->pcs.dispoffset + srcrow * ncols * 2)
    1065           0 :                             <= scr->maxdispoffset) {
    1066           0 :                                 scr->pcs.dispoffset += srcrow * ncols * 2;
    1067           0 :                         } else {
    1068           0 :                                 bus_space_copy_2(memt, memh,
    1069             :                                         scr->pcs.dispoffset + srcoff * 2,
    1070             :                                         memh, scr->mindispoffset,
    1071             :                                         nrows * ncols);
    1072           0 :                                 scr->vga_rollover = scr->pcs.dispoffset;
    1073           0 :                                 scr->pcs.dispoffset = scr->mindispoffset;
    1074             :                         }
    1075           0 :                         scr->pcs.visibleoffset = scr->pcs.dispoffset;
    1076           0 :                         vga_6845_write(&scr->cfg->hdl, startadrh,
    1077             :                                        scr->pcs.dispoffset >> 9);
    1078           0 :                         vga_6845_write(&scr->cfg->hdl, startadrl,
    1079             :                                        scr->pcs.dispoffset >> 1);
    1080             : #ifdef PCDISPLAY_SOFTCURSOR
    1081             :                         /* NOTE this assumes pcdisplay_cursor() never fails */
    1082             :                         if (cursoron)
    1083             :                                 pcdisplay_cursor(&scr->pcs, 1,
    1084             :                                     scr->pcs.vc_crow, scr->pcs.vc_ccol);
    1085             : #endif
    1086           0 :                 } else {
    1087           0 :                         bus_space_copy_2(memt, memh,
    1088             :                                         scr->pcs.dispoffset + srcoff * 2,
    1089             :                                         memh, scr->pcs.dispoffset + dstoff * 2,
    1090             :                                         nrows * ncols);
    1091             :                 }
    1092             :         } else
    1093           0 :                 bcopy(&scr->pcs.mem[srcoff], &scr->pcs.mem[dstoff],
    1094           0 :                       nrows * ncols * 2);
    1095           0 :         splx(s);
    1096             : 
    1097           0 :         return 0;
    1098             : }
    1099             : 
    1100             : int _vga_mapchar(void *, struct vgafont *, int, unsigned int *);
    1101             : 
    1102             : int
    1103           0 : _vga_mapchar(void *id, struct vgafont *font, int uni, unsigned int *index)
    1104             : {
    1105             : 
    1106           0 :         switch (font->encoding) {
    1107             :         case WSDISPLAY_FONTENC_ISO:
    1108           0 :                 if (uni < 256) {
    1109           0 :                         *index = uni;
    1110           0 :                         return (5);
    1111             :                 } else {
    1112           0 :                         *index = '?';
    1113           0 :                         return (0);
    1114             :                 }
    1115             :                 break;
    1116             :         case WSDISPLAY_FONTENC_IBM:
    1117           0 :                 return (pcdisplay_mapchar(id, uni, index));
    1118             :         default:
    1119             : #ifdef VGAFONTDEBUG
    1120             :                 printf("_vga_mapchar: encoding=%d\n", font->encoding);
    1121             : #endif
    1122           0 :                 *index = '?';
    1123           0 :                 return (0);
    1124             :         }
    1125           0 : }
    1126             : 
    1127             : int
    1128           0 : vga_mapchar(void *id, int uni, unsigned int *index)
    1129             : {
    1130           0 :         struct vgascreen *scr = id;
    1131           0 :         unsigned int idx1, idx2;
    1132             :         int res1, res2;
    1133             : 
    1134             :         res1 = 0;
    1135           0 :         idx1 = ' '; /* space */
    1136           0 :         if (scr->fontset1)
    1137           0 :                 res1 = _vga_mapchar(id, scr->fontset1, uni, &idx1);
    1138             :         res2 = -1;
    1139           0 :         if (scr->fontset2) {
    1140           0 :                 KASSERT(VGA_SCREEN_CANTWOFONTS(scr->pcs.type));
    1141           0 :                 res2 = _vga_mapchar(id, scr->fontset2, uni, &idx2);
    1142           0 :         }
    1143           0 :         if (res2 >= res1) {
    1144           0 :                 *index = idx2 | 0x0800; /* attribute bit 3 */
    1145           0 :                 return (res2);
    1146             :         }
    1147           0 :         *index = idx1;
    1148           0 :         return (res1);
    1149           0 : }
    1150             : 
    1151             : int
    1152           0 : vga_putchar(void *c, int row, int col, u_int uc, long attr)
    1153             : {
    1154           0 :         struct vgascreen *scr = c;
    1155             :         int rc;
    1156             :         int s;
    1157             :         
    1158           0 :         s = spltty();
    1159           0 :         if (scr->pcs.active && scr->pcs.visibleoffset != scr->pcs.dispoffset)
    1160           0 :                 vga_scrollback(scr->cfg, scr, 0);
    1161           0 :         rc = pcdisplay_putchar(c, row, col, uc, attr);
    1162           0 :         splx(s);
    1163             : 
    1164           0 :         return rc;
    1165             : }
    1166             : 
    1167             : void
    1168           0 : vga_burner(void *v, u_int on, u_int flags)
    1169             : {
    1170           0 :         struct vga_config *vc = v;
    1171           0 :         struct vga_handle *vh = &vc->hdl;
    1172             :         u_int8_t r;
    1173             :         int s;
    1174             : 
    1175           0 :         s = splhigh();
    1176           0 :         vga_ts_write(vh, syncreset, 0x01);
    1177           0 :         if (on) {
    1178           0 :                 vga_ts_write(vh, mode, (vga_ts_read(vh, mode) & ~0x20));
    1179           0 :                 r = vga_6845_read(vh, mode) | 0x80;
    1180           0 :                 DELAY(10000);
    1181           0 :                 vga_6845_write(vh, mode, r);
    1182           0 :         } else {
    1183           0 :                 vga_ts_write(vh, mode, (vga_ts_read(vh, mode) | 0x20));
    1184           0 :                 if (flags & WSDISPLAY_BURN_VBLANK) {
    1185           0 :                         r = vga_6845_read(vh, mode) & ~0x80;
    1186           0 :                         DELAY(10000);
    1187           0 :                         vga_6845_write(vh, mode, r);
    1188           0 :                 }
    1189             :         }
    1190           0 :         vga_ts_write(vh, syncreset, 0x03);
    1191           0 :         splx(s);
    1192           0 : }
    1193             : 
    1194             : int
    1195           0 : vga_getchar(void *c, int row, int col, struct wsdisplay_charcell *cell)
    1196             : {
    1197           0 :         struct vga_config *vc = c;
    1198             :         
    1199           0 :         return (pcdisplay_getchar(vc->active, row, col, cell));
    1200             : }       
    1201             : 
    1202             : void
    1203           0 : vga_save_palette(struct vga_config *vc)
    1204             : {
    1205           0 :         struct vga_handle *vh = &vc->hdl;
    1206             :         uint i;
    1207           0 :         uint8_t *palette = vc->vc_palette;
    1208             : 
    1209           0 :         if (vh->vh_mono)
    1210           0 :                 return;
    1211             : 
    1212           0 :         vga_raw_write(vh, VGA_DAC_MASK, 0xff);
    1213           0 :         vga_raw_write(vh, VGA_DAC_READ, 0x00);
    1214           0 :         for (i = 0; i < 3 * 256; i++)
    1215           0 :                 *palette++ = vga_raw_read(vh, VGA_DAC_DATA);
    1216             : 
    1217           0 :         vga_raw_read(vh, 0x0a);                 /* reset flip/flop */
    1218           0 : }
    1219             : 
    1220             : void
    1221           0 : vga_restore_palette(struct vga_config *vc)
    1222             : {
    1223           0 :         struct vga_handle *vh = &vc->hdl;
    1224             :         uint i;
    1225           0 :         uint8_t *palette = vc->vc_palette;
    1226             : 
    1227           0 :         if (vh->vh_mono)
    1228           0 :                 return;
    1229             : 
    1230           0 :         vga_raw_write(vh, VGA_DAC_MASK, 0xff);
    1231           0 :         vga_raw_write(vh, VGA_DAC_WRITE, 0x00);
    1232           0 :         for (i = 0; i < 3 * 256; i++)
    1233           0 :                 vga_raw_write(vh, VGA_DAC_DATA, *palette++);
    1234             : 
    1235           0 :         vga_raw_read(vh, 0x0a);                 /* reset flip/flop */
    1236             : 
    1237           0 :         vga_enable(vh);
    1238           0 : }
    1239             : 
    1240             : void
    1241           0 : vga_restore_fonts(struct vga_config *vc)
    1242             : {
    1243             :         int slot;
    1244             :         struct vgafont *f;
    1245             : 
    1246           0 :         for (slot = 0; slot < VGA_MAXFONT; slot++) {
    1247           0 :                 f = vc->vc_fonts[slot];
    1248           0 :                 if (f == NULL || f->fontdata == NULL)
    1249             :                         continue;
    1250             : 
    1251           0 :                 vga_loadchars(&vc->hdl, slot, 0, 256, f->height, f->fontdata);
    1252           0 :         }
    1253           0 : }
    1254             : 
    1255             : #ifdef __alpha__
    1256             : void
    1257             : vga_pick_monitor_type(struct vga_config *vc)
    1258             : {
    1259             :         struct vga_handle *vh = &vc->hdl;
    1260             : 
    1261             :         /*
    1262             :          * The Tadpole Alphabook1 uses a 800x600 flat panel in text mode,
    1263             :          * causing the display console to really be 100x37 instead of the
    1264             :          * usual 80x25.
    1265             :          * We attempt to detect this here by checking the CRTC registers.
    1266             :          */
    1267             :         unsigned int hend, oflow, vend;
    1268             :         unsigned int width, height;
    1269             : 
    1270             :         hend = vga_6845_read(vh, hdisple);
    1271             :         oflow = vga_6845_read(vh, overfll);
    1272             :         vend = vga_6845_read(vh, vde);
    1273             :         if (oflow & 0x02)
    1274             :                 vend |= 0x100;
    1275             :         if (oflow & 0x40)
    1276             :                 vend |= 0x200;
    1277             : 
    1278             :         width = hend + 1;
    1279             :         height = (vend + 1) / 16;
    1280             : 
    1281             :         /* check that the values sound plausible */
    1282             :         if ((width > 80 && width <= 128) && (height > 25 && height <= 50)) {
    1283             :                 snprintf(vc->custom_scr.name, sizeof(vc->custom_scr.name),
    1284             :                     "%ux%u", width, height);
    1285             :                 vc->custom_scr.ncols = width;
    1286             :                 vc->custom_scr.nrows = height;
    1287             :                 vc->custom_scr.textops = &vga_emulops;
    1288             :                 vc->custom_scr.fontwidth = 8;
    1289             :                 vc->custom_scr.fontheight = 16;
    1290             :                 vc->custom_scr.capabilities =
    1291             :                     WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK;
    1292             :                 vc->custom_scrlist[0] = &vc->custom_scr;
    1293             :                 vc->custom_list.nscreens = 1;
    1294             :                 vc->custom_list.screens =
    1295             :                     (const struct wsscreen_descr **)vc->custom_scrlist;
    1296             :         }
    1297             : }
    1298             : #endif
    1299             : 
    1300             : struct cfdriver vga_cd = {
    1301             :         NULL, "vga", DV_DULL
    1302             : };

Generated by: LCOV version 1.13