From f3e6838b44a5b37ce7664db5b8662e3d02e5f539 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 17 Apr 2025 00:51:46 -0400 Subject: font rending in framebuffer yay!! --- kernel/term.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 kernel/term.c (limited to 'kernel/term.c') diff --git a/kernel/term.c b/kernel/term.c new file mode 100644 index 0000000..e40e0fe --- /dev/null +++ b/kernel/term.c @@ -0,0 +1,169 @@ +#include "lib/kio.h" +#include +#include +#include +#include +#include +#include +#include + +// draw function +static void (*draw_char)(char c, uint16_t x, uint16_t y) = vga_draw_char; + +// terminal data +static char buffer[TERM_MAX_WIDTH * TERM_MAX_HEIGHT]; +static uint16_t buffer_line = UINT16_MAX; +static uint16_t width = VGA_WIDTH; +static uint16_t height = VGA_HEIGHT; +static uint16_t x = 0; +static uint16_t y = 0; + +#define BUFY(y) ((buffer_line + (y)) % TERM_MAX_HEIGHT) +#define BUFIDX(x,y) ((x) + (BUFY(y) * TERM_MAX_WIDTH)) + +static void buffer_check(void) +{ + if (buffer_line == UINT16_MAX) { + buffer_line = 0; + memset(buffer, 0, sizeof(buffer)); + } +} + +static inline bool printable(char c) +{ + switch (c) { + case '\0': + case '\n': + case '\t': + case '\v': + case '\f': + case '\r': + return false; + default: + return true; + } +} + +static inline void term_move_cur(char c) +{ + if (c == '\0') + return; + + switch (c) { + case '\n': + x = 0; + y++; + break; + case '\t': + x += 4; + break; + case '\v': + case '\f': + y++; + break; + case '\r': + x = 0; + break; + default: + x++; + } + + if (x >= width) { + x = 0; + y++; + } + if (y >= height) { + term_scroll(y - (height - 1)); + y = height - 1; + } +} + +uint16_t term_width(void) +{ + return width; +} + +uint16_t term_height(void) +{ + return height; +} + +void term_out(char c) +{ + term_out_at(c, x, y); + term_move_cur(c); +} + +void term_out_at(char c, uint16_t x, uint16_t y) +{ + buffer_check(); + + if (!printable(c)) + return; + + buffer[BUFIDX(x, y)] = c; + draw_char(c, x, y); +} + +void term_out_str(const char *str) +{ + char c; + while (c = *(str++), c) { + term_out_at(c, x, y); + term_move_cur(c); + } +} + +void term_out_str_at(const char *str, uint16_t x, uint16_t y) +{ + char c; + while (c = *(str++), c) + term_out_at(c, x, y); +} + +void term_clear(void) +{ + for (uint16_t y = 0; y < height; y++) + term_clear_line(y); +} + +void term_clear_line(uint16_t line) +{ + buffer_check(); + + if (line > height) + return; + + for (uint16_t x = 0; x < width; x++) { + buffer[BUFIDX(x, line)] = 0; + draw_char(0, x, line); + } +} + +void term_redraw(void) +{ + buffer_check(); + + for (uint16_t j = 0; j < height; j++) { + for (uint16_t i = 0; i < width; i++) { + char c = buffer[BUFIDX(i, j)]; + draw_char(c, i, j); + } + } +} + +void term_scroll(uint16_t lines) +{ + if (!lines) + return; + buffer_line += lines; + term_redraw(); +} + +void term_switch_handler(uint16_t w, uint16_t h, void (*fn)(char c, uint16_t x, uint16_t y)) +{ + draw_char = fn; + width = w % TERM_MAX_WIDTH; + height = h % TERM_MAX_HEIGHT; + term_redraw(); +} -- cgit v1.2.3-freya From 485c33eb10b4d877632676ee1bd8d8bdef821cfe Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 17 Apr 2025 09:26:49 -0400 Subject: fmt --- kernel/drivers/gpu.c | 4 +- kernel/drivers/gpu/bochs.c | 70 +++++++++++++++++--------------- kernel/include/comus/drivers/gpu/bochs.h | 3 +- kernel/include/comus/term.h | 3 +- kernel/term.c | 5 ++- 5 files changed, 46 insertions(+), 39 deletions(-) (limited to 'kernel/term.c') diff --git a/kernel/drivers/gpu.c b/kernel/drivers/gpu.c index 7ecdada..730fa42 100644 --- a/kernel/drivers/gpu.c +++ b/kernel/drivers/gpu.c @@ -13,9 +13,7 @@ enum gpu_type { static enum gpu_type type = GPU_UNSET; -static const char *gpu_type_str[N_GPU_TYPE] = { - "Unknown", "Bochs" -}; +static const char *gpu_type_str[N_GPU_TYPE] = { "Unknown", "Bochs" }; struct psf2_font { uint8_t magic[4]; diff --git a/kernel/drivers/gpu/bochs.c b/kernel/drivers/gpu/bochs.c index 5b0f1fc..a100908 100644 --- a/kernel/drivers/gpu/bochs.c +++ b/kernel/drivers/gpu/bochs.c @@ -4,27 +4,27 @@ #include #include -#define INDEX 0x1CE -#define DATA 0x1CF - -#define INDEX_ID 0 -#define INDEX_XRES 1 -#define INDEX_YRES 2 -#define INDEX_BPP 3 -#define INDEX_ENABLE 4 -#define INDEX_BANK 5 -#define INDEX_VIRT_WIDTH 6 -#define INDEX_VIRT_HEIGHT 7 -#define INDEX_X_OFFSET 8 -#define INDEX_Y_OFFSET 9 - -#define DATA_DISP_DISABLE 0x00 -#define DATA_DISP_ENABLE 0x01 -#define DATA_LFB_ENABLE 0x40 -#define DATA_NO_CLEAR_MEM 0x80 - -#define BOCHS_PCI_VENDOR 0x1234 -#define BOCHS_PCI_DEVICE 0x1111 +#define INDEX 0x1CE +#define DATA 0x1CF + +#define INDEX_ID 0 +#define INDEX_XRES 1 +#define INDEX_YRES 2 +#define INDEX_BPP 3 +#define INDEX_ENABLE 4 +#define INDEX_BANK 5 +#define INDEX_VIRT_WIDTH 6 +#define INDEX_VIRT_HEIGHT 7 +#define INDEX_X_OFFSET 8 +#define INDEX_Y_OFFSET 9 + +#define DATA_DISP_DISABLE 0x00 +#define DATA_DISP_ENABLE 0x01 +#define DATA_LFB_ENABLE 0x40 +#define DATA_NO_CLEAR_MEM 0x80 + +#define BOCHS_PCI_VENDOR 0x1234 +#define BOCHS_PCI_DEVICE 0x1111 #define BOCHS_WIDTH 1024 #define BOCHS_HEIGHT 768 @@ -35,33 +35,39 @@ static uint16_t width = BOCHS_WIDTH; static uint16_t height = BOCHS_HEIGHT; static uint8_t bit_depth = BOCHS_BIT_DEPTH; -static void write(uint16_t index, uint16_t data) { +static void write(uint16_t index, uint16_t data) +{ outw(INDEX, index); outw(DATA, data); } -static uint16_t read(uint16_t value) { +static uint16_t read(uint16_t value) +{ outw(INDEX, value); return inw(DATA); } -static int is_available(void) { +static int is_available(void) +{ return (read(INDEX_ID) == 0xB0C5); } -static void set_mode(uint16_t width, uint16_t height, uint16_t bit_depth, int lfb, int clear) { +static void set_mode(uint16_t width, uint16_t height, uint16_t bit_depth, + int lfb, int clear) +{ write(INDEX_ENABLE, DATA_DISP_DISABLE); write(INDEX_XRES, width); write(INDEX_YRES, height); write(INDEX_BPP, bit_depth); - write(INDEX_ENABLE, DATA_DISP_ENABLE | - (lfb ? DATA_LFB_ENABLE : 0) | - (clear ? 0 : DATA_NO_CLEAR_MEM)); + write(INDEX_ENABLE, DATA_DISP_ENABLE | (lfb ? DATA_LFB_ENABLE : 0) | + (clear ? 0 : DATA_NO_CLEAR_MEM)); } -int bochs_init(void) { - struct pci_device bochs = {0}; - bool found = pci_findby_id(&bochs, BOCHS_PCI_DEVICE, BOCHS_PCI_VENDOR, NULL); +int bochs_init(void) +{ + struct pci_device bochs = { 0 }; + bool found = + pci_findby_id(&bochs, BOCHS_PCI_DEVICE, BOCHS_PCI_VENDOR, NULL); if (!found) return 1; @@ -70,7 +76,7 @@ int bochs_init(void) { return 1; uint32_t bar0 = pci_rcfg_d(bochs, PCI_BAR0_D); - uint32_t *addr = (uint32_t *) (uintptr_t) bar0; + uint32_t *addr = (uint32_t *)(uintptr_t)bar0; framebuffer = kmapaddr(addr, NULL, width * height * bit_depth, F_WRITEABLE); return 0; diff --git a/kernel/include/comus/drivers/gpu/bochs.h b/kernel/include/comus/drivers/gpu/bochs.h index 5933a3a..31aa740 100644 --- a/kernel/include/comus/drivers/gpu/bochs.h +++ b/kernel/include/comus/drivers/gpu/bochs.h @@ -35,6 +35,7 @@ uint8_t bochs_bit_depth(void); /** * Sets the pixel at a given position */ -void bochs_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b); +void bochs_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, + uint32_t b); #endif /* bochs.h */ diff --git a/kernel/include/comus/term.h b/kernel/include/comus/term.h index 2d39915..6ac77e4 100644 --- a/kernel/include/comus/term.h +++ b/kernel/include/comus/term.h @@ -80,6 +80,7 @@ void term_scroll(uint16_t lines); /** * Switch terminal handler */ -void term_switch_handler(uint16_t width, uint16_t height, void (*draw_char)(char c, uint16_t x, uint16_t y)); +void term_switch_handler(uint16_t width, uint16_t height, + void (*draw_char)(char c, uint16_t x, uint16_t y)); #endif /* term.h */ diff --git a/kernel/term.c b/kernel/term.c index e40e0fe..101805f 100644 --- a/kernel/term.c +++ b/kernel/term.c @@ -19,7 +19,7 @@ static uint16_t x = 0; static uint16_t y = 0; #define BUFY(y) ((buffer_line + (y)) % TERM_MAX_HEIGHT) -#define BUFIDX(x,y) ((x) + (BUFY(y) * TERM_MAX_WIDTH)) +#define BUFIDX(x, y) ((x) + (BUFY(y) * TERM_MAX_WIDTH)) static void buffer_check(void) { @@ -160,7 +160,8 @@ void term_scroll(uint16_t lines) term_redraw(); } -void term_switch_handler(uint16_t w, uint16_t h, void (*fn)(char c, uint16_t x, uint16_t y)) +void term_switch_handler(uint16_t w, uint16_t h, + void (*fn)(char c, uint16_t x, uint16_t y)) { draw_char = fn; width = w % TERM_MAX_WIDTH; -- cgit v1.2.3-freya