aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-01-13 11:29:09 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-01-13 11:29:09 +0100
commit67f4809a04999be393e5b10e924bcb0f685c721c (patch)
treef29ef9b81660b533be6ea082a8517f317f0c52fd /arch/x86_64/src
parent1cba17bf7b23c5b098af2301e5abce5f5761f061 (diff)
downloadteachos-67f4809a04999be393e5b10e924bcb0f685c721c.tar.xz
teachos-67f4809a04999be393e5b10e924bcb0f685c721c.zip
x86_64/vga: split text implementation
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/vga/text.cpp64
1 files changed, 36 insertions, 28 deletions
diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp
index 1249cc3..1ee69f6 100644
--- a/arch/x86_64/src/vga/text.cpp
+++ b/arch/x86_64/src/vga/text.cpp
@@ -19,30 +19,38 @@ namespace teachos::vga::x86_64::text
{
namespace
{
- constexpr auto BUFFER_BASE_ADDRESS = std::uintptr_t{0xb8000};
- constexpr auto DEFAULT_TEXT_BUFFER_WIDTH = 80z;
- constexpr auto DEFAULT_TEXT_BUFFER_HEIGHT = 25z;
- constexpr auto CURSOR_ENABLED_BIT = 5U;
- } // namespace
+ constexpr auto default_buffer_address = std::uintptr_t{0xb8000};
+ constexpr auto default_buffer_width = 80z;
+ constexpr auto default_buffer_height = 25z;
- 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};
+ constexpr auto bit_cursor_enabled = 5U;
+
+ [[maybe_unused]] constexpr auto black_on_black = attribute{.foreground_color = color::black,
+ .foreground_flag = foreground_flag::none,
+ .background_color = color::black,
+ .background_flag = background_flag::none};
+ } // namespace
device::device()
- : m_position{boot::bootstrap_information.vga_buffer_index}
- {}
+ : m_width{default_buffer_width}
+ , m_height{default_buffer_height}
+ , m_buffer{std::bit_cast<device::cell *>(default_buffer_address +
+ std::bit_cast<std::uintptr_t>(&teachos::boot::x86_64::TEACHOS_VMA)),
+ m_width * m_height}
+ , m_position{boot::bootstrap_information.vga_buffer_index}
+ {
+ clear();
+ }
- auto device::clear(attribute attribute) -> void
+ auto device::clear() -> void
{
m_position = 0;
- std::ranges::fill(buffer, std::pair{' ', std::bit_cast<std::byte>(attribute)});
+ std::ranges::fill(m_buffer, std::pair{' ', std::bit_cast<std::byte>(black_on_black)});
}
auto device::cursor(bool enabled) -> void
{
- auto cursor_disable_byte = std::byte{!enabled} << CURSOR_ENABLED_BIT;
+ auto cursor_disable_byte = std::byte{!enabled} << bit_cursor_enabled;
crtc::address::write(crtc::registers::cursor_start);
crtc::data::write(crtc::data::read() | cursor_disable_byte);
@@ -50,12 +58,12 @@ namespace teachos::vga::x86_64::text
[[nodiscard]] auto device::column() const noexcept -> std::ptrdiff_t
{
- return m_position % DEFAULT_TEXT_BUFFER_WIDTH;
+ return m_position % m_width;
}
[[nodiscard]] auto device::line() const noexcept -> std::ptrdiff_t
{
- return m_position / DEFAULT_TEXT_BUFFER_WIDTH;
+ return m_position / m_width;
}
auto device::handle_special_code_point(char code_point, attribute attribute) -> bool
@@ -83,26 +91,26 @@ namespace teachos::vga::x86_64::text
auto device::put(char code_point, attribute attribute) -> void
{
- buffer[m_position++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)};
+ m_buffer[m_position++] = std::pair{code_point, std::bit_cast<std::byte>(attribute)};
}
auto device::newline() -> void
{
- auto free_glyphs_in_line = DEFAULT_TEXT_BUFFER_WIDTH - column();
+ auto free_glyphs_in_line = m_width - column();
m_position += free_glyphs_in_line;
}
- auto device::scroll(std::ptrdiff_t nof_lines) -> void
+ auto device::scroll(std::size_t nof_lines) -> void
{
- auto scroll_count = std::min(nof_lines, DEFAULT_TEXT_BUFFER_HEIGHT);
+ auto scroll_count = std::min(nof_lines, m_height);
- auto scroll_start = buffer.begin() + (scroll_count * DEFAULT_TEXT_BUFFER_WIDTH);
- std::ranges::move(scroll_start, buffer.end(), buffer.begin());
+ auto scroll_start = m_buffer.begin() + (scroll_count * m_width);
+ std::ranges::move(scroll_start, m_buffer.end(), m_buffer.begin());
- auto clear_start = buffer.begin() + (DEFAULT_TEXT_BUFFER_HEIGHT - scroll_count) * DEFAULT_TEXT_BUFFER_WIDTH;
- std::ranges::fill(clear_start, buffer.end(), glyph{});
+ auto clear_start = m_buffer.begin() + (m_height - scroll_count) * m_width;
+ std::ranges::fill(clear_start, m_buffer.end(), cell{});
- m_position = (line() - scroll_count) * DEFAULT_TEXT_BUFFER_WIDTH;
+ m_position = (line() - scroll_count) * m_width;
}
auto device::write(cio::output_stream stream, std::string_view text) -> void
@@ -111,9 +119,9 @@ namespace teachos::vga::x86_64::text
switch (stream)
{
case cio::output_stream::stderr:
- return common_attributes::red_on_black;
+ return red_on_black;
default:
- return common_attributes::green_on_black;
+ return green_on_black;
}
}();
write(text, attributes);
@@ -126,7 +134,7 @@ namespace teachos::vga::x86_64::text
auto device::write(char code_point, attribute attribute) -> void
{
- if (m_position + 1 > DEFAULT_TEXT_BUFFER_HEIGHT * DEFAULT_TEXT_BUFFER_WIDTH)
+ if (m_position + 1 > static_cast<std::ptrdiff_t>(m_height * m_width))
{
scroll();
}