mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +00:00
139 lines
4.3 KiB
C#
139 lines
4.3 KiB
C#
//#define COSMOSDEBUG
|
|
|
|
using System;
|
|
|
|
namespace Cosmos.HAL.Drivers
|
|
{
|
|
public class VBEDriver
|
|
{
|
|
|
|
private readonly Core.IOGroup.VBE IO = Core.Global.BaseIOGroups.VBE;
|
|
|
|
private enum RegisterIndex
|
|
{
|
|
DisplayID = 0x00,
|
|
DisplayXResolution,
|
|
DisplayYResolution,
|
|
DisplayBPP,
|
|
DisplayEnable,
|
|
DisplayBankMode,
|
|
DisplayVirtualWidth,
|
|
DisplayVirtualHeight,
|
|
DisplayXOffset,
|
|
DisplayYOffset
|
|
};
|
|
|
|
[Flags]
|
|
private enum EnableValues
|
|
{
|
|
Disabled = 0x00,
|
|
Enabled,
|
|
UseLinearFrameBuffer = 0x40,
|
|
NoClearMemory = 0x80,
|
|
};
|
|
|
|
public VBEDriver(ushort xres, ushort yres, ushort bpp)
|
|
{
|
|
/*
|
|
* XXX Why this simple test is killing the CPU? It is not working in Bochs too... probably it was neither
|
|
* tested... bah! Removing it for now.
|
|
*/
|
|
#if false
|
|
if (HAL.PCI.GetDevice(1234, 1111) == null)
|
|
{
|
|
throw new NotSupportedException("No BGA adapter found..");
|
|
}
|
|
#endif
|
|
|
|
Global.mDebugger.SendInternal($"Creating VBEDriver with Mode {xres}*{yres}@{bpp}");
|
|
VBESet(xres, yres, bpp);
|
|
}
|
|
|
|
private void Write(RegisterIndex index, ushort value)
|
|
{
|
|
IO.VbeIndex.Word = (ushort) index;
|
|
IO.VbeData.Word = value;
|
|
}
|
|
|
|
private void DisableDisplay()
|
|
{
|
|
Global.mDebugger.SendInternal($"Disabling VBE display");
|
|
Write(RegisterIndex.DisplayEnable, (ushort)EnableValues.Disabled);
|
|
}
|
|
|
|
private void SetXResolution(ushort xres)
|
|
{
|
|
Global.mDebugger.SendInternal($"VBE Setting X resolution to {xres}");
|
|
Write(RegisterIndex.DisplayXResolution, xres);
|
|
}
|
|
|
|
private void SetYResolution(ushort yres)
|
|
{
|
|
Global.mDebugger.SendInternal($"VBE Setting Y resolution to {yres}");
|
|
Write(RegisterIndex.DisplayYResolution, yres);
|
|
}
|
|
|
|
private void SetDisplayBPP(ushort bpp)
|
|
{
|
|
Global.mDebugger.SendInternal($"VBE Setting BPP to {bpp}");
|
|
Write(RegisterIndex.DisplayBPP, bpp);
|
|
}
|
|
|
|
private void EnableDisplay(EnableValues EnableFlags)
|
|
{
|
|
//Global.mDebugger.SendInternal($"VBE Enabling display with EnableFlags (ushort){EnableFlags}");
|
|
Write(RegisterIndex.DisplayEnable, (ushort)EnableFlags);
|
|
}
|
|
|
|
public void VBESet(ushort xres, ushort yres, ushort bpp)
|
|
{
|
|
DisableDisplay();
|
|
SetXResolution(xres);
|
|
SetYResolution(yres);
|
|
SetDisplayBPP(bpp);
|
|
/*
|
|
* Re-enable the Display with LinearFrameBuffer and without clearing video memory of previous value
|
|
* (this permits to change Mode without losing the previous datas)
|
|
*/
|
|
EnableDisplay(EnableValues.Enabled | EnableValues.UseLinearFrameBuffer | EnableValues.NoClearMemory);
|
|
}
|
|
|
|
public void SetVRAM(uint index, byte value)
|
|
{
|
|
Global.mDebugger.SendInternal($"Writing to driver memory in position {index} value {value} (as byte)");
|
|
IO.LinearFrameBuffer.Bytes[index] = value;
|
|
}
|
|
|
|
public void SetVRAM(uint index, ushort value)
|
|
{
|
|
Global.mDebugger.SendInternal($"Writing to driver memory in position {index} value {value} (as ushort)");
|
|
IO.LinearFrameBuffer.Words[index] = value;
|
|
}
|
|
|
|
public void SetVRAM(uint index, uint value)
|
|
{
|
|
//Global.mDebugger.SendInternal($"Writing to driver memory in position {index} value {value} (as uint)");
|
|
IO.LinearFrameBuffer.DWords[index] = value;
|
|
}
|
|
|
|
public byte GetVRAM(uint index)
|
|
{
|
|
return IO.LinearFrameBuffer.Bytes[index];
|
|
}
|
|
|
|
public void ClearVRAM(uint value)
|
|
{
|
|
IO.LinearFrameBuffer.Fill(value);
|
|
}
|
|
|
|
public void ClearVRAM(int aStart, int aCount, int value)
|
|
{
|
|
IO.LinearFrameBuffer.Fill(aStart, aCount, value);
|
|
}
|
|
|
|
public void CopyVRAM(int aStart, int[] aData, int aIndex, int aCount)
|
|
{
|
|
IO.LinearFrameBuffer.Copy(aStart, aData, aIndex, aCount);
|
|
}
|
|
}
|
|
}
|