Subversion Repositories HelenOS-historic

Rev

Rev 1671 | Rev 1683 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1671 Rev 1682
Line 34... Line 34...
34
#include <mm/slab.h>
34
#include <mm/slab.h>
35
#include <align.h>
35
#include <align.h>
36
#include <panic.h>
36
#include <panic.h>
37
#include <memstr.h>
37
#include <memstr.h>
38
#include <config.h>
38
#include <config.h>
-
 
39
#include <bitops.h>
-
 
40
#include <print.h>
39
 
41
 
40
#include "helenos.xbm"
42
#include "helenos.xbm"
41
 
43
 
42
SPINLOCK_INITIALIZE(fb_lock);
44
SPINLOCK_INITIALIZE(fb_lock);
43
 
45
 
44
static __u8 *fbaddress = NULL;
46
static __u8 *fbaddress = NULL;
45
 
47
 
46
static __u8 *blankline = NULL;
48
static __u8 *blankline = NULL;
-
 
49
static __u8 *dbbuffer = NULL; /* Buffer for fast scrolling console */
-
 
50
static int dboffset;
47
 
51
 
48
static unsigned int xres = 0;
52
static unsigned int xres = 0;
49
static unsigned int yres = 0;
53
static unsigned int yres = 0;
50
static unsigned int scanline = 0;
54
static unsigned int scanline = 0;
51
static unsigned int bitspp = 0;
55
static unsigned int bitspp = 0;
Line 65... Line 69...
65
 
69
 
66
#define RED(x, bits)    ((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
70
#define RED(x, bits)    ((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
67
#define GREEN(x, bits)  ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
71
#define GREEN(x, bits)  ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
68
#define BLUE(x, bits)   ((x >> (8 - bits)) & ((1 << bits) - 1))
72
#define BLUE(x, bits)   ((x >> (8 - bits)) & ((1 << bits) - 1))
69
 
73
 
70
#define POINTPOS(x, y)  (y * scanline + x * pixelbytes)
74
#define POINTPOS(x, y)  ((y) * scanline + (x) * pixelbytes)
71
 
75
 
72
/***************************************************************/
76
/***************************************************************/
73
/* Pixel specific fuctions */
77
/* Pixel specific fuctions */
74
 
78
 
75
static void (*putpixel)(unsigned int x, unsigned int y, int color);
79
static void (*rgb2scr)(void *, int);
76
static int (*getpixel)(unsigned int x, unsigned int y);
80
static int (*scr2rgb)(void *);
77
 
81
 
78
/** Put pixel - 24-bit depth, 1 free byte */
82
/* Conversion routines between different color representations */
79
static void putpixel_4byte(unsigned int x, unsigned int y, int color)
83
static void rgb_4byte(void *dst, int rgb)
80
{
84
{
81
    *((__u32 *)(fbaddress + POINTPOS(x, y))) = color;
85
    *(int *)dst = rgb;
82
}
86
}
83
 
87
 
84
/** Return pixel color - 24-bit depth, 1 free byte */
-
 
85
static int getpixel_4byte(unsigned int x, unsigned int y)
88
static int byte4_rgb(void *src)
86
{
89
{
87
    return *((__u32 *)(fbaddress + POINTPOS(x, y))) & 0xffffff;
90
    return (*(int *)src) & 0xffffff;
88
}
91
}
89
 
92
 
90
/** Put pixel - 24-bit depth */
-
 
91
static void putpixel_3byte(unsigned int x, unsigned int y, int color)
93
static void rgb_3byte(void *dst, int rgb)
92
{
94
{
93
    unsigned int startbyte = POINTPOS(x, y);
95
    __u8 *scr = dst;
94
 
-
 
95
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
96
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
96
    fbaddress[startbyte] = RED(color, 8);
97
    scr[0] = RED(rgb, 8);
97
    fbaddress[startbyte + 1] = GREEN(color, 8);
98
    scr[1] = GREEN(rgb, 8);
98
    fbaddress[startbyte + 2] = BLUE(color, 8);
99
    scr[2] = BLUE(rgb, 8);
99
#else
100
#else
100
    fbaddress[startbyte + 2] = RED(color, 8);
101
    scr[2] = RED(rgb, 8);
101
    fbaddress[startbyte + 1] = GREEN(color, 8);
102
    scr[1] = GREEN(rgb, 8);
102
    fbaddress[startbyte + 0] = BLUE(color, 8);
103
    scr[0] = BLUE(rgb, 8);
103
#endif  
104
#endif
104
}
105
}
105
 
