Serenity Operating System
at master 158 lines 4.5 kB view raw
1/* 2 * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Graphics/Console/VGATextModeConsole.h> 8#include <Kernel/Graphics/GraphicsManagement.h> 9#include <Kernel/Sections.h> 10 11namespace Kernel::Graphics { 12 13UNMAP_AFTER_INIT NonnullLockRefPtr<VGATextModeConsole> VGATextModeConsole::initialize() 14{ 15 auto vga_window_size = MUST(Memory::page_round_up(0xc0000 - 0xa0000)); 16 auto vga_window_region = MUST(MM.allocate_kernel_region(PhysicalAddress(0xa0000), vga_window_size, "VGA Display"sv, Memory::Region::Access::ReadWrite)); 17 return adopt_lock_ref(*new (nothrow) VGATextModeConsole(move(vga_window_region))); 18} 19 20UNMAP_AFTER_INIT VGATextModeConsole::VGATextModeConsole(NonnullOwnPtr<Memory::Region> vga_window_region) 21 : Console(80, 25) 22 , m_vga_window_region(move(vga_window_region)) 23 , m_current_vga_window(m_vga_window_region->vaddr().offset(0x18000).as_ptr()) 24{ 25 for (size_t index = 0; index < height(); index++) { 26 clear_vga_row(index); 27 } 28 dbgln("VGA Text mode console initialized!"); 29} 30 31enum VGAColor : u8 { 32 Black = 0, 33 Blue, 34 Green, 35 Cyan, 36 Red, 37 Magenta, 38 Brown, 39 LightGray, 40 DarkGray, 41 BrightBlue, 42 BrightGreen, 43 BrightCyan, 44 BrightRed, 45 BrightMagenta, 46 Yellow, 47 White, 48}; 49 50[[maybe_unused]] static inline VGAColor convert_standard_color_to_vga_color(Console::Color color) 51{ 52 switch (color) { 53 case Console::Color::Black: 54 return VGAColor::Black; 55 case Console::Color::Red: 56 return VGAColor::Red; 57 case Console::Color::Brown: 58 return VGAColor::Brown; 59 case Console::Color::Blue: 60 return VGAColor::Blue; 61 case Console::Color::Magenta: 62 return VGAColor::Magenta; 63 case Console::Color::Green: 64 return VGAColor::Green; 65 case Console::Color::Cyan: 66 return VGAColor::Cyan; 67 case Console::Color::LightGray: 68 return VGAColor::LightGray; 69 case Console::Color::DarkGray: 70 return VGAColor::DarkGray; 71 case Console::Color::BrightRed: 72 return VGAColor::BrightRed; 73 case Console::Color::BrightGreen: 74 return VGAColor::BrightGreen; 75 case Console::Color::Yellow: 76 return VGAColor::Yellow; 77 case Console::Color::BrightBlue: 78 return VGAColor::BrightBlue; 79 case Console::Color::BrightMagenta: 80 return VGAColor::BrightMagenta; 81 case Console::Color::BrightCyan: 82 return VGAColor::BrightCyan; 83 case Console::Color::White: 84 return VGAColor::White; 85 default: 86 VERIFY_NOT_REACHED(); 87 } 88} 89 90void VGATextModeConsole::set_cursor(size_t x, size_t y) 91{ 92 SpinlockLocker lock(m_vga_lock); 93 GraphicsManagement::the().set_vga_text_mode_cursor(width(), x, y); 94 m_x = x; 95 m_y = y; 96} 97void VGATextModeConsole::hide_cursor() 98{ 99 SpinlockLocker lock(m_vga_lock); 100 GraphicsManagement::the().disable_vga_text_mode_console_cursor(); 101} 102void VGATextModeConsole::show_cursor() 103{ 104 set_cursor(m_x, m_y); 105} 106 107void VGATextModeConsole::clear(size_t x, size_t y, size_t length) 108{ 109 SpinlockLocker lock(m_vga_lock); 110 auto* buf = (u16*)m_current_vga_window.offset((x * 2) + (y * width() * 2)).as_ptr(); 111 for (size_t index = 0; index < length; index++) { 112 buf[index] = 0x0720; 113 } 114} 115void VGATextModeConsole::write(size_t x, size_t y, char ch, bool critical) 116{ 117 write(x, y, ch, m_default_background_color, m_default_foreground_color, critical); 118} 119 120void VGATextModeConsole::write(size_t x, size_t y, char ch, Color background, Color foreground, bool critical) 121{ 122 SpinlockLocker lock(m_vga_lock); 123 // If we are in critical printing mode, we need to handle new lines here 124 // because there's no other responsible object to do that in the print call path 125 if (critical && (ch == '\r' || ch == '\n')) { 126 // Disable hardware VGA cursor 127 GraphicsManagement::the().disable_vga_text_mode_console_cursor(); 128 129 m_x = 0; 130 m_y += 1; 131 if (m_y >= max_row()) 132 m_y = 0; 133 return; 134 } 135 136 auto* buf = (u16*)m_current_vga_window.offset((x * 2) + (y * width() * 2)).as_ptr(); 137 *buf = foreground << 8 | background << 12 | ch; 138 m_x = x + 1; 139 140 if (m_x >= max_column()) { 141 m_x = 0; 142 m_y = y + 1; 143 if (m_y >= max_row()) 144 m_y = 0; 145 } 146} 147 148void VGATextModeConsole::clear_vga_row(u16 row) 149{ 150 clear(0, row, width()); 151} 152 153void VGATextModeConsole::write(char ch, bool critical) 154{ 155 write(m_x, m_y, ch, critical); 156} 157 158}