#include #include #include // Font bitmap. static const uint8_t kernel_font_bitmap[] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xad, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2a, 0x92, 0x11, 0x11, 0x28, 0x00, 0x00, 0x38, 0xbb, 0xab, 0xbb, 0xbb, 0x80, 0x08, 0x23, 0x02, 0x57, 0x31, 0x52, 0x41, 0x22, 0x00, 0x01, 0x51, 0x11, 0x54, 0x41, 0x55, 0x22, 0x27, 0x21, 0x04, 0x0a, 0xc4, 0x40, 0x82, 0xae, 0x0e, 0x04, 0xa2, 0xee, 0xee, 0xe2, 0xee, 0x00, 0x80, 0x24, 0x00, 0x1c, 0xd1, 0x41, 0x04, 0x08, 0x80, 0x11, 0x45, 0x04, 0x45, 0x45, 0x44, 0x88, 0x9c, 0x80, 0x10, 0x2b, 0x09, 0x81, 0x10, 0x02, 0x01, 0x03, 0x8b, 0xb8, 0xbb, 0x8b, 0xb8, 0x20, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xee, 0xec, 0xee, 0xea, 0xee, 0xa8, 0xae, 0xee, 0xee, 0x6e, 0xaa, 0xaa, 0xae, 0xe0, 0xe4, 0x05, 0x55, 0x15, 0x11, 0x14, 0x89, 0x51, 0xd5, 0x55, 0x55, 0x09, 0x55, 0x55, 0x45, 0x10, 0x54, 0x0b, 0xb2, 0x2b, 0xba, 0xb9, 0x13, 0x22, 0xaa, 0xba, 0xb3, 0x92, 0xaa, 0x91, 0x12, 0x10, 0x80, 0x55, 0x54, 0x54, 0x45, 0x52, 0x25, 0x45, 0x55, 0x47, 0x51, 0x25, 0x57, 0x52, 0x44, 0x11, 0x00, 0xca, 0xee, 0xce, 0x8e, 0xae, 0xca, 0xea, 0xae, 0x8e, 0xac, 0x4e, 0x4a, 0xa4, 0xee, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x90, 0x9a, 0x11, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x30, 0x39, 0x14, 0x31, 0x52, 0x54, 0x00, 0x42, 0x76, 0x26, 0x35, 0x37, 0x55, 0x55, 0x57, 0x22, 0x20, 0x70, 0x6c, 0x86, 0xee, 0x6c, 0xc4, 0xa4, 0xea, 0xaa, 0xac, 0xc4, 0xaa, 0xa4, 0xa4, 0x84, 0x26, 0xe1, 0x55, 0x15, 0x08, 0x54, 0x89, 0x89, 0x55, 0x58, 0xd0, 0x49, 0x55, 0xd4, 0x90, 0x88, 0x99, 0xc1, 0xb1, 0x99, 0x93, 0x2b, 0xb2, 0x9a, 0xa9, 0x20, 0xa3, 0x19, 0x92, 0xa9, 0x39, 0x93, 0x03, 0x80 }; static void font_draw_core(struct font_block_s *fblock) { extern uint32_t vram[256]; uint8_t vram_offset_y; uint32_t pixel_cursor; uint8_t pixel_test; int x; int y; // Calculate VRAM buffer starting position. // @note: // The screen width size is always 128 and we // use 4-aligned Video RAM so 32 pixels per "slot" // and 128 / 32 = 4. // y * 4 can be optimised by used shift operator, // this is why we use y << 2 because 2^2 = 4. vram_offset_y = fblock->y << 2; // Start atomic operations atomic_start(); // Draw character, pixer per pixel... (x_x) // TODO: update me !! y = -1; while (++y < fblock->height) { x = -1; while (++x < fblock->width) { // Get bitmap pixel test. pixel_cursor = fblock->bitmap.x + fblock->bitmap.y + x; pixel_test = 0x80 >> (pixel_cursor & 0x07); // Check if the pixel is block or white. if (pixel_test & kernel_font_bitmap[pixel_cursor >> 3]) { vram[((fblock->x + x) >> 5) + vram_offset_y] |= 0x80000000 >> ((fblock->x + x) & 31); } } // Update internal offset. fblock->bitmap.y = fblock->bitmap.y + KERNEL_FONT_BITMAP_WIDTH; vram_offset_y = vram_offset_y + 4; } // Stop atomic operations atomic_stop(); } void font_draw(int x, int y, char c) { struct font_block_s fblock; // Check obvious error. if (x > DISPLAY_SCREEN_WIDTH || y > DISPLAY_SCREEN_HEIGHT) return; // Calculate the charactere position (bitmap) fblock.bitmap.y = (c / KERNEL_FONT_NB_CHAR_X) * (KERNEL_FONT_BITMAP_WIDTH * KERNEL_FONT_BITMAP_CHEIGHT); fblock.bitmap.x = (c - ((c / KERNEL_FONT_NB_CHAR_X) * KERNEL_FONT_NB_CHAR_X)) * KERNEL_FONT_BITMAP_CWIDTH; // Check X axis culling // and get font "block" width. if (x < 0) { fblock.bitmap.x = fblock.bitmap.x + x; fblock.width = KERNEL_FONT_REAL_WIDTH + x; fblock.x = 0; } else { fblock.width = (x + KERNEL_FONT_REAL_WIDTH >= DISPLAY_SCREEN_WIDTH) ? DISPLAY_SCREEN_WIDTH - x - 1 : KERNEL_FONT_REAL_WIDTH; fblock.x = x; } // Check Y axis culling. // and get font "block" height. if (y < 0) { fblock.height = KERNEL_FONT_REAL_HEIGHT + y; fblock.bitmap.y = fblock.bitmap.y + ((-y) * KERNEL_FONT_BITMAP_WIDTH); fblock.y = 0; } else { fblock.height = (y + KERNEL_FONT_REAL_HEIGHT >= DISPLAY_SCREEN_HEIGHT) ? DISPLAY_SCREEN_HEIGHT - y - 1 : KERNEL_FONT_REAL_HEIGHT; fblock.y = y; } // Check useless draw. if (fblock.width < 0 || fblock.height < 0) return; // Draw ASCII character. font_draw_core(&fblock); }