www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/08/01/15:19:41

From: Chris Frolik <frolikcc AT indy DOT net>
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
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

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 <stdio.h>
#include <stdlib.h>
#include <dpmi.h>
#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<DATA_BUFFER_SIZE ; i++) *((char
*)b1.pointer_to_more_data+i) = 0;

   /* In the INFO docs for __dpmi_allocate_dos_memory, it says that
      paragraphs = ((bytes+15)>>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, &registers);

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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019