root/dev/rasops/rasops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rasops_init
  2. rasops_reconfig
  3. rasops_mapchar
  4. rasops_alloc_cattr
  5. rasops_alloc_mattr
  6. rasops_copyrows
  7. rasops_copycols
  8. rasops_cursor
  9. rasops_init_devcmap
  10. rasops_unpack_attr
  11. rasops_eraserows
  12. rasops_do_cursor
  13. rasops_erasecols
  14. rasops_rotate_font
  15. rasops_copychar
  16. rasops_putchar_rotated
  17. rasops_erasecols_rotated
  18. rasops_copyrows_rotated
  19. rasops_copycols_rotated
  20. rasops_eraserows_rotated
  21. slow_ovbcopy

    1 /*      $OpenBSD: rasops.c,v 1.17 2006/12/02 18:02:53 miod Exp $        */
    2 /*      $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $       */
    3 
    4 /*-
    5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Andrew Doran.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/time.h>
   43 
   44 #include <machine/endian.h>
   45 
   46 #include <dev/wscons/wsdisplayvar.h>
   47 #include <dev/wscons/wsconsio.h>
   48 #include <dev/wsfont/wsfont.h>
   49 #include <dev/rasops/rasops.h>
   50 
   51 #ifndef _KERNEL
   52 #include <errno.h>
   53 #endif
   54 
   55 /* ANSI colormap (R,G,B) */
   56 
   57 #define NORMAL_BLACK    0x000000
   58 #define NORMAL_RED      0x7f0000
   59 #define NORMAL_GREEN    0x007f00
   60 #define NORMAL_BROWN    0x7f7f00
   61 #define NORMAL_BLUE     0x00007f
   62 #define NORMAL_MAGENTA  0x7f007f
   63 #define NORMAL_CYAN     0x007f7f
   64 #define NORMAL_WHITE    0xc7c7c7        /* XXX too dim? */
   65 
   66 #define HILITE_BLACK    0x7f7f7f
   67 #define HILITE_RED      0xff0000
   68 #define HILITE_GREEN    0x00ff00
   69 #define HILITE_BROWN    0xffff00
   70 #define HILITE_BLUE     0x0000ff
   71 #define HILITE_MAGENTA  0xff00ff
   72 #define HILITE_CYAN     0x00ffff
   73 #define HILITE_WHITE    0xffffff
   74 
   75 const u_char rasops_cmap[256 * 3] = {
   76 #define _C(x)   ((x) & 0xff0000) >> 16, ((x) & 0x00ff00) >> 8, ((x) & 0x0000ff)
   77 
   78         _C(NORMAL_BLACK),
   79         _C(NORMAL_RED),
   80         _C(NORMAL_GREEN),
   81         _C(NORMAL_BROWN),
   82         _C(NORMAL_BLUE),
   83         _C(NORMAL_MAGENTA),
   84         _C(NORMAL_CYAN),
   85         _C(NORMAL_WHITE),
   86 
   87         _C(HILITE_BLACK),
   88         _C(HILITE_RED),
   89         _C(HILITE_GREEN),
   90         _C(HILITE_BROWN),
   91         _C(HILITE_BLUE),
   92         _C(HILITE_MAGENTA),
   93         _C(HILITE_CYAN),
   94         _C(HILITE_WHITE),
   95 
   96         /*
   97          * For the cursor, we need the last 16 colors to be the
   98          * opposite of the first 16. Fill the intermediate space with
   99          * white completely for simplicity.
  100          */
  101 #define _CMWHITE16 \
  102         _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), \
  103         _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), \
  104         _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), \
  105         _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE), _C(HILITE_WHITE),
  106         _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
  107         _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
  108         _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
  109 #undef _CMWHITE16
  110 
  111         _C(~HILITE_WHITE),
  112         _C(~HILITE_CYAN),
  113         _C(~HILITE_MAGENTA),
  114         _C(~HILITE_BLUE),
  115         _C(~HILITE_BROWN),
  116         _C(~HILITE_GREEN),
  117         _C(~HILITE_RED),
  118         _C(~HILITE_BLACK),
  119 
  120         _C(~NORMAL_WHITE),
  121         _C(~NORMAL_CYAN),
  122         _C(~NORMAL_MAGENTA),
  123         _C(~NORMAL_BLUE),
  124         _C(~NORMAL_BROWN),
  125         _C(~NORMAL_GREEN),
  126         _C(~NORMAL_RED),
  127         _C(~NORMAL_BLACK),
  128 
  129 #undef  _C
  130 };
  131 
  132 /* True if color is gray */
  133 const u_char rasops_isgray[16] = {
  134         1, 0, 0, 0,
  135         0, 0, 0, 1,
  136         1, 0, 0, 0,
  137         0, 0, 0, 1
  138 };
  139 
  140 /* Generic functions */
  141 void    rasops_copycols(void *, int, int, int, int);
  142 void    rasops_copyrows(void *, int, int, int);
  143 int     rasops_mapchar(void *, int, u_int *);
  144 void    rasops_cursor(void *, int, int, int);
  145 int     rasops_alloc_cattr(void *, int, int, int, long *);
  146 int     rasops_alloc_mattr(void *, int, int, int, long *);
  147 void    rasops_do_cursor(struct rasops_info *);
  148 void    rasops_init_devcmap(struct rasops_info *);
  149 void    rasops_unpack_attr(void *, long, int *, int *, int *);
  150 #if NRASOPS_BSWAP > 0
  151 static void slow_ovbcopy(void *, void *, size_t);
  152 #endif
  153 #if NRASOPS_ROTATION > 0
  154 void    rasops_copychar(void *, int, int, int, int);
  155 void    rasops_copycols_rotated(void *, int, int, int, int);
  156 void    rasops_copyrows_rotated(void *, int, int, int);
  157 void    rasops_erasecols_rotated(void *, int, int, int, long);
  158 void    rasops_eraserows_rotated(void *, int, int, long);
  159 void    rasops_putchar_rotated(void *, int, int, u_int, long);
  160 void    rasops_rotate_font(int *);
  161 
  162 /*
  163  * List of all rotated fonts
  164  */
  165 SLIST_HEAD(, rotatedfont) rotatedfonts = SLIST_HEAD_INITIALIZER(rotatedfonts);
  166 struct  rotatedfont {
  167         SLIST_ENTRY(rotatedfont) rf_next;
  168         int rf_cookie;
  169         int rf_rotated;
  170 };
  171 #endif
  172 
  173 /*
  174  * Initialize a 'rasops_info' descriptor.
  175  */
  176 int
  177 rasops_init(ri, wantrows, wantcols)
  178         struct rasops_info *ri;
  179         int wantrows, wantcols;
  180 {
  181 
  182 #ifdef _KERNEL
  183         /* Select a font if the caller doesn't care */
  184         if (ri->ri_font == NULL) {
  185                 int cookie;
  186 
  187                 wsfont_init();
  188 
  189                 if (ri->ri_width > 80*12)
  190                         /* High res screen, choose a big font */
  191                         cookie = wsfont_find(NULL, 12, 0, 0);
  192                 else
  193                         /*  lower res, choose a 8 pixel wide font */
  194                         cookie = wsfont_find(NULL, 8, 0, 0);
  195 
  196                 if (cookie <= 0)
  197                         cookie = wsfont_find(NULL, 0, 0, 0);
  198 
  199                 if (cookie <= 0) {
  200                         printf("rasops_init: font table is empty\n");
  201                         return (-1);
  202                 }
  203 
  204 #if NRASOPS_ROTATION > 0
  205                 /*
  206                  * Pick the rotated version of this font. This will create it
  207                  * if necessary.
  208                  */
  209                 if (ri->ri_flg & RI_ROTATE_CW)
  210                         rasops_rotate_font(&cookie);
  211 #endif
  212 
  213                 if (wsfont_lock(cookie, &ri->ri_font,
  214                     WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R) <= 0) {
  215                         printf("rasops_init: couldn't lock font\n");
  216                         return (-1);
  217                 }
  218 
  219                 ri->ri_wsfcookie = cookie;
  220         }
  221 #endif
  222 
  223         /* This should never happen in reality... */
  224 #ifdef DEBUG
  225         if ((long)ri->ri_bits & 3) {
  226                 printf("rasops_init: bits not aligned on 32-bit boundary\n");
  227                 return (-1);
  228         }
  229 
  230         if ((int)ri->ri_stride & 3) {
  231                 printf("rasops_init: stride not aligned on 32-bit boundary\n");
  232                 return (-1);
  233         }
  234 #endif
  235 
  236         if (rasops_reconfig(ri, wantrows, wantcols))
  237                 return (-1);
  238 
  239         rasops_init_devcmap(ri);
  240         return (0);
  241 }
  242 
  243 /*
  244  * Reconfigure (because parameters have changed in some way).
  245  */
  246 int
  247 rasops_reconfig(ri, wantrows, wantcols)
  248         struct rasops_info *ri;
  249         int wantrows, wantcols;
  250 {
  251         int l, bpp, s;
  252 
  253         s = splhigh();
  254 
  255         if (ri->ri_font->fontwidth > 32 || ri->ri_font->fontwidth < 4)
  256                 panic("rasops_init: fontwidth assumptions botched!");
  257 
  258         /* Need this to frob the setup below */
  259         bpp = (ri->ri_depth == 15 ? 16 : ri->ri_depth);
  260 
  261         if ((ri->ri_flg & RI_CFGDONE) != 0)
  262                 ri->ri_bits = ri->ri_origbits;
  263 
  264         /* Don't care if the caller wants a hideously small console */
  265         if (wantrows < 10)
  266                 wantrows = 10;
  267 
  268         if (wantcols < 20)
  269                 wantcols = 20;
  270 
  271         /* Now constrain what they get */
  272         ri->ri_emuwidth = ri->ri_font->fontwidth * wantcols;
  273         ri->ri_emuheight = ri->ri_font->fontheight * wantrows;
  274 
  275         if (ri->ri_emuwidth > ri->ri_width)
  276                 ri->ri_emuwidth = ri->ri_width;
  277 
  278         if (ri->ri_emuheight > ri->ri_height)
  279                 ri->ri_emuheight = ri->ri_height;
  280 
  281         /* Reduce width until aligned on a 32-bit boundary */
  282         while ((ri->ri_emuwidth * bpp & 31) != 0)
  283                 ri->ri_emuwidth--;
  284 
  285 #if NRASOPS_ROTATION > 0
  286         if (ri->ri_flg & RI_ROTATE_CW) {
  287                 ri->ri_rows = ri->ri_emuwidth / ri->ri_font->fontwidth;
  288                 ri->ri_cols = ri->ri_emuheight / ri->ri_font->fontheight;
  289         } else
  290 #endif
  291         {
  292                 ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth;
  293                 ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight;
  294         }
  295         ri->ri_emustride = ri->ri_emuwidth * bpp >> 3;
  296         ri->ri_delta = ri->ri_stride - ri->ri_emustride;
  297         ri->ri_ccol = 0;
  298         ri->ri_crow = 0;
  299         ri->ri_pelbytes = bpp >> 3;
  300 
  301         ri->ri_xscale = (ri->ri_font->fontwidth * bpp) >> 3;
  302         ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride;
  303         ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride;
  304 
  305 #ifdef DEBUG
  306         if ((ri->ri_delta & 3) != 0)
  307                 panic("rasops_init: ri_delta not aligned on 32-bit boundary");
  308 #endif
  309         /* Clear the entire display */
  310         if ((ri->ri_flg & RI_CLEAR) != 0) {
  311                 memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
  312                 ri->ri_flg &= ~RI_CLEARMARGINS;
  313         }
  314 
  315         /* Now centre our window if needs be */
  316         ri->ri_origbits = ri->ri_bits;
  317 
  318         if ((ri->ri_flg & RI_CENTER) != 0) {
  319                 ri->ri_bits += (((ri->ri_width * bpp >> 3) -
  320                     ri->ri_emustride) >> 1) & ~3;
  321                 ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
  322                     ri->ri_stride;
  323 
  324                 ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
  325                    / ri->ri_stride;
  326                 ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
  327                    % ri->ri_stride) * 8 / bpp);
  328         } else
  329                 ri->ri_xorigin = ri->ri_yorigin = 0;
  330 
  331         /* Clear the margins */
  332         if ((ri->ri_flg & RI_CLEARMARGINS) != 0) {
  333                 memset(ri->ri_origbits, 0, ri->ri_bits - ri->ri_origbits);
  334                 for (l = 0; l < ri->ri_emuheight; l++)
  335                         memset(ri->ri_bits + ri->ri_emustride +
  336                             l * ri->ri_stride, 0,
  337                             ri->ri_stride - ri->ri_emustride);
  338                 memset(ri->ri_bits + ri->ri_emuheight * ri->ri_stride, 0,
  339                     (ri->ri_origbits + ri->ri_height * ri->ri_stride) -
  340                     (ri->ri_bits + ri->ri_emuheight * ri->ri_stride));
  341         }
  342 
  343         /*
  344          * Fill in defaults for operations set.  XXX this nukes private
  345          * routines used by accelerated fb drivers.
  346          */
  347         ri->ri_ops.mapchar = rasops_mapchar;
  348         ri->ri_ops.copyrows = rasops_copyrows;
  349         ri->ri_ops.copycols = rasops_copycols;
  350         ri->ri_ops.erasecols = rasops_erasecols;
  351         ri->ri_ops.eraserows = rasops_eraserows;
  352         ri->ri_ops.cursor = rasops_cursor;
  353         ri->ri_ops.unpack_attr = rasops_unpack_attr;
  354         ri->ri_do_cursor = rasops_do_cursor;
  355         ri->ri_updatecursor = NULL;
  356 
  357         if (ri->ri_depth < 8 || (ri->ri_flg & RI_FORCEMONO) != 0) {
  358                 ri->ri_ops.alloc_attr = rasops_alloc_mattr;
  359                 ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_REVERSE;
  360         } else {
  361                 ri->ri_ops.alloc_attr = rasops_alloc_cattr;
  362                 ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
  363                     WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
  364         }
  365 
  366         switch (ri->ri_depth) {
  367 #if NRASOPS1 > 0
  368         case 1:
  369                 rasops1_init(ri);
  370                 break;
  371 #endif
  372 #if NRASOPS2 > 0
  373         case 2:
  374                 rasops2_init(ri);
  375                 break;
  376 #endif
  377 #if NRASOPS4 > 0
  378         case 4:
  379                 rasops4_init(ri);
  380                 break;
  381 #endif
  382 #if NRASOPS8 > 0
  383         case 8:
  384                 rasops8_init(ri);
  385                 break;
  386 #endif
  387 #if NRASOPS15 > 0 || NRASOPS16 > 0
  388         case 15:
  389         case 16:
  390                 rasops15_init(ri);
  391                 break;
  392 #endif
  393 #if NRASOPS24 > 0
  394         case 24:
  395                 rasops24_init(ri);
  396                 break;
  397 #endif
  398 #if NRASOPS32 > 0
  399         case 32:
  400                 rasops32_init(ri);
  401                 break;
  402 #endif
  403         default:
  404                 ri->ri_flg &= ~RI_CFGDONE;
  405                 splx(s);
  406                 return (-1);
  407         }
  408 
  409 #if NRASOPS_ROTATION > 0
  410         if (ri->ri_flg & RI_ROTATE_CW) {
  411                 ri->ri_real_ops = ri->ri_ops;
  412                 ri->ri_ops.copycols = rasops_copycols_rotated;
  413                 ri->ri_ops.copyrows = rasops_copyrows_rotated;
  414                 ri->ri_ops.erasecols = rasops_erasecols_rotated;
  415                 ri->ri_ops.eraserows = rasops_eraserows_rotated;
  416                 ri->ri_ops.putchar = rasops_putchar_rotated;
  417         }
  418 #endif
  419 
  420         ri->ri_flg |= RI_CFGDONE;
  421         splx(s);
  422         return (0);
  423 }
  424 
  425 /*
  426  * Map a character.
  427  */
  428 int
  429 rasops_mapchar(cookie, c, cp)
  430         void *cookie;
  431         int c;
  432         u_int *cp;
  433 {
  434         struct rasops_info *ri;
  435 
  436         ri = (struct rasops_info *)cookie;
  437 
  438 #ifdef DIAGNOSTIC
  439         if (ri->ri_font == NULL)
  440                 panic("rasops_mapchar: no font selected");
  441 #endif
  442         if (ri->ri_font->encoding != WSDISPLAY_FONTENC_ISO) {
  443 
  444                 if ( (c = wsfont_map_unichar(ri->ri_font, c)) < 0) {
  445 
  446                         *cp = ' ';
  447                         return (0);
  448 
  449                 }
  450         }
  451 
  452 
  453         if (c < ri->ri_font->firstchar) {
  454                 *cp = ' ';
  455                 return (0);
  456         }
  457 
  458         if (c - ri->ri_font->firstchar >= ri->ri_font->numchars) {
  459                 *cp = ' ';
  460                 return (0);
  461         }
  462 
  463         *cp = c;
  464         return (5);
  465 }
  466 
  467 /*
  468  * Allocate a color attribute.
  469  */
  470 int
  471 rasops_alloc_cattr(cookie, fg, bg, flg, attr)
  472         void *cookie;
  473         int fg, bg, flg;
  474         long *attr;
  475 {
  476         int swap;
  477 
  478 #ifdef RASOPS_CLIPPING
  479         fg &= 7;
  480         bg &= 7;
  481 #endif
  482         if ((flg & WSATTR_BLINK) != 0)
  483                 return (EINVAL);
  484 
  485         if ((flg & WSATTR_WSCOLORS) == 0) {
  486                 fg = WSCOL_WHITE;
  487                 bg = WSCOL_BLACK;
  488         }
  489 
  490         if ((flg & WSATTR_REVERSE) != 0) {
  491                 swap = fg;
  492                 fg = bg;
  493                 bg = swap;
  494         }
  495 
  496         if ((flg & WSATTR_HILIT) != 0)
  497                 fg += 8;
  498 
  499         flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
  500 
  501         if (rasops_isgray[fg])
  502                 flg |= 2;
  503 
  504         if (rasops_isgray[bg])
  505                 flg |= 4;
  506 
  507         *attr = (bg << 16) | (fg << 24) | flg;
  508         return (0);
  509 }
  510 
  511 /*
  512  * Allocate a mono attribute.
  513  */
  514 int
  515 rasops_alloc_mattr(cookie, fg, bg, flg, attr)
  516         void *cookie;
  517         int fg, bg, flg;
  518         long *attr;
  519 {
  520         int swap;
  521 
  522         if ((flg & (WSATTR_BLINK | WSATTR_HILIT | WSATTR_WSCOLORS)) != 0)
  523                 return (EINVAL);
  524 
  525         fg = 1;
  526         bg = 0;
  527 
  528         if ((flg & WSATTR_REVERSE) != 0) {
  529                 swap = fg;
  530                 fg = bg;
  531                 bg = swap;
  532         }
  533 
  534         *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
  535         return (0);
  536 }
  537 
  538 /*
  539  * Copy rows.
  540  */
  541 void
  542 rasops_copyrows(cookie, src, dst, num)
  543         void *cookie;
  544         int src, dst, num;
  545 {
  546         int32_t *sp, *dp, *srp, *drp;
  547         struct rasops_info *ri;
  548         int n8, n1, cnt, delta;
  549 
  550         ri = (struct rasops_info *)cookie;
  551 
  552 #ifdef RASOPS_CLIPPING
  553         if (dst == src)
  554                 return;
  555 
  556         if (src < 0) {
  557                 num += src;
  558                 src = 0;
  559         }
  560 
  561         if ((src + num) > ri->ri_rows)
  562                 num = ri->ri_rows - src;
  563 
  564         if (dst < 0) {
  565                 num += dst;
  566                 dst = 0;
  567         }
  568 
  569         if ((dst + num) > ri->ri_rows)
  570                 num = ri->ri_rows - dst;
  571 
  572         if (num <= 0)
  573                 return;
  574 #endif
  575 
  576         num *= ri->ri_font->fontheight;
  577         n8 = ri->ri_emustride >> 5;
  578         n1 = (ri->ri_emustride >> 2) & 7;
  579 
  580         if (dst < src) {
  581                 srp = (int32_t *)(ri->ri_bits + src * ri->ri_yscale);
  582                 drp = (int32_t *)(ri->ri_bits + dst * ri->ri_yscale);
  583                 delta = ri->ri_stride;
  584         } else {
  585                 src = ri->ri_font->fontheight * src + num - 1;
  586                 dst = ri->ri_font->fontheight * dst + num - 1;
  587                 srp = (int32_t *)(ri->ri_bits + src * ri->ri_stride);
  588                 drp = (int32_t *)(ri->ri_bits + dst * ri->ri_stride);
  589                 delta = -ri->ri_stride;
  590         }
  591 
  592         while (num--) {
  593                 dp = drp;
  594                 sp = srp;
  595                 DELTA(drp, delta, int32_t *);
  596                 DELTA(srp, delta, int32_t *);
  597 
  598                 for (cnt = n8; cnt; cnt--) {
  599                         dp[0] = sp[0];
  600                         dp[1] = sp[1];
  601                         dp[2] = sp[2];
  602                         dp[3] = sp[3];
  603                         dp[4] = sp[4];
  604                         dp[5] = sp[5];
  605                         dp[6] = sp[6];
  606                         dp[7] = sp[7];
  607                         dp += 8;
  608                         sp += 8;
  609                 }
  610 
  611                 for (cnt = n1; cnt; cnt--)
  612                         *dp++ = *sp++;
  613         }
  614 }
  615 
  616 /*
  617  * Copy columns. This is slow, and hard to optimize due to alignment,
  618  * and the fact that we have to copy both left->right and right->left.
  619  * We simply cop-out here and use ovbcopy(), since it handles all of
  620  * these cases anyway.
  621  */
  622 void
  623 rasops_copycols(cookie, row, src, dst, num)
  624         void *cookie;
  625         int row, src, dst, num;
  626 {
  627         struct rasops_info *ri;
  628         u_char *sp, *dp;
  629         int height;
  630 
  631         ri = (struct rasops_info *)cookie;
  632 
  633 #ifdef RASOPS_CLIPPING
  634         if (dst == src)
  635                 return;
  636 
  637         /* Catches < 0 case too */
  638         if ((unsigned)row >= (unsigned)ri->ri_rows)
  639                 return;
  640 
  641         if (src < 0) {
  642                 num += src;
  643                 src = 0;
  644         }
  645 
  646         if ((src + num) > ri->ri_cols)
  647                 num = ri->ri_cols - src;
  648 
  649         if (dst < 0) {
  650                 num += dst;
  651                 dst = 0;
  652         }
  653 
  654         if ((dst + num) > ri->ri_cols)
  655                 num = ri->ri_cols - dst;
  656 
  657         if (num <= 0)
  658                 return;
  659 #endif
  660 
  661         num *= ri->ri_xscale;
  662         row *= ri->ri_yscale;
  663         height = ri->ri_font->fontheight;
  664 
  665         sp = ri->ri_bits + row + src * ri->ri_xscale;
  666         dp = ri->ri_bits + row + dst * ri->ri_xscale;
  667 
  668 #if NRASOPS_BSWAP > 0
  669         if (ri->ri_flg & RI_BSWAP) {
  670                 while (height--) {
  671                         slow_ovbcopy(sp, dp, num);
  672                         dp += ri->ri_stride;
  673                         sp += ri->ri_stride;
  674                 }
  675         } else
  676 #endif
  677         {
  678                 while (height--) {
  679                         ovbcopy(sp, dp, num);
  680                         dp += ri->ri_stride;
  681                         sp += ri->ri_stride;
  682                 }
  683         }
  684 }
  685 
  686 /*
  687  * Turn cursor off/on.
  688  */
  689 void
  690 rasops_cursor(cookie, on, row, col)
  691         void *cookie;
  692         int on, row, col;
  693 {
  694         struct rasops_info *ri;
  695 
  696         ri = (struct rasops_info *)cookie;
  697 
  698         /* Turn old cursor off */
  699         if ((ri->ri_flg & RI_CURSOR) != 0)
  700 #ifdef RASOPS_CLIPPING
  701                 if ((ri->ri_flg & RI_CURSORCLIP) == 0)
  702 #endif
  703                         ri->ri_do_cursor(ri);
  704 
  705         /* Select new cursor */
  706 #ifdef RASOPS_CLIPPING
  707         ri->ri_flg &= ~RI_CURSORCLIP;
  708 
  709         if (row < 0 || row >= ri->ri_rows)
  710                 ri->ri_flg |= RI_CURSORCLIP;
  711         else if (col < 0 || col >= ri->ri_cols)
  712                 ri->ri_flg |= RI_CURSORCLIP;
  713 #endif
  714         ri->ri_crow = row;
  715         ri->ri_ccol = col;
  716 
  717         if (ri->ri_updatecursor != NULL)
  718                 ri->ri_updatecursor(ri);
  719 
  720         if (on) {
  721                 ri->ri_flg |= RI_CURSOR;
  722 #ifdef RASOPS_CLIPPING
  723                 if ((ri->ri_flg & RI_CURSORCLIP) == 0)
  724 #endif
  725                         ri->ri_do_cursor(ri);
  726         } else
  727                 ri->ri_flg &= ~RI_CURSOR;
  728 }
  729 
  730 /*
  731  * Make the device colormap
  732  */
  733 void
  734 rasops_init_devcmap(ri)
  735         struct rasops_info *ri;
  736 {
  737         int i;
  738 #if NRASOPS15 > 0 || NRASOPS16 > 0 || NRASOPS24 > 0 || NRASOPS32 > 0
  739         const u_char *p;
  740 #endif
  741 #if NRASOPS4 > 0 || NRASOPS15 > 0 || NRASOPS16 > 0 || NRASOPS24 > 0 || NRASOPS32 > 0
  742         int c;
  743 #endif
  744 
  745         switch (ri->ri_depth) {
  746 #if NRASOPS1 > 0
  747         case 1:
  748                 ri->ri_devcmap[0] = 0;
  749                 for (i = 1; i < 16; i++)
  750                         ri->ri_devcmap[i] = 0xffffffff;
  751                 return;
  752 #endif
  753 #if NRASOPS2 > 0
  754         case 2:
  755                 for (i = 1; i < 15; i++)
  756                         ri->ri_devcmap[i] = 0xaaaaaaaa;
  757 
  758                 ri->ri_devcmap[0] = 0;
  759                 ri->ri_devcmap[8] = 0x55555555;
  760                 ri->ri_devcmap[15] = 0xffffffff;
  761                 return;
  762 #endif
  763 #if NRASOPS4 > 0
  764         case 4:
  765                 for (i = 0; i < 16; i++) {
  766                         c = i | (i << 4);
  767                         ri->ri_devcmap[i] = c | (c<<8) | (c<<16) | (c<<24);
  768                 }
  769                 return;
  770 #endif
  771 #if NRASOPS8 > 0
  772         case 8:
  773                 for (i = 0; i < 16; i++)
  774                         ri->ri_devcmap[i] = i | (i<<8) | (i<<16) | (i<<24);
  775                 return;
  776 #endif
  777         default:
  778                 break;
  779         }
  780 
  781 #if NRASOPS15 > 0 || NRASOPS16 > 0 || NRASOPS24 > 0 || NRASOPS32 > 0
  782         p = rasops_cmap;
  783 
  784         for (i = 0; i < 16; i++) {
  785                 if (ri->ri_rnum <= 8)
  786                         c = (*p >> (8 - ri->ri_rnum)) << ri->ri_rpos;
  787                 else
  788                         c = (*p << (ri->ri_rnum - 8)) << ri->ri_rpos;
  789                 p++;
  790 
  791                 if (ri->ri_gnum <= 8)
  792                         c |= (*p >> (8 - ri->ri_gnum)) << ri->ri_gpos;
  793                 else
  794                         c |= (*p << (ri->ri_gnum - 8)) << ri->ri_gpos;
  795                 p++;
  796 
  797                 if (ri->ri_bnum <= 8)
  798                         c |= (*p >> (8 - ri->ri_bnum)) << ri->ri_bpos;
  799                 else
  800                         c |= (*p << (ri->ri_bnum - 8)) << ri->ri_bpos;
  801                 p++;
  802 
  803                 /* Fill the word for generic routines, which want this */
  804                 if (ri->ri_depth == 24)
  805                         c = c | ((c & 0xff) << 24);
  806                 else if (ri->ri_depth <= 16)
  807                         c = c | (c << 16);
  808 
  809                 /* 24bpp does bswap on the fly. {32,16,15}bpp do it here. */
  810 #if NRASOPS_BSWAP > 0
  811                 if ((ri->ri_flg & RI_BSWAP) == 0)
  812                         ri->ri_devcmap[i] = c;
  813                 else if (ri->ri_depth == 32)
  814                         ri->ri_devcmap[i] = swap32(c);
  815                 else if (ri->ri_depth == 16 || ri->ri_depth == 15)
  816                         ri->ri_devcmap[i] = swap16(c);
  817                 else
  818                         ri->ri_devcmap[i] = c;
  819 #else
  820                 ri->ri_devcmap[i] = c;
  821 #endif
  822         }
  823 #endif
  824 }
  825 
  826 /*
  827  * Unpack a rasops attribute
  828  */
  829 void
  830 rasops_unpack_attr(cookie, attr, fg, bg, underline)
  831         void *cookie;
  832         long attr;
  833         int *fg, *bg, *underline;
  834 {
  835         *fg = ((u_int)attr >> 24) & 0xf;
  836         *bg = ((u_int)attr >> 16) & 0xf;
  837         if (underline != NULL)
  838                 *underline = (u_int)attr & 1;
  839 }
  840 
  841 /*
  842  * Erase rows
  843  */
  844 void
  845 rasops_eraserows(cookie, row, num, attr)
  846         void *cookie;
  847         int row, num;
  848         long attr;
  849 {
  850         struct rasops_info *ri;
  851         int np, nw, cnt, delta;
  852         int32_t *dp, clr;
  853 
  854         ri = (struct rasops_info *)cookie;
  855 
  856 #ifdef RASOPS_CLIPPING
  857         if (row < 0) {
  858                 num += row;
  859                 row = 0;
  860         }
  861 
  862         if ((row + num) > ri->ri_rows)
  863                 num = ri->ri_rows - row;
  864 
  865         if (num <= 0)
  866                 return;
  867 #endif
  868 
  869         clr = ri->ri_devcmap[(attr >> 16) & 0xf];
  870 
  871         /*
  872          * XXX The wsdisplay_emulops interface seems a little deficient in
  873          * that there is no way to clear the *entire* screen. We provide a
  874          * workaround here: if the entire console area is being cleared, and
  875          * the RI_FULLCLEAR flag is set, clear the entire display.
  876          */
  877         if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
  878                 np = ri->ri_stride >> 5;
  879                 nw = (ri->ri_stride >> 2) & 7;
  880                 num = ri->ri_height;
  881                 dp = (int32_t *)ri->ri_origbits;
  882                 delta = 0;
  883         } else {
  884                 np = ri->ri_emustride >> 5;
  885                 nw = (ri->ri_emustride >> 2) & 7;
  886                 num *= ri->ri_font->fontheight;
  887                 dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
  888                 delta = ri->ri_delta;
  889         }
  890 
  891         while (num--) {
  892                 for (cnt = np; cnt; cnt--) {
  893                         dp[0] = clr;
  894                         dp[1] = clr;
  895                         dp[2] = clr;
  896                         dp[3] = clr;
  897                         dp[4] = clr;
  898                         dp[5] = clr;
  899                         dp[6] = clr;
  900                         dp[7] = clr;
  901                         dp += 8;
  902                 }
  903 
  904                 for (cnt = nw; cnt; cnt--) {
  905                         *(int32_t *)dp = clr;
  906                         DELTA(dp, 4, int32_t *);
  907                 }
  908 
  909                 DELTA(dp, delta, int32_t *);
  910         }
  911 }
  912 
  913 /*
  914  * Actually turn the cursor on or off. This does the dirty work for
  915  * rasops_cursor().
  916  */
  917 void
  918 rasops_do_cursor(ri)
  919         struct rasops_info *ri;
  920 {
  921         int full1, height, cnt, slop1, slop2, row, col;
  922         u_char *dp, *rp;
  923 
  924 #if NRASOPS_ROTATION > 0
  925         if (ri->ri_flg & RI_ROTATE_CW) {
  926                 /* Rotate rows/columns */
  927                 row = ri->ri_ccol;
  928                 col = ri->ri_rows - ri->ri_crow - 1;
  929         } else
  930 #endif
  931         {
  932                 row = ri->ri_crow;
  933                 col = ri->ri_ccol;
  934         }
  935 
  936         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  937         height = ri->ri_font->fontheight;
  938         slop1 = (4 - ((long)rp & 3)) & 3;
  939 
  940         if (slop1 > ri->ri_xscale)
  941                 slop1 = ri->ri_xscale;
  942 
  943         slop2 = (ri->ri_xscale - slop1) & 3;
  944         full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
  945 
  946         if ((slop1 | slop2) == 0) {
  947                 /* A common case */
  948                 while (height--) {
  949                         dp = rp;
  950                         rp += ri->ri_stride;
  951 
  952                         for (cnt = full1; cnt; cnt--) {
  953                                 *(int32_t *)dp ^= ~0;
  954                                 dp += 4;
  955                         }
  956                 }
  957         } else {
  958                 /* XXX this is stupid.. use masks instead */
  959                 while (height--) {
  960                         dp = rp;
  961                         rp += ri->ri_stride;
  962 
  963                         if (slop1 & 1)
  964                                 *dp++ ^= ~0;
  965 
  966                         if (slop1 & 2) {
  967                                 *(int16_t *)dp ^= ~0;
  968                                 dp += 2;
  969                         }
  970 
  971                         for (cnt = full1; cnt; cnt--) {
  972                                 *(int32_t *)dp ^= ~0;
  973                                 dp += 4;
  974                         }
  975 
  976                         if (slop2 & 1)
  977                                 *dp++ ^= ~0;
  978 
  979                         if (slop2 & 2)
  980                                 *(int16_t *)dp ^= ~0;
  981                 }
  982         }
  983 }
  984 
  985 /*
  986  * Erase columns.
  987  */
  988 void
  989 rasops_erasecols(cookie, row, col, num, attr)
  990         void *cookie;
  991         int row, col, num;
  992         long attr;
  993 {
  994         int n8, height, cnt, slop1, slop2, clr;
  995         struct rasops_info *ri;
  996         int32_t *rp, *dp;
  997 
  998         ri = (struct rasops_info *)cookie;
  999 
 1000 #ifdef RASOPS_CLIPPING
 1001         if ((unsigned)row >= (unsigned)ri->ri_rows)
 1002                 return;
 1003 
 1004         if (col < 0) {
 1005                 num += col;
 1006                 col = 0;
 1007         }
 1008 
 1009         if ((col + num) > ri->ri_cols)
 1010                 num = ri->ri_cols - col;
 1011 
 1012         if (num <= 0)
 1013                 return;
 1014 #endif
 1015 
 1016         num = num * ri->ri_xscale;
 1017         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
 1018         height = ri->ri_font->fontheight;
 1019         clr = ri->ri_devcmap[(attr >> 16) & 0xf];
 1020 
 1021         /* Don't bother using the full loop for <= 32 pels */
 1022         if (num <= 32) {
 1023                 if (((num | ri->ri_xscale) & 3) == 0) {
 1024                         /* Word aligned blt */
 1025                         num >>= 2;
 1026 
 1027                         while (height--) {
 1028                                 dp = rp;
 1029                                 DELTA(rp, ri->ri_stride, int32_t *);
 1030 
 1031                                 for (cnt = num; cnt; cnt--)
 1032                                         *dp++ = clr;
 1033                         }
 1034                 } else if (((num | ri->ri_xscale) & 1) == 0) {
 1035                         /*
 1036                          * Halfword aligned blt. This is needed so the
 1037                          * 15/16 bit ops can use this function.
 1038                          */
 1039                         num >>= 1;
 1040 
 1041                         while (height--) {
 1042                                 dp = rp;
 1043                                 DELTA(rp, ri->ri_stride, int32_t *);
 1044 
 1045                                 for (cnt = num; cnt; cnt--) {
 1046                                         *(int16_t *)dp = clr;
 1047                                         DELTA(dp, 2, int32_t *);
 1048                                 }
 1049                         }
 1050                 } else {
 1051                         while (height--) {
 1052                                 dp = rp;
 1053                                 DELTA(rp, ri->ri_stride, int32_t *);
 1054 
 1055                                 for (cnt = num; cnt; cnt--) {
 1056                                         *(u_char *)dp = clr;
 1057                                         DELTA(dp, 1, int32_t *);
 1058                                 }
 1059                         }
 1060                 }
 1061 
 1062                 return;
 1063         }
 1064 
 1065         slop1 = (4 - ((long)rp & 3)) & 3;
 1066         slop2 = (num - slop1) & 3;
 1067         num -= slop1 + slop2;
 1068         n8 = num >> 5;
 1069         num = (num >> 2) & 7;
 1070 
 1071         while (height--) {
 1072                 dp = rp;
 1073                 DELTA(rp, ri->ri_stride, int32_t *);
 1074 
 1075                 /* Align span to 4 bytes */
 1076                 if (slop1 & 1) {
 1077                         *(u_char *)dp = clr;
 1078                         DELTA(dp, 1, int32_t *);
 1079                 }
 1080 
 1081                 if (slop1 & 2) {
 1082                         *(int16_t *)dp = clr;
 1083                         DELTA(dp, 2, int32_t *);
 1084                 }
 1085 
 1086                 /* Write 32 bytes per loop */
 1087                 for (cnt = n8; cnt; cnt--) {
 1088                         dp[0] = clr;
 1089                         dp[1] = clr;
 1090                         dp[2] = clr;
 1091                         dp[3] = clr;
 1092                         dp[4] = clr;
 1093                         dp[5] = clr;
 1094                         dp[6] = clr;
 1095                         dp[7] = clr;
 1096                         dp += 8;
 1097                 }
 1098 
 1099                 /* Write 4 bytes per loop */
 1100                 for (cnt = num; cnt; cnt--)
 1101                         *dp++ = clr;
 1102 
 1103                 /* Write unaligned trailing slop */
 1104                 if (slop2 & 1) {
 1105                         *(u_char *)dp = clr;
 1106                         DELTA(dp, 1, int32_t *);
 1107                 }
 1108 
 1109                 if (slop2 & 2)
 1110                         *(int16_t *)dp = clr;
 1111         }
 1112 }
 1113 
 1114 #if NRASOPS_ROTATION > 0
 1115 /*
 1116  * Quarter clockwise rotation routines (originally intended for the
 1117  * built-in Zaurus C3x00 display in 16bpp).
 1118  */
 1119 
 1120 #include <sys/malloc.h>
 1121 
 1122 void
 1123 rasops_rotate_font(int *cookie)
 1124 {
 1125         struct rotatedfont *f;
 1126         int ncookie;
 1127 
 1128         SLIST_FOREACH(f, &rotatedfonts, rf_next) {
 1129                 if (f->rf_cookie == *cookie) {
 1130                         *cookie = f->rf_rotated;
 1131                         return;
 1132                 }
 1133         }
 1134 
 1135         /*
 1136          * We did not find a rotated version of this font. Ask the wsfont
 1137          * code to compute one for us.
 1138          */
 1139 
 1140         f = malloc(sizeof(struct rotatedfont), M_DEVBUF, M_WAITOK);
 1141         if (f == NULL)
 1142                 return;
 1143 
 1144         if ((ncookie = wsfont_rotate(*cookie)) == -1)
 1145                 return;
 1146 
 1147         f->rf_cookie = *cookie;
 1148         f->rf_rotated = ncookie;
 1149         SLIST_INSERT_HEAD(&rotatedfonts, f, rf_next);
 1150 
 1151         *cookie = ncookie;
 1152 }
 1153 
 1154 void
 1155 rasops_copychar(cookie, srcrow, dstrow, srccol, dstcol)
 1156         void *cookie;
 1157         int srcrow, dstrow, srccol, dstcol;
 1158 {
 1159         struct rasops_info *ri;
 1160         u_char *sp, *dp;
 1161         int height;
 1162         int r_srcrow, r_dstrow, r_srccol, r_dstcol;
 1163 
 1164         ri = (struct rasops_info *)cookie;
 1165 
 1166         r_srcrow = srccol;
 1167         r_dstrow = dstcol;
 1168         r_srccol = ri->ri_rows - srcrow - 1;
 1169         r_dstcol = ri->ri_rows - dstrow - 1;
 1170 
 1171         r_srcrow *= ri->ri_yscale;
 1172         r_dstrow *= ri->ri_yscale;
 1173         height = ri->ri_font->fontheight;
 1174 
 1175         sp = ri->ri_bits + r_srcrow + r_srccol * ri->ri_xscale;
 1176         dp = ri->ri_bits + r_dstrow + r_dstcol * ri->ri_xscale;
 1177 
 1178 #if NRASOPS_BSWAP > 0
 1179         if (ri->ri_flg & RI_BSWAP) {
 1180                 while (height--) {
 1181                         slow_ovbcopy(sp, dp, ri->ri_xscale);
 1182                         dp += ri->ri_stride;
 1183                         sp += ri->ri_stride;
 1184                 }
 1185         } else
 1186 #endif
 1187         {
 1188                 while (height--) {
 1189                         ovbcopy(sp, dp, ri->ri_xscale);
 1190                         dp += ri->ri_stride;
 1191                         sp += ri->ri_stride;
 1192                 }
 1193         }
 1194 }
 1195 
 1196 void
 1197 rasops_putchar_rotated(cookie, row, col, uc, attr)
 1198         void *cookie;
 1199         int row, col;
 1200         u_int uc;
 1201         long attr;
 1202 {
 1203         struct rasops_info *ri;
 1204         u_char *rp;
 1205         int height;
 1206 
 1207         ri = (struct rasops_info *)cookie;
 1208 
 1209         /* Do rotated char sans (side)underline */
 1210         ri->ri_real_ops.putchar(cookie, col, ri->ri_rows - row - 1, uc,
 1211             attr & ~1);
 1212 
 1213         /* Do rotated underline */
 1214         rp = ri->ri_bits + col * ri->ri_yscale + (ri->ri_rows - row - 1) * 
 1215             ri->ri_xscale;
 1216         height = ri->ri_font->fontheight;
 1217 
 1218         /* XXX this assumes 16-bit color depth */
 1219         if ((attr & 1) != 0) {
 1220                 int16_t c = (int16_t)ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
 1221 
 1222                 while (height--) {
 1223                         *(int16_t *)rp = c;
 1224                         rp += ri->ri_stride;
 1225                 }
 1226         }
 1227 }
 1228 
 1229 void
 1230 rasops_erasecols_rotated(cookie, row, col, num, attr)
 1231         void *cookie;
 1232         int row, col, num;
 1233         long attr;
 1234 {
 1235         struct rasops_info *ri;
 1236         int i;
 1237 
 1238         ri = (struct rasops_info *)cookie;
 1239 
 1240         for (i = col; i < col + num; i++)
 1241                 ri->ri_ops.putchar(cookie, row, i, ' ', attr);
 1242 }
 1243 
 1244 /* XXX: these could likely be optimised somewhat. */
 1245 void
 1246 rasops_copyrows_rotated(cookie, src, dst, num)
 1247         void *cookie;
 1248         int src, dst, num;
 1249 {
 1250         struct rasops_info *ri = (struct rasops_info *)cookie;
 1251         int col, roff;
 1252 
 1253         if (src > dst)
 1254                 for (roff = 0; roff < num; roff++)
 1255                         for (col = 0; col < ri->ri_cols; col++)
 1256                                 rasops_copychar(cookie, src + roff, dst + roff,
 1257                                     col, col);
 1258         else
 1259                 for (roff = num - 1; roff >= 0; roff--)
 1260                         for (col = 0; col < ri->ri_cols; col++)
 1261                                 rasops_copychar(cookie, src + roff, dst + roff,
 1262                                     col, col);
 1263 }
 1264 
 1265 void
 1266 rasops_copycols_rotated(cookie, row, src, dst, num)
 1267         void *cookie;
 1268         int row, src, dst, num;
 1269 {
 1270         int coff;
 1271 
 1272         if (src > dst)
 1273                 for (coff = 0; coff < num; coff++)
 1274                         rasops_copychar(cookie, row, row, src + coff, dst + coff);
 1275         else
 1276                 for (coff = num - 1; coff >= 0; coff--)
 1277                         rasops_copychar(cookie, row, row, src + coff, dst + coff);
 1278 }
 1279 
 1280 void
 1281 rasops_eraserows_rotated(cookie, row, num, attr)
 1282         void *cookie;
 1283         int row, num;
 1284         long attr;
 1285 {
 1286         struct rasops_info *ri;
 1287         int col, rn;
 1288 
 1289         ri = (struct rasops_info *)cookie;
 1290 
 1291         for (rn = row; rn < row + num; rn++)
 1292                 for (col = 0; col < ri->ri_cols; col++)
 1293                         ri->ri_ops.putchar(cookie, rn, col, ' ', attr);
 1294 }
 1295 #endif  /* NRASOPS_ROTATION */
 1296 
 1297 #if NRASOPS_BSWAP > 0
 1298 /*
 1299  * Strictly byte-only ovbcopy() version, to be used with RI_BSWAP, as the
 1300  * regular ovbcopy() may want to optimize things by doing larger-than-byte
 1301  * reads or write. This may confuse things if src and dst have different
 1302  * alignments.
 1303  */
 1304 void
 1305 slow_ovbcopy(void *s, void *d, size_t len)
 1306 {
 1307         u_int8_t *src = s;
 1308         u_int8_t *dst = d;
 1309 
 1310         if ((vaddr_t)dst <= (vaddr_t)src) {
 1311                 while (len-- != 0)
 1312                         *dst++ = *src++;
 1313         } else {
 1314                 src += len;
 1315                 dst += len;
 1316                 if (len != 0)
 1317                         while (--len != 0)
 1318                                 *--dst = *--src;
 1319         }
 1320 }
 1321 #endif  /* NRASOPS_BSWAP */

/* [<][>][^][v][top][bottom][index][help] */