diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2021-02-10 22:53:50 +0200 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2021-02-10 22:53:50 +0200 |
commit | 6f54758123abe9f137922df1e8d7e33835e9a9f2 (patch) | |
tree | e21b553a826c7ae67cc4b41ffde921e39ed4022b | |
parent | Add some compiler warnings (diff) | |
download | kernel.cpp-6f54758123abe9f137922df1e8d7e33835e9a9f2.tar.xz |
Update VGA cursor position on printk
-rw-r--r-- | libk/stdlib.h | 41 | ||||
-rw-r--r-- | libk/types.h | 1 | ||||
-rw-r--r-- | src/gdt.h | 6 | ||||
-rw-r--r-- | src/memory.cc | 1 | ||||
-rw-r--r-- | src/ports.h | 43 | ||||
-rw-r--r-- | src/vga.cc | 24 | ||||
-rw-r--r-- | src/vga.h | 9 |
7 files changed, 107 insertions, 18 deletions
diff --git a/libk/stdlib.h b/libk/stdlib.h index 7d89a0c..a336586 100644 --- a/libk/stdlib.h +++ b/libk/stdlib.h @@ -7,33 +7,40 @@ class Console { virtual ~Console() = default; virtual void write(char c) = 0; virtual void write(ViewIterator& msg) = 0; + virtual void update_cursor() = 0; static void set(Console* ptr); static Console* get(); }; template <typename T> -void printk(const T& a) { - if (auto* c = Console::get()) { - if constexpr (is_same<T, char>()) { - c->write(a); - } else if constexpr (requires { StringView(a); }) { - StringView v(a); - auto iter = v.begin(); - c->write(iter); - } else if constexpr (requires { IntegerView(a); }) { - IntegerView v(a); - auto iter = v.begin(); - c->write(iter); - } else - c->write(a); - } +void print_c(Console* c, const T& a) { + if constexpr (is_same<T, char>()) { + c->write(a); + } else if constexpr (requires { StringView(a); }) { + StringView v(a); + auto iter = v.begin(); + c->write(iter); + } else if constexpr (requires { IntegerView(a); }) { + IntegerView v(a); + auto iter = v.begin(); + c->write(iter); + } else + c->write(a); +} + +template <typename T, typename... Args> +void print_c(Console* console, const T& a, const Args&... x) { + print_c(console, a); + print_c(console, x...); } template <typename T, typename... Args> void printk(const T& a, const Args&... x) { - printk(a); - printk(x...); + if (auto* c = Console::get()) { + print_c(c, a, x...); + c->update_cursor(); + } } extern "C" __attribute__((__noreturn__)) void abort(); diff --git a/libk/types.h b/libk/types.h index 4018ab8..599f852 100644 --- a/libk/types.h +++ b/libk/types.h @@ -19,6 +19,7 @@ template <class T, T v> struct integral_constant { constexpr T operator()() const { return v; } constexpr operator T() const { return v; } + static const T value = v; }; /* is_same */ @@ -2,7 +2,11 @@ #include <types.h> -/* From OSDev wiki: +/* + * http://lowlevel.eu/wiki/Global_Descriptor_Table + * https://wiki.osdev.org/GDT_Tutorial + * + * From OSDev wiki: * * Segment * a logically contiguous chunk of memory with consistent properties (CPU's speaking) diff --git a/src/memory.cc b/src/memory.cc index 0dbf3d0..a2a2561 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -2,4 +2,5 @@ void operator delete(void*) { printk("Calling delete\n"); + abort(); } diff --git a/src/ports.h b/src/ports.h new file mode 100644 index 0000000..0371bcc --- /dev/null +++ b/src/ports.h @@ -0,0 +1,43 @@ +#pragma once + +template <typename T> +concept port_data_t = (is_same<T, uint8_t>::value || is_same<T, uint16_t>::value || is_same<T, uint32_t>::value); + +template <uint16_t port_num, port_data_t T> +class Port { +public: + [[nodiscard]] T read() { + T result; + + switch (sizeof(T)) { + case 1: + asm volatile("inb %1, %0" : "=a"(result) : "Nd"(port_num)); + break; + case 2: + asm volatile("inw %1, %0" : "=a"(result) : "Nd"(port_num)); + break; + case 4: + asm volatile("inl %1, %0" : "=a"(result) : "Nd"(port_num)); + break; + } + + return result; + } + + void write(T data) { + switch (sizeof(T)) { + case 1: + asm volatile("outb %0, %1" : : "a"(data), "Nd"(port_num)); + break; + case 2: + asm volatile("outw %0, %1" : : "a"(data), "Nd"(port_num)); + break; + case 4: + asm volatile("outl %0, %1" : : "a"(data), "Nd"(port_num)); + break; + } + } +}; + +typedef Port<0x3d4, uint8_t> vga_horizontal_total; +typedef Port<0x3d5, uint8_t> vga_horizontal_display_enable_end; @@ -15,6 +15,9 @@ VGA::VGA(vga_color fg, vga_color bg, uint32_t address) : color_fg(fg), color_bg( buffer[index].bg = color_bg; } } + + enable_cursor(14, 15); + update_cursor(); } void VGA::set_color(vga_color fg, vga_color bg) { @@ -29,6 +32,27 @@ void VGA::set_color(vga_color fg, vga_color bg) { } } +void VGA::enable_cursor(uint8_t start, uint8_t end) { + p_3d4.write(0x0a); + p_3d5.write((p_3d5.read() & 0xc0) | start); + + p_3d4.write(0x0b); + p_3d5.write((p_3d5.read() & 0xe0) | end); +} +void VGA::disable_cursor() { + p_3d4.write(0x0a); + p_3d5.write(0x20); +} +void VGA::update_cursor() { + const uint16_t pos = row * max_columns + column; + + p_3d4.write(0x0f); + p_3d5.write(static_cast<uint8_t>(pos & 0xff)); + + p_3d4.write(0x0e); + p_3d5.write(static_cast<uint8_t>((pos >> 8) & 0xff)); +} + void VGA::write(char c) { switch (c) { case '\n': @@ -1,5 +1,6 @@ #pragma once #include <stdlib.h> +#include "ports.h" class VGA : public Console { public: @@ -28,6 +29,10 @@ public: void set_color(vga_color fg, vga_color bg); + void enable_cursor(uint8_t start, uint8_t end); + void disable_cursor(); + void update_cursor() override; + void write(char c) override; void write(ViewIterator& iter) override; @@ -46,5 +51,9 @@ private: vga_color color_bg; Entry* buffer; + + // ports + vga_horizontal_total p_3d4; + vga_horizontal_display_enable_end p_3d5; }; |