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/vgaet4000.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 static void
   16 setet4000page(int page)
   17 {
   18         uchar p;
   19 
   20         p = page & 0x0F;
   21         p |= p<<4;
   22         outb(0x3CD, p);
   23 
   24         p = (page & 0x30);
   25         p |= p>>4;
   26         outb(0x3CB, p);
   27 }
   28 
   29 static void
   30 et4000page(VGAscr *scr, int page)
   31 {
   32         lock(&scr->devlock);
   33         setet4000page(page);
   34         unlock(&scr->devlock);
   35 }
   36 
   37 static void
   38 et4000disable(VGAscr*)
   39 {
   40         uchar imaF7;
   41 
   42         outb(0x217A, 0xF7);
   43         imaF7 = inb(0x217B) & ~0x80;
   44         outb(0x217B, imaF7);
   45 }
   46 
   47 static void
   48 et4000enable(VGAscr *scr)
   49 {
   50         uchar imaF7;
   51 
   52         et4000disable(scr);
   53 
   54         /*
   55          * Configure CRTCB for Sprite, 64x64,
   56          * CRTC pixel overlay.
   57          */
   58         outb(0x217A, 0xEF);
   59         outb(0x217B, 0x02);
   60 
   61         /*
   62          * Cursor goes in the top left corner
   63          * of the Sprite area, so the horizontal and
   64          * vertical presets are 0.
   65          */
   66         outb(0x217A, 0xE2);
   67         outb(0x217B, 0x00);
   68         outb(0x217A, 0xE3);
   69         outb(0x217B, 0x00);
   70 
   71         outb(0x217A, 0xE6);
   72         outb(0x217B, 0x00);
   73         outb(0x217A, 0xE7);
   74         outb(0x217B, 0x00);
   75 
   76         /*
   77          * Find a place for the cursor data in display memory.
   78          * Must be on a "doubleword" boundary, but put it on a
   79          * 1024-byte boundary so that there's no danger of it
   80          * crossing a page.
   81          */
   82         scr->storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024;
   83         scr->storage *= 1024/4;
   84         outb(0x217A, 0xE8);
   85         outb(0x217B, scr->storage & 0xFF);
   86         outb(0x217A, 0xE9);
   87         outb(0x217B, (scr->storage>>8) & 0xFF);
   88         outb(0x217A, 0xEA);
   89         outb(0x217B, (scr->storage>>16) & 0x0F);
   90         scr->storage *= 4;
   91 
   92         /*
   93          * Row offset in "quadwords". Must be 2 for Sprite.
   94          * Bag the pixel-panning.
   95          * Colour depth, must be 2 for Sprite.
   96          */
   97         outb(0x217A, 0xEB);
   98         outb(0x217B, 0x02);
   99         outb(0x217A, 0xEC);
  100         outb(0x217B, 0x00);
  101 
  102         outb(0x217A, 0xED);
  103         outb(0x217B, 0x00);
  104 
  105         outb(0x217A, 0xEE);
  106 //      if(vgascreen.ldepth == 3)
  107                 outb(0x217B, 0x01);
  108 //      else
  109 //              outb(0x217B, 0x00);
  110 
  111         /*
  112          * Enable the CRTCB/Sprite.
  113          */
  114         outb(0x217A, 0xF7);
  115         imaF7 = inb(0x217B);
  116         outb(0x217B, 0x80|imaF7);
  117 }
  118 
  119 static void
  120 et4000load(VGAscr *scr, Cursor *c)
  121 {
  122         uchar p0, p1, *mem;
  123         int i, x, y;
  124         ushort p;
  125         uchar clr[2*16], set[2*16];
  126 
  127         /*
  128          * Lock the display memory so we can update the
  129          * cursor bitmap if necessary.
  130          */
  131         lock(&scr->devlock);
  132 
  133         /*
  134          * Disable the cursor.
  135          * Set the display page (do we need to restore
  136          * the current contents when done?) and the
  137          * pointer to the two planes. What if this crosses
  138          * into a new page?
  139          */
  140         et4000disable(scr);
  141 
  142         setet4000page(scr->storage>>16);
  143         mem = (uchar*)scr->vaddr + (scr->storage & 0xFFFF);
  144 
  145         /*
  146          * Initialise the 64x64 cursor RAM array. There are 2 planes,
  147          * p0 and p1. Data is written 4 pixels per byte, with p1 the
  148          * MS bit of each pixel.
  149          * The cursor mode gives the following truth table:
  150          *      p1 p0   colour
  151          *       0  0   Sprite Colour 0 (defined as 0x00)
  152          *       0  1   Sprite Colour 1 (defined as 0xFF)
  153          *       1  0   Transparent (allow CRTC pixel pass through)
  154          *       1  1   Invert (allow CRTC pixel invert through)
  155          * Put the cursor into the top-left of the 64x64 array.
  156          *
  157          * This is almost certainly wrong, since it has not
  158          * been updated for the 3rd edition color values.
  159          */
  160         memmove(clr, c->clr, sizeof(clr));
  161 //      pixreverse(clr, sizeof(clr), 0);
  162         memmove(set, c->set, sizeof(set));
  163 //      pixreverse(set, sizeof(set), 0);
  164         for(y = 0; y < 64; y++){
  165                 for(x = 0; x < 64/8; x++){
  166                         if(x < 16/8 && y < 16){
  167                                 p0 = clr[x+y*2];
  168                                 p1 = set[x+y*2];
  169 
  170                                 p = 0x0000;
  171                                 for(i = 0; i < 8; i++){
  172                                         if(p1 & (1<<(7-i))){
  173                                                 /* nothing to do */
  174                                         }
  175                                         else if(p0 & (1<<(7-i)))
  176                                                 p |= 0x01<<(2*i);
  177                                         else
  178                                                 p |= 0x02<<(2*i);
  179                                 }
  180                                 *mem++ = p & 0xFF;
  181                                 *mem++ = (p>>8) & 0xFF;
  182                         }
  183                         else {
  184                                 *mem++ = 0xAA;
  185                                 *mem++ = 0xAA;
  186                         }
  187                 }
  188         }
  189 
  190         /*
  191          * enable the cursor.
  192          */
  193         outb(0x217A, 0xF7);
  194         p = inb(0x217B)|0x80;
  195         outb(0x217B, p);
  196 
  197         unlock(&scr->devlock);
  198 }
  199 
  200 static int
  201 et4000move(VGAscr *scr, Point p)
  202 {
  203         int x, xo, y, yo;
  204 
  205         if(canlock(&scr->devlock) == 0)
  206                 return 1;
  207 
  208         /*
  209          * Mustn't position the cursor offscreen even partially,
  210          * or it disappears. Therefore, if x or y is -ve, adjust the
  211          * cursor presets instead.
  212          */
  213         if((x = p.x+scr->offset.x) < 0){
  214                 xo = -x;
  215                 x = 0;
  216         }
  217         else
  218                 xo = 0;
  219         if((y = p.y+scr->offset.y) < 0){
  220                 yo = -y;
  221                 y = 0;
  222         }
  223         else
  224                 yo = 0;
  225 
  226         /*
  227          * The cursor image is jerky if we don't do this.
  228          * The cursor information is probably fetched from
  229          * display memory during the horizontal blank active
  230          * time and it doesn't like it if the coordinates
  231          * are changed underneath.
  232          */
  233         while((vgai(Status1) & 0x08) == 0)
  234                 ;
  235 
  236         outb(0x217A, 0xE2);
  237         outb(0x217B, xo);
  238 
  239         outb(0x217A, 0xE6);
  240         outb(0x217B, yo);
  241 
  242         outb(0x217A, 0xE1);
  243         outb(0x217B, (x>>8) & 0xFF);
  244         outb(0x217A, 0xE0);
  245         outb(0x217B, x & 0xFF);
  246         outb(0x217A, 0xE5);
  247         outb(0x217B, (y>>8) & 0xFF);
  248         outb(0x217A, 0xE4);
  249         outb(0x217B, y & 0xFF);
  250 
  251         unlock(&scr->devlock);
  252         return 0;
  253 }
  254 
  255 VGAcur vgaet4000cur = {
  256         "et4000hwgc",
  257 
  258         et4000enable,
  259         et4000disable,
  260         et4000load,
  261         et4000move,
  262 };
  263 
  264 VGAdev vgaet4000dev = {
  265         "et4000",
  266 
  267         0,
  268         0,
  269         et4000page,
  270         0
  271 };

Cache object: aac9abc164a9bd85cfe879ee3b37a84f


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