/**************************************************************************/
/*                                                                        */
/*  Multitool II   -   DOS-Hilfsprogramm                Version 1.3r000   */
/*                                                                        */
/*  ©1992 Boris Jakubaschk                                                */
/*                                                                        */
/*  Modul 8 - Verwaltung von "Speicherbündeln"                            */
/*                                                                        */
/**************************************************************************/

#include "MToolDefs.h"

struct MB_ENTRY
       { struct MB_ENTRY *NextMB_Entry;
         struct MB_ENTRY *PrevMB_Entry;
         ULONG            MB_ID;
         ULONG            MB_Len;
         char             MB_String;
       };

struct MB_ENTRY MB_Header =
       { NULL, NULL, ~0, 16, 0 };

ULONG MB_Alloc( ULONG Len, ULONG Attr, ULONG ID )
    {
    struct MB_ENTRY *Mem;
    
    if (Mem = (struct MB_ENTRY *)AllocMem( Len+16, Attr ))
        {
        Mem->NextMB_Entry = MB_Header.NextMB_Entry;
        if (MB_Header.NextMB_Entry != NULL )
            {
            MB_Header.NextMB_Entry->PrevMB_Entry = Mem;
            };
        MB_Header.NextMB_Entry = Mem;
        Mem->PrevMB_Entry = &MB_Header;
        Mem->MB_ID = ID;
        Mem->MB_Len = Len+16;
        return( (ULONG)&(Mem->MB_String) );
        }
    else return( 0 );
    }

void MB_Free( char *Adr, ULONG ID )
    {
    struct MB_ENTRY *Mem;
    
    Mem = (struct MB_ENTRY *)((char *)Adr-16);
    if ( Mem->MB_ID == ID )
        {
        Mem->PrevMB_Entry->NextMB_Entry = Mem->NextMB_Entry;
        if (Mem->NextMB_Entry != NULL) Mem->NextMB_Entry->PrevMB_Entry = Mem->PrevMB_Entry;
        FreeMem( Mem, Mem->MB_Len );
        };
    }

void MB_FreeID( ULONG ID )
    {
    struct MB_ENTRY *Mem;
    struct MB_ENTRY *M;

    Mem = MB_Header.NextMB_Entry;    
    while ( Mem != NULL )
        {
        if ( Mem->MB_ID == ID )
            {
            Mem->PrevMB_Entry->NextMB_Entry = Mem->NextMB_Entry;
            if (Mem->NextMB_Entry != NULL) Mem->NextMB_Entry->PrevMB_Entry = Mem->PrevMB_Entry;
            M = Mem;
            Mem = Mem->NextMB_Entry;
            FreeMem( M, M->MB_Len );
            }
        else
            {
            Mem = Mem->NextMB_Entry;
            };
        };
    }

void MB_FreeAll()
    {
    struct MB_ENTRY *Mem;
    struct MB_ENTRY *M;

    Mem = MB_Header.NextMB_Entry;    
    while ( Mem != NULL )
        {
        Mem->PrevMB_Entry->NextMB_Entry = Mem->NextMB_Entry;
        if (Mem->NextMB_Entry != NULL) Mem->NextMB_Entry->PrevMB_Entry = Mem->PrevMB_Entry;
        M = Mem;
        Mem = Mem->NextMB_Entry;
        FreeMem( M, M->MB_Len );
        };
    }
