aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/vga
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-15 17:13:12 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-15 17:13:12 +0100
commit7b9482ae637126ac9337876e60f519b493437711 (patch)
tree6fc71a253c8b0325d303bd34c95b564ba536ed14 /arch/x86_64/src/vga
parent116f9332a206767c45095950f09f7c7447b561cf (diff)
parenta9eeec745e29d89afd48ee43d09432eb6fc35be7 (diff)
downloadteachos-7b9482ae637126ac9337876e60f519b493437711.tar.xz
teachos-7b9482ae637126ac9337876e60f519b493437711.zip
os: rework kernel architecture
Rework the code structure and architecture of the kernel by separating platform-dependent and platform-independent code more cleanly. As of this patchset, full feature parity has not been achieved. Nonetheless, a sufficient subset of functionality has been ported to the new architecture to demonstrate the feasibility of the new structure.
Diffstat (limited to 'arch/x86_64/src/vga')
-rw-r--r--arch/x86_64/src/vga/text.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp
new file mode 100644
index 0000000..c9eee71
--- /dev/null
+++ b/arch/x86_64/src/vga/text.cpp
@@ -0,0 +1,84 @@
+#include "x86_64/vga/text.hpp"
+
+#include "kapi/boot.hpp"
+
+#include "x86_64/boot/boot.hpp"
+#include "x86_64/boot/ld.hpp"
+#include "x86_64/vga/crtc.hpp"
+
+#include <algorithm>
+#include <bit>
+#include <cstddef>
+#include <cstdint>
+#include <span>
+#include <string_view>
+#include <utility>
+
+namespace teachos::vga::x86_64::text
+{
+ namespace
+ {
+ constexpr auto BUFFER_BASE_ADDRESS = std::uintptr_t{0xb8000};
+ constexpr auto DEFAULT_TEXT_BUFFER_WIDTH = 80U;
+ constexpr auto DEFAULT_TEXT_BUFFER_HEIGHT = 25U;
+ constexpr auto CURSOR_ENABLED_BIT = 5U;
+ } // namespace
+
+ std::span<device::glyph> const device::buffer =
+ std::span{std::bit_cast<device::glyph *>(BUFFER_BASE_ADDRESS +
+ std::bit_cast<std::uintptr_t>(&teachos::boot::x86_64::TEACHOS_VMA)),
+ DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT};
+
+ device::device()
+ : m_position{boot::bootstrap_information.vga_buffer_index}
+ {}
+
+ auto device::clear(attribute attribute) -> void
+ {
+ m_position = 0;
+ std::ranges::fill(buffer, std::pair{' ', std::bit_cast<std::byte>(attribute)});
+ }
+
+ auto device::cursor(bool enabled) -> void
+ {
+ auto cursor_disable_byte = std::byte{!enabled} << CURSOR_ENABLED_BIT;
+
+ crtc::address::write(crtc::registers::cursor_start);
+ crtc::data::write(crtc::data::read() | cursor_disable_byte);
+ }
+
+ auto device::newline() -> void
+ {
+ auto current_line = m_position / DEFAULT_TEXT_BUFFER_WIDTH;
+ auto next_line = current_line + 1;
+
+ if (std::cmp_greater_equal(next_line, DEFAULT_TEXT_BUFFER_HEIGHT))
+ {
+ auto begin = buffer.begin() + DEFAULT_TEXT_BUFFER_WIDTH;
+ auto end = buffer.begin() + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT;
+ std::ranges::move(begin, end, buffer.begin());
+ m_position = current_line * DEFAULT_TEXT_BUFFER_WIDTH;
+ }
+ else
+ {
+ m_position = next_line * DEFAULT_TEXT_BUFFER_WIDTH;
+ }
+ }
+
+ auto device::write(std::string_view code_points, attribute attribute) -> void
+ {
+ std::ranges::for_each(code_points, [&](auto code_point) -> void { write(code_point, attribute); });
+ }
+
+ auto device::write(char code_point, attribute attribute) -> void
+ {
+ buffer[m_position++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)};
+ };
+
+ auto device::writeln(std::string_view code_points, attribute attribute) -> void
+ {
+ std::ranges::for_each(code_points, [&](auto code_point) -> void { write(code_point, attribute); });
+ newline();
+ }
+
+} // namespace teachos::vga::x86_64::text