Rev 4346 | Rev 4348 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4346 | Rev 4347 | ||
---|---|---|---|
Line 51... | Line 51... | ||
51 | #include <arch/types.h> |
51 | #include <arch/types.h> |
52 | 52 | ||
53 | SPINLOCK_INITIALIZE(fb_lock); |
53 | SPINLOCK_INITIALIZE(fb_lock); |
54 | 54 | ||
55 | static uint8_t *fb_addr; |
55 | static uint8_t *fb_addr; |
56 | static uint8_t *backbuf; |
56 | static uint16_t *backbuf; |
57 | static uint8_t *glyphs; |
57 | static uint8_t *glyphs; |
58 | static uint8_t *bgscan; |
58 | static uint8_t *bgscan; |
59 | 59 | ||
60 | static unsigned int xres; |
60 | static unsigned int xres; |
61 | static unsigned int yres; |
61 | static unsigned int yres; |
Line 75... | Line 75... | ||
75 | static unsigned int rows; |
75 | static unsigned int rows; |
76 | static unsigned int position = 0; |
76 | static unsigned int position = 0; |
77 | 77 | ||
78 | #define BG_COLOR 0x000080 |
78 | #define BG_COLOR 0x000080 |
79 | #define FG_COLOR 0xffff00 |
79 | #define FG_COLOR 0xffff00 |
- | 80 | #define INV_COLOR 0xaaaaaa |
|
80 | 81 | ||
81 | #define CURSOR 219 |
82 | #define CURSOR 0x2588 |
82 | 83 | ||
83 | #define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
84 | #define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
84 | #define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
85 | #define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
85 | #define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
86 | #define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
86 | 87 | ||
Line 197... | Line 198... | ||
197 | 198 | ||
198 | 199 | ||
199 | /** Draw character at given position |
200 | /** Draw character at given position |
200 | * |
201 | * |
201 | */ |
202 | */ |
202 | static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
203 | static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent) |
203 | { |
204 | { |
204 | unsigned int x = COL2X(col); |
205 | unsigned int x = COL2X(col); |
205 | unsigned int y = ROW2Y(row); |
206 | unsigned int y = ROW2Y(row); |
206 | unsigned int yd; |
207 | unsigned int yd; |
207 | 208 | ||
Line 240... | Line 241... | ||
240 | unsigned int x; |
241 | unsigned int x; |
241 | unsigned int col; |
242 | unsigned int col; |
242 | 243 | ||
243 | for (col = 0, x = 0; col < cols; col++, |
244 | for (col = 0, x = 0; col < cols; col++, |
244 | x += FONT_WIDTH) { |
245 | x += FONT_WIDTH) { |
245 | uint8_t glyph; |
246 | uint16_t glyph; |
246 | 247 | ||
247 | if (row < rows - 1) { |
248 | if (row < rows - 1) { |
248 | if (backbuf[BB_POS(col, row)] == |
249 | if (backbuf[BB_POS(col, row)] == |
249 | backbuf[BB_POS(col, row + 1)]) |
250 | backbuf[BB_POS(col, row + 1)]) |
250 | continue; |
251 | continue; |
Line 259... | Line 260... | ||
259 | } |
260 | } |
260 | } |
261 | } |
261 | } |
262 | } |
262 | } |
263 | } |
263 | 264 | ||
264 | memmove(backbuf, backbuf + cols, cols * (rows - 1)); |
265 | memmove(backbuf, &backbuf[BB_POS(0, 1)], cols * (rows - 1) * sizeof(uint16_t)); |
265 | memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
266 | memsetw(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
266 | } |
267 | } |
267 | 268 | ||
268 | 269 | ||
269 | static void cursor_put(bool silent) |
270 | static void cursor_put(bool silent) |
270 | { |
271 | { |
271 | glyph_draw(CURSOR, position % cols, position / cols, silent); |
272 | glyph_draw(fb_font_glyph(CURSOR), position % cols, position / cols, silent); |
272 | } |
273 | } |
273 | 274 | ||
274 | 275 | ||
275 | static void cursor_remove(bool silent) |
276 | static void cursor_remove(bool silent) |
276 | { |
277 | { |
277 | glyph_draw(0, position % cols, position / cols, silent); |
278 | glyph_draw(fb_font_glyph(0), position % cols, position / cols, silent); |
278 | } |
279 | } |
279 | 280 | ||
280 | 281 | ||
281 | /** Print character to screen |
282 | /** Print character to screen |
282 | * |
283 | * |
283 | * Emulate basic terminal commands. |
284 | * Emulate basic terminal commands. |
284 | * |
285 | * |
285 | */ |
286 | */ |
286 | static void fb_putchar(outdev_t *dev, char ch, bool silent) |
287 | static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent) |
287 | { |
288 | { |
288 | spinlock_lock(&fb_lock); |
289 | spinlock_lock(&fb_lock); |
289 | 290 | ||
290 | switch (ch) { |
291 | switch (ch) { |
291 | case '\n': |
292 | case '\n': |
Line 303... | Line 304... | ||
303 | position--; |
304 | position--; |
304 | break; |
305 | break; |
305 | case '\t': |
306 | case '\t': |
306 | cursor_remove(silent); |
307 | cursor_remove(silent); |
307 | do { |
308 | do { |
308 | glyph_draw((uint8_t) ' ', position % cols, |
309 | glyph_draw(fb_font_glyph(' '), position % cols, |
309 | position / cols, silent); |
310 | position / cols, silent); |
310 | position++; |
311 | position++; |
311 | } while ((position % 8) && (position < cols * rows)); |
312 | } while ((position % 8) && (position < cols * rows)); |
312 | break; |
313 | break; |
313 | default: |
314 | default: |
314 | glyph_draw((uint8_t) ch, position % cols, |
315 | glyph_draw(fb_font_glyph(ch), position % cols, |
315 | position / cols, silent); |
316 | position / cols, silent); |
316 | position++; |
317 | position++; |
317 | } |
318 | } |
318 | 319 | ||
319 | if (position >= cols * rows) { |
320 | if (position >= cols * rows) { |
Line 339... | Line 340... | ||
339 | * |
340 | * |
340 | */ |
341 | */ |
341 | static void glyphs_render(void) |
342 | static void glyphs_render(void) |
342 | { |
343 | { |
343 | /* Prerender glyphs */ |
344 | /* Prerender glyphs */ |
344 | unsigned int glyph; |
345 | uint16_t glyph; |
345 | 346 | ||
346 | for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
347 | for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
- | 348 | uint32_t fg_color; |
|
- | 349 | ||
- | 350 | if (glyph == FONT_GLYPHS - 1) |
|
- | 351 | fg_color = INV_COLOR; |
|
- | 352 | else |
|
- | 353 | fg_color = FG_COLOR; |
|
- | 354 | ||
347 | unsigned int y; |
355 | unsigned int y; |
348 | 356 | ||
349 | for (y = 0; y < FONT_SCANLINES; y++) { |
357 | for (y = 0; y < FONT_SCANLINES; y++) { |
350 | unsigned int x; |
358 | unsigned int x; |
351 | 359 | ||
352 | for (x = 0; x < FONT_WIDTH; x++) { |
360 | for (x = 0; x < FONT_WIDTH; x++) { |
353 | void *dst = &glyphs[GLYPH_POS(glyph, y) + |
361 | void *dst = &glyphs[GLYPH_POS(glyph, y) + |
354 | x * pixelbytes]; |
362 | x * pixelbytes]; |
355 | uint32_t rgb = (fb_font[ROW2Y(glyph) + y] & |
363 | uint32_t rgb = (fb_font[glyph][y] & |
356 | (1 << (7 - x))) ? FG_COLOR : BG_COLOR; |
364 | (1 << (7 - x))) ? fg_color : BG_COLOR; |
357 | rgb_conv(dst, rgb); |
365 | rgb_conv(dst, rgb); |
358 | } |
366 | } |
359 | } |
367 | } |
360 | } |
368 | } |
361 | 369 | ||
Line 396... | Line 404... | ||
396 | unsigned int x; |
404 | unsigned int x; |
397 | unsigned int col; |
405 | unsigned int col; |
398 | 406 | ||
399 | for (col = 0, x = 0; col < cols; |
407 | for (col = 0, x = 0; col < cols; |
400 | col++, x += FONT_WIDTH) { |
408 | col++, x += FONT_WIDTH) { |
- | 409 | uint16_t glyph = backbuf[BB_POS(col, row)]; |
|
401 | void *d = &fb_addr[FB_POS(x, y + yd)]; |
410 | void *dst = &fb_addr[FB_POS(x, y + yd)]; |
402 | void *s = &glyphs[GLYPH_POS(backbuf[BB_POS(col, |
411 | void *src = &glyphs[GLYPH_POS(glyph, yd)]; |
403 | row)], yd)]; |
- | |
404 | memcpy(d, s, glyphscanline); |
412 | memcpy(dst, src, glyphscanline); |
405 | } |
413 | } |
406 | } |
414 | } |
407 | } |
415 | } |
408 | 416 | ||
409 | if (COL2X(cols) < xres) { |
417 | if (COL2X(cols) < xres) { |
Line 492... | Line 500... | ||
492 | 500 | ||
493 | glyphscanline = FONT_WIDTH * pixelbytes; |
501 | glyphscanline = FONT_WIDTH * pixelbytes; |
494 | glyphbytes = ROW2Y(glyphscanline); |
502 | glyphbytes = ROW2Y(glyphscanline); |
495 | bgscanbytes = xres * pixelbytes; |
503 | bgscanbytes = xres * pixelbytes; |
496 | 504 | ||
497 | unsigned int fbsize = scanline * yres; |
505 | size_t fbsize = scanline * yres; |
498 | unsigned int bbsize = cols * rows; |
506 | size_t bbsize = cols * rows * sizeof(uint16_t); |
499 | unsigned int glyphsize = FONT_GLYPHS * glyphbytes; |
507 | size_t glyphsize = FONT_GLYPHS * glyphbytes; |
500 | 508 | ||
501 | backbuf = (uint8_t *) malloc(bbsize, 0); |
509 | backbuf = (uint16_t *) malloc(bbsize, 0); |
502 | if (!backbuf) |
510 | if (!backbuf) |
503 | panic("Unable to allocate backbuffer."); |
511 | panic("Unable to allocate backbuffer."); |
504 | 512 | ||
505 | glyphs = (uint8_t *) malloc(glyphsize, 0); |
513 | glyphs = (uint8_t *) malloc(glyphsize, 0); |
506 | if (!glyphs) |
514 | if (!glyphs) |
Line 508... | Line 516... | ||
508 | 516 | ||
509 | bgscan = malloc(bgscanbytes, 0); |
517 | bgscan = malloc(bgscanbytes, 0); |
510 | if (!bgscan) |
518 | if (!bgscan) |
511 | panic("Unable to allocate background pixel."); |
519 | panic("Unable to allocate background pixel."); |
512 | 520 | ||
513 | memsetb(backbuf, bbsize, 0); |
521 | memsetw(backbuf, cols * rows, 0); |
514 | 522 | ||
515 | glyphs_render(); |
523 | glyphs_render(); |
516 | 524 | ||
517 | fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
525 | fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
518 | 526 |