Kernel: Abstract TTY to use new VESA
This commit is contained in:
parent
930661619b
commit
9274c9ee2f
|
@ -0,0 +1,171 @@
|
||||||
|
#include <kernel/multiboot.h>
|
||||||
|
#include <kernel/Serial.h>
|
||||||
|
#include <kernel/VESA.h>
|
||||||
|
|
||||||
|
#define MULTIBOOT_FLAGS_FRAMEBUFFER (1 << 12)
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS 1
|
||||||
|
#define MULTIBOOT_FRAMEBUFFER_TYPE_TEXT 2
|
||||||
|
|
||||||
|
extern multiboot_info_t* s_multiboot_info;
|
||||||
|
|
||||||
|
namespace VESA
|
||||||
|
{
|
||||||
|
static void* s_addr = nullptr;
|
||||||
|
static uint8_t s_bpp = 0;
|
||||||
|
static uint32_t s_width = 0;
|
||||||
|
static uint32_t s_height = 0;
|
||||||
|
static uint8_t s_mode = 0;
|
||||||
|
|
||||||
|
static void GraphicsPutCharAt(char ch, uint32_t x, uint32_t y, Color fg, Color bg);
|
||||||
|
static void GraphicsClear(Color color);
|
||||||
|
static void GraphicsScrollLine(uint32_t line);
|
||||||
|
static bool InitializeGraphicsMode();
|
||||||
|
|
||||||
|
static inline uint8_t TextColor(Color fg, Color bg);
|
||||||
|
static inline uint16_t TextEntry(uint8_t ch, uint8_t color);
|
||||||
|
static void TextPutCharAt(char c, uint32_t x, uint32_t y, Color fg, Color bg);
|
||||||
|
static void TextClear(Color color);
|
||||||
|
static void TextScrollLine(uint32_t line);
|
||||||
|
static bool InitializeTextMode();
|
||||||
|
|
||||||
|
void PutEntryAt(char ch, uint32_t x, uint32_t y, Color fg, Color bg)
|
||||||
|
{
|
||||||
|
if (x >= s_width)
|
||||||
|
return;
|
||||||
|
if (y >= s_height)
|
||||||
|
return;
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||||
|
return GraphicsPutCharAt(ch, x, y, fg, bg);
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
||||||
|
return TextPutCharAt(ch, x, y, fg, bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear(Color color)
|
||||||
|
{
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||||
|
return GraphicsClear(color);
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
||||||
|
return TextClear(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollLine(uint32_t line)
|
||||||
|
{
|
||||||
|
if (line == 0 || line >= s_height)
|
||||||
|
return;
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||||
|
return GraphicsScrollLine(line);
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
||||||
|
return TextScrollLine(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GetWidth()
|
||||||
|
{
|
||||||
|
return s_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GetHeight()
|
||||||
|
{
|
||||||
|
return s_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Initialize()
|
||||||
|
{
|
||||||
|
if (!(s_multiboot_info->flags & MULTIBOOT_FLAGS_FRAMEBUFFER))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto& framebuffer = s_multiboot_info->framebuffer;
|
||||||
|
s_addr = (void*)framebuffer.addr;
|
||||||
|
s_bpp = framebuffer.bpp;
|
||||||
|
s_width = framebuffer.width;
|
||||||
|
s_height = framebuffer.height;
|
||||||
|
s_mode = framebuffer.type;
|
||||||
|
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_GRAPHICS)
|
||||||
|
{
|
||||||
|
dprintln("VESA in Graphics mode {}x{} ({} bpp)", s_width, s_height, s_bpp);
|
||||||
|
GraphicsClear(Color::BLACK);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_mode == MULTIBOOT_FRAMEBUFFER_TYPE_TEXT)
|
||||||
|
{
|
||||||
|
dprintln("VESA in Text mode {}x{}", s_width, s_height);
|
||||||
|
TextClear(Color::BLACK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintln("Unsupported type for VESA framebuffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void GraphicsPutCharAt(char ch, uint32_t x, uint32_t y, Color fg, Color bg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GraphicsClear(Color color)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GraphicsScrollLine(uint32_t line)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool InitializeGraphicsMode()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint8_t TextColor(Color fg, Color bg)
|
||||||
|
{
|
||||||
|
return ((bg & 0x0F) << 4) | (fg & 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t TextEntry(uint8_t ch, uint8_t color)
|
||||||
|
{
|
||||||
|
return ((uint16_t)color << 8) | ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TextPutCharAt(char c, uint32_t x, uint32_t y, Color fg, Color bg)
|
||||||
|
{
|
||||||
|
uint64_t index = y * s_width + x;
|
||||||
|
((uint16_t*)s_addr)[index] = TextEntry(c, TextColor(fg, bg));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TextClear(Color color)
|
||||||
|
{
|
||||||
|
for (uint32_t y = 0; y < s_height; y++)
|
||||||
|
for (uint32_t x = 0; x < s_width; x++)
|
||||||
|
TextPutCharAt(' ', x, y, Color::WHITE, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TextScrollLine(uint32_t line)
|
||||||
|
{
|
||||||
|
for (uint32_t x = 0; x < s_width; x++)
|
||||||
|
{
|
||||||
|
uint64_t index1 = (line - 0) * s_width + x;
|
||||||
|
uint64_t index2 = (line - 1) * s_width + x;
|
||||||
|
((uint16_t*)s_addr)[index2] = ((uint16_t*)s_addr)[index1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool InitializeTextMode()
|
||||||
|
{
|
||||||
|
TextClear(Color::BLACK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,3 +11,4 @@ $(ARCHDIR)/GDT.o \
|
||||||
$(ARCHDIR)/GDT_asm.o \
|
$(ARCHDIR)/GDT_asm.o \
|
||||||
$(ARCHDIR)/IDT.o \
|
$(ARCHDIR)/IDT.o \
|
||||||
$(ARCHDIR)/IDT_asm.o \
|
$(ARCHDIR)/IDT_asm.o \
|
||||||
|
$(ARCHDIR)/VESA.o \
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
#include <kernel/IO.h>
|
#include <kernel/IO.h>
|
||||||
#include <kernel/multiboot.h>
|
|
||||||
#include <kernel/panic.h>
|
#include <kernel/panic.h>
|
||||||
#include <kernel/Serial.h>
|
#include <kernel/Serial.h>
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
|
#include <kernel/VESA.h>
|
||||||
|
|
||||||
#include "vga.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define BEL 0x07
|
#define BEL 0x07
|
||||||
|
@ -22,89 +19,47 @@
|
||||||
namespace TTY
|
namespace TTY
|
||||||
{
|
{
|
||||||
|
|
||||||
static size_t VGA_WIDTH;
|
static uint32_t terminal_height = 0;
|
||||||
static size_t VGA_HEIGHT;
|
static uint32_t terminal_width = 0;
|
||||||
static uint16_t* VGA_MEMORY = nullptr;
|
static uint32_t terminal_row = 0;
|
||||||
|
static uint32_t terminal_col = 0;
|
||||||
static size_t terminal_row;
|
static VESA::Color terminal_fg = VESA::Color::WHITE;
|
||||||
static size_t terminal_col;
|
static VESA::Color terminal_bg = VESA::Color::BLACK;
|
||||||
static uint8_t terminal_color;
|
|
||||||
static uint16_t* terminal_buffer = nullptr;
|
|
||||||
|
|
||||||
static char s_ansi_escape_mode = '\0';
|
static char s_ansi_escape_mode = '\0';
|
||||||
static int s_ansi_escape_index = 0;
|
static int s_ansi_escape_index = 0;
|
||||||
static int s_ansi_escape_nums[2] = { -1, -1 };
|
static int s_ansi_escape_nums[2] = { -1, -1 };
|
||||||
|
|
||||||
|
template<typename T> inline constexpr T max(T a, T b) { return a > b ? a : b; }
|
||||||
|
template<typename T> inline constexpr T min(T a, T b) { return a < b ? a : b; }
|
||||||
|
template<typename T> inline constexpr T clamp(T x, T a, T b) { return x < a ? a : x > b ? b : x; }
|
||||||
|
|
||||||
inline constexpr int max(int a, int b) { return a > b ? a : b; }
|
void initialize()
|
||||||
inline constexpr int min(int a, int b) { return a < b ? a : b; }
|
|
||||||
inline constexpr int clamp(int x, int a, int b) { return x < a ? a : x > b ? b : x; }
|
|
||||||
|
|
||||||
void putentryat(unsigned char c, uint8_t color, size_t x, size_t y)
|
|
||||||
{
|
{
|
||||||
const size_t index = y * VGA_WIDTH + x;
|
terminal_width = VESA::GetWidth();
|
||||||
terminal_buffer[index] = vga_entry(c, color);
|
terminal_height = VESA::GetHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
for (size_t y = 0; y < VGA_HEIGHT; y++)
|
VESA::Clear(VESA::Color::BLACK);
|
||||||
for (size_t x = 0; x < VGA_WIDTH; x++)
|
|
||||||
putentryat(' ', terminal_color, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize()
|
void setcolor(VESA::Color fg, VESA::Color bg)
|
||||||
{
|
{
|
||||||
if (s_multiboot_info->flags & (1 << 12))
|
terminal_fg = fg;
|
||||||
{
|
terminal_bg = bg;
|
||||||
const framebuffer_info_t& fb = s_multiboot_info->framebuffer;
|
|
||||||
VGA_WIDTH = fb.width;
|
|
||||||
VGA_HEIGHT = fb.height;
|
|
||||||
VGA_MEMORY = (uint16_t*)fb.addr;
|
|
||||||
|
|
||||||
dprintln("width: {}, height: {}, bpp: {}, pitch: {}", fb.width, fb.height, fb.bpp, fb.pitch);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VGA_WIDTH = 80;
|
|
||||||
VGA_HEIGHT = 25;
|
|
||||||
VGA_MEMORY = (uint16_t*)0xB8000;
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal_row = 0;
|
|
||||||
terminal_col = 0;
|
|
||||||
terminal_color = vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
|
|
||||||
terminal_buffer = VGA_MEMORY;
|
|
||||||
clear();
|
|
||||||
|
|
||||||
if (s_multiboot_info->flags & (1 << 12))
|
|
||||||
if (s_multiboot_info->framebuffer.type != 2)
|
|
||||||
dprintln("Invalid framebuffer_type in multiboot info");
|
|
||||||
}
|
|
||||||
|
|
||||||
void setcolor(uint8_t color)
|
|
||||||
{
|
|
||||||
terminal_color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_line(size_t line)
|
|
||||||
{
|
|
||||||
for (size_t x = 0; x < VGA_WIDTH; x++)
|
|
||||||
{
|
|
||||||
const size_t index = line * VGA_WIDTH + x;
|
|
||||||
terminal_buffer[index - VGA_WIDTH] = terminal_buffer[index];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_line(size_t line)
|
void clear_line(size_t line)
|
||||||
{
|
{
|
||||||
for (size_t x = 0; x < VGA_WIDTH; x++)
|
for (size_t x = 0; x < terminal_width; x++)
|
||||||
putentryat(' ', terminal_color, x, line);
|
VESA::PutEntryAt(' ', x, line, terminal_fg, terminal_bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_cursor()
|
static void update_cursor()
|
||||||
{
|
{
|
||||||
uint16_t pos = terminal_row * VGA_WIDTH + terminal_col;
|
uint16_t pos = terminal_row * terminal_width + terminal_col;
|
||||||
IO::outb(0x3D4, 0x0F);
|
IO::outb(0x3D4, 0x0F);
|
||||||
IO::outb(0x3D5, (uint8_t) (pos & 0xFF));
|
IO::outb(0x3D5, (uint8_t) (pos & 0xFF));
|
||||||
IO::outb(0x3D4, 0x0E);
|
IO::outb(0x3D4, 0x0E);
|
||||||
|
@ -130,59 +85,29 @@ namespace TTY
|
||||||
{
|
{
|
||||||
switch (s_ansi_escape_nums[0])
|
switch (s_ansi_escape_nums[0])
|
||||||
{
|
{
|
||||||
case -1: case 0:
|
case -1:
|
||||||
terminal_color = vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
|
case 0:
|
||||||
|
terminal_fg = VESA::Color::WHITE;
|
||||||
|
terminal_bg = VESA::Color::BLACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30:
|
case 30: terminal_fg = VESA::Color::BLACK; break;
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_BLACK, terminal_color);
|
case 31: terminal_fg = VESA::Color::LIGHT_RED; break;
|
||||||
break;
|
case 32: terminal_fg = VESA::Color::LIGHT_GREEN; break;
|
||||||
case 31:
|
case 33: terminal_fg = VESA::Color::LIGHT_BROWN; break;
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_RED, terminal_color);
|
case 34: terminal_fg = VESA::Color::LIGHT_BLUE; break;
|
||||||
break;
|
case 35: terminal_fg = VESA::Color::LIGHT_MAGENTA; break;
|
||||||
case 32:
|
case 36: terminal_fg = VESA::Color::LIGHT_CYAN; break;
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_GREEN, terminal_color);
|
case 37: terminal_fg = VESA::Color::LIGHT_GREY; break;
|
||||||
break;
|
|
||||||
case 33:
|
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_BROWN, terminal_color);
|
|
||||||
break;
|
|
||||||
case 34:
|
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_BLUE, terminal_color);
|
|
||||||
break;
|
|
||||||
case 35:
|
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_MAGENTA, terminal_color);
|
|
||||||
break;
|
|
||||||
case 36:
|
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_CYAN, terminal_color);
|
|
||||||
break;
|
|
||||||
case 37:
|
|
||||||
terminal_color = vga_set_foreground(VGA_COLOR_LIGHT_GREY, terminal_color);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 40:
|
case 40: terminal_bg = VESA::Color::BLACK; break;
|
||||||
terminal_color = vga_set_background(VGA_COLOR_BLACK, terminal_color);
|
case 41: terminal_bg = VESA::Color::LIGHT_RED; break;
|
||||||
break;
|
case 42: terminal_bg = VESA::Color::LIGHT_GREEN; break;
|
||||||
case 41:
|
case 43: terminal_bg = VESA::Color::LIGHT_BROWN; break;
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_RED, terminal_color);
|
case 44: terminal_bg = VESA::Color::LIGHT_BLUE; break;
|
||||||
break;
|
case 45: terminal_bg = VESA::Color::LIGHT_MAGENTA; break;
|
||||||
case 42:
|
case 46: terminal_bg = VESA::Color::LIGHT_CYAN; break;
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_GREEN, terminal_color);
|
case 47: terminal_bg = VESA::Color::LIGHT_GREY; break;
|
||||||
break;
|
|
||||||
case 43:
|
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_BROWN, terminal_color);
|
|
||||||
break;
|
|
||||||
case 44:
|
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_BLUE, terminal_color);
|
|
||||||
break;
|
|
||||||
case 45:
|
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_MAGENTA, terminal_color);
|
|
||||||
break;
|
|
||||||
case 46:
|
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_CYAN, terminal_color);
|
|
||||||
break;
|
|
||||||
case 47:
|
|
||||||
terminal_color = vga_set_background(VGA_COLOR_LIGHT_GREY, terminal_color);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,47 +142,47 @@ namespace TTY
|
||||||
case 'A': // Cursor Up
|
case 'A': // Cursor Up
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_row = max(terminal_row - s_ansi_escape_nums[0], 0);
|
terminal_row = max<int32_t>(terminal_row - s_ansi_escape_nums[0], 0);
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'B': // Curson Down
|
case 'B': // Curson Down
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_row = min(terminal_row + s_ansi_escape_nums[0], VGA_HEIGHT - 1);
|
terminal_row = min<int32_t>(terminal_row + s_ansi_escape_nums[0], terminal_height - 1);
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'C': // Cursor Forward
|
case 'C': // Cursor Forward
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_col = min(terminal_col + s_ansi_escape_nums[0], VGA_WIDTH - 1);
|
terminal_col = min<int32_t>(terminal_col + s_ansi_escape_nums[0], terminal_width - 1);
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'D': // Cursor Back
|
case 'D': // Cursor Back
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_col = max(terminal_col - s_ansi_escape_nums[0], 0);
|
terminal_col = max<int32_t>(terminal_col - s_ansi_escape_nums[0], 0);
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'E': // Cursor Next Line
|
case 'E': // Cursor Next Line
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_row = min(terminal_row + s_ansi_escape_nums[0], VGA_HEIGHT - 1);
|
terminal_row = min<int32_t>(terminal_row + s_ansi_escape_nums[0], terminal_height - 1);
|
||||||
terminal_col = 0;
|
terminal_col = 0;
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'F': // Cursor Previous Line
|
case 'F': // Cursor Previous Line
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_row = max(terminal_row - s_ansi_escape_nums[0], 0);
|
terminal_row = max<int32_t>(terminal_row - s_ansi_escape_nums[0], 0);
|
||||||
terminal_col = 0;
|
terminal_col = 0;
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'G': // Cursor Horizontal Absolute
|
case 'G': // Cursor Horizontal Absolute
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
terminal_col = clamp(s_ansi_escape_nums[0] - 1, 0, VGA_WIDTH - 1);
|
terminal_col = clamp<int32_t>(s_ansi_escape_nums[0] - 1, 0, terminal_width - 1);
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'H': // Cursor Position
|
case 'H': // Cursor Position
|
||||||
if (s_ansi_escape_nums[0] == -1)
|
if (s_ansi_escape_nums[0] == -1)
|
||||||
s_ansi_escape_nums[0] = 1;
|
s_ansi_escape_nums[0] = 1;
|
||||||
if (s_ansi_escape_nums[1] == -1)
|
if (s_ansi_escape_nums[1] == -1)
|
||||||
s_ansi_escape_nums[1] = 1;
|
s_ansi_escape_nums[1] = 1;
|
||||||
terminal_row = clamp(s_ansi_escape_nums[0] - 1, 0, VGA_HEIGHT - 1);
|
terminal_row = clamp<int32_t>(s_ansi_escape_nums[0] - 1, 0, terminal_height - 1);
|
||||||
terminal_col = clamp(s_ansi_escape_nums[1] - 1, 0, VGA_WIDTH - 1);
|
terminal_col = clamp<int32_t>(s_ansi_escape_nums[1] - 1, 0, terminal_width - 1);
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
case 'J': // Erase in Display
|
case 'J': // Erase in Display
|
||||||
dprintln("Unsupported ANSI CSI character J");
|
dprintln("Unsupported ANSI CSI character J");
|
||||||
|
@ -266,16 +191,16 @@ namespace TTY
|
||||||
switch (s_ansi_escape_nums[0])
|
switch (s_ansi_escape_nums[0])
|
||||||
{
|
{
|
||||||
case -1: case 0:
|
case -1: case 0:
|
||||||
for (size_t i = terminal_col; i < VGA_WIDTH; i++)
|
for (size_t i = terminal_col; i < terminal_width; i++)
|
||||||
putentryat(' ', terminal_color, i, terminal_row);
|
VESA::PutEntryAt(' ', i, terminal_row, terminal_fg, terminal_bg);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
for (size_t i = 0; i <= terminal_col; i++)
|
for (size_t i = 0; i <= terminal_col; i++)
|
||||||
putentryat(' ', terminal_color, i, terminal_row);
|
VESA::PutEntryAt(' ', i, terminal_row, terminal_fg, terminal_bg);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
for (size_t i = 0; i < VGA_WIDTH; i++)
|
for (size_t i = 0; i < terminal_width; i++)
|
||||||
putentryat(' ', terminal_color, i, terminal_row);
|
VESA::PutEntryAt(' ', i, terminal_row, terminal_fg, terminal_bg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return reset_ansi_escape();
|
return reset_ansi_escape();
|
||||||
|
@ -305,9 +230,6 @@ namespace TTY
|
||||||
|
|
||||||
void putchar(char c)
|
void putchar(char c)
|
||||||
{
|
{
|
||||||
if (VGA_MEMORY == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (s_ansi_escape_mode)
|
if (s_ansi_escape_mode)
|
||||||
return handle_ansi_escape(c);
|
return handle_ansi_escape(c);
|
||||||
|
|
||||||
|
@ -339,22 +261,22 @@ namespace TTY
|
||||||
s_ansi_escape_mode = '\1';
|
s_ansi_escape_mode = '\1';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
putentryat(c, terminal_color, terminal_col, terminal_row);
|
VESA::PutEntryAt(c, terminal_col, terminal_row, terminal_fg, terminal_bg);
|
||||||
terminal_col++;
|
terminal_col++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (terminal_col >= VGA_WIDTH)
|
if (terminal_col >= terminal_width)
|
||||||
{
|
{
|
||||||
terminal_col = 0;
|
terminal_col = 0;
|
||||||
terminal_row++;
|
terminal_row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (terminal_row >= VGA_HEIGHT)
|
while (terminal_row >= terminal_height)
|
||||||
{
|
{
|
||||||
for (size_t line = 1; line < VGA_HEIGHT; line++)
|
for (size_t line = 1; line < terminal_height; line++)
|
||||||
scroll_line(line);
|
VESA::ScrollLine(line);
|
||||||
clear_line(VGA_HEIGHT - 1);
|
clear_line(terminal_height - 1);
|
||||||
|
|
||||||
terminal_col = 0;
|
terminal_col = 0;
|
||||||
terminal_row--;
|
terminal_row--;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace VESA
|
||||||
|
{
|
||||||
|
|
||||||
|
enum Color : uint8_t
|
||||||
|
{
|
||||||
|
BLACK = 0,
|
||||||
|
BLUE = 1,
|
||||||
|
GREEN = 2,
|
||||||
|
CYAN = 3,
|
||||||
|
RED = 4,
|
||||||
|
MAGENTA = 5,
|
||||||
|
BROWN = 6,
|
||||||
|
LIGHT_GREY = 7,
|
||||||
|
DARK_GREY = 8,
|
||||||
|
LIGHT_BLUE = 9,
|
||||||
|
LIGHT_GREEN = 10,
|
||||||
|
LIGHT_CYAN = 11,
|
||||||
|
LIGHT_RED = 12,
|
||||||
|
LIGHT_MAGENTA = 13,
|
||||||
|
LIGHT_BROWN = 14,
|
||||||
|
WHITE = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void PutEntryAt(char, uint32_t, uint32_t, Color, Color);
|
||||||
|
void Clear(Color);
|
||||||
|
void ScrollLine(uint32_t line);
|
||||||
|
|
||||||
|
uint32_t GetWidth();
|
||||||
|
uint32_t GetHeight();
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
#include <kernel/Serial.h>
|
#include <kernel/Serial.h>
|
||||||
#include <kernel/Shell.h>
|
#include <kernel/Shell.h>
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
|
#include <kernel/VESA.h>
|
||||||
|
|
||||||
#define DISABLE_INTERRUPTS() asm volatile("cli")
|
#define DISABLE_INTERRUPTS() asm volatile("cli")
|
||||||
#define ENABLE_INTERRUPTS() asm volatile("sti")
|
#define ENABLE_INTERRUPTS() asm volatile("sti")
|
||||||
|
@ -23,14 +24,24 @@ void kernel_main(multiboot_info_t* mbi, uint32_t magic)
|
||||||
{
|
{
|
||||||
DISABLE_INTERRUPTS();
|
DISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
Serial::initialize();
|
||||||
|
if (magic != 0x2BADB002)
|
||||||
|
{
|
||||||
|
dprintln("Invalid multiboot magic number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
s_multiboot_info = mbi;
|
s_multiboot_info = mbi;
|
||||||
|
|
||||||
if (magic != 0x2BADB002)
|
if (!VESA::Initialize())
|
||||||
|
{
|
||||||
|
dprintln("Could not initialize VESA");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
Serial::initialize();
|
|
||||||
TTY::initialize();
|
TTY::initialize();
|
||||||
|
|
||||||
|
dprintln("{}", mbi->framebuffer.type);
|
||||||
|
|
||||||
kmalloc_initialize();
|
kmalloc_initialize();
|
||||||
|
|
||||||
PIC::initialize();
|
PIC::initialize();
|
||||||
|
|
Loading…
Reference in New Issue