beautiful glitch

This commit is contained in:
Julian Barathieu 2019-05-18 22:02:16 +02:00
parent b82dc4f0a3
commit 45b2f6400d
7 changed files with 197 additions and 13 deletions

72
include/io/vga.h Normal file
View File

@ -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 <https://www.gnu.org/licenses/>. //
//----------------------------------------------------------------------------//
#ifndef _KERNEL_H
#include <kernel.h>
#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

View File

@ -23,6 +23,7 @@
//----------------------------------------------------------------------------//
#include "init.h"
#include <io/vga.h>
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();

View File

@ -25,6 +25,15 @@
#include <lib/buf.h>
#include <init/boot.h>
#include <io/cursor.h>
#include <io/vga.h>
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

View File

@ -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" },

View File

@ -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;

View File

@ -31,11 +31,13 @@
#include <mm/heap.h>
#include <io/spkr.h>
#include <io/keyb.h>
#include <io/vga.h>
#include <po/shtdwn.h>
extern void IoScrollDown(void);
extern void IoScrollUp(void);
extern int shcol;
extern int shargc;
extern char *argv0;
extern char **shargv;

View File

@ -24,6 +24,10 @@
#include <lib/buf.h>
#ifdef _KALEID_KERNEL
#include <io/vga.h>
#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 *);