Subversion Repositories HelenOS

Rev

Rev 837 | 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 <fb/font-8x16.h>
  30. #include <fb/fb.h>
  31. #include <console/chardev.h>
  32. #include <console/console.h>
  33. #include <print.h>
  34.  
  35. SPINLOCK_INITIALIZE(fb_lock);
  36.  
  37. static unsigned char *fbaddress=NULL;
  38. static int xres,yres;
  39. static int position=0;
  40. static int columns=0;
  41. static int rows=0;
  42.  
  43. #define COL_WIDTH   8
  44. #define ROW_HEIGHT  (FONT_SCANLINES)
  45. #define ROW_PIX     (xres*ROW_HEIGHT*3)
  46.  
  47. #define BGCOLOR   0x000080
  48. #define FGCOLOR   0xffff00
  49.  
  50. #define RED(x)    ((x >> 16) & 0xff)
  51. #define GREEN(x)  ((x >> 8) & 0xff)
  52. #define BLUE(x)   (x & 0xff)
  53.  
  54. #define POINTPOS(x,y,colidx)   ((y*xres+x)*3+colidx)
  55.  
  56. /** Draw pixel of given color on screen */
  57. static inline void putpixel(int x,int y,int color)
  58. {
  59.     fbaddress[POINTPOS(x,y,0)] = RED(color);
  60.     fbaddress[POINTPOS(x,y,1)] = GREEN(color);
  61.     fbaddress[POINTPOS(x,y,2)] = BLUE(color);
  62. }
  63.  
  64. /** Fill line with color BGCOLOR */
  65. static void clear_line(int y)
  66. {
  67.     int x;
  68.     for (x=0; x<xres;x++)
  69.         putpixel(x,y,BGCOLOR);
  70. }
  71.  
  72. /** Fill screen with background color */
  73. static void clear_screen(void)
  74. {
  75.     int y;
  76.  
  77.     for (y=0; y<yres;y++)
  78.         clear_line(y);
  79. }
  80.  
  81. static void invert_pixel(int x, int y)
  82. {
  83.     fbaddress[POINTPOS(x,y,0)] = ~fbaddress[POINTPOS(x,y,0)];
  84.     fbaddress[POINTPOS(x,y,1)] = ~fbaddress[POINTPOS(x,y,1)];
  85.     fbaddress[POINTPOS(x,y,2)] = ~fbaddress[POINTPOS(x,y,2)];
  86. }
  87.  
  88. /** Scroll screen one row up */
  89. static void scroll_screen(void)
  90. {
  91.     int i;
  92.  
  93.     for (i=0;i < (xres*yres*3)-ROW_PIX; i++)
  94.         fbaddress[i] = fbaddress[i+ROW_PIX];
  95.  
  96.     /* Clear last row */
  97.     for (i=0; i < ROW_HEIGHT;i++)
  98.         clear_line((rows-1)*ROW_HEIGHT+i);
  99.    
  100. }
  101.  
  102. /** Draw one line of glyph at a given position */
  103. static void draw_glyph_line(int glline, int x, int y)
  104. {
  105.     int i;
  106.  
  107.     for (i=0; i < 8; i++)
  108.         if (glline & (1 << (7-i))) {
  109.             putpixel(x+i,y,FGCOLOR);
  110.         } else
  111.             putpixel(x+i,y,BGCOLOR);
  112. }
  113.  
  114. /** Draw character at given position */
  115. static void draw_glyph(unsigned char glyph, int col, int row)
  116. {
  117.     int y;
  118.  
  119.     for (y=0; y < FONT_SCANLINES; y++)
  120.         draw_glyph_line(fb_font[glyph*FONT_SCANLINES+y],
  121.                 col*COL_WIDTH, row*ROW_HEIGHT+y);
  122. }
  123.  
  124. /** Invert character at given position */
  125. static void invert_char(int col, int row)
  126. {
  127.     int x,y;
  128.  
  129.     for (x=0; x < COL_WIDTH; x++)
  130.         for (y=0; y < FONT_SCANLINES; y++)
  131.             invert_pixel(col*COL_WIDTH+x,row*ROW_HEIGHT+y);
  132. }
  133.  
  134. /** Draw character at default position */
  135. static void draw_char(char chr)
  136. {
  137.     draw_glyph(chr, position % columns, position/columns);
  138. }
  139.  
  140. static void invert_cursor(void)
  141. {
  142.     invert_char(position % columns, position/columns);
  143. }
  144.  
  145. /** Print character to screen
  146.  *
  147.  *  Emulate basic terminal commands
  148.  */
  149. static void fb_putchar(chardev_t *dev, char ch)
  150. {
  151.     spinlock_lock(&fb->lock);
  152.  
  153.     if (ch == '\n') {
  154.         invert_cursor();
  155.         position += columns;
  156.         position -= position % columns;
  157.     } else if (ch == '\r') {
  158.         invert_cursor();
  159.         position -= position % columns;
  160.     } else if (ch == '\b') {
  161.         invert_cursor();
  162.         if (position % columns)
  163.             position--;
  164.     } else {
  165.         draw_char(ch);
  166.         position++;
  167.     }
  168.     if (position >= columns*rows) {
  169.         position -= columns;
  170.         scroll_screen();
  171.     }
  172.     invert_cursor();
  173.     spinlock_unlock(&fb->lock);
  174. }
  175.  
  176. static chardev_t framebuffer;
  177. static chardev_operations_t fb_ops = {
  178.     .write = fb_putchar,
  179. };
  180.  
  181.  
  182. /** Initialize framebuffer as a chardev output device
  183.  *
  184.  * @param addr Address of framebuffer
  185.  * @param x X resolution
  186.  * @param y Y resolution
  187.  */
  188. void fb_init(__address addr, int x, int y)
  189. {
  190.     fbaddress = (unsigned char *)addr;
  191.    
  192.     xres = x;
  193.     yres = y;
  194.    
  195.     rows = y/ROW_HEIGHT;
  196.     columns = x/COL_WIDTH;
  197.  
  198.     clear_screen();
  199.     invert_cursor();
  200.  
  201.     chardev_initialize("fb", &framebuffer, &fb_ops);
  202.     stdout = &framebuffer;
  203. }
  204.  
  205.