Listing 2 Attempts to allocate a real-mode DMA buffer
#define BYTE char typedef unsigned int WORD; typedef unsigned long BIG; #define JUNKCHUNK (128) /* how we will search for physical bounderies. (Must be >= sizeof(JUNK)) */ /* produce a big physical address. This is "large" mode code; " FP_SEG" etc. are Turbo C macros which extract the two parts of an 80x86-style segment-offset pointer. */ #define PHYSICAL(x) ((BIG)((((BIG) (FP_SEG(x)))<<4)+((BIG)FP_OFF(x)))) typedef struct JK struct JK *next; } JUNK; _f void *mustallocdma(WORD size) { BYTE *a; JUNK root, *next, *p; BIG leftover; WORD junksize; root.next=NULL; next=&root; while(1) { a=mustalloc(size); /* mustalloc==malloc, but aborts if failure; the function exists this way or via the break below at success.*/ if ( (leftover=(PHYSICAL(a) & 0xffff)) + ((BIG) size) >= 0x10000) { /* it's no good. */ if ( (junksize = 0x10000-leftover) < JUNKCHUNK) junksize=JUNKCHUNK; /* avoid endless teeny-tiny manipulations. */ free(a); next->next=mustalloc(junksize); next=next->next; } else break; /* success! */ } /* free debris. */ next=root.next; while(next) p=next; next=next->next; free(p); } return a; } /* End of File */