106
 
106
/** Return pixel color - 24-bit depth */
-
 
107
static int getpixel_3byte(unsigned int x, unsigned int y)
107
static int byte3_rgb(void *src)
108
{
108
{
109
    unsigned int startbyte = POINTPOS(x, y);
109
    __u8 *scr = src;
110
 
-
 
111
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
110
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
112
    return fbaddress[startbyte] << 16 | fbaddress[startbyte + 1] << 8 | fbaddress[startbyte + 2];
111
    return scr[0] << 16 | scr[1] << 8 | scr[2];
113
#else
112
#else
114
    return fbaddress[startbyte + 2] << 16 | fbaddress[startbyte + 1] << 8 | fbaddress[startbyte + 0];
113
    return scr[2] << 16 | scr[1] << 8 | scr[0];
115
#endif  
114
#endif  
116
}
115
}
117
 
116
 
118
/** Put pixel - 16-bit depth (5:6:6) */
117
/**  16-bit depth (5:6:5) */
119
static void putpixel_2byte(unsigned int x, unsigned int y, int color)
118
static void rgb_2byte(void *dst, int rgb)
120
{
119
{
121
    /* 5-bit, 5-bits, 5-bits */
120
    /* 5-bit, 6-bits, 5-bits */
122
    *((__u16 *)(fbaddress + POINTPOS(x, y))) = RED(color, 5) << 11 | GREEN(color, 6) << 5 | BLUE(color, 5);
121
    *((__u16 *)(dst)) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | BLUE(rgb, 5);
123
}
122
}
124
 
123
 
125
/** Return pixel color - 16-bit depth (5:6:6) */
124
/** 16-bit depth (5:6:5) */
126
static int getpixel_2byte(unsigned int x, unsigned int y)
125
static int byte2_rgb(void *src)
127
{
126
{
128
    int color = *((__u16 *)(fbaddress + POINTPOS(x, y)));
127
    int color = *(__u16 *)(src);
129
    return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
128
    return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
130
}
129
}
131
 
130
 
132
/** Put pixel - 8-bit depth (3:2:3) */
131
/** Put pixel - 8-bit depth (3:2:3) */
133
static void putpixel_1byte(unsigned int x, unsigned int y, int color)
132
static void rgb_1byte(void *dst, int rgb)
134
{
133
{
135
    fbaddress[POINTPOS(x, y)] = RED(color, 3) << 5 | GREEN(color, 2) << 3 | BLUE(color, 3);
134
    *(__u8 *)dst = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | BLUE(rgb, 3);
136
}
135
}
137
 
136
 
138
/** Return pixel color - 8-bit depth (3:2:3) */
137
/** Return pixel color - 8-bit depth (3:2:3) */
139
static int getpixel_1byte(unsigned int x, unsigned int y)
138
static int byte1_rgb(void *src)
140
{
139
{
141
    int color = fbaddress[POINTPOS(x, y)];
140
    int color = *(__u8 *)src;
142
    return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
141
    return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
143
}
142
}
144
 
143
 
145
/** Fill line with color BGCOLOR */
-
 
146
static void clear_line(unsigned int y)
144
static void putpixel(unsigned int x, unsigned int y, int color)
147
{
145
{
-
 
146
    (*rgb2scr)(&fbaddress[POINTPOS(x,y)],color);
-
 
147
 
148
    unsigned int x;
148
    if (dbbuffer) {
-
 
149
        int dline = (y + dboffset) % yres;
-
 
150
        (*rgb2scr)(&dbbuffer[POINTPOS(x,dline)],color);
149
   
151
    }
-
 
152
}
-
 
153
 
150
    for (x = 0; x < xres; x++)
154
/** Get pixel from viewport */
-
 
155
static int getpixel(unsigned int x, unsigned int y)
-
 
156
{
-
 
157
    if (dbbuffer) {
151
        (*putpixel)(x, y, BGCOLOR);
158
        int dline = (y + dboffset) % yres;
-
 
159
        return (*scr2rgb)(&dbbuffer[POINTPOS(x,dline)]);
-
 
160
    }
-
 
161
    return (*scr2rgb)(&fbaddress[POINTPOS(x,y)]);
152
}
162
}
153
 
163
 
154
 
164
 
