From: Chris Frolik Newsgroups: comp.os.msdos.djgpp Subject: buffers in conventional memory used in interrupts Date: Tue, 29 Jul 1997 02:50:36 -0500 Organization: IndyNet - Indys Internet Gateway (info AT indy DOT net) Lines: 109 Message-ID: <33DDA0CC.7A28@indy.net> NNTP-Posting-Host: ip75-28.ts.indy.net Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk I need to call a software interrupt from my DJGPP program. I already know how to allocate conventional memory and use __dpmi_int. The problem I have is that I have a struct, for example: struct buffer { int size; void *pointer_to_more_data; /* ... */ }; (This is just a simple example struct to illustrate my problem) To call my interrupt, I need ES:SI to point to this struct. I think I know how to do this. For example, here is some sample code that uses the above structure: /* begin sample code */ #include #include #include #define DATA_BUFFER_SIZE 32 /* 32 bytes */ int main(void) { struct buffer b1; int paragraphs; /* used with __dpmi_allocate_dos_memory */ int segment, selector; /* also used with __dpmi_allocate_dos_memory */ int i; /* loop counter */ __dpmi_regs registers; b1.size = sizeof(struct buffer) + DATA_BUFFER_SIZE; b1.pointer_to_more_data = (char *) malloc(DATA_BUFFER_SIZE); if (b1.pointer_to_more_data == NULL) { printf("\nError allocating memory.\n"); printf("Terminating program.\n"); exit(1); } /* ZERO the memory: */ for (i=0 ; i>4), so: */ paragraphs = ((b1.size+15)>>4); segment = __dpmi_allocate_dos_memory(paragraphs, &selector); if (segment == -1) { /* error */ printf("\nERROR allocating conventional memory.\n"); printf("Program terminated.\n"); free(b1.pointer_to_more_data); exit(1); } /* get the segment:offset into ES:SI */ registers.x.es = segment; registers.x.si = 0; /* Now, we need to move the struct AND the data buffer to conventional memory: */ dosmemput(&b1, sizeof(struct buffer), segment * 16); /* offset is 0 */ dosmemput(b1.pointer_to_more_data, DATA_BUFFER_SIZE, segment * 16 + sizeof(struct buffer)); /* HERE is the problem -- the pointer_to_more_data still points to malloc()ed memory, while it *should* point to the data in the conventional memory that was allocated with __dpmi_allocate_dos_memory */ /* Finally, call the interrupt: */ registers.x.bx = 4; /* function 4 of interrupt 0x7A */ __dpmi_int(0x7A, ®isters); /* Free the memory and exit */ free(b1.pointer_to_more_data); if (__dpmi_free_dos_memory(selector) == -1) { printf("\nERROR freeing conventional memory.\n"); exit(1); } return 0; } /* END of sample code ************************************************/ I apologize for this being such a long sample code (and I apologize if it has errors, although I compiled it and ran it), but I am hoping that it might make my problem clearer. The problem is that the buffer structure b1 (which is pointed to by ES:SI in the interrupt) contains a pointer (pointer_to_more_data) which is used by the interrupt in referencing the data buffer which was malloc()ed and moved to conventional memory. The problem here is that the interrupt references this memory through pointer_to_more_data, which *should* point to the data in the conventional memory rather than the malloc()ed data. I don't know how to get the address of this data so that the interrupt can use it. I thought that I could just store the segment in the high word and the offset in the low word of the pointer, but I read in the FAQ that conventional memory uses 20-bit addresses. How do I get the address of this data so the real-mode interrupt can use it? Or can I just leave pointer_to_more_data pointing to the malloc()ed data, instead of transferring that data to conventional memory? Sorry this post is so long, and thanks a bunch if you read thru it :-) I appreciate all help you can give me, even if it is a dissapointing "Sorry, you can't do that with DJGPP!" :-) -Chris