type
  PMemBlock = ^TMemBlock;
  TMemBlock = record
    StartAddr : Integer;
    BlockSize : Integer;
  End;
 
var
  PhisicalMem : Array [0..1023] Of Byte;
  MemBlocks : TList; 
 
function MM_GetMem(ASize : Integer) : Integer;
var
  I : Integer;
  B : PMemBlock;
begin
  Result := -1;
  If ASize < Length(PhisicalMem) Then
    Begin
      
      If MemBlocks.Count = 0 Then
        Begin
          New(B);
          B.StartAddr := Low(PhisicalMem);
          B.BlockSize := ASize;
          MemBlocks,Add(B);
          Result := B.StartAddr;
          Exit;
        End;
         
      
      If MemBlocks[0].StartAddr > ASize Then
        Begin
          New(B);
          B.StartAddr := Low(PhisicalMem);
          B.BlockSize := ASize;
          MemBlocks,Add(B);
          Result := B.StartAddr;
          Exit;
        End;
        
      
      For I := 0 To MemBlocks.Count-2 Do
        If (MemBlocks[I+1].StartAddr - (MemBlocks[i].StartAddr + MemBlocks[i].BlockSize)) >= ASize Then
          Begin
            New(B);
            B.StartAddr := MemBlocks[i].StartAddr + MemBlocks[i].BlockSize + 1;
            B.BlockSize := ASize;
            MemBlocks.Insert(B,I+1);
            Result := B.StartAddr;
            Exit;
          End;
           
      
      If Result = -1 Then
        Begin
          If High() - (MemBlocks[MemBlocks.Count-1].StartAddr + MemBlocks[MemBlocks.Count-1].BlockSize) >= ASize Then
            Begin
              New(B);
              B.StartAddr := MemBlocks[i].StartAddr + MemBlocks[i].BlockSize + 1;
              B.BlockSize := ASize;
              MemBlocks.Insert(B,I+1);
              Result := B.StartAddr;
            End;
        End;
    end;
end;
 
function MM_FreeMem(AAddr : Integer) : Result;
var
  I : Integer;
  B : PMemBlock;
begin
  Result := -1;
  For I := 0 To MemBlocks.Count-1 Do
    If MemBlocks[i].startAddr = AAddr Then
      Begin
        B := MemBlocks[i];
        MemBlocks.Delete(I);
        Dispose(B);
        Result := I;
        Exit;
      End;
end;