From 97341b9c46b840658fd27838fcd382f91a0423fc Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 5 Sep 2023 19:11:15 +0200 Subject: [PATCH] improve printing functions and project structure --- .gitignore | 2 + roadmap.md | 7 +++ src/kernel/include/internal/io.h | 10 ++++ src/kernel/include/internal/text_screen.h | 39 +++++++++++++ src/kernel/include/string.h | 7 --- src/kernel/kmain.c | 9 ++- src/kernel/lib/string.c | 44 --------------- src/kernel/lib/text_screen.c | 68 +++++++++++++++++++++++ 8 files changed, 133 insertions(+), 53 deletions(-) create mode 100644 roadmap.md create mode 100644 src/kernel/include/internal/io.h create mode 100644 src/kernel/include/internal/text_screen.h delete mode 100644 src/kernel/include/string.h delete mode 100644 src/kernel/lib/string.c create mode 100644 src/kernel/lib/text_screen.c diff --git a/.gitignore b/.gitignore index 7981869..78f7002 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ build/ *.ini + +.clangd diff --git a/roadmap.md b/roadmap.md new file mode 100644 index 0000000..fbde483 --- /dev/null +++ b/roadmap.md @@ -0,0 +1,7 @@ +# Short-term goals +1. Paging + * Write a page allocator + * Setup the x86 for Paging +2. Process scheduling +3. Implement a filesystem + diff --git a/src/kernel/include/internal/io.h b/src/kernel/include/internal/io.h new file mode 100644 index 0000000..77c3917 --- /dev/null +++ b/src/kernel/include/internal/io.h @@ -0,0 +1,10 @@ +#ifndef _CLIPPER_IO_H_ +#define _CLIPPER_IO_H_ + +#include + +inline void outb(uint16_t port, uint8_t val) { + asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port) : "memory"); +} + +#endif // _CLIPPER_IO_H_ diff --git a/src/kernel/include/internal/text_screen.h b/src/kernel/include/internal/text_screen.h new file mode 100644 index 0000000..feed931 --- /dev/null +++ b/src/kernel/include/internal/text_screen.h @@ -0,0 +1,39 @@ +#ifndef _CLIPPER_TEXT_SCREEN_H_ +#define _CLIPPER_TEXT_SCREEN_H_ + +#include + +enum text_screen_attribute { + TEXT_SCREEN_FG_BLACK = 0, + TEXT_SCREEN_FG_BLUE, + TEXT_SCREEN_FG_GREEN, + TEXT_SCREEN_FG_CYAN, + TEXT_SCREEN_FG_RED, + TEXT_SCREEN_FG_PURPLE, + TEXT_SCREEN_FG_BROWN, + TEXT_SCREEN_FG_GRAY, + TEXT_SCREEN_FG_DARK_GRAY, + TEXT_SCREEN_FG_LIGHT_BLUE, + TEXT_SCREEN_FG_LIGHT_GREEN, + TEXT_SCREEN_FG_LIGHT_CYAN, + TEXT_SCREEN_FG_LIGHT_RED, + TEXT_SCREEN_FG_LIGHT_PURPLE, + TEXT_SCREEN_FG_LIGHT_YELLOW, + TEXT_SCREEN_FG_WHITE, + + TEXT_SCREEN_BG_BLACK = 0, + TEXT_SCREEN_BG_BLUE = (1 << 4), + TEXT_SCREEN_BG_GREEN = (2 << 4), + TEXT_SCREEN_BG_CYAN = (3 << 4), + TEXT_SCREEN_BG_RED = (4 << 4), + TEXT_SCREEN_BG_PURPLE = (5 << 4), + TEXT_SCREEN_BG_BROWN = (6 << 4), + TEXT_SCREEN_BG_GRAY = (7 << 4) +}; + +void tsinit(void); + +void tsputch(char ch, uint8_t color); +void tsputs(const char* str, uint8_t color); + +#endif // _CLIPPER_TEXT_SCREEN_H_ diff --git a/src/kernel/include/string.h b/src/kernel/include/string.h deleted file mode 100644 index 4f6049d..0000000 --- a/src/kernel/include/string.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _CLIPPER_STRING_H_ -#define _CLIPPER_STRING_H_ - -void putch(char c); -void puts(const char* str); - -#endif diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index 42d71eb..58dd5d6 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -1,3 +1,4 @@ +#include "include/internal/text_screen.h" #include #include #include @@ -10,9 +11,13 @@ # error "Please use an ix86-elf compiler" #endif -#include "string.h" +#include "internal/text_screen.h" void kmain(void) { - puts("Clipper has booted!\r\n"); + tsinit(); + + const char* msg = "Clipper set sail!\n~~~~~~~~~~~~~~~~~"; + tsputs(msg, TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_LIGHT_CYAN); + return; } diff --git a/src/kernel/lib/string.c b/src/kernel/lib/string.c deleted file mode 100644 index bb51a3b..0000000 --- a/src/kernel/lib/string.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "string.h" - -#include - -static volatile char* video = (volatile char*)0xB8000; -static uint8_t cursor_x = 0, cursor_y = 0; - -#define SCREEN_WIDTH 80 -#define SCREEN_HEIGHT 25 - -static inline void advance_cursor(void) { - cursor_x++; - if (cursor_x >= SCREEN_WIDTH) { - cursor_x = 0; - cursor_y++; - - if (cursor_y >= SCREEN_HEIGHT) { - cursor_y = 0; - } - } -} - -static inline void linefeed(void) { - cursor_y++; - if (cursor_y >= SCREEN_HEIGHT) { - cursor_y = 0; - } -} - -void putch(char c) { - switch(c) { - case '\r': cursor_x = 0; return; - case '\n': linefeed(); return; - } - - video[cursor_y * (SCREEN_WIDTH * 2) + (cursor_x * 2)] = c; - advance_cursor(); -} - -void puts(const char* str) { - for (const char* c = str; *c != '\0'; c++) { - putch(*c); - } -} diff --git a/src/kernel/lib/text_screen.c b/src/kernel/lib/text_screen.c new file mode 100644 index 0000000..1150263 --- /dev/null +++ b/src/kernel/lib/text_screen.c @@ -0,0 +1,68 @@ +#include "internal/text_screen.h" +#include "internal/io.h" + +struct text_screen_char { + char character; + uint8_t attribute; +} __attribute__((packed)); + +static volatile struct text_screen_char* videomem = (struct text_screen_char*)0xB8000; +static uint8_t cursor_x = 0; +static uint8_t cursor_y = 0; + +#define SCREEN_WIDTH 80 +#define SCREEN_HEIGHT 25 + +void tsinit(void) { + outb(0x3D4, 0x0A); + outb(0x3D5, 0x20); +} + +void tsputch(char ch, uint8_t color) { + const char tmp[2] = { ch, 0 }; + tsputs(tmp, color); +} + +static void handle_special_char(char c) { + switch (c) { + case '\n': { + cursor_x = 0; + cursor_y++; + + if (cursor_y >= SCREEN_HEIGHT) { + cursor_y = 0; + } + } break; + + case '\r': cursor_x = 0; break; + case '\t': cursor_x += 4; break; + } +} + +void tsputs(const char* ch, uint8_t color) { + struct text_screen_char tsch = { + .character = '\0', + .attribute = (color & 0x7F) + }; + + for(const char* c = ch; *c != '\0'; c++) { + if ((uint8_t)(*c) < 0x20) { + handle_special_char(*c); + continue; + } + + tsch.character = *c; + + videomem[cursor_y * SCREEN_WIDTH + cursor_x] = tsch; + + cursor_x++; + if (cursor_x >= SCREEN_WIDTH) { + cursor_y++; + cursor_x = 0; + + if (cursor_y >= SCREEN_HEIGHT) { + cursor_y = 0; + } + } + } +}