155
/** Fill screen with background color */
165
/** Fill screen with background color */
156
static void clear_screen(void)
166
static void clear_screen(void)
157
{
167
{
158
    unsigned int y;
168
    unsigned int y;
159
 
169
 
160
    for (y = 0; y < yres; y++)
170
    for (y = 0; y < yres; y++) {
-
 
171
        memcpy(&fbaddress[scanline*y], blankline, xres*pixelbytes);
161
        clear_line(y);
172
        if (dbbuffer)
-
 
173
            memcpy(&dbbuffer[scanline*y], blankline, xres*pixelbytes);
-
 
174
    }
162
}
175
}
163
 
176
 
164
 
177
 
165
/** Scroll screen one row up */
178
/** Scroll screen one row up */
166
static void scroll_screen(void)
179
static void scroll_screen(void)
167
{
180
{
168
    __u8 *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
181
    __u8 *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
-
 
182
    int firstsz;
169
 
183
 
-
 
184
    if (dbbuffer) {
170
    memcpy((void *) fbaddress, (void *) &fbaddress[ROW_BYTES], scanline * yres - ROW_BYTES);
185
        memcpy(&dbbuffer[dboffset*scanline], blankline, FONT_SCANLINES*scanline);
-
 
186
       
-
 
187
        dboffset = (dboffset + FONT_SCANLINES) % yres;
-
 
188
        firstsz = yres-dboffset;
171
 
189
 
-
 
190
        memcpy(fbaddress, &dbbuffer[scanline*dboffset], firstsz*scanline);
-
 
191
        memcpy(&fbaddress[firstsz*scanline], dbbuffer, dboffset*scanline);
-
 
192
    } else {
-
 
193
        memcpy((void *) fbaddress, (void *) &fbaddress[ROW_BYTES], scanline * yres - ROW_BYTES);
172
    /* Clear last row */
194
        /* Clear last row */
173
    memcpy((void *) lastline, (void *) blankline, ROW_BYTES);
195
        memcpy((void *) lastline, (void *) blankline, ROW_BYTES);
-
 
196
    }
174
}
197
}
175
 
198
 
176
 
199
 
177
static void invert_pixel(unsigned int x, unsigned int y)
200
static void invert_pixel(unsigned int x, unsigned int y)
178
{
201
{
179
    (*putpixel)(x, y, ~(*getpixel)(x, y));
202
    putpixel(x, y, ~getpixel(x, y));
180
}
203
}
181
 
204
 
182
 
205
 
183
/** Draw one line of glyph at a given position */
206
/** Draw one line of glyph at a given position */
184
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
207
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
185
{
208
{
186
    unsigned int i;
209
    unsigned int i;
187
 
210
 
188
    for (i = 0; i < 8; i++)
211
    for (i = 0; i < 8; i++)
189
        if (glline & (1 << (7 - i))) {
212
        if (glline & (1 << (7 - i))) {
190
            (*putpixel)(x + i, y, FGCOLOR);
213
            putpixel(x + i, y, FGCOLOR);
191
        } else
214
        } else
192
            (*putpixel)(x + i, y, BGCOLOR);
215
            putpixel(x + i, y, BGCOLOR);
193
}
216
}
194
 
217
 
195
/***************************************************************/
218
/***************************************************************/
196
/* Character-console functions */
219
/* Character-console functions */
197
 
220
 
Line 233... Line 256...
233
    for (y = 0; y < helenos_height; y++)
256
    for (y = 0; y < helenos_height; y++)
234
        for (x = 0; x < helenos_width; x++) {
257
        for (x = 0; x < helenos_width; x++) {
235
            byte = helenos_bits[rowbytes * y + x / 8];
258
            byte = helenos_bits[rowbytes * y + x / 8];
236
            byte >>= x % 8;
259
            byte >>= x % 8;
237
            if (byte & 1)
260
            if (byte & 1)
238
                (*putpixel)(startx + x, starty + y, LOGOCOLOR);
261
                putpixel(startx + x, starty + y, LOGOCOLOR);
239
        }
262
        }
240
}
263
}
241
 
264
 
242
/***************************************************************/
265
/***************************************************************/
243
/* Stdout specific functions */
266
/* Stdout specific functions */
Line 309... Line 332...
309
 */
332
 */
