diff --git a/source/Cosmos.Core/BaseIOGroups.cs b/source/Cosmos.Core/BaseIOGroups.cs
index 23b989644..d4d4ecd93 100644
--- a/source/Cosmos.Core/BaseIOGroups.cs
+++ b/source/Cosmos.Core/BaseIOGroups.cs
@@ -43,6 +43,6 @@ namespace Cosmos.Core {
///
/// VBE.
///
- public readonly IOGroup.VBE VBE = new IOGroup.VBE();
+ public readonly IOGroup.VBEIOGroup VBE = new IOGroup.VBEIOGroup();
}
}
diff --git a/source/Cosmos.Core/Bootstrap.cs b/source/Cosmos.Core/Bootstrap.cs
index 09fd9a5e1..270d62146 100644
--- a/source/Cosmos.Core/Bootstrap.cs
+++ b/source/Cosmos.Core/Bootstrap.cs
@@ -1,6 +1,6 @@
namespace Cosmos.Core
{
- public static class Bootstrap
+ public unsafe static class Bootstrap
{
// See note in Global - these are a "hack" for now so
// we dont force static init of Global, and it "pulls" these later till
@@ -9,6 +9,11 @@
// Has to be static for now, ZeroFill gets called before the Init.
static public readonly CPU CPU = new CPU();
+ public static Multiboot.Header* header;
+
+ public static VBE.ModeInfo* modeinfo;
+ public static VBE.ControllerInfo* controllerinfo;
+
// Bootstrap is a class designed only to get the essentials done.
// ie the stuff needed to "pre boot". Do only the very minimal here.
// IDT, PIC, and Float
@@ -32,6 +37,11 @@
*/
CPU.InitFloat();
+ header = (Multiboot.Header*)Multiboot.GetMBIAddress();
+
+ modeinfo = (Core.VBE.ModeInfo*)header->vbeModeInfo;
+ controllerinfo = (Core.VBE.ControllerInfo*)header->vbeControlInfo;
+
// Managed_Memory_System.ManagedMemory.Initialize();
// Managed_Memory_System.ManagedMemory.SetUpMemoryArea();
}
diff --git a/source/Cosmos.Core/IOGroup/VBE.cs b/source/Cosmos.Core/IOGroup/VBE.cs
index 6e973d3c6..17ed31685 100644
--- a/source/Cosmos.Core/IOGroup/VBE.cs
+++ b/source/Cosmos.Core/IOGroup/VBE.cs
@@ -10,7 +10,7 @@ namespace Cosmos.Core.IOGroup
///
/// VBE class.
///
- public class VBE : IOGroup
+ public class VBEIOGroup : IOGroup
{
///
/// Index IOPort.
@@ -27,7 +27,7 @@ namespace Cosmos.Core.IOGroup
///
/// Frame buffer memory block.
///
- public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1920 * 1200 * 4);
+ public MemoryBlock LinearFrameBuffer;
//public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1024 * 768 * 4);
}
}
diff --git a/source/Cosmos.Core/Multiboot.cs b/source/Cosmos.Core/Multiboot.cs
new file mode 100644
index 000000000..c09760707
--- /dev/null
+++ b/source/Cosmos.Core/Multiboot.cs
@@ -0,0 +1,199 @@
+using IL2CPU.API.Attribs;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Cosmos.Core
+{
+ ///
+ /// Used for Multiboot parsing
+ ///
+ public class Multiboot
+ {
+ /// ///
+ /// Get Multiboot address. Plugged.
+ ///
+ /// The Multiboot Address
+ [PlugMethod(PlugRequired = true)]
+ public static uint GetMBIAddress() => throw null;
+
+ [StructLayout(LayoutKind.Explicit, Size = 88)]
+ public unsafe struct Header
+ {
+ [FieldOffset(0)]
+ public uint Flags;
+ [FieldOffset(4)]
+ public uint mem_lower;
+ [FieldOffset(8)]
+ public uint mem_upper;
+ [FieldOffset(12)]
+ public uint boot_device;
+ [FieldOffset(16)]
+ public uint cmdline;
+ [FieldOffset(20)]
+ public uint mods_count;
+ [FieldOffset(24)]
+ public uint mods_addr;
+ [FieldOffset(28)]
+ public fixed uint syms[4];
+ [FieldOffset(44)]
+ public uint memMapLength;
+ [FieldOffset(48)]
+ public uint memMapAddress;
+ [FieldOffset(52)]
+ public uint drivesLength;
+ [FieldOffset(56)]
+ public uint drivesAddress;
+ [FieldOffset(60)]
+ public uint configTable;
+ [FieldOffset(68)]
+ public uint apmTable;
+ [FieldOffset(72)]
+ public uint vbeControlInfo;
+ [FieldOffset(76)]
+ public uint vbeModeInfo;
+ [FieldOffset(80)]
+ public uint vbeMode;
+ [FieldOffset(82)]
+ public uint vbeInterfaceSeg;
+ [FieldOffset(84)]
+ public uint vbeInterfaceOff;
+ [FieldOffset(86)]
+ public uint vbeInterfaceLength;
+ }
+ }
+
+ public unsafe static class VBE
+ {
+
+ static uint VBEINFO_PRESENT = (1 << 11);
+
+ /// ///
+ /// Check in Multiboot if VBE is available
+ ///
+ /// True if is available, false if not
+ public static bool IsAvailable()
+ {
+ if ((Bootstrap.header->Flags & VBEINFO_PRESENT) == 0)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ /// ///
+ /// Get VBE Modeinfo structure
+ ///
+ public static ModeInfo getModeInfo()
+ {
+ return *Bootstrap.modeinfo;
+ }
+
+ /// ///
+ /// Get the linear frame buffer address from VBE ModeInfo structure
+ ///
+ /// the offset in an uint
+ public static uint getLfbOffset()
+ {
+ return Bootstrap.modeinfo->framebuffer;
+ }
+
+ [StructLayout(LayoutKind.Explicit, Size = 36)]
+ public struct ControllerInfo
+ {
+ [FieldOffset(0)]
+ public uint vbeSignature;
+ [FieldOffset(4)]
+ public ushort vbeVersion;
+ [FieldOffset(6)]
+ public uint oemStringPtr;
+ [FieldOffset(10)]
+ public uint capabilities;
+ [FieldOffset(14)]
+ public uint videoModePtr;
+ [FieldOffset(18)]
+ public ushort totalmemory;
+ [FieldOffset(20)]
+ public ushort oemSoftwareRev;
+ [FieldOffset(24)]
+ public uint oemVendorNamePtr;
+ [FieldOffset(28)]
+ public uint oemProductNamePtr;
+ [FieldOffset(32)]
+ public uint oemProductRevPtr;
+ }
+
+ [StructLayout(LayoutKind.Explicit, Size = 256)]
+ public struct ModeInfo
+ {
+ [FieldOffset(0)]
+ public ushort attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
+ [FieldOffset(2)]
+ public byte window_a; // deprecated
+ [FieldOffset(3)]
+ public byte window_b; // deprecated
+ [FieldOffset(4)]
+ public ushort granularity; // deprecated; used while calculating bank numbers
+ [FieldOffset(6)]
+ public ushort window_size;
+ [FieldOffset(8)]
+ public ushort segment_a;
+ [FieldOffset(10)]
+ public ushort segment_b;
+ [FieldOffset(12)]
+ public uint win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode
+ [FieldOffset(16)]
+ public ushort pitch; // number of bytes per horizontal line
+ [FieldOffset(18)]
+ public ushort width; // width in pixels
+ [FieldOffset(20)]
+ public ushort height; // height in pixels
+ [FieldOffset(22)]
+ public byte w_char; // unused...
+ [FieldOffset(23)]
+ public byte y_char; // ...
+ [FieldOffset(24)]
+ public byte planes;
+ [FieldOffset(25)]
+ public byte bpp; // bits per pixel in this mode
+ [FieldOffset(26)]
+ public byte banks; // deprecated; total number of banks in this mode
+ [FieldOffset(27)]
+ public byte memory_model;
+ [FieldOffset(28)]
+ public byte bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
+ [FieldOffset(29)]
+ public byte image_pages;
+ [FieldOffset(30)]
+ public byte reserved0;
+ [FieldOffset(31)]
+ public byte red_mask;
+ [FieldOffset(32)]
+ public byte red_position;
+ [FieldOffset(33)]
+ public byte green_mask;
+ [FieldOffset(34)]
+ public byte green_position;
+ [FieldOffset(35)]
+ public byte blue_mask;
+ [FieldOffset(36)]
+ public byte blue_position;
+ [FieldOffset(37)]
+ public byte reserved_mask;
+ [FieldOffset(38)]
+ public byte reserved_position;
+ [FieldOffset(39)]
+ public byte direct_color_attributes;
+ [FieldOffset(40)]
+ public uint framebuffer; // physical address of the linear frame buffer; write here to draw to the screen
+ [FieldOffset(44)]
+ public uint off_screen_mem_off;
+ [FieldOffset(48)]
+ public ushort off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen
+ [FieldOffset(50)]
+ public fixed byte reserved1[206];
+ }
+ }
+}
diff --git a/source/Cosmos.Core_Asm/Multiboot/MultibootAsm.cs b/source/Cosmos.Core_Asm/Multiboot/MultibootAsm.cs
new file mode 100644
index 000000000..f77597cf4
--- /dev/null
+++ b/source/Cosmos.Core_Asm/Multiboot/MultibootAsm.cs
@@ -0,0 +1,14 @@
+using XSharp.Assembler;
+using XSharp;
+using CPUx86 = XSharp.Assembler.x86;
+
+namespace Cosmos.Core_Asm
+{
+ public class MultibootAsm : AssemblerMethod
+ {
+ public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
+ {
+ new CPUx86.Push { DestinationRef = ElementReference.New("MultiBootInfo_Structure"), DestinationIsIndirect = true };
+ }
+ }
+}
diff --git a/source/Cosmos.Core_Asm/MultibootImpl.cs b/source/Cosmos.Core_Asm/MultibootImpl.cs
new file mode 100644
index 000000000..d3c9226ac
--- /dev/null
+++ b/source/Cosmos.Core_Asm/MultibootImpl.cs
@@ -0,0 +1,12 @@
+using Cosmos.Core;
+using IL2CPU.API.Attribs;
+
+namespace Cosmos.Core_Asm
+{
+ [Plug(Target = typeof(Multiboot))]
+ public class MultibootImpl
+ {
+ [PlugMethod(Assembler = typeof(MultibootAsm))]
+ public static uint GetMBIAddress() => throw null;
+ }
+}
diff --git a/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs b/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs
index 658316ef7..5cb63e93d 100644
--- a/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs
+++ b/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs
@@ -12,7 +12,7 @@ namespace Cosmos.HAL.Drivers
public class VBEDriver
{
- private static readonly VBE IO = Core.Global.BaseIOGroups.VBE;
+ private static readonly VBEIOGroup IO = Core.Global.BaseIOGroups.VBE;
ManagedMemoryBlock lastbuffer;
///
@@ -76,10 +76,19 @@ namespace Cosmos.HAL.Drivers
/// BPP (color depth).
public VBEDriver(ushort xres, ushort yres, ushort bpp)
{
- Global.mDebugger.SendInternal($"Creating VBEDriver with Mode {xres}*{yres}@{bpp}");
- //IO.LinearFrameBuffer = new MemoryBlock(0xE0000000, (uint)xres * yres * (uint)(bpp / 8));
- lastbuffer = new ManagedMemoryBlock(1920 * 1200 * 4);
- VBESet(xres, yres, bpp);
+ if (VBE.IsAvailable())
+ {
+ Global.mDebugger.SendInternal($"Creating VBE VESA driver with Mode {xres}*{yres}@{bpp}");
+ IO.LinearFrameBuffer = new MemoryBlock(VBE.getLfbOffset(), (uint)xres * yres * (uint)(bpp / 8));
+ lastbuffer = new ManagedMemoryBlock((uint)xres * yres * (uint)(bpp / 8));
+ }
+ else
+ {
+ Global.mDebugger.SendInternal($"Creating VBE BGA driver with Mode {xres}*{yres}@{bpp}");
+ IO.LinearFrameBuffer = new MemoryBlock(0xE0000000, 1920 * 1200 * 4);
+ lastbuffer = new ManagedMemoryBlock(1920 * 1200 * 4);
+ VBESet(xres, yres, bpp);
+ }
}
///
diff --git a/source/Cosmos.System2/Graphics/FullScreenCanvas.cs b/source/Cosmos.System2/Graphics/FullScreenCanvas.cs
index 4beffad0c..2395c13d6 100644
--- a/source/Cosmos.System2/Graphics/FullScreenCanvas.cs
+++ b/source/Cosmos.System2/Graphics/FullScreenCanvas.cs
@@ -66,7 +66,7 @@ namespace Cosmos.System.Graphics
{
return new SVGAIICanvas();
}
- else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null)
+ else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null || Core.VBE.IsAvailable())
{
return new VBECanvas();
}
@@ -88,7 +88,7 @@ namespace Cosmos.System.Graphics
{
return new SVGAIICanvas(mode);
}
- else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null)
+ else if (BGAExists() || PCI.GetDevice((VendorID)0x80EE, (DeviceID)0xBEEF) != null || Core.VBE.IsAvailable())
{
return new VBECanvas(mode);
}
diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs
index a38d5a735..1cd9bc5a5 100644
--- a/source/Cosmos.System2/Graphics/VBECanvas.cs
+++ b/source/Cosmos.System2/Graphics/VBECanvas.cs
@@ -44,6 +44,13 @@ namespace Cosmos.System.Graphics
{
Global.mDebugger.SendInternal($"Creating new VBEScreen() with mode {aMode.Columns}x{aMode.Rows}x{(uint)aMode.ColorDepth}");
+ if (Core.VBE.IsAvailable())
+ {
+ Core.VBE.ModeInfo ModeInfo = Core.VBE.getModeInfo();
+ aMode = new Mode(ModeInfo.width, ModeInfo.height, (ColorDepth)ModeInfo.bpp);
+ Global.mDebugger.SendInternal($"Detected VBE VESA with {aMode.Columns}x{aMode.Rows}x{(uint)aMode.ColorDepth}");
+ }
+
ThrowIfModeIsNotValid(aMode);
_VBEDriver = new VBEDriver((ushort)aMode.Columns, (ushort)aMode.Rows, (ushort)aMode.ColorDepth);
@@ -122,6 +129,7 @@ namespace Cosmos.System.Graphics
new Mode(1024, 768, ColorDepth.ColorDepth32),
/* The so called HD-Ready resolution */
new Mode(1280, 720, ColorDepth.ColorDepth32),
+ new Mode(1280, 768, ColorDepth.ColorDepth32),
new Mode(1280, 1024, ColorDepth.ColorDepth32),
/* A lot of HD-Ready screen uses this instead of 1280x720 */
new Mode(1366, 768, ColorDepth.ColorDepth32),