source: mainline/genarch/src/fb/fb.c@ a29bd22

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a29bd22 was a29bd22, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Fixed getpixel_1byte to work with 3:2:3 color scheme.

  • Property mode set to 100644
File size: 8.0 KB
Line 
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
37SPINLOCK_INITIALIZE(fb_lock);
38
39static __u8 *fbaddress=NULL;
40static int xres,yres;
41static int position=0;
42static int columns=0;
43static int rows=0;
44static 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
63static void (*putpixel)(int x,int y,int color);
64static int (*getpixel)(int x,int y);
65
66/** Put pixel - 24-bit depth, 1 free byte */
67static 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 */
75static 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 */
83static 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
92static 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) */
104static 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
116static 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:2:3) */
130static void putpixel_1byte(int x,int y,int color)
131{
132 int compcolor;
133
134 /* 3-bit, 2-bits, 3-bits */
135 compcolor = RED(color,3) << 5 \
136 | GREEN(color,2) << 3 \
137 | BLUE(color,3);
138 fbaddress[POINTPOS(x,y)] = compcolor;
139}
140
141
142static 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 >> 3) & 0x3;
150 blue = color & 0x7;
151 return (red << (16+5)) | (green << (8+6)) | blue << 5;
152}
153
154static void clear_line(int y);
155/** Scroll screen one row up */
156static 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 */
174static 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 */
182static void clear_screen(void)
183{
184 int y;
185
186 for (y=0; y<yres;y++)
187 clear_line(y);
188}
189
190static 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 */
197static 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 */
212static 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 */
222static 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 */
232static void draw_char(char chr)
233{
234 draw_glyph(chr, position % columns, position/columns);
235}
236
237static 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
257static 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 */
266static 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
299static chardev_t framebuffer;
300static 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 */
312void 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
Note: See TracBrowser for help on using the repository browser.