mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
214 lines
6.7 KiB
C#
214 lines
6.7 KiB
C#
#define OLD_HEAP
|
|
// BE CAREFUL: enabling/disabling the OLD_HEAP define must happen in HMI.cs as well!
|
|
|
|
#if !OLD_HEAP
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace Cosmos.Core {
|
|
// This class must be static, as for creating objects, we needd the hea
|
|
public static class Heap
|
|
{
|
|
public static bool EnableDebug = true;
|
|
//GC variables
|
|
|
|
public static bool SkipRalloc = true;
|
|
public static uint LastMallocAddr;
|
|
|
|
|
|
private static uint mStartAddress;
|
|
private static uint mEndOfRam;
|
|
internal static uint xAddr;
|
|
internal static bool IsInitalised = false;
|
|
|
|
public static uint GetMemoryUse()
|
|
{
|
|
return mStartAddress;
|
|
}
|
|
|
|
public static void DecreaseMemoryUse(uint aSize)
|
|
{
|
|
|
|
mStartAddress -= aSize;
|
|
if (mStartAddress < HMI.ProtectArea)
|
|
{
|
|
HMI.CauseProgramFault("[ Heap Error: Memory Access Violation ]");
|
|
}
|
|
else
|
|
{
|
|
LastMallocAddr = mStartAddress;
|
|
}
|
|
}
|
|
|
|
|
|
internal static void Initialize()
|
|
{
|
|
if (IsInitalised == false)
|
|
{
|
|
mEndOfRam = ((Cosmos.Core.CPU.GetAmountOfRAM() - 1) * 1048576);
|
|
mStartAddress = Cosmos.Core.CPU.GetEndOfKernel();
|
|
mStartAddress += 1024; // leave at 1024 bytes between kernel and User space;
|
|
IsInitalised = true;
|
|
}
|
|
}
|
|
|
|
public static uint MemAlloc(uint aLength)
|
|
{
|
|
Initialize();
|
|
xAddr = 0;
|
|
|
|
if (SkipRalloc == false)
|
|
{
|
|
xAddr = HMI.ReAlloc(aLength);
|
|
}
|
|
|
|
if (xAddr == 0)
|
|
{
|
|
xAddr = mStartAddress;
|
|
|
|
if (mStartAddress >= mEndOfRam)
|
|
{
|
|
HMI.HeapOutOfMemory();
|
|
}
|
|
|
|
else
|
|
{
|
|
mStartAddress += aLength;
|
|
Cosmos.Core.Global.CPU.ZeroFill(xAddr, aLength);
|
|
if (HMI.IsInitalised == true)//Prevent it from interfering with unmanaged memory before boot
|
|
{
|
|
HMI.AddBlock(xAddr, aLength);
|
|
}
|
|
if (SkipRalloc == false)
|
|
{
|
|
LastMallocAddr = xAddr;//Update this when we allocate a new block not extend an old block
|
|
}
|
|
SkipRalloc = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return xAddr;
|
|
}
|
|
|
|
public static void xHeapExcessUseFault()
|
|
{
|
|
HMI.HeapExcessUseFault();
|
|
}
|
|
|
|
}
|
|
}
|
|
#else
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Cosmos.Common;
|
|
|
|
namespace Cosmos.Core
|
|
{
|
|
// This class must be static, as for creating objects, we needd the hea
|
|
public static class Heap
|
|
{
|
|
public static bool EnableDebug = true;
|
|
private static uint mStart;
|
|
private static uint mStartAddress;
|
|
private static uint mLength;
|
|
private static uint mEndOfRam;
|
|
|
|
private static void DoInitialize(uint aStartAddress, uint aEndOfRam)
|
|
{
|
|
mStart = mStartAddress = aStartAddress + (4 - (aStartAddress % 4));
|
|
mLength = aEndOfRam - aStartAddress;
|
|
mLength = (mLength / 4) * 4;
|
|
ClearMemory(aStartAddress, mLength);
|
|
|
|
mStartAddress += 1024;
|
|
mEndOfRam = aEndOfRam;
|
|
mStartAddress = (mStartAddress / 4) * 4;
|
|
mLength -= 1024;
|
|
//UpdateDebugDisplay();
|
|
}
|
|
|
|
private static bool mInitialized = false;
|
|
internal static void Initialize()
|
|
{
|
|
if (!mInitialized)
|
|
{
|
|
mInitialized = true;
|
|
DoInitialize(CPU.GetEndOfKernel(), (CPU.GetAmountOfRAM() - 1) * 1024 * 1024);
|
|
//DoInitialize(4 * 1024 * 1024, 16 * 1024 * 1024);
|
|
}
|
|
}
|
|
|
|
private static void ClearMemory(uint aStartAddress, uint aLength)
|
|
{
|
|
//TODO: Move to memory. Internal access only...
|
|
CPU.ZeroFill(aStartAddress, aLength);
|
|
}
|
|
|
|
//private static bool mDebugDisplayInitialized = false;
|
|
|
|
// this method displays the used/total memory of the heap on the first line of the text screen
|
|
private static void UpdateDebugDisplay()
|
|
{
|
|
//if (EnableDebug)
|
|
//{
|
|
// if (!mDebugDisplayInitialized)
|
|
// {
|
|
// mDebugDisplayInitialized = true;
|
|
// int xOldPositionLeft = Console.CursorLeft;
|
|
// int xOldPositionTop = Console.CursorTop;
|
|
// Console.CursorLeft = 0;
|
|
// Console.CursorTop = 0;
|
|
// Console.Write("[Heap Usage: ");
|
|
// NumberHelper.WriteNumber(mStartAddress,
|
|
// 32);
|
|
// Console.Write("/");
|
|
// NumberHelper.WriteNumber(mEndOfRam,
|
|
// 32);
|
|
// Console.Write("] bytes");
|
|
// while (Console.CursorLeft < (Console.WindowWidth-1))
|
|
// {
|
|
// Console.Write(" ");
|
|
// }
|
|
// Console.CursorLeft = xOldPositionLeft;
|
|
// Console.CursorTop = xOldPositionTop;
|
|
// }
|
|
// else
|
|
// {
|
|
// int xOldPositionLeft = Console.CursorLeft;
|
|
// int xOldPositionTop = Console.CursorTop;
|
|
// Console.CursorLeft = 13;
|
|
// Console.CursorTop = 0;
|
|
// NumberHelper.WriteNumber(mStartAddress,
|
|
// 32);
|
|
// Console.CursorLeft = xOldPositionLeft;
|
|
// Console.CursorTop = xOldPositionTop;
|
|
// }
|
|
//}
|
|
}
|
|
|
|
public static uint MemAlloc(uint aLength)
|
|
{
|
|
Initialize();
|
|
uint xTemp = mStartAddress;
|
|
|
|
if ((xTemp + aLength) > (mStart + mLength))
|
|
{
|
|
Console.WriteLine("Too large memory block allocated!");
|
|
NumberHelper.WriteNumber(aLength, 32);
|
|
while (true)
|
|
;
|
|
}
|
|
mStartAddress += aLength;
|
|
UpdateDebugDisplay();
|
|
ClearMemory(xTemp, aLength);
|
|
return xTemp;
|
|
}
|
|
}
|
|
}
|
|
#endif
|