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.17 2004/03/24 17:26:53 drochner 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.17 2004/03/24 17:26:53 drochner Exp $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/device.h>
   35 #include <sys/queue.h>
   36 #include <machine/bus.h>
   37 
   38 #include <dev/ic/mc6845reg.h>
   39 #include <dev/ic/pcdisplay.h>
   40 #include <dev/ic/pcdisplayvar.h>
   41 #include <dev/ic/vgareg.h>
   42 #include <dev/ic/vgavar.h>
   43 
   44 #include <dev/wscons/wsdisplayvar.h>
   45 
   46 static void fontram(struct vga_handle *);
   47 static void textram(struct vga_handle *);
   48 #ifdef VGA_RESET
   49 static void vga_initregs(struct vga_handle *);
   50 #endif
   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 #ifdef VGA_RESET
  215 /*
  216  * vga_reset():
  217  *      Reset VGA registers to put it into 80x25 text mode. (mode 3)
  218  *      This function should be called from MD consinit() on ports
  219  *      whose firmware does not use text mode at boot time.
  220  */
  221 void
  222 vga_reset(vh, md_initfunc)
  223         struct vga_handle *vh;
  224         void (*md_initfunc)(struct vga_handle *);
  225 {
  226         u_int8_t reg;
  227 
  228         if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
  229                 return;
  230 
  231         reg = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, VGA_MISC_DATAR);
  232         vh->vh_mono = !(reg & 0x01);
  233 
  234         if (bus_space_map(vh->vh_iot, vh->vh_mono ? 0x3b0 : 0x3d0, 0x10,
  235             0, &vh->vh_ioh_6845))
  236                 goto out1;
  237 
  238         if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
  239                 goto out2;
  240 
  241         if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
  242             vh->vh_mono ? 0x10000 : 0x18000, 0x8000, &vh->vh_memh))
  243                 goto out3;
  244 
  245         /* check if VGA already in text mode. */
  246         if ((vga_gdc_read(vh, misc) & 0x01) == 0)
  247                 goto out3;
  248 
  249         /* initialize common VGA registers */
  250         vga_initregs(vh);
  251 
  252         /* initialize chipset specific registers */
  253         if (md_initfunc != NULL)
  254                 (*md_initfunc)(vh);
  255 
  256         delay(10000);
  257 
  258         /* clear text buffer RAM */
  259         bus_space_set_region_2(vh->vh_memt, vh->vh_memh, 0,
  260             ((BG_BLACK | FG_LIGHTGREY) << 8) | ' ', 80 * 25 /*XXX*/);
  261 
  262  out3:
  263         bus_space_unmap(vh->vh_memt, vh->vh_allmemh, 0x20000);
  264  out2:
  265         bus_space_unmap(vh->vh_iot, vh->vh_ioh_6845, 0x10);
  266  out1:
  267         bus_space_unmap(vh->vh_iot, vh->vh_ioh_vga, 0x10);
  268 }
  269 
  270 /*
  271  * values to initialize registers.
  272  */
  273 
  274 /* miscellaneous output register */
  275 #define VGA_MISCOUT     0x66
  276 
  277 /* sequencer registers */
  278 static const u_int8_t vga_ts[] = {
  279         0x03,   /* 00: reset */
  280         0x00,   /* 01: clocking mode */
  281         0x03,   /* 02: map mask */
  282         0x00,   /* 03: character map select */
  283         0x02    /* 04: memory mode */
  284 };
  285 
  286 /* CRT controller registers */
  287 static const u_int8_t vga_crtc[] = {
  288         0x5f,   /* 00: horizontal total */
  289         0x4f,   /* 01: horizontal display-enable end */
  290         0x50,   /* 02: start horizontal blanking */
  291         0x82,   /* 03: display skew control / end horizontal blanking */
  292         0x55,   /* 04: start horizontal retrace pulse */
  293         0x81,   /* 05: horizontal retrace delay / end horizontal retrace */
  294         0xbf,   /* 06: vetical total */
  295         0x1f,   /* 07: overflow register */
  296         0x00,   /* 08: preset row scan */
  297         0x4f,   /* 09: overflow / maximum scan line */
  298         0x0d,   /* 0A: cursor off / cursor start */
  299         0x0e,   /* 0B: cursor skew / cursor end */
  300         0x00,   /* 0C: start regenerative buffer address high */
  301         0x00,   /* 0D: start regenerative buffer address low */
  302         0x00,   /* 0E: cursor location high */
  303         0x00,   /* 0F: cursor location low */
  304         0x9c,   /* 10: vertical retrace start */
  305         0x8e,   /* 11: vertical interrupt / vertical retrace end */
  306         0x8f,   /* 12: vertical display enable end */
  307         0x28,   /* 13: logical line width */
  308         0x00,   /* 14: underline location */
  309         0x96,   /* 15: start vertical blanking */
  310         0xb9,   /* 16: end vertical blanking */
  311         0xa3,   /* 17: CRT mode control */
  312         0xff    /* 18: line compare */
  313 };
  314 
  315 /* graphics controller registers */
  316 static const u_int8_t vga_gdc[] = {
  317         0x00,   /* 00: set/reset map */
  318         0x00,   /* 01: enable set/reset */
  319         0x00,   /* 02: color compare */
  320         0x00,   /* 03: data rotate */
  321         0x00,   /* 04: read map select */
  322         0x10,   /* 05: graphics mode */
  323         0x0e,   /* 06: miscellaneous */
  324         0x00,   /* 07: color don't care */
  325         0xff    /* 08: bit mask */
  326 };
  327 
  328 /* attribute controller registers */
  329 static const u_int8_t vga_atc[] = {
  330         0x00,   /* 00: internal palette  0 */
  331         0x01,   /* 01: internal palette  1 */
  332         0x02,   /* 02: internal palette  2 */
  333         0x03,   /* 03: internal palette  3 */
  334         0x04,   /* 04: internal palette  4 */
  335         0x05,   /* 05: internal palette  5 */
  336         0x14,   /* 06: internal palette  6 */
  337         0x07,   /* 07: internal palette  7 */
  338         0x38,   /* 08: internal palette  8 */
  339         0x39,   /* 09: internal palette  9 */
  340         0x3a,   /* 0A: internal palette 10 */
  341         0x3b,   /* 0B: internal palette 11 */
  342         0x3c,   /* 0C: internal palette 12 */
  343         0x3d,   /* 0D: internal palette 13 */
  344         0x3e,   /* 0E: internal palette 14 */
  345         0x3f,   /* 0F: internal palette 15 */
  346         0x0c,   /* 10: attribute mode control */
  347         0x00,   /* 11: overscan color */
  348         0x0f,   /* 12: color plane enable */
  349         0x08,   /* 13: horizontal PEL panning */
  350         0x00    /* 14: color select */
  351 };
  352 
  353 /* video DAC palette registers */
  354 /* XXX only set up 16 colors used by internal palette in ATC regsters */
  355 static const u_int8_t vga_dacpal[] = {
  356         /* R     G     B */
  357         0x00, 0x00, 0x00,       /* BLACK        */
  358         0x00, 0x00, 0x2a,       /* BLUE         */
  359         0x00, 0x2a, 0x00,       /* GREEN        */
  360         0x00, 0x2a, 0x2a,       /* CYAN         */
  361         0x2a, 0x00, 0x00,       /* RED          */
  362         0x2a, 0x00, 0x2a,       /* MAGENTA      */
  363         0x2a, 0x15, 0x00,       /* BROWN        */
  364         0x2a, 0x2a, 0x2a,       /* LIGHTGREY    */
  365         0x15, 0x15, 0x15,       /* DARKGREY     */
  366         0x15, 0x15, 0x3f,       /* LIGHTBLUE    */
  367         0x15, 0x3f, 0x15,       /* LIGHTGREEN   */
  368         0x15, 0x3f, 0x3f,       /* LIGHTCYAN    */
  369         0x3f, 0x15, 0x15,       /* LIGHTRED     */
  370         0x3f, 0x15, 0x3f,       /* LIGHTMAGENTA */
  371         0x3f, 0x3f, 0x15,       /* YELLOW       */
  372         0x3f, 0x3f, 0x3f        /* WHITE        */
  373 };
  374 
  375 static void
  376 vga_initregs(vh)
  377         struct vga_handle *vh;
  378 {
  379         int i;
  380 
  381         /* disable video */
  382         vga_ts_write(vh, mode, vga_ts[1] | VGA_TS_MODE_BLANK);
  383 
  384         /* synchronous reset */
  385         vga_ts_write(vh, syncreset, 0x01);
  386         /* set TS regsters */
  387         for (i = 2; i < VGA_TS_NREGS; i++)
  388                 _vga_ts_write(vh, i, vga_ts[i]);
  389         /* clear synchronous reset */
  390         vga_ts_write(vh, syncreset, 0x03);
  391 
  392         /* unprotect CRTC regsters */
  393         vga_6845_write(vh, vsynce, vga_6845_read(vh, vsynce) & ~0x80);
  394         /* set CRTC regsters */
  395         for (i = 0; i < MC6845_NREGS; i++)
  396                 _vga_6845_write(vh, i, vga_crtc[i]);
  397 
  398         /* set GDC regsters */
  399         for (i = 0; i < VGA_GDC_NREGS; i++)
  400                 _vga_gdc_write(vh, i, vga_gdc[i]);
  401 
  402         /* set ATC regsters */
  403         for (i = 0; i < VGA_ATC_NREGS; i++)
  404                 _vga_attr_write(vh, i, vga_atc[i]);
  405 
  406         /* set DAC palette */
  407         if (!vh->vh_mono) {
  408                 for (i = 0; i < 16; i++) {
  409                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  410                             VGA_DAC_ADDRW, vga_atc[i]);
  411                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  412                             VGA_DAC_PALETTE, vga_dacpal[i * 3 + 0]);
  413                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  414                             VGA_DAC_PALETTE, vga_dacpal[i * 3 + 1]);
  415                         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  416                             VGA_DAC_PALETTE, vga_dacpal[i * 3 + 2]);
  417                 }
  418         }
  419 
  420         /* set misc output register */
  421         bus_space_write_1(vh->vh_iot, vh->vh_ioh_vga,
  422             VGA_MISC_DATAW, VGA_MISCOUT | (vh->vh_mono ? 0 : 0x01));
  423 
  424         /* reenable video */
  425         vga_ts_write(vh, mode, vga_ts[1] & ~VGA_TS_MODE_BLANK);
  426 }
  427 #endif /* VGA_RESET */

Cache object: 7305373d1e179cb26c34114d58a9e75f


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