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/pc/vgat2r4.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 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "io.h"
    7 #include "../port/error.h"
    8 
    9 #define Image   IMAGE
   10 #include <draw.h>
   11 #include <memdraw.h>
   12 #include <cursor.h>
   13 #include "screen.h"
   14 
   15 /*
   16  * #9 Ticket to Ride IV.
   17  */
   18 enum {
   19         IndexLo         = 0x10/4,
   20         IndexHi         = 0x14/4,
   21         Data            = 0x18/4,
   22         IndexCtl        = 0x1C/4,
   23 
   24         Zoom            = 0x54/4,
   25 };
   26 
   27 enum {                                          /* index registers */
   28         CursorSyncCtl   = 0x03,
   29           HsyncHi = 0x01,
   30           HsyncLo = 0x02,
   31           VsyncHi = 0x04,
   32           VsyncLo = 0x08,
   33 
   34         CursorCtl       = 0x30,
   35         CursorXLo       = 0x31,
   36         CursorXHi       = 0x32,
   37         CursorYLo       = 0x33,
   38         CursorYHi       = 0x34,
   39         CursorHotX      = 0x35,
   40         CursorHotY      = 0x36,
   41 
   42         CursorR1        = 0x40,
   43         CursorG1        = 0x41,
   44         CursorB1        = 0x42,
   45         CursorR2        = 0x43,
   46         CursorG2        = 0x44,
   47         CursorB2        = 0x45,
   48         CursorR3        = 0x46,
   49         CursorG3        = 0x47,
   50         CursorB3        = 0x48,
   51 
   52         CursorArray     = 0x100,
   53 
   54         CursorMode32x32 = 0x23,
   55         CursorMode64x64 = 0x27,
   56         CursorMode      = CursorMode32x32,
   57 };
   58 
   59 static void
   60 t2r4enable(VGAscr* scr)
   61 {
   62         Pcidev *p;
   63         void *mmio;
   64 
   65         if(scr->mmio)
   66                 return;
   67         if(p = pcimatch(nil, 0x105D, 0)){
   68                 switch(p->did){
   69                 case 0x5348:
   70                         break;
   71                 default:
   72                         return;
   73                 }
   74         }
   75         else
   76                 return;
   77         scr->pci = p;
   78         
   79         mmio = vmap(p->mem[4].bar & ~0x0F, p->mem[4].size);
   80         if(mmio == nil)
   81                 return;
   82         addvgaseg("t2r4mmio", p->mem[4].bar & ~0x0F, p->mem[4].size);
   83 
   84         scr->mmio = mmio;
   85         vgalinearpci(scr);
   86         if(scr->paddr)
   87                 addvgaseg("t2r4screen", scr->paddr, scr->apsize);
   88 }
   89 
   90 static uchar
   91 t2r4xi(VGAscr* scr, int index)
   92 {
   93         ulong *mmio;
   94 
   95         mmio = scr->mmio;
   96         mmio[IndexLo] = index & 0xFF;
   97         mmio[IndexHi] = (index>>8) & 0xFF;
   98 
   99         return mmio[Data];
  100 }
  101 
  102 static void
  103 t2r4xo(VGAscr* scr, int index, uchar data)
  104 {
  105         ulong *mmio;
  106 
  107         mmio = scr->mmio;
  108         mmio[IndexLo] = index & 0xFF;
  109         mmio[IndexHi] = (index>>8) & 0xFF;
  110 
  111         mmio[Data] = data;
  112 }
  113 
  114 static void
  115 t2r4curdisable(VGAscr* scr)
  116 {
  117         if(scr->mmio == 0)
  118                 return;
  119         t2r4xo(scr, CursorCtl, 0x00);
  120 }
  121 
  122 static void
  123 t2r4curload(VGAscr* scr, Cursor* curs)
  124 {
  125         uchar *data;
  126         int size, x, y, zoom;
  127         ulong clr, *mmio, pixels, set;
  128 
  129         mmio = scr->mmio;
  130         if(mmio == 0)
  131                 return;
  132 
  133         /*
  134          * Make sure cursor is off by initialising the cursor
  135          * control to defaults.
  136          */
  137         t2r4xo(scr, CursorCtl, 0x00);
  138 
  139         /*
  140          * Set auto-increment mode for index-register addressing
  141          * and initialise the cursor array index.
  142          */
  143         mmio[IndexCtl] = 0x01;
  144         mmio[IndexLo] = CursorArray & 0xFF;
  145         mmio[IndexHi] = (CursorArray>>8) & 0xFF;
  146 
  147         /*
  148          * Initialise the cursor RAM array. There are 2 planes,
  149          * p0 and p1. Data is written 4 pixels per byte, with p1 the
  150          * MS bit of each pixel.
  151          * The cursor is set in X-Windows mode which gives the following
  152          * truth table:
  153          *      p1 p0   colour
  154          *       0  0   underlying pixel colour
  155          *       0  1   underlying pixel colour
  156          *       1  0   cursor colour 1
  157          *       1  1   cursor colour 2
  158          * Put the cursor into the top-left of the array.
  159          *
  160          * Although this looks a lot like the IBM RGB524 cursor, the
  161          * scanlines appear to be twice as long as they should be and
  162          * some of the other features are missing.
  163          */
  164         if(mmio[Zoom] & 0x0F)
  165                 zoom = 32;
  166         else
  167                 zoom = 16;
  168         data = (uchar*)&mmio[Data];
  169         for(y = 0; y < zoom; y++){
  170                 clr = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];
  171                 set = (curs->set[2*y]<<8)|curs->set[y*2 + 1];
  172                 pixels = 0;
  173                 for(x = 0; x < 16; x++){
  174                         if(set & (1<<x))
  175                                 pixels |= 0x03<<(x*2);
  176                         else if(clr & (1<<x))
  177                                 pixels |= 0x02<<(x*2);
  178                 }
  179 
  180                 *data = pixels>>24;
  181                 *data = pixels>>16;
  182                 *data = pixels>>8;
  183                 *data = pixels;
  184 
  185                 *data = 0x00;
  186                 *data = 0x00;
  187                 *data = 0x00;
  188                 *data = 0x00;
  189 
  190                 if(CursorMode == CursorMode32x32 && zoom == 16)
  191                         continue;
  192                 *data = pixels>>24;
  193                 *data = pixels>>16;
  194                 *data = pixels>>8;
  195                 *data = pixels;
  196 
  197                 *data = 0x00;
  198                 *data = 0x00;
  199                 *data = 0x00;
  200                 *data = 0x00;
  201         }
  202         if(CursorMode == CursorMode32x32)
  203                 size = 32;
  204         else
  205                 size = 64;
  206         while(y < size){
  207                 for(x = 0; x < size/8; x++){
  208                         *data = 0x00;
  209                         *data = 0x00;
  210                 }
  211                 y++;
  212         }
  213         mmio[IndexCtl] = 0x00;
  214 
  215         /*
  216          * Initialise the hotpoint and enable the cursor.
  217          */
  218         t2r4xo(scr, CursorHotX, -curs->offset.x);
  219         zoom = (scr->mmio[Zoom] & 0x0F)+1;
  220         t2r4xo(scr, CursorHotY, -curs->offset.y*zoom);
  221 
  222         t2r4xo(scr, CursorCtl, CursorMode);
  223 }
  224 
  225 static int
  226 t2r4curmove(VGAscr* scr, Point p)
  227 {
  228         int y, zoom;
  229 
  230         if(scr->mmio == 0)
  231                 return 1;
  232 
  233         t2r4xo(scr, CursorXLo, p.x & 0xFF);
  234         t2r4xo(scr, CursorXHi, (p.x>>8) & 0x0F);
  235 
  236         zoom = (scr->mmio[Zoom] & 0x0F)+1;
  237         y = p.y*zoom;
  238         t2r4xo(scr, CursorYLo, y & 0xFF);
  239         t2r4xo(scr, CursorYHi, (y>>8) & 0x0F);
  240 
  241         return 0;
  242 }
  243 
  244 static void
  245 t2r4curenable(VGAscr* scr)
  246 {
  247         t2r4enable(scr);
  248         if(scr->mmio == 0)
  249                 return;
  250 
  251         /*
  252          * Make sure cursor is off by initialising the cursor
  253          * control to defaults.
  254          */
  255         t2r4xo(scr, CursorCtl, 0x00);
  256 
  257         /*
  258          * Cursor colour 1 (white),
  259          * cursor colour 2 (black).
  260          */
  261         t2r4xo(scr, CursorR1, Pwhite);
  262         t2r4xo(scr, CursorG1, Pwhite);
  263         t2r4xo(scr, CursorB1, Pwhite);
  264 
  265         t2r4xo(scr, CursorR2, Pblack);
  266         t2r4xo(scr, CursorG2, Pblack);
  267         t2r4xo(scr, CursorB2, Pblack);
  268 
  269         /*
  270          * Load, locate and enable the cursor, 64x64, mode 2.
  271          */
  272         t2r4curload(scr, &arrow);
  273         t2r4curmove(scr, ZP);
  274         t2r4xo(scr, CursorCtl, CursorMode);
  275 }
  276 
  277 enum {
  278         Flow            = 0x08/4,
  279         Busy            = 0x0C/4,
  280         BufCtl          = 0x20/4,
  281         DeSorg          = 0x28/4,
  282         DeDorg          = 0x2C/4,
  283         DeSptch         = 0x40/4,
  284         DeDptch         = 0x44/4,
  285         CmdOpc          = 0x50/4,
  286         CmdRop          = 0x54/4,
  287         CmdStyle        = 0x58/4,
  288         CmdPatrn        = 0x5C/4,
  289         CmdClp          = 0x60/4,
  290         CmdPf           = 0x64/4,
  291         Fore            = 0x68/4,
  292         Back            = 0x6C/4,
  293         Mask            = 0x70/4,
  294         DeKey           = 0x74/4,
  295         Lpat            = 0x78/4,
  296         Pctrl           = 0x7C/4,
  297         Clptl           = 0x80/4,
  298         Clpbr           = 0x84/4,
  299         XY0             = 0x88/4,
  300         XY1             = 0x8C/4,
  301         XY2             = 0x90/4,
  302         XY3             = 0x94/4,
  303         XY4             = 0x98/4,
  304         Alpha           = 0x128/4,
  305         ACtl            = 0x16C/4,
  306 
  307         RBaseD          = 0x4000/4,
  308 };
  309 
  310 /* wait until pipeline ready for new command */
  311 static void
  312 waitforfifo(VGAscr *scr)
  313 {
  314         int x;
  315         ulong *d;
  316         x = 0;
  317 
  318         d = scr->mmio + RBaseD;
  319         while((d[Busy]&1) && x++ < 1000000)
  320                 ;
  321         if(x >= 1000000)        /* shouldn't happen */
  322                 iprint("busy %8lux\n", d[Busy]);
  323 }
  324 
  325 /* wait until command has finished executing */
  326 static void
  327 waitforcmd(VGAscr *scr)
  328 {
  329         int x;
  330         ulong *d;
  331         x = 0;
  332 
  333         d = scr->mmio + RBaseD;
  334         while((d[Flow]&0x1B) && x++ < 1000000)
  335                 ;
  336         if(x >= 1000000)        /* shouldn't happen */
  337                 iprint("flow %8lux\n", d[Flow]);
  338 }
  339 
  340 /* wait until memory controller not busy (i.e. wait for writes to flush) */
  341 static void
  342 waitformem(VGAscr *scr)
  343 {
  344         int x;
  345         ulong *d;
  346         x = 0;
  347 
  348         d = scr->mmio + RBaseD;
  349         while((d[Flow]&2)&& x++ < 1000000)
  350                 ;
  351         if(x >= 1000000)        /* shouldn't happen */
  352                 iprint("mem %8lux\n", d[Busy]);
  353 }
  354 
  355 static int
  356 t2r4hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
  357 {
  358         int ctl;
  359         Point dp, sp;
  360         ulong *d;
  361         int depth;
  362 
  363         if(r.min.y == sr.min.y){        /* a purely horizontal scroll */
  364                 depth = scr->gscreen->depth;
  365                 switch(depth){
  366                 case 32:
  367                         /*
  368                          * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal
  369                          * 32-bit scrolls don't work perfectly on rectangles of width <= 24.
  370                          * we bail on a bigger bound for padding.
  371                          */
  372                         if(Dx(r) < 32)
  373                                 return 0;
  374                         break;
  375                 case 16:
  376                         /*
  377                          * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal
  378                          * 16-bit scrolls don't work perfectly on rectangles of width <= 96.
  379                          * we bail on a bigger bound for padding.
  380                          */
  381                         if(Dx(r) < 104)
  382                                 return 0;
  383                         break;
  384                 }
  385         }
  386         waitformem(scr);
  387         waitforfifo(scr);
  388         d = scr->mmio + RBaseD;
  389         ctl = 0;
  390         if(r.min.x <= sr.min.x){
  391                 dp.x = r.min.x;
  392                 sp.x = sr.min.x;
  393         }else{
  394                 ctl |= 2;
  395                 dp.x = r.max.x-1;
  396                 sp.x = sr.max.x-1;
  397         }
  398 
  399         if(r.min.y < sr.min.y){
  400                 dp.y = r.min.y;
  401                 sp.y = sr.min.y;
  402         }else{
  403                 ctl |= 1;
  404                 dp.y = r.max.y-1;
  405                 sp.y = sr.max.y-1;
  406         }
  407 
  408         d[CmdOpc] = 0x1;        /* bitblt */
  409         d[CmdRop] = 0xC;        /* copy source */
  410         d[CmdStyle] = 0;
  411         d[CmdPatrn] = 0;
  412         d[Fore] = 0;
  413         d[Back] = 0;
  414 
  415         /* writing XY1 executes cmd */
  416         d[XY3] = ctl;
  417         d[XY0] = (sp.x<<16)|sp.y;
  418         d[XY2] = (Dx(r)<<16)|Dy(r);
  419         d[XY4] = 0;
  420         d[XY1] = (dp.x<<16)|dp.y;
  421         waitforcmd(scr);
  422 
  423         return 1;
  424 }
  425 
  426 static int
  427 t2r4hwfill(VGAscr *scr, Rectangle r, ulong sval)
  428 {
  429         ulong *d;
  430 
  431         d = scr->mmio + RBaseD;
  432 
  433         waitformem(scr);
  434         waitforfifo(scr);
  435         d[CmdOpc] = 0x1;        /* bitblt */
  436         d[CmdRop] = 0xC;        /* copy source */
  437         d[CmdStyle] = 1;        /* use source from Fore register */
  438         d[CmdPatrn] = 0;        /* no stipple */
  439         d[Fore] = sval;
  440         d[Back] = sval;
  441 
  442         /* writing XY1 executes cmd */
  443         d[XY3] = 0;
  444         d[XY0] = (r.min.x<<16)|r.min.y;
  445         d[XY2] = (Dx(r)<<16)|Dy(r);
  446         d[XY4] = 0;
  447         d[XY1] = (r.min.x<<16)|r.min.y;
  448         waitforcmd(scr);
  449 
  450         return 1;
  451 }
  452 
  453 static void
  454 t2r4blank(VGAscr *scr, int blank)
  455 {
  456         uchar x;
  457 
  458         x = t2r4xi(scr, CursorSyncCtl);
  459         x &= ~0x0F;
  460         if(blank)
  461                 x |= HsyncLo | VsyncLo;
  462         t2r4xo(scr, CursorSyncCtl, x);
  463 }
  464 
  465 static void
  466 t2r4drawinit(VGAscr *scr)
  467 {
  468         ulong pitch;
  469         int depth;
  470         int fmt;
  471         ulong *d;
  472 
  473         pitch = Dx(scr->gscreen->r);
  474         depth = scr->gscreen->depth;
  475 
  476         switch(scr->gscreen->chan){
  477         case RGB16:
  478                 fmt = 3;
  479                 break;
  480         case XRGB32:
  481                 fmt = 2;
  482                 break;
  483         case RGB15:
  484                 fmt = 1;
  485                 break;
  486         default:
  487                 scr->fill = nil;
  488                 scr->scroll = nil;
  489                 return;
  490         }
  491 
  492         d = scr->mmio + RBaseD;
  493 
  494         d[BufCtl] = fmt<<24;
  495         d[DeSorg] = 0;
  496         d[DeDorg] = 0;
  497         d[DeSptch] = (pitch*depth)/8;
  498         d[DeDptch] = (pitch*depth)/8;
  499         d[CmdClp] = 0;  /* 2 = inside rectangle */
  500         d[Mask] = ~0;
  501         d[DeKey] = 0;
  502         d[Clptl] = 0; 
  503         d[Clpbr] = 0xFFF0FFF0;
  504         d[Alpha] = 0;
  505         d[ACtl] = 0;
  506 
  507         scr->fill = t2r4hwfill;
  508         scr->scroll = t2r4hwscroll;
  509         scr->blank = t2r4blank;
  510         hwblank = 1;
  511 }
  512 
  513 VGAdev vgat2r4dev = {
  514         "t2r4",
  515 
  516         t2r4enable,
  517         nil,
  518         nil,
  519         nil,
  520         t2r4drawinit,
  521 };
  522 
  523 VGAcur vgat2r4cur = {
  524         "t2r4hwgc",
  525 
  526         t2r4curenable,
  527         t2r4curdisable,
  528         t2r4curload,
  529         t2r4curmove,
  530 };
  531 

Cache object: f051b30db1425bc0e6acf1db78c03f1e


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