576 #include #include #include void far *aligned_malloc(long len) { void far *ptr; unsigned int far *orig_ptr; unsigned seg, orig_seg, orig_off; long lin_addr; /* Allocate double the required space */ if(allocmem((len * 2L + 32L + 15L) >> 4, &seg) != -1) return NULL; /* Compute a new pointer to the buffer such that the next "len" bytes */ /* do not cross a page boundary, and the offset is zero */ /* (as required by DMA transfers) */ orig_off = 0; orig_seg = seg; /* reserve 4 bytes for the original pointer */ lin_addr = (orig_seg * 16L) + orig_off + 4L; if((lin_addr & 0xF0000L) != ((lin_addr+len-1) & 0xF0000L)) lin_addr = (lin_addr+len-1)&0xF0000L; else lin_addr = (lin_addr+15) & 0xFFFF0L; seg = (unsigned int)(lin_addr/16); orig_ptr = (unsigned far *)MK_FP(seg-1,0x000C); orig_ptr[0] = orig_off; orig_ptr[1] = orig_seg; ptr = MK_FP(seg, 0); /* printf("Original: %04x:%04x, New: %04x:%04x, Linear: %05lx\n", orig_seg,orig_off,FP_SEG(ptr),FP_OFF(ptr),lin_addr); */ return ptr; } void aligned_free(void far *ptr) { if(ptr!=NULL) { unsigned far *old_ptr=(unsigned far *)MK_FP(FP_SEG(ptr)-1,0x000c); /* printf("Freeing: %04x:%04x, Ptr: %04x:%04x\n", FP_SEG(old_ptr),FP_OFF(old_ptr),FP_SEG(ptr),FP_OFF(ptr)); */ farfree(MK_FP(old_ptr[1],old_ptr[0])); } } . 0