15using namespace MaxOS::common;
16using namespace MaxOS::memory;
17using namespace MaxOS::console;
18using namespace MaxOS::system;
29 s_framebuffer_info = framebuffer_info;
33 Logger::DEBUG() <<
"Framebuffer: bpp=" << m_framebuffer_bpp <<
", pitch=" << m_framebuffer_pitch <<
", size=" << m_framebuffer_size <<
"\n";
45 Logger::DEBUG() <<
"Framebuffer address: physical=0x" << (uint64_t) physical_address <<
", virtual=0x" << (uint64_t) m_framebuffer_address <<
"\n";
46 Logger::DEBUG() <<
"Framebuffer mapped: 0x" << (uint64_t) m_framebuffer_address <<
" - 0x" << (uint64_t) (m_framebuffer_address + m_framebuffer_size) <<
" (pages: " << pages <<
")\n";
54 m_console_area =
new ConsoleArea(
this, 0, 0,
width() / 2 - 25,
height(), ConsoleColour::DarkGrey, ConsoleColour::Black);
64FramebufferConsole::~FramebufferConsole() =
default;
98 ansi_code[ansi_code_length++] = c;
104 if(ansi_code_length < 8) {
107 ansi_code[ansi_code_length++] = c;
111 ansi_code[ansi_code_length] =
'\0';
112 ansi_code_length = -1;
114 if(strcmp(
"\033[0m", ansi_code) == 0) {
115 m_foreground_color = ConsoleColour::Uninitialised;
116 m_background_color = ConsoleColour::Uninitialised;
121 const Colour colour(ansi_code);
124 bool foreground = ansi_code[4] ==
'3';
126 m_foreground_color = colour.to_console_colour();
128 m_background_color = colour.to_console_colour();
141 int offset = (y *
width() + x);
142 m_video_memory_meta[offset] = (m_video_memory_meta[offset] & 0xFF00) | (uint16_t) c;
149 Colour foreground = m_foreground_color == ConsoleColour::Uninitialised ? Colour(
get_foreground_color(x, y)) : Colour(m_foreground_color);
150 Colour background = m_background_color == ConsoleColour::Uninitialised ? Colour(
get_background_color(x, y)) : Colour(m_background_color);
155 for(
int y_bit_map_offset = 0; y_bit_map_offset <
FONT_WIDTH; y_bit_map_offset++) {
159 uint8_t character = c;
162 bool set = AMIGA_FONT[(uint16_t) character * 8 + y_bit_map_offset] & (128 >> (x_bit_map_offset % 8));
163 put_pixel(x * 8 + x_bit_map_offset, y *
FONT_HEIGHT + y_bit_map_offset, set ? fg : bg);
183 int offset = (y *
width() + x);
186 m_video_memory_meta[offset] = (m_video_memory_meta[offset] & 0xF0FF) | ((uint16_t) foreground << 8);
203 int offset = (y *
width() + x);
206 m_video_memory_meta[offset] = (m_video_memory_meta[offset] & 0x0FFF) | ((uint16_t) background << 12);
223 int offset = (y *
width() + x);
226 return (
char) (m_video_memory_meta[offset] & 0x00FF);
239 return ConsoleColour::White;
243 return ConsoleColour::White;
246 int offset = (y *
width() + x);
249 return (ConsoleColour) ((m_video_memory_meta[offset] & 0x0F00) >> 8);
262 return ConsoleColour::Red;
266 return ConsoleColour::Black;
269 int offset = (y *
width() + x);
272 return (ConsoleColour) ((m_video_memory_meta[offset] & 0xF000) >> 12);
283 const char* logo = is_panic ? header_data_kp : header_data;
290 uint32_t center_x = screen_width / 2;
291 uint32_t center_y = screen_height / 2 - 80;
295 memset(address, col, screen_width * screen_height * (bpp / 8));
298 for(uint32_t logo_y = 0; logo_y <
LOGO_HEIGHT; ++logo_y) {
299 for(uint32_t logo_x = 0; logo_x <
LOGO_WIDTH; ++logo_x) {
302 uint8_t pixel[3] = { 0 };
328 common::ConsoleColour foreground,
329 common::ConsoleColour background,
char fill) {
334 uint64_t framebuffer_bpp = m_framebuffer_bpp;
335 uint64_t bytes_per_pixel = framebuffer_bpp / 8;
336 uint64_t framebuffer_pitch = framebuffer_width * bytes_per_pixel;
341 uint16_t region_pixel_y = top * line_height;
342 uint16_t region_pixel_height =
height * line_height;
343 uint16_t region_pixel_left = left *
FONT_WIDTH;
345 size_t row_bytes = region_pixel_width * bytes_per_pixel;
353 for(uint16_t row = 0; row < region_pixel_height - line_height; row++) {
354 uint8_t* src = (uint8_t*)m_framebuffer_address + (region_pixel_y + row + line_height) * framebuffer_pitch + region_pixel_left * bytes_per_pixel;
355 uint8_t* dest = (uint8_t*)m_framebuffer_address + (region_pixel_y + row) * framebuffer_pitch + region_pixel_left * bytes_per_pixel;
356 memmove(dest, src, row_bytes);
360 uint16_t clear_start_y = region_pixel_y + region_pixel_height - line_height;
361 for(uint16_t row = 0; row < line_height; row++) {
362 auto row_add = (uint32_t*) ((uint8_t*)m_framebuffer_address + (clear_start_y + row) * framebuffer_pitch + region_pixel_left * 4);
363 for(uint16_t col = 0; col < region_pixel_width; col++) {
364 row_add[col] = fill_value;
369 uint16_t text_row = top +
height - 1;
370 for(uint16_t x = left; x < left +
width; x++) {
382 Logger::HEADER() <<
"MaxOS Kernel Successfully Booted\n" << ANSI_COLOURS[ANSIColour::Reset];
395 if(!s_framebuffer_info)
402 uint8_t progress_height = 15;
403 uint8_t progress_spacing = 20;
404 uint8_t progress_width_cull = 40;
411 uint32_t start_x = progress_width_cull;
413 uint32_t end_x =
LOGO_WIDTH - progress_width_cull;
414 uint32_t end_y =
LOGO_HEIGHT + progress_height + progress_spacing;
417 for(uint32_t progress_y = start_y; progress_y < end_y; ++progress_y) {
418 for(uint32_t progress_x = start_x; progress_x < end_x; ++progress_x) {
421 bool is_border = (progress_y == start_y) || (progress_y == end_y - 1) ||
422 (progress_x == start_x) || (progress_x == end_x - 1);
425 is_border = is_border && percentage == 0;
428 uint32_t logo_progress_width =
LOGO_WIDTH * percentage / 100;
429 if(progress_x > logo_progress_width && !is_border)
434 put_pixel(right_x + progress_x, bottom_y + progress_y, col);
446void FramebufferConsole::put_pixel(uint32_t x, uint32_t y, uint32_t colour) {
450 *pixel_address = colour;
static Logger * active_logger()
Gets the active logger (to be used to modify the logger)
static LogRecord DEBUG()
Gets the active logger for debug logs.
void disable_log_writer(OutputStream *log_writer)
Prevents an output stream from being used.
static LogRecord HEADER()
Gets the active logger for headers.
void add_log_writer(OutputStream *log_writer)
Adds an output stream to the logger.
static LogRecord INFO()
Gets the active logger for info logs.
static uint32_t colour_to_int(const Colour &colour, uint32_t color_depth)
Converts a colour to an integer value based on the current color depth.
A console that is a subsection of another console, limited by a width and height.
A stream that can be used to write to a console.
void set_cursor(uint16_t x, uint16_t y)
Set the m_position of the cursor.
virtual void scroll_up()
Scroll the entire console up by 1 line.
static void update_progress_bar(uint8_t percentage)
Updates the progress bar.
void set_background_color(uint16_t x, uint16_t y, common::ConsoleColour) final
Sets the background color at the specified location.
void put_character(uint16_t x, uint16_t y, char) final
Places a character at the specified location.
common::ConsoleColour get_foreground_color(uint16_t x, uint16_t y) final
Gets the foreground color at the specified location.
void set_foreground_color(uint16_t x, uint16_t y, common::ConsoleColour) final
Sets the foreground color at the specified location.
uint16_t height() final
Gets the height of the console.
common::ConsoleColour get_background_color(uint16_t x, uint16_t y) final
Gets the background color at the specified location.
void finish() const
Cleans up the boot console.
uint16_t width() final
Gets the width of the console.
FramebufferConsole(multiboot_tag_framebuffer *framebuffer_info)
Constructs a new VESA Boot Console object, initializing the console area for text output.
char get_character(uint16_t x, uint16_t y) final
Gets the character at the specified location.
static void print_logo(bool is_panic=false)
Prints the logo to the center of the screen.
ConsoleStream * cout
The boot console output stream.
static void * kmalloc(size_t size)
Allocates a block of memory in the KERNEL space.
static void * to_dm_region(uintptr_t physical_address)
Converts a physical address to a direct map region address if it is in the lower region using the hig...
void reserve(uint64_t address)
Reserves a physical address.
void map_area(virtual_address_t *virtual_address_start, size_t length, size_t flags)
Allocates a new area physical memory to a area virtual address.
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
static size_t size_to_frames(size_t size)
Converts a size to the number of frames.
static common::Spinlock panic_lock
Lock to prevent multiple panics at once.
Defines the VESABootConsole driver for handling console output during boot using an VESA framebuffer.
constexpr uint8_t FONT_PADDING
How many vertical pixels to add to the top and bottom of the font to prevent squishing.
constexpr uint8_t FONT_HEIGHT
How many pixels tall the font is.
constexpr uint8_t FONT_WIDTH
How many pixels wide the font is.
Defines a Logger class for logging messages with different severity levels to multiple output streams...
#define LOGO_HEADER_PIXEL(data, pixel)
Call this macro repeatedly. After each use, the pixel data can be extracted.
constexpr int LOGO_WIDTH
Width of the logo in pixels.
constexpr int LOGO_HEIGHT
Height of the logo in pixels.
void physical_address_t
A type representing a physical address (used for readability)
@ PRESENT
The page is present in memory.
@ WRITE
Memory in this page is writable.
multiboot_uint32_t framebuffer_width
The width of the framebuffer in pixels.
multiboot_uint8_t framebuffer_bpp
The number of bits per pixel.
multiboot_uint32_t framebuffer_height
The height of the framebuffer in pixels.
multiboot_uint64_t framebuffer_addr
The physical address of the framebuffer.
multiboot_uint32_t framebuffer_pitch
The number of bytes per horizontal line.
A tag containing information about the framebuffer.
struct multiboot_tag_framebuffer_common common
*copydoc multiboot_tag_framebuffer_common