/*! \file * \brief \ref CGA provides a basic interface to display a character in * VGA-compatible text mode */ #pragma once #include "../types.h" /*! \brief Basic operations in the VGA-compatible text mode * \ingroup io * * This namespace provides an interface to access the screen in text mode * (also known as CGA mode), with access directly on the hardware * level, i.e. the video memory and the I/O ports of the graphics * card. */ namespace CGA { constexpr unsigned ROWS = 25; ///< Visible rows in text mode constexpr unsigned COLUMNS = 80; ///< Visible columns in text mode enum RegisterIndex { CURSOR_START = 10, CURSOR_END = 11, START_ADDRESS_HIGH = 12, START_ADDRESS_LOW = 13, CURSOR_HIGH = 14, CURSOR_LOW = 15 }; /*! \brief CGA color palette * * Colors for the attribute byte. * All 16 colors can be used for the foreground while the background colors * are limited to the first eight (from`BLACK` to `LIGHT_GREY`) */ enum Color { BLACK, ///< Black (fore- and background) BLUE, ///< Blue (fore- and background) GREEN, ///< Green (fore- and background) CYAN, ///< Cyan (fore- and background) RED, ///< Red (fore- and background) MAGENTA, ///< Magenta (fore- and background) BROWN, ///< Brown (fore- and background) LIGHT_GREY, ///< Light grey (fore- and background) DARK_GREY, ///< Dark grey (foreground only) LIGHT_BLUE, ///< Light blue (foreground only) LIGHT_GREEN, ///< Light green (foreground only) LIGHT_CYAN, ///< Light cyan (foreground only) LIGHT_RED, ///< Light red (foreground only) LIGHT_MAGENTA, ///< Light magenta (foreground only) YELLOW, ///< Yellow (foreground only) WHITE ///< White (foreground only) }; /*! \brief Structure of a character attribute * consists of 4 bit fore- and 3 bit background color, and a single blink bit. * * [Bit fields](https://en.cppreference.com/w/cpp/language/bit_field) can * notably simplify the access and code readability. * * \note [Type punning](https://en.wikipedia.org/wiki/Type_punning#Use_of_union) * is indeed undefined behavior in C++. However, *gcc* explicitly allows * this construct as a [language extension](https://gcc.gnu.org/bugs/#nonbugs). * Some compilers ([other than * gcc](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Type%2Dpunning) * might allow this feature only by disabling strict aliasing * (`-fno-strict-aliasing`). In \StuBS we use this feature extensively due to * the improved code readability. * */ union Attribute { struct { uint8_t foreground : 4; uint8_t background : 3; uint8_t blink : 1; } __attribute__((packed)); uint8_t value; ///< combined value /*! \brief Attribute constructor (with default values) * * \param foreground Foreground color (Default: \ref LIGHT_GREY) * \param background Background color (Default: \ref BLACK) * \param blink Blink if `true` (default: no blinking) */ explicit Attribute(Color foreground = LIGHT_GREY, Color background = BLACK, bool blink = false) : foreground(foreground), background(background), blink(blink) {} } __attribute__((packed)); // prevent padding by the compiler /*! \brief Set the keyboard hardware cursor to absolute screen position * * \param abs_x absolute column of the keyboard hardware cursor * \param abs_y absolute row of the keyboard hardware cursor */ void setCursor(unsigned abs_x, unsigned abs_y); /*! \brief Retrieve the keyboard hardware cursor position on screen * * \todo(11) Implement the method using the \ref IOPort * * \param abs_x absolute column of the keyboard hardware cursor * \param abs_y absolute row of the keyboard hardware cursor */ void getCursor(unsigned& abs_x, unsigned& abs_y); /*! \brief Basic output of a character at a specific position on the screen. * * This method outputs the given character at the absolute screen position * (`x`, `y`) with the specified color attribute. * * The position (`0`,`0`) indicates the upper left corner of the screen. * The attribute defines characteristics such as background color, * foreground color and blinking. * * \param abs_x Column (`abs_x` < \ref COLUMNS) in which the character should be * displayed * \param abs_y Row (`abs_y` < \ref ROWS) in which the character should be * displayed * \param character Character to be displayed * \param attrib Attribute with color settings * * \todo(11) Implement the method */ void show(unsigned abs_x, unsigned abs_y, char character, Attribute attrib = Attribute()); /*! \brief Structure for a cell in text mode * * Consisting of two bytes, character and attribute */ struct Cell { char character; Attribute attribute; Cell(char character, Attribute attribute) : character(character), attribute(attribute) {} } __attribute__((packed)); /*! \brief Base address for linear text buffer in video memory */ Cell* const TEXT_BUFFER_BASE = reinterpret_cast(0xb8000); }; // namespace CGA