/***************************************************************************
*	NAME:  UALLOC.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	06/01/93		Original
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <dos.h>
#include "forte.h"
#include "extern.h"
#include "extern16.h"
#include "utility.h"

#ifdef METAWARE
#define farfree _ffree
#define farmalloc _fmalloc
#endif

void far *
MallocAlignedBuff(buffsize)
unsigned int buffsize;
{
void far *check_ptr;
unsigned long s_20bit,e_20bit;
#ifndef ADDR20BIT
void far *eptr;
unsigned int sseg,soff;
unsigned int saddr,tcount;
unsigned int eaddr;
#endif
unsigned int spage,epage;
unsigned int size;
int i;
void far *save_ptrs[10];
int buffnum;

/* Now get a CONTIGUOUS buffer. Make sure it doesn't cross page */
/* boundaries */

for (i=0;i<10;i++)
	save_ptrs[i] = NULL;

for (buffnum=0;buffnum<10;buffnum++)
	{
	check_ptr = farmalloc((long)buffsize);
	if (check_ptr == NULL)
		{
		for (i=0;i<10;i++)
			if (save_ptrs[i] != NULL)
				farfree(save_ptrs[i]);
		return(NULL);
		}

	/* Convert the pc address to a 20 bit physical address that the DMA */
	/* controller needs */
#ifdef ADDR20BIT
	s_20bit = (unsigned long)check_ptr;
#else
	sseg = FP_SEG(check_ptr);
	soff = FP_OFF(check_ptr);
	s_20bit = (unsigned long)((((unsigned long)sseg)<< 4) + (unsigned long)soff);
#endif

	/* Convert the pc address to a 20 bit physical address that the DMA */
	/* controller needs */
	e_20bit = s_20bit + buffsize;

	spage = (unsigned int)((s_20bit & 0xffff0000L)>>16);
	epage = (unsigned int)((e_20bit & 0xffff0000L)>>16);

	if (spage != epage)		/* doesn't fit on a page ... */
		{
		farfree(check_ptr);
		/* Alloc whatever is left on this page.... */
		size = (unsigned int)(s_20bit & 0x0000ffff);
		size = (0xffff - size) + 1;
		save_ptrs[buffnum] = farmalloc((long)size);
		}
	else
		break;
	}

for (i=0;i<10;i++)
	if (save_ptrs[i] != NULL)
		farfree(save_ptrs[i]);
return(check_ptr);
}


