/***************************************************************************
* NAME: MEMFREE.C
** COPYRIGHT:
** "Copyright (c) 1992, by FORTE
**
** "This software is furnished under a license and may be used,
** copied, or disclosed only in accordance with the terms of such
** license and with the inclusion of the above copyright notice.
** This software or any other copies thereof may not be provided or
** otherwise made available to any other person. No title to and
** ownership of the software is hereby transfered."
****************************************************************************
* CREATION DATE: 11/18/92
*--------------------------------------------------------------------------*
* VERSION DATE NAME DESCRIPTION
*> 1.0 11/18/92 Original
***************************************************************************/
#include <dos.h>
#include "forte.h"
#include "gf1proto.h"
#include "osproto.h"
#include "gf1hware.h"
#include "gf1os.h"
#include "ultraerr.h"
extern ULTRA_DATA _gf1_data;
static void combine_mem(void)
{
unsigned long ptr;
unsigned long next;
unsigned long next_next;
unsigned long pool_size;
unsigned long next_size;
ptr = _gf1_data.free_mem;
while (ptr != 0)
{
next = UltraPeekLong(ptr+NEXT_OFFSET);
pool_size = UltraPeekLong(ptr+SIZE_OFFSET);
if ((ptr+pool_size) == next)
{
next_next = UltraPeekLong(next+NEXT_OFFSET);
next_size = UltraPeekLong(next+SIZE_OFFSET);
pool_size += next_size;
UltraPokeLong(ptr+SIZE_OFFSET,pool_size);
UltraPokeLong(ptr+NEXT_OFFSET,next_next);
if (next_next != 0L)
UltraPokeLong(next_next+PREV_OFFSET,ptr);
else
ptr = 0L; /* end of list */
}
else
ptr = UltraPeekLong(ptr+NEXT_OFFSET); /* next please */
}
}
int
UltraMemFree(unsigned long size,unsigned long location)
{
unsigned long ptr;
unsigned long prev;
unsigned long next;
int flag = FALSE;
/* Round size up to next 32 byte boundary */
size += 31;
size &= -32L;
ptr = _gf1_data.free_mem;
if (ptr == 0L)
{
/* No free ram. Make this the first in the list */
_gf1_data.free_mem = location;
UltraPokeLong(location+NEXT_OFFSET,0L);
UltraPokeLong(location+PREV_OFFSET,0L);
UltraPokeLong(location+SIZE_OFFSET,size);
flag = TRUE;
}
else
{
while (ptr != 0L && !flag)
{
next = UltraPeekLong(ptr+NEXT_OFFSET);
prev = UltraPeekLong(ptr+PREV_OFFSET);
if (location < ptr)
{
if (prev == 0L)
_gf1_data.free_mem = location;
else
UltraPokeLong(prev+NEXT_OFFSET,location);
UltraPokeLong(location+NEXT_OFFSET,ptr);
UltraPokeLong(location+PREV_OFFSET,prev);
UltraPokeLong(location+SIZE_OFFSET,size);
UltraPokeLong(ptr+PREV_OFFSET,location);
flag = TRUE;
}
else
{
if (next == 0L)
{
UltraPokeLong(ptr+NEXT_OFFSET,location);
UltraPokeLong(location+NEXT_OFFSET,0L);
UltraPokeLong(location+PREV_OFFSET,ptr);
UltraPokeLong(location+SIZE_OFFSET,size);
flag = TRUE;
}
}
ptr = UltraPeekLong(ptr+NEXT_OFFSET); /* next please */
}
}
if (flag)
{
/* combine blocks here ... */
combine_mem();
return(ULTRA_OK);
}
else
return(CORRUPT_MEM);
}