genusOS/src/print.c

115 lines
2.2 KiB
C

#include "etc.h"
#include "font.h"
#include "../include/limine.h"
u32 bg = 0x00000000;
u32 fg = (0x007F1754 << 1);
static size_t row;
static size_t col;
static size_t term_width, term_height;
static size_t fb_width, fb_height;
static volatile u32 *fb_scr;
#define TAB_STOP 4
// buffer at each edge for readability
#define TERM_WIDTH (FONT_WIDTH + 2)
#define TERM_HEIGHT (FONT_HEIGHT + 2)
void print_init(struct limine_framebuffer *fb) {
term_width = fb->width / TERM_WIDTH;
term_height = fb->height / TERM_HEIGHT;
fb_width = fb->width;
fb_height = fb->height;
fb_scr = fb->address;
}
static void scrollback() {
memmove((void *)fb_scr, (void *)(fb_scr + fb_width * TERM_HEIGHT),
fb_width * (fb_height - TERM_HEIGHT) * sizeof(u32));
}
void put(int ch) {
ch = (unsigned char)ch;
if (!isprint(ch)) {
if (ch == '\n') {
col = 0;
row++;
} else if (ch == '\t') {
size_t target = (col + TAB_STOP) & ~(TAB_STOP - 1);
if (target >= term_width) {
col = 0;
row++;
} else {
while (col < target)
put(' ');
}
}
return;
}
if (col >= term_width) {
col = 0;
row++;
}
if (row >= term_height) {
scrollback();
row = term_height - 1;
}
size_t idx = ch - ' ';
u32 glyph = font[idx];
size_t px = col * TERM_WIDTH;
size_t py = row * TERM_HEIGHT;
for (size_t y = 0; y < TERM_HEIGHT; y++) {
for (size_t x = 0; x < TERM_WIDTH; x++) {
size_t off = (py + y) * fb_width + (px + x);
bool padding =
(y == 0 || y == TERM_HEIGHT - 1 || x == 0 || x == TERM_WIDTH - 1);
fb_scr[off] = ((~glyph & 1) | padding) ? bg : fg;
glyph >>= !padding;
}
}
col++;
}
void print(const char *msg) {
while (*msg) {
put(*(msg++));
}
}
void printn(const char *msg, size_t len) {
while (len-- > 0) {
put(*(msg++));
}
}
static u8 digits[] = "0123456789ABCDEF";
void print8(u8 n) {
put(digits[n >> 4]);
put(digits[n & 0xf]);
}
void print16(u16 n) {
print8(n >> 8);
print8(n & 0xFF);
}
void print32(u32 n) {
print16(n >> 16);
print16(n & 0xFFFF);
}
void print64(u64 n) {
print32(n >> 32);
print32(n & 0xFFFFFFFF);
}