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/dev/ic/vga_subr.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 /* $NetBSD: vga_subr.c,v 1.23 2007/12/09 20:28:00 jmcneill Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1998
    5  *      Matthias Drochner.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __KERNEL_RCSID(0, "$NetBSD: vga_subr.c,v 1.23 2007/12/09 20:28:00 jmcneill Exp $");
   31 
   32 /* for WSDISPLAY_BORDER_COLOR */
   33 #include "opt_wsdisplay_border.h"
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/device.h>
   38 #include <sys/queue.h>
   39 #include <sys/bus.h>
   40 
   41 #include <dev/ic/mc6845reg.h>
   42 #include <dev/ic/pcdisplay.h>
   43 #include <dev/ic/pcdisplayvar.h>
   44 #include <dev/ic/vgareg.h>
   45 #include <dev/ic/vgavar.h>
   46 
   47 #include <dev/wscons/wsdisplayvar.h>
   48 
   49 static void fontram(struct vga_handle *);
   50 static void textram(struct vga_handle *);
   51 
   52 static void
   53 fontram(struct vga_handle *vh)
   54 {
   55 
   56         /* program sequencer to access character generator */
   57 
   58         vga_ts_write(vh, syncreset, 0x01);      /* synchronous reset */
   59         vga_ts_write(vh, wrplmask, 0x04);       /* write to map 2 */
   60         vga_ts_write(vh, memmode, 0x07);        /* sequential addressing */
   61         vga_ts_write(vh, syncreset, 0x03);      /* clear synchronous reset */
   62 
   63         /* program graphics controller to access character generator */
   64 
   65         vga_gdc_write(vh, rdplanesel, 0x02);    /* select map 2 for CPU reads */
   66         vga_gdc_write(vh, mode, 0x00);  /* disable odd-even addressing */
   67         vga_gdc_write(vh, misc, 0x04);  /* map starts at 0xA000 */
   68 }
   69 
   70 static void
   71 textram(struct vga_handle *vh)
   72 {
   73 
   74         /* program sequencer to access video ram */
   75 
   76         vga_ts_write(vh, syncreset, 0x01);      /* synchronous reset */
   77         vga_ts_write(vh, wrplmask, 0x03);       /* write to map 0 & 1 */
   78         vga_ts_write(vh, memmode, 0x03);        /* odd-even addressing */
   79         vga_ts_write(vh, syncreset, 0x03);      /* clear synchronous reset */
   80 
   81         /* program graphics controller for text mode */
   82 
   83         vga_gdc_write(vh, rdplanesel, 0x00);    /* select map 0 for CPU reads */
   84         vga_gdc_write(vh, mode, 0x10);          /* enable odd-even addressing */
   85         /* map starts at 0xb800 or 0xb000 (mono) */
   86         vga_gdc_write(vh, misc, (vh->vh_mono ? 0x0a : 0x0e));
   87 }
   88 
   89 #ifndef VGA_RASTERCONSOLE
   90 void
   91 vga_loadchars(struct vga_handle *vh, int fontset, int first, int num, int lpc,
   92               const char *data)
   93 {
   94         int offset, i, j, s;
   95 
   96         /* fontset number swizzle done in vga_setfontset() */
   97         offset = (fontset << 13) | (first << 5);
   98 
   99         s = splhigh();
  100         fontram(vh);
  101 
  102         for (i = 0; i < num; i++)
  103                 for (j = 0; j < lpc; j++)
  104                         bus_space_write_1(vh->vh_memt, vh->vh_allmemh,
  105                             offset + (i << 5) + j, data[i * lpc + j]);
  106 
  107         textram(vh);
  108         splx(s);
  109 }
  110 
  111 void
  112 vga_readoutchars(struct vga_handle *vh, int fontset, int first, int num,
  113                  int lpc, char *data)
  114 {
  115         int offset, i, j, s;
  116 
  117         /* fontset number swizzle done in vga_setfontset() */
  118         offset = (fontset << 13) | (first << 5);
  119 
  120         s = splhigh();
  121         fontram(vh);
  122 
  123         for (i = 0; i < num; i++)
  124                 for (j = 0; j < lpc; j++)
  125                         data[i * lpc + j] = bus_space_read_1(vh->vh_memt,
  126                             vh->vh_allmemh, offset + (i << 5) + j);
  127 
  128         textram(vh);
  129         splx(s);
  130 }
  131 
  132 #ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
  133 void
  134 vga_copyfont01(struct vga_handle *vh)
  135 {
  136         int s;
  137 
  138         s = splhigh();
  139         fontram(vh);
  140 
  141         bus_space_copy_region_1(vh->vh_memt, vh->vh_allmemh, 0,
  142             vh->vh_allmemh, 1 << 13, 1 << 13);
  143 
  144         textram(vh);
  145         splx(s);
  146 }
  147 #endif
  148 
  149 void
  150 vga_setfontset(struct vga_handle *vh, int fontset1, int fontset2)
  151 {
  152         u_int8_t cmap;
  153         static const u_int8_t cmaptaba[] = {
  154                 0x00, 0x10, 0x01, 0x11,
  155                 0x02, 0x12, 0x03, 0x13
  156         };
  157         static const u_int8_t cmaptabb[] = {
  158                 0x00, 0x20, 0x04, 0x24,
  159                 0x08, 0x28, 0x0c, 0x2c
  160         };
  161 
  162         /* extended font if fontset1 != fontset2 */
  163         cmap = cmaptaba[fontset1] | cmaptabb[fontset2];
  164 
  165         vga_ts_write(vh, fontsel, cmap);
  166 }
  167 
  168 void
  169 vga_setscreentype(struct vga_handle *vh, const struct wsscreen_descr *type)
  170 {
  171 
  172         vga_6845_write(vh, maxrow, type->fontheight - 1);
  173 
  174         /* lo byte */
  175         vga_6845_write(vh, vde, type->fontheight * type->nrows - 1);
  176 
  177 #ifndef PCDISPLAY_SOFTCURSOR
  178         /* set cursor to last 2 lines */
  179         vga_6845_write(vh, curstart, type->fontheight - 2);
  180         vga_6845_write(vh, curend, type->fontheight - 1);
  181 #endif
  182         /*
  183          * disable colour plane 3 if needed for font selection
  184          */
  185         if (type->capabilities & WSSCREEN_HILIT) {
  186                 /*
  187                  * these are the screens which don't support
  188                  * 512-character fonts
  189                  */
  190                 vga_attr_write(vh, colplen, 0x0f);
  191         } else
  192                 vga_attr_write(vh, colplen, 0x07);
  193 }
  194 
  195 #else /* !VGA_RASTERCONSOLE */
  196 void
  197 vga_load_builtinfont(struct vga_handle *vh, u_int8_t *font, int firstchar,
  198         int numchars)
  199 {
  200         int i, s;
  201 
  202         s = splhigh();
  203         fontram(vh);
  204 
  205         for (i = firstchar; i < firstchar + numchars; i++)
  206                 bus_space_read_region_1(vh->vh_memt, vh->vh_allmemh, i * 32,
  207                     font + i * 16, 16);
  208 
  209         textram(vh);
  210         splx(s);
  211 }
  212 #endif /* !VGA_RASTERCONSOLE */
  213 
  214 /*
  215  * vga_reset():
  216  *      Reset VGA registers to put it into 80x25 text mode. (mode 3)
  217  *      This function should be called from MD consinit() on ports
  218  *      whose firmware does not use text mode at boot time.
  219  */
  220 void
  221 vga_reset(vh, md_initfunc)
  222         struct vga_handle *vh;
  223         void (*md_initfunc)(struct vga_handle *);
  224 {
  225         u_int8_t reg;
  226 
  227         if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
  228                 return;
  229 
  230         reg = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_MISC_DATAR);
  231         vh->vh_mono = !(reg & 0x01);
  232 
  233         if (bus_space_map(vh->vh_iot, vh->vh_mono ? 0x3b0 : 0x3d0, 0x10,
  234             0, &vh->vh_ioh_6845))
  235                 goto out1;
  236 
  237         if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
  238                 goto out2;
  239 
  240         if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
  241             vh->vh_mono ? 0x10000 : 0x18000, 0x8000, &vh->vh_memh))
  242                 goto out3;
  243 
  244         /* check if VGA already in text mode. */
  245         if ((vga_gdc_read(vh, misc) & 0x01) == 0)
  246                 goto out3;
  247 
  248         /* initialize common VGA registers */
  249         vga_initregs(vh);
  250 
  251         /* initialize chipset specific registers */
  252         if (md_initfunc != NULL)
  253                 (*md_initfunc)(vh);
  254 
  255         delay(10000);
  256 
  257         /* clear text buffer RAM */
  258         bus_space_set_region_2(vh->vh_memt, vh->vh_memh, 0,
  259             ((BG_BLACK | FG_LIGHTGREY) << 8) | ' ', 80 * 25 /*XXX*/);
  260 
  261  out3:
  262         bus_space_unmap(vh->vh_memt, vh->vh_allmemh, 0x20000);
  263  out2:
  264         bus_space_unmap(vh->vh_iot, vh->vh_ioh_6845, 0x10);
  265  out1:
  266         bus_space_unmap(vh->vh_iot, vh->vh_ioh_vga, 0x10);
  267 }
  268 
  269 /*
  270  * values to initialize registers.
  271  */
  272 
  273 /* miscellaneous output register */
  274 #define VGA_MISCOUT     0x66
  275 
  276 /* sequencer registers */
  277 static const u_int8_t vga_ts[] = {
  278         0x03,   /* 00: reset */
  279         0x00,   /* 01: clocking mode */
  280         0x03,   /* 02: map mask */
  281         0x00,   /* 03: character map select */
  282         0x02    /* 04: memory mode */
  283 };
  284 
  285 /* CRT controller registers */
  286 static const u_int8_t vga_crtc[] = {
  287         0x5f,   /* 00: horizontal total */
  288         0x4f,   /* 01: horizontal display-enable end */
  289         0x50,   /* 02: start horizontal blanking */
  290         0x82,   /* 03: display skew control / end horizontal blanking */
  291         0x55,   /* 04: start horizontal retrace pulse */
  292         0x81,   /* 05: horizontal retrace delay / end horizontal retrace */
  293         0xbf,   /* 06: vertical total */
  294         0x1f,   /* 07: overflow register */
  295         0x00,   /* 08: preset row scan */
  296         0x4f,   /* 09: overflow / maximum scan line */
  297         0x0d,   /* 0A: cursor off / cursor start */
  298         0x0e,   /* 0B: cursor skew / cursor end */
  299         0x00,   /* 0C: start regenerative buffer address high */
  300         0x00,   /* 0D: start regenerative buffer address low */
  301         0x00,   /* 0E: cursor location high */
  302         0x00,   /* 0F: cursor location low */
  303         0x9c,   /* 10: vertical retrace start */
  304         0x8e,   /* 11: vertical interrupt / vertical retrace end */
  305         0x8f,   /* 12: vertical display enable end */
  306         0x28,   /* 13: logical line width */
  307         0x00,   /* 14: underline location */
  308         0x96,   /* 15: start vertical blanking */
  309         0xb9,   /* 16: end vertical blanking */
  310         0xa3,   /* 17: CRT mode control */
  311         0xff    /* 18: line compare */
  312 };
  313 
  314 /* graphics controller registers */
  315 static const u_int8_t vga_gdc[] = {
  316         0x00,   /* 00: set/reset map */
  317         0x00,   /* 01: enable set/reset */
  318         0x00,   /* 02: color compare */
  319         0x00,   /* 03: data rotate */
  320         0x00,   /* 04: read map select */
  321         0x10,   /* 05: graphics mode */
  322         0x0e,   /* 06: miscellaneous */
  323         0x00,   /* 07: color don't care */
  324         0xff    /* 08: bit mask */
  325 };
  326 
  327 /* attribute controller registers */
  328 static const u_int8_t vga_atc[] = {
  329         0x00,   /* 00: internal palette  0 */
  330         0x01,   /* 01: internal palette  1 */
  331         0x02,   /* 02: internal palette  2 */
  332         0x03,   /* 03: internal palette  3 */
  333         0x04,   /* 04: internal palette  4 */
  334         0x05,   /* 05: internal palette  5 */
  335         0x14,   /* 06: internal palette  6 */
  336         0x07,   /* 07: internal palette  7 */
  337         0x38,   /* 08: internal palette  8 */
  338         0x39,   /* 09: internal palette  9 */
  339         0x3a,   /* 0A: internal palette 10 */
  340         0x3b,   /* 0B: internal palette 11 */
  341         0x3c,   /* 0C: internal palette 12 */
  342         0x3d,   /* 0D: internal palette 13 */
  343         0x3e,   /* 0E: internal palette 14 */
  344         0x3f,   /* 0F: internal palette 15 */
  345         0x0c,   /* 10: attribute mode control */
  346         WSDISPLAY_BORDER_COLOR, /* 11: overscan color */
  347         0x0f,   /* 12: color plane enable */
  348         0x08,   /* 13: horizontal PEL panning */
  349         0x00    /* 14: color select */
  350 };
  351 
  352 /* video DAC palette registers */
  353 /* XXX only set up 16 colors used by internal palette in ATC regsters */
  354 static const u_int8_t vga_dacpal[] = {
  355         /* R     G     B */
  356         0x00, 0x00, 0x00,       /* BLACK        */
  357         0x00, 0x00, 0x2a,       /* BLUE         */
  358         0x00, 0x2a, 0x00,       /* GREEN        */
  359         0x00, 0x2a, 0x2a,       /* CYAN         */
  360         0x2a, 0x00, 0x00,       /* RED          */
  361         0x2a, 0x00, 0x2a,       /* MAGENTA      */
  362         0x2a, 0x15, 0x00,       /* BROWN        */
  363         0x2a, 0x2a, 0x2a,       /* LIGHTGREY    */
  364         0x15, 0x15, 0x15,       /* DARKGREY     */
  365         0x15, 0x15, 0x3f,       /* LIGHTBLUE    */
  366         0x15, 0x3f, 0x15,       /* LIGHTGREEN   */
  367         0x15, 0x3f, 0x3f,       /* LIGHTCYAN    */
  368         0x3f, 0x15, 0x15,       /* LIGHTRED     */
  369         0x3f, 0x15, 0x3f,       /* LIGHTMAGENTA */
  370         0x3f, 0x3f, 0x15,       /* YELLOW       */
  371         0x3f, 0x3f, 0x3f        /* WHITE        */
  372 };
  373 
  374 void
  375 vga_initregs(vh)
  376         struct vga_handle *vh;
  377 {
  378         int i;
  379 
  380         /* disable video */
  381         vga_ts_write(vh, mode, vga_ts[1] | VGA_TS_MODE_BLANK);
  382 
  383         /* synchronous reset */
  384         vga_ts_write(vh, syncreset, 0x01);
  385         /* set TS regsters */
  386         for (i = 2; i < VGA_TS_NREGS; i++)
  387                 _vga_ts_write(vh, i, vga_ts[i]);
  388         /* clear synchronous reset */
  389         vga_ts_write(vh, syncreset, 0x03);
  390 
  391         /* unprotect CRTC regsters */
  392         vga_6845_write(vh, vsynce, vga_6845_read(vh, vsynce) & ~0x80);
  393         /* set CRTC regsters */
  394         for (i = 0; i < MC6845_NREGS; i++)
  395                 _vga_6845_write(vh, i, vga_crtc[i]);
  396 
  397         /* set GDC regsters */
  398         for (i = 0; i < VGA_GDC_NREGS; i++)
  399                 _vga_gdc_write(vh, i, vga_gdc[i]);
  400 
  401         /* set ATC regsters */
  402         for (i = 0; i < VGA_ATC_NREGS; i++)
  403                 _vga_attr_write(vh, i, vga_atc[i]);
  404 
  405         /* set DAC palette */
  406         if (!vh->vh_mono) {
  407                 for (i = 0; i < 16; i++) {
  408                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  409                             VGA_DAC_ADDRW, vga_atc[i]);
  410                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  411                             VGA_DAC_PALETTE, vga_dacpal[i * 3 + 0]);
  412                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  413                             VGA_DAC_PALETTE, vga_dacpal[i * 3 + 1]);
  414                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  415                             VGA_DAC_PALETTE, vga_dacpal[i * 3 + 2]);
  416                 }
  417         }
  418 
  419         /* set misc output register */
  420         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  421             VGA_MISC_DATAW, VGA_MISCOUT | (vh->vh_mono ? 0 : 0x01));
  422 
  423         /* reenable video */
  424         vga_ts_write(vh, mode, vga_ts[1] & ~VGA_TS_MODE_BLANK);
  425 }

Cache object: a0f2bd9b5086227f52ebc25fda85f6a9


[ 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.