Re: Port Application to 32 bit
- From: "Rod Pemberton" <do_not_have@xxxxxxxxxxx>
- Date: Tue, 17 Jul 2007 06:45:22 -0400
"Liam" <query_me2001@xxxxxxxxxxx> wrote in message
news:1184588162.111866.293380@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi,
I have been tasked with porting an application which has been written
in 16 bit to work as a 32 bit application. The restriction of the
640Kbytes memory barrier is causing a problem. There is a need to
address the full memory range.
I have not worked with DOS before so I am having difficulty get a
handle on the scope of work.
Depends on code and compiler.
What do I need to do to make this
application be able to access the full 32 bit range of memory?
Access, e.g., memory burn in, or allocate, e.g., via C malloc()? (I'll get
back to my question below... I'll get back to your question multiple times
below too...)
Are
there certain API calls that I would have to change in the source to
make it work?
Yes. The main one supported by compilers that are still in use today is
DPMI. Others, include VCPI, EMM, Pharlap, etc.
Or are there other system configuration item that I
would have to make?
Any advice or pointers would be appreciated.
I use DJGPP v2.03 and OpenWatcom v1.3.
DJGPP produces 32-bit PM code and uses DPMI. DOS and BIOS are the base of
the OS. DPMI basically adds to DOS 1) a memory manager just for memory
above 1Mb and 2) routines to switch back and forth between 16-bit RM DOS or
BIOS and 32-bit PM code. OW can produce both 16-bit RM and 32-bit PM code.
The OW 32-bit PM code uses a DPMI host with a DOS Extender. A DOS Extender
implements some 32-bit PM routines. Usually, these are just call-backs to
16-bit DOS or BIOS routines through the DPMI host.
DJGPP has two versions still in use v2.03 and v2.04. v2.04 is intended for
Windows and is (supposedly) still in development. (It seems stalled.)
v2.03 is for DOS, has LFN support, but lacks some POSIX functions that v2.04
has. DJ Delorie has basically indicated no further development of v2.03
will occur. I.e., DOS is dead and there are many useful Windows compilers:
Pelles C, MinGW, LCC-Win32, OpenWatcom, etc. I was hoping v2.03 would have
one last strong effort to become fully POSIX compatible, but another
maintainer said it wasn't going to happen...
Version 1.1 of OpenWatcom was almost too primitive to use. Version 1.3 of
OpenWatcom doesn't have any POSIX support. About version 1.5, IIRC, OW had
DOS LFN support added. I'm not sure what version OW is upto now 1.6 or
1.7... Unfortunately, a few of the key developers harshly criticized 1.5
and 1.6 prior to release. Later, they were surprised and shocked and angry
at me when I reiterated what they had stated... One of the key maintainers
was already very hostile towards supporting DOS in OW as of v1.3. He only
wanted to support OS/2, C++ STL, WxWidgets, Windows, and maybe Linux or
FreeBSD. Although there were quite a few people who use OW for DOS, there
weren't many people left who were able to help support DOS in OW. Around
version 1.5, he threaten to remove all DOS support from OW due to the lack
of help. I don't know if DOS support was pulled or not for versions after
1.3. You'll have ask someone else like, Florian Xavier, or download it.
What do I need to do to make this
application be able to access the full 32 bit range of memory?
Earlier, I asked "Access or allocate?"
Why? Because, although you can access all memory in a 32-bit range with a
DPMI host, you usually can't allocate all that memory e.g., via a C call
like malloc(). (Although, only one app. runs at a time under DOS, your app.
"shouldn't" destroy memory needed by other applications... PM TSR's are an
exception.) There are two types of DPMI hosts: paging and non-paging. The
paging hosts, while allowing virtual memory (hard disk file), typically
don't map that much real memory. Also, the addressing used by paging hosts
doesn't correspond to physical addresses unless a DPMI call is used to map
it. OW uses non-paging hosts by default (DOS4GW and PMODEW). OW will also
work with Causeway and Japheth's HXRT. DJGPP uses paging by default but
also has a non-paging DPMI host. The default host for DJGPP (CWSDPMI v5)
will only map 128Mb. The non-paging DJGPP DPMI host (PMODETSR) will allow
access to 4Gb (physically mapped) but not allocate that much. By default,
DPMI maps memory below 1Mb (or 1Mb+64k-16bytes or so) physically.
Japheth's HXRT:
http://www.japheth.de/HX.html
What do I need to do to make this
application be able to access the full 32 bit range of memory?
To access, but not allocate, the full 32-bit range of memory: A), B)1), or
B)2).
A) For the OpenWatcom compiler compiled for 32-bit DPMI, you can use
standard C pointers:
#ifdef __WATCOMC__
/* __386__ make sure not 16-bit OW or Linux or Windows... */
#ifdef __386__
unsigned char *adr; /* bytes, e.g., unsigned short for words, etc... */
unsigned char byte;
/* cast your start of base address, somehow... */
adr = (unsigned char *)strtoul(argv[1], NULL, 0);
adr = (unsigned char *)0x000FFFF0;
/* get byte from memory, somehow*/
byte=*adr; /* get just byte at adr */
byte=adr[i]; /* i is offset from base, e.g., for a loop...*/
#endif
#endif
B) For the DJGPP compiler, there are two methods:
1) farptr - uses special functions
2) "nearptr" - uses standard C pointers, but needs an address correction
Basically, DJGPP has two address spaces, i.e., segmented, both zero based:
(This doesn't work well with the C standards - but is excellent for
multi-tasking).
1) the memory from 0 to 1Mb
- corresponds to physical memory per DPMI spec.
2) the application address from 0 to app size
- base is relative to another "hidden" address
- corresponds to physical memory for non-paging DPMI (PMODETSR)
- must be mapped to physical memory for paging DPMI (CWSDPMI, CWSDPR0)
B)1) farptr - uses special functions - non-paging DPMI can access 4Gb,
paging (CWSDPMI) extra code - only 128Mb. This method is useful for low
memory or for accessing small amounts of memory.
#ifdef __DJGPP__
#include <sys/farptr.h>
#include <go32.h>
#include <dpmi.h>
#ifdef PAGING_DPMI
__dpmi_meminfo mi;
#endif
__dpmi_set_segment_limit(_dos_ds,0xFFFFFFFFU); /* set limit to 4Gb */
#ifdef PAGING_DPMI
/* map maximum 128Mb for CWSDPMI, 0 to 1Mb already physically mapped */
mi.address=0x00100000U;
mi.size=0x08000000U-1;
__dpmi_physical_address_mapping(&mi);
#endif
byte = _farpeekb(_dos_ds,adr)
#endif
B)2) "nearptr" - standard C pointers, must subtract base address to get
physical address. Setting the segment limit gives access to all 4Gb. It's
just not physically mapped 0 to 4Gb. The addresses are shifted "upwards" by
1Mb. I.e., 0 to 1Mb becomes 4G-1Mb to 4Gb, 1Mb to 4Gb becomes 0 to 4Gb-1Mb.
#ifdef __DJGPP__
#include <go32.h>
#include <dpmi.h>
unsigned long base;
unsigned char *adr; /* bytes, e.g., unsigned short for words, etc... */
unsigned char byte;
__dpmi_set_segment_limit(_my_ds(),0xFFFFFFFFU);
__dpmi_get_segment_base_address(_my_ds(),&base);
/* cast your start of base address, somehow... while subtracting *BASE* */
adr = (unsigned char *)(strtoul(argv[1], NULL, 0)-base);
adr = (unsigned char *)(0x000FFFF0-base);
/* get memory */
byte=*adr; /* get just byte at adr */
byte=adr[i]; /* i is offset from base, e.g., for a loop...*/
#endif
The code was pulled from some other programs I wrote which weren't done
exactly the same way, so I hope I didn't introduce some errors..
If you need to do other stuff, like call DOS or BIOS functions, you'll need
to learn DPMI programming. Both OW and DJGPP have C wrapper functions which
call some of the DOS and BIOS functions. DJGPP also has a full set of C
wrapper functions for DPMI.
I have a few other in depth posts on this. Search for "_dos_ds" and
"_my_ds" in all words, author Rod Pemberton:
http://groups.google.com/advanced_search?hl=en
Also, there is a DJGPP version by Daniel Borca which produces ELF and has a
flat address space. I believe it is base 0, with 4Gb...
http://www.geocities.com/dborca/djgpp/elf/djelf.html
I haven't tried it. Since it produces ELF, you might need Grub4DOS:
http://sarovar.org/projects/grub4dos
OW natively supports 16-bit code, which you may need. DJGPP does too, but
it's not native. It can be done with a patch or with assembler directives:
http://www.delorie.com/djgpp/16bit/
http://www.delorie.com/gnu/docs/binutils/as_270.html
Rod Pemberton
.
- Follow-Ups:
- Re: Port Application to 32 bit
- From: Florian Xaver
- Re: Port Application to 32 bit
- References:
- Port Application to 32 bit
- From: Liam
- Port Application to 32 bit
- Prev by Date: Microsoft Tcp Sdk for Dos
- Next by Date: Re: Port Application to 32 bit
- Previous by thread: Re: Port Application to 32 bit
- Next by thread: Re: Port Application to 32 bit
- Index(es):
Relevant Pages
|