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++

#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));
}