www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/02/15/08:51:26

Xref: news2.mv.net comp.os.msdos.djgpp:1133
From: malcolm AT manawatu DOT gen DOT nz (Malcolm Taylor)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: how to allocate DMA pages ?
Date: Thu, 15 Feb 1996 02:10:15 GMT
Organization: Grafik Software
Lines: 42
Message-ID: <4fu11h$5au@news.manawatu.gen.nz>
References: <DMM3D9 DOT F7K AT granite DOT mv DOT net>
Reply-To: malcolm AT manawatu DOT gen DOT nz
NNTP-Posting-Host: malcolm.manawatu.gen.nz
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Neil Jarvis <Neil DOT Jarvis AT proteon DOT com> wrote:

>>>>>> "Ulf" == Ulf Griesmann <ulfg AT groundhog DOT phy DOT nist DOT gov> writes:

>    Ulf> Hello All,
>    Ulf> The 8237 DMA controllers in a PC can only perform DMA
>    Ulf> transfers to the lower 16MB of physical memory. This makes it
>    Ulf> awkward to allocate buffers for DMA transfers on machines
>    Ulf> with >16MB of memory because a simple 'malloc' is no longer
>    Ulf> guaranteed to allocate DMAable memory.  Does anyone out there
>    Ulf> know of a good strategy for allocating DMA buffers which
>    Ulf> works on large memory machines ? (Will take source code...)

>Ulf,

>It is actually worse than this - the 8237 DMA controller takes
>physical addresses, malloc returns virtual addresses. There is
>currently no mechanism to translate malloc'ed virtual addresses into
>physical addresses with which to program the DMA controller.

>Having said that, I came up with a solution that uses XMS to allocate
>and lock a region of memory above 1Mb - XMS will tell you the physical
>address of this region, allowing you to program DMA transfers. I then
>used DPMI to map a region of linear memory to this XMS region. The
>application can then access the data using the <sys/farptr.h>
>functions.

There is actually an easier method than that (it has it's restrictions
though). Under DPMI the first 1M of memory is always locked and has
the linear addresses 0-1M. Just allocate some DOS memory from the DPMI
provider and the get the linear address by segment*16+offset. This can
be accessed with the far-ptr routines using the
__go32_info_block.selector_for_linear_memory as the selector and the
linear address as the offset. Usually you will want memory that starts
on the DMA page boundaries, so just allocate the size+64K and figure
from the address the start of the first page in the block.
The only limitation of this that I know of is only a limited amount of
memory can be allocated this way. This isn't normally a problem as the
limit is high.

Malcolm

- Raw text -


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