diff options
-rw-r--r-- | Source/Kernel/Core/kmain.wtf.cpp | 7 | ||||
-rw-r--r-- | Source/Kernel/DeviceManager/Disp.ns.cpp | 2 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp | 2 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/VESADisplay.class.cpp | 74 | ||||
-rw-r--r-- | Source/Kernel/Devices/Display/VESADisplay.class.h | 8 |
5 files changed, 87 insertions, 6 deletions
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index cf1713f..e3344f1 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -22,6 +22,7 @@ #include <SyscallManager/IDT.ns.h> #include <String.class.h> #include <ByteArray.class.h> +#include <Rand.ns.h> #include <VFS/Part.ns.h> #include <FileSystems/RamFS/RamFS.class.h> #include <VFS/FileNode.class.h> @@ -100,10 +101,13 @@ void selectVideoMode(SimpleVT& v) { v << "\nYour selection: "; String answer = v.readLine(); u32int n = answer.toInt(); + v.unmap(); if (n >= 0 and n < Disp::modes.size() and Disp::setMode(Disp::modes[n])) { return; } else { - v << "Error while switching video mode, please select another one.\n"; + Disp::setMode(Disp::modes[1]); + v.map(); + v << "Error while switching video mode, please select another one."; } } } @@ -173,7 +177,6 @@ void kmain(multiboot_info_t* mbd, u32int magic) { asm volatile("sti"); selectVideoMode(*kvt); //////////////////////// SETUP VIDEO MODE - kvt->unmap(); //Create a VT for handling the Melon bootup logo SimpleVT *melonLogoVT = new SimpleVT(melonLogoLines, melonLogoCols, TXTLOGO_FGCOLOR, TXTLOGO_BGCOLOR); diff --git a/Source/Kernel/DeviceManager/Disp.ns.cpp b/Source/Kernel/DeviceManager/Disp.ns.cpp index 146740d..2827869 100644 --- a/Source/Kernel/DeviceManager/Disp.ns.cpp +++ b/Source/Kernel/DeviceManager/Disp.ns.cpp @@ -1,5 +1,6 @@ #include "Disp.ns.h" #include <DeviceManager/Dev.ns.h> +#include <VTManager/VT.ns.h> namespace Disp { @@ -45,6 +46,7 @@ bool setMode(mode_t& newmode) { if (newmode.device->setMode(newmode)) { mode = newmode; + VT::redrawScreen(); return true; } return false; diff --git a/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp b/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp index 3e1264e..63fb875 100644 --- a/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp +++ b/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp @@ -10,7 +10,7 @@ u32int consoleColor[16] = { 0x00AA0000, // 4 == dark red 0x00AA00AA, // 5 == dark magenta 0x00AA5500, // 6 == dark orange - 0x00999999, // 7 == light grey + 0x00A0A0A0, // 7 == light grey 0x00555555, // 8 == dark grey 0x005555FF, // 9 == bright blue 0x0055FF55, // A == bright green diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.cpp b/Source/Kernel/Devices/Display/VESADisplay.class.cpp index 215f405..f882d5b 100644 --- a/Source/Kernel/Devices/Display/VESADisplay.class.cpp +++ b/Source/Kernel/Devices/Display/VESADisplay.class.cpp @@ -87,7 +87,7 @@ void VESADisplay::getModes(Vector<mode_t> &to) { if ((mode.attributes & 0x90) != 0x90) continue; if (mode.memory_model != 4 and mode.memory_model != 6) continue; - if (mode.bpp != 24 and mode.bpp != 16 and mode.bpp != 15) continue; + if (mode.bpp != 24 and mode.bpp != 16 and mode.bpp != 15 and mode.bpp != 8) continue; mode_t m; m.device = this; m.textCols = mode.Xres / C_FONT_WIDTH; m.textRows = mode.Yres / C_FONT_HEIGHT; m.identifier = modes[i]; @@ -104,11 +104,31 @@ bool VESADisplay::setMode(mode_t &mode) { if (mode.device != this) return false; m_currMode = getModeInfo(mode.identifier); v86_regs_t regs; - regs.ax = 0x00004F02; + + //Set mode + regs.ax = 0x4F02; regs.bx = mode.identifier | 0x4000; V86::biosInt(0x10, regs); if (regs.ax != 0x004F) return false; + if (m_currMode.bpp == 8) { + //Set palette to 8 bit + regs.ax = 0x4F08; + regs.bx = 0x0800; + V86::biosInt(0x10, regs); + if ((regs.ax & 0xFF) != 0x4F or regs.bx != 0x0800) return false; + //Set palette data + for (int i = 0; i < 16; i++) { + m_8bitPalette[i].pixels = 0; + m_8bitPalette[i].color = rgbTo15(consoleColor[i]); + setPalette(i, consoleColor[i]); + } + for (int i = 16; i < 256; i++) { + m_8bitPalette[i].pixels = 0; + m_8bitPalette[i].color = 0; + } + } + m_fb = (u8int*)0xF0000000; for (u32int i = 0; i < (u32int)(m_currMode.Yres * m_currMode.pitch); i += 0x1000) { kernelPageDirectory->map( @@ -116,6 +136,7 @@ bool VESADisplay::setMode(mode_t &mode) { (m_currMode.physbase + i) / 0x1000, false, false); } m_pixWidth = (m_currMode.bpp + 1) / 8; + clear(); return true; } @@ -128,8 +149,37 @@ void VESADisplay::unsetMode() { void VESADisplay::clear() { for (u32int* i = (u32int*)(memPos(0, 0)); i < (u32int*)(memPos(m_currMode.Xres, 0)); i++) { - *i = 0x77777777; + *i = 0; + } +} +/**************************************** + * 8BIT PALLET HANDLING + * *********************************************/ + +void VESADisplay::setPalette(u8int id, u32int color) { + Sys::outb(0x03C6, 0xFF); + Sys::outb(0x03C8, id); + Sys::outb(0x03C9, ((color >> 16) & 0xFF) / 4); + Sys::outb(0x03C9, ((color >> 8) & 0xFF) / 4); + Sys::outb(0x03C9, (color & 0xFF) / 4); +} + +u8int VESADisplay::get8Bit(u32int color) { + u16int c = rgbTo15(color); + c &= ~0x0C63; //Make the color very approximate (keep only 3bits per primary color) + for (u16int i = 0; i < 256; i++) { + if (m_8bitPalette[i].color == c) { + return i; + } } + for (u16int i = 16; i < 256; i++) { + if (m_8bitPalette[i].pixels == 0) { + m_8bitPalette[i].color = c; + setPalette(i, rgbFrom15(c)); + return i; + } + } + return 0; } /**************************************** @@ -149,6 +199,10 @@ void VESADisplay::putPix(u16int x, u16int y, u32int c) { *p.w = rgbTo15(c); } else if (m_currMode.bpp == 16) { *p.w = rgbTo16(c); + } else if (m_currMode.bpp == 8) { + m_8bitPalette[*p.c].pixels--; + *p.c = get8Bit(c); + m_8bitPalette[*p.c].pixels++; } } @@ -166,6 +220,8 @@ u32int VESADisplay::getPix(u16int x, u16int y) { ret = rgbFrom15(*p.w); } else if (m_currMode.bpp == 16) { ret = rgbFrom16(*p.w); + } else if (m_currMode.bpp == 8) { + ret = rgbFrom15(m_8bitPalette[*p.c].color); } return ret; } @@ -185,6 +241,9 @@ void VESADisplay::drawChar(u16int line, u16int col, WChar c, u8int color) { } else if (m_currMode.bpp == 16) { fgcolor = rgbTo16(consoleColor[color & 0xF]); bgcolor = rgbTo16(consoleColor[(color >> 4) & 0xF]); + } else if (m_currMode.bpp == 8) { + fgcolor = color & 0xF; + bgcolor = (color >> 4) & 0xF; } @@ -210,6 +269,15 @@ void VESADisplay::drawChar(u16int line, u16int col, WChar c, u8int color) { *pos.w = ((pixs & 1) != 0 ? fgcolor : bgcolor); pixs = pixs >> 1; } + } else if (m_pixWidth == 1) { + m_8bitPalette[*pos.c].pixels--; + *pos.c = bgcolor; + for (int x = 0; x < 8; x++) { + pos.c--; + m_8bitPalette[*pos.c].pixels--; + *pos.c = ((pixs & 1) != 0 ? fgcolor : bgcolor); + pixs = pixs >> 1; + } } y++; } diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.h b/Source/Kernel/Devices/Display/VESADisplay.class.h index bdfc3ad..a6001e2 100644 --- a/Source/Kernel/Devices/Display/VESADisplay.class.h +++ b/Source/Kernel/Devices/Display/VESADisplay.class.h @@ -48,6 +48,11 @@ class VESADisplay : public GraphicDisplay { int b, m_pixWidth; + struct { + u32int pixels; + u16int color; + } m_8bitPalette[256]; + u8int *m_fb; u8int* memPos(u16int x, u16int y) { @@ -55,6 +60,9 @@ class VESADisplay : public GraphicDisplay { return ((u8int*)m_fb) + addr; } + u8int get8Bit(u32int color); + void setPalette(u8int id, u32int color); + public: String getClass(); String getName(); |