From 3a47a8bd0edcfa3aa03562d0a5c390ef85ad0c6b Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 14 Jul 2025 21:08:02 +0000 Subject: x86_64: move basic text output implementation --- arch/x86_64/src/vga/text.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 arch/x86_64/src/vga/text.cpp (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp new file mode 100644 index 0000000..9b7946d --- /dev/null +++ b/arch/x86_64/src/vga/text.cpp @@ -0,0 +1,66 @@ +#include "x86_64/vga/text.hpp" + +#include "arch/asm_pointer.hpp" +#include "x86_64/vga/io.hpp" + +#include +#include +#include +#include + +extern "C" teachos::arch::asm_pointer> vga_buffer_pointer; + +namespace teachos::x86_64::vga::text +{ + namespace + { + // auto constexpr DEFAULT_VGA_TEXT_BUFFER_ADDRESS = 0xB8000; + + auto buffer_offset = std::ptrdiff_t{}; + + auto constexpr DEFAULT_TEXT_BUFFER_WIDTH = 80U; + auto constexpr DEFAULT_TEXT_BUFFER_HEIGHT = 25U; + } // namespace + + auto clear(attribute attribute) -> void + { + buffer_offset = 0; + std::ranges::fill_n(vga_buffer_pointer.get(), 2000, std::pair{' ', attribute}); + } + + auto cursor(bool enabled) -> void + { + auto cursor_disable_byte = std::byte{!enabled} << 5; + + io::crtc::address_port::write(io::crtc::registers::cursor_start); + io::crtc::data_port::write(io::crtc::data_port::read() | cursor_disable_byte); + } + + auto newline() -> void + { + auto current_line = buffer_offset / DEFAULT_TEXT_BUFFER_WIDTH; + auto next_line = current_line + 1; + + if (next_line >= DEFAULT_TEXT_BUFFER_HEIGHT) + { + auto begin = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH; + auto end = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT; + std::ranges::move(begin, end, vga_buffer_pointer.get()); + buffer_offset = current_line * DEFAULT_TEXT_BUFFER_WIDTH; + } + else + { + buffer_offset = next_line * DEFAULT_TEXT_BUFFER_WIDTH; + } + } + + auto write_char(char code_point, attribute attribute) -> void + { + vga_buffer_pointer[buffer_offset++] = std::pair{code_point, attribute}; + }; + + auto write(std::string_view code_points, attribute attribute) -> void + { + std::ranges::for_each(code_points, [&](auto code_point) { write_char(code_point, attribute); }); + } +} // namespace teachos::x86_64::vga::text -- cgit v1.2.3 From 05ac8c2bdd000d27b38411db2223eabb649c318f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 14 Jul 2025 21:29:10 +0000 Subject: build: reintroduce bootable ISO --- arch/x86_64/src/vga/text.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 9b7946d..16abf08 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -14,8 +14,6 @@ namespace teachos::x86_64::vga::text { namespace { - // auto constexpr DEFAULT_VGA_TEXT_BUFFER_ADDRESS = 0xB8000; - auto buffer_offset = std::ptrdiff_t{}; auto constexpr DEFAULT_TEXT_BUFFER_WIDTH = 80U; -- cgit v1.2.3 From e97e86d169849527190cef1913efdd247e6f68df Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 23 Jul 2025 13:21:32 +0000 Subject: libs: move asm_ptr to kstd --- arch/x86_64/src/vga/text.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 16abf08..dcfdb6b 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -1,15 +1,14 @@ #include "x86_64/vga/text.hpp" -#include "arch/asm_pointer.hpp" +#include "x86_64/boot/boot.hpp" #include "x86_64/vga/io.hpp" #include +#include #include #include #include -extern "C" teachos::arch::asm_pointer> vga_buffer_pointer; - namespace teachos::x86_64::vga::text { namespace @@ -23,7 +22,7 @@ namespace teachos::x86_64::vga::text auto clear(attribute attribute) -> void { buffer_offset = 0; - std::ranges::fill_n(vga_buffer_pointer.get(), 2000, std::pair{' ', attribute}); + std::ranges::fill_n(vga_buffer_pointer.get(), 2000, std::pair{' ', std::bit_cast(attribute)}); } auto cursor(bool enabled) -> void @@ -54,7 +53,7 @@ namespace teachos::x86_64::vga::text auto write_char(char code_point, attribute attribute) -> void { - vga_buffer_pointer[buffer_offset++] = std::pair{code_point, attribute}; + vga_buffer_pointer[buffer_offset++] = std::pair{code_point, std::bit_cast(attribute)}; }; auto write(std::string_view code_points, attribute attribute) -> void -- cgit v1.2.3 From 3b9bbbb4be529f2365b8bc2e43c1c8e9a65b1a07 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 24 Jul 2025 16:15:31 +0000 Subject: x86_64: clean up vga hierarchy --- arch/x86_64/src/vga/text.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index dcfdb6b..5c94b84 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -1,7 +1,7 @@ #include "x86_64/vga/text.hpp" #include "x86_64/boot/boot.hpp" -#include "x86_64/vga/io.hpp" +#include "x86_64/vga/crtc.hpp" #include #include @@ -29,8 +29,8 @@ namespace teachos::x86_64::vga::text { auto cursor_disable_byte = std::byte{!enabled} << 5; - io::crtc::address_port::write(io::crtc::registers::cursor_start); - io::crtc::data_port::write(io::crtc::data_port::read() | cursor_disable_byte); + crtc::address::write(crtc::registers::cursor_start); + crtc::data::write(crtc::data::read() | cursor_disable_byte); } auto newline() -> void -- cgit v1.2.3 From dd04850c27e8bc273506f4a64bb28b7ddf111dc5 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 24 Jul 2025 20:51:55 +0000 Subject: kapi: rework text device interface --- arch/x86_64/src/vga/text.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') 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(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(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(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 -- cgit v1.2.3 From 6434de8ff75a9143847ef529bc209790ac4909b3 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 29 Oct 2025 11:09:42 +0100 Subject: kapi: move frame and address to KAPI --- arch/x86_64/src/vga/text.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index af089fd..8f78ea9 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -9,8 +9,10 @@ #include #include -namespace teachos::x86_64::vga::text +namespace teachos::vga::x86_64::text { + using boot::x86_64::vga_buffer_pointer; + namespace { auto constinit buffer_offset = std::ptrdiff_t{}; @@ -67,4 +69,4 @@ namespace teachos::x86_64::vga::text newline(); } -} // namespace teachos::x86_64::vga::text +} // namespace teachos::vga::x86_64::text -- cgit v1.2.3 From b157e2c472d8bd67ac1656404a6a6ee821260f4b Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 29 Oct 2025 15:01:43 +0100 Subject: chore: reformat source code --- arch/x86_64/src/vga/text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 8f78ea9..8aa809f 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -17,8 +17,8 @@ namespace teachos::vga::x86_64::text { auto constinit buffer_offset = std::ptrdiff_t{}; - auto constexpr DEFAULT_TEXT_BUFFER_WIDTH = 80U; - auto constexpr DEFAULT_TEXT_BUFFER_HEIGHT = 25U; + constexpr auto DEFAULT_TEXT_BUFFER_WIDTH = 80U; + constexpr auto DEFAULT_TEXT_BUFFER_HEIGHT = 25U; auto write_char(char code_point, attribute attribute) -> void { -- cgit v1.2.3 From 7b9df8bec5038e0316540d2397df632fb14c9169 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 29 Oct 2025 17:01:22 +0100 Subject: chore: configure clang-tidy --- arch/x86_64/src/vga/text.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 8aa809f..0e0d353 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -15,10 +15,12 @@ namespace teachos::vga::x86_64::text namespace { + // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) auto constinit buffer_offset = std::ptrdiff_t{}; constexpr auto DEFAULT_TEXT_BUFFER_WIDTH = 80U; constexpr auto DEFAULT_TEXT_BUFFER_HEIGHT = 25U; + constexpr auto CURSOR_ENABLED_BIT = 5U; auto write_char(char code_point, attribute attribute) -> void { @@ -29,12 +31,13 @@ namespace teachos::vga::x86_64::text auto device::clear(attribute attribute) -> void { buffer_offset = 0; - std::ranges::fill_n(vga_buffer_pointer.get(), 2000, std::pair{' ', std::bit_cast(attribute)}); + std::ranges::fill_n(vga_buffer_pointer.get(), DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT, + std::pair{' ', std::bit_cast(attribute)}); } auto device::cursor(bool enabled) -> void { - auto cursor_disable_byte = std::byte{!enabled} << 5; + 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); -- cgit v1.2.3 From b1143bde71bb029ac2bf7d08ba422fcdaedd56a6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 31 Oct 2025 07:19:16 +0100 Subject: build: enable linting --- arch/x86_64/src/vga/text.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 0e0d353..6ecffa3 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -48,7 +48,7 @@ namespace teachos::vga::x86_64::text auto current_line = buffer_offset / DEFAULT_TEXT_BUFFER_WIDTH; auto next_line = current_line + 1; - if (next_line >= DEFAULT_TEXT_BUFFER_HEIGHT) + if (std::cmp_greater_equal(next_line, DEFAULT_TEXT_BUFFER_HEIGHT)) { auto begin = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH; auto end = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT; @@ -63,12 +63,12 @@ namespace teachos::vga::x86_64::text auto device::write(std::string_view code_points, attribute attribute) -> void { - std::ranges::for_each(code_points, [&](auto code_point) { write_char(code_point, attribute); }); + std::ranges::for_each(code_points, [&](auto code_point) -> void { write_char(code_point, attribute); }); } 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); }); + std::ranges::for_each(code_points, [&](auto code_point) -> void { write_char(code_point, attribute); }); newline(); } -- cgit v1.2.3 From 1a3c20cc9ea191a862eb7e8ac55b3a69ac74ad5e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Nov 2025 16:59:24 +0100 Subject: x86_64/vga: rely less on magic state --- arch/x86_64/src/vga/text.cpp | 50 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 6ecffa3..8b7f01b 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -1,38 +1,41 @@ #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 #include #include +#include #include #include namespace teachos::vga::x86_64::text { - using boot::x86_64::vga_buffer_pointer; - namespace { - // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) - auto constinit buffer_offset = std::ptrdiff_t{}; - + 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; - - auto write_char(char code_point, attribute attribute) -> void - { - vga_buffer_pointer[buffer_offset++] = std::pair{code_point, std::bit_cast(attribute)}; - }; } // namespace + std::span const device::buffer = + std::span{std::bit_cast(BUFFER_BASE_ADDRESS + + std::bit_cast(&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 { - buffer_offset = 0; - std::ranges::fill_n(vga_buffer_pointer.get(), DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT, - std::pair{' ', std::bit_cast(attribute)}); + m_position = 0; + std::ranges::fill(buffer, std::pair{' ', std::bit_cast(attribute)}); } auto device::cursor(bool enabled) -> void @@ -45,30 +48,35 @@ namespace teachos::vga::x86_64::text auto device::newline() -> void { - auto current_line = buffer_offset / DEFAULT_TEXT_BUFFER_WIDTH; + 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 = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH; - auto end = vga_buffer_pointer + DEFAULT_TEXT_BUFFER_WIDTH * DEFAULT_TEXT_BUFFER_HEIGHT; - std::ranges::move(begin, end, vga_buffer_pointer.get()); - buffer_offset = current_line * DEFAULT_TEXT_BUFFER_WIDTH; + 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 { - buffer_offset = next_line * DEFAULT_TEXT_BUFFER_WIDTH; + 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_char(code_point, attribute); }); + 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(attribute)}; + }; + auto device::writeln(std::string_view code_points, attribute attribute) -> void { - std::ranges::for_each(code_points, [&](auto code_point) -> void { write_char(code_point, attribute); }); + std::ranges::for_each(code_points, [&](auto code_point) -> void { write(code_point, attribute); }); newline(); } -- cgit v1.2.3 From 1945dd16716392e70e74efacd19e779f121bd1da Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 15 Dec 2025 16:46:51 +0100 Subject: chore: fix missing includes --- arch/x86_64/src/vga/text.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/x86_64/src/vga/text.cpp') diff --git a/arch/x86_64/src/vga/text.cpp b/arch/x86_64/src/vga/text.cpp index 8b7f01b..c9eee71 100644 --- a/arch/x86_64/src/vga/text.cpp +++ b/arch/x86_64/src/vga/text.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3