/*************************************************************************** * 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 #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); }