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/drivers/gpu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 kernel/drivers/gpu.c (limited to 'kernel/drivers/gpu.c') diff --git a/kernel/drivers/gpu.c b/kernel/drivers/gpu.c new file mode 100644 index 0000000..7ecdada --- /dev/null +++ b/kernel/drivers/gpu.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include + +enum gpu_type { + GPU_UNSET = 0, + GPU_BOCHS = 1, + N_GPU_TYPE, +}; + +static enum gpu_type type = GPU_UNSET; + +static const char *gpu_type_str[N_GPU_TYPE] = { + "Unknown", "Bochs" +}; + +struct psf2_font { + uint8_t magic[4]; + uint32_t version; + uint32_t header_size; + uint32_t flags; + uint32_t length; + uint32_t glyph_size; + uint32_t height; + uint32_t width; + uint8_t data[]; +}; + +extern struct psf2_font en_font; + +int gpu_init(void) +{ + if (bochs_init() == SUCCESS) + type = GPU_BOCHS; + + if (type != GPU_UNSET) { + uint16_t width = gpu_width() / en_font.width; + uint16_t height = gpu_height() / en_font.height; + term_switch_handler(width, height, gpu_draw_char); + } + + return type != GPU_UNSET; +} + +uint32_t gpu_width(void) +{ + switch (type) { + case GPU_BOCHS: + return bochs_width(); + default: + return 0; + } +} + +uint32_t gpu_height(void) +{ + switch (type) { + case GPU_BOCHS: + return bochs_height(); + default: + return 0; + } +} + +uint8_t gpu_bit_depth(void) +{ + switch (type) { + case GPU_BOCHS: + return bochs_bit_depth(); + default: + return 0; + } +} + +void gpu_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b) +{ + switch (type) { + case GPU_BOCHS: + bochs_set_pixel(x, y, r, g, b); + break; + default: + break; + } +} + +void gpu_draw_char(char c, uint16_t cx, uint16_t cy) +{ + uint32_t sx = en_font.width * cx; + uint32_t sy = en_font.height * cy; + + uint8_t *glyph = &en_font.data[en_font.glyph_size * c]; + + for (uint32_t i = 0; i < en_font.width; i++) { + for (uint32_t j = 0; j < en_font.height; j++) { + uint32_t x = sx + (en_font.width - i - 1); + uint32_t y = sy + j; + uint32_t bitoff = i + j * en_font.width; + uint32_t byteoff = bitoff / 8; + uint32_t bitshift = bitoff % 8; + + uint32_t color = ((glyph[byteoff] >> bitshift) & 0x1) * 255; + gpu_set_pixel(x, y, color, color, color); + } + } +} + +void gpu_report(void) +{ + if (type == GPU_UNSET) + return; + + kprintf("GPU (%s)\n", gpu_type_str[type]); + kprintf("Width: %d\n", gpu_width()); + kprintf("Height: %d\n", gpu_height()); + kprintf("Bit depth: %d\n\n", gpu_bit_depth()); +} -- 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/drivers/gpu.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