From 7292b995d4f7bfea699e44ed335d7cc1616c1132 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Wed, 11 Nov 2009 09:31:23 +0100 Subject: VESA works ! --- Source/Kernel/Core/kmain.wtf.cpp | 6 +- Source/Kernel/Devices/Display/Display.proto.h | 2 + .../Devices/Display/GraphicDisplay.proto.cpp | 24 +---- .../Kernel/Devices/Display/GraphicDisplay.proto.h | 6 -- .../Kernel/Devices/Display/VESADisplay.class.cpp | 102 +++++++++++---------- Source/Kernel/Devices/Display/VESADisplay.class.h | 14 ++- .../Kernel/MemoryManager/PageDirectory.class.cpp | 19 ++-- Source/Kernel/MemoryManager/PageDirectory.class.h | 1 + Source/Kernel/TaskManager/V86/V86.ns.cpp | 7 ++ Source/Kernel/TaskManager/V86/V86.ns.h | 1 + Source/Kernel/TaskManager/V86/V86Thread.class.cpp | 4 +- 11 files changed, 92 insertions(+), 94 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 2324857..a59149b 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -94,7 +94,7 @@ void selectVideoMode(SimpleVT& v) { } //v.setCursorCol(40); //v << m.device->getName() << "\n"; - v << "\n"; + v << "\n"; } while (1) { @@ -135,7 +135,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Disp::setText(vgaout); //Create a VT for logging what kernel does - SimpleVT *kvt = new ScrollableVT(25, 80, 10, KVT_FGCOLOR, KVT_BGCOLOR); + SimpleVT *kvt = new ScrollableVT(25, 80, 20, KVT_FGCOLOR, KVT_BGCOLOR); kvt->map(0, 0); *kvt << "Melon is loading..."; @@ -187,8 +187,6 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Usr::load(); Log::log(KL_STATUS, "kmain : User list loaded"); - //PANIC("Good, this works !"); - Process* p = Process::run("/System/Applications/PaperWork.app", 0); if (p == 0) { PANIC("Could not launch PaperWork !"); diff --git a/Source/Kernel/Devices/Display/Display.proto.h b/Source/Kernel/Devices/Display/Display.proto.h index 8401e0b..bccf013 100644 --- a/Source/Kernel/Devices/Display/Display.proto.h +++ b/Source/Kernel/Devices/Display/Display.proto.h @@ -7,6 +7,8 @@ namespace Disp { struct mode_t; } +class VirtualTerminal; + class Display : public Device { public: virtual ~Display() {} diff --git a/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp b/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp index 636a64c..5e2818f 100644 --- a/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp +++ b/Source/Kernel/Devices/Display/GraphicDisplay.proto.cpp @@ -30,35 +30,19 @@ void GraphicDisplay::putChar(u16int line, u16int col, WChar c, u8int color) { for (int y = 0; y < C_FONT_HEIGHT; y++) { u8int pixs = consoleFont[ch][y]; - for (int x = C_FONT_WIDTH - 1; x >= 0; x--) { + for (int x = 7; x >= 0; x--) { putPix(sx + x, sy + y, ((pixs & 1) != 0 ? fgcolor : bgcolor)); pixs = pixs >> 1; } + putPix(sx + 8, sy + y, bgcolor); } } void GraphicDisplay::moveCursor(u16int line, u16int col) { - //If the current cursor position is correct, write there what is supposed to be there - if (m_csrbuff.x >= 0 and m_csrbuff.y >= 0) { - for (int x = 0; x < C_FONT_WIDTH; x++) { - for (int y = 0; y < C_FONT_HEIGHT; y++) { - putPix(m_csrbuff.x + x, m_csrbuff.y + y, m_csrbuff.buff[x][y]); - } - } - } - - //Save the current stuff to the buffer - m_csrbuff.x = col * C_FONT_WIDTH; - m_csrbuff.y = line * C_FONT_HEIGHT; - for (int x = 0; x < C_FONT_WIDTH; x++) { - for (int y = 0; y < C_FONT_HEIGHT; y++) { - m_csrbuff.buff[x][y] = getPix(m_csrbuff.x + x, m_csrbuff.y + y); - } - } //draw some cursor for (int x = 0; x < C_FONT_WIDTH; x++) { - putPix(m_csrbuff.x + x, m_csrbuff.y + 14, 0x00FFFFFF); - putPix(m_csrbuff.x + x, m_csrbuff.y + 15, 0x00777777); + putPix((col * C_FONT_WIDTH) + x, (line * C_FONT_HEIGHT) + 14, 0x00FFFFFF); + putPix((col * C_FONT_WIDTH) + x, (line * C_FONT_HEIGHT) + 15, 0x00000000); } } diff --git a/Source/Kernel/Devices/Display/GraphicDisplay.proto.h b/Source/Kernel/Devices/Display/GraphicDisplay.proto.h index 2f4be98..35bbdae 100644 --- a/Source/Kernel/Devices/Display/GraphicDisplay.proto.h +++ b/Source/Kernel/Devices/Display/GraphicDisplay.proto.h @@ -10,13 +10,7 @@ extern u32int consoleColor[16]; #define C_FONT_HEIGHT 16 class GraphicDisplay : public Display { - struct { - int x, y; - u32int buff[C_FONT_WIDTH][C_FONT_HEIGHT]; - } m_csrbuff; - public: - GraphicDisplay() { m_csrbuff.x = -1; m_csrbuff.y = -1; } virtual void putChar(u16int line, u16int col, WChar c, u8int color); virtual void moveCursor(u16int line, u16int col); }; diff --git a/Source/Kernel/Devices/Display/VESADisplay.class.cpp b/Source/Kernel/Devices/Display/VESADisplay.class.cpp index a1dc7c1..6e46273 100644 --- a/Source/Kernel/Devices/Display/VESADisplay.class.cpp +++ b/Source/Kernel/Devices/Display/VESADisplay.class.cpp @@ -1,6 +1,8 @@ #include "VESADisplay.class.h" #include +#include + extern v86_function_t vesa_int; //in vga-vesa.wtf.asm using namespace Disp; @@ -28,6 +30,7 @@ vbe_controller_info_t VESADisplay::getCtrlrInfo() { } vbe_mode_info_t VESADisplay::getModeInfo(u16int id) { + V86::map(); vbe_mode_info_t *mode = (vbe_mode_info_t*)V86::alloc(sizeof(vbe_mode_info_t)); CMem::memset((u8int*)mode, 0, sizeof(vbe_mode_info_t)); registers_t regs; @@ -47,8 +50,8 @@ void VESADisplay::getModes(Vector &to) { if (modes[i] == 0xFFFF) break; vbe_mode_info_t mode = getModeInfo(modes[i]); - if ((mode.attributes & 0x19) != 0x19) continue; - if (mode.planes != 1) continue; + if ((mode.attributes & 0x90) != 0x90) continue; + if (mode.memory_model != 4 and mode.memory_model != 6) 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]; @@ -62,66 +65,69 @@ bool VESADisplay::setMode(mode_t &mode) { m_currMode = getModeInfo(mode.identifier); registers_t regs; regs.eax = 0x00004F02; - regs.ebx = mode.identifier; + regs.ebx = mode.identifier | 0x4000; V86::run(vesa_int, regs, 0); - return true; -} - -u8int* VESADisplay::memPos(u16int x, u16int y) { - u32int addr = y * m_currMode.pitch + x * (m_currMode.bpp / 8); - - u8int *base = (u8int*)(((m_currMode.physbase & 0xFFFF0000) >> 12) | (m_currMode.physbase & 0x0000FFFF)); - return base + addr; + m_fb = (u8int*)0xF0000000; + for (u32int i = 0; i < (u32int)(m_currMode.Yres * m_currMode.pitch); i += 0x1000) { + kernelPageDirectory->map( + kernelPageDirectory->getPage((u32int)(m_fb + i), true), + (m_currMode.physbase + i) / 0x1000, false, false); + } + m_pixWidth = (m_currMode.bpp + 1) / 8; + return true; } void VESADisplay::clear() { - for (u16int y = 0; y < m_currMode.Yres; y++) { - for (u16int x = 0; x < m_currMode.Xres; x++) { - putPix(x, y, 0x77777777); - } + for (u32int* i = (u32int*)(memPos(0, 0)); i < (u32int*)(memPos(m_currMode.Xres, 0)); i++) { + *i = 0x77777777; } } void VESADisplay::putPix(u16int x, u16int y, u32int c) { - u32int addr = y * m_currMode.pitch + x * (m_currMode.bpp / 8); - int banksize = m_currMode.granularity*1024; - int banknumber = addr / banksize; - int bankoffset = addr % banksize; - - if (banknumber != b) { - registers_t r; - r.eax = 0x4F05; - r.ebx = 0; - r.edx = banknumber; - V86::run(vesa_int, r, 0); - b = banknumber; - } + if (x >= m_currMode.Xres or y >= m_currMode.Yres) return; + union { + u8int* c; + u16int* w; + u32int* d; + } p = {memPos(x, y)}; + if (m_currMode.bpp == 24) { + *p.d = (*p.d & 0xFF000000) | c; + } else if (m_currMode.bpp == 15) { - u8int* a = (u8int*)(0xA0000 + bankoffset); - a[2] = (c >> 16) & 0xFF; - a[1] = (c >> 8) & 0xFF; - a[0] = c & 0xFF; + } } u32int VESADisplay::getPix(u16int x, u16int y) { - u32int addr = y * m_currMode.pitch + x * (m_currMode.bpp / 8); - int banksize = m_currMode.granularity*1024; - int banknumber = addr / banksize; - int bankoffset = addr % banksize; - - if (banknumber != b) { - registers_t r; - r.eax = 0x4F05; - r.ebx = 0; - r.edx = banknumber; - V86::run(vesa_int, r, 0); - b = banknumber; - } - u32int ret; - - u8int* a = (u8int*)(0xA0000 + bankoffset); + u8int* a = memPos(x, y); ret = (a[2] << 16) | (a[1] << 8) | a[0]; return ret; } + +//Advanced functions +void VESADisplay::putChar(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]; + + int y = 0; + for (u8int* p = memPos(sx, sy); p < memPos(sx, sy + C_FONT_HEIGHT); p += m_currMode.pitch) { + union { + u8int* c; + u16int* w; + u32int* d; + } pos = {p + (8 * m_pixWidth)}; + u8int pixs = consoleFont[ch][y]; + if (m_pixWidth == 3) { + *pos.d = (*pos.d & 0xFF000000) | bgcolor; + for (int x = 0; x < 8; x++) { + pos.c -= m_pixWidth; + *pos.d = (*pos.d & 0xFF000000) | ((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 9daf1b9..606c115 100644 --- a/Source/Kernel/Devices/Display/VESADisplay.class.h +++ b/Source/Kernel/Devices/Display/VESADisplay.class.h @@ -44,11 +44,16 @@ class VESADisplay : public GraphicDisplay { vbe_controller_info_t getCtrlrInfo(); vbe_mode_info_t getModeInfo(u16int mode); - u8int* memPos(u16int x, u16int y); - vbe_mode_info_t m_currMode; - int b; + int b, m_pixWidth; + + u8int *m_fb; + + u8int* memPos(u16int x, u16int y) { + u32int addr = y * m_currMode.pitch + x * m_pixWidth; + return ((u8int*)m_fb) + addr; + } public: String getClass(); @@ -60,6 +65,9 @@ class VESADisplay : public GraphicDisplay { void clear(); void putPix(u16int x, u16int y, u32int color); u32int getPix(u16int x, u16int y); + + //Advanced graphical functions, recoded for being optimized + virtual void putChar(u16int line, u16int col, WChar c, u8int color); }; #endif diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.cpp b/Source/Kernel/MemoryManager/PageDirectory.class.cpp index c10f844..064b423 100644 --- a/Source/Kernel/MemoryManager/PageDirectory.class.cpp +++ b/Source/Kernel/MemoryManager/PageDirectory.class.cpp @@ -74,13 +74,17 @@ page_t *PageDirectory::getPage(u32int address, bool make) { } } -void PageDirectory::allocFrame(u32int address, bool is_user, bool is_writable) { - page_t *p = getPage(address, true); - if (address < 0x100000) { +void PageDirectory::map(page_t* p, u32int frame, bool is_user, bool is_writable) { p->present = 1; p->user = (is_user ? 1 : 0); p->rw = (is_writable ? 1 : 0); - p->frame = (address / 0x1000); + p->frame = (frame); +} + +void PageDirectory::allocFrame(u32int address, bool is_user, bool is_writable) { + page_t *p = getPage(address, true); + if (address < 0x100000) { + map(p, address / 0x1000, is_user, is_writable); } else { if (p != 0) PhysMem::allocFrame(p, is_user, is_writable); } @@ -89,12 +93,7 @@ void PageDirectory::allocFrame(u32int address, bool is_user, bool is_writable) { void PageDirectory::freeFrame(u32int address) { page_t *p = getPage(address, false); if (p == 0) return; - if (address < 0x100000) { - p->frame = 0; - p->present = 0; - } else { - PhysMem::freeFrame(p); - } + PhysMem::freeFrame(p); } void PageDirectory::switchTo() { diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.h b/Source/Kernel/MemoryManager/PageDirectory.class.h index 14b78ca..e93524b 100644 --- a/Source/Kernel/MemoryManager/PageDirectory.class.h +++ b/Source/Kernel/MemoryManager/PageDirectory.class.h @@ -26,6 +26,7 @@ struct PageDirectory { PageDirectory(PageDirectory* other); //Clones the other pagedir ~PageDirectory(); page_t *getPage(u32int address, bool make); + void map(page_t *p, u32int frame, bool is_user, bool is_writable); void allocFrame(u32int address, bool is_user, bool is_writable); void freeFrame(u32int address); void switchTo(); diff --git a/Source/Kernel/TaskManager/V86/V86.ns.cpp b/Source/Kernel/TaskManager/V86/V86.ns.cpp index bd16e06..93d51f2 100644 --- a/Source/Kernel/TaskManager/V86/V86.ns.cpp +++ b/Source/Kernel/TaskManager/V86/V86.ns.cpp @@ -12,6 +12,13 @@ void run(v86_function_t& entry, registers_t ®s, u32int data) { while (!ret.finished) Task::currThread()->sleep(10); } +void map(Process* p) { + if (p == 0) p = Task::currProcess(); + for (u32int i = 0x00000; i < 0xFFFFF; i += 0x1000) { + p->getPagedir()->allocFrame(i, true, true); + } +} + u16int allocSeg(u16int length, Process* p) { if (p == 0) p = Task::currProcess(); if (length & 0xF) length = (length & 0xFFFF0) + 0x10; diff --git a/Source/Kernel/TaskManager/V86/V86.ns.h b/Source/Kernel/TaskManager/V86/V86.ns.h index cdeef25..9fa132b 100644 --- a/Source/Kernel/TaskManager/V86/V86.ns.h +++ b/Source/Kernel/TaskManager/V86/V86.ns.h @@ -25,6 +25,7 @@ inline FARPTR LINEAR_TO_FP(void* ptr) { namespace V86 { void run(v86_function_t& entry, registers_t ®s, u32int data); + void map(Process* p = 0); //Maps lower 1MB of virtual memory to physical memory (lower 1MB as well) u16int allocSeg(u16int size, Process* p = 0); void* alloc(u16int size, Process* p = 0); } diff --git a/Source/Kernel/TaskManager/V86/V86Thread.class.cpp b/Source/Kernel/TaskManager/V86/V86Thread.class.cpp index 4b07e98..26fca63 100644 --- a/Source/Kernel/TaskManager/V86/V86Thread.class.cpp +++ b/Source/Kernel/TaskManager/V86/V86Thread.class.cpp @@ -61,9 +61,7 @@ V86Thread::V86Thread(v86_function_t* entry, v86_retval_t* ret, u32int data) : Th m_process->getPagedir()->switchTo(); //Map all lower memory - for (u32int i = 0x00000; i < 0xFFFFF; i += 0x1000) { - m_process->getPagedir()->allocFrame(i, true, true); - } + V86::map(); u16int cs = V86::allocSeg(entry->size); //Alocate segments for the code to run in u8int* codeptr = (u8int*)(FP_TO_LINEAR(cs, 0)); -- cgit v1.2.3