Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DMA and paging

105 views
Skip to first unread message

Gerrit van Niekerk

unread,
Sep 24, 2007, 11:39:49 AM9/24/07
to dj...@delorie.com, gerr...@gpvno.co.za
The DJGPP FAQ (http://www.delorie.com/djgpp/v2faq/faq18_13.html) tells
me to use XMS when a large DMA buffer is required, do some mapping
tricks and use farptr functions to transfer between DJGPP memory and the
DMA memory. My understanding is that paging is to blame for this
complexity.

My question: If paging is disabled by either configuring CWSDPMI with
CWSPARAM or using CWSDPR0, will the physical to logical address
mapping be 1:1? Can the physical address to program the DMA unit be
simply computed by the data segment and offset?


Rod Pemberton

unread,
Sep 24, 2007, 12:34:37 PM9/24/07
to

"Gerrit van Niekerk" <gerr...@gpvno.co.za> wrote in message
news:46F7F665.17...@gerritvn.gpvno.co.za...

?

> will the physical to logical address mapping be 1:1

To get non-paging 1:1 physical addressing, you could use PMODEDJ (i.e.,
PMODETSR.EXE). Run stubedit.exe to change the DPMI host from CWSDPMI.EXE to
PMODETSR.EXE.

stubedit my_sample.exe dpmi=PMODETSR.EXE

Or, you can change the parameters interactively. Stubedit will ask for
replacement values. Stubedit will allow you to change the application's
stack space, RM transfer buffer, base filename, argv[0], and DPMI host.

stubedit my_sample.exe

I've used PMODEDJ to help find DPMI programming mistakes, and for one
situation where I don't want paging.


Rod Pemberton

Gerrit van Niekerk

unread,
Sep 24, 2007, 3:09:06 PM9/24/07
to dj...@delorie.com
> "Gerrit van Niekerk" <gerr...@gpvno.co.za> wrote in message
> news:46F7F665.17...@gerritvn.gpvno.co.za...
> > The DJGPP FAQ (http://www.delorie.com/djgpp/v2faq/faq18_13.html) tells
> > me to use XMS when a large DMA buffer is required, do some mapping
> > tricks and use farptr functions to transfer between DJGPP memory and the
> > DMA memory. My understanding is that paging is to blame for this
> > complexity.
> >
> > My question: If paging is disabled by either configuring CWSDPMI with
> > CWSPARAM or using CWSDPR0, will the physical to logical address
> > mapping be 1:1? Can the physical address to program the DMA unit be
> > simply computed by the data segment and offset?
> > will the physical to logical address mapping be 1:1?
>
> To get non-paging 1:1 physical addressing, you could use PMODEDJ (i.e.,
> PMODETSR.EXE). Run stubedit.exe to change the DPMI host from CWSDPMI.EXE to
> PMODETSR.EXE.
>
> stubedit my_sample.exe dpmi=PMODETSR.EXE
>
> Or, you can change the parameters interactively. Stubedit will ask for
> replacement values. Stubedit will allow you to change the application's
> stack space, RM transfer buffer, base filename, argv[0], and DPMI host.
>
> stubedit my_sample.exe
>
> I've used PMODEDJ to help find DPMI programming mistakes, and for one
> situation where I don't want paging.
>
> Rod Pemberton
>

Thanks, Rod.

Have you actually done DMA programming using DJGPP and PMODEDJ ?

Do you have any more pointers, warnings and/or gotchas if I simply
malloc() a memory buffer and calculate the physical address by adding
base from __dpmi_get_segment_base_address(_my_ds(),&base) to it ?
--
Gerrit van Niekerk
GP van Niekerk Ondernemings BK
Roosstraat 211, Meyerspark, 0184, South Africa
Tel: +27(12)8036501 Fax SA: 0866 413 555
Cell: +27(73)6891370
Fax Int'l: +1(206)2034139
Email: gerr...@gpvno.co.za
Web: http://www.gpvno.co.za

Rod Pemberton

unread,
Sep 24, 2007, 4:13:29 PM9/24/07
to

"Gerrit van Niekerk" <gerr...@gpvno.co.za> wrote in message
news:46F82772.5...@gerritvn.gpvno.co.za...

> Have you actually done DMA programming using DJGPP and PMODEDJ ?
>

No, I've not done any DMA programming with DJGPP. That was why I posted the
"?" - meaning I didn't have an answer to the rest of your original
questions.

> Do you have any more pointers, warnings and/or gotchas if I simply
> malloc() a memory buffer and calculate the physical address by adding
> base from __dpmi_get_segment_base_address(_my_ds(),&base) to it ?

1) subtract base
2) if you're getting DPMI crashes, you might want to try increasing the
segment limit (0x0009FFFF or so) by one method:
a) __dpmi_set_segment_limit(_my_ds(),0xFFFFFFFF)
b) __djgpp_nearptr_enable()
3) you might want to try __dpmi_allocate_memory() instead of malloc()
4) if you're using CWSDPMI or CWSDPR0 instead of PMODEDJ, you'll need to
a) call __dpmi_physical_address_mapping()
b) be aware that 0-1Mb is already physically mapped, so you'll need to map
1Mb to xxMb.
c) my experience with CWSDPMI v5 indicates it can't physically map more
that 128Mb
d) IIRC, no errors were given for failures with b) and c)
e) you might want to try CWSDPMI v6 for a larger page size, and perhaps
more physically mapped memory...
5) there is a small (64k or less) amount of memory pre-allocated below 1Mb
called a transfer buffer which you might be able to use instead of
allocating DOS memory by DPMI. Look into __tb, __tb_segment,__tb_offset.


Rod Pemberton

Rod Pemberton

unread,
Sep 24, 2007, 4:48:37 PM9/24/07
to

"Rod Pemberton" <do_no...@nowhere.cmm> wrote in message
news:fd95kj$sgt$1...@aioe.org...

6) if you need memory below 1Mb and aren't using the transfer buffer, you
can use __dpmi_allocate_dos_memory()
7) _dos_ds segment size can also be extended to 4Gb (0-4Gb physical) but
you'll still have to use farptr.h functions.
8) Windows won't do some DPMI techniques the same as DOS with DPMI. e.g.,
memory mapping, segment limit increase
9) I've had problems with some of the _go32_* functions and don't like them.
10) The __dpmi_simulate_real_mode_interrupt() usually works. But, in one
instance - for a non-returning interrupt, I had to simulate it using
__dpmi_get_real_mode_interrupt_vector() and
__dpmi_simulate_real_mode_procedure_retf().


RP

RayeR

unread,
Sep 25, 2007, 3:22:27 PM9/25/07
to
I don't know where is your DMA buffer lying, I can help you only with
my example how to handle with VESA LFB which may be similar

// Allocate a descriptor in LDT and set it up to span the entire VRAM.
vesa_lfb_selector=__dpmi_allocate_ldt_descriptors(1); // allocate
1 descriptor (desribing our new segment) in LDT and return it's
selector

__dpmi_set_segment_base_address(vesa_lfb_selector,meminfo.address); //
set segment base accorning to LFB physical address
__dpmi_set_segment_limit(vesa_lfb_selector,meminfo.size-1); // set
segment limit accorning to LFB size

then you will use movedata function to transfer physical memory to
your variables in DS or where you want.
Afrer all done don't forget to free descriptor
__dpmi_free_ldt_descriptor(vesa_lfb_selector);


0 new messages