diff --git a/include/c/color.h b/include/c/color.h new file mode 100644 index 0000000..f366336 --- /dev/null +++ b/include/c/color.h @@ -0,0 +1,27 @@ +#ifndef COLOR_H +#define COLOR_H + +#define BLACK 0x00000000 // 0 +#define RED 0x00ff0000 // 1 +#define GREEN 0x0000ff00 // 2 +#define YELLOW 0x00ffff00 // 3 +#define BLUE 0x000000ff // 4 +#define MAGENTA 0x00ff00ff // 5 +#define CYAN 0x0000ffff // 6 +#define WHITE 0x00ffffff // 7 + +uint32_t codeToColor(uint8_t code) { + switch (code) { + case 0: return BLACK; + case 1: return RED; + case 2: return GREEN; + case 3: return YELLOW; + case 4: return BLUE; + case 5: return MAGENTA; + case 6: return CYAN; + case 7: return WHITE; + default: return BLACK; + } +} + +#endif diff --git a/include/c/stdio.h b/include/c/stdio.h index 8557dae..2d281bb 100644 --- a/include/c/stdio.h +++ b/include/c/stdio.h @@ -11,6 +11,10 @@ void print(const char* s) { write(STDOUT, s, strlen(s)); } +void clear() { + print("\x1b[J"); +} + void putc(char c) { static char _c; // We need to pass in a static address. Idk why _c = c; diff --git a/include/interrupt/pit.h b/include/interrupt/pit.h index c59d49b..7fa64a3 100644 --- a/include/interrupt/pit.h +++ b/include/interrupt/pit.h @@ -18,9 +18,8 @@ void timerHandler(intFrame_t* iframe) { static uint32_t cursorTicks = 0; cursorTicks++; - if (!terminal->hideCursor) { - if (cursorTicks % 500 == 0) putcAt(127, terminal->x, terminal->y); - else if (cursorTicks % 250 == 0) putcAt(' ', terminal->x, terminal->y); + if (!terminal->hideCursor) { // TODO: Make a better cursor drawing thing + if (cursorTicks % 500 == 0) toggleCursor(); } if (*sleepTimerTicks > 0) { --(*sleepTimerTicks); } diff --git a/include/interrupt/rtc.h b/include/interrupt/rtc.h index 2f6f125..2aa2ff7 100644 --- a/include/interrupt/rtc.h +++ b/include/interrupt/rtc.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -132,7 +133,7 @@ __attribute__ ((interrupt)) void rtcHandler(intFrame_t* iframe) { uint32_t x = gfxMode->xRes - len - 1; char* str = &buf[0]; for (uint8_t i = 0; i != len; i++, x++) { - putcAt(str[i], x, 0); + drawChar(str[i], x, 0, FG_COLOR, BG_COLOR); } } } diff --git a/include/screen/gfxmode.h b/include/screen/gfxmode.h index dea5762..bb5d115 100644 --- a/include/screen/gfxmode.h +++ b/include/screen/gfxmode.h @@ -4,15 +4,6 @@ #include #include -#define BLACK 0x00000000 // 0 -#define RED 0x00ff0000 // 1 -#define GREEN 0x0000ff00 // 2 -#define YELLOW 0x00ffff00 // 3 -#define BLUE 0x000000ff // 4 -#define MAGENTA 0x00ff00ff // 5 -#define CYAN 0x0000ffff // 6 -#define WHITE 0x00ffffff // 7 - #define BG_COLOR 0x00010b17 #define FG_COLOR 0x00ebddf4 diff --git a/include/screen/text.h b/include/screen/text.h index 93c5363..9aa76a4 100644 --- a/include/screen/text.h +++ b/include/screen/text.h @@ -8,9 +8,6 @@ #include #include -uint32_t bgColor = BG_COLOR; -uint32_t fgColor = FG_COLOR; - // TODO: Make this check if it's a valid font // TODO: Make it take a fileEntry_t? uint8_t loadFont(char* filename) { @@ -21,7 +18,7 @@ uint8_t loadFont(char* filename) { } // TODO: Reimplement larger text -void putcAt(char c, uint32_t x, uint32_t y) { +void drawChar(char c, uint32_t x, uint32_t y, uint32_t fgColor, uint32_t bgColor) { // Font info char* font = (char*)FONT_LOC; uint8_t charWidth = *(uint8_t*)FONT_WIDTH; @@ -65,7 +62,7 @@ void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() help memcpy32((char*)address, (char*)(address - bytesPerLine), bytesPerLine); } - uint32_t color = convertColor(bgColor); + uint32_t color = convertColor(terminal->bg); uint8_t* lastLine = (uint8_t*)(vidmem + (lines-1) * bytesPerLine); uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; @@ -80,7 +77,7 @@ void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() help } // TODO: Make this comply with the new terminal.h thing! -void clear() { +void clearScreen(uint32_t bgColor) { uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr; uint8_t bytesPerPx = (gfxMode->bpp+1) / 8; diff --git a/include/terminal/terminal.h b/include/terminal/terminal.h index 3b01b69..a9808cb 100644 --- a/include/terminal/terminal.h +++ b/include/terminal/terminal.h @@ -3,8 +3,10 @@ #include #include +#include #include #include +#include typedef struct { uint32_t x; // X Position of cursor in characters @@ -31,24 +33,95 @@ int32_t terminalWrite(const void* buf, uint32_t len) { // Do we need to check for NULL? Can we just skip it/ignore it? for (i = 0; i < len && str[i] != '\0'; i++) { if (str[i] == '\n') { - putcAt(' ', terminal->x, terminal->y); + drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); terminal->y++; terminal->x = 0; } else if (str[i] == '\b') { - putcAt(' ', terminal->x, terminal->y); + drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); if (terminal->x == 0) { terminal->x = terminal->width - 1; terminal->y--; // Y could be 0? } else { terminal->x--; } - putcAt(' ', terminal->x, terminal->y); + drawChar(' ', terminal->x, terminal->y, terminal->fg, terminal->bg); } else if (str[i] == '\x1b') { // Escape sequence if (str[++i] != '[') { // TODO: Support more types of escape sequences + i--; continue; } + + i++; + uint32_t args[8] = { 0 }; + uint8_t argc = 0; + while (1) { // I'm not 100% sure this works, but i'd like to imagine it does + if (argc > 8) break; // Max arg count? idk + + uint32_t value = atoi(&str[i]); + args[argc++] = value; + + while (value != 0) { // Skip by the number string + value /= 10; + i++; + } + + if (str[i] != ';') break; + i++; + } + + switch (str[i]) { // TODO: Add default values (see docs/escape.txt) + case 'A': // Cursor up + terminal->y -= args[0]; + break; + case 'B': // Cursor down + terminal->y += args[0]; + break; + case 'C': // Cursor left + terminal->x -= args[0]; + break; + case 'D': // Cursor right + terminal->x += args[0]; + break; + case 'E': // nth row + terminal->x = args[0]; + break; + case 'F': // nth col + terminal->y = args[0]; + break; + case 'G': // show/hide cursor + terminal->hideCursor = args[0] ? false : true; + break; + case 'H': // move cursor to (x,y) + terminal->x = args[0]; + terminal->y = args[1]; + break; + case 'I': // RESERVED + case 'J': // Erase screen + clearScreen(terminal->bg); + break; + case 'K': // Erase line + break; // TODO + case 'L': // Erase collumn + break; // TODO + case 'M': // Set FG + if (args[0] < 8) { + terminal->fg = codeToColor(args[0]); + } else if (args[0] == 8) { + terminal->fg = FG_COLOR; + } + break; + case 'N': // Set BG + if (args[0] < 8) { + terminal->bg = codeToColor(args[0]); + } else if (args[0] == 8) { + terminal->bg = BG_COLOR; + } + break; + default: break; + } + //i++; } else { - putcAt(str[i], terminal->x, terminal->y); + drawChar(str[i], terminal->x, terminal->y, terminal->fg, terminal->bg); terminal->x++; if (terminal->x >= terminal->width) { // Go to next line @@ -60,6 +133,13 @@ int32_t terminalWrite(const void* buf, uint32_t len) { scroll(); return i; // Number of characters that were printed -} +} + +void toggleCursor() { + static bool visible = false; + visible = !visible; + + drawChar(visible ? 127 : ' ', terminal->x, terminal->y, terminal->fg, terminal->bg); +} #endif diff --git a/src/kernel.c b/src/kernel.c index e8893f4..6c6bc81 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -52,6 +52,8 @@ void main() { // Screen setup loadFont("term16n.fnt"); + terminal->fg = FG_COLOR; + terminal->bg = BG_COLOR; clear(); print("kern.\n\n"); @@ -264,9 +266,7 @@ void main() { uint32_t physicalAddress = (uint32_t)allocPage(&page); if (mapPage((void*)physicalAddress, (void*)(entryPoint + i * PAGE_SIZE)) != 0) { - fgColor = RED; - print("\nNot enough memory to allocate!\n"); - fgColor = FG_COLOR; + print("\n\x1b[1MNot enough memory to allocate!\n"); break; } }