diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-01-13 11:29:09 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-01-13 11:29:09 +0100 |
| commit | 67f4809a04999be393e5b10e924bcb0f685c721c (patch) | |
| tree | f29ef9b81660b533be6ea082a8517f317f0c52fd /arch/x86_64/src | |
| parent | 1cba17bf7b23c5b098af2301e5abce5f5761f061 (diff) | |
| download | teachos-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.cpp | 64 |
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(); } |
