delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2006/04/19/21:17:02

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: "Rod Pemberton" <do_not_have AT sorry DOT bitbuck DOT cmm>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: dos buffer
Date: Wed, 19 Apr 2006 21:01:28 -0400
Organization: Aioe.org NNTP Server
Lines: 136
Message-ID: <e26mf1$ruh$1@emma.aioe.org>
References: <A8adnbpWz9FuPdjZnZ2dnUVZ_sednZ2d AT comcast DOT com>
NNTP-Posting-Host: pCFjXAYAthfOLF6YhIh1ZA.user.aioe.org
X-Complaints-To: abuse AT aioe DOT org
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441
X-Priority: 3
X-Newsreader: Microsoft Outlook Express 6.00.2800.1437
X-MSMail-Priority: Normal
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

"Eric" <NoOne AT invalid DOT com> wrote in message
news:A8adnbpWz9FuPdjZnZ2dnUVZ_sednZ2d AT comcast DOT com...
> Can anyone point me to some sample code that shows how to allocate a dos
> buffer (below 1 meg). I want to understand how to do things this way and
> not rely on tb.
> For instance:
>   allocate buffer below 1 meg - size -32k
>   fill buffer with data and read it back
>   store actual buffer address in say regs.r.ax and regs.r.bx
>   free buffer
>
> I looked at __dpmi_allocate_dos_memory but it gets you a selector and I
dont
> know what to do to convert that to a pointer
>

Now, the memory below 1Mb is physically mapped per the DPMI specification,
but a buffer in that region still needs to be allocated.  Unfortunately, DOS
memory must be allocated through the DPMI host and not directly through DOS
itself.  It handles some other issues and allocates from DOS.  Therefore, to
allocate DOS memory, you must use either one of these:

1) __dpmi_allocate_dos_memory
2) _go32_dpmi_allocate_dos_memory

Now, _go32_dpmi_allocate_dos_memory() uses segments and offsets through a
structure, like you want.  However, I'm not fond of the _go32_xxx functions
because the set of functions is incomplete.  So, you end up spending all
your time reformating segments, offsets, etc. to switch between the _go32
functions and _dpmi functions...

Anyway, I've written two examples.  They both compile cleanly, but haven't
been thoroughly tested (i.e., possible bugs...).  If there are any bugs,
you'll need to sort them out yourself.

Method 1)
----
#include <dpmi.h>
#include <go32.h>
#include <sys/farptr.h>

#define BUFF 32768
int main(void)
{
   unsigned long base;
/*   unsigned short segment,offset; */
   int selector;
   char buf[BUFF];

/* base is the physical address of the low mem buffer */
/* selector is used for virtual addressing, i.e., within application space
*/
   __dpmi_allocate_dos_memory((BUFF+15)>>4,&selector);
   __dpmi_get_segment_base_address(selector,&base);

#if 0
   /* this is how to calculate segment & offset, if needed */
   segment=(unsigned long)base>>4;
   offset=(unsigned long)base&0x0F;
#endif

   dosmemput(buf, BUFF, base); /* copy to low mem */
   /* something done to low mem buffer: DOS call, farpoke */
   _farpokeb(selector,12,0x20); /* set low mem buf[12] to 0x20 */
   dosmemget(base, BUFF, buf); /* copy from low mem */
   __dpmi_free_dos_memory(selector);

return(0);
}

Method 2)
----
#include <string.h>
#include <dpmi.h>
#include <go32.h>
#include <sys/farptr.h>
#include <sys/nearptr.h>

#define BUFF 32768
int main(void)
{
   unsigned long base,CS_base;
/*   unsigned short segment,offset; */
   int selector;
   unsigned char buf[BUFF];
   unsigned char *bufl;

/* base is the physical address of the low mem buffer */
/* selector is used for virtual addressing, i.e., within application space
*/
   __dpmi_allocate_dos_memory((BUFF+15)>>4,&selector);
   __dpmi_get_segment_base_address(selector,&base);

/* get the physical starting address of the code segment */
/* and enable full address range */
   __dpmi_get_segment_base_address(_my_cs(),&CS_base);
   __djgpp_nearptr_enable();

#if 0
   for physical-to-virtual addressing use: (e.g., screen=0xB8000)
            #ifdef __DJGPP__
                "variable"  -=CS_base;
            #endif
   for virtual-to-physical addressing use: (e.g., lgdt,lidt,etc.)
            #ifdef __DJGPP__
                "variable"  +=CS_base;
            #endif
#endif

   bufl=(unsigned char *)base; /* create a pointer to low mem */
   bufl+=CS_base; /* convert virtual to physical address */

#if 0
   /* this is how to calculate segment & offset, if needed */
   segment=(unsigned long)bufl>>4;
   offset=(unsigned long)bufl&0x0F;
#endif

   memcpy(bufl,buf,BUFF); /* copy to low mem */
   /* something done to low mem buffer: DOS call, farpoke */
   _farpokeb(selector,12,0x20); /* set low mem buf[12] to 0x20 */
   memcpy(buf,bufl,BUFF); /* copy from low mem */
   __dpmi_free_dos_memory(selector);

return(0);
}


HTH,

Rod Pemberton




- Raw text -


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