START-INFO-DIR-ENTRY
* FAQ: (djgppfaq).           The DJGPP FAQ list.
END-INFO-DIR-ENTRY

This is the DJGPP Frequently-Asked Questions List.

Copyright (C) 1994, 1995, 1996 Eli Zaretskii

This is the second edition of the FAQ list,
and is consistent with version 2.0 of DJGPP.

This FAQ list may be freely distributed with the DJGPP package or any part
thereof, provided this copyright notice is left intact on all copies.

DJGPP FAQ List
**************

  In DJGPP (see DJGPP overview in Chapter 2), a 32-bit compiler and programming
environment originally written for Unix machines, meet a 16-bit MS-DOS
operating system.  Programmer who work in this environment have to master a
large body of knowledge from both Unix and MS-DOS, especially if they want to
use some advanced features, like interrupt handling, directly accessing
peripheral devices, etc.

  But because the DJGPP project is a product of a group of volunteers, there
isn't always enough time (or patience, or money ;-) to produce documentation
which will describe all the subtle features and pitfalls a user should know
about.  The documentation of DJGPP-specific utilities and issues is therefore
minimal, leaving wide space for confusion, in newcomers and veterans alike,
and making the DJGPP learning curve quite a steep one.

  This FAQ list is an attempt to take the sting out of that learning curve, by
supplying solutions for problems which are known to puzzle DJGPP users.
(Another solution would be to pay to DJ Delorie and other people who
developed DJGPP to produce more documentation ;-).

  This is Edition 2.0 of the FAQ, last updated 21 February 1996, for DJGPP
Version 2.0.

  The sources of the latest version of this FAQ list can always be found as
`faq200s.zip' on SimTel mirrors, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2/faq200s.zip.  This includes the
source file (written in Texinfo), and all the auxiliary tools required to
produce the Info, plain-ASCII, HTML, and a few other versions of the FAQ
list; the FAQ in all these formats is available in a separate ZIP archive as
`faq200b.zip' on SimTel mirrors, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2/faq200b.zip.  Currently, this
includes the Info version, the text (ASCII) version and an HTML version as a
single large `.htm' file.  More formats will be available as the tools for
their generation are developed/tested.

  You can browse the HTML version of this FAQ list on line at the DJ Delorie's
Web server, at this URL:

     http://www.delorie.com/djgpp/v2faq/faq.html

  If you browse this FAQ at DJ Delorie's server now, you can get the source
distribution of the FAQ right here, at this URL:

     http://www.delorie.com/djgpp/v2faq/faq200s.zip

Also available from the DJ's server: FAQ in all the supported formats, at
this URL:

     http://www.delorie.com/djgpp/v2faq/faq200b.zip

  This FAQ was also translated into French, at this URL:

     http://www.rpi.edu/~elandm/frdocs/djgppfaq.rtf

   Table of Contents
   *****************
1. If You Are In a Hurry
2. What is DJGPP?
3.  Hardware and Software Requirements
  3.1 The minimum system requirements for using DJGPP
  3.2 Does it really work under OS/2?
  3.3 Will it work under Windows/NT?
  3.4 Can I run it on a 286?
  3.5 MS-Windows applications and DJGPP
  3.6 What you *should* buy ...
  3.7 What most of us will *actually* buy ...
  3.8 How to configure your system for DJGPP?
4. Where and What to Download?
  4.1 Where can I get DJGPP?
  4.2 How do I download DJGPP?
  4.3 What if I don't know what `FTP' is?
  4.4 What Files to Download?
  4.5 How much disk space will I need?
  4.6 Can I get away with less megabytes?
5. The DJGPP Documentation
  5.1 Where are the documentation files?
  5.2 How to read the docs without `Info'?
  5.3 How to print the docs?
  5.4 Where can I find docs in PostScript?
  5.5 Some docs are nowhere to be found...
  5.6 What are these `foo.1' files?
  5.7 What if the docs don't say enough?
6. When the Compiler (or `Make', or `Info', or ...) Crashes...
  6.1 Buggy DPMI host can crash v2.x programs
  6.2 GCC can crash during optimization
  6.3 What does ``Fatal signal X'' mean?
  6.4 What does ``Unknown filetype'' mean?
  6.5 You can't use `QEMM' auto/off mode with DJGPP
  6.6 Compiler hangs, but only when invoked from Make
  6.7 Info doesn't like some files
  6.8 My problem isn't mentioned above!
  6.9 I can't keep up with the error messages
  6.10 How to search DJGPP archives for similar problems
  6.11 How to ask DJGPP gurus for help
7. Compiler Performance
8. Compile-time and Link-time Problems
  8.1 GCC can't find headers or libraries
  8.2 GCC can't find C++ headers
  8.3 GCC barfs on C++-style comments in C programs
  8.4 How does GCC recognize the source language?
  8.5 Problems with Objective C
  8.6 Writing codes fragments which are specific to DJGPP
  8.7 Unresolved externals when linking programs
  8.8 How not to lose your head with all these libraries
  8.9 DJGPP uses a one-pass linker
  8.10 C++ functions still not found
  8.11 The linker complains about __pure_virtual function.
  8.12 C++ programs yield large `.exe' file
9. Running Compiled Programs
  9.1 My program crashes only in v2.0!
  9.2 What is that gibberish printed when my program crashes?
  9.3 Reading and writing binary files
  9.4 Buffered screen I/O surprises
  9.5 What do DJGPP programs need to run?
10. Writing and Running Graphics Programs
  10.1 Accessing the video memory
11. Floating Point Issues and FP Emulation
  11.1 Floating code without 80387
  11.2 Other FP emulators cannot be used with DJGPP
  11.3 Floating-point emulation under OS/2
  11.4 DJGPP doesn't support `-msoft-float'
  11.5 Numeric exceptions---sometimes
  11.6 Floating point inaccuracies when using emulator
12. Debugging DJGPP Programs
  12.1 How to run a DJGPP program under debugger
  12.2 You need QEMM 7.53 or later
  12.3 GDB won't debug unless it sees COFF output
  12.4 Debuggers use the transfer buffer.
  12.5 How to debug a graphics program
  12.6 GDB finds only `.cc' source
  12.7 Debuggers choke on some programs ...
13. Profiling DJGPP Programs
  13.1 How to profile a DJGPP program
  13.2 Gprof won't work unless it can find COFF executable
  13.3 Where is Gprof docs?
  13.4 Why is `__dpmi_int' so heavy used?
14. Run-time Performance of DJGPP Programs
  14.1 How efficient is DJGPP-generated code?
  14.2 My program's I/O is so slow!
  14.3 My ported program runs much slower!
15. Run-Time Memory Issues
  15.1 How much virtual memory do you have?
  15.2 It seems `malloc'/`free' don't affect virtual memory...
  15.3 Failure to get more memory than is physically installed
  15.4 Memory allocation fails under QDPMI
  15.5 Memory allocation fails under Windows
  15.6 Memory allocation fails under EMM386 or HIMEM
  15.7 How much memory do parent DJGPP programs leave for their child?
  15.8 How much stack can I have in DJGPP programs?
16. Command-line Arguments Handling in DJGPP
  16.1 Filename wildcards expansion under DJGPP
  16.2 How to disable filename wildcards expansion
  16.3 How to pass command-line arguments with quotes or @
  16.4 How to pass command lines longer than 126 characters
  16.5 What is the maximum length of command line under DJGPP
  16.6 Why Make passes only 126 characters to programs?
17. Converting DOS Programs/Libraries to DJGPP
  17.1 GCC/Gas won't accept valid assembly code ...
  17.2 Double-check code produced by Gas
  17.3 Converting Intel ASM syntax to AT&T syntax
  17.4 Converted code GP Faults!
  17.5 I want to use a `.obj' or `.lib' code with DJGPP
  17.6 I *must* use my 16-bit code with DJGPP!!
18. Low-level DOS/BIOS and Hardware-oriented Programming
  18.1 Got ``Unsupported INT 0xNN'' calling `int86'
  18.2 How to use buffers with DOS/BIOS services
  18.3 How to call software interrupt functions
  18.4 How to move data between your program and conventional memory?
  18.5 Conventional-memory addresses use only 20 bits
  18.6 Fast access to memory-mapped devices or absolute addresses
  18.7 Accessing absolute address above 1MB
  18.8 How to make DOS/BIOS call your function
  18.9 How to hook hardware interrupts
  18.10 Hardware interrupt hooking has its subtleties ...
  18.11 How to read and write ports
19. Legal Aspects
  19.1 Legal (un)restrictions on DJGPP applications
  19.2 Legal restrictions of DJGPP utilities and libraries
20. Getting Help
  20.1 Don't post DJGPP-specific problems to GNU Newsgroups
  20.2 How to post to the mailing list
  20.3 How to become a subscriber to the mailing list
  20.4 How to unsubscribe from the mailing list
  20.5 If you don't see any message from the list ...
  20.6 Why do I get every message more than once?
  20.7 DJGPP now has a Newsgroup!
21. Version 2.0 vs v1.x
  21.1 New features in DJGPP v2.0
  21.2 DJGPP environment in v2.0
22. Miscellany
  22.1 How to change a DJGPP package?
  22.2 Where to find sample DJGPP code or a package ported to DJGPP?
  22.3 How to create symbolic links to programs
  22.4 Where to find the DPMI specification?
  22.5 The DJGPP Web site.
  22.6 Where to upload your contributions to DJGPP
  22.7 DJGPP as cross-compiler
  22.8 GCC says ``garbage at end of number''
  22.9 What should sizeof (struct xyzzy) return?
23. About this FAQ
24. Topic Index
25. Program Index

1. If You Are In a Hurry
************************

**Q*: Do you really mean I have to read this looongish FAQ list to get my
answers?*

**Q*: I have this problem which I absolutely MUST solve NOW!  What do I do?*

*A* : No, you don't need to read *all* of the FAQ unless you want to
(although this is by all means recommended).  The questions in this documents
are listed, as much as possible, in the order they appear when one goes
through getting DJGPP, installing it and using it.  To quickly find an answer
to your question, first look at the Table of Contents, at the beginning of
this document.  If that doesn't help, try the indices at the end of this
manual.  You can either look up your question by program name in Chapter 25,
or by topic name in Chapter 24.  If you don't find anything appropriate,
search this FAQ for words which are pertinent to your problem.  For those in
a *real* hurry, here are some pointers to the most important topics in this
FAQ list:

   * How to ask experienced DJGPP users for help?

     Use the DJGPP Newsgroup or mailing list.  For most questions, you will
     have your answer in a day or two.  See the details on how to ask the
     gurus in Section 6.11.

   * What is the best configuration of my system for DJGPP?

     This depends on your hardware and software.  See system configuration
     guidelines in Section 3.8.

   * Some files I need seem to be missing.  Where do I find them?

     Check out the list of required and optional packages in Section 4.4.

   * How do I subscribe to or unsubscribe from the DJGPP mailing list?

     See subscription instructions in Section 20.3.

   * How can I search Newsgroup/mailing list traffic for some info?

     This FAQ includes the description of DJGPP archive search servers in
     Section 6.10, set up by Stephen Turnbull
     <turnbull@shako.sk.tsukuba.ac.jp> and DJ Delorie <dj@delorie.com>.

2. What is DJGPP?
*****************

**Q*: What is DJGPP?*

*A* :  DJGPP is a port of GNU C/C++ compiler and development tools to 32-bit,
protected-mode environment on Intel 32-bit CPUs running MS-DOS and compatible
operating systems, by DJ Delorie <dj@delorie.com> and friends.  Starting from
v2.0, DJGPP programs do not need a separate extender program, only a DPMI host
to run; DJGPP includes a free 32-bit DPMI server which allows for a 32-bit,
4 GByte flat address space and up to 256 MBytes of virtual memory, a compiler
which produces 32-bit protected-mode code, and a suite of GNU development
tools ported to MS-DOS.  These provide for a development environment which
specifically favors porting Unix programs, but are also suitable for writing
new code.  With a few exceptions (notably, the C++ class library), DJGPP is
*free* which makes it ideal for developing free and commercial software alike.

DJ Delorie <dj@delorie.com> is the developer and principal maintainer of
DJGPP, but anyone is welcome and encouraged to contribute.

3.  Hardware and Software Requirements
**************************************

  This chapter describes what are the hardware and software which will allow
you to use DJGPP.  Minimum, "reasonable" and optimal system configurations
are listed.

3.1 The minimum system requirements for using DJGPP
===================================================

**Q*: What are the minimum system requirements for using DJGPP?*

**Q*: Will DJGPP run on my brand-new Acme i986DX7/300 PC with a SCSI-III
10-Terabyte disk drive under MulticOS/42 v7.99 operating system?*

*A* :  DJGPP requires at least 386SX CPU and between 15 and 35 MB of free
disk space (see more details on this below in Section 4.5), including space
for the software installation and some swap space.  A minimum of 64K of
system memory is enough for DJGPP to run with the CWSDPMI free DPMI host
(most other DPMI hosts will require much more), but at least 2.5MB of free
extended RAM is recommended for reasonably fast compilation of large source
files (4MB for compiling large C++ programs); you might see painfully slow
compiles for large sources, if you don't have at least that much.  If your
machine doesn't have a numeric co-processor, you will need to install an
emulator to run floating-point code (DJGPP provides such an emulator) or link
your applications with a special emulator library (also provided with DJGPP).

DJGPP will run under native DOS; any other operating system is OK if it
includes a DPMI server.  Environments known to run DJGPP besides native DOS:
Windows 3.1, 3.11 DOS box, OS/2 (including Warp) DOS box, Windows 95/DOS 7,
Novell NWDOS 7.x (but several people has found the DPMI services of NWDOS
buggy, so they should probably be turned off and CWSDPMI used instead), and
Linux dosemu environment.

3.2 Does it really work under OS/2?
===================================

**Q*: You tell me it will work under OS/2, but I'm experiencing strange
crashes after several compilations ...*

*A* :  There was a bug in DPMI server of the old OS/2 versions, which is
triggered by spawning child processes (like GCC does when it invokes the
various compiler passes).  If you can't upgrade to a newer OS/2 version, like
OS/2 Warp, switch to a real-mode `gcc.exe' (from v1.x archives, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v1gnu/gcc263rm.zip).

3.3 Will it work under Windows/NT?
==================================

**Q*: What about Windows NT?*

*A* :  Windows NT currently cannot spawn DPMI programs, so you should use
real-mode `gcc.exe' (it is in the gcc272rm.zip archive, e.g.
ftp://ftp.delorie.com/djgpp/ofc/gcc272rm.zip) and a real-mode Make program
(like the one in the gnuish/ directory on SimTel, e.g.
ftp://ftp.coast.net/SimTel/vendors/gnu/gnuish/gmake371.zip).  Also, any DJGPP
program which calls any function from the `spawnXXX' family to run another
DJGPP program, won't run under NT.

3.4 Can I run it on a 286?
==========================

**Q*: Why can't I run DJGPP on my 286?  It has protected mode also...*

*A* :  True, but the protected mode isn't an issue here.  Gcc doesn't care
much about memory protection, but it does care to run on a 32-bit processor,
which 286 isn't.  A 386 or better CPU really *is* required.

3.5 MS-Windows applications and DJGPP
=====================================

**Q*: Can I write MS-Windows applications with DJGPP?*

*A* :  Currently, you can only run DJGPP programs under Windows as DOS apps
(i.e. inside DOS Box).  If you need to write true Windows apps, try using the
RSX extender with EMX port of GCC and RSXWDK kit for Windows.  You can get
RSX by anonymous ftp, e.g.
ftp://ftp.uni-bielefeld.de/pub/systems/msdos/misc/.  People who tried this,
report that you must download and unzip the RSXWDK2 source archive, not only
the binaries (otherwise you'll get General Protection Faults when you try to
run DJGPP programs).  If you cannot reach the above site (some people say
that it has closed its anonymous access), try looking for RSXWDK on Cica
mirrors, e.g. ftp://ftp.cica.indiana.edu/pub/pc/win3/programr/rsxwdk2s.zip.

Apart from RSXWDK, you will need `windows.h' header file.  One place to find
it is with the WINE distribution, e.g.
ftp://ftp.cdrom.com/pub/FreeBSD/distfiles/.

You will also need a resource compiler, e.g.
ftp://ftp.aiai.ed.ac.uk/pub/packages/tex2rtf/rtfutils/hcp505.zip.

Another way to develop Windows applications is to use the Cygnus GCC/GPP
port, at this URL:

     http://www.cygnus.com

This one's compatible with Win32, but requires you to comply with GNU
Copyleft system.

A better (but harder) way would be to volunteer to add Windows support to
DJGPP.

Note that, as of this writing, nobody has reported any first-hand experience
of using RSXWDK with DJGPP v2.0; the above is based on user reports under
v1.x.  If you try RSXWDK with v2.0, please post a summary of your experience.

3.6 What you *should* buy ...
=============================

**Q*: What is the optimal system configuration for running DJGPP?*

*A* :  Here is the description of your dream machine (at least for the next 6
months :-):

   * Hardware:

        - the fastest CPU you can find (a 200 MHz Pentium-Pro as of this
          writing);

        - at least 256KB second-level (off-chip) cache memory;

        - 128 MByte RAM;

        - motherboard built around fast 32-bit-wide bus (VLB or PCI);

        - SCSI-II hard disk with bus-mastering controller;

   * Software:

        - DOS, device drivers and TSRs all loaded HIGH, leaving only 5K DOS
          footprint in lower (under 640K) memory;

        - 8 MByte RAM disk installed, `TMPDIR' environment variable points to
          it (e.g., `set TMPDIR=e:', if E: is the RAM drive letter);

        - 8 MByte of disk cache, set to delayed-write operation;

3.7 What most of us will *actually* buy ...
===========================================

**Q*: OK, I don't have this much money.  What is the *reasonable*
configuration?*

*A* :  If you have the following machine, you should be able to stop worrying
about memory and compilation performance:

   - CPU: 486DX2-66 with 256 KB off-chip cache;

   - RAM: 16 MByte;

   - Disk: 12 ms IDE with VLB controller, or SCSI;

   - 4 MByte RAM disk;

   - 3 MByte disk cache;

This will leave you with about 8 MBytes of free extended RAM.  Note that the
RAM disk must be 4 MBytes to hold the output of the preprocessor for some
exceedingly large source files (notably, some GCC source files).  If you
don't have that much RAM to spare and still want to compile *very* large
source files, either reduce the disk cache so you can give more to RAM disk,
or point `TMPDIR' to your hard disk and make the disk cache larger, if you
can.

3.8 How to configure your system for DJGPP?
===========================================

**Q*: How do I configure my system to get optimal performance under DJGPP?*

*A* :  That depends on the amount of RAM you have installed in your machine.
Below are some guidelines to help you.

  a. If you have 2 MBytes or less RAM installed:

        * Don't use *any* memory manager.

        * Use of `CWSDPMI' as your DPMI host is highly recommended.

        * Remove any TSR and device drivers you don't absolutely need (like
          `SETVER.EXE', `HIMEM.SYS' etc.) from your `CONFIG.SYS' and
          `AUTOEXEC.BAT'.

        * Do *not* install disk cache or RAM disk; point your `TMPDIR'
          environment variable to a directory on your hard disk.  Put a
          sufficiently large `BUFFERS=' statement into your `CONFIG.SYS' (I
          recommend setting `BUFFERS=40,8') to make DOS file operations
          faster.

        * If you use `CWSDPMI' as your DPMI host, get the `CWSPARAM' program
          (from the `csdpmi1p.zip' archive) and set the "Minimum application
          memory desired before 640K paging" parameter to 512K.  (Depending
          on how much memory you actually have, you might need further
          fine-tuning this parameter.  This parameter defines the lowest
          amount of the extended memory CWSDPMI will use; if your system
          doesn't have that much free extended RAM, CWSDPMI will use the
          conventional memory instead.)

        * If you run under Windows, be sure to set the maximum amount of
          extended memory on your PIF file for the DOS box to a reasonable
          value.

     With this configuration, GCC will run out of free physical RAM and page
     when compiling almost any C program and all C++ programs.  If you are
     serious about DJGPP development, you need to buy more RAM *urgently*.

  b. If you have 2-4 MBytes of RAM installed:

        * Don't use *any* memory manager.

        * Remove any TSR and device driver you don't absolutely need (like
          `SETVER.EXE', `HIMEM.SYS') from your `CONFIG.SYS' and
          `AUTOEXEC.BAT'.

        * Get a disk cache which works from conventional memory and configure
          it to 256K size at most, or don't use a cache at all.

        * Do *not* install RAM disk; point your `TMPDIR' environment variable
          to a directory on your hard disk.

        * If you run under Windows, be sure to set the maximum amount of
          extended memory on your PIF file for the DOS box to a reasonable
          value.

     With this configuration, GCC will still run out of free physical RAM and
     page when compiling large C programs and most C++ programs.  Plan to buy
     more RAM as soon as you can.

  c. If you have 5-8 MBytes of RAM installed:

        * Use memory manager such as EMM386 or QEMM386.  Try using the
          FRAME=NONE parameter of the memory manager.  This will disable
          Expanded Memory (EMS) services as far as most programs are
          concerned; if you must use DJGPP together with any program which
          needs EMS, try to configure that program to use Extended Memory
          (XMS) instead.

        * Load DOS, device drivers and TSRs *HIGH*.

        * Give your disk cache 1 MByte of RAM.  Enable its delayed-write (aka
          write-back) feature.

        * Do *not* install RAM disk; point you `TMPDIR' environment variable
          to a directory on your hard disk.

        * If, after configuring your system as above, you still have more
          than 2.5 MBytes of free RAM left (4 MBytes, if you plan to program
          in C++ a lot), enlarge the disk cache size.

        * If you run under Windows, be sure to set the maximum amount of
          extended memory on your PIF file for the DOS box to a reasonable
          value.

  d. If you have more than 8 MBytes of RAM:

        * Use memory manager to load DOS, TSRs and device drivers *HIGH*.

        * Install at least 2-MByte-large disk cache, configured to use
          delayed-write feature.  If you have plenty of RAM, you can give
          your cache as much as 8 MBytes of memory.

        * If you have more than 5 MBytes left, install RAM disk with size of
          at least 1.5 MBytes and point your `TMPDIR' environment variable to
          it.  If your RAM disk is less than 4 MBytes, GCC might run out of
          space there for *very* large source files (e.g., cccp.c file from
          the GCC source distribution), but this shouldn't happen unless the
          size of the source file you are compiling approaches 1 MByte.

4. Where and What to Download?
******************************

  This chapter explains where and how can you get DJGPP, and recommends what
parts of the archive should you download.  Application of maintenance
releases (aka patches) is also discussed.

4.1 Where can I get DJGPP?
==========================

**Q*: Where can I get DJGPP?*

*A* : Look on any SimTel mirror in the vendors/djgpp/ subdirectory.

The primary site in Detroit, Michigan, USA:
     ftp.coast.net, directory /SimTel/vendors/djgpp/.

Here is a list of hosts by countries that offer mirror sites:
Canberra, Australia:
     archie.au, directory /micros/pc/SimTel/vendors/djgpp

Newcastle, Australia:
     ftp.iniaccess.net.au, directory /pub/SimTel/vendors/djgpp

Aarshot, Belgium:
     ftp.tornado.be, directory /SimTel/vendors/djgpp

Brussels, Belgium:
     ftp.linkline.be, directory /mirror/simtel/vendors/djgpp

Sao Paulo, Brazil:
     ftp.unicamp.br, directory /pub/simtel/vendors/djgpp

Edmonton, AB, Canada:
     ftp.agt.net, directory /pub/SimTel/vendors/djgpp

Beijing, China:
     ftp.pku.edu.cn, directory /pub/simtel/vendors/djgpp

London, England:
     src.doc.ic.ac.uk, directory /pub/packages/simtel/vendors/djgpp

Lancaster, England:
     micros.hensa.ac.uk, directory /mirrors/simtel/vendors/djgpp

Espoo, Finland:
     ftp.funet.fi, directory
     /pub/mirrors/simtel.coast.net/SimTel/vendors/djgpp

Neuilly, France:
     ftp.grolier.fr, directory /pub/pc/SimTel/vendors/djgpp

Paris, France:
     ftp.ibp.fr, directory /pub/pc/SimTel/vendors/djgpp

Bochum, Germany:
     ftp.ruhr-uni-bochum.de, directory
     /mirrors/simtel.coast.net/SimTel/vendors/djgpp

Chemnitz, Germany:
     ftp.uni-chemnitz.de, directory /pub/simtel/vendors/djgpp

Mainz, Germany:
     ftp.uni-mainz.de, directory /pub/pc/mirrors/simtel/vendors/djgpp

Tuebingen, Germany:
     ftp.uni-tuebingen.de, directory /pub/simtel/vendors/djgpp

Paderborn, Germany:
     ftp.uni-paderborn.de, directory /SimTel/vendors/djgpp

Hong Kong:
     ftp.cs.cuhk.hk, directory /pub/simtel/vendors/djgpp

Hong Kong:
     ftp.hkstar.com, directory /pub/simtel/vendors/djgpp

Naples, Italy:
     ftp.unina.it, directory /pub/simtel/vendors/djgpp

Pisa, Italy:
     cnuce-arch.cnr.it, directory /pub/msdos/simtel/vendors/djgpp

Rome, Italy:
     ftp.flashnet.it, directory /mirror/simtel/vendors/djgpp

Saitama, Japan:
     ftp.saitama-u.ac.jp, directory /pub/simtel/vendors/djgpp

Saitama, Japan:
     ftp.riken.go.jp, directory /pub/SimTel/vendors/djgpp

Tokyo, Japan:
     ftp.crl.go.jp, directory /pub/pc/archives/simtel/vendors/djgpp

Seoul, Korea:
     ftp.kornet.nm.kr, directory /pub/SimTel/vendors/djgpp

Seoul, Korea:
     ftp.nowcom.co.kr, directory /pub/SimTel/vendors/djgpp

Seoul, Korea:
     ftp.nuri.net, directory /pub/SimTel/vendors/djgpp

Lithuania:
     ftp.omnitel.net, directory /pc/simtel/vendors/djgpp

Utrecht, Netherlands:
     ftp.nic.surfnet.nl, directory
     /mirror-archive/software/simtel-vendors/djgpp

Wellington, New Zealand:
     ftp.vuw.ac.nz, directory /simtel/vendors/djgpp

Bergen, Norway:
     ftp.bitcon.no, directory /pub/micro/pc/SimTel/vendors/djgpp

Krakow, Poland:
     ftp.cyf-kr.edu.pl, directory /pub/mirror/simtel/vendors/djgpp

Poznan, Poland:
     ftp.man.poznan.pl, directory /mirror/simtel/vendors/djgpp

Warsaw, Poland:
     ftp.icm.edu.pl, directory /pub/simtel/vendors/djgpp

Aveiro, Portugal:
     ftp.ua.pt, directory /pub/simtel/vendors/djgpp

Slovak Republic:
     ftp.uakom.sk, directory /pub/SimTel/vendors/djgpp

Slovenia:
     ftp.arnes.si, directory /software/SimTel/vendors/djgpp

Johannesburg, South Africa:
     ftp.is.co.za, directory /SimTel/vendors/djgpp

Stellenbosch, South Africa:
     ftp.sun.ac.za, directory /pub/simtel/vendors/djgpp

Stockholm, Sweden:
     ftp.sunet.se, directory /pub/pc/mirror/SimTel/vendors/djgpp

Zurich, Switzerland:
     ftp.switch.ch, directory /mirror/simtel/vendors/djgpp

Chung-Li, Taiwan:
     ftp.ncu.edu.tw, directory /SimTel/vendors/djgpp

Taipei, Taiwan:
     nctuccca.edu.tw, directory /PC/simtel/vendors/djgpp

Nonthaburi, Thailand:
     ftp.nectec.or.th, directory /pub/mirrors/SimTel/vendors/djgpp

Ankara, Turkey:
     ftp.metu.edu.tr, directory /pub/mirrors/simtel/vendors/djgpp

Concord, CA, USA:
     ftp.cdrom.com, directory /pub/simtel/vendors/djgpp

Urbana, IL, USA:
     uarchive.cso.uiuc.edu, directory /SimTel/vendors/djgpp

Rochester, MI, USA:
     OAK.Oakland.Edu, directory /SimTel/vendors/djgpp

St. Louis, MO, USA:
     wuarchive.wustl.edu, directory /SimTel/vendors/djgpp

Norman, OK, USA:
     ftp.uoknor.edu, directory /SimTel/vendors/djgpp

Corvallis, OR, USA:
     ftp.orst.edu, directory /pub/mirrors/simtel/vendors/djgpp

Salt Lake City, UT, USA:
     ftp.pht.com, directory /pub/mirrors/simtel/vendors/djgpp

The latest official distribution archive is also available from the FTP
server set up by DJ Delorie, e.g. ftp://ftp.delorie.com/pub/djgpp/ofc/, *but
please use that site only if unable to connect to one of the SimTel mirrors
above*, because DJ's server works over a modem and can be easily overloaded,
which will hurt the unique services that server does (like the gateway
between the mailing list and the newsgroup, searching the mailing list
archives, the on-line FAQ version, etc.).

Note that DJGPP was recently moved to the `SimTel/vendors/' directory on most
SimTel mirrors.  This is because SimTel claims a compilation copyright on its
collection, to prevent people from copying the CD-ROMs which are distributed
by SimTel.  The GNU GPL prohibits *any* restrictions, even on compilations.
So, FSF asked for GNU and GNU-related files to be moved to a separate
directory to keep people from accidentally thinking that their rights were
being reduced.

4.2 How do I download DJGPP?
============================

**Q*: How do I download files from these sites?*

*A* :  FTP to the nearest site, log in as `anonymous', give your full e-mail
address as password, and chdir to the `djgpp' subdirectory (the exact path to
it might be different on different mirrors, see the DJGPP archive path in
Section 4.1.)  Then issue the `binary' command and download files you need
(see the list of required files in What to download) with the `get' command.

4.3 What if I don't know what `FTP' is?
=======================================

**Q*: What is that `FTP' thing?  I only use `Mosaic' for Internet access.*

*A* :  OK, here are some URLs for your Web browser:

   - The main SimTel site, at this URL:

          http://www.coast.net/SimTel/vendors/djgpp/

   - The mirror in Rochester, MI, at this URL:

          http://www.acs.oakland.edu/oak/SimTel/vendors/djgpp

   - The mirror in St. Louis, MO, at this URL:

          http://wuarchive.wustl.edu/systems/msdos/simtel/vendors/djgpp

You can also convert any of the mirrors' addresses listed in the list of
SimTel mirrors in Where to find, above to a valid URL by prepending `ftp://'
to it.  For example, here is the URL for FTP from the primary SimTel FTP
site, e.g. ftp://ftp.coast.net/SimTel/vendors/djgpp/.

Gopher users can access SimTel files through a Gopher client,
gopher://gopher.oakland.edu.

For those of you who have only e-mail connection to the Internet, SimTel
files may be also obtained by e-mail from various ftp-mail servers or through
the BITNET/EARN file servers.  For details send a message to the SimTel list
server <listserv@SimTel.Coast.NET> with this command in the message body:

      get simtel-mailserver.info

You can also get DJGPP from CD-ROM copies of SimTel collections.  You can
either request a CD-ROM by e-mail <order@Mail.Coast.NET>, or order the SimTel
CD-ROM through a WWW FORMS Interface, at this URL:

     http://www.coast.net/SimTel/cdrom.html

4.4 What Files to Download?
===========================

**Q*: What's the minimum set of `.zip' files I need to download?*

*A* :  This depends on what you are planning to use DJGPP for.

   * To only run DJGPP-compiled programs, you MUST download all of these:

    `v2/readme.1st'
          This explains how to install DJGPP and get started with using it.

    `v2/FAQ'
          The text version of the latest edition of this FAQ list.  Use it
          whenever you have problems installing and using DJGPP.

    `v2misc/csdpmi1b.zip'
          CWSDPMI, the DJGPP free DPMI server.  (If you can get DPMI services
          in your environment, like if you run under Windows, or QDPMI, or
          OS/2, you don't need CWSDPMI, but I recommend to download it
          nonetheless, so you can try it in case you have trouble with other
          DPMI servers.)

   * For developing C programs (no C++), you MUST download all of the above,
     plus the following:

    `v2gnu/bnu252b.zip'
          The GNU Binutils, including `as', the GNU assembler, and `ld', the
          GNU linker, and their docs.

    `v2/djdev200.zip'
          C header files, minimal development environment, DJGPP-specific
          utilities and documentation.

    `v2/djtst200.zip'
          A set of example programs to test your installation.

    `v2gnu/gcc272b.zip'
          The GNU C Compiler binaries and docs.

    `v2gnu/txi360b.zip'
          Info, a stand-alone program to read GNU hypertext documentation
          files, and an environment to produce such files.  Without it, you
          cannot read the docs included with the GNU software tools.

   * For developing C++ programs, you will need all of the above, plus the
     following:

    `v2gnu/gpp272b.zip'
          The GNU C++ compiler binary and docs.

    `v2gnu/lgp271b.zip'
          The C++ header files and the GNU classes libraries, and their docs.

    `v2gnu/obc272b.zip'
          If you want to develop Objective-C programs, you will need this
          file, which includes the Objective-C compiler and header files.

   * The following are some optional packages which you might want:

        - Debugging:

         `v2gnu/gdb412b.zip'
               GDB, the GNU Debugger and its docs.  (Note that the `djdev'
               distribution includes two simpler debuggers, `edebug' and
               `fsdb'.  The latter presents a user interface similar to that
               of Turbo Debugger.)

        - Additional development tools (consider getting at least the Make
          distribution):

         `v2/djlsr200.zip'
               The sources of the DJGPP C library.

         `v2gnu/flx252b.zip'
               Flex, a Lex-like lexical analyzer generator, and its docs.

         `v2gnu/bsn124b.zip'
               Bison, a Yacc-like parser generator, and its docs.

         `v2gnu/dif271b.zip'
               GNU Diffutils (diff, cmp, diff3, sdiff), and their docs.

         `v2gnu/mak373b.zip'
               GNU Make program with its docs.

         `v2gnu/pat21b.zip'
               GNU Patch program and docs.

         `v2gnu/sed118b.zip'
               GNU Sed program and its docs.

        - Developing text-mode and graphics GUI applications:

         `v2tk/grx20.zip'
               The DJGPP graphics library.

         `v2tk/bcc2grx.zip'
               The interface library to convert Borland graphics calls to GRX
               library calls.

         `v2tk/pdc22.zip'
               Public-domain Curses library.

     For description of additional files not mentioned here, get the file
     `00_index.txt', it contains a full list of the distribution files and a
     short description of every file.

4.5 How much disk space will I need?
====================================

**Q*: Wow, that's a lot of files.  How much disk storage will I need?*

*A* :  The following lists the approximate disk space required for several
major configurations, and additional storage required for some optional
packages (binary distributions only):

     Execution-only environment..................300 KBytes
     Developing C programs.......................10 MBytes
     Developing C++ programs.....................13 MBytes
     Developing Objective-C programs.............11.5 MBytes
     Additional storage for C Library sources....2.7 MBytes
     Additional storage for GDB..................1.1 MBytes
     Additional storage for Flex.................280 KBytes
     Additional storage for Bison................310 KBytes
     Additional storage for Diffutils............560 KBytes
     Additional storage for Make.................520 KBytes
     Additional storage for Patch................120 KBytes
     Additional storage for Sed..................73 KBytes
     Additional storage for Graphics libraries...2.8 MBytes

In addition to the space for installing the software, you will need some free
disk space for the swap file.  You should leave enough free disk space to
make the total virtual memory at least 20 MBytes; that will be enough for
most applications.  Invoke the `go32-v2.exe' program without arguments to see
how many DPMI memory and swap space can DJGPP applications use.  Depending on
your DPMI host, you might need to review its virtual memory settings in
addition to leaving free disk space; `CWSDPMI' needs only the disk space.

4.6 Can I get away with less megabytes?
=======================================

**Q*: The above table means that I need more than 15 MBytes for C/C++
development environment; that's about 7 1.44MB diskettes to hold the
compressed archive!!  Seems to me DJGPP is afflicted by the *fatware*
disease...*

**Q*: Pulling that much megabytes through the net from my overloaded SimTel
mirror is almost impossible.  Can't you prepare a ZIP archive which only
includes stuff I can't do without?*

*A* : There is a number of shareware/freeware programs floating around which
allow to format DOS diskettes to almost twice their usual capacity, so you
can use less floppies.  One such program is 2M, available from SimTel mirrors
as 2mNN.zip, e.g. ftp://ftp.coast.net/SimTel/msdos/diskutil/2m20.zip.

To make downloading DJGPP easier, download and compile the `BatchFTP'
program.  It allows you to submit a script of FTP commands and will
repeatedly try to login into the FTP site you specify until the script is
successfully completed.  It is smart enough to understand the messages which
the FTP server sends to you (like `login refused' etc.) and also is nice to
the remote server by sleeping for some time between login attempts.
`BatchFTP' is free software and can be found on many FTP sites, e.g.
ftp://oak.oakland.edu/pub/unix-c/networks/batchftp.tar.Z.

`BatchFTP' is a Unix program; those who access the net from their PC (not by
dialing into some Unix host), can use a nice FTP-automating utility called
`AutoWinNet' (get the file autownNN.zip from your nearest SimTel mirror, e.g.
ftp://ftp.coast.net/SimTel/win3/winsock/autown18.zip).

5. The DJGPP Documentation
**************************

  This chapter explains where to find and how to read DJGPP documentation, and
how to solve occasional problems with the docs system.

5.1 Where are the documentation files?
======================================

**Q*: I don't see any documentation files...*

*A* :  The documentation files are in the `info/' subdirectory of your main
DJGPP installation directory.  You will need a program to read these docs,
which are hypertext structured files.  You have several choices:

  a. Use the stand-alone `Info' reader.

     Get the file txi360b.zip, e.g.
     ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/txi360b.zip, which
     includes `INFO.EXE' and its docs.  Unzip it and run `Info'.  It will
     bring up a (hopefully) self-explanatory online help system.  Confused?
     Press `?' to see the list of all Info commands.  Still confused?  Press
     `h' to have `Info' take you on a guided tour through its commands and
     features.

  b. Use the `Info' command of your favorite Emacs-like editor.

     If you use Emacs, you already know about `Info'.  (What's that?  You
     don't?  Type `C-h i' and you will get the top-level menu of all the Info
     topics.)


