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/bitsy/screen.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 "ureg.h"
    8 #include "../port/error.h"
    9 
   10 #define Image   IMAGE
   11 #include <draw.h>
   12 #include <memdraw.h>
   13 #include <cursor.h>
   14 #include "screen.h"
   15 #include "gamma.h"
   16 
   17 #define MINX    8
   18 
   19 int landscape = 0;      /* orientation of the screen, default is 0: portait */
   20 
   21 enum {
   22         Wid             = 240,
   23         Ht              = 320,
   24         Pal0    = 0x2000,       /* 16-bit pixel data in active mode (12 in passive) */
   25 
   26         hsw             = 0x00,
   27         elw             = 0x0e,
   28         blw             = 0x0d,
   29 
   30         vsw             = 0x02,
   31         efw             = 0x01,
   32         bfw             = 0x0a,
   33 
   34         pcd             = 0x10,
   35 };
   36 
   37 struct sa1110fb {
   38         /* Frame buffer for 16-bit active color */
   39         short   palette[16];            /* entry 0 set to Pal0, the rest to 0 */
   40         ushort  pixel[Wid*Ht];          /* Pixel data */
   41 } *framebuf;
   42 
   43 enum {
   44 /* LCD Control Register 0, lcd->lccr0 */
   45         LEN     =  0,   /*  1 bit */
   46         CMS     =  1,   /*  1 bit */
   47         SDS     =  2,   /*  1 bit */
   48         LDM     =  3,   /*  1 bit */
   49         BAM     =  4,   /*  1 bit */
   50         ERM     =  5,   /*  1 bit */
   51         PAS     =  7,   /*  1 bit */
   52         BLE     =  8,   /*  1 bit */
   53         DPD     =  9,   /*  1 bit */
   54         PDD     = 12,   /*  8 bits */
   55 };
   56 
   57 enum {
   58 /* LCD Control Register 1, lcd->lccr1 */
   59         PPL     =  0,   /* 10 bits */
   60         HSW     = 10,   /*  6 bits */
   61         ELW     = 16,   /*  8 bits */
   62         BLW     = 24,   /*  8 bits */
   63 };
   64 
   65 enum {
   66 /* LCD Control Register 2, lcd->lccr2 */
   67         LPP     =  0,   /* 10 bits */
   68         VSW     = 10,   /*  6 bits */
   69         EFW     = 16,   /*  8 bits */
   70         BFW     = 24,   /*  8 bits */
   71 };
   72 
   73 enum {
   74 /* LCD Control Register 3, lcd->lccr3 */
   75         PCD     =  0,   /*  8 bits */
   76         ACB     =  8,   /*  8 bits */
   77         API     = 16,   /*  4 bits */
   78         VSP     = 20,   /*  1 bit */
   79         HSP     = 21,   /*  1 bit */
   80         PCP     = 22,   /*  1 bit */
   81         OEP     = 23,   /*  1 bit */
   82 };
   83 
   84 enum {
   85 /* LCD Status Register, lcd->lcsr */
   86         LDD     =  0,   /*  1 bit */
   87         BAU     =  1,   /*  1 bit */
   88         BER     =  2,   /*  1 bit */
   89         ABC     =  3,   /*  1 bit */
   90         IOL     =  4,   /*  1 bit */
   91         IUL     =  5,   /*  1 bit */
   92         OIU     =  6,   /*  1 bit */
   93         IUU     =  7,   /*  1 bit */
   94         OOL     =  8,   /*  1 bit */
   95         OUL     =  9,   /*  1 bit */
   96         OOU     = 10,   /*  1 bit */
   97         OUU     = 11,   /*  1 bit */
   98 };
   99 
  100 struct sa1110regs {
  101         ulong   lccr0;
  102         ulong   lcsr;
  103         ulong   dummies[2];
  104         short*  dbar1;
  105         ulong   dcar1;
  106         ulong   dbar2;
  107         ulong   dcar2;
  108         ulong   lccr1;
  109         ulong   lccr2;
  110         ulong   lccr3;
  111 } *lcd;
  112 
  113 Point   ZP = {0, 0};
  114 
  115 static Memdata xgdata;
  116 
  117 static Memimage xgscreen =
  118 {
  119         { 0, 0, Wid, Ht },              /* r */
  120         { 0, 0, Wid, Ht },              /* clipr */
  121         16,                             /* depth */
  122         3,                              /* nchan */
  123         RGB16,                  /* chan */
  124         nil,                            /* cmap */
  125         &xgdata,                        /* data */
  126         0,                              /* zero */
  127         Wid/2,                  /* width */
  128         0,                              /* layer */
  129         0,                              /* flags */
  130 };
  131 
  132 struct{
  133         Point   pos;
  134         int     bwid;
  135 }out;
  136 
  137 Memimage *gscreen;
  138 Memimage *conscol;
  139 Memimage *back;
  140 
  141 Memsubfont      *memdefont;
  142 
  143 Lock            screenlock;
  144 
  145 Point           ZP = {0, 0};
  146 ushort          *vscreen;       /* virtual screen */
  147 Rectangle       window;
  148 Point           curpos;
  149 int                     h, w;
  150 int                     drawdebug;
  151 
  152 static  ulong   rep(ulong, int);
  153 static  void    screenwin(void);
  154 static  void    screenputc(char *buf);
  155 static  void    bitsyscreenputs(char *s, int n);
  156 static  void    scroll(void);
  157 
  158 static void
  159 lcdinit(void)
  160 {
  161         /* the following line works because main memory is direct mapped */
  162         gpioregs->direction |= 
  163                 GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
  164                 |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o;
  165         gpioregs->altfunc |= 
  166                 GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
  167                 |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o;
  168         framebuf->palette[0] = Pal0;
  169         lcd->dbar1 = framebuf->palette;
  170         lcd->lccr3 = pcd<<PCD | 0<<ACB | 0<<API | 1<<VSP | 1<<HSP | 0<<PCP | 0<<OEP;
  171         lcd->lccr2 = (Wid-1)<<LPP | vsw<<VSW | efw<<EFW | bfw<<BFW;
  172         lcd->lccr1 = (Ht-16)<<PPL | hsw<<HSW | elw<<ELW | blw<<BLW;
  173         lcd->lccr0 = 1<<LEN | 0<<CMS | 0<<SDS | 1<<LDM | 1<<BAM | 1<<ERM | 1<<PAS | 0<<BLE | 0<<DPD | 0<<PDD;
  174 }
  175 
  176 void
  177 flipscreen(int ls) {
  178         if (ls == landscape)
  179                 return;
  180         if (ls) {
  181                 gscreen->r = Rect(0, 0, Ht, Wid);
  182                 gscreen->clipr = gscreen->r;
  183                 gscreen->width = Ht/2;
  184                 xgdata.bdata = (uchar *)framebuf->pixel;
  185         } else {
  186                 gscreen->r = Rect(0, 0, Wid, Ht);
  187                 gscreen->clipr = gscreen->r;
  188                 gscreen->width = Wid/2;
  189                 xgdata.bdata = (uchar *)vscreen;
  190         }
  191         landscape = ls;
  192 }
  193 
  194 void
  195 lcdtweak(Cmdbuf *cmd)
  196 {
  197         if(cmd->nf < 4)
  198                 return;
  199         if(*cmd->f[0] == 'h')
  200                 lcd->lccr1 = ((Ht-16)<<PPL)
  201                         | (atoi(cmd->f[1])<<HSW)
  202                         | (atoi(cmd->f[2])<<ELW)
  203                         | (atoi(cmd->f[3])<<BLW);
  204         if(*cmd->f[0] == 'v')
  205                 lcd->lccr2 = ((Wid-1)<<LPP)
  206                         | (atoi(cmd->f[1])<<VSW)
  207                         | (atoi(cmd->f[2])<<EFW)
  208                         | (atoi(cmd->f[3])<<BFW);
  209 }
  210 
  211 void
  212 screenpower(int on)
  213 {
  214         blankscreen(on == 0);
  215 }
  216 
  217 void
  218 screeninit(void)
  219 {
  220         int i;
  221 
  222         /* map the lcd regs into the kernel's virtual space */
  223         lcd = (struct sa1110regs*)mapspecial(LCDREGS, sizeof(struct sa1110regs));;
  224 
  225         framebuf = xspanalloc(sizeof *framebuf, 0x100, 0);
  226 
  227         vscreen = xalloc(sizeof(ushort)*Wid*Ht);
  228 
  229         lcdpower(1);
  230         lcdinit();
  231 
  232         gscreen = &xgscreen;
  233 
  234         xgdata.ref = 1;
  235         i = 0;
  236         if (landscape) {
  237                 gscreen->r = Rect(0, 0, Ht, Wid);
  238                 gscreen->clipr = gscreen->r;
  239                 gscreen->width = Ht/2;
  240                 xgdata.bdata = (uchar *)framebuf->pixel;
  241                 while (i < Wid*Ht*1/3)  framebuf->pixel[i++] = 0xf800;  /* red */
  242                 while (i < Wid*Ht*2/3)  framebuf->pixel[i++] = 0xffff;          /* white */
  243                 while (i < Wid*Ht*3/3)  framebuf->pixel[i++] = 0x001f;  /* blue */
  244         } else {
  245                 gscreen->r = Rect(0, 0, Wid, Ht);
  246                 gscreen->clipr = gscreen->r;
  247                 gscreen->width = Wid/2;
  248                 xgdata.bdata = (uchar *)vscreen;
  249                 while (i < Wid*Ht*1/3)  vscreen[i++] = 0xf800;  /* red */
  250                 while (i < Wid*Ht*2/3)  vscreen[i++] = 0xffff;  /* white */
  251                 while (i < Wid*Ht*3/3)  vscreen[i++] = 0x001f;  /* blue */
  252                 flushmemscreen(gscreen->r);
  253         }
  254         memimageinit();
  255         memdefont = getmemdefont();
  256 
  257         out.pos.x = MINX;
  258         out.pos.y = 0;
  259         out.bwid = memdefont->info[' '].width;
  260 
  261         blanktime = 3;  /* minutes */
  262 
  263         screenwin();
  264 //      screenputs = bitsyscreenputs;
  265         screenputs = nil;
  266 }
  267 
  268 void
  269 flushmemscreen(Rectangle r)
  270 {
  271         int x, y;
  272         ulong start, end;
  273 
  274         if (landscape == 0) {
  275                 if (r.min.x <   0) r.min.x = 0;
  276                 if (r.max.x > Wid) r.max.x = Wid;
  277                 if (r.min.y <   0) r.min.y = 0;
  278                 if (r.max.y >  Ht) r.max.y = Ht;
  279                 for (x = r.min.x; x < r.max.x; x++)
  280                         for (y = r.min.y; y < r.max.y; y++)
  281                                 framebuf->pixel[(x+1)*Ht-1-y] = gamma[vscreen[y*Wid+x]];
  282                 start = (ulong)&framebuf->pixel[(r.min.x+1)*Ht-1-(r.max.y-1)];
  283                 end = (ulong)&framebuf->pixel[(r.max.x-1+1)*Ht-1-(r.min.y)];
  284         } else {
  285                 start = (ulong)&framebuf->pixel[r.min.y*Ht + r.min.x];
  286                 end = (ulong)&framebuf->pixel[(r.max.y-1)*Ht + r.max.x - 1];
  287         }
  288         cachewbregion(start, end-start);
  289 }
  290 
  291 /*
  292  * export screen to devdraw
  293  */
  294 uchar*
  295 attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen)
  296 {
  297         *r = gscreen->r;
  298         *d = gscreen->depth;
  299         *chan = gscreen->chan;
  300         *width = gscreen->width;
  301         *softscreen = (landscape == 0);
  302 
  303         return (uchar*)gscreen->data->bdata;
  304 }
  305 
  306 void
  307 getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb)
  308 {
  309         USED(p, pr, pg, pb);
  310 }
  311 
  312 int
  313 setcolor(ulong p, ulong r, ulong g, ulong b)
  314 {
  315         USED(p,r,g,b);
  316         return 0;
  317 }
  318 
  319 void
  320 blankscreen(int blank)
  321 {
  322         int cnt;
  323 
  324         if (blank) {
  325                 lcd->lccr0 &= ~(1<<LEN);        /* disable the LCD */
  326                 cnt = 0;
  327                 while((lcd->lcsr & (1<<LDD)) == 0) {
  328                         delay(10);
  329                         if (++cnt == 100) {
  330                                 iprint("LCD doesn't stop\n");
  331                                 break;
  332                         }
  333                 }
  334                 lcdpower(0);
  335         } else {
  336                 lcdpower(1);
  337                 lcdinit();
  338         }
  339 }
  340 
  341 static void
  342 bitsyscreenputs(char *s, int n)
  343 {
  344         int i;
  345         Rune r;
  346         char buf[4];
  347 
  348         if(!islo()) {
  349                 /* don't deadlock trying to print in interrupt */
  350                 if(!canlock(&screenlock))
  351                         return; 
  352         }
  353         else
  354                 lock(&screenlock);
  355 
  356         while(n > 0){
  357                 i = chartorune(&r, s);
  358                 if(i == 0){
  359                         s++;
  360                         --n;
  361                         continue;
  362                 }
  363                 memmove(buf, s, i);
  364                 buf[i] = 0;
  365                 n -= i;
  366                 s += i;
  367                 screenputc(buf);
  368         }
  369         unlock(&screenlock);
  370 }
  371 
  372 static void
  373 screenwin(void)
  374 {
  375         Point p, q;
  376         char *greet;
  377         Memimage *orange;
  378         Rectangle r;
  379 
  380         memsetchan(gscreen, RGB16);
  381 
  382         back = memwhite;
  383         conscol = memblack;
  384 
  385         orange = allocmemimage(Rect(0,0,1,1), RGB16);
  386         orange->flags |= Frepl;
  387         orange->clipr = gscreen->r;
  388         orange->data->bdata[0] = 0x40;
  389         orange->data->bdata[1] = 0xfd;
  390 
  391         w = memdefont->info[' '].width;
  392         h = memdefont->height;
  393 
  394         r = insetrect(gscreen->r, 4);
  395 
  396         memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
  397         window = insetrect(r, 4);
  398         memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
  399 
  400         memimagedraw(gscreen, Rect(window.min.x, window.min.y,
  401                         window.max.x, window.min.y+h+5+6), orange, ZP, nil, ZP, S);
  402         freememimage(orange);
  403         window = insetrect(window, 5);
  404 
  405         greet = " Plan 9 Console ";
  406         p = addpt(window.min, Pt(10, 0));
  407         q = memsubfontwidth(memdefont, greet);
  408         memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
  409         flushmemscreen(r);
  410         window.min.y += h+6;
  411         curpos = window.min;
  412         window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
  413 }
  414 
  415 static void
  416 screenputc(char *buf)
  417 {
  418         Point p;
  419         int w, pos;
  420         Rectangle r;
  421         static int *xp;
  422         static int xbuf[256];
  423 
  424         if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
  425                 xp = xbuf;
  426 
  427         switch(buf[0]) {
  428         case '\n':
  429                 if(curpos.y+h >= window.max.y)
  430                         scroll();
  431                 curpos.y += h;
  432                 screenputc("\r");
  433                 break;
  434         case '\r':
  435                 xp = xbuf;
  436                 curpos.x = window.min.x;
  437                 break;
  438         case '\t':
  439                 p = memsubfontwidth(memdefont, " ");
  440                 w = p.x;
  441                 if(curpos.x >= window.max.x-4*w)
  442                         screenputc("\n");
  443 
  444                 pos = (curpos.x-window.min.x)/w;
  445                 pos = 4-(pos%4);
  446                 *xp++ = curpos.x;
  447                 r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
  448                 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
  449                 flushmemscreen(r);
  450                 curpos.x += pos*w;
  451                 break;
  452         case '\b':
  453                 if(xp <= xbuf)
  454                         break;
  455                 xp--;
  456                 r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
  457                 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
  458                 flushmemscreen(r);
  459                 curpos.x = *xp;
  460                 break;
  461         case '\0':
  462                 break;
  463         default:
  464                 p = memsubfontwidth(memdefont, buf);
  465                 w = p.x;
  466 
  467                 if(curpos.x >= window.max.x-w)
  468                         screenputc("\n");
  469 
  470                 *xp++ = curpos.x;
  471                 r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y + h);
  472                 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
  473                 memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
  474                 flushmemscreen(r);
  475                 curpos.x += w;
  476         }
  477 }
  478 
  479 static void
  480 scroll(void)
  481 {
  482         int o;
  483         Point p;
  484         Rectangle r;
  485 
  486         o = 8*h;
  487         r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
  488         p = Pt(window.min.x, window.min.y+o);
  489         memimagedraw(gscreen, r, gscreen, p, nil, p, S);
  490         flushmemscreen(r);
  491         r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
  492         memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
  493         flushmemscreen(r);
  494 
  495         curpos.y -= o;
  496 }

Cache object: 6422eee492578a0d411bb24a4f68e13a


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