diff options
author | Alexis211 <alexis211@gmail.com> | 2009-11-11 18:16:15 +0100 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-11-11 18:16:15 +0100 |
commit | b367cdbbc77f3b1b0f83a87219ea2c4d88ee78f1 (patch) | |
tree | 9ebc81bf6c25375da26c137be3f28ba83edddc8d /Source/Kernel/Devices/Display | |
parent | 7c5f4adcc8725efa0f0476e33732873a4167f54d (diff) | |
download | Melon-b367cdbbc77f3b1b0f83a87219ea2c4d88ee78f1.tar.gz Melon-b367cdbbc77f3b1b0f83a87219ea2c4d88ee78f1.zip |
15bpp and 16bpp modes are now supported correctly
Diffstat (limited to 'Source/Kernel/Devices/Display')
4 files changed, 73 insertions, 22 deletions
diff --git a/Source/Kernel/Devices/Display/Display.proto.h b/Source/Kernel/Devices/Display/Display.proto.h index 26c3696..27d7ccc 100644 --- a/Source/Kernel/Devices/Display/Display.proto.h +++ b/Source/Kernel/Devices/Display/Display.proto.h @@ -13,6 +13,7 @@ class Display : public Device { virtual void getModes(Vector<Disp::mode_t> &to) = 0; virtual bool setMode(Disp::mode_t& mode) = 0; + virtual void unsetMode() {} //To be overloaded if driver has to do some cleaning-up virtual void clear() = 0; //Text functions diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.cpp b/Source/Kernel/Devices/Display/VESADisplay.class.cpp index ae64403..215f405 100644 --- a/Source/Kernel/Devices/Display/VESADisplay.class.cpp +++ b/Source/Kernel/Devices/Display/VESADisplay.class.cpp @@ -5,6 +5,42 @@ using namespace Disp; +/**************************************** + * COLOR HANDLING FUNCTIONS + * *********************************************/ + +inline u16int rgbTo15(u32int color) { + return ( + (((color >> 16 & 0xFF) / 8) << 10) | + (((color >> 8 & 0xFF) / 8) << 5) | + ((color & 0xFF) / 8)); +} + +inline u32int rgbFrom15(u16int color) { + return ( + (((color >> 10 & 0x1F) * 8) << 16) | + (((color >> 5 & 0x1F) * 8) << 8) | + ((color & 0x1F) * 8)); +} + +inline u16int rgbTo16(u32int color) { + return ( + (((color >> 16 & 0xFF) / 8) << 11) | + (((color >> 8 & 0xFF) / 4) << 5) | + ((color & 0xFF) / 8)); +} + +inline u32int rgbFrom16(u16int color) { + return ( + (((color >> 11 & 0x1F) * 8) << 16) | + (((color >> 5 & 0x3F) * 4) << 8) | + ((color & 0x1F) * 8)); +} + +/**************************************** + * DEVICE INFORMATION RELATED FUNCTIONS + * *********************************************/ + String VESADisplay::getClass() { return "display.vesa"; } @@ -51,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) continue; + if (mode.bpp != 24 and mode.bpp != 16 and mode.bpp != 15) 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]; @@ -60,6 +96,10 @@ void VESADisplay::getModes(Vector<mode_t> &to) { } } +/**************************************** + * MODE SELECTION FUNCTIONS + * *********************************************/ + bool VESADisplay::setMode(mode_t &mode) { if (mode.device != this) return false; m_currMode = getModeInfo(mode.identifier); @@ -67,6 +107,7 @@ bool VESADisplay::setMode(mode_t &mode) { regs.ax = 0x00004F02; regs.bx = mode.identifier | 0x4000; V86::biosInt(0x10, regs); + if (regs.ax != 0x004F) return false; m_fb = (u8int*)0xF0000000; for (u32int i = 0; i < (u32int)(m_currMode.Yres * m_currMode.pitch); i += 0x1000) { @@ -78,12 +119,23 @@ bool VESADisplay::setMode(mode_t &mode) { return true; } +void VESADisplay::unsetMode() { + for (u32int i = 0; i < (u32int)(m_currMode.Yres * m_currMode.pitch); i += 0x1000) { + page_t* p = kernelPageDirectory->getPage((u32int)(m_fb + i), false); + if (p != 0) p->present = 0, p->frame = 0; + } +} + void VESADisplay::clear() { for (u32int* i = (u32int*)(memPos(0, 0)); i < (u32int*)(memPos(m_currMode.Xres, 0)); i++) { *i = 0x77777777; } } +/**************************************** + * DRAWING FUNCTIONS + * *********************************************/ + void VESADisplay::putPix(u16int x, u16int y, u32int c) { if (x >= m_currMode.Xres or y >= m_currMode.Yres) return; union { @@ -94,10 +146,9 @@ void VESADisplay::putPix(u16int x, u16int y, u32int c) { if (m_currMode.bpp == 24) { *p.d = (*p.d & 0xFF000000) | c; } else if (m_currMode.bpp == 15) { - u32int r = (c & 0x00FF0000 >> 16) * 32 / 256, - g = (c & 0x0000FF00 >> 8) * 32 / 256, - b = (c & 0x000000FF) * 32 / 256; - *p.w = (r << 10) | (g << 5) | b; + *p.w = rgbTo15(c); + } else if (m_currMode.bpp == 16) { + *p.w = rgbTo16(c); } } @@ -112,30 +163,28 @@ u32int VESADisplay::getPix(u16int x, u16int y) { if (m_currMode.bpp == 24) { ret = *p.d & 0x00FFFFFF; } else if (m_currMode.bpp == 15) { - u32int r = ((*p.w >> 10) & 0x1F) * 256 / 32, - g = ((*p.w >> 5) & 0x1F) * 256 / 32, - b = (*p.w & 0x1F) * 256 / 32; - return (r << 16) | (g << 8) | b; + ret = rgbFrom15(*p.w); + } else if (m_currMode.bpp == 16) { + ret = rgbFrom16(*p.w); } return ret; } -//Advanced functions void VESADisplay::drawChar(u16int line, u16int col, WChar c, u8int color) { u8int ch = c.toAscii(); if (ch == 0) return; u16int sx = col * C_FONT_WIDTH, sy = line * C_FONT_HEIGHT; - u32int fgcolor = consoleColor[color & 0xF], bgcolor = consoleColor[(color >> 4) & 0xF]; - - if (m_pixWidth == 2) { - u32int r = (fgcolor & 0x00FF0000 >> 16) * 32 / 256, - g = (fgcolor & 0x0000FF00 >> 8) * 32 / 256, - b = (fgcolor & 0x000000FF) * 32 / 256; - fgcolor = (r << 10) | (g << 5) | b; - r = (bgcolor & 0x00FF0000 >> 16) * 32 / 256, - g = (bgcolor & 0x0000FF00 >> 8) * 32 / 256, - b = (bgcolor & 0x000000FF) * 32 / 256; - bgcolor = (r << 10) | (g << 5) | b; + u32int fgcolor = 1, bgcolor = 0; + + if (m_currMode.bpp == 24) { + fgcolor = consoleColor[color & 0xF]; + bgcolor = consoleColor[(color >> 4) & 0xF]; + } else if (m_currMode.bpp == 15) { + fgcolor = rgbTo15(consoleColor[color & 0xF]); + bgcolor = rgbTo15(consoleColor[(color >> 4) & 0xF]); + } else if (m_currMode.bpp == 16) { + fgcolor = rgbTo16(consoleColor[color & 0xF]); + bgcolor = rgbTo16(consoleColor[(color >> 4) & 0xF]); } diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.h b/Source/Kernel/Devices/Display/VESADisplay.class.h index 04c8e90..bdfc3ad 100644 --- a/Source/Kernel/Devices/Display/VESADisplay.class.h +++ b/Source/Kernel/Devices/Display/VESADisplay.class.h @@ -61,6 +61,7 @@ class VESADisplay : public GraphicDisplay { void getModes(Vector<Disp::mode_t> &to); bool setMode(Disp::mode_t& mode); + void unsetMode(); void clear(); void putPix(u16int x, u16int y, u32int color); diff --git a/Source/Kernel/Devices/Display/VGATextOutput.class.cpp b/Source/Kernel/Devices/Display/VGATextOutput.class.cpp index 8c687ba..50a57b2 100644 --- a/Source/Kernel/Devices/Display/VGATextOutput.class.cpp +++ b/Source/Kernel/Devices/Display/VGATextOutput.class.cpp @@ -14,7 +14,7 @@ String VGATextOutput::getClass() { } String VGATextOutput::getName() { - return "Standard mode0 VGA text display"; + return "Standard VGA text display"; } void VGATextOutput::getModes(Vector<mode_t> &to) { |