#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 */