aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-02-10 22:53:50 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-02-10 22:53:50 +0200
commit6f54758123abe9f137922df1e8d7e33835e9a9f2 (patch)
treee21b553a826c7ae67cc4b41ffde921e39ed4022b
parentAdd some compiler warnings (diff)
downloadkernel.cpp-6f54758123abe9f137922df1e8d7e33835e9a9f2.tar.xz
Update VGA cursor position on printk
-rw-r--r--libk/stdlib.h41
-rw-r--r--libk/types.h1
-rw-r--r--src/gdt.h6
-rw-r--r--src/memory.cc1
-rw-r--r--src/ports.h43
-rw-r--r--src/vga.cc24
-rw-r--r--src/vga.h9
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 */
diff --git a/src/gdt.h b/src/gdt.h
index 274cb6a..a86a14f 100644
--- a/src/gdt.h
+++ b/src/gdt.h
@@ -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;
diff --git a/src/vga.cc b/src/vga.cc
index 6b64b98..66a6b3a 100644
--- a/src/vga.cc
+++ b/src/vga.cc
@@ -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':
diff --git a/src/vga.h b/src/vga.h
index 32c152f..7a8c755 100644
--- a/src/vga.h
+++ b/src/vga.h
@@ -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;
};