diff --git a/include/io/vga.h b/include/io/vga.h new file mode 100644 index 0000000..b0b8857 --- /dev/null +++ b/include/io/vga.h @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: VGA terminal // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#ifndef _KERNEL_H +#include +#endif + +#ifndef _IO_VGA_H +#define _IO_VGA_H + +//----------------------------------------------------------------------------// + +enum +{ + VGA_COLOR_BLACK, + VGA_COLOR_BLUE, + VGA_COLOR_GREEN, + VGA_COLOR_CYAN, + VGA_COLOR_RED, + VGA_COLOR_MAGENTA, + VGA_COLOR_BROWN, + VGA_COLOR_LIGHT_GREY, + VGA_COLOR_DARK_GREY, + VGA_COLOR_LIGHT_BLUE, + VGA_COLOR_LIGHT_GREEN, + VGA_COLOR_LIGHT_CYAN, + VGA_COLOR_LIGHT_RED, + VGA_COLOR_LIGHT_MAGENTA, + VGA_COLOR_LIGHT_BROWN, + VGA_COLOR_WHITE, + + VGA_COLOR_CURRENT = -1, +}; + +extern const char *RtlColorNames[VGA_COLOR_WHITE+1]; + +#define RtlColorToChar(c) ((c) + 130) +#define RtlCharToColor(c) ((c) - 130) + +void IoScrollDown(void); +void IoScrollUp(void); + +void IoChangeTermColor(int, int); + +error_t IoInitVGABuffer(void); + +//----------------------------------------------------------------------------// + +#endif + + diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index c2058d5..91d48ff 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -23,6 +23,7 @@ //----------------------------------------------------------------------------// #include "init.h" +#include void MmInitPaging(void); @@ -55,12 +56,19 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) KeSetupIDT(); KeEnableIRQs(); - //KalCmdLineToArgVec("test 1 2 3 4 5\n", &buf, ); - // Start drivers KeEnableRTC(); IoEnableKeyb(); + KernLog("%CThis %Cis %Ca %CColor %Ctest%C...%C\n", + VGA_COLOR_LIGHT_BLUE, + VGA_COLOR_BROWN, + VGA_COLOR_MAGENTA, + VGA_COLOR_LIGHT_GREEN, + VGA_COLOR_RED, + VGA_COLOR_DARK_GREY, + VGA_COLOR_LIGHT_GREY); + KeStartShell(); PoShutdown(); diff --git a/kaleid/kernel/io/vga.c b/kaleid/kernel/io/vga.c index 1c6a752..bdc18cb 100644 --- a/kaleid/kernel/io/vga.c +++ b/kaleid/kernel/io/vga.c @@ -25,6 +25,15 @@ #include #include #include +#include + +const char *RtlColorNames[VGA_COLOR_WHITE+1] = +{ + "Black", "Blue", "Green", "Cyan", "Red", + "Magenta", "Brown", "Light Grey", "Dark Grey", + "Light Blue", "Light Green", "Light Cyan", + "Light Red", "Light Magenta", "Light Brown", "White", +}; // // VGA-related macros @@ -34,6 +43,8 @@ #define VGA_ComputeEntry(ch, cl) (((ushort)(ch)) | (ushort)(cl) << 8) static uint bscroll = 0; +static int bfg = VGA_COLOR_LIGHT_GREY; +static int bbg = VGA_COLOR_BLACK; // // VGA Buffer Flusher @@ -41,7 +52,8 @@ static uint bscroll = 0; error_t bvgaflusher(Buffer_t *buf) { ushort *fbp = BtVideoInfo.framebufferAddr; - uchar color = 0xf; + uint color = VGA_ComputeColorCode(bfg, bbg), cols = 0; + uint oldfg = bfg, skip, rem = BStdOut->lineLen; uchar *currentLine = buf->wp - buf->lastLF; uchar *bufStart = (uchar *)lmax((size_t)buf->buf, @@ -50,15 +62,32 @@ error_t bvgaflusher(Buffer_t *buf) uchar *ptr = bufStart; - // Writes the buffer's content + for (skip = 0; ptr < buf->wp ; ptr++) { + // Handle color codes + if (*ptr >= RtlColorToChar(VGA_COLOR_BLACK) + && *ptr <= RtlColorToChar(VGA_COLOR_WHITE)) { + skip++; cols++; // 'cols' is for scrolling + bfg = RtlCharToColor(*ptr); + } + + // Write regular characters + else { + color = VGA_ComputeColorCode(bfg, bbg); + *fbp++ = VGA_ComputeEntry(*ptr, color); + } - for (; ptr < buf->wp ; ptr++) { - *fbp++ = VGA_ComputeEntry(*ptr, color); + // End of line? + if (--rem == 0) { + rem = BStdOut->lineLen; + cols = 0; + while (skip > 0) { + skip--; + *fbp++ = VGA_ComputeEntry(' ', color); + } + } } - - // Update the cursor - size_t curX = ((size_t)ptr - (size_t)bufStart) % buf->lineLen; + size_t curX = ((size_t)ptr - (size_t)bufStart - cols) % buf->lineLen; size_t curY = ((size_t)ptr - (size_t)bufStart) / buf->lineLen; IoUpdateCursor(curX, curY); @@ -73,6 +102,8 @@ error_t bvgaflusher(Buffer_t *buf) const ushort filler = VGA_ComputeEntry(' ', color); while (fbp < fbe) *fbp++ = filler; } + + bfg = oldfg; return EOK; } @@ -104,6 +135,17 @@ void IoScrollUp(void) BUnlockBuf(BStdOut); } +void IoChangeTermColor(int fg, int bg) +{ + if (fg < 0) fg = bfg; + if (bg < 0) bg = bbg; + + assert(fg <= VGA_COLOR_WHITE); + assert(bg <= VGA_COLOR_WHITE); + + bfg = fg; + bbg = bg; +} // // Initialize VGA buffer diff --git a/kaleid/kernel/sh/shcmds.c b/kaleid/kernel/sh/shcmds.c index eefbaae..9e0ffc9 100644 --- a/kaleid/kernel/sh/shcmds.c +++ b/kaleid/kernel/sh/shcmds.c @@ -251,6 +251,48 @@ error_t CmdArgs(int argc, char **argv, char *cmdline) return EOK; } +error_t CmdColor(int argc, char **argv, char *cmdline) +{ + int col = 0; + char *p; + + if (argc > 2) { + KernLog("Usage: 'color [#|list]'\n"); + return EINVAL; + } + + if (argc == 1) { + KernLog("Current color: %s (%d)\n", RtlColorNames[shcol], shcol); + } + + else if (!strcmp(argv[1], "list")) { + KernLog("Available colors:\n"); + for (col = 0; col <= VGA_COLOR_WHITE; col++) { + KernLog("%d - %s\n", col, RtlColorNames[col]); + } + } + + else { + p = argv[1]; + + while (isdigit(*p) && col < VGA_COLOR_WHITE) { + col = 10 * col + *p++ - '0'; + } + + if (*p || col < VGA_COLOR_BLACK || col > VGA_COLOR_WHITE) { + KernLog("Invalid color: %d\n", col); + KernLog("Usage: 'color [#|list]'\n"); + return EINVAL; + } + + else { + shcol = col; + } + + } + return EOK; +} + void MmInitPaging(void); error_t CmdReloadPage(int argc, char **argv, char *cmdline) @@ -280,6 +322,7 @@ Command_t cmdtable[] = { "args", CmdArgs, "Print command line" }, { "beep", CmdBeep, "Make a beep" }, { "cls", CmdClear, "Clears standard output" }, + { "color", CmdColor, "Change shell text color" }, { "date", CmdDate, "Print date" }, { "die", CmdDie, "Die painfully" }, { "exit", CmdQuit, "Initiate shutdown" }, diff --git a/kaleid/kernel/sh/shell.c b/kaleid/kernel/sh/shell.c index 6b82927..dfaee76 100644 --- a/kaleid/kernel/sh/shell.c +++ b/kaleid/kernel/sh/shell.c @@ -24,6 +24,8 @@ #include "shell.h" +int shcol = VGA_COLOR_LIGHT_GREY; + int shargc = 0; char *argv0 = 0; char **shargv = 0; @@ -67,7 +69,7 @@ void KeStartShell(void) memzero(argv0, ARG_MAX * 2); shargv = (char **)argv0; - KernLog("\nshell> "); + KernLog("\n%Cshell> ", shcol); BFlushBuf(BStdOut); while ((rc = BGetFromBuf(BStdIn, &ch)) == EOK || rc == EENDF) { @@ -80,7 +82,7 @@ void KeStartShell(void) memzero(cmdbuf, CMDBUFSIZE); BFlushBuf(BStdIn); - KernLog("shell> "); + KernLog("%Cshell> ", shcol); BFlushBuf(BStdOut); } else break; @@ -131,7 +133,7 @@ void KeStartShell(void) ExecuteCommand(cmdbuf); memzero(cmdbuf, CMDBUFSIZE); - KernLog("shell> "); + KernLog("%Cshell> ", shcol); BFlushBuf(BStdIn); BFlushBuf(BStdOut); break; diff --git a/kaleid/kernel/sh/shell.h b/kaleid/kernel/sh/shell.h index c0f1151..aba40f7 100644 --- a/kaleid/kernel/sh/shell.h +++ b/kaleid/kernel/sh/shell.h @@ -31,11 +31,13 @@ #include #include #include +#include #include extern void IoScrollDown(void); extern void IoScrollUp(void); +extern int shcol; extern int shargc; extern char *argv0; extern char **shargv; diff --git a/kaleid/libbuf/bprint.c b/kaleid/libbuf/bprint.c index a3ccfec..4d97295 100644 --- a/kaleid/libbuf/bprint.c +++ b/kaleid/libbuf/bprint.c @@ -24,6 +24,10 @@ #include +#ifdef _KALEID_KERNEL +#include +#endif + // // Prints formatted string on buf according to fmt // @@ -254,11 +258,22 @@ error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // Characters if (type == 'c') { uch = (uchar)va_arg(ap, int); - bputc(buf, uch); + rc = bputc(buf, uch); continue; } +#ifdef _KALEID_KERNEL + if (type == 'C') { + base = va_arg(ap, int); + + if (!(base < 0 || base > VGA_COLOR_WHITE)) + rc = bputc(buf, RtlColorToChar(base)); + + continue; + } +#endif + // Strings else if (type == 's') { s = va_arg(ap, char *);