From cfd4b8d6a5de930cfd3cf21cea9cedede68c0af5 Mon Sep 17 00:00:00 2001 From: EnderIce2 Date: Sat, 10 Feb 2024 06:56:26 +0200 Subject: [PATCH] Update display buffer handling --- core/crash/crash_handler.cpp | 211 ++++++++--------- core/crash/kb_drv.cpp | 6 +- core/video/display.cpp | 426 ++++++++++++++--------------------- include/display.hpp | 122 ++++++---- kernel.cpp | 21 +- kshell/cmds.hpp | 1 + kshell/commands/clear.cpp | 4 +- kshell/commands/panic.cpp | 29 +++ kshell/commands/tree.cpp | 2 +- kshell/shell.cpp | 59 ++--- storage/devices/tty/kcon.cpp | 2 +- storage/devices/tty/tty.cpp | 11 +- tests/lsof.cpp | 15 +- tests/taskmgr.cpp | 15 +- tests/treefs.cpp | 2 +- 15 files changed, 431 insertions(+), 495 deletions(-) create mode 100644 kshell/commands/panic.cpp diff --git a/core/crash/crash_handler.cpp b/core/crash/crash_handler.cpp index 65302f9..0f49f28 100644 --- a/core/crash/crash_handler.cpp +++ b/core/crash/crash_handler.cpp @@ -53,7 +53,7 @@ namespace CrashHandler nsa void printfWrapper(char c, void *unused) { - Display->Print(c, SBIdx, true); + Display->Print(c, nullptr, true); UNUSED(unused); } @@ -68,7 +68,7 @@ namespace CrashHandler nsa void EHDumpData(void *Address, unsigned long Length) { EHPrint("-------------------------------------------------------------------------\n"); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); unsigned char *AddressChar = (unsigned char *)Address; unsigned char Buffer[17]; unsigned long Iterate; @@ -79,7 +79,7 @@ namespace CrashHandler if (Iterate != 0) EHPrint(" \e8A78FF%s\eAABBCC\n", Buffer); EHPrint(" \e9E9E9E%04x\eAABBCC ", Iterate); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } EHPrint(" \e4287f5%02x\eAABBCC", AddressChar[Iterate]); if ((AddressChar[Iterate] < 0x20) || (AddressChar[Iterate] > 0x7e)) @@ -92,13 +92,13 @@ namespace CrashHandler while ((Iterate % 16) != 0) { EHPrint(" "); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); Iterate++; } EHPrint(" \e8A78FF%s\eAABBCC\n", Buffer); EHPrint("-------------------------------------------------------------------------\n\n."); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } nsa char *TrimWhiteSpace(char *str) @@ -119,11 +119,10 @@ namespace CrashHandler nsa void DisplayTopOverlay() { - Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); Video::Font *f = Display->GetCurrentFont(); Video::FontInfo fi = f->GetInfo(); - // for (uint32_t i = 0; i < sb->Width; i++) + // for (uint32_t i = 0; i < Display->GetWidth; i++) // { // for (uint32_t j = 0; j < fi.Height + 8; j++) // { @@ -132,19 +131,19 @@ namespace CrashHandler // } // } - for (uint32_t i = 0; i < sb->Width; i++) + for (uint32_t i = 0; i < Display->GetWidth; i++) { for (uint32_t j = 0; j < fi.Height + 8; j++) { uint32_t grayValue = 0x505050 - (j * 0x020202); - Display->SetPixel(i, j, grayValue, SBIdx); + Display->SetPixel(i, j, grayValue); } } - for (uint32_t i = 0; i < sb->Width; i++) - Display->SetPixel(i, fi.Height + 8, 0x404040, SBIdx); + for (uint32_t i = 0; i < Display->GetWidth; i++) + Display->SetPixel(i, fi.Height + 8, 0x404040); - Display->SetBufferCursor(SBIdx, 8, (fi.Height + 8) / 6); + Display->SetBufferCursor(8, (fi.Height + 8) / 6); switch (SBIdx) { case 255: @@ -185,84 +184,83 @@ namespace CrashHandler EHPrint(" \eAA0F0F%s", CPU::Hypervisor()); EHPrint(" \eAAF00F%s", CPU::Vendor()); EHPrint(" \eAA00FF%s", CPU::Name()); - Display->SetBufferCursor(SBIdx, 0, fi.Height + 10); + Display->SetBufferCursor(0, fi.Height + 10); /* https://imgflip.com/i/77slbl */ if ((Random::rand32() % 100) >= 98) { debug("Easter egg activated!"); - int BaseXOffset = sb->Width - 14; + int BaseXOffset = Display->GetWidth - 14; int BaseYOffset = 8; - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 0, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 0, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 0, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 7, BaseYOffset + 0, 0x21852E, SBIdx); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 0, 0x21852E); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 0, 0x21852E); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 0, 0x21852E); + Display->SetPixel(BaseXOffset + 7, BaseYOffset + 0, 0x21852E); - Display->SetPixel(BaseXOffset + 2, BaseYOffset + 1, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 1, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 1, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 5, BaseYOffset + 1, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 1, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 7, BaseYOffset + 1, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 8, BaseYOffset + 1, 0x21852E, SBIdx); + Display->SetPixel(BaseXOffset + 2, BaseYOffset + 1, 0x21852E); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 1, 0x21852E); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 1, 0x21852E); + Display->SetPixel(BaseXOffset + 5, BaseYOffset + 1, 0x21852E); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 1, 0x21852E); + Display->SetPixel(BaseXOffset + 7, BaseYOffset + 1, 0x21852E); + Display->SetPixel(BaseXOffset + 8, BaseYOffset + 1, 0x21852E); - Display->SetPixel(BaseXOffset + 1, BaseYOffset + 2, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 2, BaseYOffset + 2, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 2, 0xFFFFFF, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 2, 0x000000, SBIdx); - Display->SetPixel(BaseXOffset + 5, BaseYOffset + 2, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 2, 0xFFFFFF, SBIdx); - Display->SetPixel(BaseXOffset + 7, BaseYOffset + 2, 0x000000, SBIdx); - Display->SetPixel(BaseXOffset + 8, BaseYOffset + 2, 0x21852E, SBIdx); + Display->SetPixel(BaseXOffset + 1, BaseYOffset + 2, 0x21852E); + Display->SetPixel(BaseXOffset + 2, BaseYOffset + 2, 0x21852E); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 2, 0xFFFFFF); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 2, 0x000000); + Display->SetPixel(BaseXOffset + 5, BaseYOffset + 2, 0x21852E); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 2, 0xFFFFFF); + Display->SetPixel(BaseXOffset + 7, BaseYOffset + 2, 0x000000); + Display->SetPixel(BaseXOffset + 8, BaseYOffset + 2, 0x21852E); - Display->SetPixel(BaseXOffset + 1, BaseYOffset + 3, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 2, BaseYOffset + 3, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 3, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 3, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 5, BaseYOffset + 3, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 3, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 7, BaseYOffset + 3, 0x21852E, SBIdx); + Display->SetPixel(BaseXOffset + 1, BaseYOffset + 3, 0x21852E); + Display->SetPixel(BaseXOffset + 2, BaseYOffset + 3, 0x21852E); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 3, 0x21852E); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 3, 0x21852E); + Display->SetPixel(BaseXOffset + 5, BaseYOffset + 3, 0x21852E); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 3, 0x21852E); + Display->SetPixel(BaseXOffset + 7, BaseYOffset + 3, 0x21852E); - Display->SetPixel(BaseXOffset + 0, BaseYOffset + 4, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 1, BaseYOffset + 4, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 2, BaseYOffset + 4, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 4, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 4, 0xA84832, SBIdx); - Display->SetPixel(BaseXOffset + 5, BaseYOffset + 4, 0xA84832, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 4, 0xA84832, SBIdx); - Display->SetPixel(BaseXOffset + 7, BaseYOffset + 4, 0xA84832, SBIdx); + Display->SetPixel(BaseXOffset + 0, BaseYOffset + 4, 0x21852E); + Display->SetPixel(BaseXOffset + 1, BaseYOffset + 4, 0x21852E); + Display->SetPixel(BaseXOffset + 2, BaseYOffset + 4, 0x21852E); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 4, 0x21852E); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 4, 0xA84832); + Display->SetPixel(BaseXOffset + 5, BaseYOffset + 4, 0xA84832); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 4, 0xA84832); + Display->SetPixel(BaseXOffset + 7, BaseYOffset + 4, 0xA84832); - Display->SetPixel(BaseXOffset + 0, BaseYOffset + 5, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 1, BaseYOffset + 5, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 2, BaseYOffset + 5, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 5, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 5, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 5, BaseYOffset + 5, 0x21852E, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 5, 0x21852E, SBIdx); + Display->SetPixel(BaseXOffset + 0, BaseYOffset + 5, 0x21852E); + Display->SetPixel(BaseXOffset + 1, BaseYOffset + 5, 0x21852E); + Display->SetPixel(BaseXOffset + 2, BaseYOffset + 5, 0x21852E); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 5, 0x21852E); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 5, 0x21852E); + Display->SetPixel(BaseXOffset + 5, BaseYOffset + 5, 0x21852E); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 5, 0x21852E); - Display->SetPixel(BaseXOffset + 0, BaseYOffset + 6, 0x1216FF, SBIdx); - Display->SetPixel(BaseXOffset + 1, BaseYOffset + 6, 0x1216FF, SBIdx); - Display->SetPixel(BaseXOffset + 2, BaseYOffset + 6, 0x1216FF, SBIdx); - Display->SetPixel(BaseXOffset + 3, BaseYOffset + 6, 0x1216FF, SBIdx); - Display->SetPixel(BaseXOffset + 4, BaseYOffset + 6, 0x1216FF, SBIdx); - Display->SetPixel(BaseXOffset + 5, BaseYOffset + 6, 0x1216FF, SBIdx); - Display->SetPixel(BaseXOffset + 6, BaseYOffset + 6, 0x1216FF, SBIdx); + Display->SetPixel(BaseXOffset + 0, BaseYOffset + 6, 0x1216FF); + Display->SetPixel(BaseXOffset + 1, BaseYOffset + 6, 0x1216FF); + Display->SetPixel(BaseXOffset + 2, BaseYOffset + 6, 0x1216FF); + Display->SetPixel(BaseXOffset + 3, BaseYOffset + 6, 0x1216FF); + Display->SetPixel(BaseXOffset + 4, BaseYOffset + 6, 0x1216FF); + Display->SetPixel(BaseXOffset + 5, BaseYOffset + 6, 0x1216FF); + Display->SetPixel(BaseXOffset + 6, BaseYOffset + 6, 0x1216FF); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } } nsa void DisplayBottomOverlay() { - Video::ScreenBuffer *sb = Display->GetBuffer(SBIdx); Video::Font *f = Display->GetCurrentFont(); Video::FontInfo fi = f->GetInfo(); - for (uint32_t i = 0; i < sb->Width; i++) - for (uint32_t j = sb->Height - fi.Height - 8; j < sb->Height; j++) - Display->SetPixel(i, j, 0x282828, SBIdx); + for (uint32_t i = 0; i < Display->GetWidth; i++) + for (uint32_t j = Display->GetHeight - fi.Height - 8; j < Display->GetHeight; j++) + Display->SetPixel(i, j, 0x282828); - Display->SetBufferCursor(SBIdx, 8, sb->Height - fi.Height - 4); + Display->SetBufferCursor(8, Display->GetHeight - fi.Height - 4); EHPrint("\eAAAAAA> \eFAFAFA"); } @@ -297,7 +295,7 @@ namespace CrashHandler default: break; } - Display->ClearBuffer(SBIdx); + Display->ClearBuffer(); DisplayTopOverlay(); EHPrint("\eFAFAFA"); @@ -334,13 +332,13 @@ namespace CrashHandler } } DisplayBottomOverlay(); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } nsa void UserInput(char *Input) { SmartCriticalSection(UserInputLock); - Display->ClearBuffer(SBIdx); + Display->ClearBuffer(); DisplayTopOverlay(); EHPrint("\eFAFAFA"); @@ -374,14 +372,14 @@ namespace CrashHandler { PowerManager->Shutdown(); EHPrint("\eFFFFFFNow it's safe to turn off your computer."); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); CPU::Stop(); } else if (strcmp(Input, "reboot") == 0) { PowerManager->Reboot(); EHPrint("\eFFFFFFNow it's safe to reboot your computer."); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); CPU::Stop(); } else if (strncmp(Input, "showbuf", 7) == 0 || strncmp(Input, "sb", 2) == 0) @@ -389,13 +387,13 @@ namespace CrashHandler char *arg = TrimWhiteSpace(Input + 7); int tmpidx = SBIdx; SBIdx = atoi(arg); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); #if defined(a86) for (int i = 0; i < 5000000; i++) inb(0x80); #endif // a64 || a32 SBIdx = tmpidx; - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strncmp(Input, "ifr", 3) == 0) { @@ -408,7 +406,7 @@ namespace CrashHandler if (CountI > TotalCount) { EHPrint("\eFF4400Count too big! Maximum allowed is %ld\eFAFAFA\n", TotalCount); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else { @@ -434,7 +432,7 @@ namespace CrashHandler for (int i = 0; i < 20000; i++) inb(0x80); #endif // a64 || a32 - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } } } @@ -466,7 +464,7 @@ namespace CrashHandler PML4.Accessed ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PML4.ExecuteDisable ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PML4.GetAddress() << 12); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); if (!PML4.Present) continue; @@ -486,7 +484,7 @@ namespace CrashHandler PDPTE->Entries[PDPTEIndex].Accessed ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PDPTE->Entries[PDPTEIndex].ExecuteDisable ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PDPTE->Entries[PDPTEIndex].GetAddress() << 12); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); if (!PDPTE->Entries[PDPTEIndex].Present) continue; @@ -506,7 +504,7 @@ namespace CrashHandler PDE->Entries[PDEIndex].Accessed ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PDE->Entries[PDEIndex].ExecuteDisable ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PDE->Entries[PDEIndex].GetAddress() << 12); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); if (!PDE->Entries[PDEIndex].Present) continue; @@ -530,7 +528,7 @@ namespace CrashHandler PTE->Entries[PTEIndex].ProtectionKey, PTE->Entries[PTEIndex].ExecuteDisable ? "\e00FF001\e4500F5" : "\eFF00000\e4500F5", PTE->Entries[PTEIndex].GetAddress() << 12); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } } } @@ -552,11 +550,11 @@ namespace CrashHandler { short Percentage = s_cst(short, (i * 100) / bm.Size); EHPrint("\n\eFAFAFA[%03ld%%] %08ld: ", Percentage, i); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } } EHPrint("\n\e22AA44--- END OF BITMAP ---\nBitmap size: %ld\n\n.", bm.Size); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strcmp(Input, "mem") == 0) { @@ -577,7 +575,7 @@ namespace CrashHandler EHPrint("\eFF00FF|"); EHPrint("\eCCCCCC]\n"); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strncmp(Input, "cr", 2) == 0) { @@ -693,7 +691,7 @@ namespace CrashHandler if (!vmm.Check((void *)adr)) { EHPrint("\eFFA500Address %#lx is not mapped\n", adr); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); ActualLength -= PAGE_SIZE; } } @@ -740,7 +738,7 @@ namespace CrashHandler break; } EHPrint("\eF8F8F8Dumping memory to UART port %c (%#lx) and %s inaccessible pages.\n", cPort[0], port, cBoolSkip[0] == '1' ? "skipping" : "zeroing"); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); uint64_t TotalMemLength = KernelAllocator.GetTotalMemory(); uint64_t ProgressLength = TotalMemLength; UniversalAsynchronousReceiverTransmitter::UART uart(port); @@ -764,11 +762,11 @@ namespace CrashHandler { Progress = NewProgress; EHPrint("\n%d%%\n", Progress); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } - Display->Print('.', SBIdx); + Display->Print('.'); if (unlikely(i % 0x500 == 0)) - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } } EHPrint("\nDone.\n"); @@ -778,42 +776,42 @@ namespace CrashHandler SBIdx = 255; DisplayTopOverlay(); DisplayMainScreen(crashdata); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strcmp(Input, "details") == 0) { SBIdx = 254; DisplayTopOverlay(); DisplayDetailsScreen(crashdata); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strcmp(Input, "frames") == 0) { SBIdx = 253; DisplayTopOverlay(); DisplayStackFrameScreen(crashdata); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strcmp(Input, "tasks") == 0) { SBIdx = 252; DisplayTopOverlay(); DisplayTasksScreen(crashdata); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strcmp(Input, "console") == 0) { SBIdx = 251; DisplayTopOverlay(); DisplayConsoleScreen(crashdata); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } else if (strlen(Input) > 0) EHPrint("Unknown command: %s", Input); DrawBottom: DisplayBottomOverlay(); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); } nsa void StopAllCores() @@ -907,7 +905,6 @@ namespace CrashHandler if (TaskManager) TaskManager->Panic(); ForceUnlock = true; - Display->CreateBuffer(0, 0, SBIdx); StopAllCores(); } else @@ -943,7 +940,6 @@ namespace CrashHandler if (TaskManager) TaskManager->Panic(); ForceUnlock = true; - Display->CreateBuffer(0, 0, SBIdx); StopAllCores(); return false; } @@ -1008,7 +1004,6 @@ namespace CrashHandler if (TaskManager) TaskManager->Panic(); ForceUnlock = true; - Display->CreateBuffer(0, 0, SBIdx); StopAllCores(); } else @@ -1042,7 +1037,6 @@ namespace CrashHandler if (TaskManager) TaskManager->Panic(); ForceUnlock = true; - Display->CreateBuffer(0, 0, SBIdx); StopAllCores(); return false; } @@ -1214,15 +1208,15 @@ namespace CrashHandler if (ExceptionOccurred) { SBIdx = 255; - Display->ClearBuffer(SBIdx); - Display->SetBufferCursor(SBIdx, 0, 0); + Display->ClearBuffer(); + Display->SetBufferCursor(0, 0); #if defined(a64) Print_x86_64(Frame); #elif defined(a32) Print_x86_32(Frame); #endif EHPrint("\nException occurred while handling exception! HALTED!"); - Display->SetBuffer(SBIdx); + Display->UpdateBuffer(); Interrupts::RemoveAll(); CPU::Stop(); } @@ -1436,27 +1430,20 @@ namespace CrashHandler if (Config.InterruptsOnCrash) { - // 255 // Main - Display->CreateBuffer(0, 0, 254); // Details - Display->CreateBuffer(0, 0, 253); // Frames - Display->CreateBuffer(0, 0, 252); // Tasks - Display->CreateBuffer(0, 0, 251); // Console - Display->CreateBuffer(0, 0, 250); // Empty - DisplayTopOverlay(); DisplayMainScreen(crashdata); - Display->SetBuffer(255); + Display->UpdateBuffer(); Interrupts::RemoveAll(); kbd = new CrashKeyboardDriver; DisplayBottomOverlay(); - Display->SetBuffer(255); + Display->UpdateBuffer(); } else { /* TODO: Stuff that should be done when IOC is disabled. */ - Display->SetBuffer(255); + Display->UpdateBuffer(); } CPU::Halt(true); diff --git a/core/crash/kb_drv.cpp b/core/crash/kb_drv.cpp index 8b50035..8431b63 100644 --- a/core/crash/kb_drv.cpp +++ b/core/crash/kb_drv.cpp @@ -267,7 +267,7 @@ namespace CrashHandler { if (BackSpaceLimit > 0) { - Display->Print('\b', SBIdx); + Display->Print('\b'); backspace(UserInputBuffer); BackSpaceLimit--; } @@ -281,10 +281,10 @@ namespace CrashHandler else { append(UserInputBuffer, s_cst(char, key)); - Display->Print((char)key, SBIdx); + Display->Print((char)key); BackSpaceLimit++; } - Display->SetBuffer(SBIdx); /* Update as we type. */ + Display->UpdateBuffer(); /* Update as we type. */ } #endif // a64 || a32 } diff --git a/core/video/display.cpp b/core/video/display.cpp index 1b4f220..60aa692 100644 --- a/core/video/display.cpp +++ b/core/video/display.cpp @@ -85,179 +85,28 @@ namespace Video uint16_t Display::GetBitsPerPixel() { return this->framebuffer.BitsPerPixel; } size_t Display::GetPitch() { return this->framebuffer.Pitch; } - void Display::CreateBuffer(uint32_t Width, uint32_t Height, int Index) + void Display::ClearBuffer() { - if (Width == 0 || Height == 0) - { - Width = this->framebuffer.Width; - Height = this->framebuffer.Height; - debug("Buffer %d created with default size (%d, %d)", Index, Width, Height); - } - - if (this->Buffers[Index].Checksum == 0xBBFFE515A117E) - { - warn("Buffer %d already exists, skipping creation", Index); - return; - } - - size_t Size = this->framebuffer.Pitch * Height; - - this->Buffers[Index].Buffer = KernelAllocator.RequestPages(TO_PAGES(Size + 1)); - memset(this->Buffers[Index].Buffer, 0, Size); - - this->Buffers[Index].Width = Width; - this->Buffers[Index].Height = Height; - this->Buffers[Index].Size = Size; - this->Buffers[Index].Color = 0xFFFFFF; - this->Buffers[Index].CursorX = 0; - this->Buffers[Index].CursorY = 0; - this->Buffers[Index].Brightness = 100; - this->Buffers[Index].Checksum = 0xBBFFE515A117E; - debug("Buffer %d created", Index); + memset(this->Buffer, 0, this->Size); + // std::fill(this->DirtyMap.begin(), this->DirtyMap.end(), true); } - void Display::SetBuffer(int Index) + __no_sanitize("undefined") void Display::SetPixel(uint32_t X, uint32_t Y, uint32_t Color) { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } + if (unlikely(X >= this->Width)) + X = this->Width - 1; - if (this->Buffers[Index].Brightness != 100) - this->SetBrightness(this->Buffers[Index].Brightness, Index); + if (unlikely(Y >= this->Height)) + Y = this->Height - 1; - if (this->Buffers[Index].Brightness == 0) /* Just clear the buffer */ - memset(this->Buffers[Index].Buffer, 0, this->Buffers[Index].Size); - - memcpy(this->framebuffer.BaseAddress, this->Buffers[Index].Buffer, this->Buffers[Index].Size); - } - - ScreenBuffer *Display::GetBuffer(int Index) { return &this->Buffers[Index]; } - - void Display::ClearBuffer(int Index) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - memset(this->Buffers[Index].Buffer, 0, this->Buffers[Index].Size); - } - - void Display::DeleteBuffer(int Index) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - KernelAllocator.FreePages(this->Buffers[Index].Buffer, TO_PAGES(this->Buffers[Index].Size + 1)); - this->Buffers[Index].Buffer = nullptr; - this->Buffers[Index].Checksum = 0; - debug("Buffer %d deleted", Index); - } - - void Display::SetBrightness(int Value, int Index) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - if (Value > 100) - Value = 100; - else if (Value < 0) - Value = 0; - - uint32_t *pixel = (uint32_t *)this->Buffers[Index].Buffer; - - for (uint32_t y = 0; y < this->Buffers[Index].Height; y++) - { - for (uint32_t x = 0; x < this->Buffers[Index].Width; x++) - { - uint32_t color = pixel[y * this->Buffers[Index].Width + x]; - - uint8_t r = color & 0xff; - uint8_t g = (color >> 8) & 0xff; - uint8_t b = (color >> 16) & 0xff; - - r = s_cst(uint8_t, (r * Value) / 100); - g = s_cst(uint8_t, (g * Value) / 100); - b = s_cst(uint8_t, (b * Value) / 100); - - pixel[y * this->Buffers[Index].Width + x] = (b << 16) | (g << 8) | r; - } - } - this->Buffers[Index].Brightness = s_cst(char, Value); - } - - void Display::SetBufferCursor(int Index, uint32_t X, uint32_t Y) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - this->Buffers[Index].CursorX = X; - this->Buffers[Index].CursorY = Y; - } - - void Display::GetBufferCursor(int Index, uint32_t *X, uint32_t *Y) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - *X = this->Buffers[Index].CursorX; - *Y = this->Buffers[Index].CursorY; - } - - __no_sanitize("undefined") void Display::SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - if (unlikely(X >= this->Buffers[Index].Width)) - X = this->Buffers[Index].Width - 1; - - if (unlikely(Y >= this->Buffers[Index].Height)) - Y = this->Buffers[Index].Height - 1; - - uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index].Buffer + (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)); + uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffer + (Y * this->Width + X) * (this->framebuffer.BitsPerPixel / 8)); *Pixel = Color; + // MarkRegionDirty(Y / RegionHeight, X / RegionWidth); } - uint32_t Display::GetPixel(uint32_t X, uint32_t Y, int Index) + void Display::Scroll(int Lines) { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - return 0; - - if (unlikely(X >= this->Buffers[Index].Width || Y >= this->Buffers[Index].Height)) - return 0; - - uint32_t *Pixel = (uint32_t *)((uintptr_t)this->Buffers[Index].Buffer + (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)); - return *Pixel; - } - - void Display::Scroll(int Index, int Lines) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - if (this->Buffers[Index].DoNotScroll) + if (this->DoNotScroll) return; if (Lines == 0) @@ -265,43 +114,31 @@ namespace Video if (Lines > 0) { - uint32_t LineSize = this->Buffers[Index].Width * (this->framebuffer.BitsPerPixel / 8); + uint32_t LineSize = this->Width * (this->framebuffer.BitsPerPixel / 8); uint32_t BytesToMove = LineSize * Lines * this->CurrentFont->GetInfo().Height; - size_t BytesToClear = this->Buffers[Index].Size - BytesToMove; - memmove(this->Buffers[Index].Buffer, (uint8_t *)this->Buffers[Index].Buffer + BytesToMove, BytesToClear); - memset((uint8_t *)this->Buffers[Index].Buffer + BytesToClear, 0, BytesToMove); + size_t BytesToClear = this->Size - BytesToMove; + memmove(this->Buffer, (uint8_t *)this->Buffer + BytesToMove, BytesToClear); + memset((uint8_t *)this->Buffer + BytesToClear, 0, BytesToMove); + + // memset(this->DirtyMap.data(), true, this->DirtyMap.size()); } } - void Display::SetDoNotScroll(bool Value, int Index) + __no_sanitize("undefined") char Display::Print(char Char, Video::Font *_Font, bool WriteToUART) { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - { - debug("Invalid buffer %d", Index); - return; - } - - this->Buffers[Index].DoNotScroll = Value; - } - - __no_sanitize("undefined") char Display::Print(char Char, int Index, bool WriteToUART) - { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) - return 0; - // SmartLock(PrintLock); if (this->ColorIteration) { // RRGGBB if (Char >= '0' && Char <= '9') - this->Buffers[Index].Color = (this->Buffers[Index].Color << 4) | (Char - '0'); + this->Color = (this->Color << 4) | (Char - '0'); else if (Char >= 'a' && Char <= 'f') - this->Buffers[Index].Color = (this->Buffers[Index].Color << 4) | (Char - 'a' + 10); + this->Color = (this->Color << 4) | (Char - 'a' + 10); else if (Char >= 'A' && Char <= 'F') - this->Buffers[Index].Color = (this->Buffers[Index].Color << 4) | (Char - 'A' + 10); + this->Color = (this->Color << 4) | (Char - 'A' + 10); else - this->Buffers[Index].Color = 0xFFFFFF; + this->Color = 0xFFFFFF; this->ColorPickerIteration++; if (this->ColorPickerIteration == 6) { @@ -314,6 +151,10 @@ namespace Video if (WriteToUART && Char != '\e') UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(Char); + if (_Font == nullptr) + _Font = this->DefaultFont; + this->CurrentFont = _Font; + switch (Char) { case '\e': @@ -323,7 +164,7 @@ namespace Video } case '\b': { - switch (this->CurrentFont->GetInfo().Type) + switch (_Font->GetInfo().Type) { case FontType::PCScreenFont1: { @@ -332,13 +173,21 @@ namespace Video } case FontType::PCScreenFont2: { - uint32_t fonthdrWidth = this->CurrentFont->GetInfo().PSF2Font->Header->width; - uint32_t fonthdrHeight = this->CurrentFont->GetInfo().PSF2Font->Header->height; + uint32_t fonthdrWidth = _Font->GetInfo().PSF2Font->Header->width; + uint32_t fonthdrHeight = _Font->GetInfo().PSF2Font->Header->height; - for (unsigned long Y = this->Buffers[Index].CursorY; Y < this->Buffers[Index].CursorY + fonthdrHeight; Y++) - for (unsigned long X = this->Buffers[Index].CursorX - fonthdrWidth; X < this->Buffers[Index].CursorX; X++) - *(uint32_t *)((uintptr_t)this->Buffers[Index].Buffer + - (Y * this->Buffers[Index].Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0; + for (unsigned long Y = this->CursorY; Y < this->CursorY + fonthdrHeight; Y++) + for (unsigned long X = this->CursorX - fonthdrWidth; X < this->CursorX; X++) + *(uint32_t *)((uintptr_t)this->Buffer + + (Y * this->Width + X) * (this->framebuffer.BitsPerPixel / 8)) = 0; + + // for (size_t i = 0; i < 9; ++i) + // { + // size_t row = (CursorY / RegionHeight) + (i / 3) - 1; + // size_t col = (CursorX / RegionWidth) + (i % 3) - 1; + // if (row < Height / RegionHeight && col < Width / RegionWidth) + // MarkRegionDirty(row, col); + // } break; } default: @@ -346,25 +195,25 @@ namespace Video break; } - if (this->Buffers[Index].CursorX > 0) - this->Buffers[Index].CursorX -= this->GetCurrentFont()->GetInfo().Width; + if (this->CursorX > 0) + this->CursorX -= this->GetCurrentFont()->GetInfo().Width; return Char; } case '\t': { - this->Buffers[Index].CursorX = (this->Buffers[Index].CursorX + 8) & ~(8 - 1); + this->CursorX = (this->CursorX + 8) & ~(8 - 1); return Char; } case '\r': { - this->Buffers[Index].CursorX = 0; + this->CursorX = 0; return Char; } case '\n': { - this->Buffers[Index].CursorX = 0; - this->Buffers[Index].CursorY += this->GetCurrentFont()->GetInfo().Height; + this->CursorX = 0; + this->CursorY += this->GetCurrentFont()->GetInfo().Height; return Char; } default: @@ -373,44 +222,44 @@ namespace Video uint32_t FontHeight = this->GetCurrentFont()->GetInfo().Height; - if (this->Buffers[Index].CursorX + this->GetCurrentFont()->GetInfo().Width >= this->Buffers[Index].Width) + if (this->CursorX + this->GetCurrentFont()->GetInfo().Width >= this->Width) { - this->Buffers[Index].CursorX = 0; - this->Buffers[Index].CursorY += FontHeight; + this->CursorX = 0; + this->CursorY += FontHeight; } - if (this->Buffers[Index].CursorY + FontHeight >= this->Buffers[Index].Height) + if (this->CursorY + FontHeight >= this->Height) { - if (!this->Buffers[Index].DoNotScroll) + if (!this->DoNotScroll) { - this->Buffers[Index].CursorY -= FontHeight; - this->Scroll(Index, 1); + this->CursorY -= FontHeight; + this->Scroll(1); } } - switch (this->CurrentFont->GetInfo().Type) + switch (_Font->GetInfo().Type) { case FontType::PCScreenFont1: { - uint32_t *PixelPtr = (uint32_t *)this->Buffers[Index].Buffer; - char *FontPtr = (char *)this->CurrentFont->GetInfo().PSF1Font->GlyphBuffer + (Char * this->CurrentFont->GetInfo().PSF1Font->Header->charsize); - for (uint64_t Y = this->Buffers[Index].CursorY; Y < this->Buffers[Index].CursorY + 16; Y++) + uint32_t *PixelPtr = (uint32_t *)this->Buffer; + char *FontPtr = (char *)_Font->GetInfo().PSF1Font->GlyphBuffer + (Char * _Font->GetInfo().PSF1Font->Header->charsize); + for (uint64_t Y = this->CursorY; Y < this->CursorY + 16; Y++) { - for (uint64_t X = this->Buffers[Index].CursorX; X < this->Buffers[Index].CursorX + 8; X++) - if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index].CursorX))) > 0) - *(unsigned int *)(PixelPtr + X + (Y * this->Buffers[Index].Width)) = this->Buffers[Index].Color; + for (uint64_t X = this->CursorX; X < this->CursorX + 8; X++) + if ((*FontPtr & (0b10000000 >> (X - this->CursorX))) > 0) + *(unsigned int *)(PixelPtr + X + (Y * this->Width)) = this->Color; FontPtr++; } - this->Buffers[Index].CursorX += 8; + this->CursorX += 8; break; } case FontType::PCScreenFont2: { - // if (this->CurrentFont->PSF2Font->GlyphBuffer == (uint16_t *)0x01) // HAS UNICODE TABLE - // Char = this->CurrentFont->PSF2Font->GlyphBuffer[Char]; + // if (_Font->PSF2Font->GlyphBuffer == (uint16_t *)0x01) // HAS UNICODE TABLE + // Char = _Font->PSF2Font->GlyphBuffer[Char]; - FontInfo fInfo = this->CurrentFont->GetInfo(); + FontInfo fInfo = _Font->GetInfo(); int BytesPerLine = (fInfo.PSF2Font->Header->width + 7) / 8; char *FontAddress = (char *)fInfo.StartAddress; @@ -422,71 +271,128 @@ namespace Video uint32_t FontHdrWidth = fInfo.PSF2Font->Header->width; uint32_t FontHdrHeight = fInfo.PSF2Font->Header->height; - for (size_t Y = this->Buffers[Index].CursorY; Y < this->Buffers[Index].CursorY + FontHdrHeight; Y++) + for (size_t Y = this->CursorY; Y < this->CursorY + FontHdrHeight; Y++) { - for (size_t X = this->Buffers[Index].CursorX; X < this->Buffers[Index].CursorX + FontHdrWidth; X++) + for (size_t X = this->CursorX; X < this->CursorX + FontHdrWidth; X++) { - if ((*FontPtr & (0b10000000 >> (X - this->Buffers[Index].CursorX))) > 0) + if ((*FontPtr & (0b10000000 >> (X - this->CursorX))) > 0) { - void *FramebufferAddress = (void *)((uintptr_t)this->Buffers[Index].Buffer + - (Y * this->Buffers[Index].Width + X) * + void *FramebufferAddress = (void *)((uintptr_t)this->Buffer + + (Y * this->Width + X) * (this->framebuffer.BitsPerPixel / 8)); - *(uint32_t *)FramebufferAddress = this->Buffers[Index].Color; + *(uint32_t *)FramebufferAddress = this->Color; } } FontPtr += BytesPerLine; } - this->Buffers[Index].CursorX += FontHdrWidth; + this->CursorX += FontHdrWidth; break; } default: warn("Unsupported font type"); break; } + + // // MarkRegionDirty(CursorY / RegionHeight, CursorX / RegionWidth); + // for (size_t i = 0; i < 9; ++i) + // { + // size_t row = (CursorY / RegionHeight) + (i / 3) - 1; + // size_t col = (CursorX / RegionWidth) + (i % 3) - 1; + // if (row < Height / RegionHeight && col < Width / RegionWidth) + // MarkRegionDirty(row, col); + // } return Char; } - void Display::DrawString(const char *String, uint32_t X, uint32_t Y, int Index, bool WriteToUART) + void Display::UpdateBuffer() { - if (unlikely(this->Buffers[Index].Checksum != 0xBBFFE515A117E)) + if (!DirectWrite) + memcpy(this->framebuffer.BaseAddress, this->Buffer, this->Size); + + // for (size_t i = 0; i < DirtyMap.size(); ++i) + // { + // if (DirtyMap[i]) + // { + // size_t rRow = i / (framebuffer.Width / RegionWidth); + // size_t rCol = i % (framebuffer.Width / RegionWidth); + // UpdateRegion(rRow, rCol); + // DirtyMap[i] = false; + // } + // } + } + + void Display::UpdateRegion(size_t RegionRow, size_t RegionColumn) + { + size_t startRow = RegionRow * RegionHeight; + size_t endRow = startRow + RegionHeight; + size_t startCol = RegionColumn * RegionWidth; + size_t endCol = startCol + RegionWidth; + + uint8_t *framebufferPtr = (uint8_t *)framebuffer.BaseAddress; + uint8_t *bufferPtr = (uint8_t *)Buffer; + + for (size_t row = startRow; row < endRow; ++row) { - debug("Invalid buffer %d", Index); + uint8_t *framebufferRowPtr = framebufferPtr + (row % framebuffer.Height) * framebuffer.Width * (framebuffer.BitsPerPixel / 8); + uint8_t *bufferRowPtr = bufferPtr + row * framebuffer.Width * (framebuffer.BitsPerPixel / 8); + + for (size_t col = startCol; col < endCol; ++col) + { + uint8_t *framebufferPixelPtr = framebufferRowPtr + (col % framebuffer.Width) * (framebuffer.BitsPerPixel / 8); + uint8_t *bufferPixelPtr = bufferRowPtr + col * (framebuffer.BitsPerPixel / 8); + + memcpy(framebufferPixelPtr, bufferPixelPtr, framebuffer.BitsPerPixel / 8); + } + } + /* + size_t startRow = RegionRow * RegionHeight; + size_t endRow = startRow + RegionHeight; + size_t startCol = RegionColumn * RegionWidth; + size_t endCol = startCol + RegionWidth; + + for (size_t row = startRow; row < endRow; ++row) + { + for (size_t col = startCol; col < endCol; ++col) + { + size_t bufferIndex = row * framebuffer.Width + col; + size_t framebufferIndex = (row % framebuffer.Height) * framebuffer.Width + (col % framebuffer.Width); + memcpy((uint8_t *)framebuffer.BaseAddress + framebufferIndex * (framebuffer.BitsPerPixel / 8), + (uint8_t *)Buffer + bufferIndex * (framebuffer.BitsPerPixel / 8), + framebuffer.BitsPerPixel / 8); + } + } + */ + } + + void Display::MarkRegionDirty(size_t RegionRow, size_t RegionCol) + { + size_t index = RegionRow * (framebuffer.Width / RegionWidth) + RegionCol; + DirtyMap[index] = true; + } + + Display::Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont, bool _DirectWrite) + : framebuffer(Info), DirectWrite(_DirectWrite) + { + Width = Info.Width; + Height = Info.Height; + Size = this->framebuffer.Pitch * Height; + if (DirectWrite) + Buffer = (void *)this->framebuffer.BaseAddress; + else + Buffer = KernelAllocator.RequestPages(TO_PAGES(Size)); + + // DirtyMap.resize((Width / RegionWidth) * (Height / RegionHeight), false); + + if (!LoadDefaultFont) return; - } - - this->Buffers[Index].CursorX = X; - this->Buffers[Index].CursorY = Y; - - for (int i = 0; String[i] != '\0'; i++) - this->Print(String[i], Index, WriteToUART); - } - - Display::Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont) - { - this->framebuffer = Info; - if (LoadDefaultFont) - { - this->CurrentFont = new Font(&_binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, FontType::PCScreenFont2); + this->DefaultFont = new Font(&_binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, FontType::PCScreenFont2); #ifdef DEBUG - FontInfo Info = this->CurrentFont->GetInfo(); - debug("Font loaded: %dx%d %s", - Info.Width, Info.Height, - Info.Type == FontType::PCScreenFont1 ? "PSF1" : "PSF2"); + FontInfo fInfo = this->DefaultFont->GetInfo(); + debug("Font loaded: %dx%d %s", + fInfo.Width, fInfo.Height, + fInfo.Type == FontType::PCScreenFont1 ? "PSF1" : "PSF2"); #endif - } - this->CreateBuffer(Info.Width, Info.Height, 0); } - Display::~Display() - { - debug("Destructor called"); - this->ClearBuffer(0); - this->SetBuffer(0); - - for (int i = 0; i < s_cst(int, sizeof(this->Buffers) / sizeof(this->Buffers[0])); i++) - { - if (this->Buffers[i].Checksum == 0xBBFFE515A117E) - this->DeleteBuffer(i); - } - } + Display::~Display() {} } diff --git a/include/display.hpp b/include/display.hpp index 3cabdec..34c7c64 100644 --- a/include/display.hpp +++ b/include/display.hpp @@ -35,6 +35,24 @@ namespace Video #define PSF2_MAGIC2 0x4a #define PSF2_MAGIC3 0x86 + enum DisplayFont + { + Tamsyn5x9r, + Tamsyn5x9b, + Tamsyn6x12r, + Tamsyn6x12b, + Tamsyn7x14r, + Tamsyn7x14b, + Tamsyn7x13r, + Tamsyn7x13b, + Tamsyn8x15r, + Tamsyn8x15b, + Tamsyn8x16r, + Tamsyn8x16b, + Tamsyn10x20r, + Tamsyn10x20b, + }; + struct PSF1_HEADER { uint8_t magic[2]; @@ -93,72 +111,82 @@ namespace Video ~Font(); }; - struct ScreenBuffer + union Pixel { - void *Buffer = nullptr; - uint32_t Width, Height; - size_t Size; - uint32_t Color; - uint32_t CursorX, CursorY; - char Brightness; - bool DoNotScroll; - long long Checksum; + struct + { + uint8_t Alpha; + uint8_t Red; + uint8_t Green; + uint8_t Blue; + }; + uint32_t raw; }; class Display { private: BootInfo::FramebufferInfo framebuffer; + Font *DefaultFont = nullptr; Font *CurrentFont = nullptr; - ScreenBuffer Buffers[256]; bool ColorIteration = false; int ColorPickerIteration = 0; + void *Buffer; + size_t Size; + uint32_t Width, Height; + uint32_t Color; + uint32_t CursorX, CursorY; + bool DoNotScroll; + bool DirectWrite; + + uint32_t RegionWidth = 64, RegionHeight = 64; + std::vector DirtyMap; + public: + decltype(Buffer) &GetBuffer = Buffer; + decltype(Size) &GetSize = Size; + decltype(Width) &GetWidth = Width; + decltype(Height) &GetHeight = Height; + BootInfo::FramebufferInfo GetFramebufferStruct() { return framebuffer; } Font *GetCurrentFont(); void SetCurrentFont(Font *Font); uint16_t GetBitsPerPixel(); size_t GetPitch(); - /** - * @brief Create a new buffer - * - * This function creates a new buffer. - * - * For @see Width and @see Height. Both values must be greater than 0. - * - * @note Some indexes are reserved for the kernel. - * 0 - Main buffer - * 1 - Loading screen buffer - * 200 - GUI buffer - * 250 - Empty (crash screen) - * 251 - Console (crash screen) - * 252 - Tasks (crash screen) - * 253 - Frames (crash screen) - * 254 - Details (crash screen) - * 255 - Main (crash screen) - * - * @param Width The width of the buffer - * @param Height The height of the buffer - * @param Index The index of the buffer (0-255) - */ - void CreateBuffer(uint32_t Width, uint32_t Height, int Index); - void SetBuffer(int Index); - ScreenBuffer *GetBuffer(int Index); - void ClearBuffer(int Index); - void DeleteBuffer(int Index); - void SetBrightness(int Value, int Index); - void SetBufferCursor(int Index, uint32_t X, uint32_t Y); - void GetBufferCursor(int Index, uint32_t *X, uint32_t *Y); - void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index); - uint32_t GetPixel(uint32_t X, uint32_t Y, int Index); - void Scroll(int Index, int Lines); - void SetDoNotScroll(bool Value, int Index); + void ClearBuffer(); + void SetPixel(uint32_t X, uint32_t Y, uint32_t Color); + void Scroll(int Lines); - char Print(char Char, int Index, bool WriteToUART = false); - void DrawString(const char *String, uint32_t X, uint32_t Y, int Index, bool WriteToUART = false); - Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont = true); + void SetDoNotScroll(bool Value) + { + this->DoNotScroll = Value; + } + + void SetBufferCursor(uint32_t X, uint32_t Y) + { + this->CursorX = X; + this->CursorY = Y; + } + + void GetBufferCursor(uint32_t *X, uint32_t *Y) + { + *X = this->CursorX; + *Y = this->CursorY; + } + + void UpdateRegion(size_t RegionRow, size_t RegionColumn); + void MarkRegionDirty(size_t RegionRow, size_t RegionCol); + void UpdateBuffer(); + + char Print(char Char, + Video::Font *Font = nullptr, + bool WriteToUART = false); + + Display(BootInfo::FramebufferInfo Info, + bool LoadDefaultFont = true, + bool DirectWrite = true); ~Display(); }; } diff --git a/kernel.cpp b/kernel.cpp index 4bf3388..a85d393 100644 --- a/kernel.cpp +++ b/kernel.cpp @@ -63,12 +63,10 @@ Time::time *TimeManager = nullptr; Tasking::Task *TaskManager = nullptr; PCI::Manager *PCIManager = nullptr; -// For the Display class. Printing on first buffer as default. -int PutCharBufferIndex = 0; EXTERNC void putchar(char c) { if (Display) - Display->Print(c, PutCharBufferIndex); + Display->Print(c); else UniversalAsynchronousReceiverTransmitter::UART(UniversalAsynchronousReceiverTransmitter::COM1).Write(c); } @@ -98,7 +96,7 @@ EXTERNC void _KPrint(const char *Format, va_list Args) vprintf(Format, Args); printf("\eCCCCCC\n"); if (!Config.Quiet && Display) - Display->SetBuffer(0); + Display->UpdateBuffer(); } EXTERNC void KPrint(const char *Format, ...) @@ -207,21 +205,6 @@ EXTERNC NIF void Main() bInfo.Kernel.Symbols.Shndx, bInfo.Kernel.Symbols.Sections); - if (Config.Quiet) - { - Display->CreateBuffer(0, 0, 1); - - Display->SetDoNotScroll(true, 1); - Video::ScreenBuffer *buf = Display->GetBuffer(1); - Video::FontInfo fi = Display->GetCurrentFont()->GetInfo(); - Display->SetBufferCursor(1, 0, buf->Height - fi.Height); - PutCharBufferIndex = 1; - printf("Fennix Operating System - %s [\e058C19%s\eFFFFFF]\n", - KERNEL_VERSION, GIT_COMMIT_SHORT); - Display->SetBuffer(1); - PutCharBufferIndex = 0; - } - KPrint("Initializing Power Manager"); PowerManager = new Power::Power; diff --git a/kshell/cmds.hpp b/kshell/cmds.hpp index e523061..8d78bdb 100644 --- a/kshell/cmds.hpp +++ b/kshell/cmds.hpp @@ -42,6 +42,7 @@ void cmd_lspci(const char *args); void cmd_lsacpi(const char *args); void cmd_lsmod(const char *args); void cmd_modinfo(const char *args); +void cmd_panic(const char *args); #define IF_ARG(x) strcmp(args, x) == 0 diff --git a/kshell/commands/clear.cpp b/kshell/commands/clear.cpp index d518561..5fc2474 100644 --- a/kshell/commands/clear.cpp +++ b/kshell/commands/clear.cpp @@ -21,6 +21,6 @@ void cmd_clear(const char *) { - Display->SetBufferCursor(0, 0, 0); - Display->ClearBuffer(0); + Display->SetBufferCursor(0, 0); + Display->ClearBuffer(); } diff --git a/kshell/commands/panic.cpp b/kshell/commands/panic.cpp new file mode 100644 index 0000000..dc2550e --- /dev/null +++ b/kshell/commands/panic.cpp @@ -0,0 +1,29 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#include "../cmds.hpp" + +#include + +#include "../../kernel.h" + +using namespace vfs; + +void cmd_panic(const char *args) +{ + int3; +} diff --git a/kshell/commands/tree.cpp b/kshell/commands/tree.cpp index 9166b5d..70876c9 100644 --- a/kshell/commands/tree.cpp +++ b/kshell/commands/tree.cpp @@ -27,7 +27,7 @@ void tree_loop(Node *rootNode, int depth = 0) { foreach (auto Child in rootNode->Children) { - Display->SetBuffer(0); + Display->UpdateBuffer(); if (Child->Type == NodeType::DIRECTORY || Child->Type == NodeType::MOUNTPOINT) { diff --git a/kshell/shell.cpp b/kshell/shell.cpp index f16b36f..01d51fe 100644 --- a/kshell/shell.cpp +++ b/kshell/shell.cpp @@ -77,6 +77,7 @@ static Command commands[] = { {"rmmod", nullptr}, {"modprobe", nullptr}, {"depmod", nullptr}, + {"panic", cmd_panic}, }; void StartKernelShell() @@ -118,7 +119,7 @@ void StartKernelShell() "kernel", "fennix", cwd->FullPath); - Display->SetBuffer(0); + Display->UpdateBuffer(); uint8_t scBuf[2]; scBuf[1] = 0x00; /* Request scan code */ @@ -167,10 +168,10 @@ void StartKernelShell() if (BackspaceCount == 0) continue; - Display->Print('\b', 0); + Display->Print('\b'); Buffer.pop_back(); BackspaceCount--; - Display->SetBuffer(0); + Display->UpdateBuffer(); continue; } case KEY_UP_ARROW: @@ -185,15 +186,15 @@ void StartKernelShell() HistoryIndex--; for (size_t i = 0; i < Buffer.size(); i++) - Display->Print('\b', 0); - Display->SetBuffer(0); + Display->Print('\b'); + Display->UpdateBuffer(); Buffer = History[HistoryIndex]->c_str(); for (size_t i = 0; i < strlen(Buffer.c_str()); i++) - Display->Print(Buffer[i], 0); + Display->Print(Buffer[i]); BackspaceCount = Buffer.size(); - Display->SetBuffer(0); + Display->UpdateBuffer(); continue; } case KEY_DOWN_ARROW: @@ -209,24 +210,24 @@ void StartKernelShell() { HistoryIndex++; for (size_t i = 0; i < Buffer.size(); i++) - Display->Print('\b', 0); + Display->Print('\b'); BackspaceCount = Buffer.size(); - Display->SetBuffer(0); + Display->UpdateBuffer(); continue; } for (size_t i = 0; i < Buffer.size(); i++) - Display->Print('\b', 0); - Display->SetBuffer(0); + Display->Print('\b'); + Display->UpdateBuffer(); HistoryIndex++; Buffer = History[HistoryIndex]->c_str(); for (size_t i = 0; i < strlen(Buffer.c_str()); i++) - Display->Print(Buffer[i], 0); + Display->Print(Buffer[i]); BackspaceCount = Buffer.size(); - Display->SetBuffer(0); + Display->UpdateBuffer(); continue; } case KEY_TAB: @@ -245,14 +246,14 @@ void StartKernelShell() for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) printf("%s ", commands[i].Name); - Display->Print('\n', 0); - Display->SetBuffer(0); + Display->Print('\n'); + Display->UpdateBuffer(); goto SecLoopEnd; } for (size_t i = 0; i < Buffer.size(); i++) - Display->Print('\b', 0); - Display->SetBuffer(0); + Display->Print('\b'); + Display->UpdateBuffer(); for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { @@ -260,9 +261,9 @@ void StartKernelShell() { Buffer = commands[i].Name; for (size_t i = 0; i < strlen(Buffer.c_str()); i++) - Display->Print(Buffer[i], 0); + Display->Print(Buffer[i]); BackspaceCount = Buffer.size(); - Display->SetBuffer(0); + Display->UpdateBuffer(); break; } } @@ -286,20 +287,20 @@ void StartKernelShell() { case 'C': { - Display->Print('^', 0); - Display->Print('C', 0); - Display->Print('\n', 0); + Display->Print('^'); + Display->Print('C'); + Display->Print('\n'); fixme("No SIGINT handler yet."); - Display->SetBuffer(0); + Display->UpdateBuffer(); goto SecLoopEnd; } case 'D': { - Display->Print('^', 0); - Display->Print('D', 0); - Display->Print('\n', 0); + Display->Print('^'); + Display->Print('D'); + Display->Print('\n'); fixme("No SIGKILL handler yet."); - Display->SetBuffer(0); + Display->UpdateBuffer(); goto SecLoopEnd; } default: @@ -307,7 +308,7 @@ void StartKernelShell() } } - Display->Print(c, 0); + Display->Print(c); if (c == '\n') { if (Buffer.length() > 0) @@ -321,7 +322,7 @@ void StartKernelShell() Buffer += c; BackspaceCount++; - Display->SetBuffer(0); + Display->UpdateBuffer(); } SecLoopEnd: diff --git a/storage/devices/tty/kcon.cpp b/storage/devices/tty/kcon.cpp index abc8562..30a1af7 100644 --- a/storage/devices/tty/kcon.cpp +++ b/storage/devices/tty/kcon.cpp @@ -38,7 +38,7 @@ namespace vfs putchar(((char *)Buffer)[i]); if (!Config.Quiet) - Display->SetBuffer(0); + Display->UpdateBuffer(); return Size; } diff --git a/storage/devices/tty/tty.cpp b/storage/devices/tty/tty.cpp index 57236b9..866cf02 100644 --- a/storage/devices/tty/tty.cpp +++ b/storage/devices/tty/tty.cpp @@ -28,7 +28,7 @@ namespace vfs for (size_t i = 0; i < Size; i++) putchar(((char *)Buffer)[i]); - Display->SetBuffer(0); /* FIXME: stub */ + Display->UpdateBuffer(); /* FIXME: stub */ return Size; } @@ -39,14 +39,13 @@ namespace vfs case TIOCGWINSZ: { struct winsize *ws = (struct winsize *)Argp; - Video::ScreenBuffer *sb = Display->GetBuffer(0); Video::FontInfo fi = Display->GetCurrentFont()->GetInfo(); fixme("TIOCGWINSZ: stub"); - ws->ws_xpixel = uint16_t(sb->Width); - ws->ws_ypixel = uint16_t(sb->Height); - ws->ws_col = uint16_t(sb->Width / fi.Width); - ws->ws_row = uint16_t(sb->Height / fi.Height); + ws->ws_xpixel = uint16_t(Display->GetWidth); + ws->ws_ypixel = uint16_t(Display->GetHeight); + ws->ws_col = uint16_t(Display->GetWidth / fi.Width); + ws->ws_row = uint16_t(Display->GetHeight / fi.Height); break; } default: diff --git a/tests/lsof.cpp b/tests/lsof.cpp index 9618eb9..28f78c3 100644 --- a/tests/lsof.cpp +++ b/tests/lsof.cpp @@ -44,19 +44,20 @@ void lsof() while (ShowOpenFiles == 0) CPU::Pause(); - Video::ScreenBuffer *sb = Display->GetBuffer(0); for (short i = 0; i < 500; i++) { for (short j = 0; j < 500; j++) { - uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); - *Pixel = 0x222222; + Video::Pixel *p = (Video::Pixel *)((uintptr_t)Display->GetBuffer + + (j * Display->GetWidth + i) * + (bInfo.Framebuffer[0].BitsPerPixel / 8)); + *p = {0xFF, 0x22, 0x22, 0x22}; } } uint32_t tmpX, tmpY; - Display->GetBufferCursor(0, &tmpX, &tmpY); - Display->SetBufferCursor(0, 0, 0); + Display->GetBufferCursor(&tmpX, &tmpY); + Display->SetBufferCursor(0, 0); printf("\eF02C21Open Files (%ld):\e00AAAA\n", TaskManager->GetProcessList().size()); foreach (auto Proc in TaskManager->GetProcessList()) @@ -72,9 +73,9 @@ void lsof() printf(" %d: %s\n", fd.Descriptor, fd.Handle->node->FullPath); } - Display->SetBufferCursor(0, tmpX, tmpY); + Display->SetBufferCursor(tmpX, tmpY); if (!Config.Quiet) - Display->SetBuffer(0); + Display->UpdateBuffer(); } } diff --git a/tests/taskmgr.cpp b/tests/taskmgr.cpp index 8d54ce9..86bc63e 100644 --- a/tests/taskmgr.cpp +++ b/tests/taskmgr.cpp @@ -111,19 +111,20 @@ void TaskMgr() CPU::Pause(); static int sanity = 0; - Video::ScreenBuffer *sb = Display->GetBuffer(0); for (short i = 0; i < 1000; i++) { for (short j = 0; j < 500; j++) { - uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); - *Pixel = 0x222222; + Video::Pixel *p = (Video::Pixel *)((uintptr_t)Display->GetBuffer + + (j * Display->GetWidth + i) * + (bInfo.Framebuffer[0].BitsPerPixel / 8)); + *p = {0xFF, 0x22, 0x22, 0x22}; } } uint32_t tmpX, tmpY; - Display->GetBufferCursor(0, &tmpX, &tmpY); - Display->SetBufferCursor(0, 0, 0); + Display->GetBufferCursor(&tmpX, &tmpY); + Display->SetBufferCursor(0, 0); printf("\eF02C21Task Manager\n"); static uint64_t OldSystemTime = 0; foreach (auto Proc in TaskManager->GetProcessList()) @@ -176,9 +177,9 @@ void TaskMgr() #endif if (sanity > 1000) sanity = 0; - Display->SetBufferCursor(0, tmpX, tmpY); + Display->SetBufferCursor(tmpX, tmpY); if (!Config.Quiet) - Display->SetBuffer(0); + Display->UpdateBuffer(); TaskManager->Sleep(100); } diff --git a/tests/treefs.cpp b/tests/treefs.cpp index bfbc9d5..0ce2643 100644 --- a/tests/treefs.cpp +++ b/tests/treefs.cpp @@ -29,7 +29,7 @@ void TreeFS(vfs::Node *node, int Depth) printf("%*c %s\eFFFFFF\n", Depth, ' ', Chld->Name); if (!Config.Quiet) - Display->SetBuffer(0); + Display->UpdateBuffer(); TaskManager->Sleep(100); TreeFS(Chld, Depth + 1); }