You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.2 KiB
C++
55 lines
1.2 KiB
C++
4 weeks ago
|
#include "portio.hpp"
|
||
|
#include "vgaterminal.hpp"
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <cstddef>
|
||
|
#include <cstdint>
|
||
|
#include <utility>
|
||
|
|
||
|
void VGATerminal::write(char c) noexcept
|
||
|
{
|
||
|
switch (c) {
|
||
|
case '\n':
|
||
|
offset += Width;
|
||
|
[[fallthrough]];
|
||
|
case '\r':
|
||
|
offset -= offset % Width;
|
||
|
break;
|
||
|
default:
|
||
|
checkpos();
|
||
|
put(c);
|
||
|
updatecursor();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void VGATerminal::put(char c) noexcept
|
||
|
{
|
||
|
std::uint16_t cell = c
|
||
|
| (std::to_underlying(foreground) << 8)
|
||
|
| (std::to_underlying(background) << 12);
|
||
|
|
||
|
auto ptr = reinterpret_cast<std::uint16_t *>(Videoram);
|
||
|
ptr[offset++] = cell;
|
||
|
}
|
||
|
|
||
|
void VGATerminal::checkpos() noexcept
|
||
|
{
|
||
|
if (offset >= Width * Height) {
|
||
|
auto ptr = reinterpret_cast<std::uint16_t *>(Videoram);
|
||
|
const auto end = ptr + Width * Height;
|
||
|
std::copy(ptr + Width, end, ptr);
|
||
|
std::fill(end - Width, end, 0);
|
||
|
offset = Width * Height - Width;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void VGATerminal::updatecursor() const noexcept
|
||
|
{
|
||
|
outb(0x03d4, 0x0f);
|
||
|
outb(0x03d5, static_cast<std::uint8_t>(offset));
|
||
|
outb(0x03d4, 0x0e);
|
||
|
outb(0x03d5, static_cast<std::uint8_t>(offset >> 8));
|
||
|
}
|
||
|
|