www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/02/13/07:15:29

From: B Hodge <bhodge AT gpu DOT srv DOT ualberta DOT ca>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: DMA under djgpp
Date: 13 Feb 1998 07:52:34 GMT
Organization: University of Alberta
Lines: 66
Message-ID: <6c0u42$b92$1@pulp.ucs.ualberta.ca>
References: <199802130639 DOT WAA14453 AT adit DOT ap DOT net>
NNTP-Posting-Host: gpu2.srv.ualberta.ca
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Nate Eldredge <eldredge AT ap DOT net> wrote:
> Normally you allocate the DMA buffer in conventional memory. That way you
> know its physical location, and that it's contiguous. Allocate 128K, then
> find a 64K boundary within that.

I always hear and see about that approach and get an ill feeling in my
gut.  Wasting 64K like that seemse sorta pointless.  I see how it would
probably require it if the buffer needed to be 64K, as it is next to
impossible to get a perfectly aligned page 64K.

If you don't need 64K, then I have a different approach.  I've used it
numerous times and it works great.  You could use a stack, but for
something this simple, recursion works fine.

1.  allocate a buffer from the conventional memory of the given size
	a.  if could not allocate the memory, then return a fail
2.  if it doesn't cross any page boundaries
	a.  save that buffer, and return success
3.  else if it does fail, then...
	a.  save that buffer for the moment (use a stack or recursion)
	b.  recursively call the buffer allocate function again and hold
		on to the return value
	c.  free the buffer allocated back in 1
	d.  return the return value from the ball in 3b

Here's some pseudo-C code, it ain't the full blown thing and its more of a
real mode C thing, but you get the idea.

void *allocBuffer( unsigned size )
{
	void *ptr;
	void *result;

	/* allocate memory for buffer */
	ptr = malloc( size );

	/* no memory available, can't allocate a buffer */
	if ( ptr == NULL )
		return NULL; /* failure! */

	/* check if the buffer is good */
	if ( !crossPageBoundary( ptr ) )
		return ptr;

	result = allocBuffer( size ); /* recursion */
	free( ptr ); /* free the bad buffer */
	return result; /* return the recursive result */

}

In an actual implementation, see the function
_go32_dpmi_allocate_dos_memory and not malloc.

The recursion is to keep track of any conventional memory that was
allocated but crossed a page boundary and free it after another successive
attempt was made.

Blaine Hodge

 _     ___
#_~`--'__ `===-,   +-----------------------------------+
`.`.     `#.,//    |            Blaine Hodge           +
,_\_\     ## #\    |     bhodge AT gpu DOT srv DOT ualberta DOT ca    |
`__.__    `####\   |       blaine AT cs DOT ualberta DOT ca       |
     ~~\ ,###'~    |  http://www.ualberta.ca/~bhodge/  |
        \##'       +-----------------------------------+

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019