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/tc/sfb.c

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

    1 /* $NetBSD: sfb.c,v 1.64 2003/12/20 09:17:28 tsutsui Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1998, 1999 Tohru Nishimura.  All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Tohru Nishimura
   17  *      for the NetBSD Project.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: sfb.c,v 1.64 2003/12/20 09:17:28 tsutsui Exp $");
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/kernel.h>
   39 #include <sys/device.h>
   40 #include <sys/malloc.h>
   41 #include <sys/buf.h>
   42 #include <sys/ioctl.h>
   43 
   44 #include <machine/bus.h>
   45 #include <machine/intr.h>
   46 
   47 #include <dev/wscons/wsconsio.h>
   48 #include <dev/wscons/wsdisplayvar.h>
   49 
   50 #include <dev/rasops/rasops.h>
   51 #include <dev/wsfont/wsfont.h>
   52 
   53 #include <dev/tc/tcvar.h>
   54 #include <dev/ic/bt459reg.h>    
   55 #include <dev/tc/sfbreg.h>
   56 
   57 #include <uvm/uvm_extern.h>
   58 
   59 #if defined(pmax)
   60 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
   61 #endif
   62 
   63 #if defined(alpha)
   64 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
   65 #endif
   66 
   67 /*
   68  * N.B., Bt459 registers are 8bit width.  Some of TC framebuffers have
   69  * obscure register layout such as 2nd and 3rd Bt459 registers are
   70  * adjacent each other in a word, i.e.,
   71  *      struct bt459triplet {
   72  *              struct {
   73  *                      u_int8_t u0;
   74  *                      u_int8_t u1;
   75  *                      u_int8_t u2;
   76  *                      unsigned :8;
   77  *              } bt_lo;
   78  *
   79  * Although HX has single Bt459, 32bit R/W can be done w/o any trouble.
   80  *      struct bt459reg {
   81  *                 u_int32_t       bt_lo;
   82  *                 u_int32_t       bt_hi;
   83  *                 u_int32_t       bt_reg;
   84  *                 u_int32_t       bt_cmap;
   85  *      };
   86  */
   87 
   88 /* Bt459 hardware registers, memory-mapped in 32bit stride */
   89 #define bt_lo   0x0
   90 #define bt_hi   0x4
   91 #define bt_reg  0x8
   92 #define bt_cmap 0xc
   93 
   94 #define REGWRITE32(p,i,v) do {                                  \
   95         *(volatile u_int32_t *)((p) + (i)) = (v); tc_wmb();     \
   96     } while (/* CONSTCOND */ 0)
   97 #define SFBWRITE32(p,i,v) do {                                  \
   98         *(volatile u_int32_t *)((p) + (i)) = (v);               \
   99     } while (/* CONSTCOND */ 0)
  100 #define MEMWRITE32(p,v) do {                                    \
  101         *(volatile u_int32_t *)(p) = (v);                       \
  102     } while (/* CONSTCOND */ 0)
  103 
  104 #define VDACSELECT(p,r) do {                                    \
  105         REGWRITE32(p, bt_lo, 0xff & (r));                       \
  106         REGWRITE32(p, bt_hi, 0x0f & ((r)>>8));                  \
  107    } while (/* CONSTCOND */ 0)
  108 
  109 struct hwcmap256 {
  110 #define CMAP_SIZE       256     /* 256 R/G/B entries */
  111         u_int8_t r[CMAP_SIZE];
  112         u_int8_t g[CMAP_SIZE];
  113         u_int8_t b[CMAP_SIZE];
  114 };
  115 
  116 struct hwcursor64 {
  117         struct wsdisplay_curpos cc_pos;
  118         struct wsdisplay_curpos cc_hot;
  119         struct wsdisplay_curpos cc_size;
  120         struct wsdisplay_curpos cc_magic;
  121 #define CURSOR_MAX_SIZE 64
  122         u_int8_t cc_color[6];
  123         u_int64_t cc_image[CURSOR_MAX_SIZE];
  124         u_int64_t cc_mask[CURSOR_MAX_SIZE];
  125 };
  126 
  127 struct sfb_softc {
  128         struct device sc_dev;
  129         vaddr_t sc_vaddr;
  130         size_t sc_size;
  131         struct rasops_info *sc_ri;
  132         struct hwcmap256 sc_cmap;       /* software copy of colormap */
  133         struct hwcursor64 sc_cursor;    /* software copy of cursor */
  134         int sc_blanked;                 /* video visibility disabled */
  135         int sc_curenb;                  /* cursor sprite enabled */
  136         int sc_changed;                 /* need update of hardware */
  137 #define WSDISPLAY_CMAP_DOLUT    0x20
  138         int nscreens;
  139 };
  140 
  141 #define HX_MAGIC_X      368
  142 #define HX_MAGIC_Y      38
  143 
  144 static int  sfbmatch(struct device *, struct cfdata *, void *);
  145 static void sfbattach(struct device *, struct device *, void *);
  146 
  147 CFATTACH_DECL(sfb, sizeof(struct sfb_softc),
  148     sfbmatch, sfbattach, NULL, NULL);
  149 
  150 static void sfb_common_init(struct rasops_info *);
  151 static struct rasops_info sfb_console_ri;
  152 static tc_addr_t sfb_consaddr;
  153 
  154 static void sfb_putchar(void *, int, int, u_int, long);
  155 static void sfb_erasecols(void *, int, int, int, long);
  156 static void sfb_eraserows(void *, int, int, long);
  157 static void sfb_copyrows(void *, int, int, int);
  158 static void sfb_do_cursor(struct rasops_info *);
  159 #if 0
  160 static void sfb_copycols(void *, int, int, int, int);
  161 #endif
  162 
  163 static struct wsscreen_descr sfb_stdscreen = {
  164         "std", 0, 0,
  165         0, /* textops */
  166         0, 0,
  167         WSSCREEN_REVERSE
  168 };
  169 
  170 static const struct wsscreen_descr *_sfb_scrlist[] = {
  171         &sfb_stdscreen,
  172 };
  173 
  174 static const struct wsscreen_list sfb_screenlist = {
  175         sizeof(_sfb_scrlist) / sizeof(struct wsscreen_descr *), _sfb_scrlist
  176 };
  177 
  178 static int      sfbioctl(void *, u_long, caddr_t, int, struct proc *);
  179 static paddr_t  sfbmmap(void *, off_t, int);
  180 
  181 static int      sfb_alloc_screen(void *, const struct wsscreen_descr *,
  182                                       void **, int *, int *, long *);
  183 static void     sfb_free_screen(void *, void *);
  184 static int      sfb_show_screen(void *, void *, int,
  185                                      void (*) (void *, int, int), void *);
  186 
  187 static const struct wsdisplay_accessops sfb_accessops = {
  188         sfbioctl,
  189         sfbmmap,
  190         sfb_alloc_screen,
  191         sfb_free_screen,
  192         sfb_show_screen,
  193         0 /* load_font */
  194 };
  195 
  196 int  sfb_cnattach(tc_addr_t);
  197 static int  sfbintr(void *);
  198 static void sfbhwinit(caddr_t);
  199 static void sfb_cmap_init(struct sfb_softc *);
  200 static void sfb_screenblank(struct sfb_softc *, int);
  201 
  202 static int  get_cmap(struct sfb_softc *, struct wsdisplay_cmap *);
  203 static int  set_cmap(struct sfb_softc *, struct wsdisplay_cmap *);
  204 static int  set_cursor(struct sfb_softc *, struct wsdisplay_cursor *);
  205 static int  get_cursor(struct sfb_softc *, struct wsdisplay_cursor *);
  206 static void set_curpos(struct sfb_softc *, struct wsdisplay_curpos *);
  207 
  208 /*
  209  * Compose 2 bit/pixel cursor image.  Bit order will be reversed.
  210  *   M M M M I I I I            M I M I M I M I
  211  *      [ before ]                 [ after ]
  212  *   3 2 1 0 3 2 1 0            0 0 1 1 2 2 3 3
  213  *   7 6 5 4 7 6 5 4            4 4 5 5 6 6 7 7
  214  */
  215 static const u_int8_t shuffle[256] = {
  216         0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
  217         0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55,
  218         0x80, 0xc0, 0x90, 0xd0, 0x84, 0xc4, 0x94, 0xd4,
  219         0x81, 0xc1, 0x91, 0xd1, 0x85, 0xc5, 0x95, 0xd5,
  220         0x20, 0x60, 0x30, 0x70, 0x24, 0x64, 0x34, 0x74,
  221         0x21, 0x61, 0x31, 0x71, 0x25, 0x65, 0x35, 0x75,
  222         0xa0, 0xe0, 0xb0, 0xf0, 0xa4, 0xe4, 0xb4, 0xf4,
  223         0xa1, 0xe1, 0xb1, 0xf1, 0xa5, 0xe5, 0xb5, 0xf5,
  224         0x08, 0x48, 0x18, 0x58, 0x0c, 0x4c, 0x1c, 0x5c,
  225         0x09, 0x49, 0x19, 0x59, 0x0d, 0x4d, 0x1d, 0x5d,
  226         0x88, 0xc8, 0x98, 0xd8, 0x8c, 0xcc, 0x9c, 0xdc,
  227         0x89, 0xc9, 0x99, 0xd9, 0x8d, 0xcd, 0x9d, 0xdd,
  228         0x28, 0x68, 0x38, 0x78, 0x2c, 0x6c, 0x3c, 0x7c,
  229         0x29, 0x69, 0x39, 0x79, 0x2d, 0x6d, 0x3d, 0x7d,
  230         0xa8, 0xe8, 0xb8, 0xf8, 0xac, 0xec, 0xbc, 0xfc,
  231         0xa9, 0xe9, 0xb9, 0xf9, 0xad, 0xed, 0xbd, 0xfd,
  232         0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56,
  233         0x03, 0x43, 0x13, 0x53, 0x07, 0x47, 0x17, 0x57,
  234         0x82, 0xc2, 0x92, 0xd2, 0x86, 0xc6, 0x96, 0xd6,
  235         0x83, 0xc3, 0x93, 0xd3, 0x87, 0xc7, 0x97, 0xd7,
  236         0x22, 0x62, 0x32, 0x72, 0x26, 0x66, 0x36, 0x76,
  237         0x23, 0x63, 0x33, 0x73, 0x27, 0x67, 0x37, 0x77,
  238         0xa2, 0xe2, 0xb2, 0xf2, 0xa6, 0xe6, 0xb6, 0xf6,
  239         0xa3, 0xe3, 0xb3, 0xf3, 0xa7, 0xe7, 0xb7, 0xf7,
  240         0x0a, 0x4a, 0x1a, 0x5a, 0x0e, 0x4e, 0x1e, 0x5e,
  241         0x0b, 0x4b, 0x1b, 0x5b, 0x0f, 0x4f, 0x1f, 0x5f,
  242         0x8a, 0xca, 0x9a, 0xda, 0x8e, 0xce, 0x9e, 0xde,
  243         0x8b, 0xcb, 0x9b, 0xdb, 0x8f, 0xcf, 0x9f, 0xdf,
  244         0x2a, 0x6a, 0x3a, 0x7a, 0x2e, 0x6e, 0x3e, 0x7e,
  245         0x2b, 0x6b, 0x3b, 0x7b, 0x2f, 0x6f, 0x3f, 0x7f,
  246         0xaa, 0xea, 0xba, 0xfa, 0xae, 0xee, 0xbe, 0xfe,
  247         0xab, 0xeb, 0xbb, 0xfb, 0xaf, 0xef, 0xbf, 0xff,
  248 };
  249 
  250 static int
  251 sfbmatch(parent, match, aux)
  252         struct device *parent;
  253         struct cfdata *match;
  254         void *aux;
  255 {
  256         struct tc_attach_args *ta = aux;
  257 
  258         if (strncmp("PMAGB-BA", ta->ta_modname, TC_ROM_LLEN) != 0)
  259                 return (0);
  260         return (1);
  261 }
  262 
  263 static void
  264 sfbattach(parent, self, aux)
  265         struct device *parent, *self;
  266         void *aux;
  267 {
  268         struct sfb_softc *sc = (struct sfb_softc *)self;
  269         struct tc_attach_args *ta = aux;
  270         struct rasops_info *ri;
  271         struct wsemuldisplaydev_attach_args waa;
  272         caddr_t asic;
  273         int console;
  274 
  275         console = (ta->ta_addr == sfb_consaddr);
  276         if (console) {
  277                 sc->sc_ri = ri = &sfb_console_ri;
  278                 sc->nscreens = 1;
  279         }
  280         else {
  281                 MALLOC(ri, struct rasops_info *, sizeof(struct rasops_info),
  282                         M_DEVBUF, M_NOWAIT);
  283                 if (ri == NULL) {
  284                         printf(": can't alloc memory\n");
  285                         return;
  286                 }
  287                 memset(ri, 0, sizeof(struct rasops_info));
  288 
  289                 ri->ri_hw = (void *)ta->ta_addr;
  290                 sfb_common_init(ri);
  291                 sc->sc_ri = ri;
  292         }
  293         printf(": %dx%d, %dbpp\n", ri->ri_width, ri->ri_height, ri->ri_depth);
  294 
  295         sfb_cmap_init(sc);
  296 
  297         sc->sc_vaddr = ta->ta_addr;
  298         sc->sc_cursor.cc_magic.x = HX_MAGIC_X;
  299         sc->sc_cursor.cc_magic.y = HX_MAGIC_Y;
  300         sc->sc_blanked = sc->sc_curenb = 0;
  301 
  302         tc_intr_establish(parent, ta->ta_cookie, IPL_TTY, sfbintr, sc);
  303 
  304         asic = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
  305         
  306         SFBWRITE32(asic, SFB_ASIC_CLEAR_INTR, 0);
  307         SFBWRITE32(asic, SFB_ASIC_ENABLE_INTR, 1);
  308 
  309         waa.console = console;
  310         waa.scrdata = &sfb_screenlist;
  311         waa.accessops = &sfb_accessops;
  312         waa.accesscookie = sc;
  313 
  314         config_found(self, &waa, wsemuldisplaydevprint);
  315 }
  316 
  317 static void
  318 sfb_cmap_init(sc)
  319         struct sfb_softc *sc;
  320 {
  321         struct hwcmap256 *cm;
  322         const u_int8_t *p;
  323         int index;
  324 
  325         cm = &sc->sc_cmap;
  326         p = rasops_cmap;
  327         for (index = 0; index < CMAP_SIZE; index++, p += 3) {
  328                 cm->r[index] = p[0];
  329                 cm->g[index] = p[1];
  330                 cm->b[index] = p[2];
  331         }
  332 }
  333 
  334 static void
  335 sfb_common_init(ri)
  336         struct rasops_info *ri;
  337 {
  338         caddr_t base, asic;
  339         int hsetup, vsetup, vbase, cookie;
  340 
  341         base = (caddr_t)ri->ri_hw;
  342         asic = base + SFB_ASIC_OFFSET;
  343         hsetup = *(u_int32_t *)(asic + SFB_ASIC_VIDEO_HSETUP);
  344         vsetup = *(u_int32_t *)(asic + SFB_ASIC_VIDEO_VSETUP);
  345 
  346         vbase = 1;
  347         SFBWRITE32(asic, SFB_ASIC_VIDEO_BASE, vbase);
  348         SFBWRITE32(asic, SFB_ASIC_PLANEMASK, ~0);
  349         SFBWRITE32(asic, SFB_ASIC_PIXELMASK, ~0);
  350         SFBWRITE32(asic, SFB_ASIC_MODE, 0);     /* MODE_SIMPLE */
  351         SFBWRITE32(asic, SFB_ASIC_ROP, 3);      /* ROP_COPY */
  352         SFBWRITE32(asic, 0x180000, 0);          /* Bt459 reset */
  353 
  354         /* initialize colormap and cursor hardware */
  355         sfbhwinit(base);
  356 
  357         ri->ri_flg = RI_CENTER;
  358         ri->ri_depth = 8;
  359         ri->ri_width = (hsetup & 0x1ff) << 2;
  360         ri->ri_height = (vsetup & 0x7ff);
  361         ri->ri_stride = ri->ri_width * (ri->ri_depth / 8);
  362         ri->ri_bits = base + SFB_FB_OFFSET + vbase * 4096;
  363 
  364         /* clear the screen */
  365         memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
  366 
  367         wsfont_init();
  368         /* prefer 12 pixel wide font */
  369         cookie = wsfont_find(NULL, 12, 0, 0, WSDISPLAY_FONTORDER_R2L,
  370             WSDISPLAY_FONTORDER_L2R);
  371         if (cookie <= 0)
  372                 cookie = wsfont_find(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_R2L,
  373                     WSDISPLAY_FONTORDER_L2R);
  374         if (cookie <= 0) {
  375                 printf("sfb: font table is empty\n");
  376                 return;
  377         }
  378 
  379         /* the accelerated sfb_putchar() needs LSbit left */
  380         if (wsfont_lock(cookie, &ri->ri_font)) {
  381                 printf("sfb: couldn't lock font\n");
  382                 return;
  383         }
  384         ri->ri_wsfcookie = cookie;
  385 
  386         rasops_init(ri, 34, 80);
  387 
  388         /* add our accelerated functions */
  389         ri->ri_ops.putchar = sfb_putchar;
  390         ri->ri_ops.erasecols = sfb_erasecols;
  391         ri->ri_ops.copyrows = sfb_copyrows;
  392         ri->ri_ops.eraserows = sfb_eraserows;
  393         ri->ri_do_cursor = sfb_do_cursor;
  394 
  395         /* XXX shouldn't be global */
  396         sfb_stdscreen.nrows = ri->ri_rows;
  397         sfb_stdscreen.ncols = ri->ri_cols;
  398         sfb_stdscreen.textops = &ri->ri_ops;
  399         sfb_stdscreen.capabilities = ri->ri_caps;
  400 }
  401 
  402 static int
  403 sfbioctl(v, cmd, data, flag, p)
  404         void *v;
  405         u_long cmd;
  406         caddr_t data;
  407         int flag;
  408         struct proc *p;
  409 {
  410         struct sfb_softc *sc = v;
  411         struct rasops_info *ri = sc->sc_ri;
  412         int turnoff, s;
  413 
  414         switch (cmd) {
  415         case WSDISPLAYIO_GTYPE:
  416                 *(u_int *)data = WSDISPLAY_TYPE_SFB;
  417                 return (0);
  418 
  419         case WSDISPLAYIO_GINFO:
  420 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
  421                 wsd_fbip->height = ri->ri_height;
  422                 wsd_fbip->width = ri->ri_width;
  423                 wsd_fbip->depth = ri->ri_depth;
  424                 wsd_fbip->cmsize = CMAP_SIZE;
  425 #undef fbt
  426                 return (0);
  427 
  428         case WSDISPLAYIO_GETCMAP:
  429                 return get_cmap(sc, (struct wsdisplay_cmap *)data);
  430 
  431         case WSDISPLAYIO_PUTCMAP:
  432                 return set_cmap(sc, (struct wsdisplay_cmap *)data);
  433 
  434         case WSDISPLAYIO_SVIDEO:
  435                 turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
  436                 sfb_screenblank(sc, turnoff);
  437                 return (0);
  438 
  439         case WSDISPLAYIO_GVIDEO:
  440                 *(u_int *)data = sc->sc_blanked ?
  441                     WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
  442                 return (0);
  443 
  444         case WSDISPLAYIO_GCURPOS:
  445                 *(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
  446                 return (0);
  447 
  448         case WSDISPLAYIO_SCURPOS:
  449                 s = spltty();
  450                 set_curpos(sc, (struct wsdisplay_curpos *)data);
  451                 sc->sc_changed |= WSDISPLAY_CURSOR_DOPOS;
  452                 splx(s);
  453                 return (0);
  454 
  455         case WSDISPLAYIO_GCURMAX:
  456                 ((struct wsdisplay_curpos *)data)->x =
  457                 ((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
  458                 return (0);
  459 
  460         case WSDISPLAYIO_GCURSOR:
  461                 return get_cursor(sc, (struct wsdisplay_cursor *)data);
  462 
  463         case WSDISPLAYIO_SCURSOR:
  464                 return set_cursor(sc, (struct wsdisplay_cursor *)data);
  465 
  466         case WSDISPLAYIO_SMODE:
  467                 if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
  468                         s = spltty();
  469                         sfb_cmap_init(sc);
  470                         sc->sc_curenb = 0;
  471                         sc->sc_changed |= (WSDISPLAY_CURSOR_DOCUR |
  472                             WSDISPLAY_CMAP_DOLUT);
  473                         splx(s);
  474                         sfb_screenblank(sc, 0);
  475                 }
  476                 return (0);
  477         }
  478         return (EPASSTHROUGH);
  479 }
  480 
  481 static void
  482 sfb_screenblank(sc, turnoff)
  483         struct sfb_softc *sc;
  484         int turnoff;
  485 {
  486         struct rasops_info *ri;
  487         caddr_t asic;
  488 
  489         ri = sc->sc_ri;
  490         asic = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
  491         SFBWRITE32(asic, SFB_ASIC_VIDEO_VALID, !turnoff);
  492         tc_wmb();
  493         sc->sc_blanked = turnoff;
  494 }
  495 
  496 static paddr_t
  497 sfbmmap(v, offset, prot)
  498         void *v;
  499         off_t offset;
  500         int prot;
  501 {
  502         struct sfb_softc *sc = v;
  503 
  504         if (offset >= SFB_SIZE || offset < 0)
  505                 return (-1);
  506         return machine_btop(sc->sc_vaddr + offset);
  507 }
  508 
  509 static int
  510 sfb_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
  511         void *v;
  512         const struct wsscreen_descr *type;
  513         void **cookiep;
  514         int *curxp, *curyp;
  515         long *attrp;
  516 {
  517         struct sfb_softc *sc = v;
  518         struct rasops_info *ri = sc->sc_ri;
  519         long defattr;
  520 
  521         if (sc->nscreens > 0)
  522                 return (ENOMEM);
  523 
  524         *cookiep = ri;   /* one and only for now */
  525         *curxp = 0;
  526         *curyp = 0;
  527         (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
  528         *attrp = defattr;
  529         sc->nscreens++;
  530         return (0);
  531 }
  532 
  533 static void
  534 sfb_free_screen(v, cookie)
  535         void *v;
  536         void *cookie;
  537 {
  538         struct sfb_softc *sc = v;
  539 
  540         if (sc->sc_ri == &sfb_console_ri)
  541                 panic("sfb_free_screen: console");
  542 
  543         sc->nscreens--;
  544 }
  545 
  546 static int
  547 sfb_show_screen(v, cookie, waitok, cb, cbarg)
  548         void *v;
  549         void *cookie;
  550         int waitok;
  551         void (*cb)(void *, int, int);
  552         void *cbarg;
  553 {
  554 
  555         return (0);
  556 }
  557 
  558 /* EXPORT */ int
  559 sfb_cnattach(addr)
  560         tc_addr_t addr;
  561 {
  562         struct rasops_info *ri;
  563         long defattr;
  564 
  565         ri = &sfb_console_ri;
  566         ri->ri_hw = (void *)addr;
  567         sfb_common_init(ri);
  568         (*ri->ri_ops.allocattr)(&ri, 0, 0, 0, &defattr);
  569         wsdisplay_cnattach(&sfb_stdscreen, ri, 0, 0, defattr);
  570         sfb_consaddr = addr;
  571         return (0);
  572 }
  573 
  574 static int
  575 sfbintr(arg)
  576         void *arg;
  577 {
  578         struct sfb_softc *sc = arg;
  579         caddr_t base, asic, vdac;
  580         int v;
  581         
  582         base = (caddr_t)sc->sc_ri->ri_hw;
  583         asic = base + SFB_ASIC_OFFSET;
  584         SFBWRITE32(asic, SFB_ASIC_CLEAR_INTR, 0);
  585         /* SFBWRITE32(asic, SFB_ASIC_ENABLE_INTR, 1); */
  586 
  587         if (sc->sc_changed == 0)
  588                 goto done;
  589 
  590         vdac = base + SFB_RAMDAC_OFFSET;
  591         v = sc->sc_changed;
  592         if (v & WSDISPLAY_CURSOR_DOCUR) {
  593                 int  onoff;
  594 
  595                 onoff = (sc->sc_curenb) ? 0xc0 : 0x00;
  596                 VDACSELECT(vdac, BT459_IREG_CCR);
  597                 REGWRITE32(vdac, bt_reg, onoff);
  598         }
  599         if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
  600                 int x, y;
  601 
  602                 x = sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x;
  603                 y = sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y;
  604                 x += sc->sc_cursor.cc_magic.x;
  605                 y += sc->sc_cursor.cc_magic.y;
  606 
  607                 VDACSELECT(vdac, BT459_IREG_CURSOR_X_LOW);
  608                 REGWRITE32(vdac, bt_reg, x);
  609                 REGWRITE32(vdac, bt_reg, x >> 8);
  610                 REGWRITE32(vdac, bt_reg, y);
  611                 REGWRITE32(vdac, bt_reg, y >> 8);
  612         }
  613         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  614                 u_int8_t *cp = sc->sc_cursor.cc_color;
  615 
  616                 VDACSELECT(vdac, BT459_IREG_CCOLOR_2);
  617                 REGWRITE32(vdac, bt_reg, cp[1]);
  618                 REGWRITE32(vdac, bt_reg, cp[3]);
  619                 REGWRITE32(vdac, bt_reg, cp[5]);
  620 
  621                 REGWRITE32(vdac, bt_reg, cp[0]);
  622                 REGWRITE32(vdac, bt_reg, cp[2]);
  623                 REGWRITE32(vdac, bt_reg, cp[4]);
  624         }
  625         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  626                 u_int8_t *ip, *mp, img, msk;
  627                 u_int8_t u;
  628                 int bcnt;
  629 
  630                 ip = (u_int8_t *)sc->sc_cursor.cc_image;
  631                 mp = (u_int8_t *)sc->sc_cursor.cc_mask;
  632 
  633                 bcnt = 0;
  634                 VDACSELECT(vdac, BT459_IREG_CRAM_BASE+0);
  635                 /* 64 pixel scan line is consisted with 16 byte cursor ram */
  636                 while (bcnt < sc->sc_cursor.cc_size.y * 16) {
  637                         /* pad right half 32 pixel when smaller than 33 */
  638                         if ((bcnt & 0x8) && sc->sc_cursor.cc_size.x < 33) {
  639                                 REGWRITE32(vdac, bt_reg, 0);
  640                                 REGWRITE32(vdac, bt_reg, 0);
  641                         }
  642                         else {
  643                                 img = *ip++;
  644                                 msk = *mp++;
  645                                 img &= msk;     /* cookie off image */
  646                                 u = (msk & 0x0f) << 4 | (img & 0x0f);
  647                                 REGWRITE32(vdac, bt_reg, shuffle[u]);
  648                                 u = (msk & 0xf0) | (img & 0xf0) >> 4;
  649                                 REGWRITE32(vdac, bt_reg, shuffle[u]);
  650                         }
  651                         bcnt += 2;
  652                 }
  653                 /* pad unoccupied scan lines */
  654                 while (bcnt < CURSOR_MAX_SIZE * 16) {
  655                         REGWRITE32(vdac, bt_reg, 0);
  656                         REGWRITE32(vdac, bt_reg, 0);
  657                         bcnt += 2;
  658                 }
  659         }
  660         if (v & WSDISPLAY_CMAP_DOLUT) {
  661                 struct hwcmap256 *cm = &sc->sc_cmap;
  662                 int index;
  663 
  664                 VDACSELECT(vdac, 0);
  665                 for (index = 0; index < CMAP_SIZE; index++) {
  666                         REGWRITE32(vdac, bt_cmap, cm->r[index]);
  667                         REGWRITE32(vdac, bt_cmap, cm->g[index]);
  668                         REGWRITE32(vdac, bt_cmap, cm->b[index]);
  669                 }
  670         }
  671         sc->sc_changed = 0;
  672 done:
  673         return (1);
  674 }
  675 
  676 static void
  677 sfbhwinit(base)
  678         caddr_t base;
  679 {
  680         caddr_t vdac = base + SFB_RAMDAC_OFFSET;
  681         const u_int8_t *p;
  682         int i;
  683 
  684         VDACSELECT(vdac, BT459_IREG_COMMAND_0);
  685         REGWRITE32(vdac, bt_reg, 0x40); /* CMD0 */
  686         REGWRITE32(vdac, bt_reg, 0x0);  /* CMD1 */
  687         REGWRITE32(vdac, bt_reg, 0xc0); /* CMD2 */
  688         REGWRITE32(vdac, bt_reg, 0xff); /* PRM */
  689         REGWRITE32(vdac, bt_reg, 0);    /* 205 */
  690         REGWRITE32(vdac, bt_reg, 0x0);  /* PBM */
  691         REGWRITE32(vdac, bt_reg, 0);    /* 207 */
  692         REGWRITE32(vdac, bt_reg, 0x0);  /* ORM */
  693         REGWRITE32(vdac, bt_reg, 0x0);  /* OBM */
  694         REGWRITE32(vdac, bt_reg, 0x0);  /* ILV */
  695         REGWRITE32(vdac, bt_reg, 0x0);  /* TEST */
  696 
  697         VDACSELECT(vdac, BT459_IREG_CCR);
  698         REGWRITE32(vdac, bt_reg, 0x0);
  699         REGWRITE32(vdac, bt_reg, 0x0);
  700         REGWRITE32(vdac, bt_reg, 0x0);
  701         REGWRITE32(vdac, bt_reg, 0x0);
  702         REGWRITE32(vdac, bt_reg, 0x0);
  703         REGWRITE32(vdac, bt_reg, 0x0);
  704         REGWRITE32(vdac, bt_reg, 0x0);
  705         REGWRITE32(vdac, bt_reg, 0x0);
  706         REGWRITE32(vdac, bt_reg, 0x0);
  707         REGWRITE32(vdac, bt_reg, 0x0);
  708         REGWRITE32(vdac, bt_reg, 0x0);
  709         REGWRITE32(vdac, bt_reg, 0x0);
  710         REGWRITE32(vdac, bt_reg, 0x0);
  711 
  712         /* build sane colormap */
  713         VDACSELECT(vdac, 0);
  714         p = rasops_cmap;
  715         for (i = 0; i < CMAP_SIZE; i++, p += 3) {
  716                 REGWRITE32(vdac, bt_cmap, p[0]);
  717                 REGWRITE32(vdac, bt_cmap, p[1]);
  718                 REGWRITE32(vdac, bt_cmap, p[2]);
  719         }
  720 
  721         /* clear out cursor image */
  722         VDACSELECT(vdac, BT459_IREG_CRAM_BASE);
  723         for (i = 0; i < 1024; i++)
  724                 REGWRITE32(vdac, bt_reg, 0xff);
  725 
  726         /*
  727          * 2 bit/pixel cursor.  Assign MSB for cursor mask and LSB for
  728          * cursor image.  CCOLOR_2 for mask color, while CCOLOR_3 for
  729          * image color.  CCOLOR_1 will be never used.
  730          */
  731         VDACSELECT(vdac, BT459_IREG_CCOLOR_1);
  732         REGWRITE32(vdac, bt_reg, 0xff);
  733         REGWRITE32(vdac, bt_reg, 0xff);
  734         REGWRITE32(vdac, bt_reg, 0xff);
  735 
  736         REGWRITE32(vdac, bt_reg, 0);    
  737         REGWRITE32(vdac, bt_reg, 0);    
  738         REGWRITE32(vdac, bt_reg, 0);    
  739 
  740         REGWRITE32(vdac, bt_reg, 0xff);
  741         REGWRITE32(vdac, bt_reg, 0xff);
  742         REGWRITE32(vdac, bt_reg, 0xff);
  743 }
  744 
  745 static int
  746 get_cmap(sc, p)
  747         struct sfb_softc *sc;
  748         struct wsdisplay_cmap *p;
  749 {
  750         u_int index = p->index, count = p->count;
  751         int error;
  752 
  753         if (index >= CMAP_SIZE || count > CMAP_SIZE - index)
  754                 return (EINVAL);
  755 
  756         error = copyout(&sc->sc_cmap.r[index], p->red, count);
  757         if (error)
  758                 return error;
  759         error = copyout(&sc->sc_cmap.g[index], p->green, count);
  760         if (error)
  761                 return error;
  762         error = copyout(&sc->sc_cmap.b[index], p->blue, count);
  763         return error;
  764 }
  765 
  766 static int
  767 set_cmap(sc, p)
  768         struct sfb_softc *sc;
  769         struct wsdisplay_cmap *p;
  770 {
  771         struct hwcmap256 cmap;
  772         u_int index = p->index, count = p->count;
  773         int error, s;
  774 
  775         if (index >= CMAP_SIZE || count > CMAP_SIZE - index)
  776                 return (EINVAL);
  777 
  778         error = copyin(p->red, &cmap.r[index], count);
  779         if (error)
  780                 return error;
  781         error = copyin(p->green, &cmap.g[index], count);
  782         if (error)
  783                 return error;
  784         error = copyin(p->blue, &cmap.b[index], count);
  785         if (error)
  786                 return error;
  787 
  788         s = spltty();
  789         memcpy(&sc->sc_cmap.r[index], &cmap.r[index], count);
  790         memcpy(&sc->sc_cmap.g[index], &cmap.g[index], count);
  791         memcpy(&sc->sc_cmap.b[index], &cmap.b[index], count);
  792         sc->sc_changed |= WSDISPLAY_CMAP_DOLUT;
  793         splx(s);
  794         return (0);
  795 }
  796 
  797 static int
  798 set_cursor(sc, p)
  799         struct sfb_softc *sc;
  800         struct wsdisplay_cursor *p;
  801 {
  802 #define cc (&sc->sc_cursor)
  803         u_int v, index = 0, count = 0, icount = 0;
  804         uint8_t r[2], g[2], b[2], image[512], mask[512];
  805         int error, s;
  806 
  807         v = p->which;
  808         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  809                 index = p->cmap.index;
  810                 count = p->cmap.count;
  811                 if (index >= 2 || (index + count) > 2)
  812                         return (EINVAL);
  813                 error = copyin(p->cmap.red, &r[index], count);
  814                 if (error)
  815                         return error;
  816                 error = copyin(p->cmap.green, &g[index], count);
  817                 if (error)
  818                         return error;
  819                 error = copyin(p->cmap.blue, &b[index], count);
  820                 if (error)
  821                         return error;
  822         }
  823         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  824                 if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
  825                         return (EINVAL);
  826                 icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
  827                 error = copyin(p->image, image, icount);
  828                 if (error)
  829                         return error;
  830                 error = copyin(p->mask, mask, icount);
  831                 if (error)
  832                         return error;
  833         }
  834 
  835         s = spltty();
  836         if (v & WSDISPLAY_CURSOR_DOCUR)
  837                 sc->sc_curenb = p->enable;
  838         if (v & WSDISPLAY_CURSOR_DOPOS)
  839                 set_curpos(sc, &p->pos);
  840         if (v & WSDISPLAY_CURSOR_DOHOT)
  841                 cc->cc_hot = p->hot;
  842         if (v & WSDISPLAY_CURSOR_DOCMAP) {
  843                 memcpy(&cc->cc_color[index], &r[index], count);
  844                 memcpy(&cc->cc_color[index + 2], &g[index], count);
  845                 memcpy(&cc->cc_color[index + 4], &b[index], count);
  846         }
  847         if (v & WSDISPLAY_CURSOR_DOSHAPE) {
  848                 cc->cc_size = p->size;
  849                 memset(cc->cc_image, 0, sizeof cc->cc_image);
  850                 memcpy(cc->cc_image, image, icount);
  851                 memset(cc->cc_mask, 0, sizeof cc->cc_mask);
  852                 memcpy(cc->cc_mask, mask, icount);
  853         }
  854         sc->sc_changed |= v;
  855         splx(s);
  856 
  857         return (0);
  858 #undef cc
  859 }
  860 
  861 static int
  862 get_cursor(sc, p)
  863         struct sfb_softc *sc;
  864         struct wsdisplay_cursor *p;
  865 {
  866 
  867         return (EPASSTHROUGH); /* XXX */
  868 }
  869 
  870 static void
  871 set_curpos(sc, curpos)
  872         struct sfb_softc *sc;
  873         struct wsdisplay_curpos *curpos;
  874 {
  875         struct rasops_info *ri = sc->sc_ri;
  876         int x = curpos->x, y = curpos->y;
  877 
  878         if (y < 0)
  879                 y = 0;
  880         else if (y > ri->ri_height);
  881                 y = ri->ri_height;
  882         if (x < 0)
  883                 x = 0;
  884         else if (x > ri->ri_width);
  885                 x = ri->ri_width;
  886         sc->sc_cursor.cc_pos.x = x;
  887         sc->sc_cursor.cc_pos.y = y;
  888 }
  889 
  890 #define MODE_SIMPLE             0
  891 #define MODE_OPAQUESTIPPLE      1
  892 #define MODE_OPAQUELINE         2
  893 #define MODE_TRANSPARENTSTIPPLE 5
  894 #define MODE_TRANSPARENTLINE    6
  895 #define MODE_COPY               7
  896 
  897 /* parameters for 8bpp configuration */
  898 #define SFBALIGNMASK            0x7
  899 #define SFBSTIPPLEALL1          0xffffffff
  900 #define SFBSTIPPLEBITS          32
  901 #define SFBSTIPPLEBITMASK       0x1f
  902 #define SFBSTIPPLEBYTESDONE     32
  903 #define SFBCOPYALL1             0xffffffff
  904 #define SFBCOPYBITS             32
  905 #define SFBCOPYBITMASK          0x1f
  906 #define SFBCOPYBYTESDONE        32
  907 
  908 #if defined(pmax)
  909 #define WRITE_MB()
  910 #define BUMP(p) (p)
  911 #endif
  912 
  913 #if defined(alpha)
  914 #define WRITE_MB() tc_wmb()
  915 /* SFB registers replicated in 128B stride; cycle after eight iterations */
  916 #define BUMP(p) ((p) = (caddr_t)(((long)(p) + 0x80) & ~0x400))
  917 #endif
  918 
  919 #define SFBMODE(p, v) \
  920                 SFBWRITE32(BUMP(p), SFB_ASIC_MODE, (v))
  921 #define SFBROP(p, v) \
  922                 SFBWRITE32(BUMP(p), SFB_ASIC_ROP, (v))
  923 #define SFBPLANEMASK(p, v) \
  924                 SFBWRITE32(BUMP(p), SFB_ASIC_PLANEMASK, (v))
  925 #define SFBPIXELMASK(p, v) \
  926                 SFBWRITE32(BUMP(p), SFB_ASIC_PIXELMASK, (v))
  927 #define SFBADDRESS(p, v) \
  928                 SFBWRITE32(BUMP(p), SFB_ASIC_ADDRESS, (v))
  929 #define SFBSTART(p, v) \
  930                 SFBWRITE32(BUMP(p), SFB_ASIC_START, (v))
  931 #define SFBPIXELSHIFT(p, v) \
  932                 SFBWRITE32(BUMP(p), SFB_ASIC_PIXELSHIFT, (v))
  933 #define SFBFG(p, v) \
  934                 SFBWRITE32(BUMP(p), SFB_ASIC_FG, (v))
  935 #define SFBBG(p, v) \
  936                 SFBWRITE32(BUMP(p), SFB_ASIC_BG, (v))
  937 
  938 /*
  939  * Paint the cursor.
  940  */
  941 static void
  942 sfb_do_cursor(ri)
  943         struct rasops_info *ri;
  944 {
  945         caddr_t sfb, p;
  946         int scanspan, height, width, align, x, y;
  947         u_int32_t lmask, rmask;
  948 
  949         x = ri->ri_ccol * ri->ri_font->fontwidth;
  950         y = ri->ri_crow * ri->ri_font->fontheight;
  951         scanspan = ri->ri_stride;
  952         height = ri->ri_font->fontheight;
  953 
  954         p = ri->ri_bits + y * scanspan + x;
  955         align = (long)p & SFBALIGNMASK;
  956         p -= align;
  957         width = ri->ri_font->fontwidth + align;
  958         lmask = SFBSTIPPLEALL1 << align;
  959         rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
  960         sfb = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
  961 
  962         SFBMODE(sfb, MODE_TRANSPARENTSTIPPLE);
  963         SFBPLANEMASK(sfb, ~0);
  964         SFBROP(sfb, 6);  /* ROP_XOR */
  965         SFBFG(sfb, ~0);
  966 
  967         lmask = lmask & rmask;
  968         while (height > 0) {
  969                 SFBADDRESS(sfb, (long)p);
  970                 SFBSTART(sfb, lmask);
  971                 p += scanspan;
  972                 height--;
  973         }
  974         SFBMODE(sfb, MODE_SIMPLE);
  975         SFBROP(sfb, 3); /* ROP_COPY */
  976 }
  977 
  978 /*
  979  * Paint a character.
  980  */
  981 static void
  982 sfb_putchar(id, row, col, uc, attr)
  983         void *id;
  984         int row, col;
  985         u_int uc;
  986         long attr;
  987 {
  988         struct rasops_info *ri = id;
  989         caddr_t sfb, p;
  990         int scanspan, height, width, align, x, y;
  991         u_int32_t lmask, rmask, glyph;
  992         u_int8_t *g;
  993 
  994         x = col * ri->ri_font->fontwidth;
  995         y = row * ri->ri_font->fontheight;
  996         scanspan = ri->ri_stride;
  997         height = ri->ri_font->fontheight;
  998         uc -= ri->ri_font->firstchar;
  999         g = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
 1000 
 1001         p = ri->ri_bits + y * scanspan + x;
 1002         align = (long)p & SFBALIGNMASK;
 1003         p -= align;
 1004         width = ri->ri_font->fontwidth + align;
 1005         lmask = SFBSTIPPLEALL1 << align;
 1006         rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
 1007         sfb = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
 1008 
 1009         SFBMODE(sfb, MODE_OPAQUESTIPPLE);
 1010         SFBPLANEMASK(sfb, ~0);
 1011         SFBFG(sfb, ri->ri_devcmap[(attr >> 24) & 15]);
 1012         SFBBG(sfb, ri->ri_devcmap[(attr >> 16) & 15]);
 1013 
 1014         /* XXX 2B stride fonts only XXX */
 1015         lmask = lmask & rmask;
 1016         while (height > 0) {
 1017                 glyph = *(u_int16_t *)g;                /* XXX */
 1018                 SFBPIXELMASK(sfb, lmask);
 1019                 SFBADDRESS(sfb, (long)p);
 1020                 SFBSTART(sfb, glyph << align);
 1021                 p += scanspan;
 1022                 g += 2;                                 /* XXX */
 1023                 height--;
 1024         }
 1025         if (attr & 1 /* UNDERLINE */) {
 1026                 p -= scanspan * 2;
 1027                 SFBMODE(sfb, MODE_TRANSPARENTSTIPPLE);
 1028                 SFBADDRESS(sfb, (long)p);
 1029                 SFBSTART(sfb, lmask);
 1030         }
 1031 
 1032         SFBMODE(sfb, MODE_SIMPLE);
 1033         SFBPIXELMASK(sfb, ~0);          /* entire pixel */
 1034 }
 1035 
 1036 #if 0
 1037 /*
 1038  * Copy characters in a line.
 1039  */
 1040 static void
 1041 sfb_copycols(id, row, srccol, dstcol, ncols)
 1042         void *id;
 1043         int row, srccol, dstcol, ncols;
 1044 {
 1045         struct rasops_info *ri = id;
 1046         caddr_t sp, dp, basex, sfb;
 1047         int scanspan, height, width, aligns, alignd, shift, w, y;
 1048         u_int32_t lmaskd, rmaskd;
 1049 
 1050         scanspan = ri->ri_stride;
 1051         y = row * ri->ri_font->fontheight;
 1052         basex = ri->ri_bits + y * scanspan;
 1053         height = ri->ri_font->fontheight;
 1054         w = ri->ri_font->fontwidth * ncols;
 1055 
 1056         sp = basex + ri->ri_font->fontwidth * srccol;
 1057         aligns = (long)sp & SFBALIGNMASK;
 1058         dp = basex + ri->ri_font->fontwidth * dstcol;
 1059         alignd = (long)dp & SFBALIGNMASK;
 1060         sfb = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
 1061 
 1062         SFBMODE(sfb, MODE_COPY);
 1063         SFBPLANEMASK(sfb, ~0);
 1064         /* small enough to fit in a single 32bit */
 1065         if ((aligns + w) <= SFBCOPYBITS && (alignd + w) <= SFBCOPYBITS) {
 1066                 SFBPIXELSHIFT(sfb, alignd - aligns);
 1067                 lmaskd = SFBCOPYALL1 << alignd;
 1068                 rmaskd = SFBCOPYALL1 >> (-(alignd + w) & SFBCOPYBITMASK);
 1069                 lmaskd = lmaskd & rmaskd;
 1070                 sp -= aligns;
 1071                 dp -= alignd;
 1072                 while (height > 0) {
 1073                         MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1074                         MEMWRITE32(dp, lmaskd); WRITE_MB();
 1075                         sp += scanspan;
 1076                         dp += scanspan;
 1077                         height--;
 1078                 }
 1079         }
 1080         /* copy forward (left-to-right) */
 1081         else if (dstcol < srccol || srccol + ncols < dstcol) {
 1082                 caddr_t sq, dq;
 1083 
 1084                 shift = alignd - aligns;
 1085                 if (shift < 0) {
 1086                         shift = 8 + shift;      /* enforce right rotate */
 1087                         alignd += 8;            /* bearing on left edge */
 1088                 }
 1089                 width = alignd + w;
 1090                 lmaskd = SFBCOPYALL1 << alignd;
 1091                 rmaskd = SFBCOPYALL1 >> (-width & SFBCOPYBITMASK);
 1092                 sp -= aligns;
 1093                 dp -= alignd;
 1094 
 1095                 SFBPIXELSHIFT(sfb, shift);
 1096                 w = width;
 1097                 sq = sp;
 1098                 dq = dp;
 1099                 while (height > 0) {
 1100                         MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1101                         MEMWRITE32(dp, lmaskd); WRITE_MB();
 1102                         width -= 2 * SFBCOPYBITS;
 1103                         while (width > 0) {
 1104                                 sp += SFBCOPYBYTESDONE;
 1105                                 dp += SFBCOPYBYTESDONE;
 1106                                 MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1107                                 MEMWRITE32(dp, SFBCOPYALL1);    WRITE_MB();
 1108                                 width -= SFBCOPYBITS;
 1109                         }
 1110                         sp += SFBCOPYBYTESDONE;
 1111                         dp += SFBCOPYBYTESDONE;
 1112                         MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1113                         MEMWRITE32(dp, rmaskd); WRITE_MB();
 1114                         sp = (sq += scanspan);
 1115                         dp = (dq += scanspan);
 1116                         width = w;
 1117                         height--;
 1118                 }
 1119         }
 1120         /* copy backward (right-to-left) */
 1121         else {
 1122                 caddr_t sq, dq;
 1123 
 1124                 shift = alignd - aligns;
 1125                 if (shift > 0) {
 1126                         shift = shift - 8;      /* force left rotate */
 1127                         alignd += 24;
 1128                 }
 1129                 width = alignd + w;
 1130                 lmaskd = SFBCOPYALL1 << alignd;
 1131                 rmaskd = SFBCOPYALL1 >> (-width & SFBCOPYBITMASK);
 1132                 sp -= aligns;
 1133                 dp -= alignd;
 1134 
 1135                 SFBPIXELSHIFT(sfb, shift);
 1136                 w = width;
 1137                 sq = sp += (((aligns + w) - 1) & ~31);
 1138                 dq = dp += (((alignd + w) - 1) & ~31);
 1139                 while (height > 0) {
 1140                         MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1141                         MEMWRITE32(dp, rmaskd); WRITE_MB();
 1142                         width -= 2 * SFBCOPYBITS;
 1143                         while (width > 0) {
 1144                                 sp -= SFBCOPYBYTESDONE;
 1145                                 dp -= SFBCOPYBYTESDONE;
 1146                                 MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1147                                 MEMWRITE32(dp, SFBCOPYALL1);    WRITE_MB();
 1148                                 width -= SFBCOPYBITS;
 1149                         }
 1150                         sp -= SFBCOPYBYTESDONE;
 1151                         dp -= SFBCOPYBYTESDONE;
 1152                         MEMWRITE32(sp, SFBCOPYALL1);    WRITE_MB();
 1153                         MEMWRITE32(dp, lmaskd); WRITE_MB();
 1154 
 1155                         sp = (sq += scanspan);
 1156                         dp = (dq += scanspan);
 1157                         width = w;
 1158                         height--;
 1159                 }
 1160         }
 1161         SFBMODE(sfb, MODE_SIMPLE);
 1162         SFBPIXELSHIFT(sfb, 0);
 1163 }
 1164 #endif
 1165 
 1166 /*
 1167  * Clear characters in a line.
 1168  */
 1169 static void
 1170 sfb_erasecols(id, row, startcol, ncols, attr)
 1171         void *id;
 1172         int row, startcol, ncols;
 1173         long attr;
 1174 {
 1175         struct rasops_info *ri = id;
 1176         caddr_t sfb, p;
 1177         int scanspan, startx, height, width, align, w, y;
 1178         u_int32_t lmask, rmask;
 1179 
 1180         scanspan = ri->ri_stride;
 1181         y = row * ri->ri_font->fontheight;
 1182         startx = startcol * ri->ri_font->fontwidth;
 1183         height = ri->ri_font->fontheight;
 1184         w = ri->ri_font->fontwidth * ncols;
 1185 
 1186         p = ri->ri_bits + y * scanspan + startx;
 1187         align = (long)p & SFBALIGNMASK;
 1188         p -= align;
 1189         width = w + align;
 1190         lmask = SFBSTIPPLEALL1 << align;
 1191         rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
 1192         sfb = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
 1193 
 1194         SFBMODE(sfb, MODE_TRANSPARENTSTIPPLE);
 1195         SFBPLANEMASK(sfb, ~0);
 1196         SFBFG(sfb, ri->ri_devcmap[(attr >> 16) & 15]); /* fill with bg */
 1197         if (width <= SFBSTIPPLEBITS) {
 1198                 lmask = lmask & rmask;
 1199                 while (height > 0) {
 1200                         SFBADDRESS(sfb, (long)p);
 1201                         SFBSTART(sfb, lmask);
 1202                         p += scanspan;
 1203                         height--;
 1204                 }
 1205         }
 1206         else {
 1207                 caddr_t q = p;
 1208                 while (height > 0) {
 1209                         MEMWRITE32(p, lmask);   WRITE_MB();
 1210                         width -= 2 * SFBSTIPPLEBITS;
 1211                         while (width > 0) {
 1212                                 p += SFBSTIPPLEBYTESDONE;
 1213                                 MEMWRITE32(p, SFBSTIPPLEALL1); WRITE_MB();
 1214                                 width -= SFBSTIPPLEBITS;
 1215                         }
 1216                         p += SFBSTIPPLEBYTESDONE;
 1217                         MEMWRITE32(p, rmask); WRITE_MB();
 1218                         WRITE_MB();
 1219 
 1220                         p = (q += scanspan);
 1221                         width = w + align;
 1222                         height--;
 1223                 }
 1224         }
 1225         SFBMODE(sfb, MODE_SIMPLE);
 1226 }
 1227 
 1228 /*
 1229  * Copy lines.
 1230  */
 1231 static void
 1232 sfb_copyrows(id, srcrow, dstrow, nrows)
 1233         void *id;
 1234         int srcrow, dstrow, nrows;
 1235 {
 1236         struct rasops_info *ri = id;
 1237         caddr_t sfb, p;
 1238         int scanspan, offset, srcy, height, width, align, w;
 1239         u_int32_t lmask, rmask;
 1240 
 1241         scanspan = ri->ri_stride;
 1242         height = ri->ri_font->fontheight * nrows;
 1243         offset = (dstrow - srcrow) * ri->ri_yscale;
 1244         srcy = ri->ri_font->fontheight * srcrow;
 1245         if (srcrow < dstrow && srcrow + nrows > dstrow) {
 1246                 scanspan = -scanspan;
 1247                 srcy += height;
 1248         }
 1249 
 1250         p = ri->ri_bits + srcy * ri->ri_stride;
 1251         align = (long)p & SFBALIGNMASK;
 1252         p -= align;
 1253         w = ri->ri_emuwidth;
 1254         width = w + align;
 1255         lmask = SFBCOPYALL1 << align;
 1256         rmask = SFBCOPYALL1 >> (-width & SFBCOPYBITMASK);
 1257         sfb = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
 1258 
 1259         SFBMODE(sfb, MODE_COPY);
 1260         SFBPLANEMASK(sfb, ~0);
 1261         SFBPIXELSHIFT(sfb, 0);
 1262         if (width <= SFBCOPYBITS) {
 1263                 /* never happens */;
 1264         }
 1265         else {
 1266                 caddr_t q = p;
 1267                 while (height > 0) {
 1268                         MEMWRITE32(p, lmask);
 1269                         MEMWRITE32(p + offset, lmask);
 1270                         width -= 2 * SFBCOPYBITS;
 1271                         while (width > 0) {
 1272                                 p += SFBCOPYBYTESDONE;
 1273                                 MEMWRITE32(p, SFBCOPYALL1);
 1274                                 MEMWRITE32(p + offset, SFBCOPYALL1);
 1275                                 width -= SFBCOPYBITS;
 1276                         }
 1277                         p += SFBCOPYBYTESDONE;
 1278                         MEMWRITE32(p, rmask);
 1279                         MEMWRITE32(p + offset, rmask);
 1280 
 1281                         p = (q += scanspan);
 1282                         width = w + align;
 1283                         height--;
 1284                 }
 1285         }
 1286         SFBMODE(sfb, MODE_SIMPLE);
 1287 }
 1288 
 1289 /*
 1290  * Erase lines.
 1291  */
 1292 void
 1293 sfb_eraserows(id, startrow, nrows, attr)
 1294         void *id;
 1295         int startrow, nrows;
 1296         long attr;
 1297 {
 1298         struct rasops_info *ri = id;
 1299         caddr_t sfb, p;
 1300         int scanspan, starty, height, width, align, w;
 1301         u_int32_t lmask, rmask;
 1302 
 1303         scanspan = ri->ri_stride;
 1304         starty = ri->ri_font->fontheight * startrow;
 1305         height = ri->ri_font->fontheight * nrows;
 1306 
 1307         p = ri->ri_bits + starty * scanspan;
 1308         align = (long)p & SFBALIGNMASK;
 1309         p -= align;
 1310         w = ri->ri_emuwidth;
 1311         width = w + align;
 1312         lmask = SFBSTIPPLEALL1 << align;
 1313         rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
 1314         sfb = (caddr_t)ri->ri_hw + SFB_ASIC_OFFSET;
 1315 
 1316         SFBMODE(sfb, MODE_TRANSPARENTSTIPPLE);
 1317         SFBPLANEMASK(sfb, ~0);
 1318         SFBFG(sfb, ri->ri_devcmap[(attr >> 16) & 15]); /* fill with bg */
 1319         if (width <= SFBSTIPPLEBITS) {
 1320                 /* never happens */;
 1321         }
 1322         else {
 1323                 caddr_t q = p;
 1324                 while (height > 0) {
 1325                         MEMWRITE32(p, lmask); WRITE_MB();
 1326                         width -= 2 * SFBSTIPPLEBITS;
 1327                         while (width > 0) {
 1328                                 p += SFBSTIPPLEBYTESDONE;
 1329                                 MEMWRITE32(p, SFBSTIPPLEALL1); WRITE_MB();
 1330                                 width -= SFBSTIPPLEBITS;
 1331                         }
 1332                         p += SFBSTIPPLEBYTESDONE;
 1333                         MEMWRITE32(p, rmask); WRITE_MB();
 1334 
 1335                         p = (q += scanspan);
 1336                         width = w + align;
 1337                         height--;
 1338                 }
 1339         }
 1340         SFBMODE(sfb, MODE_SIMPLE);
 1341 }

Cache object: 7504af656aaed4c77388318de30ddc32


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