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

Cache object: c5f4ad82f7b600a841e8c4d9dfc6a0e9


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