// Terminal output #include #include #include "kernel.h" #include "term.h" extern struct limine_framebuffer* framebuffer; // Importing the PSF object file extern unsigned char _binary_zap_light16_psf_start[]; extern unsigned char _binary_zap_light16_psf_end[]; PSF1_Header* font = (PSF1_Header*)_binary_zap_light16_psf_start; uint8_t* glyphs = _binary_zap_light16_psf_start + sizeof(PSF1_Header); #define FONT_WIDTH 8 #define FONT_HEIGHT font->characterSize // Character cursor typedef struct { unsigned int x; unsigned int y; } Cursor; Cursor cursor = {0}; unsigned char* fb; int term_init() { // Get framebuffer address from Limine struct if (framebuffer) { fb = framebuffer->address; return 0; } return -ENOMEM; } // These are marked "static" because we don't wanna expose them all around // AKA they should just be seen here (kind of like private functions in cpp) static void putpixel(int x, int y, int color) { // Depth isn't part of limine_framebuffer attributes so it will be 4 unsigned pos = x*4 + y*framebuffer->pitch; fb[pos] = color & 255; // blue channel fb[pos+1] = (color >> 8) & 255; // green fb[pos+2] = (color >> 16) & 255; // blue } static void draw_char(char c, int px, int py, int fg, int bg) { uint8_t* glyph = glyphs + ((unsigned char)c * FONT_HEIGHT); for (size_t y=0; y> x)) ? fg : bg; putpixel(px+x, py+y, color); } } } static void putchar(char c) { if (c == '\n') { cursor.x = 0; cursor.y++; return; } if ((cursor.x+1)*FONT_WIDTH >= framebuffer->width) { cursor.x = 0; cursor.y++; } int px = cursor.x * FONT_WIDTH; int py = cursor.y * FONT_HEIGHT; draw_char(c, px, py, WHITE, BLACK); cursor.x++; } // Overhead that could be avoided, right? void _putchar(char character) { putchar(character); } // Debug-printing void kputs(const char* str) { unsigned int i=0; while (str[i] != 0) { putchar(str[i]); i++; } }