summaryrefslogtreecommitdiff
path: root/Source/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel')
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp7
-rw-r--r--Source/Kernel/DeviceManager/Disp.ns.cpp2
-rw-r--r--Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp2
-rw-r--r--Source/Kernel/Devices/Display/VESADisplay.class.cpp74
-rw-r--r--Source/Kernel/Devices/Display/VESADisplay.class.h8
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();