5.2 How to read the docs without `Info'?
========================================

**Q*: I'm too old/lazy/busy to learn yet another browser, and I despise
uGNUsable programs like Emacs.  How in the world can I read the DJGPP docs??*

*A* :  Info files are almost plain ASCII files, so you should be able to
browse them with your favorite text file browser or editor.  You will lose
the hypertext structure and you might have hard time finding the next chapter
(hint: look up the name of the Next node at the beginning of this node, then
use the search commands of the browser, or the Grep program, to find that
name), but other than that you will see all the text.

Anthony Appleyard <A.APPLEYARD@fs2.mt.umist.ac.uk> has translated the Info
files for GNU C/C++ Compiler (`gcc.iNN') and GNU C Preprocessor (`cpp.iNN')
into ISO-8859 (aka plain ASCII), and Stephen Turnbull
<turnbull@shako.sk.tsukuba.ac.jp> has made them available on his anonymous
ftp and WWW server.  You can get them as `gcc.txt' and `preprocessor.txt' by
anonymous ftp, e.g. ftp://turnbull.sk.tsukuba.ac.jp/pub/djgpp/doc/; or get
them with your Web browser, at this URL:

     http://turnbull.sk.tsukuba.ac.jp/pub/djgpp/doc/

You can also produce pure ASCII files yourself, if you have their Texinfo
sources.  These are usually called `*.txi' or `*.tex' and should be included
with the source distribution of every package.  To produce an ASCII file
`foo.txt' from the Texinfo file `foo.txi', invoke the `Makeinfo' program like
this:

      makeinfo --no-split --no-headers --output foo.txt foo.txi

The `Makeinfo' program is part of the Texinfo distribution which is available
in txi360b.zip, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/txi360b.zip.

5.3 How to print the docs?
==========================

**Q*: I like my docs the old way: printed on paper, stacked near my
workplace.  How can I print the documentation files which come with DJGPP?*

*A* :  You will need to get and install a program called TeX or its
work-alike, like LaTeX or emTeX.  (They are NOT part of DJGPP.) Then run your
TeX work-alike on the docs' *source* files (called `*.txi' or `*.tex') which
you get with every `*s.zip' file you download.  You will get a `.dvi' file
which you can print; or you can run a DVI-to-PostScript converter like
`DVIPS' to produce a PostScript output.  `DVIPS' is a free program; you can
find it with your `archie' client.

DJGPP comes with a program called `TEXI2PS' which can convert *.txi files to
a crude PostScript; try it if you don't care much about the appearance of the
printed docs.

If TeX won't run, check that you have the file `texinfo.tex' which defines
the TeX macros specific to Texinfo files.  If you don't, get the GNU or DJGPP
Texinfo distribution which includes that file.

Note that some docs files (notably, those for GCC) will produce voluminous
print-outs.  You *have* been warned!

5.4 Where can I find docs in PostScript?
========================================

**Q*: I don't have all these fancy packages, and I don't have disk space to
install them in the first place.  Can't you guys just include with DJGPP a
set of ready-to-print PostScript files?*

