aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-07-24 20:51:55 +0000
committerFelix Morgner <felix.morgner@ost.ch>2025-07-24 20:51:55 +0000
commitdd04850c27e8bc273506f4a64bb28b7ddf111dc5 (patch)
treea00212f5c903e80e4e729c87ce34ece2c40e4ee6 /arch
parentfeac668578a35aac280b59d478a57b6937bb68da (diff)
downloadteachos-dd04850c27e8bc273506f4a64bb28b7ddf111dc5.tar.xz
teachos-dd04850c27e8bc273506f4a64bb28b7ddf111dc5.zip
kapi: rework text device interface
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/CMakeLists.txt2
-rw-r--r--arch/x86_64/include/x86_64/vga/text.hpp122
-rw-r--r--arch/x86_64/kapi/cio.cpp16
-rw-r--r--arch/x86_64/kapi/io.cpp36
-rw-r--r--arch/x86_64/src/vga/text.cpp23
5 files changed, 80 insertions, 119 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index c585cbf..e8b5162 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -12,7 +12,7 @@ target_link_libraries("x86_64" PUBLIC
target_sources("x86_64" PRIVATE
# api::kapi implementation
- "kapi/io.cpp"
+ "kapi/cio.cpp"
"kapi/memory.cpp"
"kapi/system.cpp"
diff --git a/arch/x86_64/include/x86_64/vga/text.hpp b/arch/x86_64/include/x86_64/vga/text.hpp
index 267eae9..f8e6f1b 100644
--- a/arch/x86_64/include/x86_64/vga/text.hpp
+++ b/arch/x86_64/include/x86_64/vga/text.hpp
@@ -1,9 +1,10 @@
#ifndef TEACHOS_X86_64_VIDEO_VGA_TEXT_HPP
#define TEACHOS_X86_64_VIDEO_VGA_TEXT_HPP
+#include "kapi/cio.hpp"
+
#include <cstdint>
#include <string_view>
-#include <type_traits>
namespace teachos::x86_64::vga::text
{
@@ -89,84 +90,57 @@ namespace teachos::x86_64::vga::text
attribute{color::gray, foreground_flag::intense, color::red, background_flag::none};
} // namespace common_attributes
- /**
- * @brief Clear the VGA text mode buffer.
- *
- * @note This function also resets the text mode buffer pointer.
- *
- * @param attribute The attribute to "clear" the screen with.
- */
- auto clear(attribute attribute = common_attributes::gray_on_black) -> void;
-
- /**
- * @brief Enable or disable the VGA text mode cursor.
- *
- * @param enabled Whether or not to enable the cursors.
- */
- auto cursor(bool enabled) -> void;
+ struct device final : teachos::cio::output_device
+ {
+ /**
+ * @brief Clear the VGA text mode buffer.
+ *
+ * @note This function also resets the text mode buffer pointer.
+ *
+ * @param attribute The attribute to "clear" the screen with.
+ */
+ auto clear(attribute attribute = common_attributes::gray_on_black) -> void;
- /**
- * @brief Move the cursor to a new line, scrolling the buffer if necessary.
- */
- auto newline() -> void;
+ /**
+ * @brief Enable or disable the VGA text mode cursor.
+ *
+ * @param enabled Whether or not to enable the cursors.
+ */
+ auto cursor(bool enabled) -> void;
- /**
- * @brief Write a string of code points to the VGA text buffer.
- *
- * @note This function also updates the text mode buffer pointer.
- *
- * @param code_points A string of (8-bit) code points to write to the VGA text mode buffer.
- * @param attribute The attribute to apply to the written sequence of code points.
- * @see vga::text::attribute
- */
- auto write(std::string_view code_points, attribute attribute) -> void;
+ auto write(std::string_view text) -> void override { write(text, common_attributes::green_on_black); }
+ auto writeln(std::string_view text) -> void override { writeln(text, common_attributes::green_on_black); }
+ auto write_error(std::string_view text) -> void override { write(text, common_attributes::red_on_black); }
+ auto writeln_error(std::string_view text) -> void override { writeln(text, common_attributes::red_on_black); }
- /**
- * @brief Write a single character to the VGA text buffer.
- *
- * @note This function also updates the text mode buffer pointer.
- *
- * @param code_point A code point to write to the VGA text mode buffer.
- * @param attribute The attribute to apply to the written sequence of code points.
- * @see vga::text::attribute
- */
- auto write_char(char code_point, attribute attribute) -> void;
+ private:
+ /**
+ * @brief Move the cursor to a new line, scrolling the buffer if necessary.
+ */
+ auto newline() -> void;
- template<typename T>
- concept Integral = std::is_integral_v<T>;
+ /**
+ * @brief Write a string of code points to the VGA text buffer.
+ *
+ * @note This function also updates the text mode buffer pointer.
+ *
+ * @param code_points A string of (8-bit) code points to write to the VGA text mode buffer.
+ * @param attribute The attribute to apply to the written sequence of code points.
+ * @see vga::text::attribute
+ */
+ auto write(std::string_view code_points, attribute attribute) -> void;
- /**
- * @brief Write a integral value to the VGA text buffer.
- *
- * @note This function also updates the text mode buffer pointer.
- *
- * @param value A integral value to write to the VGA text mode buffer.
- * @param attribute The attribute to apply to the written sequence of code points.
- * @see vga::text::attribute
- */
- template<Integral T>
- auto write_number(T value, attribute attribute) -> void
- {
- T current_value = value;
- T divisor = 1;
-
- while (current_value > 9)
- {
- divisor *= 10;
- current_value = current_value / 10;
- }
-
- current_value = value;
- while (divisor > 0)
- {
- uint8_t quotient = current_value / divisor;
- char ascii_digit = quotient + '0';
-
- write_char(ascii_digit, attribute);
- current_value %= divisor;
- divisor /= 10;
- }
- }
+ /**
+ * @brief Write a string of code points followed by a newline to the VGA text buffer.
+ *
+ * @note This function also updates the text mode buffer pointer.
+ *
+ * @param code_points A string of (8-bit) code points to write to the VGA text mode buffer.
+ * @param attribute The attribute to apply to the written sequence of code points.
+ * @see vga::text::attribute
+ */
+ auto writeln(std::string_view code_points, attribute attribute) -> void;
+ };
} // namespace teachos::x86_64::vga::text
diff --git a/arch/x86_64/kapi/cio.cpp b/arch/x86_64/kapi/cio.cpp
new file mode 100644
index 0000000..ac3ae39
--- /dev/null
+++ b/arch/x86_64/kapi/cio.cpp
@@ -0,0 +1,16 @@
+#include "kapi/cio.hpp"
+
+#include "x86_64/vga/text.hpp"
+
+namespace teachos::cio
+{
+
+ auto static constinit vga_device = std::optional<x86_64::vga::text::device>{};
+
+ auto init() -> void
+ {
+ vga_device.emplace();
+ set_output_device(*vga_device);
+ }
+
+} // namespace teachos::cio
diff --git a/arch/x86_64/kapi/io.cpp b/arch/x86_64/kapi/io.cpp
deleted file mode 100644
index eab6473..0000000
--- a/arch/x86_64/kapi/io.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "kapi/io.hpp"
-
-#include "x86_64/vga/text.hpp"
-
-namespace teachos::io
-{
-
- auto init() -> void
- {
- x86_64::vga::text::clear();
- x86_64::vga::text::cursor(false);
- }
-
- auto print(std::string_view text) -> void
- {
- x86_64::vga::text::write(text, x86_64::vga::text::common_attributes::green_on_black);
- }
-
- auto println(std::string_view text) -> void
- {
- x86_64::vga::text::write(text, x86_64::vga::text::common_attributes::green_on_black);
- x86_64::vga::text::newline();
- }
-
- auto print_error(std::string_view text) -> void
- {
- x86_64::vga::text::write(text, x86_64::vga::text::common_attributes::red_on_black);
- }
-
- auto println_error(std::string_view text) -> void
- {
- x86_64::vga::text::write(text, x86_64::vga::text::common_attributes::red_on_black);
- x86_64::vga::text::newline();
- }
-
-} // namespace teachos::io
diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp
index 5c94b84..af089fd 100644
--- a/arch/x86_64/src/vga/text.cpp
+++ b/arch/x86_64/src/vga/text.cpp
@@ -13,19 +13,24 @@ namespace teachos::x86_64::vga::text
{
namespace
{
- auto buffer_offset = std::ptrdiff_t{};
+ auto constinit buffer_offset = std::ptrdiff_t{};
auto constexpr DEFAULT_TEXT_BUFFER_WIDTH = 80U;
auto constexpr DEFAULT_TEXT_BUFFER_HEIGHT = 25U;
+
+ auto write_char(char code_point, attribute attribute) -> void
+ {
+ vga_buffer_pointer[buffer_offset++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)};
+ };
} // namespace
- auto clear(attribute attribute) -> void
+ auto device::clear(attribute attribute) -> void
{
buffer_offset = 0;
std::ranges::fill_n(vga_buffer_pointer.get(), 2000, std::pair{' ', std::bit_cast<std::byte>(attribute)});
}
- auto cursor(bool enabled) -> void
+ auto device::cursor(bool enabled) -> void
{
auto cursor_disable_byte = std::byte{!enabled} << 5;
@@ -33,7 +38,7 @@ namespace teachos::x86_64::vga::text
crtc::data::write(crtc::data::read() | cursor_disable_byte);
}
- auto newline() -> void
+ auto device::newline() -> void
{
auto current_line = buffer_offset / DEFAULT_TEXT_BUFFER_WIDTH;
auto next_line = current_line + 1;
@@ -51,13 +56,15 @@ namespace teachos::x86_64::vga::text
}
}
- auto write_char(char code_point, attribute attribute) -> void
+ auto device::write(std::string_view code_points, attribute attribute) -> void
{
- vga_buffer_pointer[buffer_offset++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)};
- };
+ std::ranges::for_each(code_points, [&](auto code_point) { write_char(code_point, attribute); });
+ }
- auto write(std::string_view code_points, attribute attribute) -> void
+ auto device::writeln(std::string_view code_points, attribute attribute) -> void
{
std::ranges::for_each(code_points, [&](auto code_point) { write_char(code_point, attribute); });
+ newline();
}
+
} // namespace teachos::x86_64::vga::text