Rev 837 | Rev 839 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 837 | Rev 838 | ||
|---|---|---|---|
| Line 32... | Line 32... | ||
| 32 | #include <console/console.h> |
32 | #include <console/console.h> |
| 33 | #include <print.h> |
33 | #include <print.h> |
| 34 | 34 | ||
| 35 | SPINLOCK_INITIALIZE(fb_lock); |
35 | SPINLOCK_INITIALIZE(fb_lock); |
| 36 | 36 | ||
| 37 | static unsigned char *fbaddress=NULL; |
37 | static __u8 *fbaddress=NULL; |
| 38 | static int xres,yres; |
38 | static int xres,yres; |
| 39 | static int position=0; |
39 | static int position=0; |
| 40 | static int columns=0; |
40 | static int columns=0; |
| 41 | static int rows=0; |
41 | static int rows=0; |
| - | 42 | static int pixelbytes=0; |
|
| 42 | 43 | ||
| 43 | #define COL_WIDTH 8 |
44 | #define COL_WIDTH 8 |
| 44 | #define ROW_HEIGHT (FONT_SCANLINES) |
45 | #define ROW_HEIGHT (FONT_SCANLINES) |
| 45 | #define ROW_PIX (xres*ROW_HEIGHT*3) |
46 | #define ROW_PIX (xres*ROW_HEIGHT*pixelbytes) |
| 46 | 47 | ||
| 47 | #define BGCOLOR 0x000080 |
48 | #define BGCOLOR 0x000080 |
| 48 | #define FGCOLOR 0xffff00 |
49 | #define FGCOLOR 0xffff00 |
| 49 | 50 | ||
| 50 | #define RED(x) ((x >> 16) & 0xff) |
51 | #define RED(x,bits) ((x >> (16+8-bits)) & ((1<<bits)-1)) |
| 51 | #define GREEN(x) ((x >> 8) & 0xff) |
52 | #define GREEN(x,bits) ((x >> (8+8-bits)) & ((1<<bits)-1)) |
| 52 | #define BLUE(x) (x & 0xff) |
53 | #define BLUE(x,bits) ((x >> (8-bits)) & ((1<<bits)-1)) |
| 53 | 54 | ||
| 54 | #define POINTPOS(x,y,colidx) ((y*xres+x)*3+colidx) |
55 | #define POINTPOS(x,y) ((y*xres+x)*pixelbytes) |
| - | 56 | ||
| - | 57 | /***************************************************************/ |
|
| - | 58 | /* Pixel specific fuctions */ |
|
| 55 | 59 | ||
| 56 | /** Draw pixel of given color on screen */ |
60 | /** Draw pixel of given color on screen */ |
| 57 | static inline void putpixel(int x,int y,int color) |
61 | static inline void putpixel(int x,int y,int color) |
| 58 | { |
62 | { |
| - | 63 | int startbyte = POINTPOS(x,y); |
|
| - | 64 | ||
| - | 65 | if (pixelbytes == 3) { |
|
| 59 | fbaddress[POINTPOS(x,y,0)] = RED(color); |
66 | fbaddress[startbyte] = RED(color,8); |
| 60 | fbaddress[POINTPOS(x,y,1)] = GREEN(color); |
67 | fbaddress[startbyte+1] = GREEN(color,8); |
| 61 | fbaddress[POINTPOS(x,y,2)] = BLUE(color); |
68 | fbaddress[startbyte+2] = BLUE(color,8); |
| - | 69 | } else if (pixelbytes == 4) { |
|
| - | 70 | *((__u32 *)(fbaddress+startbyte)) = color; |
|
| - | 71 | } else { |
|
| - | 72 | int compcolor; |
|
| - | 73 | /* 5-bit, 5-bits, 5-bits */ |
|
| - | 74 | compcolor = RED(color,5) << 10 \ |
|
| - | 75 | | GREEN(color,5) << 5 \ |
|
| - | 76 | | BLUE(color,5); |
|
| - | 77 | *((__u16 *)(fbaddress+startbyte)) = compcolor; |
|
| - | 78 | } |
|
| - | 79 | } |
|
| - | 80 | ||
| - | 81 | /** Return pixel color */ |
|
| - | 82 | static inline int getpixel(int x,int y) |
|
| - | 83 | { |
|
| - | 84 | int startbyte = POINTPOS(x,y); |
|
| - | 85 | int color; |
|
| - | 86 | int result; |
|
| - | 87 | ||
| - | 88 | if (pixelbytes == 3) { |
|
| - | 89 | result = fbaddress[startbyte] << 16 \ |
|
| - | 90 | | fbaddress[startbyte+1] << 8 \ |
|
| - | 91 | | fbaddress[startbyte+2]; |
|
| - | 92 | } else if (pixelbytes == 4) { |
|
| - | 93 | result = *((__u32 *)(fbaddress+startbyte)) & 0xffffff; |
|
| - | 94 | } else { |
|
| - | 95 | int red,green,blue; |
|
| - | 96 | color = *((__u16 *)(fbaddress+startbyte)); |
|
| - | 97 | red = (color >> 10) & 0x1f; |
|
| - | 98 | green = (color >> 5) & 0x1f; |
|
| - | 99 | blue = color & 0x1f; |
|
| - | 100 | result = (red << 16) | (green << 8) | blue; |
|
| - | 101 | } |
|
| - | 102 | return result; |
|
| 62 | } |
103 | } |
| 63 | 104 | ||
| - | 105 | static void clear_line(int y); |
|
| - | 106 | /** Scroll screen one row up */ |
|
| - | 107 | static void scroll_screen(void) |
|
| - | 108 | { |
|
| - | 109 | int i; |
|
| - | 110 | ||
| - | 111 | for (i=0;i < (xres*yres*pixelbytes)-ROW_PIX; i++) |
|
| - | 112 | fbaddress[i] = fbaddress[i+ROW_PIX]; |
|
| - | 113 | ||
| - | 114 | /* Clear last row */ |
|
| - | 115 | for (i=0; i < ROW_HEIGHT;i++) |
|
| - | 116 | clear_line((rows-1)*ROW_HEIGHT+i); |
|
| - | 117 | ||
| - | 118 | } |
|
| - | 119 | ||
| - | 120 | ||
| - | 121 | /***************************************************************/ |
|
| - | 122 | /* Screen specific function */ |
|
| - | 123 | ||
| 64 | /** Fill line with color BGCOLOR */ |
124 | /** Fill line with color BGCOLOR */ |
| 65 | static void clear_line(int y) |
125 | static void clear_line(int y) |
| 66 | { |
126 | { |
| 67 | int x; |
127 | int x; |
| 68 | for (x=0; x<xres;x++) |
128 | for (x=0; x<xres;x++) |
| Line 78... | Line 138... | ||
| 78 | clear_line(y); |
138 | clear_line(y); |
| 79 | } |
139 | } |
| 80 | 140 | ||
| 81 | static void invert_pixel(int x, int y) |
141 | static void invert_pixel(int x, int y) |
| 82 | { |
142 | { |
| 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)]; |
143 | putpixel(x,y, ~getpixel(x,y)); |
| 86 | } |
144 | } |
| 87 | 145 | ||
| 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 | 146 | ||
| 102 | /** Draw one line of glyph at a given position */ |
147 | /** Draw one line of glyph at a given position */ |
| 103 | static void draw_glyph_line(int glline, int x, int y) |
148 | static void draw_glyph_line(int glline, int x, int y) |
| 104 | { |
149 | { |
| 105 | int i; |
150 | int i; |
| Line 109... | Line 154... | ||
| 109 | putpixel(x+i,y,FGCOLOR); |
154 | putpixel(x+i,y,FGCOLOR); |
| 110 | } else |
155 | } else |
| 111 | putpixel(x+i,y,BGCOLOR); |
156 | putpixel(x+i,y,BGCOLOR); |
| 112 | } |
157 | } |
| 113 | 158 | ||
| - | 159 | /***************************************************************/ |
|
| - | 160 | /* Character-console functions */ |
|
| - | 161 | ||
| 114 | /** Draw character at given position */ |
162 | /** Draw character at given position */ |
| 115 | static void draw_glyph(unsigned char glyph, int col, int row) |
163 | static void draw_glyph(__u8 glyph, int col, int row) |
| 116 | { |
164 | { |
| 117 | int y; |
165 | int y; |
| 118 | 166 | ||
| 119 | for (y=0; y < FONT_SCANLINES; y++) |
167 | for (y=0; y < FONT_SCANLINES; y++) |
| 120 | draw_glyph_line(fb_font[glyph*FONT_SCANLINES+y], |
168 | draw_glyph_line(fb_font[glyph*FONT_SCANLINES+y], |
| Line 135... | Line 183... | ||
| 135 | static void draw_char(char chr) |
183 | static void draw_char(char chr) |
| 136 | { |
184 | { |
| 137 | draw_glyph(chr, position % columns, position/columns); |
185 | draw_glyph(chr, position % columns, position/columns); |
| 138 | } |
186 | } |
| 139 | 187 | ||
| - | 188 | /***************************************************************/ |
|
| - | 189 | /* Stdout specific functions */ |
|
| - | 190 | ||
| 140 | static void invert_cursor(void) |
191 | static void invert_cursor(void) |
| 141 | { |
192 | { |
| 142 | invert_char(position % columns, position/columns); |
193 | invert_char(position % columns, position/columns); |
| 143 | } |
194 | } |
| 144 | 195 | ||
| Line 159... | Line 210... | ||
| 159 | position -= position % columns; |
210 | position -= position % columns; |
| 160 | } else if (ch == '\b') { |
211 | } else if (ch == '\b') { |
| 161 | invert_cursor(); |
212 | invert_cursor(); |
| 162 | if (position % columns) |
213 | if (position % columns) |
| 163 | position--; |
214 | position--; |
| - | 215 | } else if (ch == '\t') { |
|
| - | 216 | invert_cursor(); |
|
| - | 217 | do { |
|
| - | 218 | draw_char(' '); |
|
| - | 219 | position++; |
|
| - | 220 | } while (position % 8); |
|
| 164 | } else { |
221 | } else { |
| 165 | draw_char(ch); |
222 | draw_char(ch); |
| 166 | position++; |
223 | position++; |
| 167 | } |
224 | } |
| 168 | if (position >= columns*rows) { |
225 | if (position >= columns*rows) { |
| Line 182... | Line 239... | ||
| 182 | /** Initialize framebuffer as a chardev output device |
239 | /** Initialize framebuffer as a chardev output device |
| 183 | * |
240 | * |
| 184 | * @param addr Address of framebuffer |
241 | * @param addr Address of framebuffer |
| 185 | * @param x X resolution |
242 | * @param x X resolution |
| 186 | * @param y Y resolution |
243 | * @param y Y resolution |
| - | 244 | * @param bytes Bytes per pixel (2,3,4) |
|
| 187 | */ |
245 | */ |
| 188 | void fb_init(__address addr, int x, int y) |
246 | void fb_init(__address addr, int x, int y, int bytes) |
| 189 | { |
247 | { |
| 190 | fbaddress = (unsigned char *)addr; |
248 | fbaddress = (unsigned char *)addr; |
| 191 | 249 | ||
| 192 | xres = x; |
250 | xres = x; |
| 193 | yres = y; |
251 | yres = y; |
| - | 252 | pixelbytes = bytes; |
|
| 194 | 253 | ||
| 195 | rows = y/ROW_HEIGHT; |
254 | rows = y/ROW_HEIGHT; |
| 196 | columns = x/COL_WIDTH; |
255 | columns = x/COL_WIDTH; |
| 197 | 256 | ||
| 198 | clear_screen(); |
257 | clear_screen(); |