Rev 4153 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4153 | Rev 4263 | ||
|---|---|---|---|
| Line 45... | Line 45... | ||
| 45 | #include <panic.h> |
45 | #include <panic.h> |
| 46 | #include <memstr.h> |
46 | #include <memstr.h> |
| 47 | #include <config.h> |
47 | #include <config.h> |
| 48 | #include <bitops.h> |
48 | #include <bitops.h> |
| 49 | #include <print.h> |
49 | #include <print.h> |
| - | 50 | #include <string.h> |
|
| 50 | #include <ddi/ddi.h> |
51 | #include <ddi/ddi.h> |
| 51 | #include <arch/types.h> |
52 | #include <arch/types.h> |
| 52 | 53 | ||
| 53 | SPINLOCK_INITIALIZE(fb_lock); |
54 | SPINLOCK_INITIALIZE(fb_lock); |
| 54 | 55 | ||
| 55 | static uint8_t *fb_addr; |
56 | static uint8_t *fb_addr; |
| 56 | static uint8_t *backbuf; |
57 | static uint16_t *backbuf; |
| 57 | static uint8_t *glyphs; |
58 | static uint8_t *glyphs; |
| 58 | static uint8_t *bgscan; |
59 | static uint8_t *bgscan; |
| 59 | 60 | ||
| 60 | static unsigned int xres; |
61 | static unsigned int xres; |
| 61 | static unsigned int yres; |
62 | static unsigned int yres; |
| Line 75... | Line 76... | ||
| 75 | static unsigned int rows; |
76 | static unsigned int rows; |
| 76 | static unsigned int position = 0; |
77 | static unsigned int position = 0; |
| 77 | 78 | ||
| 78 | #define BG_COLOR 0x000080 |
79 | #define BG_COLOR 0x000080 |
| 79 | #define FG_COLOR 0xffff00 |
80 | #define FG_COLOR 0xffff00 |
| 80 | - | ||
| 81 | #define CURSOR 219 |
81 | #define INV_COLOR 0xaaaaaa |
| 82 | 82 | ||
| 83 | #define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
83 | #define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
| 84 | #define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
84 | #define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
| 85 | #define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
85 | #define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
| 86 | 86 | ||
| Line 197... | Line 197... | ||
| 197 | 197 | ||
| 198 | 198 | ||
| 199 | /** Draw character at given position |
199 | /** Draw character at given position |
| 200 | * |
200 | * |
| 201 | */ |
201 | */ |
| 202 | static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
202 | static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent, bool overlay) |
| 203 | { |
203 | { |
| 204 | unsigned int x = COL2X(col); |
204 | unsigned int x = COL2X(col); |
| 205 | unsigned int y = ROW2Y(row); |
205 | unsigned int y = ROW2Y(row); |
| 206 | unsigned int yd; |
206 | unsigned int yd; |
| 207 | 207 | ||
| 208 | if (y >= ytrim) |
208 | if (y >= ytrim) |
| 209 | logo_hide(silent); |
209 | logo_hide(silent); |
| 210 | 210 | ||
| - | 211 | if (!overlay) |
|
| 211 | backbuf[BB_POS(col, row)] = glyph; |
212 | backbuf[BB_POS(col, row)] = glyph; |
| 212 | 213 | ||
| 213 | if (!silent) { |
214 | if (!silent) { |
| 214 | for (yd = 0; yd < FONT_SCANLINES; yd++) |
215 | for (yd = 0; yd < FONT_SCANLINES; yd++) |
| 215 | memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
216 | memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
| 216 | &glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
217 | &glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
| 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 | { |
| - | 272 | unsigned int col = position % cols; |
|
| - | 273 | unsigned int row = position / cols; |
|
| - | 274 | ||
| 271 | glyph_draw(CURSOR, position % cols, position / cols, silent); |
275 | glyph_draw(fb_font_glyph(U_CURSOR), col, row, silent, true); |
| 272 | } |
276 | } |
| 273 | 277 | ||
| 274 | 278 | ||
| 275 | static void cursor_remove(bool silent) |
279 | static void cursor_remove(bool silent) |
| 276 | { |
280 | { |
| - | 281 | unsigned int col = position % cols; |
|
| - | 282 | unsigned int row = position / cols; |
|
| - | 283 | ||
| 277 | glyph_draw(0, position % cols, position / cols, silent); |
284 | glyph_draw(backbuf[BB_POS(col, row)], col, row, silent, true); |
| 278 | } |
285 | } |
| 279 | 286 | ||
| 280 | 287 | ||
| 281 | /** Print character to screen |
288 | /** Print character to screen |
| 282 | * |
289 | * |
| 283 | * Emulate basic terminal commands. |
290 | * Emulate basic terminal commands. |
| 284 | * |
291 | * |
| 285 | */ |
292 | */ |
| 286 | static void fb_putchar(outdev_t *dev, char ch, bool silent) |
293 | static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent) |
| 287 | { |
294 | { |
| 288 | spinlock_lock(&fb_lock); |
295 | spinlock_lock(&fb_lock); |
| 289 | 296 | ||
| 290 | switch (ch) { |
297 | switch (ch) { |
| 291 | case '\n': |
298 | case '\n': |
| Line 303... | Line 310... | ||
| 303 | position--; |
310 | position--; |
| 304 | break; |
311 | break; |
| 305 | case '\t': |
312 | case '\t': |
| 306 | cursor_remove(silent); |
313 | cursor_remove(silent); |
| 307 | do { |
314 | do { |
| 308 | glyph_draw((uint8_t) ' ', position % cols, |
315 | glyph_draw(fb_font_glyph(' '), position % cols, |
| 309 | position / cols, silent); |
316 | position / cols, silent, false); |
| 310 | position++; |
317 | position++; |
| 311 | } while ((position % 8) && (position < cols * rows)); |
318 | } while ((position % 8) && (position < cols * rows)); |
| 312 | break; |
319 | break; |
| 313 | default: |
320 | default: |
| 314 | glyph_draw((uint8_t) ch, position % cols, |
321 | glyph_draw(fb_font_glyph(ch), position % cols, |
| 315 | position / cols, silent); |
322 | position / cols, silent, false); |
| 316 | position++; |
323 | position++; |
| 317 | } |
324 | } |
| 318 | 325 | ||
| 319 | if (position >= cols * rows) { |
326 | if (position >= cols * rows) { |
| 320 | position -= cols; |
327 | position -= cols; |
| Line 339... | Line 346... | ||
| 339 | * |
346 | * |
| 340 | */ |
347 | */ |
| 341 | static void glyphs_render(void) |
348 | static void glyphs_render(void) |
| 342 | { |
349 | { |
| 343 | /* Prerender glyphs */ |
350 | /* Prerender glyphs */ |
| 344 | unsigned int glyph; |
351 | uint16_t glyph; |
| 345 | 352 | ||
| 346 | for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
353 | for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
| - | 354 | uint32_t fg_color; |
|
| - | 355 | ||
| - | 356 | if (glyph == FONT_GLYPHS - 1) |
|
| - | 357 | fg_color = INV_COLOR; |
|
| - | 358 | else |
|
| - | 359 | fg_color = FG_COLOR; |
|
| - | 360 | ||
| 347 | unsigned int y; |
361 | unsigned int y; |
| 348 | 362 | ||
| 349 | for (y = 0; y < FONT_SCANLINES; y++) { |
363 | for (y = 0; y < FONT_SCANLINES; y++) { |
| 350 | unsigned int x; |
364 | unsigned int x; |
| 351 | 365 | ||
| 352 | for (x = 0; x < FONT_WIDTH; x++) { |
366 | for (x = 0; x < FONT_WIDTH; x++) { |
| 353 | void *dst = &glyphs[GLYPH_POS(glyph, y) + |
367 | void *dst = &glyphs[GLYPH_POS(glyph, y) + |
| 354 | x * pixelbytes]; |
368 | x * pixelbytes]; |
| 355 | uint32_t rgb = (fb_font[ROW2Y(glyph) + y] & |
369 | uint32_t rgb = (fb_font[glyph][y] & |
| 356 | (1 << (7 - x))) ? FG_COLOR : BG_COLOR; |
370 | (1 << (7 - x))) ? fg_color : BG_COLOR; |
| 357 | rgb_conv(dst, rgb); |
371 | rgb_conv(dst, rgb); |
| 358 | } |
372 | } |
| 359 | } |
373 | } |
| 360 | } |
374 | } |
| 361 | 375 | ||
| Line 396... | Line 410... | ||
| 396 | unsigned int x; |
410 | unsigned int x; |
| 397 | unsigned int col; |
411 | unsigned int col; |
| 398 | 412 | ||
| 399 | for (col = 0, x = 0; col < cols; |
413 | for (col = 0, x = 0; col < cols; |
| 400 | col++, x += FONT_WIDTH) { |
414 | col++, x += FONT_WIDTH) { |
| - | 415 | uint16_t glyph = backbuf[BB_POS(col, row)]; |
|
| 401 | void *d = &fb_addr[FB_POS(x, y + yd)]; |
416 | void *dst = &fb_addr[FB_POS(x, y + yd)]; |
| 402 | void *s = &glyphs[GLYPH_POS(backbuf[BB_POS(col, |
417 | void *src = &glyphs[GLYPH_POS(glyph, yd)]; |
| 403 | row)], yd)]; |
- | |
| 404 | memcpy(d, s, glyphscanline); |
418 | memcpy(dst, src, glyphscanline); |
| 405 | } |
419 | } |
| 406 | } |
420 | } |
| 407 | } |
421 | } |
| 408 | 422 | ||
| 409 | if (COL2X(cols) < xres) { |
423 | if (COL2X(cols) < xres) { |
| Line 492... | Line 506... | ||
| 492 | 506 | ||
| 493 | glyphscanline = FONT_WIDTH * pixelbytes; |
507 | glyphscanline = FONT_WIDTH * pixelbytes; |
| 494 | glyphbytes = ROW2Y(glyphscanline); |
508 | glyphbytes = ROW2Y(glyphscanline); |
| 495 | bgscanbytes = xres * pixelbytes; |
509 | bgscanbytes = xres * pixelbytes; |
| 496 | 510 | ||
| 497 | unsigned int fbsize = scanline * yres; |
511 | size_t fbsize = scanline * yres; |
| 498 | unsigned int bbsize = cols * rows; |
512 | size_t bbsize = cols * rows * sizeof(uint16_t); |
| 499 | unsigned int glyphsize = FONT_GLYPHS * glyphbytes; |
513 | size_t glyphsize = FONT_GLYPHS * glyphbytes; |
| 500 | 514 | ||
| 501 | backbuf = (uint8_t *) malloc(bbsize, 0); |
515 | backbuf = (uint16_t *) malloc(bbsize, 0); |
| 502 | if (!backbuf) |
516 | if (!backbuf) |
| 503 | panic("Unable to allocate backbuffer."); |
517 | panic("Unable to allocate backbuffer."); |
| 504 | 518 | ||
| 505 | glyphs = (uint8_t *) malloc(glyphsize, 0); |
519 | glyphs = (uint8_t *) malloc(glyphsize, 0); |
| 506 | if (!glyphs) |
520 | if (!glyphs) |
| Line 508... | Line 522... | ||
| 508 | 522 | ||
| 509 | bgscan = malloc(bgscanbytes, 0); |
523 | bgscan = malloc(bgscanbytes, 0); |
| 510 | if (!bgscan) |
524 | if (!bgscan) |
| 511 | panic("Unable to allocate background pixel."); |
525 | panic("Unable to allocate background pixel."); |
| 512 | 526 | ||
| 513 | memsetb(backbuf, bbsize, 0); |
527 | memsetw(backbuf, cols * rows, 0); |
| 514 | 528 | ||
| 515 | glyphs_render(); |
529 | glyphs_render(); |
| 516 | 530 | ||
| 517 | fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
531 | fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
| 518 | 532 | ||