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

Cache object: 3545c3197b613a7e8363ba7fbf1ac938


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