/***************************************************************************
*	NAME:  MEMALLOC.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 <conio.h>
#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;

unsigned long
UltraMaxAlloc(void)
{
unsigned long size = 0L;
unsigned long pool_size;
unsigned long ptr;

ptr = _gf1_data.free_mem;

while(ptr != 0L)
	{
	/* See if this buffer will fit */
	pool_size = UltraPeekLong(ptr+SIZE_OFFSET);
	if (pool_size > size)
		{
		size = pool_size;
		}
	ptr = UltraPeekLong(ptr+NEXT_OFFSET);
	}
return(size);
}

int
UltraMemAlloc(unsigned long size,unsigned long far *location)
{
unsigned long ptr;
unsigned long pool_size;
unsigned long size_left;
unsigned long prev;
unsigned long next;

/* Round size up to next 32 byte boundary */
size += 31;
size &= -32L;

ptr = _gf1_data.free_mem;

while(ptr != 0L)
	{
	/* See if this buffer will fit */
	pool_size = UltraPeekLong(ptr+SIZE_OFFSET);
	if (pool_size >= size)
		{
		size_left = pool_size - size;
		if (size_left < MEM_HEADER_SIZE)
			{
			next = UltraPeekLong(ptr+NEXT_OFFSET);
			prev = UltraPeekLong(ptr+PREV_OFFSET);

			if (next != 0L)
				UltraPokeLong(next+PREV_OFFSET,prev);

			if (prev != 0L)
				UltraPokeLong(prev+NEXT_OFFSET,next);
			else
				_gf1_data.free_mem = next;
			
			*location = ptr;
			}
		else
			{
			/* adjust size of this pool. */
			UltraPokeLong(ptr+SIZE_OFFSET,pool_size-size);
			/* calculate new address */
			*location = ptr + (pool_size-size);
			}
		return(ULTRA_OK);
		}
	ptr = UltraPeekLong(ptr+NEXT_OFFSET);	/* next please */
	}

/* should we return the max hole size in location ???? */
return(NO_MEMORY);
}