310
void fb_init(__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan)
333
void fb_init(__address addr, unsigned int x, unsigned int y, unsigned int bpp, unsigned int scan)
311
{
334
{
312
    switch (bpp) {
335
    switch (bpp) {
313
        case 8:
336
        case 8:
314
            putpixel = putpixel_1byte;
337
            rgb2scr = rgb_1byte;
315
            getpixel = getpixel_1byte;
338
            scr2rgb = byte1_rgb;
316
            pixelbytes = 1;
339
            pixelbytes = 1;
317
            break;
340
            break;
318
        case 16:
341
        case 16:
319
            putpixel = putpixel_2byte;
342
            rgb2scr = rgb_2byte;
320
            getpixel = getpixel_2byte;
343
            scr2rgb = byte2_rgb;
321
            pixelbytes = 2;
344
            pixelbytes = 2;
322
            break;
345
            break;
323
        case 24:
346
        case 24:
324
            putpixel = putpixel_3byte;
347
            rgb2scr = rgb_3byte;
325
            getpixel = getpixel_3byte;
348
            scr2rgb = byte3_rgb;
326
            pixelbytes = 3;
349
            pixelbytes = 3;
327
            break;
350
            break;
328
        case 32:
351
        case 32:
329
            putpixel = putpixel_4byte;
352
            rgb2scr = rgb_4byte;
330
            getpixel = getpixel_4byte;
353
            scr2rgb = byte4_rgb;
331
            pixelbytes = 4;
354
            pixelbytes = 4;
332
            break;
355
            break;
333
        default:
356
        default:
334
            panic("Unsupported bpp");
357
            panic("Unsupported bpp");
335
    }
358
    }
Line 345... Line 368...
345
    scanline = scan;
368
    scanline = scan;
346
   
369
   
347
    rows = y / FONT_SCANLINES;
370
    rows = y / FONT_SCANLINES;
348
    columns = x / COL_WIDTH;
371
    columns = x / COL_WIDTH;
349
 
372
 
-
 
373
    /* Allocate double buffer */
-
 
374
    int totsize = scanline * yres;
-
 
375
    int pages = SIZE2FRAMES(totsize);
-
 
376
    int order;
-
 
377
    int rc;
-
 
378
    if (pages == 1)
350
    clear_screen();
379
        order = 0;
-
 
380
    else
-
 
381
        order = fnzb(pages-1)+1;
-
 
382
 
-
 
383
    pfn_t frame = frame_alloc_rc(order,FRAME_ATOMIC,&rc);
-
 
384
    if (!rc)
-
 
385
        dbbuffer = (void *)PA2KA(PFN2ADDR(frame));
-
 
386
    else
-
 
387
        printf("Failed to allocate scroll buffer.\n");
-
 
388
    dboffset = 0;
-
 
389
 
-
 
390
    /* Initialized blank line */
351
    blankline = (__u8 *) malloc(ROW_BYTES, FRAME_ATOMIC);
391
    blankline = (__u8 *) malloc(ROW_BYTES, FRAME_ATOMIC);
352
    ASSERT(blankline);
392
    ASSERT(blankline);
-
 
393
    for (y=0; y < FONT_SCANLINES; y++)
-
 
394
        for (x=0; x < xres; x++)
353
    memcpy((void *) blankline, (void *) &fbaddress[(rows - 1) * ROW_BYTES], ROW_BYTES);
395
            (*rgb2scr)(&blankline[POINTPOS(x,y)],BGCOLOR);
-
 
396
 
-
 
397
    clear_screen();
-
 
398
 
-
 
399
    /* Update size of screen to match text area */
-
 
400
    yres = rows * FONT_SCANLINES;
354
   
401
 
355
    draw_logo(xres - helenos_width, 0);
402
    draw_logo(xres - helenos_width, 0);
356
    invert_cursor();
403
    invert_cursor();
357
 
404
 
358
    chardev_initialize("fb", &framebuffer, &fb_ops);
405
    chardev_initialize("fb", &framebuffer, &fb_ops);
359
    stdout = &framebuffer;
406
    stdout = &framebuffer;
Line 363... Line 410...
363
    sysinfo_set_item_val("fb.width", NULL, x);
410
    sysinfo_set_item_val("fb.width", NULL, x);
364
    sysinfo_set_item_val("fb.height", NULL, y);
411
    sysinfo_set_item_val("fb.height", NULL, y);
365
    sysinfo_set_item_val("fb.bpp", NULL, bpp);
412
    sysinfo_set_item_val("fb.bpp", NULL, bpp);
366
    sysinfo_set_item_val("fb.scanline", NULL, scan);
413
    sysinfo_set_item_val("fb.scanline", NULL, scan);
367
    sysinfo_set_item_val("fb.address.physical", NULL, addr);
414
    sysinfo_set_item_val("fb.address.physical", NULL, addr);
-
 
415
 
368
}
416
}