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 *);