From: B Hodge 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 Precedence: bulk Nate Eldredge 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/ | \##' +-----------------------------------+