*A* :  They are *very* large and would eat up too much storage (much more
than the fancy packages you don't want to install).  Most of the people read
the docs on-line and never print them anyway.  Sorry.

However, some *Good Samaritans* from all across the Net have taken time and
effort to produce the docs in PostScript format and made them available by
anonymous ftp.  The most full set of docs for the latest versions of GNU
software is available in plain ASCII, `zip' and `tar.gz' format by anonymous
ftp from phi.sinica.edu.tw, e.g. ftp://phi.sinica.edu.tw/pub/aspac/gnu/; they
are all for A4 paper.  Other places to look for PostScript versions of GNU
documentation are:

In European A4 format, e.g. ftp://liasun.epfl.ch/pub/gnu/ps-doc/.
In US letter format, e.g. ftp://primus.com/pub/gnu-ps/.
Many GNU manuals in `HTML' (hypertext) format, suitable for reading with your
Web browser can be viewed at the DJGPP Web site, at this URL:

     http://www.delorie.com/gnu/docs/

DJGPP includes a utility called `TEXI2PS' which converts the Texinfo source
files to crude PostScript; try it.

5.5 Some docs are nowhere to be found...
========================================

**Q*: I looked in my `info/' subdirectory, but I can't find docs for some of
the utilities, like `Sed' or `Gprof'.*

*A* :  Download the source archive (`*s.zip') for that package and look
inside it, usually in the directory called `man' or `doc'.

5.6 What are these `foo.1' files?
=================================

**Q*: Some docs files are called `foo.1' or `bar.man' or `baz.nroff', and
they seem to be written in some weird format which is very difficult to read.
How can I convert them to readable text files?*

*A* :  That weird format is the `troff' format which is used for writing Unix
manual pages.  The Unix command `man' converts them to formatted text files
which are usually displayed with a program like `more' or `less' (and here
`less' is considered to be more than `more' :-)).  The formatted file
includes bold and underlined letters produced by over-typing using Backspace
characters.  To format these files, you can choose one of these methods:

   * Get and install a DOS port of the `groff' package, or port it yourself
     (a very difficult task).  The latest `groff' distribution can be found
     on the GNU ftp archive, e.g. ftp://ftp.gnu.ai.mit.edu/pub/gnu/ or any of
     its mirrors.

   * Get and install `CAWF', a DOS program which knows about most of the
     `troff' formatting commands.  `CAWF' can be found on SimTel and its
     mirrors, e.g. ftp://ftp.coast.net/SimTel/msdos/textutil/cawf404.zip.

   * Write or port a `man' clone.  Source for one such clone was posted to
     the DJGPP newsgroup, so you can get it there, at this URL:

          http://www.delorie.com/djgpp/mail-archives/djgpp/1995/06/19/12:57:43

   * Format the file on any Unix machine, and download the results to your PC.
     Under Unix, typing `catman -p' will print the commands which are
     required to do this; you can then run those commands on your `*.1'
     `troff' source files.

No matter which of the above methods you choose, you will need some kind of
browser which understands how to show bold and underlined letters instead of
backspace-over-typed characters.  I suggest to download a DOS port of GNU
Less, e.g. ftp://ftp.coast.net/SimTel/vendors/gnu/gnuish/less291x.zip, which
uses colors to show bold and underlined letters.  Another possibility is to
get the latest official GNU `Less' distribution which can be compiled out of
the box with the Microsoft C compiler (but I didn't try to do so).

Another possibility to read formatted man pages would be with an Emacs
editor, if you use one.  Emacs has a special command to read man pages.

Beginning with version 3.6, the stand-alone `Info' program can also read man
pages (it invokes a subsidiary program `man' to format them, then displays
its output; see the file `readme.dj' in the DJGPP Texinfo distribution for
more details on how to set this up).  So if you have the DJGPP Texinfo
distribution, you can read man pages with `Info' already; if not, just
download Texinfo, e.g. ftp://ftp.coast.net/SimTel/vendors/djgpp/txi360b.zip.

Note that, for GNU packages, the man pages aren't always updated on a regular
basis.  If you need more up-to-date information, see the Info files.

5.7 What if the docs don't say enough?
======================================

**Q*: OK, I've got the docs and have read it, but I still can't figure out
some details.*

*A* :  Download the sources and look there, or ask on the net--either the
DJGPP mailing list or an appropriate GNU Newsgroup.

6. When the Compiler (or `Make', or `Info', or ...) Crashes...
**************************************************************

  This chapter explains how to deal with certain problems which may prevent
DJGPP programs from running on your machine.  The first 7 items on the next
menu describe specific problems; if yours doesn't go away with these
techniques, read the description of the general debugging procedure in
Section 6.8.

6.1 Buggy DPMI host can crash v2.x programs
===========================================

**Q*: When I try to run Info, it crashes imediately...*

**Q*: I cannot run v2.0 applications: they all hang or reboot my system,
while v1.x apps run OK.  Is this what v2.0 is all about--getting me out of
the DJGPP community?*

*A* :  No, believe it or not, we don't want to oust you.  Your problems might
be caused by a buggy "DPMI" (see DOS Protected Mode Interface in Section
22.4) host installed on your machine.  One DPMI host which is particularly
known to be a source of trouble is the DPMI server which comes with Novell
NWDOS.  Please see if v2.0 programs run when you disable DPMI services of
your usual configuration (DJGPP will then use the CWSDPMI program supplied
with DJGPP).

Another DPMI host which is known to cause problems in DJGPP is Quarterdeck's
QDPMI which comes with QEMM 7.5.  It was reported to cause `Info' and all
DJGPP debuggers to crash.  If you use QDPMI, upgrade to the version 7.53 or
later (patches for that version are available from the Quarterdeck's ftp
site), or disable QDPMI and use CWSDPMI.

6.2 GCC can crash during optimization
=====================================

**Q*: When I compile my program, the compiler crashes, but the problem seems
to go away if I compile without optimization.*

*A* :  GCC 2.6.0 was known to have such bugs, especially when compiling C++
programs, but it can also happen for later versions.  (This is usually a
genuine GCC bug, not something special to DJGPP.)  Upgrade to the latest
version of GCC.  If the problem won't go away, then narrow the offending code
fragment using the `#if 0 ... #endif' paradigm.  If this fragment includes an
error, correct it and try again; if it is syntactically and semantically
correct, then rewrite it as equivalent, but syntactically different one.

You can also try to disable the strength-reduction optimizations of GCC by
using the `-fno-strength-reduce' switch.  GCC has a known bug in that type of
optimizations; this bug raises its ugly head on rare occasions, but is
notoriously hard to hunt when it does.  (The stock v2.0 distribution should
by default disable this kind of optimizations on the `lib/specs' file.)

As an extreme measure, don't optimize at all, if that's the only way to make
your program work.

Another reason for this could be some problem with your system hardware or
the BIOS (like if you set an incorrect number of wait states when accessing
memory).  To check, try running the same compilation on another machine, or
review your BIOS settings.

6.3 What does "Fatal signal X" mean?
====================================

**Q*: I get "fatal signal 2" when I run GCC.*

**Q*: GCC aborts with "Internal compiler error" when compiling a large C++
program.*

*A* :  When GCC reports a "signal", it really means that an error occurred
trying to run the given program.  The "signal" number is the DOS error code,
and 2 means "file not found" (dig out your DOS reference for other error
codes).  This means GCC couldn't find some program it needs to run to compile
your source.  Check the `COMPILER_PATH' environment variable or what the
`COMPILER_PATH' line in the `DJGPP.ENV' file says, and make sure they point
to the directory where DJGPP programs reside.  Also check that the named
directory has all the required programs: `cpp.exe', `cc1.exe', `cc1plus.exe',
`cxxfilt.exe', `gasp.exe', `as.exe', `ld.exe', and (for Objective-C)
`cc1obj.exe'.  You can use the `-v' switch to GCC to see what programs it
invokes.

The "Internal compiler error" message usually means a genuine bug in GCC
(which should be reported to FSF), but it can also happen when GCC requests
additional chunk of memory, but the DPMI server fails to allocate it because
it exhausts available memory for its internal tables.  CWSDPMI can fail like
this if an application asks for a larger number of small memory chunks.  You
can enlarge the maximum space that CWSDPMI uses if you get a CWSDPMI heap-fix
patch, e.g. ftp://ftp.neosoft.com/pub/users/s/sandmann/csdpmi1heapfix.zip.
You can also run `stubedit' on `cc1plus.exe' and enlarge its maximum stack
size to 512K bytes (some people report that they needed to enlarge both the
heap of CWSDPMI and the stack of the C++ compiler to make this problem go
away).

For a program that you wrote, another work-around is to use an alternative
algorithm for `sbrk,' by putting the following somewhere in your program:

       #include <crt0.h>
       int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;

6.4 What does "Unknown filetype" mean?
======================================

**Q*: I get error messages saying "Unknown filetype" from GCC.*

**Q*: Since a few days ago, whenever I try to run most of the DJGPP programs,
they print a message "C:DJGPPBINprog.exe: not COFF" and just terminate.
Help!!!*

*A* :  It might be that your `STUBIFY.EXE' are infected by a virus.  (This is
*not* a joke!  It did happen to a few of us and can happen even to you.)  As
the DOS stub prepended to the DJGPP programs is very small, most viruses
cannot attach themselves to it without overwriting the beginning of the DJGPP
COFF image, therefore triggering this error from the code in the stub that
loads the COFF image.

Another possible cause of the "Unknown filetype" message is that you mix v2.0
`gcc.exe' driver with `cc1plus.exe', `cc1.exe' or other programs from an old
v1.x distribution.

6.5 You can't use `QEMM' auto/off mode with DJGPP
=================================================

**Q*: Why do I get error message from `CWSDPMI' if I keep QEMM in auto/off
mode and run DJGPP?*

*A* :  When QEMM is in auto/off mode and there isn't anything in the system
that is using any of QEMM's features, the CPU remains in real mode.
Normally, when CWSDPMI finds the CPU in real mode, it will try to use raw XMS
services to access the extended memory.  Unfortunately, when some program
requests XMS services, it will cause QEMM to turn on.  So if CWSDPMI tries to
switch into protected mode, QEMM will trap it and give a protection violation
warning.  To avoid this unfortunate event (which requires a system reboot to
fix), CWSDPMI first checks to see if enabling XMS caused the CPU to switch
into v86 mode (meaning QEMM just turned on).  If so, CWSDPMI gracefully exits
after telling you it can't work in this set-up, like this:

      "Error: Using XMS switched the CPU into V86 mode."

All you have to do to work around this is force QEMM to be ON whenever you
run DJGPP programs so that CWSDPMI will know how to work with it properly.
To do this, just turn QEMM on before running any DJGPP program, with this
command:

      c:\qemm\qemm on

(that assumes your QEMM directory is `c:\qemm').

6.6 Compiler hangs, but only when invoked from Make
===================================================

**Q*: My compiles run OK from the command line, but hang when I invoke the
compiler from Make.*

*A* :  Be sure you are invoking the correct Make program.  Borland Make was
reported to cause trouble when you invoke GCC with it.  It might be that
another program called Make is found earlier on your `PATH' than the Make
which came with DJGPP.

If you use Make compiled under DJGPP v1.x, you will also experience all kinds
of trouble when invoking programs compiled under DJGPP v2.0.  That's because
v1.x programs cannot spawn v2.0 programs directly (the v1.x program sees that
the child is a DJGPP program and tries to call `go32' to run it).  The result
usually will be that the child crashes.  If that's your problem, be sure to
upgrade your `Make' to the port distributed with v2.  (Note that v2.x
programs generally know how to spawn both v1.x and v2.x programs.)

Some users report that v1.x programs might sometimes hang or reboot the
machine when invoked from v2.0 Make, if the Makefile calls the v1.x program
by a name longer than the 8+3 DOS filename restriction.  To work around,
truncate the filename of that program in the Makefile.

6.7 Info doesn't like some files
================================

**Q*: When I run the Info browser, it tells me it cannot find the node "Top".*

*A* :  Check your installation of info files.  The file `DJGPP.ENV' in the
root of your DJGPP installation mentions the variable `INFOPATH' which should
point to the directory where Info looks for its files.  It must find there a
file named `dir', the file you are trying to read, and other files with
`.iNN' or `.NN' extension, where `NN' is a number.

Assuming the above checks OK, and all the necessary info files are indeed
installed in those directories (did you remember to give that `-d' switch to
`PKUNZIP'?), it might be that some of the files were edited with a DOS-based
editor, which converted the Newline characters to the CR/LF pairs.  Some DOS
ports of Info don't like this, because this invalidates the tag tables
included with the files, which Info uses to quickly find the various nodes.

To solve the problem, upgrade to the latest versions of Info ported to DJGPP,
which don't have this problem (beginning from version 3.6).

If you cannot upgrade for some reason, run `DTOU.EXE' on the offending files,
it will strip the extra CR characters to make Info happy.  DTOU is in your
`bin/' subdirectory of the main DJGPP directory.

6.8 My problem isn't mentioned above!
=====================================

**Q*: I've installed DJGPP just like explained in `README.*' files, but when
I run gcc, my machine crashes/hangs/needs cold boot.*

**Q*: When I compile my program, gcc says "Segmentation violation" and prints
all kinds of funny numbers and registers.*

**Q*: I get errors I can't figure out when I try to compile something.*

*A* :  Add the `-v' switch to the GCC command line and run it again.  It will
print all the subprograms (compiler passes) it is running.  Then you can see
which subprogram caused the error, or where does your machine crash.  This
might give you a hint on what's wrong.

6.9 I can't keep up with the error messages
===========================================

**Q*: I want to read all the error messages that GCC throws on me, but they
are so many that I can't keep up.  How can I redirect them to a file?*

**Q*: When I add `-v' to the GCC command line, how can I put all the
voluminous output into a file, so I don't miss anything when reporting a
problem?*

**Q*: I have this nifty graphics program which bombs from time to time, but
the registers and traceback info is hidden by the graphics display.  How can
I see it?*

*A* :  There are several alternatives:

  a. You can use a shell smarter then `COMMAND.COM', such as `4DOS', which
     knows how to redirect standard error stream to a file.  4DOS is
     shareware and can be found on SimTel, e.g.
     ftp://ftp.coast.net/SimTel/msdos/4dos/.

  b. You can also run your program under any one of the programs which save
     the output of programs they spawn in a file.  I suggest using a program
     called `SCRIPT', which is similar to its Unix namesake.  It has an
     advantage of saving everything which goes to screen *and* showing it on
     the screen at the same time.  You can find SCRIPT on SimTel, e.g.
     ftp://ftp.coast.net/SimTel/msdos/screen/script11.zip.

  c. Or you can use the `REDIR' program which comes with DJGPP.  It also
     redirects standard output and/or standard error to a file, but you don't
     get a chance to look at the output while the program runs.

6.10 How to search DJGPP archives for similar problems
======================================================

**Q*: OK, I have all this voluminous output of `gcc -v', but I still have no
clue.*

*A* :  Your problem might be one which already have been solved on the DJGPP
Newsgroup.  DJ Delorie <dj@delorie.com> has set up a searchable Newsgroup
archive on his Web server, at this URL:

     http://www.delorie.com/djgpp/mail-archives/

You can search the *entire* mailing list archives in just a few seconds.
DJ's archives are always up to date, as they receive and store all posted
messages automatically, but the index is updated every 24 hours, so the last
day might not be searchable yet.  To search the DJGPP archives at DJ's, point
your Web browser to the above URL and specify a list of keywords pertinent to
your problem.  You will get a list of messages which include those keywords;
clicking on any of the messages will get the full text of that message.

Stephen Turnbull <turnbull@shako.sk.tsukuba.ac.jp> has set up another search
engine which you can use to search the entire Newsgroup archive for an
arbitrary regular expression, at this URL:

     http://turnbull.sk.tsukuba.ac.jp/cgi-bin/search

Point your Web browser to that URL and do whatever the instructions you get
tell you.  You will receive a list of lines in the archive which contain your
regexp, with a two-line surrounding context.  You can use this to decide
which parts of the archive you need to download and read.

Steve's archives can also be fast-searched, at this URL:

     http://turnbull.sk.tsukuba.ac.jp/yaseppochi-gumi.html#djgpp

using any Web browser supporting `ISINDEX' capabilities.  This is faster, but
supports only simple keyword searches, not regular expressions.

You can also download `gzip''ed copies of DJGPP correspondence split up by
months (the most recent month might not be up-to-date) from the anonymous ftp
server set up by Stephen Turnbull <turnbull@shako.sk.tsukuba.ac.jp>.  They
are available at turnbull.sk.tsukuba.ac.jp, e.g.
ftp://turnbull.sk.tsukuba.ac.jp/pub/djgpp/list-archive/.  If you look for the
traffic from a specific time period, you should look for files named
`djgpp.YYMM.gz' (they are around 250K bytes each), where YY is the year and
MM is the month number.  E.g., for February 1996 traffic get the file
`djgpp.9602.gz'.  Alternatively, look for the file which holds list traffic
for the year and the month you need with your Web browser, at this URL:

     http://turnbull.sk.tsukuba.ac.jp/pub/djgpp/list-archive/

Once you have the Newsgroup archives, or a relevant portion(s) thereof,
search for your problem by using some keywords specific to your problem, like
"crash", "violation", etc.  The archive is just a text file, so any text file
viewer/editor with search capability can do it.

6.11 How to ask DJGPP gurus for help
====================================

**Q*: I've searched the Newsgroup archives, but didn't find anything helpful.
I am totally lost.  *Help!!!**

**Q*: I don't have time to download all these huge files, not to mention
looking through them.  Can't you DJGPP gurus help me?  *Please??**

*A* :  To get fast and effective solution to your problem, you will have to
supply the relevant info about your system, and exactly in what way does it
go wrong.  To gather this info, do the following:

   * At the DOS command prompt, type `set > environ.lst', then press RET.

   * Invoke the `go32-v2' program (it's in your `bin/' subdirectory) and save
     its output.

   * Post to the comp.os.msdos.djgpp Newsgroup or write to the DJGPP mailing
     list <djgpp@delorie.com> and put into your message the description of
     your calamity, the contents of the file `ENVIRON.LST', the output of
     `go32-v2', the contents of your `AUTOEXEC.BAT' and `CONFIG.SYS', and
     what GCC printed during compilation with the `-v' switch.

   * Allow for up to 2 days (more on weekends) for all the reply messages to
     come in, then act according to what they recommend.

Be warned that you might get several dozens of messages in reply to your
request; this is not meant to overflow your mailbox or sabotage your
relationship with your system manager, it's just the usual friendly response
of fellow DJGPP'ers to your lonely cry for help.  Some of the replies might
suggest what you already checked and reported in your original message, or
even miss the point altogether.  Be ready for this and don't flame us for
trying to help you as much as we can.

7. Compiler Performance
***********************

**Q*: Why GCC is compiling sooo slooowww?*

*A* :  That depends on what you mean by "slow".  The following table gives
"normal" gcc compilation speed, in source lines per second, on a 486DX2-66:

                 |  Without optimization  |  With -O2
      -----------+------------------------+------------
      C++ source |        200             |   100
      -----------+------------------------+------------
      C   source |        430             |   250

(Btw, these numbers are about 20% faster than you will get on a 40MHz Sparc2
box.)  On machines faster or slower than 486DX2-66, scale these numbers
appropriately.  When comparing to this table, don't forget to count header
files your program `#include''s in the total line count.  And *don't* check
compilation speed on very short programs (like the classic ```Hello,
world!'''), because the overhead of loading the multiple passes of the
compiler will completely hide the compiler performance.

If your results are close to these (deviations of a few percents are
considered "close" here), then that's as fast as you can get with GCC.  If
they are *significantly* lower, you may indeed have a problem; read on.

First, check to see if GCC pages to disk when it compiles.  This is
manifested by a heavy disk traffic which won't go away even if you have a
large write-back disk cache installed.  To be sure, disable the virtual
memory services for your DPMI host (for `CWSDPMI', use the `SWSDPR0' as your
DPMI host, or get the `CWSPARAM' program and change the swap filename to
point to a non-existent drive), then run the compilation again: if the
compiler aborts with an error message saying there isn't enough memory, then
it *is* paging.

If paging does happen, you need to free more extended memory.  If you have a
RAM disk, make it smaller, or don't use it at all (it only makes compiles to
run about 10% faster), or make your disk cache smaller (but don't discard the
disk cache altogether); if you have other programs which use extended RAM,
make them use less of it.  Failing all of the above, buy more RAM (see the
description of reasonable configuration in Section 3.7).  Also see
recommendations for optimal software configuration in Section 3.8.

If GCC doesn't page, check settings of your disk cache.  If you don't use a
cache, install one--this can slash your compilation times by as much as 30%,
more so when compiling a large number of small files.  If you already have a
cache, enable its delayed-write (aka write-back, aka staggered-write)
operation.

If you had some of the beta releases of v2.0 installed during the
beta-testing period, be sure to upgrade your `CWSDPMI' to the latest version.
The memory allocation scheme has been changed halfway through the
beta-testing, which made old versions of `CWSDPMI' *awfully* slow when used
with programs linked against the new library versions.

It is also worthwhile to check the settings of your system BIOS.  In
particular, the following items should be checked against your motherboard
vendor recommendations:

     Internal and external CPU cache....set to Enable
     CPU cache scheme...................set to Write-back, if possible
     DRAM and SRAM wait states..........vendor-recommended optimal values

Incorrect or suboptimal settings of the above items can explain as much as
30% performance degradation on 486 machines, and as much as 500% (!) if you
have a Pentium CPU.

DJ Delorie <dj@delorie.com> reports that his well-tuned 90 MHz Pentium system
with 32 MBytes of RAM and 4 MBytes of RAM disk compiles the entire GCC source
in about 20 minutes (this takes about 45 minutes on a 40MHz Sparc2).

For very large (several MBytes) executables which are built from a large
number of small source files, the link stage might be the one which needs
more RAM than you have free, and thus be the bottleneck of the time it takes
to build your program.  Check that the size of the executable isn't larger
than the amount of your free RAM.  If it is, then it might make sense to use
a smaller (or even no) disk cache, and allow the linker as much physical RAM
as it needs.  Be sure that the linker wasn't stub-edited to make its transfer
buffer too small (the default 16KB should be more than enough).

8. Compile-time and Link-time Problems
**************************************

  Being of a Unix origin, GCC has a somewhat different flavor of command-line
syntax and its peculiar compilation and link algorithms.  It also has a
plethora of optional switches, some of them obscure or semi-documented.
These are known to confuse users, especially those who had previous
experience with DOS-based C compilers.

  This chapter explains how to solve some of those problems which tend to
appear when compiling and linking your programs.

8.1 GCC can't find headers or libraries
=======================================

**Q*: When I run the compiler it says it couldn't find header files and/or
libraries.  But the headers and libraries are all there, so why won't it find
them?*

*A* :  In order for the compiler to find its include files, libraries and
other stuff it can't do without, you should have the following variable set
in your environment:

      DJGPP=c:/djgpp/djgpp.env

and it should point to the correct path of the file `DJGPP.ENV' on your
system (the file itself comes with the file djdev200.zip, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2/djdev200.zip in the DJGPP
distribution).  In the above example it is assumed to be in the `C:/DJGPP'
directory, but you should set it as appropriate for your installation.

If the DJGPP variable is set correctly, then check the following possible
causes of this misbehavior:

   * You renamed the `gcc.exe' driver to some other name.  For example, you
     might be using the real-mode GCC and call it something like
     `gcc-rm.exe', so you could use the protected-mode version also.  In this
     case, you should edit the file `DJGPP.ENV' to add a section called (in
     our example) `[gcc-rm]' which is an exact duplicate of the section
     called `[gcc]'.  DJGPP start-up code uses this file to find environment
     variables which it should put into environment before your `main'
     function is called, but it searches for the relevant variables using the
     actual name of the program, so when you rename the executable, it can't
     find its section and doesn't put the necessary variables into the
     environment.

   * Your `FILES=' setting in `CONFIG.SYS' is insufficient, so GCC runs out
     of available handles.

     You should have at least `FILE=15' in your `CONFIG.SYS'.

   * Your DJGPP directory is on a networked drive, and the network redirector
     doesn't have enough available handles in its configuration.

     Presumably, there should be a parameter in some configuration file or a
     command-line argument to one of the network drivers which sets the number
     of files that can be open simultaneously on a networked drive; you should
     set it to be at least 15.

8.2 GCC can't find C++ headers
==============================

**Q*: I installed all the packages, but GCC complains it can't find
`iostream.h', `_string.h' and other C++ headers.  Where can I find those
header files?*

**Q*: GCC complains about it being unable to find `Complex.h', `Regex.h' and
other header files which start with a capital letter, and I indeed don't see
them in my `lang/cxx/' directory.  Where are they?*

**Q*: My C++ program needs header files whose filenames exceed the 8+3 DOS
filename restrictions, like `stdiostream.h' and `streambuf.h', and GCC cannot
find those files.  How in the world can I write portable C++ programs??*

*A* :  C++ include files are in the file lgp271b.zip, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/lgp271b.zip.  Files whose
names usually start with a capital letter, on MS-DOS have an underscore `_'
prepended so they could be distinguished from `complex.h', `regex.h' and the
like under case-insensitive DOS.  Change `Complex.h' to `_complex.h' in your
source, and GCC will find them.

If you have problems with header files with long filenames, and you run under
Win95 or some other environment which allows for long filenames, try
disabling the "Long File Names" (LFN) support in DJGPP, by setting the `LFN'
environment variable to `No,' like this:

       set LFN=n

(DJGPP comes with LFN disabled by default on the `DJGPP.ENV' file, but you
might have enabled it.)  If this makes the problems to go away, then you have
some conflict between the way LFN is supported by DJGPP and your environment.
Under Win95, you must rename the files which should have long filenames to
those long names (as opposed to the truncated names you find in the DJGPP
archives).  You must also set the option in the Win95 registry which disables
name-munging of the files which have exactly 8 characters in their name part.
This is how:

   * From the "Start" menu select "Run" and type `regedit', to start the
     Registry Editor.

   * Expand the `HKEY_LOCAL_MACHINE' branch of the registry until you see in
     the left pane an item called
     `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem,' then
     click on it.

   * The right pane now shows the list of values assigned to the `FileSystem'
     key.  If you don't see an item there called `NameNumericTail,' select
     "New", "Binary Value" from the "Edit" menu, then type `NameNumericTail'
     and it will appear.  Now double-click on `NameNumericTail' and enter a
     value of 0.

   * Restart Windows 95.

8.3 GCC barfs on C++-style comments in C programs
=================================================

**Q*: My C program compiles OK with Borland's C, but GCC complains about
"parse error before `/' " at a line where I have a "//"-style comment.*

*A* :  That's because // isn't a comment neither in ANSI C nor in K&R C.
Borland and Microsoft C compilers support it as an extension.  GCC also
supports this extension (beginning with version 2.7.0), but using the `-ansi'
or `-traditional' switches to GCC disables this extension.  In general, it's
a bad practice to use this extension in a portable program until such time as
the ANSI C standard includes it.  If it's a C++ program, then rename it to
have a suffix which will cause gcc to compile it as such (see list of
language-specific suffixes in Section 8.4), or use `-x c++' switch.  If it's
a C program, but you want to compile it as C++ anyway, try `-x c++'; it can
help, but can also get you in more trouble, because C++ has its own rules.
For example, the following program will print 10 if compiled as a C program,
but 5 if compiled as C++:

         #include <stdio.h>
     
         int
         main ()
         {
           printf ("%d \n" 10    //*
     		     / 2    //*/
     		       1
     		       );
           return 0;
         }

(While admittedly perverse, this little monstrosity was written with a the
sole purpose to demonstrate that C and C++ have quite different semantics
under certain circumstances.)

If you must have both `-ansi' and C++-style comments, you can use the
`-lang-c-c++-comments' preprocessor switch.  Gcc doesn't accept the
`-lang-XXX' switches on its command line, so you will have to use the `-Wp'
option, like this:

      gcc -c -Wp,-lang-c-c++-comments myprog.c

Alternatively, you can add `-lang-c-c++-comments' to the `*cpp:' section of
your `lib/specs' file (but that will make it permanent).

Bottom line: until the future ANSI/ISO C standard includes this as part of
the C language, it's best to change those comments to C-style ones, if you
really mean to write a C program.  The following `Sed' command will convert a
C program with C++-style comments into a valid C source, provided you don't
have the string "//" in a character string:

      sed "s?//\(.*\)?/*\1 */?" file.c > newfile.c

Sed can be found in the DJGPP distribution, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/sed118b.zip.

8.4 How does GCC recognize the source language?
===============================================

**Q*: I type `GCC PROG.CC' and GCC complains that it can't recognize
`PROG.CC''s file format.  How come a C++ compiler doesn't recognize a C++
source??*

**Q*: I type `GCC PROG.C' to compile a C program which I already remember to
pass compilation without a single warning, and suddenly it gives all kinds of
strange error messages and unresolved externals.*

*A* :  That's because you typed your source file extension in *upper* case.
GCC is *not* case-insensitive about filenames like DOS is, and it uses the
file's extension to determine how to compile a file.  Valid extensions are:

`.cc'
`.C'
`.cxx'
`.cpp'
     C++ source (passed through cpp).

`.c'
     C source that must be passed through cpp first.

`.i'
     Raw C source (no cpp pass).

`.ii'
     Raw C++ source (not to be preprocessed).

`.m'
     Objective-C source.

`.S'
     Assembler that must be passed through cpp first.

`.s'
     Raw assembler source (no cpp pass).

Any other file is passed to the linker, under the assumption that it's an
object file.

In the examples above, `PROG.C' is taken as C++ program, not a C one, and
`PROG.CC' is passed to the linker as if it were an object file.  You can see
what GCC does by adding `-v' switch to the GCC command line; if you see it's
invoking `cc1plus.exe' (the C++ compiler) instead of `cc1.exe' (the C
compiler), or calling `ld.exe' (the linker) on a source file, then you'd know
this is your problem.  If you have problems keeping up with the verbose GCC
output caused by `-v', see how to capture GCC output in Section 6.9, in this
FAQ.

You can override the default rules gcc uses to decide how each input file
should be treated, with the help of `-x LANGUAGE' switch.  For instance, the
command

      gcc -x c++ prog.c

compiles `prog.c' as a C++ source.  See -x LANGUAGE switch description in
"The GNU C Compiler Manual", or point your Web browser to
http://www.delorie.com/gnu/docs/gcc/gcc_8.html#SEC11, for more info on `-x'
options.

8.5 Problems with Objective C
=============================

**Q*: How do I tell gcc my .cc file is to be compiled as Objective-C source?*

**Q*: I compile an Objective-C program, but get unresolved symbols.*

**Q*: I can't compile the Objective-C test program which came with DJGPP.*

*A* :  Give your sources the `.m' extension, or use `-x objective-c' switch
to GCC, so it will *know* you mean to compile with Objective C.

Objective-C was broken in GCC 2.6.0.  The problem manifests itself by
unresolved modules.  If you use that version, you'll have to upgrade to
version 2.6.3 or higher.

8.6 Writing codes fragments which are specific to DJGPP
=======================================================

**Q*: I must put a DJGPP-specific code fragment into my program.  What symbol
should I use in the `#ifdef' directive to make it only visible under DJGPP?*

*A* :  Use `__DJGPP__,' like this:

         #ifdef __DJGPP__
         ... DJGPP-specific code ...
         #else
         ... not seen under DJGPP ...
         #endif

`__DJGPP__' has a value of the DJGPP major revision number, so you can write
code fragments which have different behavior under different versions of
DJGPP:

         #ifdef __DJGPP__
         #if __DJGPP__ > 2
         .... will work only in DJGPP v3.x and later ...
         #else
         .... get here for DJGPP v2.x ...
         #else
         .... get here in DJGPP v1.x or non-DJGPP environment
         #endif

Another DJGPP-specific pre-processor symbol which DJGPP defines is
`__GO32__'; but it is only provided for compatibility with previous versions
of DJGPP (v1.x) and its use should be discouraged.

8.7 Unresolved externals when linking programs
==============================================

**Q*: Why do I get so many unresolved symbols when linking my programs?*

*A* :  By default, GCC instructs the linker to only look in two libraries:
`libgcc.a' and `libc.a'.  Some functions aren't included there, so the linker
can't find them.  GPL library routines, like obstack and regex packages are
in `libgpl.a' library; append `-lgpl' to the link command line to use them.
To use C++ classes in the `libgpp.a' (it's called `libg++.a' on Unix
systems), append `-lgpp'.  If you only use the `iostream' classes and don't
want your program to be affected by the GNU Copyleft, use the `libiostream.a'
library by appending `-liostream' (these are also included in the `libgpp.a'
library).

When linking C++ programs, you can use the `gxx' instead of `gcc' command; it
will then instruct the linker to also scan the C++ libraries.

If your program uses a lot of floating-point math, or needs math functions
beyond those specified in the ANSI/ISO standard, consider appending `-lm' to
your link command line.  The basic math functions required by ANSI/ISO
standard are included in the `libc.a' library, but `libm.a' includes higher
quality versions of these functions, and also some functions not included in
the default library, like Gamma function and Bessel functions.

8.8 How not to lose your head with all these libraries
======================================================

**Q*: I'm lost with all those different libraries.  How in the world can I
find out which functions are included in which library?*

*A* :  You can use the `nm' program to check what functions are included in a
library.  Run it with `-C' option and with the library as its argument and
look in the output for the name of your function (the `-C', or `--demangle'
option makes the function names to look closer to what they are called in the
source file).  Functions which have their code included in the library have a
capital `T' before their name.  For example, the following is a fragment from
the listing produced by `nm':

         c:\djgpp\lib> nm --demangle libc.a
         .
         .
         .
         stdio.o:
         000000e4 b .bss
         000000e4 d .data
         00000000 t .text
         00000098 t L12
         0000001e t L3
         00000042 t L6
         0000004d t L7
         0000006a t L9
         00000000 t __gnu_compiled_c
     	     U _filbuf
     	     U _flsbuf
         00000000 T clearerr
         000000ac T feof
         000000c2 T ferror
         000000d8 T fileno
         0000000c T getc
         00000052 T getchar
         0000002a T putc
         0000007c T putchar
         00000000 t gcc2_compiled.
         .
         .
         .

Here we see that the module `stdio.o' defines the functions `clearerr,'
`feof,' `ferror,' `fileno,' `getc,' `getchar,' `putc' and `putchar,' and
calls functions `_filbuf' and `_flsbuf' which aren't defined on this module.

Alternatively, you can call `nm' with the `-s' or `--print-armap', which will
print an index of what symbols are included in what modules.  For instance,
for `libc.a', we will see:

         c:\djgpp\lib> nm --print-armap libc.a
         .
         .
         .
         _feof in stdio.o
         _ferror in stdio.o
         _fileno in stdio.o
         .
         .
         .

which tells us that the functions `feof,' `ferror' and `fileno' are defined
in the module `stdio.o'.

`nm' is fully described in the GNU docs. See the Binutils package docs in
"GNU Binutils Manual", or point your Web browser to
http://www.delorie.com/gnu/docs/binutils/binutils_6.html#SEC5.

8.9 DJGPP uses a one-pass linker
================================

**Q*: I give all the libraries to gcc, but I still get unresolved externals
when I link.  What gives?*

*A* :  `Ld' is a one-pass linker, it only scans each library once looking for
unresolved externals it saw *until that point*.  This means the relative
position of object files and libraries' names on the command line is
significant.  You should put all the libraries *after* all the object files,
and in this order:

      -lgpp -lgpl -lm

E.g., to link files main.o and sub.o into a C++ library, use the following
command line:

      gcc -o main.exe main.o sub.o -lgpp -lgpl

or, if you compile and link in one command:

      gcc -o main.exe main.cc sub.cc -lgpp -lgpl -lm

If you have any libraries of your own, put them *before* the above system
libraries, like this:

      gcc -o main.exe main.cc sub.cc -lmylib -lgpp -lgpl -lm

When you use the `gxx' compilation driver to compile a C++ program, it names
the C++ libraries in the correct order.

If your installation tree is different from the default, i.e., if you keep
the libraries *not* in the default `lib/' subdirectory, then you should add
that directory to the line in the `[gcc]' section of your `DJGPP.ENV' file
which starts with `LIBRARY_PATH', or put into your environment a variable
called `LIBRARY_PATH' and point it to the directory where you keep the
libraries.  Note that if you invoke the linker by itself (not through the gcc
driver), then `LIBRARY_PATH' will have no effect, because this variable is
only known to the gcc driver.  So if you must call `ld' from the command
line, use the `-L' option to tell it where to look for the libraries.

8.10 C++ functions still not found
==================================

**Q*: I put all the libraries in the above order, but the linker still can't
find some C++ functions from `complex.h' and `iostream.h'.*

*A* :  These functions are declared `inline' and defined on these header
files.  However, GCC won't inline them unless you compile with optimizations
enabled, so it tries to find the compiled version of the functions in the
library.  Workaround: compile with `-O'.

8.11 The linker complains about __pure_virtual function.
========================================================

**Q*: When I link a C++ program, the linker complains about "__pure_virtual"
being an unresolved symbol.  What should I do?*

*A* :  This problem is caused by a `libgcc.a' library which lacks a module
called `___pure_virtual' (yes, with *three* leading underscores!).  You
should get an updated version of that library which includes such a module.
`libgcc.a' comes with the Gcc distribution, so look in the latest
`gccNNNb.zip' file.

If, for some reason, you cannot find `libgcc.a' with that module, you can add
it yourself.  To this end, create a file called `pure.c' with this content:

     #define MESSAGE "pure virtual method called\n"
     
     void __pure_virtual()
     {
         write(2, MESSAGE, sizeof(MESSAGE) - 1);
         _exit(-1);
     }

Compile this file and put the object file into `libgcc.a', like this:

             gcc -c pure.c
             ar rvs libgcc.a pure.o

That's all!

8.12 C++ programs yield large `.exe' file
=========================================

**Q*: It seems that declaring a large `static' array has an effect of
bloating the program image on disk by that many bytes.  Surely there is a
more compact way of telling the loader to set the next N bytes of RAM to
zero?*

*A* :  This only happens in C++ programs and is a (mis-)feature of GCC.  You
can use the `-fconserve-space' switch to GCC to prevent this from happening,
but it also turns off the diagnostics of duplicate definitions, which, if
uncaught, might cause your program to crash.  Thus, this switch isn't
recommended for programs which haven't been completely debugged (if there is
such a creature).  The `-fconserve-space' switch is described in the GCC
docs, See GNU C Compiler docs in "GNU C Compiler Manual", or point your Web
browser to http://www.delorie.com/gnu/docs/gcc/gcc_11.html#SEC14.

If the downside of using this switch doesn't deter you, you can even add this
switch to your `lib/specs' file to make it permanent.

9. Running Compiled Programs
****************************

  This chapter discusses various problems which may happen when running DJGPP
programs under different environments, and gives solutions to them.

9.1 My program crashes only in v2.0!
====================================

**Q*: I have this program which runs fine when compiled with DJGPP v1.12, but
crashes and burns in v2.0.  Isn't it obvious that you guys blew it with v2.0?*

**Q*: My v2.0 program crashes, but only under CWSDPMI; it runs OK under other
DPMI hosts like Windows, OS/2 or QDPMI.  Is this a bug in CWSDPMI?*

*A* :  Not necessarily so, it could still be a bug in your program which just
went unnoticed in v1.12.  One area where such things can happen is use of
uninitialized memory.  In v1.x, memory first allocated to the stack or by a
call to `malloc' is always zeroed, but v2.0 doesn't behave this way, so your
program might exhibit erratic behavior or crash with `SIGSEGV' because of
such bugs.  In particular, if the program behaves differently depending on
which program was run before it, you might suspect bugs of this kind.

To check whether this is the source of your grief, include the header
`crt0.h' in your `main' and set `_crt0_startup_flags' to
`_CRT0_FLAG_FILL_SBRK_MEMORY'; this will fill the memory with zeroes when it
is first allocated.  If the program will run OK after recompilation, then
this is probably the cause of your problem.  To make spotting uninitialized
memory simpler, you can set `_crt0_startup_flags' to
`_CRT0_FLAG_FILL_DEADBEAF' (don't laugh!); this will cause the sbrk()'ed
memory to be filled with the value `0xdeadbeaf' which is easy to spot with a
debugger.  Any variable which has this value, was used without initializing
it first.

Another possible cause of problems will most probably be seen under CWSDPMI.
Unlike other DPMI hosts, CWSDPMI supports some DPMI 1.0 extensions which
allow DJGPP to capture and disallow illegal dereference of pointers which
point to addresses less than 1000h (aka "NULL pointer protection").  This
feature may be disabled by setting the `_CRT0_FLAG_NULLOK' bit in
`_crt0_startup_flags'; if this makes SIGSEGV crashes to go away, your program
is using such illegal pointers.

9.2 What is that gibberish printed when my program crashes?
===========================================================

**Q*: My program dies with a cryptic message like "Segmentation violation" or
"Unsupported DOS request" or "General Protection Fault" and prints some
funny-looking numbers.  Can't I get some decent human-readable traceback
information, so I could pinpoint where in the program did the problem happen?*

*A* :  Those "funny-looking numbers" *are* the traceback.  They describe the
sequence of function calls which led to the fatal error by giving you the
addresses where each function was called.  You can have these addresses
translated to source line numbers by using the `SYMIFY' program (it is
included in the djdev200.zip, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2/djdev200.zip, and should be in
your `bin/' subdirectory).  To this end, make sure that your program was
compiled with `-g' switch, linked *without* `-s' switch and *not* stripped,
and that you have the source files available in your current directory.  Now
invoke your program and do whatever it takes to make it crash.  Then, with
the traceback still on the screen, type this from the DOS command line:

      symify your-program-name

You will see the list of source files and line numbers right next to their
hex addresses.  Now you can start debugging.

You can ask `SYMIFY' to put the stack trace into a file (so you can consult
it later, e.g., from your editor while fixing the bug), by giving it an
output file, like this:

      symify -o problem.dmp yourprog

You can also save the raw stack trace (without source info) to a disk file
and submit it to `SYMIFY' later, like this:

      symify -i core.dmp yourprog

This comes in handy when your program grabs the screen (e.g., for some
graphics) and the stack trace can't be seen.  You can then redirect the stack
trace to a file in Section 6.9, e.g., with the`REDIR' program which comes
with DJGPP.

But what if you *didn't* compile your program with `-g', and you aren't sure
how to recreate the problem which crashed it, after you recompile?  Well, you
can submit the stack dump *after* you recompile your program.  Just press
that PrintScreen key or otherwise save the stack trace, then submit it to
`SYMIFY' from a file as described above, after you've recompiled the program.
Be sure to give gcc all the compilation switches (sans `-s') that you gave
it when you originally compiled your program (in addition to `-g'), including
the optimization switches, or else the addresses shown in the stack trace
might be invalid.

9.3 Reading and writing binary files
====================================

**Q*: I'm reading/writing data files, but the data gets corrupted.*

**Q*: When I read a file I get only a small portion of it.*

*A* :  Are your data files binary?  The default file type in DOS is "text",
even when you use `read' and `write' library functions.  Text files get their
Newlines converted to CR-LF pairs on write and vice versa on read; reading in
"text" mode stops at the first ^Z character.  You must tell the system that a
file is binary through the `b' flag in `fopen,' or `O_BINARY' in `open,' or
use the `setmode' library function.

You can also use the low-level `_read' and `_write' library functions which
give you the direct interface to the DOS file I/O.

9.4 Buffered screen I/O surprises
=================================

**Q*: My program prompts the user to enter data from the keyboard, then reads
its response.  When compiled with a 16-bit compiler like BCC or MSC it works
as expected, but with gcc the prompt doesn't show, or is printed much later
in the program.*

*A* :  Do you write to screen using buffered I/O (`fprintf,' `fputs' and the
like) functions?  Then maybe your program defined a large buffer for standard
output streams.  If so, the buffer is not written to screen until it's full,
which might produce very unpleasant and unexpected behavior when used in
interactive programs.

It is usually bad idea to use buffered I/O in interactive programs; you
should instead use screen-oriented functions like `cprintf' and `cputs'.  If
you must use buffered I/O, you should be sure that both `stdout' and `stderr'
are line-buffered or unbuffered (you can change the buffering by calling the
`setvbuf' library function); another solution would be to `fflush' the output
stream before calling any input function, which will ensure all pending
output is written to the operating system.  While this will work under DOS and
DJGPP, note that some operating systems (including some DOS extenders) might
further buffer your output, so sometimes a call like `sync' would be needed
to actually cause the output be delivered to the screen.

9.5 What do DJGPP programs need to run?
=======================================

**Q*: When I copy my DJGPP application program to another PC where no DJGPP
is installed, I can't run it.  It complains that it cannot find DPMI (??).
Do I really need all of your multi-megabyte installation to run compiled
programs?*

*A* :  No, you don't.  You can either (1) bring the `CWSDPMI.EXE' free DPMI
host to the target machine and put it in the same directory as your compiled
program or somewhere along the `PATH,' or (2) install another DPMI host (such
as QDPMI, 386Max, Windows, etc.) on the target machine.  Note that the author
of CWSDPMI, Charles W Sandmann <sandmann@clio.rice.edu>, requests a
notification by mail or acknowledged e-mail in case you distribute CWSDPMI
with a commercial or shareware products.

If your program could be run on a machine which lacks floating-point
processor, you should also distribute an emulator, or link your program with
an emulator library.  See floating-point emulation issues in Section 11.1.

Future DJGPP releases might have a way to bind your executable with `CWSDPMI'
to produce a stand-alone program.  If you need such a feature *now* and if
you need it *badly*, ask Charles W Sandmann <sandmann@clio.rice.edu> to make
this happen as soon as he can.

10. Writing and Running Graphics Programs
*****************************************

  This chapter discusses some problems and explains some subtle points related
to graphics programming under DJGPP.

10.1 Accessing the video memory
===============================

**Q*: I try to access the video memory at `0xa0000,' but get "Segmentation
violation" ...*

**Q*: How can I access the text-mode video memory of my VGA?*

*A* :  Absolute addresses of memory-mapped devices are mapped differently
under DJGPP, than what you might be used to under other DOS development
environments. That's because DJGPP is protected-mode environment, where you
can't just poke any address: that's what protected mode is all about!  To
access such absolute addresses, use the so-called "farptr" functions like
`_farpeekb' and `_farpokew'; they are described  in the C Library reference.
See more details on using "farptr" functions to access absolute addresses in
low memory in Section 18.4, below.

For text-mode screen updates, you can also use the `ScreenUpdate' and
`ScreenUpdateLine' library functions to quickly update the screen from a text
buffer.

Using `_farpeekX'/`_farpokeX' paradigm to access memory isn't much slower
than direct access (they compile into 2 machine instructions when
optimizations are enabled).  But if you need even more fast access (and don't
want to write it in assembly), See using the "nearptr" access facilities in
Section 18.4, as described below.

11. Floating Point Issues and FP Emulation
******************************************

  This chapter deals with issues pertaining to floating-point code and
floating-point emulation under DJGPP.

11.1 Floating code without 80387
================================

**Q*: I don't have an 80387.  How do I compile and run floating point
programs?*

**Q*: What shall I install on a target machine which lacks hardware
floating-point support?*

*A* :  Programs which use floating point computations and could be run on
machines without 80387, should either be linked with `libemu.a' emulation
library (add `-lemu' to your link command line) or be allowed to dynamically
load the `emu387.dxe' file at run-time if needed.  Linking with libemu makes
distribution simpler at a price of adding about 20KB to the size of the
program `.exe' file (the emulator functions will be used only if no hardware
floating point support is detected at runtime).  You should *always* do one of
the above when you distribute floating-point programs.

A few users reported that the emulation won't work for them unless they
explicitly tell DJGPP there is no x87 hardware, like this:

       set 387=N
       set emu387=c:/djgpp/bin/emu387.dxe

There is an alternative FP emulator called `WMEMU' (get the file
`v2misc/wmemu2b.zip').  It mimics a real coprocessor more closely, but is
larger in size and is distributed under the GNU General Public License (which
generally means you need to distribute its source if you distribute
`wmemu387.dxe', or distribute the source or objects to your entire program,
if you link it with `libwmemu.a').  Its advantage is that with `WMEMU', you
can debug FP apps on a non-FPU machine.

11.2 Other FP emulators cannot be used with DJGPP
=================================================

**Q*: I have an 80387 emulator installed in my `AUTOEXEC.BAT', but
DJGPP-compiled floating point programs still doesn't work.  Why?*

*A* :  DJGPP switches the CPU to *protected* mode, and the information needed
to emulate the 80387 is different.  Not to mention that the exceptions never
get to the real-mode handler.  You *must* use emulators which are designed
for DJGPP.

11.3 Floating-point emulation under OS/2
========================================

**Q*: I run DJGPP in OS/2 DOS box, and I'm told that OS/2 will install its
own emulator library if the CPU has no FPU, and will transparently execute
FPU instructions.  So why won't DJGPP run floating-point code under OS/2 on
my machine?*

*A* :  OS/2 installs an emulator for native OS/2 images, but does not provide
FPU emulation for DOS sessions.

11.4 DJGPP doesn't support `-msoft-float'
=========================================

**Q*: I've read in the GCC Info file that gcc has a `-msoft-float' option
which is said to generate library calls for floating point support.  Can this
facility be used for FP emulation on a machine without x87?*

*A* :  Gcc Info file also says that the library required by `-msoft-float' is
*not* part of GNU C compiler.  As nobody wrote such a library for DJGPP
(yet), this option currently isn't supported.

11.5 Numeric exceptions--sometimes
==================================

**Q*: I have a program which works with FP emulation, but dies with "Numeric
Exception" when run on a machine with a co-processor.  It also runs OK when
compiled with Microsoft C.  Can't you people make your floating-point code
right?*

*A* :  This might be still a problem with your program.  Under DJGPP, the
80x87 control word is set up so that it generates an exception when your
program feeds it with a "NaN" ("Not a Number"), while the emulator doesn't
have this behavior.  You should check that your program doesn't generate
NaNs, or set 80x87 control word to a different value.  There is a program
called ctrl87.c, e.g. ftp://ftp.delorie.com/pub/djgpp/contrib/ctrl87.zip,
which enables this kind of diddling the 80x87 control word; check it out.
There is also a library function called `_control87' which can be used from
within a program to set the coprocessor to a non-default state.

11.6 Floating point inaccuracies when using emulator
====================================================

**Q*: I am experiencing inaccurate results in some floating point
calculations, sometimes in the 2nd or 3rd significant digit (like getting
118.401 instead of 120.0).  This is really unacceptable!  (And no, I'm *not*
using a buggy Pentium CPU.)*

*A* :  Are you using the emulator?  If so, it might be that the emulator
isn't as accurate as you expect.  One particular known problem is that it
does a bad job when computing `atan' function.  So if you use `atan(1.)' to
get the value of `Pi', that might be your problem.  Solution: make `Pi' a
constant, as God intended.  The header file `<math.h>' includes the constant
`M_PI' which you can use; or get the value of Pi from the net, at this URL:

     http://www.diku.dk/~terra/pi.html

12. Debugging DJGPP Programs
****************************

  This chapter discusses the debuggers you can use with DJGPP and answers some
of the questions you might have when debugging DJGPP programs.

12.1 How to run a DJGPP program under debugger
==============================================

**Q*: How do I debug my programs?*

*A* :  First, remember to use the `-g' switch when you compile and link.
This puts debugging information into your executable.  When linking, don't
use the `-s' switch, and give the name of the output file *without the .exe
extension*, so that `gcc' would leave both the COFF output and the DOS
executable after the link stage.  Here are a few examples of compilation and
link command lines when you intend to debug a program:

      gcc -Wall -c -g -O myfile.c
     
      gcc -Wall -O2 -g -o myprog mymain.c mysub1.c mysub2.c -lm
     
      gcc -g -o myprog myprog.o mysub.o

(Note that with `gcc', you can use optimization switches when compiling with
`-g'.)

Then, to debug the program, use a command line like this (here for `gdb'):

      gdb myprog

You can use on of several available debuggers with DJGPP:

  a. `FSDB', the full-screen debugger, from the `djdev' distribution.  This
     presents a user interface like that of Borland's Turbo Debugger, but
     unlike TD, *it isn't a source-level debugger* (although it will show the
     source code together with the machine instructions).  It also supports
     data-write breakpoints: a powerful feature for hunting down code which
     overwrites data it shouldn't touch.

  b. The GNU Debugger, `GDB' (get the file gdb412b.zip, e.g.
     ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/gdb412b.zip.  This is a
     powerful source-level debugger, but it uses a line-oriented user
     interface.  Note that the initial commands are read from a file named
     `gdb.ini' instead of `.gdbinit' which is illegal filename under MS-DOS.

You invoke any debugger like this:

      <debugger-name> <program> <args...>

12.2 You need QEMM 7.53 or later
================================

**Q*: Whenever I call any DJGPP debugger to debug my program, it crashes
immediately.*

*A* :  Are you running under Quarterdeck's QDPMI?  Then you should upgrade to
QEMM 7.5 patch-level #3 or later.  That patch corrects a subtle problem in
QDPMI which was triggered by the debugger.  If you cannot or wouldn't
upgrade, for money or love, turn OFF the DPMI services of QDPMI and use
`CWSDPMI' as your DPMI host.  To disable QEMM DPMI services either uninstall
QDPMI, or go to the QEMM directory and issue the following command:

      qdpmi off

12.3 GDB won't debug unless it sees COFF output
===============================================

**Q*: I try invoking GDB on my program, but it says: "not in executable
format: File format not recognized."  Huh?*

*A* :  Most probably, you've invoked GDB on a `.exe' program.  GDB needs to
be called with the name of un-stubbed COFF executable as its argument.  To
get both a `.exe' and a COFF file, you should make your link command line to
look this way:

      gcc -o foo foo.o

instead of

      gcc -o foo.exe foo.o

(the latter will only produce `foo.exe', while the former produces both
`foo', the COFF executable which gdb needs, and `foo.exe').

To produce a COFF file from a `.exe' program, use the `EXE2COFF' program
which comes with DJGPP, like this:

      exe2coff foo.exe

12.4 Debuggers use the transfer buffer.
=======================================

**Q*: My program corrupts files and screen writes, and otherwise behaves
strangely when run under a debugger.*

*A* :  Do you use the transfer buffer to move data between your program and
conventional (under 1 MByte) memory?  Then it might be that the debugger
corrupts your I/O. The debugger itself uses the transfer buffer for disk read
requests and screen writes.  If you single step through any of your app
routines which use the transfer buffer, the debugger might overwrite its
contents, which may alter the correct behavior.

To work around this, don't step with the debugger through your functions
which use the transfer buffer.

If all of the above doesn't make sense for you, don't worry: if you don't
know what the transfer buffer is, and you only trace into your own functions,
then you won't hit this problem.

12.5 How to debug a graphics program
====================================

**Q*: How can I debug a graphics program?  The debugger runs my program fine,
but when a breakpoint is hit with the screen in a graphics mode I can't read
the text printed by the debugger.*

*A* :  Redirect the debugger output to your printer, like this:

      gdb myprog > prn

This will only work if the program itself doesn't write to stdout (this is
usually the case with graphics programs); otherwise the debugger output will
get mixed up with your program's output.

The FSDB debugger can switch between the application screen and the debugger
screen, so you might use it, at a price of working with low-level debugger.
Press `Alt-F5' to switch between the two screens.

As yet another possibility, consider using the `MSHELL' program which will
redirect I/O from any program to the monochrome, monitor at the BIOS level,
so you can use it even with GDB.  `MSHELL' was written by DJ Delorie
<dj@delorie.com> and is available as mshell10.zip, e.g.
ftp://ftp.delorie.com/pub/djgpp/ofc/mshell10.zip.

12.6 GDB finds only `.cc' source
================================

**Q*: When I try to debug my C++ programs, the debugger claims it can't find
the source file:*

      file.cc: No such file or directory.

*The source file *is* there, but it's called `file.cpp', not `file.cc'.  Why
does this happen?*

*A* :  It's a bug in GCC.  It erroneously assumes that a C++ source always
has a `.cc' extension.  Until this bug is corrected in some future version of
GCC, you're better off calling your C++ files `*.cc'.  If this is
unacceptable, then you can work around this bug by invoking `cc1plus' and the
assembler pass manually.  The bug in GCC manifests itself in that `cc1plus'
is called with the option `-dumpbase file.cc'.  If you replace this with
`-dumpbase file.cpp' (or whatever your extension is), the debugger will
happily find your sources.

12.7 Debuggers choke on some programs ...
=========================================

**Q*: I cannot debug Emacs (or any program that requests raw keyboard input):
when I press Ctrl-C, any debugger I tried reported SIGINT.  But I cannot
operate the debugged program without Ctrl-C (in Emacs, it's necessary to exit
the editor)!*

**Q*: I cannot debug any program which catches signals!!??*

**Q*: I compiled my program with `-pg' switch, and now I cannot debug it...*

*A* : There are currently a few limitations in debugging programs which use
interrupts or exceptions.  Programs compiled for profiling may crash with
SIGSEGV or a GPF, with no addresses that `symify' can identify; programs
using `alarm' or `setitimer' can't be debugged, either.  You can't hook the
keyboard interrupt in a debugged program, and you can't debug a program which
uses floating point on a machine without an FP hardware (unless you use
`WMEMU' as your emulator).  If your program catches signals, the debugger
will catch them instead and they won't get passed to the debuggee.

At least some of these limitations will be fixed in future versions of DJGPP.
For now, the only work-around that's available is for the case that you need
a `Ctrl-C' keypress to go to the debuggee instead of the debugger: use the
`Alt-Numeric-3' (that is, simultaneously press the `Alt' key and the `3' key
on the numeric keypad, then release the `Alt' key).

13. Profiling DJGPP Programs
****************************

  This chapter explains how to optimize your program for speed using the
profiler, and discusses some problems you might have with it.

13.1 How to profile a DJGPP program
===================================

**Q*: How can I profile my program to see where it spends most of its run
time?*

*A* :  DJGPP includes a profiling facility.  To use it, compile and link with
`-pg' option, run your program as you usually would, then run a program
called `gprof':

      gprof myprog

(change `myprog' to whatever name your program is).  This will print an
execution profile.

`Gprof' is part of GNU Binutils distribution, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/bnu252b.zip.

13.2 Gprof won't work unless it can find COFF executable
========================================================

**Q*: When I run `Gprof', it complains that it cannot find my program.  But
I've just run it!!*

**Q*: I run `Gprof' on my program, and it says: "bad format".*

*A* :  `Gprof' needs the original COFF file the linker produced.  If you
delete it, or feed `Gprof' with the `.exe' file instead, it will be most
unhappy.  The way to produce the COFF output is explained in the section
dealing with GDB in Section 12.3, above.

13.3 Where is Gprof docs?
=========================

**Q*: What about all those `Gprof' options?  Where can I find their docs?*

**Q*: I can't figure out some of the info in `Gprof' report ...*

*A* :  `Gprof' is only documented on a man page, `gprof.1'.  If you don't
have one, you will have to look for it in the Binutils distribution, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/bnu252b.zip.

13.4 Why is `__dpmi_int' so heavy used?
=======================================

**Q*: I've profiled my program and found that the routine which takes 60% of
the running time is some obscure library function called `__dpmi_int'.  Can't
you guys make your library right?*

*A* :  Does your program use I/O or other real-mode services (like BIOS)
extensively?  All those services are invoked through a DPMI service call
which is issued by `__dpmi_int'.  So what the profile really says is that the
running time of your program is governed by time-consuming operations such as
disk I/O.

14. Run-time Performance of DJGPP Programs
******************************************

  This chapter deals with issues pertinent to run-time performance of DJGPP
programs.

14.1 How efficient is DJGPP-generated code?
===========================================

**Q*: How does DJGPP compare with other DOS-based C compilers in terms of
efficiency of generated code?*

**Q*: Won't my program run *much* slower when compiled by DJGPP, due to all
those CPU cycles wasted in switches between protected and real mode?*

*A* :  The quality of code generated by GCC with optimization turned on
(`-O2' switch to the compiler) is generally at least as good as what you will
get from top commercial products, like Borland, Microsoft and Watcom.  Mode
switches indeed have a certain performance hit, but in most programs it is
negligibly small, because only DOS and BIOS services require such a switch,
and most programs spend most of their time doing other things.

14.2 My program's I/O is so slow!
=================================

**Q*: I measured time required to read a 2 MByte file in DJGPP and in Borland
C.  It took DJGPP program 2.5 seconds to do it, while Borland did it in just
under 2.  Isn't that *horribly* slow performance??*

**Q*: I tried to improve DJGPP I/O throughput by defining a 64KB-large buffer
for buffered I/O with a call to `setvbuf,' but that had no effect.  Why is
that?*

*A* :  Doing I/O from protected-mode programs requires that low-level library
functions move the data between the extended memory and low memory under 1
MByte mark, where real-mode DOS can get at it.  This area in the low memory
is called the "transfer buffer".  This data shuffling means that some I/O
speed degradation is inevitable in any protected-mode program which runs
under DOS.  By default, DJGPP moves data in chunks of 16 KB, so defining a
buffer larger than that won't gain anything.  The size of transfer buffer is
customizable up to a maximum of 64 KB, so if your program really reads a lot
of large files, you might be better off enlarging it (with the `STUBEDIT'
program).

That said, I would like to point out that waiting another 0.5sec for reading
a 2 MByte file isn't that bad: it is indeed about 25% longer than you can do
under DOS, but it's only half a second...  Besides, most programs read and
write files which are only a few hundreds of kilobytes, and those will suffer
only a negligible slow-down.

14.3 My ported program runs much slower!
========================================

**Q*: How come my program, which I ported from Borland C and which doesn't
use much I/O, still runs much slower under DJGPP? *

*A* :  Explore the following possible causes for this:

  a. Your program extensively calls services other than I/O which require mode
     switch (like BIOS Int 10h, mouse services, etc.).

     You can tell how much your program switches to real mode by profiling
     your program.  In the profile, look at the proportion of time your
     program spends in low-level library functions called `__dpmi_int' (which
     calls real-mode DOS/BIOS services) and `__dj_movedata' (which moves data
     between the transfer buffer and your program).  If this proportion is
     large, try rewriting your program to minimize use of those functions
     which require a mode switch, even at a price of more computation (a mode
     switch usually eats up hundreds of CPU cycles).

  b. Your program uses library functions/classes which are implemented less
     efficiently by GCC.  Or you might be a heavy user of functions which
     other compilers convert to inline code, while GCC doesn't inline most
     library functions.  If this is the case, you will see those functions as
     "hot spots" on the program histogram produced by the `Gprof' profiler.
     If you find this to be the problem, write your own, optimized versions of
     those functions.  It's best to write them as inline assembly functions,
     for maximum performance.  If you find library functions which are
     inefficient, please inform the DJGPP newsgroup by posting to
     comp.os.msdos.djgpp Newsgroup, so this could be fixed by people who
     maintain the library.

  c. If your program spends most of its time in a certain innermost loop, you
     might try enabling the strength-reduction optimizations.  This is
     disabled by default, because GCC has a known bug which sometimes causes
     it to generate incorrect code when this kind of optimization is enabled.
     If you decide to enable it, examine the behavior and the output of your
     program carefully, to be sure you didn't hit that bug.


15. Run-Time Memory Issues
**************************

  This chapter answers questions which are related to DJGPP run-time memory
allocation.

15.1 How much virtual memory do you have?
=========================================

**Q*: How much virtual memory can I use in DJGPP programs?*

*A* :  That depends on the DPMI host you are using.  CWSDPMI (the free DPMI
host which comes with DJGPP) will let you use all available conventional and
extended memory (up to 128M) and up to 128M of disk space, for a grand total
of 256M of virtual memory for your application.  Try a `malloc(50*1024*1024)'
some day.

With other DPMI hosts, your mileage may vary.  Quarterdeck's QDPMI, for
instance, has a bug in some of its versions which effectively disables
virtual memory under DJGPP (described under QDPMI VM bug in Section 15.3,
below), so you only have whatever free physical RAM is left.  Under Windows
3.x, the amount of virtual memory you get depends on various virtual memory
settings in the Control Panel and on the `.pif' file settings for the program
you run (see Windows allocation subtleties in Windows alloc, below).

15.2 It seems `malloc'/`free' don't affect virtual memory...
============================================================

**Q*: I did `malloc(50*1024*1024),' but didn't see any paging happen, and I
only have 8 MBytes of RAM on my machine.  Is this virtual memory thing for
real?*

**Q*: I `malloc''ed a large chunk of memory, but when I check values returned
by `_go32_remaining_physical_memory' or `__dpmi_get_memory_information,' I
don't see any change...*

**Q*: When I `free' allocated RAM, `_go32_remaining_physical_memory' reports
there was no change in the available RAM.*

*A* :  CWSDPMI (and, possibly, other DPMI hosts) only pages in memory when it
is actually accessed.  If you only `malloc' it, but don't actually access it,
it won't grab those pages.  Try `calloc' and see the *big* difference.

When you call `free,' DJGPP library doesn't return memory to the system, it
just adds it to its internal pool of free pages.  So, from the system point
of view, these pages are not "free".

15.3 Failure to get more memory than is physically installed
============================================================

**Q*: When I try to access more memory than the free physical RAM, `malloc'
returns a `NULL' pointer, or I get some cryptic error message like this:*

     DPMI: Not enough memory (0x00860000 bytes)

*or like this:*

     QDPMI: Memory Paging Violation: Illegal Page Reference [PTE=0000-0000h]
            [CR2=8006-3000h at 00E7h:0000-4936h]
     
     QDPMI: Unrecoverable Exception: 000Eh at 00E7h:0000-4936h.  Error Code = 0006h

*A* :  This is typical of Quarterdeck's DPMI host called QDPMI which comes
with QEMM386 version 7.53 and earlier.  Some versions of QDPMI (those which
come with QEMM v6.x) fail to resize memory block when the new size is more
than available physical RAM, even though virtual memory services are enabled;
other versions (those which come with QEMM v7.x) just don't let you allocate
more memory than is physically available.  If you must use more RAM than is
physically available, disable or uninstall QDPMI in Section 12.2, and use
CWSDPMI instead.

This bug was corrected in QDPMI version 1.10 or later, distributed with QEMM
beginning with version 8.0, so upgrading to the latest version of QEMM might
also be a solution.  With QEMM 6.x, make sure your programs don't override
the default type of `sbrk' behavior by setting `_crt0_startup_flags' to
`_CRT0_FLAG_UNIX_SBRK' (QEMM 8.0 and later can allocate virtual memory with
both types of `sbrk' algorithm).

If you use another DPMI host, make sure that virtual memory is enabled.
E.g., for 386Max, include the `swapfile=' parameter to establish a virtual
memory swap file; you can make it permanent (this will speed up DJGPP
start-up) with the `/p' option.

15.4 Memory allocation fails under QDPMI
========================================

**Q*: OK, I've changed my program to never allocate more memory than is
physically available, to work around that QDPMI VM bug in Section 15.3, but
my program still gets a `NULL' pointer from `malloc'/`calloc'!*

*A* :  Another peculiarity of QDPMI which came with QEMM before version 8.0:
it will never let you allocate a chunk which is larger than half of what's
available.  Several people reported the same to be true under Windows 95.

With some DPMI providers, this behavior might be triggered by a small
overhead of each `malloc' call: you might ask for half of available memory,
but the DJGPP implementation of `malloc' adds the overhead and then rounds
the amount of memory to the next power of 2 before calling `sbrk'; thus
`malloc(8MB + 1)' will actually request 16MBytes from the DPMI host.  When in
doubt, call `sbrk' directly, especially if you don't plan to free that memory
during execution.

15.5 Memory allocation fails under Windows
==========================================

**Q*: I'm running under Windows 3.x DOS box, but DJGPP complains about there
not being enough DPMI memory, although virtual memory is enabled.*

*A* :  You must make sure the size of your Windows swap file can be at least
2 times the largest virtual memory size you need.  Check if you have enough
free disk space; if you do, run a defragger (Windows needs the swap file to
be contiguous).  This size is normally limited by the the "virtual = 4 times
free physical" rule, but you can change that by inserting the line

      PageOverCommit=n

in the `[386Enh]' section of your `SYSTEM.INI' file.  The parameter `n' is 4
by default, but can be set to be as large as 20.

15.6 Memory allocation fails under EMM386 or HIMEM
==================================================

**Q*: My machine has 48 MBytes of RAM, but when I run DJGPP programs, they
start paging after 32 MBytes has been used...*

**Q*: I have 5 MBytes of free RAM on my machine, but DJGPP programs start
paging after only 256KBytes of memory were used??*

*A* :  This might be caused by some old version of memory manager installed
in your machine (like HIMEM or EMM386 from an old version of DOS), which were
limited to 32 MBytes of expanded memory.  Try running without them (CWSDPMI
can use raw extended memory), or upgrade to a newer version of DOS.

If your programs start paging after only 256KBytes of memory were used, most
probably you are using EMM386 and CWSDPMI, and your `CONFIG.SYS' specifies no
amount of memory when it installs EMM386.  EMM386 defaults to 256K in this
case; you should tell EMM386 explicitly how much memory should it take over.
You can use the `go32-v2' program to see what amount of extended memory your
DJGPP programs will get.

15.7 How much memory do parent DJGPP programs leave for their child?
====================================================================

**Q*: How much memory is available when I use the `system' call?*

*A* :  In the conventional (below 640K mark) memory, you are left with
everything which was free before your program started, except what the DPMI
host uses.  The amount of conventional memory required by the DPMI host
depends heavily on the host you use.  For the first DJGPP program, QDPMI uses
about 97K, CWSDPMI uses about 70K, Windows 3.x only 18 KBytes.  Each
subsidiary call to `system' (like in recursive invocation of `Make') eats up
about 18K (16K for the transfer buffer and 2K for the PSP and environment)
for most DPMI servers; a notable exception is QDPMI which needs 97K bytes of
low memory for the subsequent calls too.  If you change the size of the
transfer buffer (with `STUBEDIT'), the amount of free conventional RAM will
change accordingly.

Extended memory management is left to the DPMI server; DJGPP does nothing
special about XMS when `system' is called.  This means that all the extended
memory used by the parent program is *not* freed when the child program
starts; if the child requests more memory than is physically free, the DPMI
server is expected to page some of the parent out to honor the request.
(This is unlike DJGPP v1.x, where the `go32' extender would completely page
out the parent before starting the child.)  The advantage of this is that
spawning a child or shelling out is much faster in v2.0 than it used to be
with v1.x.

15.8 How much stack can I have in DJGPP programs?
=================================================

**Q*: My program bombs when I use very large automatic arrays.*

**Q*: How much stack space do I have in my program?*

**Q*: My program crashes with SIGSEGV, but the traceback makes no sense: it
points to something called ___djgpp_exception_table...  When I try to debug
this, the traceback mysteriously changes to some innocent library function,
like getc().  The same program works flawlessly when compiled with DJGPP v1.x
What's going on??*

*A* : DJGPP v2.0 programs impose a limit on the maximum stack size; this is a
bug/feature of the DPMI 0.9 specification.  By default, you have a 256KB-long
stack, but some programs which use large automatic arrays, or are deeply
recursive, might need more.  If the default stack size is not enough, you can
change it with `STUBEDIT' program (change the parameter "Minimum amount of
stack space"), or by setting the global variable `_stklen' in your program.
Example:

      extern unsigned _stklen = 1048576;

Setting `_stklen' makes sure your program always works, but wastes memory,
since the 256K stack originally allocated must be discarded.  The best bet is
to do both--setting `_stklen' in your program will ensure it works, but also
using `STUBEDIT' to set a slightly (by a few KB) larger amount than the value
of `_stklen,' will ensure the original stack won't have to be reallocated,
and you will save the wasted memory.

Programs which needs an unusually large stack might crash with bogus stack
trace, because parts of the heap get overwritten by the overflowing stack. To
see if that is the cause of such crashes, run `stubedit' on your program and
crank up the stack size to a large value (like 4MBytes).  If that makes the
problem go away, tune the stack limit to the minimum value your program can
live with, then set `_stklen' to an appropriate value as explained above.
(Some DPMI hosts will actually allocate the stack, even if not all of it is
used, so leaving it at unnecessarily large value will hurt the program on
low-memory machines.)

Some users have reported that they needed to enlarge the stack size of the
C++ compiler, `cc1plus.exe', to prevent it from crashing when compiling some
exceedingly large and complex C++ programs.  Another program that was
reported to need a stack larger than the default is `bccbgi.exe' from the
`BCC2GRX' package.

After you've used `STUBEDIT' to change the stack size, run it again to make
sure it displays as default the value you thought you entered.  This is
because STUBEDIT will sometimes silently set the stack size to 0 (and then
you will get the default 256K stack) if it doesn't like the value you type.

Under Windows, be sure you've allocated a sufficiently large swap file (let's
say, 40MBytes) from the Windows' Control Panel.

You should also make sure the `.PIF' file for your program doesn't have too
low limit on EMS/XMS usage (better make them both -1).  What's that?  You
don't have a `.PIF' file for this program?  Then Windows uses the default
`DOSPROMPT.PIF', which almost surely defines very low limits on these two,
and your program can't get the memory it needs for its stack.

16. Command-line Arguments Handling in DJGPP
********************************************

  DJGPP handles command-line argument differently from most DOS-based
compilers, to make it closer to Unix platforms (so that porting of Unix
programs will be easier).  This chapter answers some questions about this
aspect of DJGPP.

16.1 Filename wildcards expansion under DJGPP
=============================================

**Q*: Can I do filename globbing with DJGPP?*

**Q*: I call my program with an argument `x*y' and it complains about
something called `xyzzy'??...*

*A* :  The filename globbing in DJGPP is done by the start-up code, before
your `main' function is called.  Unlike other DOS-based compilers, where you
must link your program with a special object module if you want the program
to get expanded filenames, in DJGPP this is considered normal behavior and
performed by default on behalf of every DJGPP program.  The `x*y' above was
expanded to a file called `xyzzy' which was probably present in the current
working directory.  (If you don't want the default expansion, see how to
disable globbing in Section 16.2.)

In DJGPP, filename globbing works like in Unix, which is more general than
the usual DOS wildcard expansion.  It understands the following constructs
with special meta-characters:

`?'
     any single character.

`*'
     zero or more arbitrary characters, including a dot `.'

`[aA_]'
     any one of characters `a', `A', or `_'.

`[a-d]'
     any one of characters `a', `b', `c', or `d'.

`[!a-z]'
     anything *but* a lowercase letter.

`...'
     all the subdirectories, recursively (VMS aficionados, rejoice!).

`.../*'
     all the files in all subdirectories, recursively.

Unlike DOS, the `*' and `?' meta-characters can appear *anywhere* in the
filename pattern, like in `[a-z]*[0-9].*pp'.  You can also use `*' instead of
directories, like in `*/*/*.c', but *not* on drive letters (e.g., `[a-c]:/'
won't work).

An argument which cannot be expanded (no filenames matching that particular
pattern) will be passed to the program verbatim.  This is different from what
you might see under Unix, where some shells (like `csh') would say something
like "No match" and won't call your program at all.  DJGPP's behavior in this
case is like shells of the Bourne legacy (`sh', `ksh', and `bash').

16.2 How to disable filename wildcards expansion
================================================

**Q*: OK, but I don't want my program to glob its arguments (they aren't
files at all, but they include characters like `*' and `?').  What should I
do?*

*A* :  You have these alternatives:

   * Surround your arguments with single or double quotes (this is what you
     would do under a Unix shell).

   * Disable globbing for your program by linking it with your custom version
     of function with the special name `__crt0_glob_function' and make it
     always return a `NULL' pointer.  See the documentation of this function
     in the library reference.

16.3 How to pass command-line arguments with quotes or @
========================================================

**Q*: I have a file with a single quote in its name, but the quote seems to
be stripped away when I pass it to my program ...*

**Q*: How do I pass a command-line argument which contains double quotes? *

**Q*: How do I pass an argument which begins with the @ character?*

*A* :  This is because usually, the command-line arguments are expanded
("globbed") before they are passed to `main' (see description of filename
expansion in Section 16.1), and the quote characters serve to protect the
arguments from expansion.  You should escape-protect the quote characters
with a backslash.  For example, if you have a file called `myfile.c'v', type
it as `myfile.c\'v' when you call your program.  If you have single quotes in
your program arguments *and* you don't want those arguments to be expanded,
then surround them by double quotes, like this: `"*.c\'v"'.  The program will
get the string `*.c'v' with the double quotes stripped away.

Note that backslashes are only special if they are in front of a quote,
whitespace, or backslash (they also serve as DOS directory separators,
remember?).

The @ character serves to signal a "response file" (see the description of
response file method in Long commands), so it's also special.  To pass an
argument whose first character is @, surround that argument with single or
double quotes, otherwise it will be taken as a name of a response file which
holds the actual command line.

16.4 How to pass command lines longer than 126 characters
=========================================================

**Q*: Can I invoke my program with a command line longer than the infamous
DOS 126-character limit?*

**Q*: I have a Makefile of Unix origin which contains some *very* long
command lines.  Will it work with DJGPP?*

*A* :  Yes and yes.  DJGPP supports several methods of passing command-line
arguments which allow to work around the DOS 126-character limit.  These are:

   * The `!proxy' method.  If you invoke the program from within another
     DJGPP program (like Make or Gcc compilation driver), it gets the address
     of the memory block where the actual command line is stored.  The
     start-up code will detect this and use that info to retrieve the
     command-line arguments.

     This method is suitable only for invoking DJGPP programs from other DJGPP
     programs.  You don't have to do anything special to use this method, it
     is all done automagically for you by the library functions like
     `system,' `spawnXX' and `execXX' on the parent program side, and by the
     start-up code on the child side.  (In case you wonder, the name `!proxy'
     comes from the the string which identifies the use of this method:
     instead of getting the actual command line, the program gets `!proxy'
     followed by the address of the actual command line.)

   * The GNUish MS-DOS method.  This was invented when some GNU programs were
     ported to 16-bit MS-DOS compilers as part of GNUish MS-DOS project.  The
     arguments are passed as values of the environment variables which are
     called `_argc,' `_argv0,' `_argv1,' etc.  Note that the variables' names
     are indeed all-lowercase, which means you cannot use this method from
     DOS `COMMAND.COM' prompt.

     This method is suitable for invoking DJGPP programs from GNUish ports of
     GNU software, like real-mode Make program found on SimTel mirrors, e.g.
     ftp://ftp.coast.net/SimTel/vendors/gnu/gnuish/gmake371.zip, some ports
     of Unix shells (like ms_sh, e.g.
     ftp://ftp.coast.net/SimTel/msdos/shell/ms_sh23.zip), etc.  You can also
     use it in your real-mode programs by creating the above environment
     variables.

     Note that DJGPP programs can only *use* this method, but they don't
     *generate* GNUish-style environment variables, so you *cannot* use this
     method to pass long command lines between DJGPP and non-DJGPP programs,
     unless your program explicitly creates these variables before calling
     `execXX'/`spawnXX'.

   * The response file method.  Any argument which starts with a @ character
     (like in `myprog @file') will cause the named `file' to be read and its
     contents used as command-line arguments, like in many DOS-based
     compilers and linkers.  If you invoke your DJGPP program from DOS
     command line, this would be the only method available for you to pass
     long command lines (like when calling `Gawk' or `Sed' without `-f'
     option).

     Note that this method makes @ special when it is the first (or the only)
     character of a command-line argument, which should be escape-protected
     if you want to use it verbatim (see how to pass the @ character in
     Section 16.3).

Of course, if the start-up code doesn't see any of the above methods, it will
use the command line by default.

16.5 What is the maximum length of command line under DJGPP
===========================================================

**Q*: What is the longest command line I can pass to gcc when it is invoked
by `Make'?*

*A* :  The arguments are passed to DOS Exec call (Int 21h function 4Bh) via
the transfer buffer which is 16KB-long.  Apart of the command line, it is
also used to pass other info, such as the `!proxy' parameters and the copy of
the environment for the child program (let's say, less than 2000 bytes in
most cases, but your mileage may vary).  This leaves at least 13K bytes for
arguments (including a separating blank between any two arguments).  So
unless your arguments span more than 160 screen lines, you shouldn't worry.

This limit depends on the size of the transfer buffer, so check how large is
the value recorded in the stub header of any program before you pass it
extremely long command lines.  The linker (`ld.exe') is the first program you
should worry about, because it usually gets long command lines (they include
the list of all the object files and libraries to be linked).

16.6 Why Make passes only 126 characters to programs?
=====================================================

**Q*: I use Make to compile with GCC, but GCC gets only the first 126
characters of its command line.  Didn't you just explain in so many words
that invoking a DJGPP program (GCC) from another DJGPP program (Make) can
safely pass up to 13K characters of command-line arguments using the `!proxy'
method?*

*A* :  Check your Makefile for `SHELL = command.com' statements, or for
commands which include pipe or redirection characters like `>', `|', etc.  If
Make sees any such statements, it will invoke `COMMAND.COM' to run GCC, and
`COMMAND.COM' can't pass more than 126 characters to GCC.  To work around,
comment-out the `SHELL=' line, and change your commands to work without
redirection/pipe characters.

17. Converting DOS Programs/Libraries to DJGPP
**********************************************

  If you have a program or a library developed under some other DOS-based
compiler, which you want to port to DJGPP, read this chapter.

17.1 GCC/Gas won't accept valid assembly code ...
=================================================

**Q*: I have some code written in assembly which compiles under `MASM' and
`TASM', but GCC gives me a long list of error messages.*

*A* :  The GNU Assembler (`as.exe'), or `Gas', called by GCC accepts "AT&T"
syntax which is different from "Intel" syntax.  Notable differences between
the two syntaxes are:

   * AT&T immediate operands are preceded by `$'; Intel immediate operands
     are undelimited (Intel `push 4' is AT&T `pushl $4').

   * AT&T register operands are preceded by `%'; Intel register operands are
     undelimited.  AT&T absolute (as opposed to PC-relative) `jump'/`call'
     operands are prefixed by `*'; they are undelimited in Intel syntax.

   * AT&T and Intel syntax use the opposite order for source and destination
     operands.  Intel `add eax, 4' is `addl $4, %eax' in AT&T syntax.

     The `source, dest' convention is maintained for compatibility with
     previous Unix assemblers, so that GCC won't care about the assembler with
     which it is configured, as part of GCC installations don't use GNU
     Binutils.

   * In AT&T syntax, the size of memory operands is determined from the last
     character of the opcode name.  Opcode suffixes of `b,' `w,' and `l'
     specify byte (8-bit), word (16-bit), and long (32-bit) memory
     references.  Intel syntax accomplishes this by prefixing memory operands
     (*not* the opcodes themselves) with ``byte ptr',' ``word ptr',' and
     ``dword ptr''.  Thus, Intel `mov al, byte ptr FOO' is `movb FOO, %al' in
     AT&T syntax.

   * Immediate form long jumps and calls are `lcall/ljmp $SECTION, $OFFSET'
     in AT&T syntax; the Intel syntax is `call/jmp far SECTION:OFFSET'.
     Also, the far return instruction is `lret $STACK-ADJUST' in AT&T syntax;
     Intel syntax is `ret far STACK-ADJUST'.

   * The AT&T assembler does not provide support for multiple-section (aka
     multi-segment) programs.  Unix style systems expect all programs to be
     single sections.

   * An Intel syntax indirect memory reference of the form

           SECTION:[BASE + INDEX*SCALE + DISP]

     is translated into the AT&T syntax

           SECTION:DISP(BASE, INDEX, SCALE)

Examples:

         `Intel':  [ebp - 4]         `AT&T':  -4(%ebp)
         `Intel':  [foo + eax*4]     `AT&T':  foo(,%eax,4)
         `Intel':  [foo]             `AT&T':  foo(,1)
         `Intel':  gs:foo            `AT&T':  %gs:foo

For a complete description of the differences, get and unzip the files named
`as.iN' (where `N' is a digit) from the bnu252b.zip, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/bnu252b.zip archive, then See
i386-dependent features in "GNU assembler documentation", or point your Web
browser to http://www.delorie.com/gnu/docs/gas/as_190.html#SEC192.  If you
don't read this FAQ with an Info browser, type at the DOS prompt:

      info as machine i386

You will see a menu of `Gas' features specific to x86 architecture.

17.2 Double-check code produced by Gas
======================================

**Q*: My assembly code gets corrupted by `Gas'!*

*A* :  When writing assembly code, you should remember *to not trust Gas!*
You should always check that it does what you expect it to do.  GNU Assembler
can currently be trusted only when it assembles code produced by GCC.  All
other code--yours--is subject to introduction of subtle errors.  To be sure,
use a debugger to check the code (even `objdump' from GNU Binutils doesn't
always treat segment overrides correctly).  The following lists some
guidelines for safer machine-language programming with `Gas':

  a. Use explicit sizing.  E.g., use `movl' instead of `mov,' even if you're
     sure the arguments are 32-bit wide.  The fact that you use byte
     registers doesn't seem to matter with `Gas'.

  b. Write code segment overrides as `.byte' constants, not as e.g.  `%cs:.'
     According to Charles Sandmann <sandmann@clio.rice.edu>, `Gas' uses the
     current phase of the moon in deciding whether to ignore your prefixes.
     So unless you know *exactly* what is the phase of the moon at the moment
     of assembly, use `.byte' constants.

  c. Make sure the operands match the instructions.  Don't assume that if they
     don't, you'll get an error message from the assembler.

17.3 Converting Intel ASM syntax to AT&T syntax
===============================================

**Q*: Where can I find an automated conversion tool to convert my
`Intel'-style assembly code into a code acceptable by `Gas'?*

*A* :  A `Sed' script which should do most of the conversion was posted to
the DJGPP newsgroup in the past.  You can find it in the DJGPP archives, at
this URL:

     http://www.delorie.com/djgpp/mail-archives/djgpp/1995/06/06/05:48:34

A conversion program called `TA2AS' which can convert TASM assembly source to
the AT&T format, can be found on OULU repository and on the DJGPP server.
`TA2AS' was written by Jan Oonk <jan@stack.urc.tue.nl>.

Alternatively, here is what you can do to convert your code:

   * For a small number of relatively short files, consider converting them
     with a smart editor (like Emacs or its work-alikes).

   * Obtain a copy of Microsoft MASM 6.11. It has `-coff' option to generate
     object code in COFF format which can be submitted to GCC, so you can
     compile your original source.  You can also use `LIB32' librarian from
     Microsoft C8 to convert object files to COFF by putting them into a
     `.lib' library, then extracting them as COFF files.

(If you use MASM or LIB32, please post your experiences to the
comp.os.msdos.djgpp Newsgroup, so that I could make the above instructions
less vague.)

Keep in mind that syntax is only one of the aspects of converting code
written for DOS to DJGPP.  You should also make sure your code doesn't
violate any rules for protected-mode programming (see next question in
Section 17.4).

17.4 Converted code GP Faults!
==============================

**Q*: OK, I've succeeded to convert and compile my assembly-language program,
but when I run it, I get "Segmentation Violation" and "General Protection
Fault".  This program works when compiled with MASM, so how can it be?*

*A* :  In DJGPP, your program runs in *protected mode*.  There are certain
things you can't do in protected-mode programs (that's why it is called
protected mode).  This issue is too complex to describe here, so only a few
of the more important aspects will be briefly mentioned.  If you are serious
about writing assembly language protected-mode code, or have a large body of
existing code to convert to protected mode, you should read any of the books
about protected-mode programming with 80x86 processors.

Here is a short list of some of the techniques found in many real-mode
programs, which will trigger protection violation or erratic behavior in
protected mode:

   * Loading arbitrary values into segment registers, then using them to
     reference code or data.

   * Referencing code with data segment register, or vice versa.

   * Assuming certain locations (like BIOS area or video memory) will be found
     at certain absolute addresses.

   * Calling DOS or BIOS services with `INT NN' instruction.

17.5 I want to use a `.obj' or `.lib' code with DJGPP
=====================================================

**Q*: I have a set of useful functions in a `.obj' format, but no source
code.  Can I use them with my DJGPP program?*

**Q*: I have this `ACMELUXE.LIB' library of functions which I want to use.
I've extracted all the `.obj' files, but when I try to link them with my
program, GCC complains: "File format not recognized".  Can't I use these
object files?*

**Q*: I've got a bunch of `.obj' files I want to use.  I've ran AR to make a
GCC-style `.a' object library, but got an error message from GCC saying
"couldn't read symbols: No symbols".  How can I link them with my code?*

*A* :  Sorry, you probably can't.  The GNU linker called by GCC doesn't
understand the format of `.obj' files which other DOS-based
compilers/assemblers emit.  Unless you can get the source of those functions,
convert it to protected-mode, flat-address model code and compile them with
GCC, you most probably won't be able to use them.  Lately, an automated
conversion tool called `OBJ2COFF' was written by Jan Oonk
<jan@stack.urc.tue.nl> which can be used to convert `.obj' object files and
`.lib' libraries to `COFF' format, provided that the original `.obj' files
must have been written for flat-address memory model.  (You can also try
using LIB32 librarian from Microsoft C8 to convert object files to COFF.)
The main problem, of course, is that most such object files were written for
real-mode programs in memory models other than flat, and without extensive
modifications would crash your program anyway...  (See previous question in
Section 17.4.)

`OBJ2COFF' is available from the `OULU' repository, e.g.
ftp://x2ftp.oulu.fi/pub/msdos/programming/converters/o2cv06.arj and from the
DJ Delorie's ftp server, e.g.
ftp://ftp.delorie.com/pub/djgpp/contrib/o2cv06.arj.

17.6 I *must* use my 16-bit code with DJGPP!!
=============================================

**Q*: If that's how it is, then I would have to give up using DJGPP.  I
simply cannot live without these `.obj' files.  Are you *really* sure there
is nothing I can do??*

*A* :  If you need your old code *that* bad, then there might be a way,
albeit a cumbersome one.  You can write a 16-bit, real-mode program and link
it with your precious functions you can't live without.  Have this program
spawn a DJGPP-compiled program and make the two communicate with each other
via a buffer allocated in low memory, or via command-line parameters passed
to the 32-bit program by the `spawnXX' function call.  You can also call
16-bit functions directly with the library function called
`__dpmi_simulate_real_mode_procedure_retf,' provided the 16-bit program
passes the CS:IP values of these functions to the 32-bit program.  You can
even put your 16-bit code as binary instructions into a buffer allocated in
low memory and call it with `__dpmi_simulate_real_mode_procedure_retf' (but
if you can do that, you probably can also disassembly the code into a source
form and submit it to `Gas').

*Now* will you consider to stick with DJGPP?  *Please??...*

18. Low-level DOS/BIOS and Hardware-oriented Programming
********************************************************

  This chapter sheds some light on a few aspects of writing DJGPP programs
which interact with hardware or use interrupts.

18.1 Got "Unsupported INT 0xNN" calling `int86'
===============================================

**Q*: Why does my program crash with "Unsupported DOS request 0xNN" or
"Unsupported INT 0xNN" when I call `int86' or `intdos' functions to invoke a
software interrupt?*

*A* :  Calling real-mode DOS or BIOS services from protected-mode program
requires a switch to real mode, so `int86' family of functions in the DJGPP
library should reissue the INT instruction after the mode switch.  However,
some services require pointers to memory buffers.  Real-mode DOS/BIOS
functions can only access buffers in conventional memory, so `int86' has to
move data between your program and low memory to transparently support these
services.  But this means it should know about all these services to perform
these chores correctly, because each service has its own layout and size of
the buffer(s).  While `int86' supports many of these services, it doesn't
support all of them.  The supported functions are listed in the library
reference.  See int86 library reference in "libc.a reference", or point your
Web browser to
http://www.delorie.com/djgpp/doc/libc-2.00/libc_394.html#SEC394.  For those it
doesn't support, you will have to call the `__dpmi_int' library function
instead.  It is also documented in the library reference, See __dpmi_int in
"libc.a reference", or point your Web browser to
http://www.delorie.com/djgpp/doc/libc-2.00/libc_196.html#SEC196.
`__dpmi_int' requires that you set up all the data as required by the service
you are calling, including moving the data to and from low memory (See how to
use buffers with DOS/BIOS services in Section 18.2, below).

18.2 How to use buffers with DOS/BIOS services
==============================================

**Q*: I want to call a DOS/BIOS function which requires a pointer to a buffer
in, e.g. `ES:DI' (or any other) register pair.  How do I get the segment to
put into the `ES' register?*

*A* :  If you use `int86x' or `intdosx' for a DOS or BIOS function supported
by them, then just put the address of your buffer into the register which
expects the offset (`regs.x.di') and forget about the segment.  These
functions are processed specially by the library, which will take care of the
rest.

If you call `__dpmi_int,' then you must put into that register pair an
address of some buffer in *conventional* memory (in the first 1 MByte).  If
the size of that buffer doesn't have to be larger than the size of transfer
buffer used by DJGPP (16KB by default), then the easiest way is to use the
transfer buffer.  (Library functions don't assume its contents to be
preserved across function calls, so you can use it freely.) That buffer is
used for all DOS/BIOS services supported by DJGPP, and it resides in
conventional memory.  DJGPP makes the address and the size of the transfer
buffer available for you in the `_go32_info_block' external variable, which
is documented the library reference.  Check the size of the buffer (usually,
16K bytes), and if it suits you, use its linear address this way:

     dpmi_regs.x.di =
      _go32_info_block.linear_address_of_transfer_buffer & 0x0f;
     dpmi_regs.x.es =
      (_go32_info_block.linear_address_of_transfer_buffer >> 4) & 0xffff;

For your convenience, the header file `<go32.h>' defines a macro `__tb' which
is an alias for `_go32_info_block.linear_address_of_transfer_buffer'.

If the size of the transfer buffer isn't enough, you will have to allocate
your own buffer in conventional memory with a call to the
`__dpmi_allocate_dos_memory' library function.  It returns you the segment of
the allocated block (the offset is zero).  If you only need a small number of
such buffers which can be allocated once, then you don't have to worry about
freeing them: they will be freed by DOS when your program calls `exit'.

For bullet-proof code, you should test the size of the transfer buffer at
runtime and act accordingly.  This is because its size can be changed by the
`STUBEDIT' program without your knowledge.

18.3 How to call software interrupt functions
=============================================

**Q*: My program crashes/doesn't do what it should when I call
`__dpmi_simulate_real_mode_interrupt'.*

*A* :  You should zero out some of the fields of the `__dpmi_regs' structure
before you call that function.  Random values in these fields can cause your
program to behave erratically.  The fields in point are `SS', `SP' and
`FLAGS'.  When `SS' and `SP' are zeroed, the DPMI host will provide a stack
for the interrupt handler which is at least 30-word long (most DPMI hosts
provide much larger stack); this is usually enough, but if it isn't, then you
should point `SS' and `SP' to a larger buffer in conventional memory
(possibly part of the transfer buffer).

If `SS:SP' isn't zero, they will be used as the address of the stack you want
to be used by the interrupt handler, so if they have random values, your
program will crash.  A non-zero `FLAGS' field can also make the processor do
all kinds of weird things (e.g., imagine that the single-step or the debug
bit is set!).

If you don't have any reason to set `SS:SP' to your stack, it's easier to
call `__dpmi_int' library function, which zeroes out the stack pointer and
the `FLAGS' fields for you (and also doesn't force you to type long names!).

18.4 How to move data between your program and conventional memory?
===================================================================

**Q*: How can I move data between my program and the transfer buffer?*

**Q*: How do I access my peripheral card which is memory-mapped to an address
between 640K and 1M?*

**Q*: How can I read or change a value of one of the variables in the BIOS
data area?*

**Q*: How can I peek at an address whose far pointer I get from an INT 21h
call?*

*A* :  Depending on your specific needs, you can use one of three methods:

   * If you want to access a byte, a 16-bit word, or a 32-bit double word, use
     the "far pointer" functions declared on the the `<sys/farptr.h>' header
     file.  You should convert any real-mode far pointer segment:offset pair
     into a "linear address" (i.e., segment*16 + offset), and use `_dos_ds'
     macro to get the selector which allows access to conventional memory,
     like this:

           unsigned char value = _farpeekb(_dos_ds, segment*16 + offset);

     Use `_farpeekw' to peek at 16-bit shorts and `_farpeekl' to peek at
     32-bit longs.  If you need to access several (non-contiguous) values in
     a loop, use corresponding `_farnspeekX' functions which allow you to set
     the selector only once, as opposed to passing it with every call (but be
     sure the loop doesn't call any function that itself sets the selector;
     see the library reference for more details).

     There is a corresponding set of `_farpokeX' and `_farnspokeX' functions
     to poke (change the values of) such memory locations.

     These functions have an advantage of emitting inline assembly code when
     you compile with optimizations, so they are very fast.  See the library
     reference Info file for further details about these functions.

   * If you need to access more than 4 contiguous bytes, use `dosmemget' and
     `dosmemput' library functions.  They also require that you convert the
     segment:offset pair into a linear address, but they don't need the
     conventional memory selector, as they can only be used to access the
     conventional memory.

     Note that some memory-mapped peripheral devices might require 16-bit word
     accesses to work properly, so if `dosmemXXX' yields garbled results, try
     `dosmemXXXw' or "farptr" functions.

   * For moving buffers larger than a few tens of bytes, it's best to use
     `movedata' library function.  It requires that you pass selector and
     offset for both the conventional memory address and for the buffer in
     your program's address space.  Use the `_my_ds' macro to get the
     selector of any variable in your program, and use its address as its
     "offset" or linear address.  `movedata' is faster because it moves by
     32-bit longs, but be careful with its use when moving data to and from
     peripheral cards: many of them only support 8- or 16-bit wide data path,
     so moving data 4 bytes at a time won't gain you much, and might even get
     you in trouble with some buggy BIOSes.  The functions `movedatab' and
     `movedataw' are provided for moving by bytes and by 16-bit words,
     respectively.

   * For the fastest access to memory outside your usual flat address space,
     you might consider using the "nearptr" functions declared on
     `<sys/nearptr.h>' header; see library reference for more details.  Also
     see the description of how to get the fastest direct access to
     peripheral devices in Section 18.6, below.

18.5 Conventional-memory addresses use only 20 bits
===================================================

**Q*: I call `movedata' to pass data between my program and the transfer
buffer, but get bogus values or General Protection Fault.*

*A* :  Valid conventional-memory addresses are only 20 bit-wide.  However,
the value stored in the variable
`_go32_info_block.linear_address_of_transfer_buffer' (or its alias, `__tb')
is not guaranteed to have the higher 12 bits zeroed, and `movedata' doesn't
mask those high bits, because it can also be used to move data between 2
protected-memory locations.  Be sure to mask off the high 12 bits of the
value returned by various `..._linear_address_...' fields in DJGPP
structures, whenever that address references a conventional memory location,
before you call *any* of the functions from the `movedataX' family, the
"farptr" or the "nearptr" functions.

18.6 Fast access to memory-mapped devices or absolute addresses
===============================================================

**Q*: The "farptr" functions are too slow for my application which *MUST*
have direct access to a memory-mapped device under DPMI.  How can I have this
in DJGPP?  My entire optimized graphics library is at stake if I can't! :(*

*A* :  The following so-called Fat DS method was suggested by Junaid A.
Walker <junaid@barney.eng.monash.edu.au> (he also posted a program which uses
this technique to access the video RAM; you can look it up by searching the
mailing list archives).  But first, a word of warning: the method I'm about
to describe effectively disables memory protection, and so might do all kinds
of damage if used by a program with a wild pointer.  Or, as Stephen Turnbull
<turnbull@shako.sk.tsukuba.ac.jp> has put it:

     *Surgeon General's WARNING*:  The description below uses the "Fat DS
     hack", a steroid derivative which gives your program great strength, a
     thick neck, baldness, and is known to be closely linked with the
     Alzheimer's disease.

Having said that, here is the trick: you change the limit of the segment
descriptor stored in `DS' to `0xffffffff' (i.e., -1), using function 8 of the
DPMI interrupt 31h.  After that, you have access to all the memory which is
currently mapped in.  You then use the 32-bit wrap-around in the linear
address space to access memory at, say, linear address 0xa0000 (which belongs
to the VGA), or any other address on your memory-mapped device.

You should know up front that this trick won't work with every DPMI host, and
some events break this scheme even for those DPMI hosts which will silently
allow you to set such a huge limit on the memory segment.  CWSDPMI, QDPMI,
Win 3.x all allow this; Linux's DOSEMU and, probably, OS/2 Warp don't.  A
call to malloc or any other library function which calls `sbrk' might
sometimes change the base address of `DS' selector and break this method
unless the base address is recomputed after `sbrk' call.  (The "nearptr"
functions support this recomputation by providing you with the
`__djgpp_conventional_base' variable, but it is your responsibility to use
it.)  The same change happens when you call `system,' and as result of some
other events external to the executing code thread, like multitasking or
debugger execution.

If you are aware of these limitations, and don't need your code to run under
all DPMI hosts, it might be the fix to your problems.

Confused about how exactly should you go about using this technique in your
program?  Look at the docs of the "nearptr" functions, See
__djgpp_nearptr_enable in "libc.a reference", or point your Web browser to
http://www.delorie.com/djgpp/doc/libc-2.00/libc_111.html#SEC111.

18.7 Accessing absolute address above 1MB
=========================================

**Q*: How can I access a memory-mapped peripheral devices (or any other
absolute address) above 1 MByte mark?*

*A* :  Use the `__dpmi_physical_address_mapping' library function.  It
returns a linear address which can be used to access a given absolute
physical address.  You can then use the functions from <sys/farptr.h> to
access that linear address.  Specifically, these are the DPMI calls that you
will have to use:

   - allocate an LDT descriptor (Int 31h/AX=0);

   - map selector to physical address (Int 31h/AX=0800h);

   - lock linear address (Int 31h/AX=0600h);

   - set segment base address (Int 31h/AX=7);

   - set segment limit (Int 31h/AX=8).

All of these DPMI calls have `__dpmi__XXX' wrappers in the DJGPP library.

18.8 How to make DOS/BIOS call your function
============================================

**Q*: How can I make any real-mode service call my function?  E.g., the mouse
driver has a provision (function 0Ch) to call user-defined handler when
certain events occur, which expects a far pointer to my function in `ES:DX'
register pair.*

*A* :  Those services expect a real-mode function, so you should wrap your
protected-mode function with a real-mode stub.  To this end, call either the
`_go32_dpmi_allocate_real_mode_callback_retf' or the
`_go32_dpmi_allocate_real_mode_callback_iret' library function, as required
by the real-mode service you want to hook, and pass the `segment' and
`offset' fields it returns to the service you want (in the above example, Int
33h function 0Ch) by calling `__dpmi_int'.  See the docs in the library
reference Info file for further details about allocating wrapper function.

18.9 How to hook hardware interrupts
====================================

**Q*: How do I register my DJGPP function as a hardware interrupt handler?*

*A* :  The optimal set-up depends on the interrupt frequency and on the
amount of processing it requires.  Therefore, only some basic considerations
and techniques are listed below.  What combination of these is best for your
application is up to you to decide.

First, some background.  Hardware interrupts can occur when the processor is
either in real mode (like when your program calls some DOS service) or in
protected mode.  When your program runs under a DPMI host, hardware
interrupts are always passed to protected mode first, and only if unhandled,
they are reflected to real mode.  Therefore, in DPMI mode you can get away
with installing only a protected-mode handler.  However, if the interrupts
happen at a high frequency (say, more than 10 KHz), then the overhead of the
interrupt reflection from real to protected mode might be too painful, and
you might consider installing a real-mode interrupt handler in addition to
the protected-mode one.  If you do, you must hook the PM interrupt first,
then the RM one (because hooking the PM interrupt modifies the RM one). Also,
you should know that some DPMI hosts don't allow you to hook the RM interrupt
(CWSDPMI does); the only way to be sure is to try.

To install a protected-mode interrupt handler, you do this:

   * In general, your handler should be written in assembly to be
     bullet-proof.  It should lock all the memory (code, data and stack) it
     touches during interrupt processing (this is virtually impossible in C),
     explicitly issue the `STI' instruction before `IRET' and perform all the
     other chores described in the DPMI spec (see DOS Protected Mode Interface
     Specification in Section 22.4).  To install assembly handler, you should
     do this:

        - Call `__dpmi_get_protected_mode_interrupt_vector' and save the
          structure it returns (to restore the previous handler address
          before your program exits).

        - Lock all the memory your handler touches with a series of calls to
          `__dpmi_lock_linear_region'.

        - Finally, call `__dpmi_set_protected_mode_interrupt_vector' passing
          it the pointer to a `__dpmi_paddr' structure filled with `_my_cs'
          in the `selector' field and the address of your function in the
          `offset32' field.

   * If your handler function is written in C, you should generally call the
     `_go32_dpmi_XXX' functions instead of the bare-bones API wrappers whose
     names start with `__dpmi_'.  Specifically:

        - Call `_go32_dpmi_get_protected_mode_interrupt_vector'.  This
          function puts the selector and offset of the specified interrupt
          vector into the `pm_selector' and `pm_offset' fields of the
          structure pointed to by its second argument.  This data should be
          saved and later passed to
          `_go32_dpmi_get_protected_mode_interrupt_vector' to restore the
          vector on exit.

        - Call `_go32_dpmi_allocate_iret_wrapper'  passing it the address of
          your functions as the `pm_offset' field and the value of `_my_cs'
          in the `pm_offset' field.  The `pm_offset' field will get replaced
          with the address of the wrapper function which is a small assembler
          function that handles everything an interrupt handler should do on
          entry and before exit (and what the code GCC generates for an
          ordinary C function doesn't include); the effect is similar to using
          interrupt or `_interrupt' keyword in some DOS-based compilers.

        - If you want your handler to chain to the previous handler, call
          `_go32_dpmi_chain_protected_mode_interrupt_vector'.  This will set
          up a wrapper function which, when called, will call your handler,
          then jump to the previous handler after your handler returns.  Put
          the address of your handler into the `pm_offset' field and the
          value of `_my_cs' into the `pm_selector' field of the
          `_go32_dpmi_seginfo' structure and pass a pointer to it to this
          function.

        - You then call `_go32_dpmi_set_protected_mode_interrupt_vector' with
          the address of the `_go32_dpmi_seginfo' structure you got either
          from `_go32_dpmi_allocate_iret_wrapper' or from
          `_go32_dpmi_chain_protected_mode_interrupt_vector'.

     The problem with writing handlers in C as above is that the wrappers
     aren't locked, and in practice you can't lock all of memory the handler
     itself uses, either.  Thus, this approach is generally unsuitable for
     production-quality software and should be used only when the program is
     known to not page (i.e., only the physical memory is used).  (You might
     consider disabling virtual memory to make sure your program doesn't
     page.)

To install a real-mode interrupt handler, you do this:

   * Call `__dpmi_get_real_mode_interrupt_vector' and save the structure it
     returns (to restore the previous handler address before your program
     exits).

   * Allocate some conventional memory with `__dpmi_allocate_dos_memory' and
     put the code of your handler there with `dosmemput' function.  (You
     could also call one of the functions which allocate real-mode call-back,
     but these will cause a mode switch on every interrupt which you want to
     avoid, otherwise there is no point in installing a real-mode handler,
     right?)

   * Put the address which `__dpmi_allocate_dos_memory' returned into a
     `__dpmi_raddr' structure (the lower 4 bits into `offset16' field, the
     rest into `segment' field), then call
     `__dpmi_set_real_mode_interrupt_vector'.

For examples of installing and using hardware interrupt handlers, see the
files sb05_dj2.zip (Sound Blaster interrupt-driven functions), e.g.
ftp://ftp.delorie.com/pub/djgpp/contrib/sb05_dj2.zip (also available on OULU
repository, e.g.
ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2/sb05_dj2.zip).

18.10 Hardware interrupt hooking has its subtleties ...
=======================================================

**Q*: I did all the above, but my program occasionally still hangs...*

*A* :  Hooking hardware interrupt in DJGPP (and in protected mode in general)
has a few subtle aspects.  In general, hardware interrupt handling in DJGPP
v2.0 is rock solid *if you play by the rules*.  Unfortunately, the rules are
a bit tricky.

One cause of your problems might be that your interrupt handler or some
memory location it uses get paged out because of the virtual memory
mechanism, or because your program spawned a child program.  In that case,
the interrupt might cause a call to a non-existent service routine, with the
obvious results.  You should lock all the memory pages that your handler
accesses by calling the `__dpmi_lock_linear_region' library function.  This
also means in practice that you should write your handler in assembly, as
described in how to set an interrupt handler in Section 18.9, above.  You can
disable virtual memory, or put `_CRT0_FLAG_LOCK_MEMORY' into
`_crt0_startup_flags' to make sure nothing is paged out (but then your
program might not have enough memory to run, unless you run on
memory-abundant system).

Another problem might be that the hardware peripheral you use generates a lot
of interrupts.  Due to specifics of hardware interrupts handling in protected
mode, there is a substantial overhead involved with reflection of interrupts
between real and protected modes.  For instance, on a 486DX/33 this
reflection might consume up to 3000 clocks; on a 386SX/16, even a 1KHz clock
might eat up 1/2 of available cycles.  If your hardware fires too much
interrupts, your CPU might not be able to keep up.  In that case, consider
reducing the interrupt frequency, or move some of the processing done inside
interrupt handler to some other place.  If your handler is written in C,
write it in assembly and make sure it doesn't chain.  If that doesn't help,
install a real-mode handler.

Some losing memory managers, notably EMM386, were reported to induce a high
interrupt handling overhead.  In one case, a user reported an increase in the
interrupt rate from 2 KHz to 6 KHz after uninstalling EMM386.

Still another possibility is that you use a non-default `sbrk' algorithm in
your program (check if the header file `crt0.h' is included anywhere in the
program, and if so, is the `_CRT0_FLAG_UNIX_SBRK' bit in the
`_crt0_startup_flags' variable set by the program.  If it is, then a hardware
interrupt which happens at the wrong time could crash your machine,
especially if you run under Windows 3.x.

If the above still doesn't explain your problem, then post your code on the
comp.os.msdos.djgpp Newsgroup or the djgpp mailing list <djgpp@delorie.com>,
tell us how does it fail and somebody will usually have a solution for you.

18.11 How to read and write ports
=================================

**Q*: I need to read from and write to PC ports, and I'm accustomed to using
the `inp' and `outp' functions.  But I hear they aren't available in DJGPP?*

*A* :  They are in v2.x.  Just  `#include <pc.h>'  and you get their
prototypes.  The functions themselves are in the default library. Note that
there are also size-specific versions for byte- word- and dword-long access
(e.g., `inportl' for reading a 32-bit dword), as well as functions to
read/write sequences of bytes and words, like `inportsb' and `outportsw;'
these are DJGPP-specific.

19. Legal Aspects
*****************

  This chapter answers some questions about various legal aspects of writing
programs with DJGPP.

19.1 Legal (un)restrictions on DJGPP applications
=================================================

**Q*: Can you explain in plain English the legal restrictions of distributing
programs compiled with DJGPP?*

**Q*: Can I write commercial programs with DJGPP?*

*A* :  In most cases, you don't have to worry.  Using the GNU C/C++ compiler
to compile your programs doesn't make your programs subject to *any*
restrictions.  The C library which comes with DJGPP is *free*, which means
you are free to use it in every way you like (but please observe basic rules
of courtesy in Section 19.2.)  So, if you write C programs, you have
absolutely nothing to worry about.

The basic C++ `iostream' class library (`libiostr.a') which comes with DJGPP
allows you to use it binary-wise (i.e., without changing library sources) in
your C++ programs *without restrictions*, unless you compile your programs
with a compiler other than Gcc (which won't happen if you work with DJGPP).
The library of additional C++ classes (`libgpp.a') also allows you to link it
freely with your applications, but requires that you provide your customers
with source or object code of the application, so they could relink the
application with future or modified versions of the C++ library.  (If you
intend to distribute commercial programs linked with the `libgpp.a' library,
you are strongly advised to read the GNU Library General Public License which
comes with the library, for rigorous definition of its terms.)

Note that `libiostream.a' library is special in that it doesn't place your
program under GPL or LGPL, so if you only use C++ classes included in that
library, make your compilations use it instead of `libgpp.a'.  (That's the
only reason of having `libiostream.a' as a separate file, because `libgpp.a'
includes everything `libiostream.a' does, so you never need both of them.)

Two GNU packages, `Flex' and `Bison', are also special in that using them to
produce your programs doesn't place your programs under GPL or LGPL.  In
other words, lexers produced by `Flex' and parsers produced by `Bison' do
*not* imply GPL/LGPL.

If you *do* use in your program any of the FSF sources that fall under
GPL/LGPL (like some of the GCC's sources, or the GNU `getopt' or `regex'
packages which come with many GNU programs), then you must comply with the
terms of GNU licenses when distributing your programs; in this case your
entire application becomes GPL.  If that is unacceptable to you, consider
using the versions of `regex' and `getopt' from the DJGPP C library (which is
free).

You may ship any of the utilities developed specifically for DJGPP (e.g., the
floating-point emulator or the CWSDPMI DPMI host) *as distributed by DJ
Delorie* with your program with no other requirement besides telling your
customers how to get DJGPP for themselves.

19.2 Legal restrictions of DJGPP utilities and libraries
========================================================

**Q*: Can I redistribute djgpp, and if so, how?*

**Q*: I run a business that sells shareware for distribution costs.  Can I
include djgpp on my CD-ROM?*

**Q*: I want to include djgpp in a product that happens to need a compiler
provided with it.  Can I do this?*

**Q*: Is DJGPP GNU software?*

**Q*: Is DJGPP public domain software?*

**Q*: Is DJGPP shareware?*

*A* :  DJGPP is *not* public domain, neither is it shareware (you *don't*
have to pay a license fee to use DJGPP).  Parts of DJGPP (the compiler and
some of the development tools) *are* GNU software, so you must comply with
GNU GPL if you distribute those parts (usually, you won't need to distribute
them, because they are freely available to everyone).  A small part of the C
library is taken from the Berkeley BSD sources, and is therefore in public
domain.  Other parts of DJGPP, which includes most of the C library, the free
DPMI host CWSDPMI, and some of the utilities are copyrighted, but in a way
that allows you to use them freely and without restrictions.

When you redistribute parts of DJGPP itself (as opposed to your programs
compiled with DJGPP), you must comply to the conditions applicable to
whatever you distribute.  The parts which are in public domain are, of course
freely distributable.  Other parts of DJGPP fall under the DJGPP copyright
which allows you to redistribute everything provided you follow these rules:

   * You must either distribute the sources of DJGPP tools, or provide them
     on request.

   * You must call it *DJGPP* and nothing else.

   * You may *not* take credit for it, and you must *not* remove any notices
     in DJGPP that give credit to those who worked on it.

   * You must tell the recipient how to get the latest version off the
     Internet, or at least how to find out what the latest version is.
     DJ Delorie gets a lot of questions from people who got old versions from
     vendors, and don't realize that they're way out of date.

   * Distributing CWSDPMI with shareware or commercial programs requires
     notification of its author Charles Sandmann <sandmann@clio.rice.edu> by
     mail or acknowledged e-mail.

In addition, it would be a courtesy to inform DJ Delorie <dj@delorie.com>
that you are including DJGPP in your product, in case this information is
obsolete.  A token sample of your distribution would be nice also.

20. Getting Help
****************

  This chapter tells you how to get answers to questions you didn't find in
this FAQ.

20.1 Don't post DJGPP-specific problems to GNU Newsgroups
=========================================================

**Q*: I post my problem to the "help-gcc" Newsgroup, but don't get any
answers.*

*A* :  Is your problem likely to be special to the DJGPP port or to DOS
environment?  If so, don't post to GNU Usenet groups, but to the
comp.os.msdos.djgpp Newsgroup or to the DJGPP mailing list
<djgpp@delorie.com>.  People who read GNU Newsgroups usually neither know nor
care about DOS-specific problems.  Post there only if the problem seems to be
a generic one in one of the FSF utilities.  For most problems, this can be
deduced only after either tracing a problem in the source code or testing it
on some non-DOS platform.  As a general rule, always post to DJGPP group
first.

20.2 How to post to the mailing list
====================================

**Q*: How do I post to the DJGPP mailing list?*

*A* :  Send mail to the list address <djgpp@delorie.com> as if it were a
person.  Please use the mailing list only if you cannot access the DJGPP
Newsgroup, because reflecting the mail to and from the mailing lists incurs
additional load on the DJGPP server.

20.3 How to become a subscriber to the mailing list
===================================================

**Q*: How do I subscribe to DJGPP mailing list?*

*A* :  Send mail to the list server <listserv@delorie.com> (NOT to djgpp@!!),
leave the subject line empty and in the body write:

      subscribe <your e-mail address> djgpp

If you only want to receive announcements of new versions and ported
software, but don't want to see any other DJGPP mail traffic, subscribe to
djgpp-announce mailing list <djgpp-announce@delorie.com>:

      subscribe <your e-mail address> djgpp-announce

The announcements which go to `djgpp-announce' get reflected to `djgpp', so
you don't have to subscribe to both these lists.

The DJGPP mailing list is available in the daily and weekly digest forms.  To
subscribe to one of these, send this one-line message to the above list
server:

      subscribe <your e-mail address> djgpp-digest-daily

or

      subscribe <your e-mail address> djgpp-digest-weekly

You can also subscribe to DJGPP-related mailing lists through DJ Delorie's
WWW server, at this URL:

     http://www.delorie.com/mailing-lists/subscribe.html

Note that you don't have to subscribe to djgpp mailing list if you don't want
to get all the traffic in your mailbox (typically, about 30 messages per
day).  You can ask questions on the list even if you are not a subscriber,
because people usually answer both to your e-mail address and to the list
(well, actually, the mailer program does it automatically and most people
don't bother to change that).  If you want to be sure the mail gets to you
directly, say in your message that you don't subscribe to the list, and ask
people to answer directly.

If you have a Usenet feed, consider reading the comp.os.msdos.djgpp Newsgroup
instead, so that the load on the DJ's list server will get lower.  There is
also a possibility of reading the Newsgroup (but not posting to it) through
the Mercury Gopher server at Michigan State University,
gopher://gopher.msu.edu:3441/chronological%20comp.os.msdos.djgpp

20.4 How to unsubscribe from the mailing list
=============================================

**Q*: Whew!  There's too much traffic on djgpp mailing list (at least the
SysAdmin glaring over my shoulder thinks so... ;-).  How do I unsubscribe
myself?*

**Q*: I've been trying for days to unsubscribe from the djgpp mailing list.
What am I doing wrong?*

*A* :  You should be sending your unsubscribe messages to the list server
<listserv@delorie.com> (not djgpp@delorie.com!), with the contents being just
this:

      unsubscribe <your e-mail address> djgpp

If you have done that and it didn't help, write to the DJ Delorie
<dj@delorie.com> and ask him to help you.

You can also unsubscribe yourself from any of the DJGPP-related mailing lists
through DJ Delorie's WWW server, at this URL:

     http://www.delorie.com/djgpp/mailing-lists/subscribe.html

20.5 If you don't see any message from the list ...
===================================================

**Q*: I don't get any messages from DJGPP list for several days.  Is the list
alive?*

*A* :  Try sending a message to the list and see if you get it back.  If not,
it is possible that your name was inadvertently taken off the list.  This is
known to happen sometimes (don't ask me how).  You can check if you are
subscribed to any of the DJGPP-related mailing lists through DJ Delorie's WWW
server, at this URL:

     http://www.delorie.com/djgpp/mailing-lists/subscribe.html

If this tells you you're not, re-subscribe yourself by sending the above
subscription message to listserv <listserv@delorie.com>, or via DJ's server,
at this URL:

     http://www.delorie.com/djgpp/mailing-lists/subscribe.html

When in doubt, re-subscribe anyway (it doesn't hurt neither you, nor the list
server).

20.6 Why do I get every message more than once?
===============================================

**Q*: Why am I getting 2 and often more copies of the same message?  Don't
you people think I can get the idea at the first reading??*

*A* :  First, check the headers to make sure that all of the duplicate
messages have their `To:' header addressed to the DJGPP list, not to your
direct e-mail address.  Often, when people reply to your post, you get the
direct message, and a `Cc:' (the "carbon copy") one via djgpp list server.
This is normal behavior.

If indeed you get more than one copy of a message addressed to the list, it
is possible that you have added yourself to the list several times.  (This
could happen if your site supports a mail exploder which re-mails DJGPP to
you, and you also have subscribed yourself directly.)  One way to check this
would be to unsubscribe and see if you keep getting mail.  Another way is to
check your subscription through DJ's server, at this URL:

     http://www.delorie.com/djgpp/mailing-lists/subscribe.html

Look out for multiple subscriptions, possibly under different
names/addresses.  You could also write to a DJ Delorie <dj@delorie.com>, and
ask him to investigate.

Another thing to do, especially if you think it's not your fault, is to write
to a user named POSTMASTER at the address of each of the machines whose names
you find in the `Received:' headers of the bouncing messages (these are
people responsible for the operation of the mail software at their sites) and
ask them politely to help.

Many times this kind of problems is caused by excessive load on the list
server, so everybody who can, please switch to reading the
comp.os.msdos.djgpp Newsgroup and unsubscribe from the list.

20.7 DJGPP now has a Newsgroup!
===============================

**Q*: With so much daily traffic (about 30 messages a day), isn't it high
time to create a Newsgroup?*

*A* :  Beginning June 1st, 1995, DJGPP *has* its Newsgroup!  It is called
comp.os.msdos.djgpp Newsgroup, and it is two-way gated to the venerable DJGPP
mailing list.  This means messages posted to either the mailing list or the
newsgroup will appear on both (once, let's hope ;-); you can read either one
and post to either one, and everyone eventually sees everything.  The entire
traffic ends up in the mail archives on the DJ's Web server within 24 hours,
and is available for searching, at this URL:

     http://www.delorie.com/djgpp/mail-archives/

If you have a Usenet feed, now is the time to consider unsubscribing from the
mailing list and switch to reading the Newsgroup instead, so that the load on
the list server will get lower.

21. Version 2.0 vs v1.x
***********************

  This chapter is for those who are used to working with DJGPP v1.x and want to
more about v2.0 while they consider to switch.

21.1 New features in DJGPP v2.0
===============================

**Q*: What exciting new features will I find in v2.0 as opposed to v1.x?*

*A* :  DJGPP v2.0 is a DPMI-only environment, and it includes a free DPMI
host for those who don't have other DPMI provider installed.  In addition,
v2.0 features the following major improvements upon v1.1x:

   * much faster extender (the free DPMI host) and library functions;

   * very low memory footprint of the DPMI host below 640KB;

   * the DPMI server is loaded only once: no more problems with spawning child
     programs (e.g., almost unlimited recursive Make's);

   * ANSI- and POSIX-compliant libraries and header files, which should make
     porting Unix programs a lot easier;

   * support for signals;

   * 387 emulation under DPMI;

   * graphics which works in *any* setup, including under DPMI;

   * fixes of many bugs in hardware interrupts' and mixed-mode programming
     support;

   * ability to build all of DJGPP without commercial products (like Turbo C
     required to compile go32 in v1.x);

If you want to help in further v2.0 development, check out the list of
features which have yet to be done and volunteer to implement some of them.

21.2 DJGPP environment in v2.0
==============================

**Q*: There's been this talk about v2.0 and about `go32' going away in that
version, but I'm confused on what the new setup will be.  Could you clarify
the details of this change?*

*A* :  In v1.x of DJGPP, the `go32' extender was responsible for the
following:

   * Loading and running the application in protected mode.

   * Managing protected-mode and virtual memory.

   * "Extending DOS" so that protected-mode programs could issue calls to
     real-mode DOS and BIOS services and still run.  (This is mostly done by
     switching to real mode and reissuing the interrupt, but some services
     require special handling by the extender.)

   * Handling of hardware interrupts which happen while the CPU is in
     protected mode.

   * Loading 387 emulator (if required).

   * Loading the graphics driver and working with VGA bank-switching to create
     an illusion of a linear video memory.

   * Command-line and wild-card expansion in a Unix-like fashion.

In v2.x, most of these functions are done by a DPMI host, which is a
memory-resident software required to run protected-mode programs under
MS-DOS.  There are a few commercial DPMI hosts (like Quarterdeck's `QDPMI',
Qualitas `386Max', MS-Windows 3.x and Win95, OS/2, even Linux), but DJGPP
v2.0 comes with a free DPMI host called `CWSDPMI' for those who don't have
one already.  Loading the application into protected-mode memory (a function
done in v1.x by `go32') is handled by a 2KB-long real-mode stub which runs at
start-up, before the application's `main' functions us called (the stub will
also load `CWSDPMI' if no other DPMI host is detected).  All the other custom
code required to process BIOS- and DOS-related calls from protected-mode is
now built into the library functions which your program calls, so there is no
need for a special extender, because the application just issues DPMI calls
serviced by the DPMI host.

`CWSDPMI' can be loaded as a TSR, even loaded `HIGH' into the HMA/UMB, which
will make the applications load much faster.

22. Miscellany
**************

  This chapter is a hodgepodge of questions which don't belong to any of the
other chapters.

22.1 How to change a DJGPP package?
===================================

**Q*: I want to change cc1.  How do I do this?*

**Q*: How do I fix a bug/add a feature to one of the DJGPP programs?*

*A* :  First, get the sources.  These are called `*s.zip' in the DJGPP
distribution.  The C Library sources are in `djlsr200.zip'.  Some sources are
too big, and might be split into multiple zips, all of which must be unzipped
to get a complete source distribution, like this:

`gcc263s1.zip'
`gcc263s2.zip'
`gcc263s3.zip'
`gcc263s4.zip'
`gcc263s5.zip'
`gcc263s6.zip'
All sources are shipped in ready-to-build form.  The diffs in the `diffs/'
directory have already been applied.

Next, try to build the program without changing it.  Some packages will have
a `CONFIGUR.BAT' file; if so, run it first.  If there is a `MAKE.BAT' file,
run it; if not, look for a file named `MAKEFILE.DJ' or `MAKEFILE.DJG';
sometimes these will be in a subdirectory called `dos/', or `msdos/', or
`pc/'.  If there is such a file, then type, e.g., `make -f makefile.djg', if
not, just say `make' and see what happens.  (The reason for an apparent lack
of a standards here is that different packages were ported to DJGPP by
different people, as best as they saw fit.)  After you've succeeded to build
the program, make your fixes and build the program the same way you did
before.

Note that generally you must have GNU `Make' program to build these programs
(get the file mak373b.zip, e.g.
ftp://ftp.coast.net/SimTel/vendors/djgpp/v2gnu/mak373b.zip), and some
makefiles require that you install additional utilities, like Sed (get
sed118b.zip, e.g. ftp://ftp.coast.net/SimTel/vendors/djgpp/sed118b.zip).
Sometimes the makefiles won't even run under `COMMAND.COM' (they require a
smarter shell).  In that case, either get a better shell, convert the
makefile to be runnable by `COMMAND', or do the required steps manually.  If
the Makefile is too complex for you and you can't figure out what are the
necessary commands, invoke make with `-n' switch and see what it would have
done.

If your machine lacks floating-point hardware (like a 386 without a 387, or a
486SX), then you should know that current versions of GNU Sed and GNU Make
issue floating point instructions, so you will have to make provisions for
loading an emulator, see above, FP Emulation in Section 11.1.

22.2 Where to find sample DJGPP code or a package ported to DJGPP?
==================================================================

**Q*: Where can I find an example of XXXX / a package doing YYYY ?*

*A* :  Stephen Turnbull <turnbull@shako.sk.tsukuba.ac.jp> has compiled a list
of publicly available packages related to DJGPP, based on the DJGPP mailing
list traffic.  The list is still under construction (Steve says that many
pointers have not been followed up to get host and directory references
right), so this list must be taken with a grain of salt.  Check out Steve's
list, at this URL:

     http://turnbull.sk.tsukuba.ac.jp/public-ftp/djgpp/doc/documentation.list.html

Here is a short list of places you might look into for examples of frequently
needed code fragments, or for packages people keep asking about:

   * Interrupt-driven support of peripheral devices and hooking hardware
     interrupts:

        - download the Sound Blaster support package `sbXX.zip' from any
          SimTel mirror, in the `msdos/sound' directory.

        - you can look at the latest version of Sound Blaster support library
          at the OULU repository, e.g.
          ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2/sb05_dj2.zip or at
          the DJGPP server, e.g.
          ftp://ftp.delorie.com/pub/djgpp/contrib/sb05_dj2.zip; this package
          is maintained by Joel Hunter <jhunter@kendaco.telebyte.net>.

        - check out the example of hooking the timer interrupt, e.g.
          ftp://ftp.coast.net/msdos/c/pctime13.zip.

   * Network support libraries:

        - the TCPLIB library, e.g.
          ftp://lab1.psy.univie.ac.at/pub/tcplib-dj200/tcplib-dj200.1.tar.gz
          provides the TCP/IP sockets interface.  (I am told that you can
          safely ignore the warnings you get when compiling the package.)

   * Port of curses library to DJGPP:

        - download PDCurses package, e.g.
          ftp://ftp.coast.net/SimTel/vendors/djgpp/v2tk/pdc22.zip.

   * X library:

        - the Xlibemu library, e.g. ftp://asterix.inescn.pt/pub/PC/X/ includes
          `Xt' and `Xmu' toolkits, a 3D version of the `AW' toolkit, a few
          demo applications (e.g. `xmine'), and can be used to compile
          `Tcl'/`Tk' and GNU Emacs with X support.  Xlibemu is based on X11R5
          and is being developed by Antonio Costa <acc@asterix.inescn.pt>.
          It is also available on alternative sites, e.g.
          ftp://groucho.idt-isep.ipp.pt/pub/pc/djgpp/etc/X/.

        - the Xlib and Xt for DV/X, e.g.
          ftp://ftp.coast.net/SimTel/vendors/djgpp/qddvxNNN.zip (also
          qdlibNNN.zip and qdtktNNN.zip).

   * Ports of various GNU utilities not included in DJGPP (like Fileutils,
     Grep, Less, etc.):

        - Look on SimTel mirrors in the GNUish, e.g.
          ftp://ftp.coast.net/SimTel/vendors/gnu/gnuish/ and Textutil, e.g.
          ftp://ftp.coast.net/SimTel/msdos/textutil/ directories.  These are
          16-bit ports.

        - Marc Singer <elf@netcom.com> maintains a port of RCS, the Revision
          Control System, to DJGPP, e.g.
          ftp://ftp.netcom.com/pub/el/elf/rcsdos/.

   * Port of Borland's Turbo Vision

        - check out the BCGUI package, at this URL:

               http://www.delorie.com/djgpp/dl/contrib/

          or BCGUI via FTP, e.g.
          ftp://ftp.delorie.com/pub/djgpp/contrib/bcguiNNN.zip or BCGUI at
          Stephen Turnbull's server, e.g.
          ftp://turnbull.sk.tsukuba.ac.jp/pub/djgpp/packages/bcguiNNN.zip.

        - If you actually have the original Borland Turbo Vision, then you
          might want to get patches to compile Turbo Vision under DJGPP, e.g.
          ftp://ftp.uni-stuttgart.de/pub/systems/os2/programming/support/.
          For more info on this port, visit the TVPlus site, at this URL:

               http://www.zeta.org.au/~grove/tvhome.html

   * Game programming:

        - Try the Jlib gaming/graphics library, e.g.
          ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2/jlib_NNN.zip
          written by J P Griffiths <jpg@cs.waikato.ac.nz>.

   * VGA Mode-X graphics:

        - Paul Fenwick <bg914@FreeNet.Carleton.CA> wrote an X-Mode package
          Xlib, e.g. ftp://ftp.delorie.com/pub/djgpp/contrib/xlibdj24.zip or
          Xlib at OULU, e.g.
          ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2/xlibdj24.zip.

22.3 How to create symbolic links to programs
=============================================

**Q*: How do I create symbolic links?*

**Q*: I have this program that behaves differently depending on the name it's
called.  Under Unix, I just create symbolic links to achieve that, but DOS
doesn't support links.  Do I have to put several identical programs under
different names on my disk??*

*A* :  DJGPP allows you to simulate symbolic links to programs.  Generate a
stub (which is a small DOS program attached to every DJGPP program by the
`stubify.exe' program), call it by the name of the link you want, then edit
its header to run another program.  For example, let's say the real program
is `dj1.exe' and we want to make a link called `dj2.exe' that really calls
`dj1.exe'.  First, generate a stub under the name `dj2.exe'.  Next, run
`STUBEDIT' to modify the new programs' stub info block to change the name of
the executable it runs.  In this case, we'd change it to `dj1':

      C:\USR\BIN> stubify -g dj2.exe
      C:\USR\BIN> stubedit dj2.exe runfile=dj1

Voila!  Now, when you run `dj2', it tells the stub to load the image of
`dj1', but pass "dj2" in `argv[0]'.

22.4 Where to find the DPMI specification?
==========================================

**Q*: Where can I find the specifications for the DPMI functions?*

*A* :  You can find the DPMI 0.9 spec by anonymous ftp to one of the
following sites:

At Quarterdeck ftp site, e.g. ftp://qdeck.com/pub/memory/dpmispec.zip.

At the OULU repository of PC-specific programming info, e.g.
ftp://x2ftp.oulu.fi/pub/msdos/programming/specs/dpmispec.arj.

The DPMI 1.0 specs are available by anonymous ftp from the Intel anonymous
ftp site, e.g. ftp://ftp.intel.com/pub/IAL/software_specs/dpmiv1.txt.  (The
file `dpmiv1p.zip' at the same location is the PostScript version of this
spec.)

Some information about the DPMI API is also found in the Ralf Brown's
Interrupt List, e.g. ftp://ftp.coast.net/SimTel/msdos/info/inter48c.zip.
Look at the functions of Interrupt 31h, or search the files for the word
`DPMI'.

22.5 The DJGPP Web site.
========================

**Q*: Where is the DJGPP Web site?*

*A* :  Yes, DJGPP has its own home on the Internet, set up and maintained by
(who else?) DJ Delorie <dj@delorie.com>.  It has an HTML version of this FAQ
list with search capabilities, the entire set of DJGPP distribution files, a
searchable archive of the DJGPP mailing list traffic, plus other interesting
information about DJGPP.  For instance, did you ever wondered how DJGPP got
started and what were DJ's original goals?  Rejoice: the Web site includes
the story of DJGPP genesis, at this URL:

     http://www.delorie.com/djgpp/history.html

To visit, point your Web browser to the DJGPP Web site, at this URL:

     http://www.delorie.com/djgpp

22.6 Where to upload your contributions to DJGPP
================================================

**Q*: I wrote a program using DJGPP.  How can I make it available to others?*

**Q*: I found and corrected a bug in one of the programs distributed with
DJGPP.  Where should I put it?*

*A* :  If the program/patches are small enough, consider posting it to the
mailing list or the comp.os.msdos.djgpp Newsgroup as uuencoded compressed
archive (to conserve space).

If the compressed file is larger than, say, 50K bytes, it's best to upload it
to a public site where everybody can get it.  You can upload your
contribution to a special directory on the DJ Delorie's FTP server, e.g.
ftp://ftp.delorie.com/incoming/.  This directory is write-only, and it gets
purged every couple of days, so be sure to write to DJ Delorie
<dj@delorie.com> about your upload; he will then move it to the
`/pub/djgpp/contrib' directory.  (There used to be another place, a directory
on `omnigate.clarkson.edu' which was writable by anonymous, but it was being
used for malicious purposes and the sysadmins there decided to close it :-(.)

If you decide to upload, please send mail to djgpp-announce list
<djgpp-announce@delorie.com> with a brief description of your program/patch.
(The message will get reflected to both the newsgroup and the DJGPP mailing
list, so you don't have to cross-post there, but it also goes to people who
only subscribe to djgpp-announce list because they only want to get
announcements.)

If your program is more than a patch or a beta version, you might consider
uploading it to SimTel.  If you decide to do it, write to DJ Delorie
<dj@delorie.com> and ask him for uploading instructions.  Material uploaded
there gets automatically distributed to all of the SimTel mirrors throughout
the world, which makes it easier to get.

22.7 DJGPP as cross-compiler
============================

**Q*: I want to use DJGPP as a cross-compiler for Motorola 68K targets.  How
should I proceed about this?*

**Q*: I want to build GCC as a Unix-to-DOS cross-compiler.  What should I do?*

*A* :  If you want a cross-compiler for m68k on a DOS machine, you need is
DJGPP configured as `host=i386-go32', and `target=m68k-coff'.  This has been
done already, e.g. ftp://ftp.lysator.liu.se/pub/msdos/gnu/gcc-dos-m68k.  The
binaries there are based on GCC 2.6.0.

For building GCC as a Unix-to-DOS cross-compiler, here are the instructions
on how to do it.  (Unfortunately, "make install" in the Gcc distribution does
exactly the wrong thing by default, so you end up copying a lot of stuff
around manually.)

Unpack Gcc and Binutils into a directory, let's call it `X/'.  Thus, you
have, say, `X/gcc-2.7.0' and `X/binutils-2.5.2'.  The following sequence of
commands should make the job:

     mkdir $X/dos-binu
     cd $X/dos-binu
      --target=i386-coff-go32
     make CFLAGS=-O
     
     mkdir -p /usr/local/i386-go32-msdos/bin
     
     cd binutils
     cp ar c++filt objcopy objdump size /usr/local/i386-go32-msdos/bin
     cp nm.new /usr/local/i386-go32-msdos/bin/nm
     cp strip.new /usr/local/i386-go32-msdos/bin/strip
     
     cd ../gas
     cp as.new /usr/local/i386-go32-msdos/bin/as
     cp gasp.new /usr/local/i386-go32-msdos/bin/gasp
     
     cd ../ld
     cd ld.new /usr/local/i386-go32-msdos/bin/ld
     
     mkdir $X/dos-gcc
     cd $X/dos-gcc
      --target=i386-go32-msdos
     make LANGUAGES=c CFLAGS=-O
     
     cp xgcc /usr/local/bin/gcc-dos
     cp cc1 /usr/local/i386-go32-msdos/bin/cc1
     cp cccp /usr/local/i386-go32-msdos/bin/cpp

Unzip the DJDev and Gcc distributions in, say, /usr/local/djgpp.  Ideally,
build libgcc.a on a DOS machine.

Remove all `^M' characters from include files (you can compile DTOU.c on the
Unix box to make this easier).  Alternatively, use the `-a' switch to UnZip
when unzipping the archives.

Change lib/djgpp.lnk to use "coff-i386" instead of "coff-go32" and remove the
`^M' characters from that file also.

     mkdir -p /usr/local/lib/gcc-lib/i386-go32-msdos/2.7.0
     cd /usr/local/lib/gcc-lib/i386-go32-msdos/2.7.0
     ln -s /usr/local/djgpp/include .
     ln -s /usr/local/djgpp/lib/* .

Build `stubify' and install it in `/usr/local/i386-go32-msdos/bin'.

That's it!  To build a program for DOS, say something like this:

      gcc-dos hello.c -o hello.exe

22.8 GCC says "garbage at end of number"
========================================

**Q*: There is a severe bug in GCC: it says "garbage at end of number" for
this line:*

      i = 0xfe+0x20;

*Ain't it silly that such a great compiler would fail so miserably?*

*A* :  That's not a bug, that's a feature of the *ANSI C language
definition*.  By ANSI rules, the above expression is a single "preprocessing
token", unless you place whitespace in front of the plus sign.  The reason
for this seemingly counterintuitive feature is the syntax of floating-point
constants in which letters `e' and `E' followed immediately by a sign signal
a decimal exponent.  You can use the `-traditional' compiler switch to turn
this feature off (together with a plethora of other ANSI features; see the
GCC docs for details).

22.9 What should sizeof (struct xyzzy) return?
==============================================

**Q*: When I call `sizeof' on a struct, I sometimes get values which are
larger than the sum of the sizes of the struct fields, whereas in Borland C++
I always get the correct result.  Is it a bug in GCC?*

*A* : No, it's not a bug.  GCC generates 32-bit code, and in that mode, there
is a significant penalty (in terms of run-time performance) for unaligned
accesses, like accessing a 16-bit short which isn't aligned on a word
boundary, or accessing a 32-bit int which isn't aligned on a double-word
boundary.  To produce faster code, GCC pads struct fields so that each field
can be accessed without delays; this sometimes produces struct size which is
larger than the sum of sizes of its fields.  If you need to avoid this
padding (e.g., if your program uses large arrays of such structs, where
padding will waste a lot of memory), lay out your structures so that the
longer fields are before the shorter ones.  For example, let's say that you
have a struct defined thus:

       struct my_struct {
         char name[7];
         unsigned long offset;
         double quality;
       };

To make such a struct use the least number of bytes, rearrange the fields,
like this:

       struct my_struct {
         double quality;
         unsigned long offset;
         char name[7];
       };

If the layout of the structure cannot be changed (e.g., when it must match
some external specification, like a block of data returned by some system
call), you can use the `__attribute__((packed))' extension of GCC (See the
Gcc docs in "GNU C/C++ Manual", or point your Web browser to
http://www.delorie.com/gnu/docs/gcc/gcc_83.html#SEC86.) to prevent GCC from
padding the structure fields; this will make accesses to some of the fields
slower.

Beginning from version 2.7.0, GCC has a command-line option `-fpack-struct'
which causes GCC to pack all members of all structs together without any
holes, just as if you used `__attribute__((packed))' on every struct
declaration in the source file you compile with that switch.  If you use this
switch, be sure that source files which you compile with it don't use *any*
of the structures defined by library functions, or you will get some fields
garbled (because the library functions weren't compiled with that switch).

23. About this FAQ
******************

  Maintainer: Eli Zaretskii <eliz@is.elta.co.il>.

  This FAQ is Copyright (C) 1994, 1995, 1996 by Eli Zaretskii
<eliz@is.elta.co.il>.  It may be freely redistributed with the DJGPP package
or any part thereof, provided that you don't prevent anybody else from
redistributing it on the same terms, and that this copyright notice is left
intact.

  Comments about, suggestions for, or corrections to this FAQ list are welcome.
Please make sure to include in your mail the version number of the document
to which your comments apply (you can find the version at the beginning of
this FAQ list).

  Much of the info in this FAQ list was taken from the DJGPP mailing
list/newsgroup traffic, so many of you have (unbeknownst to you) contributed
to this list.  The following people read this list in its previous versions
and provided useful feedback, comments, information and/or suggestions:

     Anthony Appleyard <A.APPLEYARD@fs2.mt.umist.ac.uk>
     John Bodfish <bodfish@austen.notis.com>
     Bill Davidson <bdavidson@ra.isisnet.com>
     DJ Delorie <dj@delorie.com>
     Juergen Erhard <Jae@laden.ilk.de>
     Gordon Hogenson <ghogenso@u.washington.edu>
     Pieter Kunst <kunst@prl.philips.nl>
     Alexander Lehmann <lehmann@mathematik.th-darmstadt.de>
     Steve Salter <salters@admin.fanshawec.on.ca>
     Charles Sandmann <sandmann@clio.rice.edu>
     Terrel Shumway <Shumw001@Cerritos.edu>
     Stephen Turnbull <turnbull@shako.sk.tsukuba.ac.jp>
     Santiago Vila <sanvila@pizarro.unex.es>
     Morten Welinder <terra@diku.dk>
     Anthony Edward Wesley <awesley@galaxy.anutech.com.au>

24. Topic Index
***************

  This is an alphabetical list of all the topics covered in this FAQ.  Use it
to search for a description of your problem and follow the link to find the
answer(s).



* !proxy method of passing long command lines: Section 16.4.
* -ansi switch and C++-style comments in C programs: Section 8.3.
* -fconserve-space switch: Section 8.12.
* -msoft-float switch to GCC: Section 11.4.
* -traditional switch and C++-style comments in C programs: Section 8.3.
* .lib libraries, using with GCC: Section 17.5.
* .obj object files, using with GCC: Section 17.5.
* 16-bit code, using with DJGPP: Section 17.6.
* 68K targets, cross-compiling with DJGPP: Section 22.7.
* @ character, how to pass it to programs: Section 16.3.
* __crt0_glob_function, disable filename globbing: Section 16.2.
* __DJGPP__ pre-processor symbol: Section 8.6.
* __dpmi_get_memory_information, doesn't change after free/malloc: Section 15.2.
* __dpmi_get_protected_mode_interrupt_vector: Section 18.9.
* __dpmi_get_real_mode_interrupt_vector: Section 18.9.
* __dpmi_int, calling DOS/BIOS services: Section 18.1.
* __dpmi_int, high in program's profile: Section 13.4.
* __dpmi_int, how to pass buffers: Section 18.2.
* __dpmi_int, use to invoke software interrupts: Section 18.3.
* __dpmi_simulate_real_mode_interrupt, need zero SS, SP and FLAGS: Section 18.3.
* __GO32__ pre-processor symbol: Section 8.6.
* __pure_virtual, unresolved function: Section 8.11.
* _go32_dpmi_allocate_iret_wrapper: Section 18.9.
* _go32_dpmi_chain_protected_mode_interrupt_vector: Section 18.9.
* _go32_remaining_physical_memory, doesn't change after free/malloc: Section 15.2.
* _stklen, setting stack size: Section 15.8.
* Accessing absolute addresses above 1MB: Section 18.7.
* Accessing absolute addresses in conventional memory: Section 18.4.
* Accessing video memory: Section 10.1.
* Announcements, mailing list: Section 20.3.
* Archives, DJGPP mailing list/Newsgroup, how to search: Section 6.10.
* Asking for help: Section 6.11.
* Assembly source, code produced by Gas: Section 17.2.
* Assembly source, converting to AT&T syntax: Section 17.3.
* Assembly source, converting to protected mode: Section 17.4.
* Assembly source, GCC/Gas syntax: Section 17.1.
* Assembly syntax: Section 17.1.
* AT&T vs Intel assembly syntax: Section 17.1.
* atan, inaccuracies with FP emulator: Section 11.6.
* Automated downloading from a PC: Section 4.6.
* Automated downloading from a Unix box: Section 4.6.
* Automated FTP from a Unix box: Section 4.6.
* Automatic variables, how much memory: Section 15.8.
* Bad format, profiler error message: Section 13.2.
* Binary data I/O: Section 9.3.
* BIOS service calls: Section 18.1.
* BIOS service calls which need buffers: Section 18.2.
* BIOS setup, influence on compilation speed: Chapter 7.
* Browsing documentation: Section 5.1.
* Buffered I/O, effect of buffer size on I/O speed: Section 14.2.
* C library, legal restrictions: Section 19.2.
* C programs compilation, recommended system RAM: Section 3.1.
* C++ programs compilation, recommended system RAM: Section 3.1.
* C++ programs, large executable: Section 8.12.
* C++ source, debugger cannot find: Section 12.6.
* C++, missing header files: Section 8.2.
* C++-style comments in C programs, GCC won't compile: Section 8.3.
* Calling 16-bit code from DJGPP: Section 17.6.
* calloc fails under EMM386 or HIMEM: Section 15.6.
* calloc fails under QDPMI or Windows 95: Section 15.4.
* calloc fails under Windows 3.x: Section 15.5.
* calloc, effect on "Fat DS": Section 18.6.
* Can't find node "Top", Info message: Section 6.7.
* CD-ROM, getting DJGPP: Section 4.3.
* Chaining interrupt: Section 18.9.
* Changing GNU/DJGPP programs: Section 22.1.
* Child processes, spawning under OS/2: Section 3.2.
* Child processes, spawning under Windows/NT: Section 3.3.
* Child programs, how much memory is left: Section 15.7.
* Code quality, GCC: Section 14.1.
* Code, DJGPP-specific: Section 8.6.
* COFF output from linker, how to get: Section 12.3.
* COFF output, required for profiling: Section 13.2.
* Command line, disabling filename expansion/globbing: Section 16.2.
* Command line, escaping special characters: Section 16.3.
* Command line, filename expansion/globbing: Section 16.1.
* Command lines, longer than 126 characters: Section 16.4.
* Command-line arguments: Chapter 16.
* Comments, C++-style in C programs: Section 8.3.
* Commercial programs, writing with DJGPP: Section 19.1.
* Compatibility, hardware, general: Chapter 3.
* Compatibility, Linux: Section 3.1.
* Compatibility, Novell NWDOS 7: Section 3.1.
* Compatibility, operating systems, general: Chapter 3.
* Compatibility, OS/2: Section 3.1.
* Compatibility, Warp: Section 3.1.
* Compatibility, Windows 3.x: Section 3.1.
* Compatibility, Windows 9x: Section 3.1.
* Compatibility, Windows/NT: Section 3.1.
* Compilation for debugging: Section 12.1.
* Compilation messages, bogus: Section 8.4.
* Compilation speed: Chapter 7.
* Compile-time problems: Chapter 8.
* Compiler crashes, which subprogram of: Section 6.8.
* Compiling GCC and CPP: Section 3.7.
* Compiling GCC and CPP, RAM disk: Section 3.8.
* Compiling large programs, disk cache settings: Section 3.7.
* Compiling large programs, RAM disk settings: Section 3.7.
* Compiling large source files: Section 3.7.
* Compiling Objective C sources: Section 8.5.
* Configuration, for optimal performance: Section 3.8.
* Configuration, reasonable: Section 3.7.
* Configuration, the best: Section 3.6.
* Conventional memory, moving data to/from: Section 18.4.
* Converting DOS .obj/.lib files to GCC: Section 17.5.
* Converting DOS code to DJGPP: Chapter 17.
* Coprocessor setup, change with _control87: Section 11.5.
* Copyleft, effect on DJGPP: Section 19.1.
* Copyright issues: Chapter 19.
* Crash traceback, how to read: Section 9.2.
* Crash, DJGPP programs: Chapter 6.
* Crash, numeric exception: Section 11.5.
* Crashes, general troubleshooting: Section 6.8.
* Crashes, v2.0 programs: Section 9.1.
* Cross-compiling with DJGPP: Section 22.7.
* Ctrl-C in debugged programs: Section 12.7.
* Curses library for DJGPP: Section 22.2.
* DEADBEAF, use to spot uninitialized memory: Section 9.1.
* Debugger cannot find C++ source: Section 12.6.
* Debugger crashes on programs compiled for profiling: Section 12.7.
* Debugger crashes on programs which use exceptions: Section 12.7.
* Debugger crashes under QEMM/QDPMI: Section 12.2.
* Debugger doesn't pass signals to debuggee: Section 12.7.
* Debugger, usage: Section 12.1.
* Debuggers for DJGPP programs: Section 12.1.
* Debuggers use transfer buffer: Section 12.4.
* Debugging C++ programs: Section 12.6.
* Debugging graphics programs: Section 12.5.
* Debugging issues: Chapter 12.
* Debugging with GDB, needs COFF output: Section 12.3.
* Disabling globbing in filenames: Section 16.2.
* Disabling virtual memory for CWSDPMI: Chapter 7.
* Disabling wildcard expansion: Section 16.2.
* Disk cache, influence on compilation speed: Chapter 7.
* Disk cache, recommended settings: Section 3.8.
* Disk cache, when compiling large programs: Section 3.7.
* Disk space, required for installation: Section 3.1.
* Disk space, using less of it: Section 4.6.
* Distributing DJGPP programs: Section 9.5.
* Distributing DJGPP programs, FP emulator: Section 11.1.
* DJGPP applications, legal restrictions: Section 19.1.
* DJGPP archives, how to search: Section 6.10.
* DJGPP as cross-compiler: Section 22.7.
* DJGPP distribution, list of: Section 4.4.
* DJGPP Documentation: Chapter 5.
* DJGPP documentation, in man page format: Section 5.6.
* DJGPP documentation, in PostScript format: Section 5.4.
* DJGPP documentation, look in source distributions: Section 5.5.
* DJGPP documentation, printing: Section 5.3.
* DJGPP documentation, reading as ASCII file: Section 5.2.
* DJGPP documentation, reading with a Web browser: Section 5.4.
* DJGPP documentation, see source files: Section 5.7.
* DJGPP documentation, where to find it: Section 5.1.
* DJGPP mailing list, duplicate messages: Section 20.6.
* DJGPP mailing list, how to post: Section 20.2.
* DJGPP mailing list, how to subscribe: Section 20.3.
* DJGPP mailing list, how to unsubscribe: Section 20.4.
* DJGPP mailing list, in digest form: Section 20.3.
* DJGPP mailing list, no messages: Section 20.5.
* DJGPP Newsgroup: Section 20.7.
* DJGPP Newsgroup, reading via WWW: Section 20.3.
* DJGPP programs, problems with: Chapter 6.
* DJGPP programs, problems with DPMI host: Section 6.1.
* DJGPP programs, profiling: Section 13.1.
* DJGPP software, where to upload: Section 22.6.
* DJGPP users, asking for help: Section 6.11.
* DJGPP utilities, legal restrictions: Section 19.2.
* DJGPP v2.0, alternative DPMI hosts: Section 21.2.
* DJGPP, a list of packages: Section 4.4.
* DJGPP, downloading via e-mail: Section 4.3.
* DJGPP, downloading with FTP: Section 4.2.
* DJGPP, downloading with Gopher: Section 4.3.
* DJGPP, downloading with WWW: Section 4.3.
* DJGPP, how to get it: Chapter 4.
* DJGPP, sample code: Section 22.2.
* DJGPP, what it is: Chapter 2.
* DJGPP, where to download: Section 4.1.
* DJGPP-ANNOUNCE mailing list: Section 20.3.
* DJGPP-compiled programs can't find DPMI: Section 9.5.
* DJGPP-specific code: Section 8.6.
* Documentation, converting to plain ASCII: Section 5.2.
* Documentation, converting to PostScript format: Section 5.3.
* Documentation, in man page format: Section 5.6.
* Documentation, in PostScript format: Section 5.4.
* Documentation, inside source distribution archives: Section 5.5.
* Documentation, reading: Section 5.1.
* Documentation, the profiler: Section 13.3.
* DOS code, using with GCC: Section 17.6.
* DOS libraries, using with GCC: Section 17.5.
* DOS object files, using with GCC: Section 17.5.
* DOS programs, converting to DJGPP: Chapter 17.
* DOS service calls: Section 18.1.
* DOS service calls which need buffers: Section 18.2.
* Downloading DJGPP via e-mail: Section 4.2.
* Downloading DJGPP with FTP: Section 4.2.
* Downloading DJGPP with WWW: Section 4.3.
* DPMI host bugs, might crash DJGPP programs: Section 6.1.
* DPMI hosts, commercially available: Section 21.2.
* DPMI services, problems with Novell NWDOS 7: Section 3.1.
* DPMI services, required to run DJGPP: Section 3.1.
* DPMI spec, where to get it: Section 22.4.
* DPMI, required to run DJGPP programs: Section 9.5.
* Duplicate messages from DJGPP mailing list: Section 20.6.
* E-mail, downloading DJGPP: Section 4.3.
* Emulation, floating-point: Chapter 11.
* Emulator library: Section 11.1.
* Emulator, floating-point inaccuracies: Section 11.6.
* Environment variables, DJGPP: Section 3.6.
* Environment variables, linker: Section 8.9.
* Error messages, redirecting to a file: Section 6.9.
* Excessive paging, tuning CWSDPMI: Section 3.8.
* Executable, bloated by static array: Section 8.12.
* Far pointer memory access: Section 10.1.
* Farptr functions, mask off 12 higher bits of address: Section 18.5.
* Fatal signal, GCC message: Section 6.3.
* File format not recognized by GCC: Section 8.4.
* Filename globbing: Section 16.1.
* Filename globbing, disabling: Section 16.2.
* Filename wildcards expansion: Section 16.1.
* Filename wildcards, disabling expansion: Section 16.2.
* Files, minimum set to download: Section 4.4.
* Files, reading and writing: Section 9.3.
* Files, required disk space: Section 4.5.
* Floating-point emulation: Chapter 11.
* Floating-point emulation doesn't work: Section 11.1.
* Floating-point emulation under debugger: Section 12.7.
* Floating-point emulation, -msoft-float switch: Section 11.4.
* Floating-point emulation, non-DJGPP emulators: Section 11.2.
* Floating-point emulation, under OS/2: Section 11.3.
* Floating-point issues: Chapter 11.
* Floating-point math functions, standard and high-quality: Section 8.7.
* Floating-point, debugger support: Section 12.1.
* free doesn't change virtual memory: Section 15.2.
* FTP, downloading DJGPP: Section 4.2.
* FTP, downloading DJGPP in batch mode: Section 4.6.
* Functions, which is in what library: Section 8.8.
* Game programming, libraries and techniques for DJGPP: Section 22.2.
* Garbage at end of number, GCC message: Section 22.8.
* GCC aborts with "Internal compiler error": Section 6.3.
* GCC can't recognize file format: Section 8.4.
* GCC can't recognize source language: Section 8.4.
* GCC crashes, which subprogram of: Section 6.8.
* GCC hangs/crashes under Make: Section 6.6.
* GCC says "Fatal signal X": Section 6.3.
* Getting DJGPP <1>: Section 4.1.
* Getting DJGPP: Chapter 4.
* getting DJGPP from a CD-ROM: Section 4.3.
* Getting documentation: Section 5.1.
* Getting more help: Chapter 20.
* Globbing in filenames: Section 16.1.
* Globbing in filenames, disabling: Section 16.2.
* GNU Copyleft, effect on DJGPP: Section 19.1.
* GNU development utilities, port to DJGPP: Section 22.2.
* GNU Newsgroups, don't post DJGPP problems: Section 20.1.
* GNU packages, how to change: Section 22.1.
* GNUish method to pass long command lines: Section 16.4.
* Gopher, downloading DJGPP: Section 4.3.
* GPL, effect on DJGPP: Section 19.1.
* Graphics issues: Chapter 10.
* Graphics programs, debugging: Section 12.5.
* Graphics, direct video access: Section 10.1.
* Gurus, asking for help: Section 6.11.
* Hang, all DJGPP programs: Section 6.1.
* Hang, DJGPP programs: Chapter 6.
* Hardware interrupt handler crashes: Section 18.10.
* Hardware interrupts, hooking: Section 18.9.
* Hardware interrupts, subtleties: Section 18.10.
* Hardware requirements: Chapter 3.
* Hardware requirements, minimal: Section 3.1.
* Hardware-oriented programming: Chapter 18.
* Header files, C++, GCC can't find: Section 8.2.
* Header files, GCC can't find: Section 8.1.
* Help, asking for: Section 6.11.
* HTML format, DJGPP documentation: Section 5.4.
* I/O speed, DJGPP programs: Section 14.2.
* i286: Section 3.4.
* i386SX: Section 3.1.
* Inaccuracies, using emulator: Section 11.6.
* Incompatibilities, i286: Section 3.4.
* Incompatibilities, OS/2: Section 3.2.
* Incompatibilities, Warp: Section 3.2.
* Incompatibilities, Windows/NT: Section 3.3.
* Info won't display a file: Section 6.7.
* Inline functions, linker won't find: Section 8.10.
* inp function: Section 18.11.
* int86 crashes program: Section 18.1.
* int86x/intdosx, how to pass a buffer: Section 18.2.
* intdos crashes program: Section 18.1.
* Intel assembly syntax, converting to AT&T: Section 17.3.
* Intel vs AT&T assembly syntax: Section 17.1.
* Interactive programs, screen I/O: Section 9.4.
* Internal compiler error, when compiling C++ programs: Section 6.3.
* Interrupt chaining: Section 18.9.
* Interrupt frequency, maximum: Section 18.10.
* Interrupt handlers, locking memory: Section 18.10.
* Interrupt reflection: Section 18.9.
* Interrupts handlers in DJGPP: Section 18.9.
* Keyboard interrupt cannot be hooked under debugger: Section 12.7.
* Legal aspects of DJGPP programming: Chapter 19.
* Legal restrictions on DJGPP apps: Section 19.1.
* Legal restrictions, DJGPP utilities: Section 19.2.
* Length of command line: Section 16.5.
* Letter case in filenames submitted to GCC: Section 8.4.
* LGPL, effect on DJGPP: Section 19.1.
* Libraries, converting to DJGPP: Chapter 17.
* Libraries, GCC can't find: Section 8.1.
* Libraries, order on compilation/link command line: Section 8.9.
* Libraries, searching for functions: Section 8.8.
* Library functions, C++, linker won't find: Section 8.10.
* Library functions, linker won't find: Section 8.7.
* Library functions, linker won't find in non-default directories: Section 8.9.
* Library functions, linker won't find, libraries' order: Section 8.9.
* Library, floating-point emulation: Section 11.1.
* Linear address, mask off 12 higher bits: Section 18.5.
* Link-time problems: Chapter 8.
* Linking C++ programs, use the GXX driver: Section 8.7.
* Linking programs, unresolved C++ library functions: Section 8.10.
* Linking programs, unresolved library functions: Section 8.7.
* Linking programs, unresolved library functions, libraries' order: Section 8.9.
* Links, symbolic, simulation with DJGPP: Section 22.3.
* List of DJGPP packages: Section 4.4.
* Locking memory for interrupt handlers: Section 18.10.
* Long command lines: Section 16.4.
* Long command lines, from Makefile: Section 16.6.
* Long command lines, maximum length: Section 16.5.
* Low-level programming issues: Chapter 18.
* Machines with low extended RAM, tuning CWSDPMI: Section 3.8.
* Makefile, passing long command lines: Section 16.6.
* Makefiles with long command lines: Section 16.4.
* malloc doesn't change virtual memory: Section 15.2.
* malloc fails under EMM386 or HIMEM: Section 15.6.
* malloc fails under QDPMI or Windows 95: Section 15.4.
* malloc fails under Windows 3.x: Section 15.5.
* malloc, effect on "Fat DS": Section 18.6.
* Man pages, how to read: Section 5.6.
* Maximum interrupt frequency: Section 18.10.
* Maximum length of command line: Section 16.5.
* Memory allocation fails under EMM386 or HIMEM: Section 15.6.
* Memory allocation fails under QDPMI or Windows 95: Section 15.4.
* Memory allocation fails under Windows 3.x: Section 15.5.
* Memory at run time: Chapter 15.
* Memory manager, settings for optimal performance: Section 3.8.
* Memory, how much is left for spawned programs: Section 15.7.
* Memory, virtual, failure to allocate: Section 15.3.
* Memory, virtual, free doesn't change: Section 15.2.
* Memory, virtual, malloc doesn't change: Section 15.2.
* Memory, virtual, maximum available: Section 15.1.
* Memory, virtual, QDPMI failure: Section 15.3.
* Memory-mapped devices above 1MB: Section 18.7.
* Memory-mapped devices, fast access: Section 18.6.
* Memory-mapped devices, moving data to/from: Section 18.4.
* Minimal hardware requirements: Section 3.1.
* Minimum system RAM: Section 3.1.
* Minimum system RAM, CWSDPMI: Section 3.1.
* Missing C++ header files: Section 8.2.
* Missing header files: Section 8.1.
* Missing libraries: Section 8.1.
* Mixing v2.0 GCC with CC1PLUS from v1.x, Unknown filetype message.: Section 6.4.
* Mixing v2.x Make with v1.x programs hangs the machine: Section 6.6.
* Mode switches, effect on program speed: Section 14.1.
* Monochrome monitor, redirecting screen output: Section 12.5.
* More help, how to get: Chapter 20.
* Motorola 68K targets, cross-compiling with DJGPP: Section 22.7.
* Mouse handler with DJGPP: Section 18.8.
* movedata, mask off 12 higher bits of address: Section 18.5.
* Moving data to and from conventional memory: Section 18.4.
* Moving data to and from transfer buffer: Section 18.4.
* MS-Windows header file windows.h, where to get it: Section 3.5.
* MS-Windows programming under DJGPP: Section 3.5.
* Nearptr functions: Section 18.6.
* Nearptr functions, mask off 12 higher bits of address: Section 18.5.
* nearptr method of direct memory access: Section 18.4.
* Nested programs, how much memory is left: Section 15.7.
* New features in v2.0: Section 21.1.
* No messages from the mailing list: Section 20.5.
* Non-DJGPP floating-point emulators: Section 11.2.
* Not COFF error message from DJGPP programs: Section 6.4.
* Novell NDOS, buggy DPMI services crash DJGPP: Section 6.1.
* Null pointer dereference crashes v2.0 programs: Section 9.1.
* Numeric exception, program crash: Section 11.5.
* Objective C, compiling: Section 8.5.
* Old CWSDPMI, influence on compilation speed: Chapter 7.
* Optimal performance, CWSDPMI tuning: Section 3.8.
* Optimal performance, disk cache settings: Section 3.8.
* Optimal performance, RAM disk settings: Section 3.8.
* Optimal performance, system configuration: Section 3.8.
* optimization crashes GCC: Section 6.2.
* Optimizing DJGPP programs: Section 13.1.
* outp function: Section 18.11.
* Packages, DJGPP, list of: Section 4.4.
* Packages, ported to DJGPP: Section 22.2.
* Packages, required disk space: Section 4.5.
* Packages, which to download: Section 4.4.
* Packing the structs: Section 22.9.
* Paging starts before all RAM is used: Section 15.6.
* Peek/poke absolute address: Section 18.4.
* Performance issues: Chapter 14.
* Peripheral devices above 1MB: Section 18.7.
* Peripheral devices, fast access: Section 18.6.
* Peripheral devices, reading/writing ports: Section 18.11.
* Peripherals, moving data to/from: Section 18.4.
* Pi, accurate computation: Section 11.6.
* Port reading/writing: Section 18.11.
* Ported programs run much slower: Section 14.3.
* Posting problems, not to GNU Newsgroups: Section 20.1.
* Posting to DJGPP mailing list: Section 20.2.
* PostScript documentation: Section 5.3.
* PostScript documentation, ready-to-print: Section 5.4.
* Pre-processor symbols, DJGPP-specific: Section 8.6.
* Printing DJGPP documentation: Section 5.3.
* Problems with DJGPP programs: Chapter 6.
* Problems, asking for help: Section 6.11.
* Problems, searching for solution in DJGPP archives: Section 6.10.
* Profiled programs crash under debugger: Section 12.7.
* Profiler documentation: Section 13.3.
* Profiling DJGPP programs: Section 13.1.
* Profiling DJGPP programs, need COFF output: Section 13.2.
* Profiling issues: Chapter 13.
* Profiling, library routines: Section 13.4.
* Program crashes in int86/intdos: Section 18.1.
* Program crashes in v2.0, but not in v1.x: Section 9.1.
* Programs crash with SIGSEGV due to small stack size: Section 15.8.
* Programs crash, general troubleshooting: Section 6.8.
* Programs crash, numeric exception: Section 11.5.
* Programs crash, saving debugging output: Section 6.9.
* Programs crash, searching DJGPP archives: Section 6.10.
* Protected mode and converted assembly code: Section 17.4.
* Protected-mode interrupt vector: Section 18.9.
* QEMM auto/off mode, conflicts with DJGPP: Section 6.5.
* Quotes, how to pass them to programs: Section 16.3.
* RAM disk, influence on compilation speed: Chapter 7.
* RAM disk, recommended settings: Section 3.8.
* RAM disk, when compiling large programs: Section 3.7.
* RCS port to DJGPP: Section 22.2.
* Reading documentation: Section 5.1.
* Reading documentation with text editor/viewer: Section 5.2.
* Reading documentation, converting to plain ASCII: Section 5.2.
* Real-mode call-back: Section 18.8.
* Real-mode interrupt vector: Section 18.9.
* Real-mode services, calling DJGPP functions: Section 18.8.
* realloc, effect on "Fat DS": Section 18.6.
* Reboot, every DJGPP program: Section 6.1.
* Reboot, when running DJGPP programs: Chapter 6.
* Recommended system RAM, for C programs compilation: Section 3.1.
* Recommended system RAM, for C++ programs compilation: Section 3.1.
* Recompiling GCC: Section 22.1.
* Redirecting GCC messages to a file: Section 6.9.
* Redirection in Makefile, effect on long command lines: Section 16.6.
* Required hardware, general: Chapter 3.
* Response file, passing long command lines: Section 16.4.
* Run-time environment in v2.0: Section 21.2.
* Run-time performance: Chapter 14.
* Run-time problems: Chapter 9.
* sbrk, effect on "Fat DS": Section 18.6.
* Screen I/O: Section 9.4.
* Searching DJGPP archives: Section 6.10.
* setvbuf, effect on I/O speed: Section 14.2.
* SHELL= variable in Makefile, effect on long command lines: Section 16.6.
* Signals in debugged programs: Section 12.7.
* SimTel mirrors' list: Section 4.1.
* Size of a struct under DJGPP: Section 22.9.
* Slow compilation: Chapter 7.
* Slow compilation, tuning CWSDPMI: Section 3.8.
* Slow-down, programs ported from other compilers: Section 14.3.
* Software interrupts, need zero SS, SP and FLAGS: Section 18.3.
* Solved problems, searching in DJGPP archives: Section 6.10.
* Sound Blaster code for DJGPP: Section 22.2.
* Source files, using as the best docs: Section 5.7.
* Spawned programs, how much memory is left: Section 15.7.
* Spawning child processes, OS/2: Section 3.2.
* Spawning child processes, Windows/NT: Section 3.3.
* Spawning v2.x programs from v1.x programs doesn't work: Section 6.6.
* Speed of compilation: Chapter 7.
* Stack dump, how to read: Section 9.2.
* Stack size under DJGPP: Section 15.8.
* Stack size, insufficient, causes programs to crash: Section 15.8.
* Standard output/error stream, redirecting to a file: Section 6.9.
* Static array enlarges C++ executable: Section 8.12.
* Struct, size in bytes under DJGPP: Section 22.9.
* Structure padding: Section 22.9.
* Subscription to DJGPP mailing list: Section 20.3.
* Subsidiary programs, how much memory is left: Section 15.7.
* Symbolic links, simulation with DJGPP: Section 22.3.
* System configuration, the best: Section 3.6.
* System RAM, minimum: Section 3.1.
* Systems programming issues: Chapter 18.
* TCP/IP library for DJGPP: Section 22.2.
* Text-mode video memory access: Section 10.1.
* Timer interrupts code for DJGPP: Section 22.2.
* Traceback, how to read: Section 9.2.
* Transfer buffer, mask off 12 higher bits of address: Section 18.5.
* Transfer buffer, moving data: Section 18.4.
* Transfer buffer, use when debugging: Section 12.4.
* Transfer buffer, using to call DOS/BIOS: Section 18.2.
* Tuning CWSDPMI for optimal performance: Section 3.8.
* Turbo Vision, DJGPP port: Section 22.2.
* Uninitialized memory crashes v2.0 programs: Section 9.1.
* Unix-like sbrk algorithm considered harmful for HW interrupts: Section 18.10.
* Unix-to-DOS cross-compiling with DJGPP: Section 22.7.
* Unknown filetype, GCC message: Section 6.4.
* Unresolved __pure_virtual function in C++: Section 8.11.
* Unresolved externals: Section 8.7.
* Unresolved externals in C++ programs, use GXX: Section 8.7.
* Unresolved externals, C++: Section 8.10.
* Unsubscribing from the DJGPP mailing list: Section 20.4.
* Unsupported DOS request message: Section 18.1.
* Unsupported INT message: Section 18.1.
* Uploading DJGPP software: Section 22.6.
* V2.0, new environment: Section 21.2.
* V2.0, new features and bug fixes: Chapter 21.
* v2.0, program crashes: Section 9.1.
* V86 mode, QEMM and CWSDPMI problems: Section 6.5.
* VGA Mode-X graphics for DJGPP: Section 22.2.
* Video memory, direct access: Section 10.1.
* Virtual memory: Chapter 15.
* Virtual memory, failure to allocate: Section 15.3.
* Virtual memory, free doesn't change: Section 15.2.
* Virtual memory, how to disable it for CWSDPMI: Chapter 7.
* Virtual memory, malloc doesn't change: Section 15.2.
* Virtual memory, maximum available: Section 15.1.
* Virtual memory, QDPMI failure: Section 15.3.
* Virus infection cause "Not COFF" message: Section 6.4.
* Web site for DJGPP: Section 22.5.
* Wildcards expansion: Section 16.1.
* Wildcards expansion, disabling: Section 16.2.
* Win32 programming with GCC: Section 3.5.
* Windows applications with DJGPP: Section 3.5.
* WWW services for DJGPP: Section 22.5.
* WWW, downloading DJGPP: Section 4.3.
* X emulation for DJGPP: Section 22.2.

25. Program Index
*****************

  This index lists the problems and solutions by the program/package to which
they pertain.  If you know what program or package gives you the trouble,
look it up here.



* 386Max, how to ensure virtual memory: Section 15.3.
* 386Max, speeding up DJGPP start-up: Section 15.3.
* 4DOS, redirecting GCC messages to a file: Section 6.9.
* _control87, change coprocessor setup: Section 11.5.
* _crt0_startup_flags settings and QDPMI: Section 15.3.
* _crt0_startup_flags, setting to lock memory: Section 18.10.
* _crt0_startup_flags, Unix sbrk is incompatible with HW interrupts: Section 18.10.
* _string.h, GCC can't find: Section 8.2.
* AutoWinNet, automated downloading: Section 4.6.
* BatchFTP, automated downloading from a Unix box: Section 4.6.
* BCCBGI (from BCC2GRX) crashes with the default stack: Section 15.8.
* Bison doesn't imply GPL/LGPL: Section 19.1.
* C++ class libraries, legal restrictions: Section 19.1.
* C++ compiler crashes for large programs: Section 15.8.
* C++ compiler overflows its stack for large programs: Section 6.3.
* Cawf, using to read man pages: Section 5.6.
* CC1PLUS crashes with SIGSEGV: Section 15.8.
* complex.h functions, linker can't find: Section 8.10.
* Complex.h, GCC can't find: Section 8.2.
* CPP, compiling, memory requirements: Section 3.7.
* CPP, compiling, RAM disk: Section 3.8.
* CTRL87, control numeric exceptions: Section 11.5.
* CWSDPMI allows "Fat DS": Section 18.6.
* CWSDPMI crashes programs which dereference NULL pointers: Section 9.1.
* CWSDPMI runs out of virtual memory: Section 6.3.
* CWSDPMI, alternative DPMI hosts: Section 21.2.
* CWSDPMI, diasbling virtual memory: Chapter 7.
* CWSDPMI, legal restrictions: Section 19.2.
* CWSDPMI, maximum available virtual memory: Section 15.1.
* CWSDPMI, memory usage for nested programs: Section 15.7.
* CWSDPMI, minimum required system RAM: Section 3.1.
* CWSDPMI, old (beta) versions slow-down compilation: Chapter 7.
* CWSDPMI, pages too early under EMM386: Section 15.6.
* CWSDPMI, problems with QEMM auto/off mode: Section 6.5.
* CWSDPMI, setting parameters for optimal performance: Section 3.8.
* CWSDPMI, should be distributed with DJGPP programs: Section 9.5.
* CWSPARAM, a program to tune CWSDPMI performance: Section 3.8.
* DJGPP.ENV, compiler environment variables: Section 8.1.
* DJGPP.ENV, linker environment variables: Section 8.9.
* DOSEMU doesn't allow "Fat DS": Section 18.6.
* Emacs, reading docs: Section 5.1.
* Emacs, reading Info files: Section 5.1.
* Emacs, using to read man pages: Section 5.6.
* EMM386, cannot use all free memory: Section 15.6.
* EMM386, effect on max interrupt frequency: Section 18.10.
* EMM386, malloc/calloc fails: Section 15.6.
* EMM386, settings for optimal performance: Section 3.8.
* emTeX, printing the docs: Section 5.3.
* emu387.dxe, distribution with DJGPP programs: Section 11.1.
* EMX/GCC, writing Windows applications: Section 3.5.
* Flex doesn't imply GPL/LGPL: Section 19.1.
* FSDB crashes under QEMM/QDPMI: Section 12.2.
* FSDB, the full-screen debugger: Section 12.1.
* Gas can introduce errors into assembly code: Section 17.2.
* GCC can't find C++ headers: Section 8.2.
* GCC can't find headers: Section 8.1.
* GCC can't find libraries: Section 8.1.
* GCC crashes during optimization: Section 6.2.
* GCC crashes, which subprogram of: Section 6.8.
* GCC doesn't recognize .lib libraries: Section 17.5.
* GCC doesn't recognize .obj object files: Section 17.5.
* GCC doesn't recognize file format: Section 8.4.
* GCC from v2.x crashes under v1.x Make: Section 6.6.
* GCC hangs under Make: Section 6.6.
* GCC says "garbage at end of number": Section 22.8.
* GCC won't compile C++-style comments in C programs: Section 8.3.
* GCC won't find inline functions without -O: Section 8.10.
* GCC, -fconserve-space switch: Section 8.12.
* GCC, -msoft-float switch: Section 11.4.
* GCC, -v switch shows the compilation passes: Section 8.4.
* GCC, assumes C++ source is .cc: Section 12.6.
* GCC, code efficiency: Section 14.1.
* GCC, compiling for debugging: Section 12.1.
* GCC, compiling, memory requirements: Section 3.7.
* GCC, compiling, RAM disk: Section 3.8.
* GCC, environment variables: Section 8.1.
* GCC, file source language recognition: Section 8.4.
* GCC, I/O speed: Section 14.2.
* GCC, maximum length of command line in Makefiles: Section 16.5.
* GCC, passing long command lines via Makefile: Section 16.6.
* GCC, recompiling: Section 22.1.
* GCC, redirecting messages to a file: Section 6.9.
* GCC, slow compilation: Chapter 7.
* GCCRM (real-mode GCC), use with OS/2: Section 3.2.
* GCCRM (real-mode GCC), use with Windows/NT: Section 3.3.
* GDB crashes under QEMM/QDPMI: Section 12.2.
* GDB needs COFF output: Section 12.3.
* GDB, debugging DJGPP programs: Section 12.1.
* GDB, debugging graphics programs: Section 12.5.
* go32-v2, use to find out how much memory is available to DJGPP: Section 15.6.
* Gprof cannot find program: Section 13.2.
* Gprof documentation: Section 13.3.
* Gprof says "bad format": Section 13.2.
* Gprof, documentation: Section 5.5.
* Gprof, the GNU profiler: Section 13.1.
* Groff, port to DJGPP: Section 5.6.
* Groff, using to read man pages: Section 5.6.
* gxx driver, searches C++ libraries automatically: Section 8.7.
* HIMEM, malloc/calloc fails: Section 15.6.
* Info crashes under QDPMI: Section 6.1.
* Info won't display a file: Section 6.7.
* Info, a stand-alone docs browser: Section 5.1.
* Info, using to read man pages: Section 5.6.
* iostream functions, linker can't find: Section 8.10.
* iostream library, why use it: Section 8.7.
* iostream.h, GCC can't find: Section 8.2.
* LaTeX, printing the docs: Section 5.3.
* Less, using to read man pages: Section 5.6.
* libemu.a FP emulation library: Section 11.1.
* libg++ library: Section 8.7.
* libgpp library: Section 8.7.
* libgpp.a, legal restrictions: Section 19.1.
* libiostream.a, legal restrictions: Section 19.1.
* Linker can't find library functions: Section 8.7.
* Linker can't find library functions in non-default directories: Section 8.9.
* Linker can't find some C++ library functions: Section 8.10.
* Linker, environment variables: Section 8.9.
* Linker, how to get COFF output: Section 12.3.
* Linker, order of libraries in the command line: Section 8.9.
* Linux doesn't allow "Fat DS": Section 18.6.
* Linux, compatibility: Section 3.1.
* Make requires floating point: Section 22.1.
* Make, GCC hangs when invoked from it: Section 6.6.
* Make, maximum length of command line to pass to GCC: Section 16.5.
* Make, passing long command lines via Makefile: Section 16.6.
* Makeinfo, using to convert Info files to plain ASCII: Section 5.2.
* Man program for DJGPP docs: Section 5.6.
* math library, default ANSI/ISO and high-quality functions: Section 8.7.
* More, using to read man pages: Section 5.6.
* Mosaic, downloading DJGPP: Section 4.3.
* MSHELL, redirecting screen output: Section 12.5.
* NDOS, buggy DPMI services crash DJGPP: Section 6.1.
* Netscape, downloading DJGPP: Section 4.3.
* NM, printing library contents: Section 8.8.
* Novell NWDOS 7, buggy DPMI services: Section 3.1.
* Novell NWDOS 7, compatibility: Section 3.1.
* NWDOS, buggy DPMI services crash DJGPP: Section 6.1.
* OBJ2COFF converter from .obj to COFF format: Section 17.5.
* OBJDUMP segment overrides bugs: Section 17.2.
* Objective C, compilation problems: Section 8.5.
* obstack package: Section 8.7.
* OS/2, compatibility: Section 3.1.
* OS/2, floating point emulation: Section 11.3.
* OS/2, incompatibilities: Section 3.2.
* QDPMI allows "Fat DS": Section 18.6.
* QDPMI and _crt0_startup_flags settings: Section 15.3.
* QDPMI crashes debugger: Section 12.2.
* QDPMI crashes Info: Section 6.1.
* QDPMI fails to provide virtual memory: Section 15.3.
* QDPMI, malloc/calloc failure: Section 15.4.
* QDPMI, memory usage for nested programs: Section 15.7.
* QEMM crashes debugger: Section 12.2.
* QEMM, auto/off mode, conflicts with CWSDPMI: Section 6.5.
* QEMM386, settings for optimal performance: Section 3.8.
* RCS port to DJGPP: Section 22.2.
* REDIR, redirecting GCC messages to a file: Section 6.9.
* REDIR, redirecting stack dump to a file: Section 9.2.
* regex package from GNU: Section 8.7.
* Regex.h, GCC can't find: Section 8.2.
* RSX extender: Section 3.5.
* RSXWDK2 Windows development kit: Section 3.5.
* sbrk algorithm and QDPMI: Section 15.3.
* sbrk, Unix-like algorithm is incompatible with HW interrupts: Section 18.10.
* SCRIPT, redirecting GCC messages to a file: Section 6.9.
* Sed requires floating point: Section 22.1.
* Sed script to convert ASM to AT&T syntax: Section 17.3.
* Sed, documentation: Section 5.5.
* sizeof, result when called on a structure: Section 22.9.
* stdiostream.h, GCC can't find: Section 8.2.
* streambuf.h, GCC can't find: Section 8.2.
* STUBEDIT, changing stack size: Section 15.8.
* STUBEDIT, effect on memory left to spawned programs: Section 15.7.
* STUBIFY.EXE, infected by a virus: Section 6.4.
* SYMIFY, a program to read crash traceback: Section 9.2.
* TA2AS, a converter from Intel to AT&T assembly syntax: Section 17.3.
* TeX, printing the docs: Section 5.3.
* TEXI2PS, converting docs to crude PostScript: Section 5.3.
* Warp, compatibility: Section 3.1.
* Warp, incompatibilities: Section 3.2.
* Win95 long filenames and C++ headers: Section 8.2.
* Windows 3.x allows "Fat DS": Section 18.6.
* Windows 3.x, compatibility: Section 3.1.
* Windows 3.x, malloc/calloc fails: Section 15.5.
* Windows 95, malloc/calloc failure: Section 15.4.
* Windows 9x, compatibility: Section 3.1.
* Windows applications, writing with EMX/GCC: Section 3.5.
* Windows, memory usage for nested programs: Section 15.7.
* Windows, setting memory parameters for DJGPP: Section 3.8.
* Windows, stack size control: Section 15.8.
* windows.h header file, where to get it: Section 3.5.
* Windows/NT, compatibility: Section 3.1.
* WMEMU, and alternative floating-point emulator: Section 11.1.
* WMEMU, use when debugging FP programs on non-FPU machine: Section 12.7.



