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.

139 lines
4.9 KiB
C++

/*! \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
/*! \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.
*
* \todo(11) Fill in the bitfield
*/
union Attribute {
struct {
uint8_t todo : 8;
} __attribute__((packed));
uint8_t value; ///< combined value
/*! \brief Attribute constructor (with default values)
*
* \todo(11) Complete constructor
*
* \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) { // NOLINT
(void)foreground;
(void)background;
(void)blink;
}
} __attribute__((packed)); // prevent padding by the compiler
/*! \brief Set the keyboard hardware cursor to absolute screen position
*
* \todo(11) Implement the method using \ref IOPort
*
* \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 = nullptr;
}; // namespace CGA