diff --git a/arch/x86/kernel/vga.c b/arch/x86/kernel/vga.c index 18cd183a..3b66f271 100644 --- a/arch/x86/kernel/vga.c +++ b/arch/x86/kernel/vga.c @@ -209,15 +209,15 @@ int vga_puts(const char *text) } /* Sets the forecolor and backcolor we will use */ -//void settextcolor(unsigned char forecolor, unsigned char backcolor) -//{ +void settextcolor(unsigned char forecolor, unsigned char backcolor) +{ /* * Top 4 bytes are the background, bottom 4 bytes * are the foreground color */ -// attrib = (backcolor << 4) | (forecolor & 0x0F); -//} + attrib = ((backcolor & 0x0F) << 4) | (forecolor & 0x0F); +} /* Sets our text-mode VGA pointer, then clears the screen for us */ void vga_init(void) diff --git a/include/metalsvm/stdio.h b/include/metalsvm/stdio.h index 6f9fc20e..cd5d2a61 100644 --- a/include/metalsvm/stdio.h +++ b/include/metalsvm/stdio.h @@ -74,6 +74,45 @@ int koutput_init(void); */ int kvprintf(char const *fmt, void (*func) (int, void *), void *arg, int radix, va_list ap); +/** @brief Set a new foreground color for kprintf and kputchar. + * + * The color change will affect any procedure using vga_putchar()/vga_puts(). + * This procedure pushes the color onto a colorstack making you + * able to revert this change just with a popfg(). + * */ +void pushfg(unsigned char fgcol); + +/** @brief Set a new background color for kprintf and kputchar. + * + * The color change will affect any procedure using vga_putchar()/vga_puts(). + * This procedure pushes the color onto a colorstack making you + * able to revert this change just with a popbg(). + * */ +void pushbg(unsigned char bgcol); + +#define COL_BLACK 0 +#define COL_BLUE 1 +#define COL_GREEN 2 +#define COL_CYAN 3 +#define COL_RED 4 +#define COL_MAGENTA 5 +#define COL_BROWN 6 +#define COL_LGRAY 7 +#define COL_DGRAY 8 +#define COL_LBLUE 9 +#define COL_LGREEN 10 +#define COL_LCYAN 11 +#define COL_LRED 12 +#define COL_LMAGENTA 13 +#define COL_LYELLOW 14 +#define COL_WHITE 15 + +/** @brief Revert the last foreground color change introduced by pushfg() */ +void popfg(); + +/** @brief Revert the last background color change introduced by pushfg() */ +void popbg(); + #ifdef __cplusplus } #endif diff --git a/kernel/main.c b/kernel/main.c index 2d9caca9..daf7f3af 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -82,7 +82,10 @@ int main(void) { lowlevel_init(); - kprintf("This is MetalSVM %s Build %u, %u\n", METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME); + pushbg(COL_BLUE); + kprintf("This is MetalSVM %s Build %u, %u\n", + METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME); + popbg(); system_init(); irq_init(); diff --git a/libkern/printf.c b/libkern/printf.c index 780184bb..416d2893 100644 --- a/libkern/printf.c +++ b/libkern/printf.c @@ -45,6 +45,7 @@ */ #include +#include #define __64BIT__ @@ -74,6 +75,14 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ #define MAXNBUF (sizeof(intmax_t) * NBBY + 1) +#define COLOR_STACK_SIZE 10 +static int fgstack[COLOR_STACK_SIZE] = {0xf}; +static int bgstack[COLOR_STACK_SIZE] = {0x0}; +static unsigned int fgstack_pos = 0; +static unsigned int bgstack_pos = 0; +static spinlock_t fglock = SPINLOCK_INIT; +static spinlock_t bglock = SPINLOCK_INIT; + /* * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse * order; return an optional length and a pointer to the last character @@ -483,3 +492,57 @@ int kprintf(const char *fmt, ...) return ret; } + +extern void settextcolor(unsigned char forecolor, unsigned char backcolor); + +void pushfg(unsigned char fgcol) +{ + spinlock_lock(&fglock); + /* Ignore this request if the stack is full */ + if (fgstack_pos == COLOR_STACK_SIZE) goto rel_pushfglock; + + ++fgstack_pos; + fgstack[fgstack_pos] = fgcol; + + settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]); +rel_pushfglock: + spinlock_unlock(&fglock); +} + +void pushbg(unsigned char bgcol) +{ + spinlock_lock(&bglock); + /* Ignore this request if the stack is full */ + if (bgstack_pos == COLOR_STACK_SIZE) goto rel_pushbglock; + + ++bgstack_pos; + bgstack[bgstack_pos] = bgcol; + + settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]); +rel_pushbglock: + spinlock_unlock(&bglock); +} + +void popfg() +{ + spinlock_lock(&fglock); + /* Ignore if we're already at the stack's bottom */ + if (!fgstack_pos) goto rel_popfglock; + + --fgstack_pos; + settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]); +rel_popfglock: + spinlock_unlock(&fglock); +} + +void popbg() +{ + spinlock_lock(&bglock); + /* Ignore if we're already at the stack's bottom */ + if (!bgstack_pos) goto rel_popbglock; + + --bgstack_pos; + settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]); +rel_popbglock: + spinlock_unlock(&bglock); +}