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/syscons/scvgarndr.c

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

    1 /*-
    2  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
    3  * All rights reserved.
    4  *
    5  * This code is derived from software contributed to The DragonFly Project
    6  * by Sascha Wildner <saw@online.de>
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer as
   13  *    the first lines of this file unmodified.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  *
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/9.0/sys/dev/syscons/scvgarndr.c 212806 2010-09-17 23:09:31Z jkim $");
   33 
   34 #include "opt_syscons.h"
   35 #include "opt_vga.h"
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/module.h>
   41 #include <sys/fbio.h>
   42 #include <sys/consio.h>
   43 
   44 #include <machine/bus.h>
   45 
   46 #include <dev/fb/fbreg.h>
   47 #include <dev/fb/vgareg.h>
   48 #include <dev/syscons/syscons.h>
   49 
   50 #include <isa/isareg.h>
   51 
   52 #ifndef SC_RENDER_DEBUG
   53 #define SC_RENDER_DEBUG         0
   54 #endif
   55 
   56 static vr_clear_t               vga_txtclear;
   57 static vr_draw_border_t         vga_txtborder;
   58 static vr_draw_t                vga_txtdraw;
   59 static vr_set_cursor_t          vga_txtcursor_shape;
   60 static vr_draw_cursor_t         vga_txtcursor;
   61 static vr_blink_cursor_t        vga_txtblink;
   62 #ifndef SC_NO_CUTPASTE
   63 static vr_draw_mouse_t          vga_txtmouse;
   64 #else
   65 #define vga_txtmouse            (vr_draw_mouse_t *)vga_nop
   66 #endif
   67 
   68 #ifdef SC_PIXEL_MODE
   69 static vr_init_t                vga_rndrinit;
   70 static vr_clear_t               vga_pxlclear_direct;
   71 static vr_clear_t               vga_pxlclear_planar;
   72 static vr_draw_border_t         vga_pxlborder_direct;
   73 static vr_draw_border_t         vga_pxlborder_planar;
   74 static vr_draw_t                vga_egadraw;
   75 static vr_draw_t                vga_vgadraw_direct;
   76 static vr_draw_t                vga_vgadraw_planar;
   77 static vr_set_cursor_t          vga_pxlcursor_shape;
   78 static vr_draw_cursor_t         vga_pxlcursor_direct;
   79 static vr_draw_cursor_t         vga_pxlcursor_planar;
   80 static vr_blink_cursor_t        vga_pxlblink_direct;
   81 static vr_blink_cursor_t        vga_pxlblink_planar;
   82 #ifndef SC_NO_CUTPASTE
   83 static vr_draw_mouse_t          vga_pxlmouse_direct;
   84 static vr_draw_mouse_t          vga_pxlmouse_planar;
   85 #else
   86 #define vga_pxlmouse_direct     (vr_draw_mouse_t *)vga_nop
   87 #define vga_pxlmouse_planar     (vr_draw_mouse_t *)vga_nop
   88 #endif
   89 #endif /* SC_PIXEL_MODE */
   90 
   91 #ifndef SC_NO_MODE_CHANGE
   92 static vr_draw_border_t         vga_grborder;
   93 #endif
   94 
   95 static void                     vga_nop(scr_stat *scp);
   96 
   97 static sc_rndr_sw_t txtrndrsw = {
   98         (vr_init_t *)vga_nop,
   99         vga_txtclear,
  100         vga_txtborder,
  101         vga_txtdraw,    
  102         vga_txtcursor_shape,
  103         vga_txtcursor,
  104         vga_txtblink,
  105         (vr_set_mouse_t *)vga_nop,
  106         vga_txtmouse,
  107 };
  108 RENDERER(mda, 0, txtrndrsw, vga_set);
  109 RENDERER(cga, 0, txtrndrsw, vga_set);
  110 RENDERER(ega, 0, txtrndrsw, vga_set);
  111 RENDERER(vga, 0, txtrndrsw, vga_set);
  112 
  113 #ifdef SC_PIXEL_MODE
  114 static sc_rndr_sw_t egarndrsw = {
  115         (vr_init_t *)vga_nop,
  116         vga_pxlclear_planar,
  117         vga_pxlborder_planar,
  118         vga_egadraw,
  119         vga_pxlcursor_shape,
  120         vga_pxlcursor_planar,
  121         vga_pxlblink_planar,
  122         (vr_set_mouse_t *)vga_nop,
  123         vga_pxlmouse_planar,
  124 };
  125 RENDERER(ega, PIXEL_MODE, egarndrsw, vga_set);
  126 
  127 static sc_rndr_sw_t vgarndrsw = {
  128         vga_rndrinit,
  129         (vr_clear_t *)vga_nop,
  130         (vr_draw_border_t *)vga_nop,
  131         (vr_draw_t *)vga_nop,
  132         vga_pxlcursor_shape,
  133         (vr_draw_cursor_t *)vga_nop,
  134         (vr_blink_cursor_t *)vga_nop,
  135         (vr_set_mouse_t *)vga_nop,
  136         (vr_draw_mouse_t *)vga_nop,
  137 };
  138 RENDERER(vga, PIXEL_MODE, vgarndrsw, vga_set);
  139 #endif /* SC_PIXEL_MODE */
  140 
  141 #ifndef SC_NO_MODE_CHANGE
  142 static sc_rndr_sw_t grrndrsw = {
  143         (vr_init_t *)vga_nop,
  144         (vr_clear_t *)vga_nop,
  145         vga_grborder,
  146         (vr_draw_t *)vga_nop,
  147         (vr_set_cursor_t *)vga_nop,
  148         (vr_draw_cursor_t *)vga_nop,
  149         (vr_blink_cursor_t *)vga_nop,
  150         (vr_set_mouse_t *)vga_nop,
  151         (vr_draw_mouse_t *)vga_nop,
  152 };
  153 RENDERER(cga, GRAPHICS_MODE, grrndrsw, vga_set);
  154 RENDERER(ega, GRAPHICS_MODE, grrndrsw, vga_set);
  155 RENDERER(vga, GRAPHICS_MODE, grrndrsw, vga_set);
  156 #endif /* SC_NO_MODE_CHANGE */
  157 
  158 RENDERER_MODULE(vga, vga_set);
  159 
  160 #ifndef SC_NO_CUTPASTE
  161 #if !defined(SC_ALT_MOUSE_IMAGE) || defined(SC_PIXEL_MODE)
  162 static u_short mouse_and_mask[16] = {
  163         0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80,
  164         0xfe00, 0x1e00, 0x1f00, 0x0f00, 0x0f00, 0x0000, 0x0000, 0x0000
  165 };
  166 static u_short mouse_or_mask[16] = {
  167         0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800,
  168         0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000
  169 };
  170 #endif
  171 #endif
  172 
  173 #ifdef SC_PIXEL_MODE
  174 #define GET_PIXEL(scp, pos, x, w)                                       \
  175 ({                                                                      \
  176         (scp)->sc->adp->va_window +                                     \
  177             (x) * (scp)->xoff +                                         \
  178             (scp)->yoff * (scp)->font_size * (w) +                      \
  179             (x) * ((pos) % (scp)->xsize) +                              \
  180             (scp)->font_size * (w) * ((pos) / (scp)->xsize);            \
  181 })
  182 
  183 #define DRAW_PIXEL(scp, pos, color) do {                                \
  184         switch ((scp)->sc->adp->va_info.vi_depth) {                     \
  185         case 32:                                                        \
  186                 writel((pos), vga_palette32[color]);                    \
  187                 break;                                                  \
  188         case 24:                                                        \
  189                 if (((pos) & 1) == 0) {                                 \
  190                         writew((pos), vga_palette32[color]);            \
  191                         writeb((pos) + 2, vga_palette32[color] >> 16);  \
  192                 } else {                                                \
  193                         writeb((pos), vga_palette32[color]);            \
  194                         writew((pos) + 1, vga_palette32[color] >> 8);   \
  195                 }                                                       \
  196                 break;                                                  \
  197         case 16:                                                        \
  198                 if ((scp)->sc->adp->va_info.vi_pixel_fsizes[1] == 5)    \
  199                         writew((pos), vga_palette15[color]);            \
  200                 else                                                    \
  201                         writew((pos), vga_palette16[color]);            \
  202                 break;                                                  \
  203         case 15:                                                        \
  204                 writew((pos), vga_palette15[color]);                    \
  205                 break;                                                  \
  206         case 8:                                                         \
  207                 writeb((pos), (uint8_t)(color));                        \
  208         }                                                               \
  209 } while (0)
  210         
  211 static uint32_t vga_palette32[16] = {
  212         0x000000, 0x0000ad, 0x00ad00, 0x00adad,
  213         0xad0000, 0xad00ad, 0xad5200, 0xadadad,
  214         0x525252, 0x5252ff, 0x52ff52, 0x52ffff,
  215         0xff5252, 0xff52ff, 0xffff52, 0xffffff
  216 };
  217 
  218 static uint16_t vga_palette16[16] = {
  219         0x0000, 0x0016, 0x0560, 0x0576, 0xb000, 0xb016, 0xb2a0, 0xb576,
  220         0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff
  221 };
  222 
  223 static uint16_t vga_palette15[16] = {
  224         0x0000, 0x0016, 0x02c0, 0x02d6, 0x5800, 0x5816, 0x5940, 0x5ad6,
  225         0x294a, 0x295f, 0x2bea, 0x2bff, 0x7d4a, 0x7d5f, 0x7fea, 0x7fff
  226 };
  227 
  228 #ifndef SC_NO_CUTPASTE
  229 static uint32_t mouse_buf32[256];
  230 static uint16_t mouse_buf16[256];
  231 static uint8_t  mouse_buf8[256];
  232 #endif
  233 #endif
  234 
  235 static void
  236 vga_nop(scr_stat *scp)
  237 {
  238 }
  239 
  240 /* text mode renderer */
  241 
  242 static void
  243 vga_txtclear(scr_stat *scp, int c, int attr)
  244 {
  245         sc_vtb_clear(&scp->scr, c, attr);
  246 }
  247 
  248 static void
  249 vga_txtborder(scr_stat *scp, int color)
  250 {
  251         vidd_set_border(scp->sc->adp, color);
  252 }
  253 
  254 static void
  255 vga_txtdraw(scr_stat *scp, int from, int count, int flip)
  256 {
  257         vm_offset_t p;
  258         int c;
  259         int a;
  260 
  261         if (from + count > scp->xsize*scp->ysize)
  262                 count = scp->xsize*scp->ysize - from;
  263 
  264         if (flip) {
  265                 for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) {
  266                         c = sc_vtb_getc(&scp->vtb, from);
  267                         a = sc_vtb_geta(&scp->vtb, from);
  268                         a = (a & 0x8800) | ((a & 0x7000) >> 4) 
  269                                 | ((a & 0x0700) << 4);
  270                         p = sc_vtb_putchar(&scp->scr, p, c, a);
  271                 }
  272         } else {
  273                 sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count);
  274         }
  275 }
  276 
  277 static void 
  278 vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink)
  279 {
  280         if (base < 0 || base >= scp->font_size)
  281                 return;
  282         /* the caller may set height <= 0 in order to disable the cursor */
  283 #if 0
  284         scp->curs_attr.base = base;
  285         scp->curs_attr.height = height;
  286 #endif
  287         vidd_set_hw_cursor_shape(scp->sc->adp, base, height,
  288             scp->font_size, blink);
  289 }
  290 
  291 static void
  292 draw_txtcharcursor(scr_stat *scp, int at, u_short c, u_short a, int flip)
  293 {
  294         sc_softc_t *sc;
  295 
  296         sc = scp->sc;
  297         scp->cursor_saveunder_char = c;
  298         scp->cursor_saveunder_attr = a;
  299 
  300 #ifndef SC_NO_FONT_LOADING
  301         if (scp->curs_attr.flags & CONS_CHAR_CURSOR) {
  302                 unsigned char *font;
  303                 int h;
  304                 int i;
  305 
  306                 if (scp->font_size < 14) {
  307                         font = sc->font_8;
  308                         h = 8;
  309                 } else if (scp->font_size >= 16) {
  310                         font = sc->font_16;
  311                         h = 16;
  312                 } else {
  313                         font = sc->font_14;
  314                         h = 14;
  315                 }
  316                 if (scp->curs_attr.base >= h)
  317                         return;
  318                 if (flip)
  319                         a = (a & 0x8800)
  320                                 | ((a & 0x7000) >> 4) | ((a & 0x0700) << 4);
  321                 bcopy(font + c*h, font + sc->cursor_char*h, h);
  322                 font = font + sc->cursor_char*h;
  323                 for (i = imax(h - scp->curs_attr.base - scp->curs_attr.height, 0);
  324                         i < h - scp->curs_attr.base; ++i) {
  325                         font[i] ^= 0xff;
  326                 }
  327                 /* XXX */
  328                 vidd_load_font(sc->adp, 0, h, 8, font, sc->cursor_char, 1);
  329                 sc_vtb_putc(&scp->scr, at, sc->cursor_char, a);
  330         } else
  331 #endif /* SC_NO_FONT_LOADING */
  332         {
  333                 if ((a & 0x7000) == 0x7000) {
  334                         a &= 0x8f00;
  335                         if ((a & 0x0700) == 0)
  336                                 a |= 0x0700;
  337                 } else {
  338                         a |= 0x7000;
  339                         if ((a & 0x0700) == 0x0700)
  340                                 a &= 0xf000;
  341                 }
  342                 if (flip)
  343                         a = (a & 0x8800)
  344                                 | ((a & 0x7000) >> 4) | ((a & 0x0700) << 4);
  345                 sc_vtb_putc(&scp->scr, at, c, a);
  346         }
  347 }
  348 
  349 static void
  350 vga_txtcursor(scr_stat *scp, int at, int blink, int on, int flip)
  351 {
  352         video_adapter_t *adp;
  353         int cursor_attr;
  354 
  355         if (scp->curs_attr.height <= 0) /* the text cursor is disabled */
  356                 return;
  357 
  358         adp = scp->sc->adp;
  359         if (blink) {
  360                 scp->status |= VR_CURSOR_BLINK;
  361                 if (on) {
  362                         scp->status |= VR_CURSOR_ON;
  363                         vidd_set_hw_cursor(adp, at%scp->xsize,
  364                             at/scp->xsize);
  365                 } else {
  366                         if (scp->status & VR_CURSOR_ON)
  367                                 vidd_set_hw_cursor(adp, -1, -1);
  368                         scp->status &= ~VR_CURSOR_ON;
  369                 }
  370         } else {
  371                 scp->status &= ~VR_CURSOR_BLINK;
  372                 if (on) {
  373                         scp->status |= VR_CURSOR_ON;
  374                         draw_txtcharcursor(scp, at,
  375                                            sc_vtb_getc(&scp->scr, at),
  376                                            sc_vtb_geta(&scp->scr, at),
  377                                            flip);
  378                 } else {
  379                         cursor_attr = scp->cursor_saveunder_attr;
  380                         if (flip)
  381                                 cursor_attr = (cursor_attr & 0x8800)
  382                                         | ((cursor_attr & 0x7000) >> 4)
  383                                         | ((cursor_attr & 0x0700) << 4);
  384                         if (scp->status & VR_CURSOR_ON)
  385                                 sc_vtb_putc(&scp->scr, at,
  386                                             scp->cursor_saveunder_char,
  387                                             cursor_attr);
  388                         scp->status &= ~VR_CURSOR_ON;
  389                 }
  390         }
  391 }
  392 
  393 static void
  394 vga_txtblink(scr_stat *scp, int at, int flip)
  395 {
  396 }
  397 
  398 #ifndef SC_NO_CUTPASTE
  399 
  400 static void
  401 draw_txtmouse(scr_stat *scp, int x, int y)
  402 {
  403 #ifndef SC_ALT_MOUSE_IMAGE
  404     if (ISMOUSEAVAIL(scp->sc->adp->va_flags)) {
  405         u_char font_buf[128];
  406         u_short cursor[32];
  407         u_char c;
  408         int pos;
  409         int xoffset, yoffset;
  410         int crtc_addr;
  411         int i;
  412 
  413         /* prepare mousepointer char's bitmaps */
  414         pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
  415         bcopy(scp->font + sc_vtb_getc(&scp->scr, pos)*scp->font_size,
  416               &font_buf[0], scp->font_size);
  417         bcopy(scp->font + sc_vtb_getc(&scp->scr, pos + 1)*scp->font_size,
  418               &font_buf[32], scp->font_size);
  419         bcopy(scp->font 
  420                  + sc_vtb_getc(&scp->scr, pos + scp->xsize)*scp->font_size,
  421               &font_buf[64], scp->font_size);
  422         bcopy(scp->font
  423                  + sc_vtb_getc(&scp->scr, pos + scp->xsize + 1)*scp->font_size,
  424               &font_buf[96], scp->font_size);
  425         for (i = 0; i < scp->font_size; ++i) {
  426                 cursor[i] = font_buf[i]<<8 | font_buf[i+32];
  427                 cursor[i + scp->font_size] = font_buf[i+64]<<8 | font_buf[i+96];
  428         }
  429 
  430         /* now and-or in the mousepointer image */
  431         xoffset = x%8;
  432         yoffset = y%scp->font_size;
  433         for (i = 0; i < 16; ++i) {
  434                 cursor[i + yoffset] =
  435                         (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset))
  436                         | (mouse_or_mask[i] >> xoffset);
  437         }
  438         for (i = 0; i < scp->font_size; ++i) {
  439                 font_buf[i] = (cursor[i] & 0xff00) >> 8;
  440                 font_buf[i + 32] = cursor[i] & 0xff;
  441                 font_buf[i + 64] = (cursor[i + scp->font_size] & 0xff00) >> 8;
  442                 font_buf[i + 96] = cursor[i + scp->font_size] & 0xff;
  443         }
  444 
  445 #if 1
  446         /* wait for vertical retrace to avoid jitter on some videocards */
  447         crtc_addr = scp->sc->adp->va_crtc_addr;
  448         while (!(inb(crtc_addr + 6) & 0x08)) /* idle */ ;
  449 #endif
  450         c = scp->sc->mouse_char;
  451         vidd_load_font(scp->sc->adp, 0, 32, 8, font_buf, c, 4); 
  452 
  453         sc_vtb_putc(&scp->scr, pos, c, sc_vtb_geta(&scp->scr, pos));
  454         /* FIXME: may be out of range! */
  455         sc_vtb_putc(&scp->scr, pos + scp->xsize, c + 2,
  456                     sc_vtb_geta(&scp->scr, pos + scp->xsize));
  457         if (x < (scp->xsize - 1)*8) {
  458                 sc_vtb_putc(&scp->scr, pos + 1, c + 1,
  459                             sc_vtb_geta(&scp->scr, pos + 1));
  460                 sc_vtb_putc(&scp->scr, pos + scp->xsize + 1, c + 3,
  461                             sc_vtb_geta(&scp->scr, pos + scp->xsize + 1));
  462         }
  463     } else
  464 #endif /* SC_ALT_MOUSE_IMAGE */
  465     {
  466         /* Red, magenta and brown are mapped to green to to keep it readable */
  467         static const int col_conv[16] = {
  468                 6, 6, 6, 6, 2, 2, 2, 6, 14, 14, 14, 14, 10, 10, 10, 14
  469         };
  470         int pos;
  471         int color;
  472         int a;
  473 
  474         pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff;
  475         a = sc_vtb_geta(&scp->scr, pos);
  476         if (scp->sc->adp->va_flags & V_ADP_COLOR)
  477                 color = (col_conv[(a & 0xf000) >> 12] << 12)
  478                         | ((a & 0x0f00) | 0x0800);
  479         else
  480                 color = ((a & 0xf000) >> 4) | ((a & 0x0f00) << 4);
  481         sc_vtb_putc(&scp->scr, pos, sc_vtb_getc(&scp->scr, pos), color);
  482     }
  483 }
  484 
  485 static void
  486 remove_txtmouse(scr_stat *scp, int x, int y)
  487 {
  488 }
  489 
  490 static void 
  491 vga_txtmouse(scr_stat *scp, int x, int y, int on)
  492 {
  493         if (on)
  494                 draw_txtmouse(scp, x, y);
  495         else
  496                 remove_txtmouse(scp, x, y);
  497 }
  498 
  499 #endif /* SC_NO_CUTPASTE */
  500 
  501 #ifdef SC_PIXEL_MODE
  502 
  503 /* pixel (raster text) mode renderer */
  504 
  505 static void
  506 vga_rndrinit(scr_stat *scp)
  507 {
  508         if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_PLANAR) {
  509                 scp->rndr->clear = vga_pxlclear_planar;
  510                 scp->rndr->draw_border = vga_pxlborder_planar;
  511                 scp->rndr->draw = vga_vgadraw_planar;
  512                 scp->rndr->draw_cursor = vga_pxlcursor_planar;
  513                 scp->rndr->blink_cursor = vga_pxlblink_planar;
  514                 scp->rndr->draw_mouse = vga_pxlmouse_planar;
  515         } else
  516         if (scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_DIRECT ||
  517             scp->sc->adp->va_info.vi_mem_model == V_INFO_MM_PACKED) {
  518                 scp->rndr->clear = vga_pxlclear_direct;
  519                 scp->rndr->draw_border = vga_pxlborder_direct;
  520                 scp->rndr->draw = vga_vgadraw_direct;
  521                 scp->rndr->draw_cursor = vga_pxlcursor_direct;
  522                 scp->rndr->blink_cursor = vga_pxlblink_direct;
  523                 scp->rndr->draw_mouse = vga_pxlmouse_direct;
  524         }
  525 }
  526 
  527 static void
  528 vga_pxlclear_direct(scr_stat *scp, int c, int attr)
  529 {
  530         vm_offset_t p;
  531         int line_width;
  532         int pixel_size;
  533         int lines;
  534         int i;
  535 
  536         line_width = scp->sc->adp->va_line_width;
  537         pixel_size = scp->sc->adp->va_info.vi_pixel_size;
  538         lines = scp->ysize * scp->font_size; 
  539         p = scp->sc->adp->va_window +
  540             line_width * scp->yoff * scp->font_size +
  541             scp->xoff * 8 * pixel_size;
  542 
  543         for (i = 0; i < lines; ++i) {
  544                 bzero_io((void *)p, scp->xsize * 8 * pixel_size);
  545                 p += line_width;
  546         }
  547 }
  548 
  549 static void
  550 vga_pxlclear_planar(scr_stat *scp, int c, int attr)
  551 {
  552         vm_offset_t p;
  553         int line_width;
  554         int lines;
  555         int i;
  556 
  557         /* XXX: we are just filling the screen with the background color... */
  558         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
  559         outw(GDCIDX, 0x0003);           /* data rotate/function select */
  560         outw(GDCIDX, 0x0f01);           /* set/reset enable */
  561         outw(GDCIDX, 0xff08);           /* bit mask */
  562         outw(GDCIDX, ((attr & 0xf000) >> 4) | 0x00); /* set/reset */
  563         line_width = scp->sc->adp->va_line_width;
  564         lines = scp->ysize*scp->font_size; 
  565         p = scp->sc->adp->va_window + line_width*scp->yoff*scp->font_size
  566                 + scp->xoff;
  567         for (i = 0; i < lines; ++i) {
  568                 bzero_io((void *)p, scp->xsize);
  569                 p += line_width;
  570         }
  571         outw(GDCIDX, 0x0000);           /* set/reset */
  572         outw(GDCIDX, 0x0001);           /* set/reset enable */
  573 }
  574 
  575 static void
  576 vga_pxlborder_direct(scr_stat *scp, int color)
  577 {
  578         vm_offset_t s;
  579         vm_offset_t e;
  580         vm_offset_t f;
  581         int line_width;
  582         int pixel_size;
  583         int x;
  584         int y;
  585         int i;
  586 
  587         line_width = scp->sc->adp->va_line_width;
  588         pixel_size = scp->sc->adp->va_info.vi_pixel_size;
  589 
  590         if (scp->yoff > 0) {
  591                 s = scp->sc->adp->va_window;
  592                 e = s + line_width * scp->yoff * scp->font_size;
  593 
  594                 for (f = s; f < e; f += pixel_size)
  595                         DRAW_PIXEL(scp, f, color);
  596         }
  597 
  598         y = (scp->yoff + scp->ysize) * scp->font_size;
  599 
  600         if (scp->ypixel > y) {
  601                 s = scp->sc->adp->va_window + line_width * y;
  602                 e = s + line_width * (scp->ypixel - y);
  603 
  604                 for (f = s; f < e; f += pixel_size)
  605                         DRAW_PIXEL(scp, f, color);
  606         }
  607 
  608         y = scp->yoff * scp->font_size;
  609         x = scp->xpixel / 8 - scp->xoff - scp->xsize;
  610 
  611         for (i = 0; i < scp->ysize * scp->font_size; ++i) {
  612                 if (scp->xoff > 0) {
  613                         s = scp->sc->adp->va_window + line_width * (y + i);
  614                         e = s + scp->xoff * 8 * pixel_size;
  615 
  616                         for (f = s; f < e; f += pixel_size)
  617                                 DRAW_PIXEL(scp, f, color);
  618                 }
  619 
  620                 if (x > 0) {
  621                         s = scp->sc->adp->va_window + line_width * (y + i) +
  622                             scp->xoff * 8 * pixel_size +
  623                             scp->xsize * 8 * pixel_size;
  624                         e = s + x * 8 * pixel_size;
  625 
  626                         for (f = s; f < e; f += pixel_size)
  627                                 DRAW_PIXEL(scp, f, color);
  628                 }
  629         }
  630 }
  631 
  632 static void
  633 vga_pxlborder_planar(scr_stat *scp, int color)
  634 {
  635         vm_offset_t p;
  636         int line_width;
  637         int x;
  638         int y;
  639         int i;
  640 
  641         vidd_set_border(scp->sc->adp, color);
  642 
  643         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
  644         outw(GDCIDX, 0x0003);           /* data rotate/function select */
  645         outw(GDCIDX, 0x0f01);           /* set/reset enable */
  646         outw(GDCIDX, 0xff08);           /* bit mask */
  647         outw(GDCIDX, (color << 8) | 0x00);      /* set/reset */
  648         line_width = scp->sc->adp->va_line_width;
  649         p = scp->sc->adp->va_window;
  650         if (scp->yoff > 0)
  651                 bzero_io((void *)p, line_width*scp->yoff*scp->font_size);
  652         y = (scp->yoff + scp->ysize)*scp->font_size;
  653         if (scp->ypixel > y)
  654                 bzero_io((void *)(p + line_width*y), line_width*(scp->ypixel - y));
  655         y = scp->yoff*scp->font_size;
  656         x = scp->xpixel/8 - scp->xoff - scp->xsize;
  657         for (i = 0; i < scp->ysize*scp->font_size; ++i) {
  658                 if (scp->xoff > 0)
  659                         bzero_io((void *)(p + line_width*(y + i)), scp->xoff);
  660                 if (x > 0)
  661                         bzero_io((void *)(p + line_width*(y + i)
  662                                      + scp->xoff + scp->xsize), x);
  663         }
  664         outw(GDCIDX, 0x0000);           /* set/reset */
  665         outw(GDCIDX, 0x0001);           /* set/reset enable */
  666 }
  667 
  668 static void 
  669 vga_egadraw(scr_stat *scp, int from, int count, int flip)
  670 {
  671         vm_offset_t d;
  672         vm_offset_t e;
  673         u_char *f;
  674         u_short bg;
  675         u_short col1, col2;
  676         int line_width;
  677         int i, j;
  678         int a;
  679         u_char c;
  680 
  681         line_width = scp->sc->adp->va_line_width;
  682 
  683         d = GET_PIXEL(scp, from, 1, line_width);
  684 
  685         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
  686         outw(GDCIDX, 0x0003);           /* data rotate/function select */
  687         outw(GDCIDX, 0x0f01);           /* set/reset enable */
  688         bg = -1;
  689         if (from + count > scp->xsize*scp->ysize)
  690                 count = scp->xsize*scp->ysize - from;
  691         for (i = from; count-- > 0; ++i) {
  692                 a = sc_vtb_geta(&scp->vtb, i);
  693                 if (flip) {
  694                         col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
  695                         col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
  696                 } else {
  697                         col1 = (a & 0x0f00);
  698                         col2 = (a & 0xf000) >> 4;
  699                 }
  700                 /* set background color in EGA/VGA latch */
  701                 if (bg != col2) {
  702                         bg = col2;
  703                         outw(GDCIDX, bg | 0x00);        /* set/reset */
  704                         outw(GDCIDX, 0xff08);           /* bit mask */
  705                         writeb(d, 0);
  706                         c = readb(d);   /* set bg color in the latch */
  707                 }
  708                 /* foreground color */
  709                 outw(GDCIDX, col1 | 0x00);              /* set/reset */
  710                 e = d;
  711                 f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
  712                 for (j = 0; j < scp->font_size; ++j, ++f) {
  713                         outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */
  714                         writeb(e, 0);
  715                         e += line_width;
  716                 }
  717                 ++d;
  718                 if ((i % scp->xsize) == scp->xsize - 1)
  719                         d += scp->font_size * line_width - scp->xsize;
  720         }
  721         outw(GDCIDX, 0x0000);           /* set/reset */
  722         outw(GDCIDX, 0x0001);           /* set/reset enable */
  723         outw(GDCIDX, 0xff08);           /* bit mask */
  724 }
  725 
  726 static void
  727 vga_vgadraw_direct(scr_stat *scp, int from, int count, int flip)
  728 {
  729         vm_offset_t d;
  730         vm_offset_t e;
  731         u_char *f;
  732         u_short col1, col2, color;
  733         int line_width, pixel_size;
  734         int i, j, k;
  735         int a;
  736 
  737         line_width = scp->sc->adp->va_line_width;
  738         pixel_size = scp->sc->adp->va_info.vi_pixel_size;
  739 
  740         d = GET_PIXEL(scp, from, 8 * pixel_size, line_width);
  741 
  742         if (from + count > scp->xsize * scp->ysize)
  743                 count = scp->xsize * scp->ysize - from;
  744 
  745         for (i = from; count-- > 0; ++i) {
  746                 a = sc_vtb_geta(&scp->vtb, i);
  747 
  748                 if (flip) {
  749                         col1 = (((a & 0x7000) >> 4) | (a & 0x0800)) >> 8;
  750                         col2 = (((a & 0x8000) >> 4) | (a & 0x0700)) >> 8;
  751                 } else {
  752                         col1 = (a & 0x0f00) >> 8;
  753                         col2 = (a & 0xf000) >> 12;
  754                 }
  755 
  756                 e = d;
  757                 f = &(scp->font[sc_vtb_getc(&scp->vtb, i) * scp->font_size]);
  758 
  759                 for (j = 0; j < scp->font_size; ++j, ++f) {
  760                         for (k = 0; k < 8; ++k) {
  761                                 color = *f & (1 << (7 - k)) ? col1 : col2;
  762                                 DRAW_PIXEL(scp, e + pixel_size * k, color);
  763                         }
  764 
  765                         e += line_width;
  766                 }
  767 
  768                 d += 8 * pixel_size;
  769 
  770                 if ((i % scp->xsize) == scp->xsize - 1)
  771                         d += scp->font_size * line_width -
  772                             scp->xsize * 8 * pixel_size;
  773         }
  774 }
  775 
  776 static void
  777 vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip)
  778 {
  779         vm_offset_t d;
  780         vm_offset_t e;
  781         u_char *f;
  782         u_short bg;
  783         u_short col1, col2;
  784         int line_width;
  785         int i, j;
  786         int a;
  787         u_char c;
  788 
  789         line_width = scp->sc->adp->va_line_width;
  790 
  791         d = GET_PIXEL(scp, from, 1, line_width);
  792 
  793         outw(GDCIDX, 0x0305);           /* read mode 0, write mode 3 */
  794         outw(GDCIDX, 0x0003);           /* data rotate/function select */
  795         outw(GDCIDX, 0x0f01);           /* set/reset enable */
  796         outw(GDCIDX, 0xff08);           /* bit mask */
  797         bg = -1;
  798         if (from + count > scp->xsize*scp->ysize)
  799                 count = scp->xsize*scp->ysize - from;
  800         for (i = from; count-- > 0; ++i) {
  801                 a = sc_vtb_geta(&scp->vtb, i);
  802                 if (flip) {
  803                         col1 = ((a & 0x7000) >> 4) | (a & 0x0800);
  804                         col2 = ((a & 0x8000) >> 4) | (a & 0x0700);
  805                 } else {
  806                         col1 = (a & 0x0f00);
  807                         col2 = (a & 0xf000) >> 4;
  808                 }
  809                 /* set background color in EGA/VGA latch */
  810                 if (bg != col2) {
  811                         bg = col2;
  812                         outw(GDCIDX, 0x0005);   /* read mode 0, write mode 0 */
  813                         outw(GDCIDX, bg | 0x00); /* set/reset */
  814                         writeb(d, 0);
  815                         c = readb(d);           /* set bg color in the latch */
  816                         outw(GDCIDX, 0x0305);   /* read mode 0, write mode 3 */
  817                 }
  818                 /* foreground color */
  819                 outw(GDCIDX, col1 | 0x00);      /* set/reset */
  820                 e = d;
  821                 f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]);
  822                 for (j = 0; j < scp->font_size; ++j, ++f) {
  823                         writeb(e, *f);
  824                         e += line_width;
  825                 }
  826                 ++d;
  827                 if ((i % scp->xsize) == scp->xsize - 1)
  828                         d += scp->font_size * line_width - scp->xsize;
  829         }
  830         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
  831         outw(GDCIDX, 0x0000);           /* set/reset */
  832         outw(GDCIDX, 0x0001);           /* set/reset enable */
  833 }
  834 
  835 static void 
  836 vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink)
  837 {
  838         if (base < 0 || base >= scp->font_size)
  839                 return;
  840         /* the caller may set height <= 0 in order to disable the cursor */
  841 #if 0
  842         scp->curs_attr.base = base;
  843         scp->curs_attr.height = height;
  844 #endif
  845 }
  846 
  847 static void 
  848 draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip)
  849 {
  850         vm_offset_t d;
  851         u_char *f;
  852         int line_width, pixel_size;
  853         int height;
  854         int col1, col2, color;
  855         int a;
  856         int i, j;
  857 
  858         line_width = scp->sc->adp->va_line_width;
  859         pixel_size = scp->sc->adp->va_info.vi_pixel_size;
  860 
  861         d = GET_PIXEL(scp, at, 8 * pixel_size, line_width) +
  862             (scp->font_size - scp->curs_attr.base - 1) * line_width;
  863 
  864         a = sc_vtb_geta(&scp->vtb, at);
  865 
  866         if (flip) {
  867                 col1 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8;
  868                 col2 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8;
  869         } else {
  870                 col1 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8;
  871                 col2 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8;
  872         }
  873 
  874         f = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size +
  875               scp->font_size - scp->curs_attr.base - 1]);
  876 
  877         height = imin(scp->curs_attr.height, scp->font_size);
  878 
  879         for (i = 0; i < height; ++i, --f) {
  880                 for (j = 0; j < 8; ++j) {
  881                         color = *f & (1 << (7 - j)) ? col1 : col2;
  882                         DRAW_PIXEL(scp, d + pixel_size * j, color);
  883                 }
  884 
  885                 d -= line_width;
  886         }
  887 }
  888 
  889 static void 
  890 draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip)
  891 {
  892         vm_offset_t d;
  893         u_char *f;
  894         int line_width;
  895         int height;
  896         int col;
  897         int a;
  898         int i;
  899         u_char c;
  900 
  901         line_width = scp->sc->adp->va_line_width;
  902 
  903         d = GET_PIXEL(scp, at, 1, line_width) +
  904             (scp->font_size - scp->curs_attr.base - 1) * line_width;
  905 
  906         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
  907         outw(GDCIDX, 0x0003);           /* data rotate/function select */
  908         outw(GDCIDX, 0x0f01);           /* set/reset enable */
  909         /* set background color in EGA/VGA latch */
  910         a = sc_vtb_geta(&scp->vtb, at);
  911         if (flip)
  912                 col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
  913         else
  914                 col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
  915         outw(GDCIDX, col | 0x00);       /* set/reset */
  916         outw(GDCIDX, 0xff08);           /* bit mask */
  917         writeb(d, 0);
  918         c = readb(d);                   /* set bg color in the latch */
  919         /* foreground color */
  920         if (flip)
  921                 col = (on) ? (a & 0x0f00) : ((a & 0xf000) >> 4);
  922         else
  923                 col = (on) ? ((a & 0xf000) >> 4) : (a & 0x0f00);
  924         outw(GDCIDX, col | 0x00);       /* set/reset */
  925         f = &(scp->font[sc_vtb_getc(&scp->vtb, at)*scp->font_size
  926                 + scp->font_size - scp->curs_attr.base - 1]);
  927         height = imin(scp->curs_attr.height, scp->font_size);
  928         for (i = 0; i < height; ++i, --f) {
  929                 outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */
  930                 writeb(d, 0);
  931                 d -= line_width;
  932         }
  933         outw(GDCIDX, 0x0000);           /* set/reset */
  934         outw(GDCIDX, 0x0001);           /* set/reset enable */
  935         outw(GDCIDX, 0xff08);           /* bit mask */
  936 }
  937 
  938 static int pxlblinkrate = 0;
  939 
  940 static void 
  941 vga_pxlcursor_direct(scr_stat *scp, int at, int blink, int on, int flip)
  942 {
  943         if (scp->curs_attr.height <= 0) /* the text cursor is disabled */
  944                 return;
  945 
  946         if (on) {
  947                 if (!blink) {
  948                         scp->status |= VR_CURSOR_ON;
  949                         draw_pxlcursor_direct(scp, at, on, flip);
  950                 } else if (++pxlblinkrate & 4) {
  951                         pxlblinkrate = 0;
  952                         scp->status ^= VR_CURSOR_ON;
  953                         draw_pxlcursor_direct(scp, at,
  954                                               scp->status & VR_CURSOR_ON,
  955                                               flip);
  956                 }
  957         } else {
  958                 if (scp->status & VR_CURSOR_ON)
  959                         draw_pxlcursor_direct(scp, at, on, flip);
  960                 scp->status &= ~VR_CURSOR_ON;
  961         }
  962         if (blink)
  963                 scp->status |= VR_CURSOR_BLINK;
  964         else
  965                 scp->status &= ~VR_CURSOR_BLINK;
  966 }
  967 
  968 static void 
  969 vga_pxlcursor_planar(scr_stat *scp, int at, int blink, int on, int flip)
  970 {
  971         if (scp->curs_attr.height <= 0) /* the text cursor is disabled */
  972                 return;
  973 
  974         if (on) {
  975                 if (!blink) {
  976                         scp->status |= VR_CURSOR_ON;
  977                         draw_pxlcursor_planar(scp, at, on, flip);
  978                 } else if (++pxlblinkrate & 4) {
  979                         pxlblinkrate = 0;
  980                         scp->status ^= VR_CURSOR_ON;
  981                         draw_pxlcursor_planar(scp, at,
  982                                               scp->status & VR_CURSOR_ON,
  983                                               flip);
  984                 }
  985         } else {
  986                 if (scp->status & VR_CURSOR_ON)
  987                         draw_pxlcursor_planar(scp, at, on, flip);
  988                 scp->status &= ~VR_CURSOR_ON;
  989         }
  990         if (blink)
  991                 scp->status |= VR_CURSOR_BLINK;
  992         else
  993                 scp->status &= ~VR_CURSOR_BLINK;
  994 }
  995 
  996 static void
  997 vga_pxlblink_direct(scr_stat *scp, int at, int flip)
  998 {
  999         if (!(scp->status & VR_CURSOR_BLINK))
 1000                 return;
 1001         if (!(++pxlblinkrate & 4))
 1002                 return;
 1003         pxlblinkrate = 0;
 1004         scp->status ^= VR_CURSOR_ON;
 1005         draw_pxlcursor_direct(scp, at, scp->status & VR_CURSOR_ON, flip);
 1006 }
 1007 
 1008 static void
 1009 vga_pxlblink_planar(scr_stat *scp, int at, int flip)
 1010 {
 1011         if (!(scp->status & VR_CURSOR_BLINK))
 1012                 return;
 1013         if (!(++pxlblinkrate & 4))
 1014                 return;
 1015         pxlblinkrate = 0;
 1016         scp->status ^= VR_CURSOR_ON;
 1017         draw_pxlcursor_planar(scp, at, scp->status & VR_CURSOR_ON, flip);
 1018 }
 1019 
 1020 #ifndef SC_NO_CUTPASTE
 1021 
 1022 static void
 1023 draw_pxlmouse_planar(scr_stat *scp, int x, int y)
 1024 {
 1025         vm_offset_t p;
 1026         int line_width;
 1027         int xoff, yoff;
 1028         int ymax;
 1029         u_short m;
 1030         int i, j;
 1031 
 1032         line_width = scp->sc->adp->va_line_width;
 1033         xoff = (x - scp->xoff*8)%8;
 1034         yoff = y - (y/line_width)*line_width;
 1035         ymax = imin(y + 16, scp->ypixel);
 1036 
 1037         outw(GDCIDX, 0x0805);           /* read mode 1, write mode 0 */
 1038         outw(GDCIDX, 0x0001);           /* set/reset enable */
 1039         outw(GDCIDX, 0x0002);           /* color compare */
 1040         outw(GDCIDX, 0x0007);           /* color don't care */
 1041         outw(GDCIDX, 0xff08);           /* bit mask */
 1042         outw(GDCIDX, 0x0803);           /* data rotate/function select (and) */
 1043         p = scp->sc->adp->va_window + line_width*y + x/8;
 1044         if (x < scp->xpixel - 8) {
 1045                 for (i = y, j = 0; i < ymax; ++i, ++j) {
 1046                         m = ~(mouse_and_mask[j] >> xoff);
 1047 #if defined(__i386__) || defined(__amd64__)
 1048                         *(u_char *)p &= m >> 8;
 1049                         *(u_char *)(p + 1) &= m;
 1050 #else
 1051                         writeb(p, readb(p) & (m >> 8));
 1052                         writeb(p + 1, readb(p + 1) & (m >> 8));
 1053 #endif
 1054                         p += line_width;
 1055                 }
 1056         } else {
 1057                 xoff += 8;
 1058                 for (i = y, j = 0; i < ymax; ++i, ++j) {
 1059                         m = ~(mouse_and_mask[j] >> xoff);
 1060 #if defined(__i386__) || defined(__amd64__)
 1061                         *(u_char *)p &= m;
 1062 #else
 1063                         writeb(p, readb(p) & (m >> 8));
 1064 #endif
 1065                         p += line_width;
 1066                 }
 1067         }
 1068         outw(GDCIDX, 0x1003);           /* data rotate/function select (or) */
 1069         p = scp->sc->adp->va_window + line_width*y + x/8;
 1070         if (x < scp->xpixel - 8) {
 1071                 for (i = y, j = 0; i < ymax; ++i, ++j) {
 1072                         m = mouse_or_mask[j] >> xoff;
 1073 #if defined(__i386__) || defined(__amd64__)
 1074                         *(u_char *)p &= m >> 8;
 1075                         *(u_char *)(p + 1) &= m;
 1076 #else
 1077                         writeb(p, readb(p) & (m >> 8));
 1078                         writeb(p + 1, readb(p + 1) & (m >> 8));
 1079 #endif
 1080                         p += line_width;
 1081                 }
 1082         } else {
 1083                 for (i = y, j = 0; i < ymax; ++i, ++j) {
 1084                         m = mouse_or_mask[j] >> xoff;
 1085 #if defined(__i386__) || defined(__amd64__)
 1086                         *(u_char *)p &= m;
 1087 #else
 1088                         writeb(p, readb(p) & (m >> 8));
 1089 #endif
 1090                         p += line_width;
 1091                 }
 1092         }
 1093         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
 1094         outw(GDCIDX, 0x0003);           /* data rotate/function select */
 1095 }
 1096 
 1097 static void
 1098 remove_pxlmouse_planar(scr_stat *scp, int x, int y)
 1099 {
 1100         vm_offset_t p;
 1101         int col, row;
 1102         int pos;
 1103         int line_width;
 1104         int ymax;
 1105         int i;
 1106 
 1107         /* erase the mouse cursor image */
 1108         col = x/8 - scp->xoff;
 1109         row = y/scp->font_size - scp->yoff;
 1110         pos = row*scp->xsize + col;
 1111         i = (col < scp->xsize - 1) ? 2 : 1;
 1112         (*scp->rndr->draw)(scp, pos, i, FALSE);
 1113         if (row < scp->ysize - 1)
 1114                 (*scp->rndr->draw)(scp, pos + scp->xsize, i, FALSE);
 1115 
 1116         /* paint border if necessary */
 1117         line_width = scp->sc->adp->va_line_width;
 1118         outw(GDCIDX, 0x0005);           /* read mode 0, write mode 0 */
 1119         outw(GDCIDX, 0x0003);           /* data rotate/function select */
 1120         outw(GDCIDX, 0x0f01);           /* set/reset enable */
 1121         outw(GDCIDX, 0xff08);           /* bit mask */
 1122         outw(GDCIDX, (scp->border << 8) | 0x00);        /* set/reset */
 1123         if (row == scp->ysize - 1) {
 1124                 i = (scp->ysize + scp->yoff)*scp->font_size;
 1125                 ymax = imin(i + scp->font_size, scp->ypixel);
 1126                 p = scp->sc->adp->va_window + i*line_width + scp->xoff + col;
 1127                 if (col < scp->xsize - 1) {
 1128                         for (; i < ymax; ++i) {
 1129                                 writeb(p, 0);
 1130                                 writeb(p + 1, 0);
 1131                                 p += line_width;
 1132                         }
 1133                 } else {
 1134                         for (; i < ymax; ++i) {
 1135                                 writeb(p, 0);
 1136                                 p += line_width;
 1137                         }
 1138                 }
 1139         }
 1140         if ((col == scp->xsize - 1) && (scp->xoff > 0)) {
 1141                 i = (row + scp->yoff)*scp->font_size;
 1142                 ymax = imin(i + scp->font_size*2, scp->ypixel);
 1143                 p = scp->sc->adp->va_window + i*line_width
 1144                         + scp->xoff + scp->xsize;
 1145                 for (; i < ymax; ++i) {
 1146                         writeb(p, 0);
 1147                         p += line_width;
 1148                 }
 1149         }
 1150         outw(GDCIDX, 0x0000);           /* set/reset */
 1151         outw(GDCIDX, 0x0001);           /* set/reset enable */
 1152 }
 1153 
 1154 static void 
 1155 vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on)
 1156 {
 1157         vm_offset_t p;
 1158         int line_width, pixel_size;
 1159         int xend, yend;
 1160         static int x_old = 0, xend_old = 0;
 1161         static int y_old = 0, yend_old = 0;
 1162         int i, j;
 1163         uint32_t *u32;
 1164         uint16_t *u16;
 1165         uint8_t  *u8;
 1166         int bpp;
 1167 
 1168         if (!on)
 1169                 return;
 1170 
 1171         bpp = scp->sc->adp->va_info.vi_depth;
 1172 
 1173         if ((bpp == 16) && (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5))
 1174                 bpp = 15;
 1175 
 1176         line_width = scp->sc->adp->va_line_width;
 1177         pixel_size = scp->sc->adp->va_info.vi_pixel_size;
 1178 
 1179         xend = imin(x + 16, scp->xpixel);
 1180         yend = imin(y + 16, scp->ypixel);
 1181 
 1182         p = scp->sc->adp->va_window + y_old * line_width + x_old * pixel_size;
 1183 
 1184         for (i = 0; i < (yend_old - y_old); i++) {
 1185                 for (j = (xend_old - x_old - 1); j >= 0; j--) {
 1186                         switch (bpp) {
 1187                         case 32:
 1188                                 u32 = (uint32_t*)(p + j * pixel_size);
 1189                                 writel(u32, mouse_buf32[i * 16 + j]);
 1190                                 break;
 1191                         case 16:
 1192                                 /* FALLTHROUGH */
 1193                         case 15:
 1194                                 u16 = (uint16_t*)(p + j * pixel_size);
 1195                                 writew(u16, mouse_buf16[i * 16 + j]);
 1196                                 break;
 1197                         case 8:
 1198                                 u8 = (uint8_t*)(p + j * pixel_size);
 1199                                 writeb(u8, mouse_buf8[i * 16 + j]);
 1200                                 break;
 1201                         }
 1202                 }
 1203 
 1204                 p += line_width;
 1205         }
 1206 
 1207         p = scp->sc->adp->va_window + y * line_width + x * pixel_size;
 1208 
 1209         for (i = 0; i < (yend - y); i++) {
 1210                 for (j = (xend - x - 1); j >= 0; j--) {
 1211                         switch (bpp) {
 1212                         case 32:
 1213                                 u32 = (uint32_t*)(p + j * pixel_size);
 1214                                 mouse_buf32[i * 16 + j] = *u32;
 1215                                 if (mouse_or_mask[i] & (1 << (15 - j)))
 1216                                         writel(u32, vga_palette32[15]);
 1217                                 else if (mouse_and_mask[i] & (1 << (15 - j)))
 1218                                         writel(u32, 0);
 1219                                 break;
 1220                         case 16:
 1221                                 u16 = (uint16_t*)(p + j * pixel_size);
 1222                                 mouse_buf16[i * 16 + j] = *u16;
 1223                                 if (mouse_or_mask[i] & (1 << (15 - j)))
 1224                                         writew(u16, vga_palette16[15]);
 1225                                 else if (mouse_and_mask[i] & (1 << (15 - j)))
 1226                                         writew(u16, 0);
 1227                                 break;
 1228                         case 15:
 1229                                 u16 = (uint16_t*)(p  + j * pixel_size);
 1230                                 mouse_buf16[i * 16 + j] = *u16;
 1231                                 if (mouse_or_mask[i] & (1 << (15 - j)))
 1232                                         writew(u16, vga_palette15[15]);
 1233                                 else if (mouse_and_mask[i] & (1 << (15 - j)))
 1234                                         writew(u16, 0);
 1235                                 break;
 1236                         case 8:
 1237                                 u8 = (uint8_t*)(p + j * pixel_size);
 1238                                 mouse_buf8[i * 16 + j] = *u8;
 1239                                 if (mouse_or_mask[i] & (1 << (15 - j)))
 1240                                         writeb(u8, 15);
 1241                                 else if (mouse_and_mask[i] & (1 << (15 - j)))
 1242                                         writeb(u8, 0);
 1243                                 break;
 1244                         }
 1245                 }
 1246 
 1247                 p += line_width;
 1248         }
 1249 
 1250         x_old = x;
 1251         y_old = y;
 1252         xend_old = xend;
 1253         yend_old = yend;
 1254 }
 1255 
 1256 static void 
 1257 vga_pxlmouse_planar(scr_stat *scp, int x, int y, int on)
 1258 {
 1259         if (on)
 1260                 draw_pxlmouse_planar(scp, x, y);
 1261         else
 1262                 remove_pxlmouse_planar(scp, x, y);
 1263 }
 1264 
 1265 #endif /* SC_NO_CUTPASTE */
 1266 #endif /* SC_PIXEL_MODE */
 1267 
 1268 #ifndef SC_NO_MODE_CHANGE
 1269 
 1270 /* graphics mode renderer */
 1271 
 1272 static void
 1273 vga_grborder(scr_stat *scp, int color)
 1274 {
 1275         vidd_set_border(scp->sc->adp, color);
 1276 }
 1277 
 1278 #endif

Cache object: 65a56c4dcf262b33bd7c1f96b80494d8


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