Subversion Repositories HelenOS-historic

Rev

Rev 839 | Rev 891 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2006 Ondrej Palkovsky
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - 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.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #include <genarch/fb/font-8x16.h>
  30. #include <genarch/fb/fb.h>
  31. #include <console/chardev.h>
  32. #include <console/console.h>
  33. #include <panic.h>
  34.  
  35. #include "helenos.xbm"
  36.  
  37. SPINLOCK_INITIALIZE(fb_lock);
  38.  
  39. static __u8 *fbaddress=NULL;
  40. static int xres,yres;
  41. static int position=0;
  42. static int columns=0;
  43. static int rows=0;
  44. static int pixelbytes=0;
  45.  
  46. #define COL_WIDTH   8
  47. #define ROW_HEIGHT  (FONT_SCANLINES)
  48. #define ROW_PIX     (xres*ROW_HEIGHT*pixelbytes)
  49.  
  50. #define BGCOLOR   0x000080
  51. #define FGCOLOR   0xffff00
  52. #define LOGOCOLOR 0x2020b0
  53.  
  54. #define RED(x,bits)    ((x >> (16+8-bits)) & ((1<<bits)-1))
  55. #define GREEN(x,bits)  ((x >> (8+8-bits)) & ((1<<bits)-1))
  56. #define BLUE(x,bits)   ((x >> (8-bits)) & ((1<<bits)-1))
  57.  
  58. #define POINTPOS(x,y)   ((y*xres+x)*pixelbytes)
  59.  
  60. /***************************************************************/
  61. /* Pixel specific fuctions */
  62.  
  63. static void (*putpixel)(int x,int y,int color);
  64. static int (*getpixel)(int x,int y);
  65.  
  66. /** Put pixel - 24-bit depth, 1 free byte */
  67. static void putpixel_4byte(int x,int y,int color)
  68. {
  69.     int startbyte = POINTPOS(x,y);
  70.  
  71.     *((__u32 *)(fbaddress+startbyte)) = color;
  72. }
  73.  
  74. /** Return pixel color */
  75. static int getpixel_4byte(int x,int y)
  76. {
  77.     int startbyte = POINTPOS(x,y);
  78.  
  79.     return *((__u32 *)(fbaddress+startbyte)) & 0xffffff;
  80. }
  81.  
  82. /** Draw pixel of given color on screen - 24-bit depth */
  83. static void putpixel_3byte(int x,int y,int color)
  84. {
  85.     int startbyte = POINTPOS(x,y);
  86.  
  87.     fbaddress[startbyte] = RED(color,8);
  88.     fbaddress[startbyte+1] = GREEN(color,8);
  89.     fbaddress[startbyte+2] = BLUE(color,8);
  90. }
  91.  
  92. static int getpixel_3byte(int x,int y)
  93. {
  94.     int startbyte = POINTPOS(x,y);
  95.     int result;
  96.  
  97.     result = fbaddress[startbyte] << 16 \
  98.         | fbaddress[startbyte+1] << 8 \
  99.         | fbaddress[startbyte+2];
  100.     return result;
  101. }
  102.  
  103. /** Put pixel - 16-bit depth (5:6:6) */
  104. static void putpixel_2byte(int x,int y,int color)
  105. {
  106.     int startbyte = POINTPOS(x,y);
  107.     int compcolor;
  108.  
  109.     /* 5-bit, 5-bits, 5-bits */
  110.     compcolor = RED(color,5) << 11 \
  111.         | GREEN(color,6) << 5 \
  112.         | BLUE(color,5);
  113.     *((__u16 *)(fbaddress+startbyte)) = compcolor;
  114. }
  115.  
  116. static int getpixel_2byte(int x,int y)
  117. {
  118.     int startbyte = POINTPOS(x,y);
  119.     int color;
  120.     int red,green,blue;
  121.  
  122.     color = *((__u16 *)(fbaddress+startbyte));
  123.     red = (color >> 11) & 0x1f;
  124.     green = (color >> 5) & 0x3f;
  125.     blue = color & 0x1f;
  126.     return (red << (16+3)) | (green << (8+2)) | (blue << 3);
  127. }
  128.  
  129. /** Put pixel - 8-bit depth (3:3:2) */
  130. static void putpixel_1byte(int x,int y,int color)
  131. {
  132.     int compcolor;
  133.  
  134.     /* 3-bit, 3-bits, 2-bits */
  135.     compcolor = RED(color,3) << 5 \
  136.         | GREEN(color,3) << 2 \
  137.         | BLUE(color,2);
  138.     fbaddress[POINTPOS(x,y)] = compcolor;
  139. }
  140.  
  141.  
  142. static int getpixel_1byte(int x,int y)
  143. {
  144.     int color;
  145.     int red,green,blue;
  146.  
  147.     color = fbaddress[POINTPOS(x,y)];
  148.     red = (color >> 5) & 0x7;
  149.     green = (color >> 5) & 0x7;
  150.     blue = color & 0x3;
  151.     return (red << (16+5)) | (green << (8+5)) | blue << 6;
  152. }
  153.  
  154. static void clear_line(int y);
  155. /** Scroll screen one row up */
  156. static void scroll_screen(void)
  157. {
  158.     int i;
  159.  
  160.     for (i=0;i < (xres*yres*pixelbytes)-ROW_PIX; i++)
  161.         fbaddress[i] = fbaddress[i+ROW_PIX];
  162.  
  163.     /* Clear last row */
  164.     for (i=0; i < ROW_HEIGHT;i++)
  165.         clear_line((rows-1)*ROW_HEIGHT+i);
  166.    
  167. }
  168.  
  169.  
  170. /***************************************************************/
  171. /* Screen specific function */
  172.  
  173. /** Fill line with color BGCOLOR */
  174. static void clear_line(int y)
  175. {
  176.     int x;
  177.     for (x=0; x<xres;x++)
  178.         (*putpixel)(x,y,BGCOLOR);
  179. }
  180.  
  181. /** Fill screen with background color */
  182. static void clear_screen(void)
  183. {
  184.     int y;
  185.  
  186.     for (y=0; y<yres;y++)
  187.         clear_line(y);
  188. }
  189.  
  190. static void invert_pixel(int x, int y)
  191. {
  192.     (*putpixel)(x,y, ~(*getpixel)(x,y));
  193. }
  194.  
  195.  
  196. /** Draw one line of glyph at a given position */
  197. static void draw_glyph_line(int glline, int x, int y)
  198. {
  199.     int i;
  200.  
  201.     for (i=0; i < 8; i++)
  202.         if (glline & (1 << (7-i))) {
  203.             (*putpixel)(x+i,y,FGCOLOR);
  204.         } else
  205.             (*putpixel)(x+i,y,BGCOLOR);
  206. }
  207.  
  208. /***************************************************************/
  209. /* Character-console functions */
  210.  
  211. /** Draw character at given position */
  212. static void draw_glyph(__u8 glyph, int col, int row)
  213. {
  214.     int y;
  215.  
  216.     for (y=0; y < FONT_SCANLINES; y++)
  217.         draw_glyph_line(fb_font[glyph*FONT_SCANLINES+y],
  218.                 col*COL_WIDTH, row*ROW_HEIGHT+y);
  219. }
  220.  
  221. /** Invert character at given position */
  222. static void invert_char(int col, int row)
  223. {
  224.     int x,y;
  225.  
  226.     for (x=0; x < COL_WIDTH; x++)
  227.         for (y=0; y < FONT_SCANLINES; y++)
  228.             invert_pixel(col*COL_WIDTH+x,row*ROW_HEIGHT+y);
  229. }
  230.  
  231. /** Draw character at default position */
  232. static void draw_char(char chr)
  233. {
  234.     draw_glyph(chr, position % columns, position/columns);
  235. }
  236.  
  237. static void draw_logo(int startx, int starty)
  238. {
  239.     int x,y;
  240.     int byte;
  241.     int rowbytes;
  242.  
  243.     rowbytes = (helenos_width-1)/8 + 1;
  244.  
  245.     for (y=0;y < helenos_height;y++)
  246.         for (x=0;x < helenos_width; x++ ) {
  247.             byte = helenos_bits[rowbytes*y + x/8];
  248.             byte >>= x % 8;
  249.             if (byte & 1)
  250.                 (*putpixel)(startx+x,starty+y,LOGOCOLOR);
  251.         }
  252. }
  253.  
  254. /***************************************************************/
  255. /* Stdout specific functions */
  256.  
  257. static void invert_cursor(void)
  258. {
  259.     invert_char(position % columns, position/columns);
  260. }
  261.  
  262. /** Print character to screen
  263.  *
  264.  *  Emulate basic terminal commands
  265.  */
  266. static void fb_putchar(chardev_t *dev, char ch)
  267. {
  268.     spinlock_lock(&fb->lock);
  269.  
  270.     if (ch == '\n') {
  271.         invert_cursor();
  272.         position += columns;
  273.         position -= position % columns;
  274.     } else if (ch == '\r') {
  275.         invert_cursor();
  276.         position -= position % columns;
  277.     } else if (ch == '\b') {
  278.         invert_cursor();
  279.         if (position % columns)
  280.             position--;
  281.     } else if (ch == '\t') {
  282.         invert_cursor();
  283.         do {
  284.             draw_char(' ');
  285.             position++;
  286.         } while (position % 8);
  287.     } else {
  288.         draw_char(ch);
  289.         position++;
  290.     }
  291.     if (position >= columns*rows) {
  292.         position -= columns;
  293.         scroll_screen();
  294.     }
  295.     invert_cursor();
  296.     spinlock_unlock(&fb->lock);
  297. }
  298.  
  299. static chardev_t framebuffer;
  300. static chardev_operations_t fb_ops = {
  301.     .write = fb_putchar,
  302. };
  303.  
  304.  
  305. /** Initialize framebuffer as a chardev output device
  306.  *
  307.  * @param addr Address of framebuffer
  308.  * @param x X resolution
  309.  * @param y Y resolution
  310.  * @param bytes Bytes per pixel (2,3,4)
  311.  */
  312. void fb_init(__address addr, int x, int y, int bytes)
  313. {
  314.     fbaddress = (unsigned char *)addr;
  315.  
  316.     switch (bytes) {
  317.     case 1:
  318.         putpixel = putpixel_1byte;
  319.         getpixel = getpixel_1byte;
  320.         break;
  321.     case 2:
  322.         putpixel = putpixel_2byte;
  323.         getpixel = getpixel_2byte;
  324.         break;
  325.     case 3:
  326.         putpixel = putpixel_3byte;
  327.         getpixel = getpixel_3byte;
  328.         break;
  329.     case 4:
  330.         putpixel = putpixel_4byte;
  331.         getpixel = getpixel_4byte;
  332.         break;
  333.     default:
  334.         panic("Unsupported color depth");
  335.     }
  336.    
  337.     xres = x;
  338.     yres = y;
  339.     pixelbytes = bytes;
  340.    
  341.     rows = y/ROW_HEIGHT;
  342.     columns = x/COL_WIDTH;
  343.  
  344.     clear_screen();
  345.     draw_logo(xres-helenos_width, 0);
  346.     invert_cursor();
  347.  
  348.     chardev_initialize("fb", &framebuffer, &fb_ops);
  349.     stdout = &framebuffer;
  350. }
  351.  
  352.