home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-01-17 | 379.8 KB | 8,083 lines |
- 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, 1997 Eli Zaretskii
-
- This is the second edition of the FAQ list,
- and is consistent with version 2.01 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. Programmers 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.10 of the FAQ, last updated 17 January 1997, for DJGPP
- Version 2.01.
-
- Another place to look for DJGPP documentation is the DJGPP Knowledge Base, at
- this URL:
-
- http://www.delorie.com/djgpp/doc/kb/
-
- Brennan Underwood <brennan@mack.rt66.com> maintains a home page which is
- another valuable source for information about DJGPP, at this URL:
-
- http://brennan.home.ml.org/djgpp
-
- 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/faq210s.zip
-
- Also available from the DJ's server: FAQ in all the supported formats, at
- this URL:
-
- http://www.delorie.com/djgpp/v2faq/faq210b.zip
-
- A previous version of this FAQ was translated into French, e.g.
- ftp://ftp.delorie.com/pub/djgpp/v2faq/frfaq.zip, also available through the
- WWW, at this URL:
-
- http://www.delorie.com/djgpp/v2faq/frfaq.zip
-
- 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 it run under Linux?
- 3.5 Can I run it on a 286?
- 3.6 MS-Windows applications and DJGPP
- 3.7 What you *should* buy ...
- 3.8 What most of us will *actually* buy ...
- 3.9 How to configure your system for DJGPP?
- 4. Where and What to Download?
- 4.1 Where can I get DJGPP?
- 4.2 CCT sites
- 4.3 How do I download DJGPP?
- 4.4 What if I don't know what `FTP' is?
- 4.5 What Files to Download?
- 4.6 How much disk space will I need?
- 4.7 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 GCC says ``No DPMI''
- 6.2 Buggy DPMI host or junk in DJGPP.ENV can crash v2.x programs
- 6.3 GCC can crash during optimization
- 6.4 What does ``Fatal signal X'' mean?
- 6.5 What does ``Unknown filetype'' mean?
- 6.6 You can't use `QEMM' auto/off mode with DJGPP
- 6.7 Compiler hangs, but only when invoked from Make
- 6.8 Info doesn't like some files
- 6.9 My problem isn't mentioned above!
- 6.10 I can't keep up with the error messages
- 6.11 How to search DJGPP archives for similar problems
- 6.12 How to ask DJGPP gurus for help
- 7. Compiler and Linker Performance
- 7.1 Slow Compilation
- 7.2 Slow Linking
- 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 Where is class Complex?
- 8.12 The linker complains about __pure_virtual function.
- 8.13 Unresolved djgpp_first_ctor
- 8.14 C++ programs yield large `.exe' file
- 8.15 Why are DJGPP `.exe' files so large?
- 8.16 Linker complains about `djgpp.lnk'
- 8.17 Linker fails to produce the EXE program under Novell
- 8.18 Linker fails for large object files or large libraries
- 8.19 Building Allegro library fails
- 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 What GRX driver to use with your SVGA
- 10.2 Accessing the video memory
- 10.3 Graphics screen restoring under Windows
- 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
- 11.7 Floating point exception in Objective-C programs
- 11.8 Floating point exception in libm functions
- 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 Can GDB print class members?
- 12.8 GDB cannot list source that was #include'd
- 12.9 Debuggers choke on some programs ...
- 13. Profiling DJGPP Programs
- 13.1 How to profile a DJGPP program
- 13.2 Programs compiled with -pg crash when run
- 13.3 Gprof won't work unless it can find COFF executable
- 13.4 Where is Gprof docs?
- 13.5 Why is `__dpmi_int' so heavily used?
- 13.6 `gprof' doesn't produce output
- 14. Run-time Performance of DJGPP Programs
- 14.1 How efficient is DJGPP-generated code?
- 14.2 Comparing v2 with DJGPP v1.x
- 14.3 DJGPP programs on a Pentium
- 14.4 My program's I/O is so slow!
- 14.5 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 before all memory is used
- 15.5 Memory allocation fails under Windows
- 15.6 Memory allocation peculiarities under Windows 9x
- 15.7 Memory allocation fails under EMM386 or HIMEM
- 15.8 How much memory do parent DJGPP programs leave for their child?
- 15.9 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!!
- 17.7 What should I do with those ``near'' and ``far'' declarations?
- 17.8 How to convert _AX pseudo-registers?
- 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 Should I use _go32_XXX or __dpmi_YYY functions?
- 18.11 Hardware interrupt hooking has its subtleties ...
- 18.12 How to read and write ports
- 18.13 Inline Assembly code with GCC
- 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 News groups
- 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 news group!
- 21. Version 2 vs v1.x
- 21.1 New features in DJGPP v2
- 21.2 DJGPP environment in v2.x
- 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?
- 22.10 C++ doesn't pack structs!
- 22.11 How to avoid ``Abort, Retry, Fail'' messages
- 22.12 What is that `go32-v2.exe' program?
- 22.13 What is DXE?
- 22.14 Long Filenames Don't Work!
- 22.15 Make says ``missing separator''
- 22.16 What is in that `zoneinfo' directory?
- 22.17 Generating the FAQ in your favorite format
- 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 document
- 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 News group 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.12.
-
- * What is the best configuration of my system for DJGPP?
-
- This depends on your hardware and software. See system configuration
- guidelines in Section 3.9.
-
- * 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.5.
-
- * How do I subscribe to or unsubscribe from the DJGPP mailing list?
-
- See subscription instructions in Section 20.3.
-
- * How can I search News group/mailing list traffic for some info?
-
- This FAQ includes the description of DJGPP archive search server in
- Section 6.11, set up by DJ Delorie <dj@delorie.com>, which you should
- use whenever you have any questions or look for an information on a
- DJGPP-related subject.
-
- 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
- server 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 is also
- suitable for writing new code (for example, the DOS version of the well-known
- game `Quake' by id Software was compiled with DJGPP). With a few exceptions
- (notably, some of the C++ class libraries), DJGPP is *free* which makes it
- deal 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.6), 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,
- Windows NT (on Intel CPUs), Novell NWDOS 7 and Caldera's OpenDOS (but several
- people have found the DPMI services of NWDOS and OpendDOS incompatible with
- DJGPP, 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 ...*
-
- **Q*: DJGPP Make crashes when I run it on OS/2!*
-
- *A* : There was a bug in the DPMI server of the old OS/2 versions, which was
- triggered by spawning child processes (like GCC does when it invokes the
- various compiler passes). Current versions of OS/2 don't have that bug, so
- DJGPP programs should run fine under OS/2. If you can't make this happen,
- chances are that your setup is incorrect. One system parameter that can
- cause problems with DJGPP (reportedly, Make crashes if it isn't set
- correctly) is `DPMI_DOS_API.' Setting it to `ENABLED' instead of the default
- `AUTO' should solve the problem. I'm also told that experimenting with the
- value of `DPMI_MEMORY_LIMIT' sometimes solves problems on OS/2.
-
- If the above doesn't help, please post the details of the crashes you see to
- the DJGPP News group (see description of the DJGPP news group in Section
- 20.7) or mailing list (see how to post to the mailing list in Section 20.2),
- and somebody will help you.
-
- 3.3 Will it work under Windows/NT?
- ==================================
-
- **Q*: What about Windows NT?*
-
- *A* : Current Windows NT versions support DPMI programs in the DOS box, so
- DJGPP programs should in general run fine under NT (but see the list of
- possible problems below). Therefore, beginning with DJGPP v2.0, the
- distribution doesn't include real-mode `gcc.exe' anymore, as it is not needed.
-
- The DPMI server built into NT (and Windows 95) loses selectors with each
- child program that is invoked by a DJGPP program, so after about two thousand
- calls to functions from the `spawnXX' family you can see an error message
- like this:
-
- Load error: no DPMI selectors
-
- This problem is likely to afflict only DJGPP ports of Unix shells (such as
- `bash'), since no other DJGPP program, not even `Make', is likely to call so
- many child programs before it exits. The only known work-around is to exit
- the shell every now and then, because when all the available selectors are
- exhausted, the DOS box will crash. I'm told that `Make' was seen crashing on
- long `Makefiles' on Windows 95, where the selectors are lost at even higher
- rate than on NT. If you ever run a very long `Makefile' and see `Make' crash,
- just run `Make' again, and it will pick up where the crashed session has left
- off.
-
- Note that the long filename API (the special LFN-aware functions of Int 21h)
- for DOS box is not supported by current versions of Win/NT, so you cannot
- have long filenames there from DJGPP programs.
-
- You might have problems with using the SVGA modes of your video card under
- Win/NT. That is because NT doesn't allow direct access to the SVGA
- registers, without which it is impossible to recognize the type of the SVGA
- and employ its capabilities. For example, a user reported that GRX functions
- and the `MODETEST.EXE' program thought that only a standard VGA was
- installed, whereas he had an S3 card. There is nothing you can do about this
- feature of Win/NT; that is the price you pay for the stability and protection
- you get under this OS (a runaway program that accesses hardware registers can
- wipe out your disk or wedge the entire system cold). However, I'm told that
- Win/NT 4.0 supports "DirectX" which is a method of accessing screen, audio
- and other peripherals directly, so it's possible to use full GRX graphics
- capabilities there.
-
- Programs that use the "nearptr" facility of DJGPP to access absolute memory
- addresses (e.g., for memory-mapped devices) won't work on NT, because its
- DPMI server silently ignores functions that set huge limits on selectors.
- Since the default algorithm which allocates memory from the DPMI server needs
- to set such huge limit in some rare cases, there's a small probability that a
- program will fail or crash even if it doesn't set selector limits in user
- code. It is best to use the Unix-style `sbrk' algorithm in programs that run
- on Windows/NT. See the library docs for `_crt0_startup_flags' where the
- `_CRT0_FLAG_UNIX_SBRK' bit is explained, for more info on this issue. If you
- cannot switch to the Unixy `sbrk' (e.g., if you don't have access to its
- source), I'm told that sometimes such problems can be worked around if you
- run DJGPP programs in a full-screen session; your mileage may vary.
-
- Some people report that NT servers cause much more problems than NT
- workstations of the same version and build. It seems that these problems
- usually mean that NT installation was done incorrectly (maybe it is much
- harder to get it right with a server than with a workstation?). If you have
- such problems, try to install a workstation, or re-install the server, and
- see if that helps. And if you gain some insight as to why servers like DJGPP
- less than workstations, please tell what you've learned.
-
- The Cygnus Win32 project is another (unrelated to DJGPP) port of GCC and
- development tools to WinNT and Win95 platforms, which specifically targets
- development of Windows programs. It is available from the Cygnus archives,
- e.g. ftp://ftp.cygnus.com/pub/sac/win32/ or through the Web, at this URL:
-
- http://www.cygnus.com/misc/gnu-win32/
-
- 3.4 Can it run under Linux?
- ===========================
-
- **Q*: You say it works on Linux, but I seem to be unable to run the compiler
- from within Make...*
-
- **Q*: I can run DJGPP on Linux, but Make crashes with SIGFPE on even the
- simplest Makefiles!*
-
- *A* : Versions of Linux which were released before 13 March 1996 need a
- patch to be able to reliably run nested DJGPP programs. That patch was
- posted to the DJGPP mailing list and is available from the DJGPP mail
- archives, at this URL:
-
- http://www.delorie.com/djgpp/mail-archives/djgpp/1996/02/26/13:28:52
-
- If you prefer to download that patch via ftp, you can find it on the DJGPP
- ftp server, e.g.
- ftp://ftp.delorie.com/pub/djgpp/contrib/dpmi-dosemu-djgpp.mail.
-
- You might also need to edit the RAM section of the `dosemu.conf' file to make
- it comfortable for DJGPP. I suggest setting `dpmi' and `xms' to 16MB and
- `ems' to 4MB.
-
- Some users reported that `Make', and possibly other programs which use
- floating point computations, crash in DOSEmu environment on systems without
- an FPU, even if you set the 387 and EMU387 environment variables correctly
- (as explained in Setting up the FP emulator in Section 11.1, below). The
- only known work-around is to not use floating point or to upgrade your
- machine hardware. It is possible that newer versions of Linux might solve
- this problem too, so try upgrading your Linux software.
-
- If your only problem is to run GNU Make, get the latest DJGPP port of Make,
- since ports of Make 3.75 or later can be configured to not issue FP
- instructions at all.
-
- 3.5 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 the 286 isn't. A 386 or better CPU really *is* required.
-
- 3.6 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, you will have
- to use auxiliary tools. One possibility is to use 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
- using this package with DJGPP 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 on an alternative site, e.g.
- ftp://hermes.hrz.uni-bielefeld.de/pub/systems/msdos/misc/. Other locations
- to look are RSXWDK on Cica mirrors, e.g.
- ftp://ftp.winsite.com/pub/pc/win3/programr/rsxwdk2s.zip, or RSXWDK on any of
- the TeX Archive Network sites, e.g.
- ftp://ftp.shsu.edu/tex-archive/systems/msdos/dpmigcc/.
-
- Another problem with RSXWDK is that the Makefiles there are written for
- `ndmake', so they should be rewritten for GNU Make to work. Some more
- hacking of Makefiles might be required due to the fact that they are set to
- work with EMX, and assume you unpacked everything into `/rsxwdk.' You will
- also have to recompile the libraries as they were compiled with DJGPP v1.x,
- and hack the v2 startup file `crt0.s' along the same lines as the v1 version
- which comes with RSXWDK. (`crt0.s' comes with the DJGPP source distribution,
- `djlsr201.zip'.)
-
- Apart from RSXWDK, you will need a `windows.h' header file. One place to
- find it is with the WINE distribution, e.g.
- ftp://ftp.cdrom.com/pub/FreeBSD/distfiles/ (you'll have to add -DWINELIB to
- CFLAGS when compiling). However, be warned that this is a complete rewrite
- of the original, and might produce error messages when used to compile
- Windows apps. I don't know about a better solution except using `windows.h'
- from a commercial compiler, which might get you into legal trouble.
-
- You will also need a help compiler, e.g.
- ftp://ftp.aiai.ed.ac.uk/pub/packages/tex2rtf/rtfutils/hcp505.zip, or try at
- the Microsoft ftp site, e.g.
- ftp://ftp.microsoft.com/Softlib/MSFILES/HC305.EXE. I'm told that, legally,
- you must already have purchased a help compiler from Microsoft to use either
- one of these.
-
- A resource compiler is also required. RSXNT (below) includes one such, but I
- didn't yet hear any success stories using it. Anybody?
-
- Note that, according RSXWDK's author, that package is meant for those who
- already have working debugged Windows applications and are simply looking to
- port them to 32-bit code. Therefore, some crucial parts of a development
- environment (like a debugger) are missing there. The author of RSX has
- recently discontinued his support of the package and switched to RSXNT
- project that targets Win32 (Win9x and WinNT) platforms (below).
-
- As of this writing, nobody has reported any first-hand experience of using
- RSXWDK with DJGPP v2; the above is based on user reports under v1.x. If you
- try RSXWDK with v2.x, please post a summary of your experience.
-
- There is also a newer Windows development tool-chain by the author of RSXWDK
- called RSXNT. This is targeted for Win32 platforms (Win95 and WinNT); it
- does have debugging tools included and has better support for DJGPP v2.x, but
- it needs to be registered (for a fee) if you want to develop commercial or
- shareware applications with it. It can be found on the same sites as RSXWDK
- and comes with header files from Cygnus. You can find the DJGPP-specific
- version of RSXNT on SimTel mirrors, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/rsxntdj1.zip. The sources
- of all the RSXNT utilities can be found in `rsxnt1.zip' archive on Cica
- mirrors, in the `win95/programr/' directory. Note that currently, due to
- limitations of DJGPP, you cannot produce DLLs or programs that will run on
- Win32s platforms with RSXNT.
-
- Another way to develop Windows applications is to use the Cygnus GCC/GPP
- port, at this URL:
-
- http://www.cygnus.com/gnu-win32/
-
- You can also download it via anonymous ftp, e.g.
- ftp://ftp.cygnus.com/pub/sac/win32/. This one's compatible with Win32 (Win95
- or WinNT, not Win32s), but requires you to comply with the GNU Copyleft
- system. The Cygnus distribution includes development environments which run
- on WinNT and Linux, targeting WinNT and Win95 platforms. Note that, as of
- this writing, the Cygnus port is still in early beta phase, and some nasty
- bugs are bound to be there. Contact Steve Chamberlain <sac@rtl.cygnus.com>,
- for more details.
-
- A better (but harder) way would be to volunteer to add Windows support to
- DJGPP.
-
- 3.7 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 512KB 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.8 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.9 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 `csdpmi3b.zip' archive) and set the "Minimum application
- memory desired before 640K paging" parameter to 512K or larger.
- Depending on how much memory you actually have, you might need to
- further fine-tune this parameter. This parameter defines the
- lowest amount of extended memory CWSDPMI will use; if your system
- doesn't have that much free extended RAM, CWSDPMI will use
- conventional memory instead, where usually there should be around
- 600K of free RAM.
-
- * 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 start
- paging 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 a 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
- start paging 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 a 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 a RAM disk; point your `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 a memory manager to load DOS, TSRs and device drivers *HIGH*.
-
- * Install at least a 2-MByte-large disk cache, configured to use the
- 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 a RAM disk with a 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.
-
- Some people disable the delayed-write feature for safety reasons, to avoid
- losing files due to system crashes. If you are worried about this, you can
- usually gain performance without sacrificing safety by enabling delayed-write
- together with an option that causes the cache to flush the write-behind data
- before the system returns to the DOS prompt. For a `SmartDrv' disk cache,
- this is achieved by specifying `/N/F' switches instead of `/X'.
-
- A tutorial is available on how to set up and get started with DJGPP, at this
- URL:
-
- http://remus.rutgers.edu/~avly/djgpp.html
-
- 4. Where and What to Download?
- ******************************
-
- This chapter explains where and how can you get DJGPP, and recommends which
- parts of the archive you should download.
-
- 4.1 Where can I get DJGPP?
- ==========================
-
- **Q*: Where can I get DJGPP?*
-
- *A* : Look on any SimTel.NET mirror in the pub/simtelnet/gnu/djgpp/
- subdirectory.
-
- Lately, there has been considerable confusion caused by the fact that the
- repository which was long known by the name "SimTel" is no longer called
- that; its new name is "CCT". The name SimTel has moved (along with its
- originator and long-time manager, Keith Petersen <w8sdz@Simtel.Net>) to
- another distribution network which uses almost the same ftp sites, but in
- different subdirectories. The name SimTel is copyrighted by this new
- distribution network, and so CCT will have to discontinue its use of that
- name. Experience shows that SimTel.NET (not CCT) is better managed and
- updates propagate there much faster, so I advise you to try using SimTel
- mirrors first, and fall back to CCT only if a SimTel site is unavailable to
- you. In particular, DJGPP version 2.01 and later wasn't even uploaded to CCT
- sites.
-
- This section lists the SimTel.NET mirrors; see below in Section 4.2, for the
- list of CCT sites.
-
- The primary SimTel.NET site is:
- ftp.simtel.net, directory /pub/simtelnet/gnu/djgpp
-
- (ftp.simtel.net is actually several ftp sites arranged in a rotating
- pattern of IP addresses to help balance the load and to avoid access
- problems due to network outages and simultaneous user limits.)
-
- Here is a list of hosts by countries that offer mirror sites:
- Argentina
- ftp.satlink.com, directory /pub/mirrors/simtelnet/gnu/djgpp
-
- Newcastle, Australia:
- ftp.iniaccess.net.au, directory /pub/simtelnet/gnu/djgpp
-
- Australia:
- ftp.tas.gov.au, directory /pub/simtelnet/gnu/djgpp
-
- Australia:
- sunsite.anu.edu.au, directory /pub/simtelnet/gnu/djgpp
-
- Vienna, Austria:
- ftp.univie.ac.at, directory /mirror/simtelnet/gnu/djgpp
-
- Brussels, Belgium:
- ftp.linkline.be, directory /mirror/simtelnet/gnu/djgpp
-
- Aarshot, Belgium:
- ftp.tornado.be, directory /pub/simtelnet/gnu/djgpp
-
- Sao Paulo, Brazil:
- ftp.unicamp.br, directory /pub/simtelnet/gnu/djgpp
-
- Brazil:
- ftp.iis.com.br, directory /pub/simtelnet/gnu/djgpp
-
- Bulgaria:
- ftp.eunet.bg, directory /pub/simtelnet/gnu/djgpp
-
- Ottawa, Canada:
- ftp.crc.doc.ca, directory /systems/ibmpc/simtelnet/gnu/djgpp
-
- Vancouver, Canada:
- ftp.direct.ca, directory /pub/simtelnet/gnu/djgpp
-
- Chile:
- sunsite.dcc.uchile.cl, directory /pub/Mirror/simtelnet/gnu/djgpp
-
- Beijing, China:
- ftp.pku.edu.cn, directory /pub/simtelnet/gnu/djgpp
-
- Czech Republic:
- ftp.eunet.cz, directory /pub/simtelnet/gnu/djgpp
-
- Prague, Czech Republic:
- pub.vse.cz, directory /pub/simtelnet/gnu/djgpp
-
- Czech Republic:
- ftp.zcu.cz, directory /pub/simtelnet/gnu/djgpp
-
- Espoo, Finland:
- ftp.funet.fi, directory /mirrors/ftp.simtel.net/pub/simtelnet/gnu/djgpp
-
- Neuilly, France:
- ftp.grolier.fr, directory /pub/simtelnet/gnu/djgpp
-
- Paris, France:
- ftp.ibp.fr, directory /pub/simtelnet/gnu/djgpp
-
- Germany:
- ftp.mpi-sb.mpg.de, directory /pub/simtelnet/gnu/djgpp
-
- Bochum, Germany:
- ftp.rz.ruhr-uni-bochum.de, directory /pub/simtelnet/gnu/djgpp
-
- Chemnitz, Germany:
- ftp.tu-chemnitz.de, directory /pub/simtelnet/gnu/djgpp
-
- Heidelberg, Germany:
- ftp.uni-heidelberg.de, directory /pub/simtelnet/gnu/djgpp
-
- Magdeburg, Germany:
- ftp.uni-magdeburg.de, directory /pub/simtelnet/gnu/djgpp
-
- Paderborn, Germany:
- ftp.uni-paderborn.de, directory /pub/simtelnet/gnu/djgpp
-
- Trier, Germany:
- ftp.uni-trier.de, directory /pub/pc/mirrors/simtelnet/gnu/djgpp
-
- Wuerzburg, Germany:
- ftp.rz.uni-wuerzburg.de, directory /pub/pc/simtelnet/gnu/djgpp
-
- Athens, Greece:
- ftp.ntua.gr, directory /pub/pc/simtelnet/gnu/djgpp
-
- Hong Kong:
- sunsite.ust.hk, directory /pub/simtelnet/gnu/djgpp
-
- Hong Kong:
- ftp.hkstar.com, directory /pub/simtelnet/gnu/djgpp
-
- Hong Kong:
- ftp.cs.cuhk.hk, directory /pub/simtelnet/gnu/djgpp
-
- Ireland:
- ftp.iol.ie, directory /pub/simtelnet/gnu/djgpp
-
- Jerusalem, Israel:
- ftp.huji.ac.il, directory /pub/simtelnet/gnu/djgpp
-
- Naples, Italy:
- ftp.unina.it, directory /pub/simtelnet/gnu/djgpp
-
- Italy:
- cis.utovrm.it, directory /simtelnet/gnu/djgpp
-
- Italy:
- ftp.flashnet.it, directory /pub/simtelnet/gnu/djgpp
-
- Italy:
- mcftp.mclink.it, directory /pub/simtelnet/gnu/djgpp
-
- Saitama, Japan:
- ftp.saitama-u.ac.jp, directory /pub/simtelnet/gnu/djgpp
-
- Saitama, Japan:
- ftp.riken.go.jp, directory /pub/simtelnet/gnu/djgpp
-
- Japan:
- ftp.iij.ad.jp, directory /pub/simtelnet/gnu/djgpp
-
- Japan:
- ftp.u-aizu.ac.jp, directory /pub/PC/simtelnet/gnu/djgpp
-
- Japan:
- ring.aist.go.jp, directory /pub/simtelnet/gnu/djgpp
-
- Japan:
- ring.asahi-net.or.jp, directory /pub/simtelnet/gnu/djgpp
-
- Japan:
- ftp.web.ad.jp, directory /pub/simtelnet/gnu/djgpp
-
- Latvia:
- ftp.lanet.lv, directory /pub/mirror/simtelnet/gnu/djgpp
-
- Malaysia:
- ftp.jaring.my, directory /pub/simtelnet/gnu/djgpp
-
- Malaysia:
- ftp.mimos.my, directory /pub/simtelnet/gnu/djgpp
-
- Mexico:
- ftp.gdl.iteso.mx, directory /pub/simtelnet/gnu/djgpp
-
- Netherlands:
- ftp.euro.net, directory /d5/simtelnet/gnu/djgpp/
-
- Utrecht, Netherlands:
- ftp.nic.surfnet.nl, directory
- /mirror-archive/software/simtelnet/gnu/djgpp
-
- Wellington, New Zealand:
- ftp.vuw.ac.nz, directory /pub/simtelnet/gnu/djgpp
-
- Bergen, Norway:
- ftp.bitcon.no, directory /pub/simtelnet/gnu/djgpp
-
- Krakow, Poland:
- ftp.cyf-kr.edu.pl, directory /pub/mirror/Simtel.Net/gnu/djgpp
-
- Poznan, Poland:
- ftp.man.poznan.pl, directory /pub/simtelnet/gnu/djgpp
-
- Warsaw, Poland:
- ftp.icm.edu.pl, directory /pub/simtelnet/gnu/djgpp
-
- Aveiro, Portugal:
- ftp.ua.pt, directory /pub/simtelnet/gnu/djgpp
-
- Portugal:
- ftp.ip.pt, directory /pub/simtelnet/gnu/djgpp
-
- Romania:
- ftp.sorostm.ro, directory /pub/simtelnet/gnu/djgpp
-
- Singapore:
- ftp.nus.sg, directory /pub/simtelnet/gnu/djgpp
-
- Slovakia:
- ftp.uakom.sk, directory /pub/simtelnet/gnu/djgpp
-
- Slovenia:
- ftp.arnes.si, directory /software/simtelnet/gnu/djgpp
-
- Johannesburg, South Africa:
- ftp.is.co.za, directory /pub/simtelnet/gnu/djgpp
-
- Stellenbosch, South Africa:
- ftp.sun.ac.za, directory /pub/simtelnet/gnu/djgpp
-
- Seoul, South Korea:
- ftp.nuri.net, directory /pub/simtelnet/gnu/djgpp
-
- South Korea:
- ftp.sogang.ac.kr, directory /pub/simtelnet/gnu/djgpp
-
- South Korea:
- sunsite.snu.ac.kr, directory /pub/simtelnet/gnu/djgpp
-
- Spain:
- ftp.rediris.es, directory /mirror/simtelnet/gnu/djgpp
-
- Stockholm, Sweden:
- ftp.sunet.se, directory /pub/simtelnet/gnu/djgpp
-
- Zurich, Switzerland:
- sunsite.cnlab-switch.ch, directory /mirror/simtelnet/gnu/djgpp
-
- Chung-Li, Taiwan:
- ftp.ncu.edu.tw, directory /Packages/simtelnet/gnu/djgpp
-
- Taipei, Taiwan:
- nctuccca.edu.tw, directory /PC/simtelnet/gnu/djgpp
-
- Nonthaburi, Thailand:
- ftp.nectec.or.th, directory /pub/mirrors/simtelnet/gnu/djgpp
-
- Edinburgh, UK:
- emwac.ed.ac.uk, directory /mirror/simtelnet/gnu/djgpp
-
- Lancaster, UK:
- micros.hensa.ac.uk, directory /pub/simtelnet/gnu/djgpp
-
- London, UK:
- sunsite.doc.ic.ac.uk, directory /packages/simtelnet/gnu/djgpp
-
- London, UK:
- ftp.demon.co.uk, directory /pub/simtelnet/gnu/djgpp
-
- Suffolk, UK:
- ftp.flexnet.net, directory /pub/simtelnet/gnu/djgpp
-
- Concord, California, USA:
- ftp.cdrom.com, directory /pub/simtelnet/gnu/djgpp
-
- California, USA:
- ftp.digital.com, directory /pub/simtelnet/gnu/djgpp/
-
- California, USA:
- ftp.lib.sonoma.edu, directory /pub/simtelnet/gnu/djgpp/
-
- Urbana, Illinois, USA:
- uarchive.cso.uiuc.edu, directory /pub/systems/pc/simtelnet/gnu/djgpp
-
- Massachusets, USA
- ftp.bu.edu, directory /pub/mirrors/simtelnet/gnu/djgpp/
-
- Rochester, Michigan, USA:
- OAK.Oakland.Edu, directory /pub/simtelnet/gnu/djgpp
-
- New York, NY, USA:
- ftp.rge.com, directory /pub/systems/simtelnet/gnu/djgpp/
-
- Oklahoma, USA:
- ftp.ou.edu, directory /pub/simtelnet/gnu/djgpp/
-
- Corvallis, Oregon, USA:
- ftp.orst.edu, directory /pub/simtelnet/gnu/djgpp
-
- Pennsylvania, USA:
- ftp.epix.net, directory /pub/simtelnet/gnu/djgpp
-
- Utah, USA:
- ftp.cyber-naut.com, directory /pub/simtelnet/gnu/djgpp
-
- Virginia, USA:
- mirrors.aol.com, directory /pub/simtelnet/gnu/djgpp/
-
- 4.2 CCT sites
- =============
-
- **Q*: Where can I find the nearest CCT site?*
-
- *A* : Look up the site nearest to you in the list below:
-
- Note that the copyright to the name "SimTel" is owned by Walnut Creek which
- sponsors the SimTel.NET repository, so the CCT mirrors are in the process of
- renaming their directories to `Coast'. Therefore, if you don't find the
- directories listed below, replace "SimTel" by "Coast" and try again.
-
- The primary CCT site is in Detroit, Michigan, USA:
- ftp.coast.net, directory /Coast/vendors/djgpp/.
-
- Here is a list of hosts by countries that offer mirror sites:
- Canberra, Australia:
- archie.au, directory /micros/pc/SimTel/vendors/djgpp
-
- Edmonton, AB, Canada:
- ftp.agt.net, directory /pub/SimTel/vendors/djgpp
-
- Prague, Czech Republic:
- pub.vse.cz, directory /pub/simtel/vendors/djgpp
-
- London, England:
- src.doc.ic.ac.uk, directory /pub/packages/simtel/vendors/djgpp
-
- Liverpool, England:
- ftp.mersinet.co.uk, directory /pub/ibmpc/coast/vendors/djgpp
-
- London, England:
- ftp.demon.co.uk, directory /pub/mirrors/simtel/vendors/djgpp
-
- Chemnitz, Germany:
- ftp.tu-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
-
- Hong Kong:
- ftp.cs.cuhk.hk, directory /pub/simtel/vendors/djgpp
-
- Hong Kong:
- sunsite.ust.hk, directory /pub/simtel/vendors/djgpp
-
- Dublin, Ireland:
- ftp.hea.ie, directory /pub/simtel/vendors/djgpp
-
- Haifa, Israel:
- ftp.technion.ac.il, directory /pub/unsupported/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
-
- Rome, Italy:
- cis.utovrm.it, directory /SimTel/vendors/djgpp
-
- Tokyo, Japan:
- ftp.crl.go.jp, directory /pub/pc/archives/simtel/vendors/djgpp
-
- Tokyo, Japan:
- ftp.web.ad.jp, directory /pub/mirrors/Coast/vendors/djgpp
-
- Tokyo, Japan:
- ring.aist.go.jp, directory /pub/coast/vendors/djgpp
-
- Tokyo, Japan:
- ring.asahi-net.or.jp, directory /pub/coast/vendors/djgpp
-
- Seoul, Korea:
- ftp.kornet.nm.kr, directory /pub/SimTel/vendors/djgpp
-
- Seoul, Korea:
- ftp.nowcom.co.kr, directory /pub/SimTel/vendors/djgpp
-
- Utrecht, Netherlands:
- ftp.nic.surfnet.nl, directory
- /mirror-archive/software/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
-
- Moscow, Russia:
- ftp.radio-msu.net, directory /mirror/Coast/vendors/djgpp
-
- Singapore:
- ftp.singnet.com.sg, directory /pub/mirrors/SimTel/vendors/djgpp
-
- Slovak Republic:
- ftp.uakom.sk, directory /pub/SimTel/vendors/djgpp
-
- Taipei, Taiwan:
- nctuccca.edu.tw, directory /PC/simtel/vendors/djgpp
-
- Bangkok, Thailand:
- ftp.bu.ac.th, directory /pub/SimTel/vendors/djgpp
-
- Sunnyvale, CA, USA:
- ftp.drcdrom.com, directory /Coast/vendors/djgpp
-
- Note that DJGPP was moved to the `SimTel/vendors/' directory on most CCT
- mirrors about a year ago. This is because CCT claims a compilation copyright
- on its collection, to prevent people from copying the CD-ROMs which are
- distributed by CCT. 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.3 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, check out the DJGPP archive path
- in Section 4.1, for your nearest mirror.). Then issue the `binary' command
- and download files you need (see the list of required files in Section 4.5)
- with the `get' or `mget' commands.
-
- 4.4 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.NET site, at this URL:
-
- http://www.simtel.net/simtel.net/gnu/djgpp/
-
- - The main CCT site, at this URL:
-
- http://www.coast.net/Coast/vendors/djgpp/
-
- - The CCT mirror in Rochester, MI, at this URL:
-
- http://www.acs.oakland.edu/oak/SimTel/vendors/djgpp/
-
- - The CCT 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.NET 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 CCT
- FTP site, e.g. ftp://ftp.coast.net/Coast/vendors/djgpp/.
-
- Gopher users can access CCT files through a Gopher client,
- gopher://gopher.oakland.edu.
-
- For those of you who only have an e-mail connection to the Internet, CCT
- 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 CCT list
- server <listserv@Coast.NET> with this command in the message body:
-
- get simtel-mailserver.info
-
- 4.5 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:
- (The version numbers of the packages below might not be up to date. For
- the latest versions, check out the DJGPP Mini-FAQ posted weekly to the
- comp.os.msdos.djgpp news group.)
-
- `v2/readme.1st'
- This explains how to install DJGPP and get started with using it.
-
- `v2/faq210b.zip'
- The latest edition of this FAQ list. Use it whenever you have
- problems installing and using DJGPP.
-
- `v2misc/csdpmi3b.zip'
- CWSDPMI, the DJGPP free DPMI server. (If you can get DPMI services
- in your environment, like if you run under Windows, QDPMI, or OS/2,
- you don't need CWSDPMI, but I recommend downloading it nonetheless
- so you can try it in case you have trouble with other DPMI servers.)
-
- `v2misc/pmode11b.zip'
- This is an alternative DPMI server, PMODE/DJ. Its memory footprint
- is smaller than CWSDPMI and it can be bundled with DJGPP programs
- to make a stand-alone executable that doesn't require a DPMI server
- to run. PMODE/DJ doesn't support virtual memory and its
- implementation of the DPMI spec is a bit more restricted than that
- of CWSDPMI.
-
- * For developing C programs (no C++), you MUST download all of the above,
- plus the following:
-
- `v2gnu/bnu27b.zip'
- The GNU Binutils, including `as', the GNU assembler; `ld', the GNU
- linker; and their docs.
-
- `v2/djdev201.zip'
- C header files and libraries, library reference, minimal development
- environment, DJGPP-specific utilities and their documentation.
-
- `v2gnu/gcc2721b.zip'
- The GNU C Compiler binaries and docs (including the docs for the C++
- compiler).
-
- `v2gnu/txi390b.zip'
- Info, a stand-alone program to read GNU hypertext documentation
- files, and an environment to produce such files. Without `info',
- you cannot read the C library reference and the docs included with
- the ported GNU software packages.
-
- * For developing C++ programs, you will need all of the above, plus the
- following:
-
- `v2gnu/gpp2721b.zip'
- The GNU C++ compiler binary (the docs are part of the gccNNNb.zip
- package, see above).
-
- `v2gnu/lgp271b.zip'
- The C++ header files, the GNU C++ class libraries, and their docs.
-
- `v2gnu/obc2721b.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/gdb416b.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):
-
- `v2gnu/mak375b.zip'
- GNU Make program with its docs. You should install Make 3.75
- if you use DJGPP v2.01 (previous ports of Make have subtle
- incompatibilities with v2.01 tools). The port of Make 3.75
- supports Unix-style shells (as well as DOS `COMMAND.COM' and
- its `4DOS/NDOS' replacements) and can be used to run Unix
- Makefiles if you install a Unix-style shell (e.g., `bash') and
- auxiliary utilities. It also supports long filenames on
- Windows 9x and MSDOS pathnames with drive letters.
-
- `v2apps/rhide10b.zip'
- The RHIDE integrated development environment for DJGPP
- (similar to Borland's IDE), written by Robert Hoehne
- <Robert.Hoehne@Mathematik.TU-Chemnitz.DE>. The latest version
- features an integrated debugger, based on GDB code; a
- stand-alone version of GDB with a Turbo Vision interface (but
- not all GDB features can be used); and support for user
- interface in languages other than English (using a port of GNU
- `Gettext' library).
-
- `v2/djlsr201.zip'
- The sources of the DJGPP C library and utilities written
- specifically for DJGPP. If you can afford the disk space (it
- requires about 10MB), I recommend installing or at least
- downloading it, so you can easily fix possible library bugs.
-
- `v2gnu/bsh1147b.zip'
- Bash (`Borne-Again SHell'), the GNU shell, and its docs. If
- you mostly work in Unix environment, you will feel right at
- home using `bash' as your interactive shell. It is also great
- as a batch shell for running Unix-born shell scripts and
- Makefiles when these are too complex to convert them to MSDOS.
- If you install `bash', you should also install auxiliary
- utilities (Fileutils, Textutils, Sh-utils, Grep, Diffutils,
- Findutils, Sed and Gawk) as these are usually invoked from
- many shell scripts and Makefiles.
-
- `v2gnu/bsn124b.zip'
- Bison, a Yacc-like parser generator, and its docs.
-
- `v2gnu/dif271b.zip'
- GNU Diffutils (diff, cmp, diff3, sdiff), and their docs. If
- you need to submit patches or changes to DJGPP or GNU sources,
- you will need the GNU `diff' program from this package.
-
- `v2gnu/emacs.README'
- `v2gnu/em1934*.zip'
- GNU Emacs, the most powerful, customizable, extensible
- programmer's editor known today. The DJGPP port supports
- mouse, menu bar, pop-up menus, color syntax highlighting,
- reading Info documentation and compilation from within the
- editor, long filenames on Windows 9x, and much more. Emacs
- can and should be used as an integrated development
- environment (another alternative is `RHIDE', see above).
- Please read the file `emacs.README' before you begin
- downloading the rest.
-
- `v2gnu/fil313b.zip'
- GNU Fileutils, including `ls', `rm', `cp', `mv', and others.
- Highlights of the latest port: `ls' supports colorization of
- files (like on Linux), `ln -s' knows about DJGPP-style
- "symlinks" (see symlink feature of DJGPP in Section 22.3,
- elsewhere in this document), `install -s' will strip
- executables on the fly, and all the utilities support long
- filenames on Windows 9x and numbered backups (even on plain
- DOS). This package is a must if you want to run Unix shell
- scripts, as they use some of these utilities *a lot*.
-
- `v2gnu/flx252b.zip'
- Flex, a Lex-like lexical analyzer generator, and its docs.
-
- `v2gnu/grep20b.zip'
- GNU Grep package and its docs. You need this if you use Emacs
- (which has commands that invoke Grep) or if you want to run
- Unix shells and Makefiles.
-
- `v2gnu/pat21b.zip'
- GNU Patch program and docs. Required to apply patches to
- DJGPP sources.
-
- `v2gnu/sed118b.zip'
- GNU Sed (a batch editor) program and its docs. Many ported
- packages require it during the build process on MSDOS.
-
- `v2gnu/shl112b.zip'
- GNU Sh-utils. A must if you use the port of `bash' or want to
- run Unix Makefiles, but some utilities (such as `env' or
- `test') can also be very useful on their own right.
-
- `v2gnu/txt119b.zip'
- GNU Textutils. Includes many useful programs, such as `sort',
- `wc', `cat', `join', `paste', `od', and `uniq'. Unix shell
- scripts and Makefiles call some of these *a lot*, so you
- should install this package if you run them.
-
- - 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.6 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:
-
- Execution-only environment..................300 KBytes
- Developing C programs.......................13 MBytes
- Developing C++ programs.....................17 MBytes
- Developing Objective-C programs.............15 MBytes
- Additional storage for RHIDE................2.5 MBytes
- Additional storage for DJGPP sources........10 MBytes
- Additional storage for GDB..................1.1 MBytes
- Additional storage for Emacs................30 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...4 MBytes
-
- Note that the above lists only approximate numbers. In particular, the disk
- cluster size can significantly change the actual disk space required by some
- of the distributions (those with a large number of files). The numbers above
- are for disks up to 512MB which have 8KB-long clusters.
-
- 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 much DPMI memory and swap space DJGPP applications can use. Depending on
- your DPMI host, you might need to review its virtual memory settings in
- addition to leaving free disk space; `CWSDPMI' requires only that enough free
- disk space be available, but other DPMI hosts have special settings to
- specify how much virtual memory they let their clients use, as explained
- below in Section 15.1.
-
- 4.7 Can I get away with less megabytes?
- =======================================
-
- **Q*: The above table means that I need more than 17 MBytes for C/C++
- development environment; that's about 7 1.44MB diskettes to hold even the
- compressed archive!! Seems to me DJGPP is afflicted by the *fatware*
- disease...*
-
- **Q*: Pulling that many megabytes through the net from my overloaded
- SimTel.NET mirror is almost impossible. Can't you prepare a ZIP archive
- which only includes stuff I can't do without?*
-
- *A* : There are a number of shareware/freeware programs floating around which
- allow formatting DOS diskettes to almost twice their usual capacity, so you
- can use less floppies. One such program is 2M, available from CCT mirrors as
- 2mNN.zip, e.g. ftp://ftp.coast.net/Coast/msdos/diskutil/2m30.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 with a shell account), can use a nice
- FTP-automating utility called `AutoWinNet' (get the file autownNN.zip from
- your nearest CCT mirror, e.g.
- ftp://ftp.coast.net/Coast/win3/winsock/autown19.zip).
-
- As for the minimal DJGPP installation, volunteers are welcome to prepare such
- an archive and make it publicly available, in the same spirit as `EZ-GCC' did
- for DJGPP v1.x.
-
- 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 txi390b.zip, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/txi390b.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 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.) RHIDE also has an integrated Info reader, which is the
- core of its help system.
-
-
- 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 view
- them with your favorite text file browser or editor. You will lose the
- hypertext structure and you might have a 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 txi390b.zip, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/txi390b.zip.
-
- If you prefer reading the docs through the Web, point your Web browser to the
- docs page of the DJGPP Web site, at this URL:
-
- http://www.delorie.com/gnu/docs/
-
- 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 the source distribution of every package you download. You will
- get a `.dvi' file which you can print; or you can run a DVI-to-PostScript
- converter such as `DVIPS' to produce a PostScript output. `DVIPS' is a free
- program; you can find it on SimTel.NET mirrors, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/msdos/postscrp/dvips558.zip.
-
- 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 latest GNU
- or DJGPP Texinfo distribution which includes that file.
-
- If you'd like to produce printed docs of the library reference, TeX might
- complain that it cannot find a file named `libc2.tex'. This file is
- generated from all the `*.txh' files in the DJGPP source distribution
- (`djlsr201.zip'). In order to build this file, you need to install
- `djlsr201.zip', then go to the `src/libc' directory and type this from the DOS
- command prompt:
-
- make -C ../mkdoc
- make doc
-
- If the above command fails due to unresolved externals, you will need to edit
- the file `makefile' in the `mkdoc' directory. It has a line which calls `ld'
- (the linker), where you should change `-lgcc -lc' into `-lgcc -lc -lgcc'.
- Save `makefile' and try the above commands again.
-
- Note that some documentation 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. A port of (an old version of) Groff to (an old version of)
- DJGPP can be downloaded from the DJGPP ftp server, e.g.
- ftp://ftp.delorie.com/pub/djgpp/contrib/groff.zip.
-
- * Get and install `CAWF', a DOS program which knows about most of the
- `troff' formatting commands. `CAWF' can be found on one of the CCT
- mirrors, e.g. ftp://ftp.coast.net/Coast/msdos/textutil/cawf404.zip.
-
- * Write or port a `man' clone. Source for one such clone was posted to
- the DJGPP news group, so you can get it there, at this URL:
-
- http://www.delorie.com/djgpp/mail-archives/djgpp/1995/06/19/12:57:43
-
- You can also download this port from the DJGPP ftp server, e.g.
- ftp://ftp.delorie.com/pub/djgpp/contrib/man-pc.zip.
-
- * Format the file on any Unix machine, and download the results to your PC.
- On 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 DJGPP port of GNU
- Less, e.g. ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/lss321b.zip,
- which uses colors to show bold and underlined letters. Alternatively, you
- can get the latest official GNU Less distribution, e.g.
- ftp://ftp.gnu.ai.mit.edu/pub/gnu/less-321.tar.gz which can be compiled out of
- the box with the Borland C compiler. (Future versions of `Less' will also
- compile with DJGPP.)
-
- Another possibility for reading formatted man pages would be with an Emacs
- editor, if you use one. Emacs has a special command to read man pages, but
- it requires a port or a clone of a Unix `man' command, described above.
-
- 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.djgpp' 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.simtel.net/pub/simtelnet/gnu/djgpp/txi390b.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 them, but I still can't figure out
- some details.*
-
- *A* : Some ported packages include DJGPP-specific or MSDOS-specific `README'
- files (named `README.dj', `README.dos' or some such), which explain
- DOS-specific issues; you should read them before any serious use of the
- package, or in case of any problems. If this doesn't help, download the
- sources and look there, or ask on the net--either the DJGPP News group or
- appropriate GNU News groups.
-
- 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 8 sections describe
- specific problems; if yours isn't solved with these techniques, read the
- description of the general debugging procedure in Section 6.9.
-
- 6.1 GCC says "No DPMI"
- ======================
-
- **Q*: I'm trying to run `gcc', but all I get is a message saying "Load error:
- no DPMI". What am I doing wrong?*
-
- *A* : You don't have a DPMI server installed, and DJGPP v2 requires it to
- run. You can either use one of the commercial DPMI servers (e.g., run `gcc'
- in a DOS box from Windows) or download and install CWSDPMI
- (`v2misc/csdpmi3b.zip' from SimTel.NET mirrors) which is a free DPMI server
- written for DJGPP.
-
- 6.2 Buggy DPMI host or junk in DJGPP.ENV can crash v2.x programs
- ================================================================
-
- **Q*: When I try to run Info, it crashes immediately...*
-
- **Q*: I cannot run v2 applications: they all hang or reboot my system, while
- v1.x apps run OK. Is this what v2 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 one which comes with Novell NWDOS (and
- also Caldera's OpenDOS, which is a derivative of NWDOS). Please see if v2.0
- programs run when you disable DPMI services of your usual configuration
- (DJGPP programs will then use the CWSDPMI host supplied with DJGPP). To turn
- off the DPMI host built into Novell NWDOS and Caldera's OpenDOS, either
- remove the `DPMI=TRUE' parameter from the EMM386 command line, or type `DPMI
- OFF' from the DOS command prompt.
-
- 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.
-
- Yet another cause of crashes in `Info' might be trailing whitespace in the
- `DJGPP.ENV' file. The telltale signs of this failure are a stack dump that
- is bogus or doesn't start with your `main' function, or a series of SIGSEGV
- that won't stop. Actually, this is a bug in the DJGPP v2.0 startup code, so
- any v2.0 program could crash in this way, but since the last section of stock
- `DJGPP.ENV' belongs to `Info', it is the one which suffers most from this
- bug. Make sure your `DJGPP.ENV' doesn't have a `^Z' character at the end
- (some DOS editors put it if you edit the file), and doesn't end with a blank
- line. Alternatively, upgrade to DJGPP v2.01 or later, where that bug is
- fixed.
-
- 6.3 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.*
-
- **Q*: The compiler prints "Virtual memory exhausted" and dies while compiling
- some long functions with some optimization options, such as -funroll-loops or
- -fforce-addr.*
-
- *A* : For some programs, this can be caused by an insufficient stack. Some
- source files make `cc1.exe' or `cc1plus.exe' need preposterously large
- amounts of stack space, but only when you turn on optimizations. (One user
- reported that an innocent-looking C source file required 700KB of stack
- before `cc1.exe' was able to compile it with optimizations!) Try stubediting
- the compiler to enlarge its stack, as described elsewhere in this FAQ, how to
- enlarge the stack in Section 6.4, before you try any other remedies in this
- section.
-
- GCC 2.6.0 was known to crash when optimizing, especially when compiling C++
- programs, but it can also happen for later versions, especially if your code
- has some syntactic or semantic bug. (This is usually a genuine GCC bug, not
- something special to DJGPP.) Upgrade to the latest version of GCC. If that
- doesn't help, 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.
-
- If GCC reports that it has exhausted virtual memory, you should first see if
- your swap space is large enough (run `go32-v2' with no arguments) and make
- more free space on your disk if so. Some users have reported that GCC seems
- to run out of virtual memory if TMPDIR environment variable points to a RAM
- disk which doesn't have enough free space. Changing TMPDIR to point to a
- hard disk would reportedly save the day in those cases.
-
- An undocumented GCC switch can sometimes help you zero in on the code
- fragment that causes GCC to crash. If you add `-Q' to the GCC command line,
- it will print the name of every function it compiles. The function that
- makes it crash is probably the one whose name is the last one printed, or the
- one after that.
-
- 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
- optimization which goes back as far as version 2.5.8 and is only corrected in
- GCC 2.7.2.1 or later; this bug raises its ugly head on rare occasions, but is
- notoriously hard to hunt down when it does. (The stock v2.0 distribution
- should by default disable this kind of optimizations on the `lib/specs' file,
- and v2.01 comes with GCC 2.7.2.1 where that bug is fixed.)
-
- As an extreme measure, don't optimize at all, if that's the only way to make
- your program compile.
-
- 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.
-
- Yet another cause for such crashes can be connected with excess memory usage
- that GCC needs when compiling certain programs, which makes some DPMI hosts
- fail. For details about this, see CWSDPMI allocation problems in Section
- 6.4, in the next section.
-
- 6.4 What does "Fatal signal X" mean?
- ====================================
-
- **Q*: I get "fatal signal 2" when I run GCC.*
-
- **Q*: When I try compiling a program, GCC aborts saying "Installation
- problem, cannot exec `as': No such file". What does that mean?*
-
- **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 one of the compiler passes. The "signal" number is the DOS
- error code, and 2 means "file not found" (dust off your DOS reference for
- other error codes). This (and the more explicit "cannot exec" message) 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.' A
- typical case is when people fail to install the Binutils package, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu27b.zip and GCC cannot
- find `as.exe' (the assembler) and `ld.exe' (the linker). You can use the
- `-v' switch to GCC to see what programs it invokes and which one of them
- causes the fatal error.
-
- 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, and the DPMI server fails to allocate it because
- it exhausts available memory for its internal tables. Release 1 of CWSDPMI
- can fail like this if an application asks for a large number of small memory
- chunks. If you use release 1 of CWSDPMI, 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. Beginning
- with release 2, CWSDPMI defines a larger (6KB) default heap that is
- configurable by CWSPARAM program to be anywhere between 3K and 40K bytes,
- without recompiling CWSDPMI. You should upgrade to the latest CWSDPMI if you
- experience such problems.
-
- 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). If you see such problems when compiling a C program, stubedit
- `cc1.exe.'
-
- 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;
-
- Note that the Unix algorithm for `sbrk' might cause trouble in programs that
- install hardware interrupts handlers.
-
- 6.5 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:\DJGPP\BIN\prog.exe: not COFF" and just terminate.
- Help!!!*
-
- *A* : It might be that your DJGPP programs and/or `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
- short, most viruses cannot attach themselves to it without overwriting the
- beginning of the DJGPP COFF image which specifies vital information such as
- location and length of various program sections, 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 a
- v2.0 `gcc.exe' driver with `cc1plus.exe', `cc1.exe' or other programs from an
- old v1.x distribution.
-
- 6.6 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.7 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 (because Borland's
- programs are 16-bit DPMI clients, and the DPMI 0.9 spec doesn't allow mixing
- them with 32-bit DPMI clients such as DJGPP programs). It might be that
- another program called `make.exe' 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. That's because
- v1.x programs cannot spawn v2 programs directly (the v1.x program sees that
- the child is a DJGPP program and tries to call `go32' to run it, but v1's
- `go32' cannot run v2 programs). The result usually will be that the child
- either crashes or silently exits. 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.) You can use
- `go32-v2' to work around this limitation (see description of go32-v2 in
- Section 22.12, below), but I suggest doing that only if you absolutely cannot
- upgrade to v2's `Make.'
-
- 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 (that is usual for
- Makefiles that come from Unix). To work around, truncate the filename of
- that program in the Makefile.
-
- 6.8 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 old 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 with 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 the
- `bin/' subdirectory of your main DJGPP directory.
-
- 6.9 My problem isn't mentioned above!
- =====================================
-
- **Q*: I've installed DJGPP just like explained in the `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 your machine crashes. This might
- give you a hint on what's wrong.
-
- Another cause of such problems might be that your system is set up
- inefficiently. If GCC gets too few free RAM, it will run very slowly, and
- you might think it crashed when in fact it didn't. (This kind of problem
- usually happens on memory-starved machines.) Check out the system
- configuration advice in Section 3.9, in this FAQ list and configure your
- system accordingly.
-
- 6.10 I can't keep up with the error messages
- ============================================
-
- **Q*: I want to read all the error messages that GCC throws at me, but there
- 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 are hidden by the graphics display. How can
- I see it?*
-
- *A* : Error messages are usually written to `stderr', and stock
- `COMMAND.COM' cannot redirect it. There are several alternatives to do that:
-
- a. You can use a shell smarter then `COMMAND.COM', such as `4DOS' or
- `bash', which knows how to redirect standard error stream to a file.
- 4DOS is shareware and can be found on CCT mirrors, e.g.
- ftp://ftp.coast.net/Coast/msdos/4dos/, while `bash' is available from the
- DJGPP archives, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bsh1147b.zip.
-
- b. You can also run your program under any one of the programs which save
- all screen 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 CCT mirrors,
- e.g. ftp://ftp.coast.net/Coast/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. Here's how
- to run GCC with `REDIR':
-
- redir -o gcc.log -eo gcc -v ...
-
- (put the rest of the GCC command line instead of the dots). The
- messages printed by GCC will be written to the file `gcc.log'.
-
-
- 6.11 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 has already been posted and solved on
- the DJGPP News group. DJ Delorie <dj@delorie.com> has set up a searchable
- News group 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, 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.
-
- 6.12 How to ask DJGPP gurus for help
- ====================================
-
- **Q*: I've searched the news group archives, but didn't find anything
- helpful. I am totally lost. *Help!!!**
-
- **Q*: I don't have time to download all these messages, not to mention
- looking through them. Can't you DJGPP gurus help me? *Please??**
-
- *A* : DJGPP News group is famous for its outstanding user support. To get a
- fast and effective solution to your problem, you will have to supply the
- relevant info about your system, and describe exactly how things went wrong
- for you. To gather this info, do the following:
-
- * At the DOS command prompt, type `set > environ.lst', then press <Enter>.
-
- * Invoke the `go32-v2' program (it's in your `bin/' subdirectory) and save
- its output.
-
- * Post to the comp.os.msdos.djgpp news group 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 (if your
- problem is that GCC won't work).
-
- * If your problem involves a program that crashes and prints a stack dump,
- please post that stack dump. It's best to run `symify' on the stack
- dump, and post the output of `symify':
-
- symify -o dumpfile yourprog
-
- (See detailed description of symify in Section 9.2, for more details
- about `symify.')
-
- * Allow for 2-3 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 dozen 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 and Linker Performance
- **********************************
-
- This chapter deals with speed of compilation and linking under DJGPP, and how
- they could be improved.
-
- If you already know whether the compiler or the linker is the slow part, go
- to the appropriate section; if not, add `-v' to your GCC command line and run
- it again. With the `-v' switch, GCC will print all the programs it invokes,
- and you will be able to tell which one is taking most of the time.
-
- 7.1 Slow Compilation
- ====================
-
- **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
- accordingly. 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 percent 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 `CWSDPR0' as your
- DPMI host, or use the `CWSPARAM' program to point the swap file to a
- non-existent drive), or use `PMODE/DJ' as the DPMI host, then run the
- compilation again; if the compiler aborts with an error message saying there
- isn't enough memory, then it *was* paging in your original environment.
-
- 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 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.8). Also see
- recommendations for optimal software configuration in Section 3.9.
-
- If GCC doesn't page, check the 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. Some people disable the delayed-write feature for safety reasons,
- to avoid losing files due to system crashes. If you are worried about this,
- you can usually gain performance without sacrificing safety by enabling
- delayed-write together with an option that causes the cache to flush the
- write-behind data before the system returns to the DOS prompt. (For
- `SmartDrv' disk cache, this is achieved by specifying `/N/F' switches instead
- of `/X'.) GCC usually gains a lot when you set up your cache in such a way,
- because each compiler pass (pre-processor, compiler, assembler) must write
- temporary files that are used by the following passes.
-
- 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 versions of the library.
-
- 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 166 MHz Pentium
- system with 32 MBytes of RAM and 4 MBytes of RAM disk compiles the entire GCC
- source in under 10 minutes (this takes about 45 minutes on a 40MHz Sparc2).
-
- 7.2 Slow Linking
- ================
-
- **Q*: The compiler finishes in a few seconds, but then the linker grinds away
- for more than a minute, even on a very short program...*
-
- *A* : Try linking the trivial `"Hello, world!"' program; it should take no
- more than 7-10 seconds on a 486, 3-5 seconds on a Pentium. If you see much
- slower linking on your system, then the following advice might help you.
-
- A few users have reported that they got much faster linking after they've
- stub-edited `ld.exe' to change the transfer buffer size to 64KB. This
- speedup effect is usually seen when DJGPP is installed on a networked drive,
- or on a compressed disk; when DJGPP is installed on a local disk drive,
- linking speed is not affected by the size of transfer buffer.
-
- If you use a disk cache, make sure you enable its write-back (aka
- delayed-write) operation. Some people disable the delayed-write feature for
- safety reasons, to avoid losing files due to system crashes. If you are
- worried about this, you can usually gain performance without sacrificing
- safety by enabling delayed-write together with an option that causes the
- cache to flush the write-behind data before the system returns to the DOS
- prompt. For `SmartDrv' disk cache, this is achieved by specifying `/N/F'
- switches instead of `/X'.
-
- For very large (several MBytes) executables which are built from a large
- number of small source files, the link (as opposed to the compilation) 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. Make sure that the linker
- wasn't stub-edited to make its transfer buffer too small.
-
- Another reason for slow linking might be that the `DJGPP.ENV' file by default
- sets `TMPDIR' to a `tmp/' subdirectory of the main DJGPP installation
- directory; if DJGPP is installed on a networked drive, this means all your
- temporary files go back and forth through the network (and networked disks
- are usually not cached on your PC). In such cases, setting `TMPDIR' to a
- directory on your local drive, or to a RAM disk, would probably make linking
- faster.
-
- 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?*
-
- **Q*: When I link my programs, ld.exe complains that it cannot open crt0.o,
- although that file exists in the lib subdirectory...*
-
- *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:
-
- set 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 djdev201.zip, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/djdev201.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.
-
- Sometimes, people make errors in their `AUTOEXEC.BAT' that cause the DJGPP
- variable to be defined incorrectly, or not defined at all (some of the more
- common errors are listed below). To check what is the actual setting, type
- from the DOS prompt:
-
- set > env.lst
-
- then examine the contents of the file `env.lst'. You should see there a line
- like this:
-
- DJGPP=c:/djgpp/djgpp.env
-
- If a line such as this isn't there, you should investigate the cause for this
- (see below for some of the possibilities).
-
- Many problems with setting DJGPP happen when people put excess blanks around
- the `=' character, which has the effect of defining "DJGPP " (with the blank)
- which is not the same as "DJGPP" (without blanks). You should make sure
- there are no such excess blanks, or DJGPP won't find its files.
-
- Another possible cause of DJGPP variable not being set is that you invoke
- another batch file from your `AUTOEXEC.BAT' before the line that sets DJGPP.
- Make sure such batch files are invoked with the `CALL' statement, because
- otherwise the subsidiary batch file will never return to process the rest of
- `AUTOEXEC.BAT' (that's a "feature" of DOS batch file processing).
-
- The code that processes `DJGPP.ENV' assumes that this file resides in the
- main DJGPP installation directory. If that assumption is wrong, the compiler
- (and some other DJGPP programs) might fail to find some of the files or
- auxiliary programs they need. *Do NOT move DJGPP.ENV to any other directory!*
-
- Note that if you run DJGPP under Win95, WinNT or any other environment that
- supports long filenames (e.g., if DJGPP is installed on a networked drive
- whose network redirector supports long filenames), you *cannot* use long
- names of the directories in the pathname of `DJGPP.ENV' when you set the
- above variable in the environment; you should use their 8+3 aliases instead.
- First, some of these systems (such as WinNT) do not even support the LFN API
- for DOS programs. But even if LFN API *is* supported, e.g. on Win95, DJGPP
- won't know that it should support LFN until *after* it read `DJGPP.ENV'--it's
- a chicken-and-egg problem. For example, the following setting *won't work*
- because `Development' is longer than 8 characters:
-
- set DJGPP=c:/Programs/Development/Djgpp/djgpp.env
-
- If the DJGPP variable is set correctly, then check the following possible
- causes of this misbehavior:
-
- * You have edited the file `DJGPP.ENV' in a way that invalidated some of
- the settings there; try restoring the original file from the
- distribution to see if that fixes your problems. Be sure you are
- familiar with the syntax of `DJGPP.ENV' before you edit it. The DJGPP
- server has a page with a description of the `DJGPP.ENV' syntax, at this
- URL:
-
- http://www.delorie.com/djgpp/doc/kb/kb_7.html#SEC7
-
- The syntax of `DJGPP.ENV' is also described in the DJGPP Knowledge Base,
- See in (kb.inf)DJGPP.ENV, which comes with the `djdev' distribution.
-
- * Some older versions of Novell Netware cause the linker to fail if the
- libraries or the startup file `crt0.o' reside on a networked drive.
- This is due to a peculiarity of Novell that happens to fail the library
- function `stat' in some cases. The exact reason of the failure has been
- identified, and the library which comes with DJGPP v2.01 includes a
- version of `stat' that works around that problem, so the linker from
- v2.01 is free of this bug, and upgrading will solve this. Another
- solution would be to upgrade your Novell software; version 4.x is
- reportedly free of this problem, even if you use DJGPP v2.0.
-
- * You renamed the `gcc.exe' driver to some other name. In this case, you
- should edit the file `DJGPP.ENV' to add a section named after the new
- name of GCC, 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 the environment before the `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.
-
- * You passed the `-B' switch to GCC. This overrides the default location
- of `crt0.o' and if you follow `-B' with a directory other than that
- where `crt0.o' resides, the linker won't find it.
-
- You should not need to use the `-B' or `-L' switches at all if your
- installation is correct and the `DJGPP' variable points to the main
- installation directory, because GCC should be able to figure out all the
- linker switches itself. If linking fails without explicit `-L' or `-B',
- check out above for the possible causes.
-
- 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 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.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/lgp271b.zip, so if you
- didn't install it, GCC won't find them. Files whose names usually start with
- a capital letter, on MS-DOS have an underscore `_' prepended so they can 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.
-
- Another possible cause for problems with C++ include files is that your
- source file has a `.c' extension. GCC then thinks that this is a C program
- and doesn't instruct the preprocessor to search the include directories
- specific to C++. Rename your file to `.cc' or `.cpp' extension, or call GCC
- with the `-x c++' switch, and the header files will be found. A full list of
- extension rules which GCC uses to determine the source language can be found
- in the list of language-specific suffixes in Which language, elsewhere in
- this FAQ.
-
- 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 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.
-
- If the `NameNumericTail' set to 0 breaks some programs, you can restore its
- original setting after you've renamed the files as described above.
- `NameNumericTail' only affects the short names of new files being created, it
- has no effect on the files that already exist.
-
- 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 the sole
- purpose of demonstrating 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.simtel.net/pub/simtelnet/gnu/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 a 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 the `-v' switch to the GCC command line; if you see
- that 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.10, in
- this FAQ.
-
- You can override the default rules gcc uses to decide how each input file
- should be treated, with the help of the `-x LANGUAGE' switch. For instance,
- the command
-
- gcc -x c++ prog.c
-
- compiles `prog.c' as 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 the 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 ...
- #endif
- #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. If you need to link against some optional library, say
- `libxy.a', put the library into the DJGPP `lib/' subdirectory and append a
- `-lxy' to the link command line. To use C++ classes in the `libgpp.a' (it's
- called `libg++.a' on Unix systems), append `-lgpp.' The Standard C++
- Template classes are in `libstdcx.a' (it's called `libstdc++.a' on Unix);
- append `-lstdcxx.'
-
- When linking C++ programs, you can use the `gxx' command instead of `gcc'; it
- will then instruct the linker to also scan the C++ libraries automatically,
- so you don't have to remember doing that yourself.
-
- Note that the first release of DJGPP v2.0 didn't include `gxx.exe' and the
- C++ STL library `libstdcx.a.' If you cannot find them on your machine,
- download the latest `gcc272b.zip' and `lgp271b.zip' archives that are dated
- 22-Feb-96 or later, or upgrade to DJGPP v2.01.
-
- 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 the `-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 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 -lstdcxx -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 -lstdcxx
-
- or, if you compile and link in one command:
-
- gcc -o main.exe main.cc sub.cc -lgpp -lstdcxx -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 -lstdcxx -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' directly, 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 Where is class Complex?
- ============================
-
- **Q*: I cannot use class Complex in v2! My C++ program compiled fine with
- DJGPP v1.x, but in v2 the linker complains that it cannot find Complex class
- definitions in the library. Where are they?*
-
- **Q*: I looked into libgpp.a and there aren't any references to any Complex
- class functions. I also didn't find complex.cc source file in the source of
- Libg++ library. Where did the Complex class go?*
-
- *A* : The latest Draft C++ Standard has changed its notion of complex
- numbers, and the latest versions of Libg++ have followed suit. Instead of
- `class Complex' there is now a *template* `class complex<double>', and
- `Complex' is now a typedef which uses that template class. Look into the
- headers `lang/cxx/_complex.h' and `lang/cxx/std/complext.h' and you will see
- that change. Part of the code found previously on `complex.cc' in the Libg++
- source distribution is now found on `cdinst.cc' source file in the STL
- sources (look inside `libstdcx.a'), another part is scattered between the
- various files included at compile time (such as `lang/cxx/std/dcomplex.h' and
- `lang/cxx/std/complext.cc'), while the rest is generated by the compiler
- itself. Therefore, there aren't any predefined functions of class Complex in
- `libgpp.a.' Programs that use class Complex need to be edited to replace every
- instance of `class Complex' to either just `Complex' or `class
- complex<double>.'
-
- As long as the C++ Standard is not officially published, C++ is still a
- moving target, and Libg++ releases that try to track it sometimes have no
- other alternative but to break existing code. If you use C++, you have to
- accept this as a fact of life.
-
- 8.12 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.13 Unresolved djgpp_first_ctor
- ================================
-
- **Q*: I do everything like your praised FAQ says, but the linker complains
- about unresolved symbols with strange names like `djgpp_first_ctor',
- `djgpp_last_dtor', etc. I looked in every library with `nm', and I cannot
- find these creatures. Where in the world are they??*
-
- *A* : These symbols are defined by the `djgpp.djl' linker script that should
- be in your `lib/' subdirectory. When you call `gcc' to link a program, it
- invokes `ld.exe' with the option `-Tdjgpp.djl.' If you invoke `ld' directly
- (this is generally not recommended), be sure to include that switch. If you
- did invoke it through `gcc', maybe your linker is set up incorrectly. Add
- `-v' to the GCC switches and check that the command line that GCC gives to LD
- includes that switch, that your `lib/' subdirectory includes that script
- file, and that the script file is intact and includes the definition of the
- above symbols.
-
- Another reason might be that you have edited your `DJGPP.ENV' file in a way
- that prevents the linker from finding its `djgpp.djl' script.
-
- Mixing an old v1.x installation with a v2.x one can also cause such problems.
- Be sure to delete the entire v1.x tree, or rename it, before installing the
- v2.x distribution.
-
- 8.14 C++ programs yield large `.exe' file
- =========================================
-
- **Q*: It seems that declaring a large `static' array has the 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.
-
- 8.15 Why are DJGPP `.exe' files so large?
- =========================================
-
- **Q*: I compiled a trivial "Hello world" program and got a 60KB executable
- file. That's ridiculously bloated!*
-
- **Q*: How come I recompile my programs with v2, and my executables become
- larger by some 20-30 KBytes? Isn't the latest version supposed to be better?*
-
- *A* : Did you link with `-s' switch to `gcc', or run `strip' on the output
- of the linker? If not, the executable includes the debugging symbols, which
- makes it quite a lot larger. (It is not recommended to strip the symbols
- except when distributing production programs, because this makes debugging
- very hard indeed; that is why `-s' is not passed to gcc by default.)
-
- In general, v2 programs are about 20-30K larger on disk, but use 50-120K less
- memory at run-time, than v1.x programs. The larger disk image is due to two
- main factors:
-
- * Part of the code that used to be inside `go32' DOS extender in v1.x is
- now part of the library and thus gets linked into every program.
-
- * The v2 startup code is much more powerful, but also larger.
-
- Judging code sizes by looking at the size of "Hello" programs is meaningless,
- since most of the power of protected-mode programming goes wasted in such
- programs. There is no point in switching the processor to protected mode
- (which requires a lot of code) just to print a 15-byte string and exit. The
- overhead induced by the code needed to set up the protected-mode environment
- is additive; the larger the program, the smaller the overhead relative to the
- program size.
-
- Apart from getting to protected-mode, the DJGPP startup code also includes
- such functionality as wildcard expansion, long command-line support, and
- loading the environment from a disk file; these usually aren't available with
- other DOS protected-mode compilers. Exception and signal handling (not
- available at all in v1.x), FPU detection and emulator loading (which were
- part of `go32' in v1.x), are now also part of the startup code.
-
- If your program doesn't need parts of the startup code, it can be made
- smaller by defining certain functions with empty bodies. These functions are
- `__crt0_glob_function', `__crt0_load_environment_file', and
- `__crt0_setup_arguments.' By defining empty substitutes for all three of
- these, you can make the "Hello" program be 18KB on disk. These functions are
- documented in the DJGPP libc reference, which see.
-
- You can make your program image still smaller by compressing it with `DJP'
- which is a DJGPP-specific executable compressor, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2misc/mlp105b.zip. It is fast
- and has no memory overhead. It also supports DJGPP "Dynamically Loaded
- Module" (DLM) technology.
-
- Another cause for differences in executable sizes between v1.x and v2 might
- be the code generated by GCC: DJGPP v2 uses a newer version of GCC. Usually,
- the code size is quite similar, but in some cases GCC 2.7.2 has been seen to
- produce code which is 50% larger or 50% smaller than GCC 2.6.3 included with
- v1.12.
-
- 8.16 Linker complains about `djgpp.lnk'
- =======================================
-
- **Q*: I run DJGPP under Windows 95, but the linker complains about
- `djgpp.lnk' file...*
-
- **Q*: When I try to link a program, I get an error message which says that
- linker script file djgpp.lnk cannot be open. What gives?*
-
- *A* : Do you use DJGPP v2.0 on Windows 9x and have a shortcut to DJGPP in
- your current directory? If so, and if you call that shortcut `djgpp',
- Windows will create a file `djgpp.lnk' in your working directory. In that
- case, when `ld.exe' looks for its linking script, it will find this shortcut
- instead, and will be totally confused by its format and contents. In DJGPP
- v2.01 and later, the linker script is called `djgpp.djl', so that this
- conflict doesn't exist after you upgrade.
-
- Another possible cause of such problems is RSXNTDJ. When you install it, it
- replaces some of the files which come with DJGPP by its customized versions,
- but since version 1 of RSXNTDJ is consistent with DJGPP v2.0, these
- customized files still specify `djgpp.lnk' as the linker script, whereas
- DJGPP v2.01 and later has renamed that file to `djgpp.djl'. Please look into
- your `rsxntdj/lib/specs' file and see if it has a line like so:
-
- %{L*} %D %{T*} %o -Tdjgpp.lnk\
-
- If so, you should change `-Tdjgpp.lnk' into `-Tdjgpp.djl', and see if that
- solves the problem, or look for a version of RSXNTDJ which is compatible with
- your release of DJGPP. You should also compare the rest of the RSXNTDJ
- `specs' file with the one which comes with DJGPP and check for other
- inconsistencies.
-
- 8.17 Linker fails to produce the EXE program under Novell
- =========================================================
-
- **Q*: When I link my program, it fails to produce the .EXE executable, but
- only if I do this on a networked drive...*
-
- **Q*: I run STUBIFY on a networked drive under Novell, but it doesn't produce
- a .EXE file. How come?*
-
- *A* : You might have another copy of the file with the same name that GCC is
- creating in another directory somewhere on your networked drive. If that
- other directory is on your PATH, it is searched by Novell when the linker and
- `STUBIFY' try to create the executable file, because that file doesn't exist
- in the current directory. So what might actually happen is that the linker
- and `STUBIFY' are overwriting the files they find on your PATH instead of
- creating new files in the current directory.
-
- You can verify that this indeed is the problem by searching your networked
- disks for files with the same name as those you are trying to build, and
- looking at their time stamps. If that is indeed the problem, then you have
- several possible ways of solving it:
-
- 1. You can remove the other files, rename them, or move them to another
- directory that isn't searched by Novell.
-
- 2. You can rename the program you are trying to link.
-
- 3. You can change the way Novell searches for files (aka "the search
- mode"), so that it won't look in the directories on your PATH.
-
- 4. You can change your access rights to the directory on the PATH where the
- other files reside, so that you won't have write privileges to that
- directory.
-
- 5. You can change the search mode for `STUBIFY' and the linker (or for any
- other program that gives you that trouble) by running commands like
- these:
-
- SMODE stubify.exe 2
- SMODE ld.exe 2
-
-
- 8.18 Linker fails for large object files or large libraries
- ===========================================================
-
- **Q*: Whenever I define very large static arrays in my program, the linker
- fails saying "could not read symbols: Bad value". Huh??*
-
- **Q*: I have some large libraries that I cannot link because the linker fails
- on them with a message saying "memory exhausted". I have plenty of virtual
- memory on my system, so why would ld fail?*
-
- *A* : This is a known bug in `ld.exe' from GNU Binutils 2.5.2. Please
- upgrade to DJGPP v2.01 which comes with Binutils 2.7. If you can't upgrade,
- or if the latest `ld.exe' exhibits such bugs, these are your alternatives for
- a work-around:
-
- * In case of a large library, split it into several smaller ones.
-
- * For a module that defines large data structures, move some of the static
- data to other files, or allocate the space at runtime with `calloc.'
-
- `ld.exe' from GNU Binutils 2.7 (which comes with DJGPP v2.01) doesn't have
- most of these problems, but there are still some cases where you might see
- such messages. One such case is the `POVRAY' package, where the failure is
- caused by an object file called `_pmlite.o' in the library. The problem here
- is that `_pmlite.o' is a TASM-compiled file, processed by `EMXAOUT'.
- `EMXAOUT' produces `a.out' object files which `ld.exe' cannot link if they
- are in a library. Either taking that object file out of the library, or
- processing the original `_pmlite.obj' with another tool (such as `OBJ2COFF')
- will solve these problems. Note however, that the authors of `OBJ2COFF' have
- explicitly forbidden commercial use of their tool.
-
- 8.19 Building Allegro library fails
- ===================================
-
- **Q*: When I try to build the Allegro library, liballeg.a, I get some cryptic
- message about register-opcode mismatch. What am I doing wrong?*
-
- **Q*: It seems I miss one of the source files from the Allegro distribution,
- because Make cannot find it when I try to build Allegro.*
-
- *A* : You should get the latest version 2.11 of Allegro from SimTel.NET,
- e.g. ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/alleg211.zip or from
- Shawn Hargreaves' site, at this URL:
-
- http://www.talula.demon.co.uk/allegro/
-
- Version 2.1 of Allegro and some uploads of 2.11 to sites other than
- SimTel.NET are known to have bugs such as above.
-
- 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. Isn't it obvious that you guys blew it with v2?*
-
- **Q*: My v2 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 until now. 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 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' (`-559838801' in decimal)
- 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 only under
- CWSDPMI; its telltale sign is a message "Page fault at ..." that is printed
- when a program crashes, and an error code of 6. 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 can be disabled by
- setting the `_CRT0_FLAG_NULLOK' bit in `_crt0_startup_flags'; if this makes
- SIGSEGV crashes go away, your program is using such illegal pointers; the
- stack trace printed when the program crashes should be a starting point to
- debug this.
-
- An insufficient stack size can also be a cause of your program's demise, see
- setting the stack size in Section 15.9, below.
-
- 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 djdev201.zip, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/djdev201.zip, and should be
- in your `bin/' subdirectory). To this end, make sure that your program was
- compiled with the `-g' switch, linked *without* the `-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.10, 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*: My program crashes when I read data files, but the same program on Unix
- works OK.*
-
- **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 the `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.
-
- Note that the above distinction between binary and text files is written into
- the ANSI/ISO C standard, so programs that rely on the Unix behavior whereby
- there's no such distinction, are strictly speaking not portable.
-
- You can also use the low-level `_read' and `_write' library functions which
- give you the direct interface to the DOS file I/O; they always use binary 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.*
-
- **Q*: Help! I cannot make `gotoxy' work! The text I print appears on the
- screen in incorrect locations after I use `gotoxy'!*
-
- **Q*: Why does the text appear in the default colors even though I call
- `textcolor' and `textbackground'?*
-
- *A* : Do you write to screen using buffered I/O (`fprintf', `fputs' and the
- like) functions, or send your output to the C++ `cout' stream? Then what you
- see is the effect of the buffering of the standard output streams. The
- buffer is not written to screen until it's full, or until a Newline is
- output, which might produce very unpleasant and unexpected behavior when used
- in interactive programs.
-
- It is usually a 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 generally work
- under DOS and DJGPP, note that in some cases the operating system might
- further buffer your output, so sometimes a call like `sync' would be needed
- to actually cause the output be delivered to the screen.
-
- The functions that set text attributes only affect the screen-oriented output
- (aka "conio") functions (`cputs', `cprintf' etc.), the text written by
- `fprintf' and other "stdio" functions doesn't change. This is unlike some
- 16-bit DOS compilers where `stdio' functions can also print colored text.
-
- 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 Sandmann <sandmann@clio.rice.edu>, requests a
- notification by mail or acknowledged e-mail in case you distribute CWSDPMI
- with a commercial or shareware product.
-
- If your program could be run on a machine which lacks a 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*, write to Charles Sandmann <sandmann@clio.rice.edu> and
- ask him about a modified stub code that creates an image of CWSDPMI if none
- is found first time the program is run.
-
- You can bind `PMODE/DJ' with your program, but remember that `PMODE/DJ'
- doesn't support virtual memory, so such programs will only run on machines
- with enough free physical RAM.
-
- 10. Writing and Running Graphics Programs
- *****************************************
-
- This chapter discusses some problems and explains some subtle points related
- to graphics programming under DJGPP.
-
- A tutorial is available on graphics programming with DJGPP, at this URL:
-
- http://remus.rutgers.edu/~avly/djgpp.html
-
- 10.1 What GRX driver to use with your SVGA
- ==========================================
-
- **Q*: Why won't GRX work with my SVGA adapter in any resolution but the
- standard VGA?*
-
- **Q*: How do I tell GRX which driver to use with my SVGA?*
-
- *A* : In order for GRX to work with your SVGA, you should set the `GRX20DRV'
- environment variable, like this:
-
- set GRX20DRV=et4000 gw 1024 gh 768 nc 256
-
- To set that variable, you need to know the chip-set on your adapter; refer to
- your SVGA documentation. Currently, GRX supports the following chip-sets:
-
- `ati28800'
- The ATi 28800 chip-set.
-
- `cl5426'
- Cirrus Logic CL-GD5426 or higher (like CL-GD5428) chip-set.
-
- `et4000'
- Tzeng Labs ET4000 chip-set.
-
- `mach64'
- The ATi Mach-64 SVGA.
-
- `stdega'
- The standard EGA adapter.
-
- `stdvga'
- The standard VGA adapter.
-
- `VESA'
- For any VESA-compatible adapter.
-
- After you set the `GRX20DRV' variable, run `modetest.exe' to see what modes
- you have available.
-
- If your chip-set is not one of the above, try the `VESA' driver because many
- adapters support the VESA BIOS extensions. If yours doesn't, try installing
- a VESA BIOS emulator, like UNIVBE, e.g.
- ftp://ftp.coast.net/Coast/msdos/graphics/univbe51.zip.
-
- 10.2 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 a protected-mode environment, in which
- 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 the `_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 faster access (and don't
- want to write it in assembly), See using the "nearptr" access facilities in
- Section 18.4, as described below.
-
- If your video card supports the VBE 2.0 standard, you can access the linear
- frame buffer as a normal array in memory. For an example of such a
- technique, see the VBE example code by Charles Sandmann, e.g.
- ftp://ftp.neosoft.com/pub/users/s/sandmann/vbe.zip. You can also reach this
- file via the Web, at this URL:
-
- http://www.rt66.com/~brennan/djgpp/vbe.zip
-
- 10.3 Graphics screen restoring under Windows
- ============================================
-
- **Q*: When I switch away from my DJGPP program under Windows, then switch
- back to it, graphics mode is down, or my screen is all messed up. Why?*
-
- *A* : Windows only saves the VGA screen in standard VGA modes (1..13h) when
- you task-switch away from a DOS application. In any other mode it only
- saves/restores the video mode *number*, but not the actual screen contents.
- Your application is most likely still in the proper video mode (if not, it's
- probably the fault of the Windows driver for your SVGA card), but the video
- memory is messed up. The beauty of all this is that your program has no way
- of knowing that the screen has been taken away and then returned to it.
-
- The only reasonable thing to do is to dedicate a "hotkey" in your application
- (e.g., `Alt-R') whose action is to redraw the entire screen. If you do that,
- it's best to start all the way from the beginning, with a call to
- `GrSetMode', as there are a few bad Windows video drivers which do not
- restore SVGA graphics modes properly upon the switch back.
-
- 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 an 80387 should either be linked with the `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
-
- This is probably due to some subtle bug in the emulator setup code. This
- code is hard to debug, because the people who developed it have machines with
- hardware FP processors. Volunteers with FPU-less machines are needed to help
- debug the above problem. If you have access to a system without an FPU and
- are willing to fix this problem, write to Charles Sandmann
- <sandmann@clio.rice.edu> and ask him for guidance.
-
- 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. (But you will need to get the
- sources and recompile it, since it was compiled with a beta release of DJGPP
- and will cause unresolved externals if you try linking against `libwmemu.a'
- without recompiling it.) Note, however, that even `WMEMU' doesn't solve all
- the problems of debugging FP programs on a non-FPU machine (e.g., emulating
- flags doesn't work).
-
- 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. Apart of `emu387' and `WMEMU', the only other emulator known to
- work with DJGPP is `Q87' from QuickWare. `Q87' is shareware and is available
- from the QuickWare Web site, at this URL:
-
- http://www.weblane.com/quickware
-
- 11.3 Floating-point emulation under OS/2
- ========================================
-
- **Q*: I run DJGPP in an 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* : The GCC Info file also says that the library required by
- `-msoft-float' is *not* part of the 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 make sure that your program doesn't generate
- NaNs, or set the 80x87 control word to a different value. A library function
- called `_control87' 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 the `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
-
- 11.7 Floating point exception in Objective-C programs
- =====================================================
-
- **Q*: When I run my Objective-C programs on a machine without an FPU, it dies
- with a floating point exception, even though I installed the emulator as the
- docs say...*
-
- *A* : There is a bug in GCC 2.7.2 whereby it sometimes emits Objective-C code
- that crashes ObjC programs. A patch that fixes it was posted to the DJGPP
- news group and can be found in the DJGPP mail archives, at this URL:
-
- http://www.delorie.com/djgpp/mail-archives/djgpp/1996/05/05/11:05:21
-
- You will have to get the GCC source distribution `gcc2721s.zip', install the
- above patch, rebuild `cc1obj.exe', and then recompile `libobjc.a' to make the
- problem go away.
-
- 11.8 Floating point exception in libm functions
- ===============================================
-
- **Q*: When I use the `ldexp' function, my program crashes with SIGFPE.
- What's wrong?*
-
- *A* : There is a bug in the scaling code in `libm.a' library released with
- DJGPP v2.0 which affects several library functions such as `ldexp'. A
- work-around is to link without `-lm' switch; this will cause `GCC' to use
- math functions from `libc.a'. If you need math functions which are only in
- `libm.a', or if you need `libm.a' for better numerical performance, a patched
- version of libm is available, e.g.
- ftp://ftp.lstm.ruhr-uni-bochum.de/pub/djgpp/libm.zip, courtesy of Tom Demmer
- <Demmer@LStM.Ruhr-Uni-Bochum.De>. DJGPP v2.01 corrects this bug, so upgrade
- to that version if you can.
-
- 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. 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.exe
-
- Beginning with v2.01, DJGPP debuggers can debug both unstubbed COFF images
- and DOS-style .exe executables (v2.0 only supported COFF files). To debug a
- COFF file, name it without the .exe extension, like so:
-
- gdb myprog
-
- You can use one of several available debuggers with DJGPP:
-
- a. `RHIDE', the DJGPP IDE by Robert Hoehne (available from the DJGPP
- archives, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2apps/rhide10b.zip). It
- includes an integrated source-level debugger based on GDB code and
- presents a user interface like that of Borland's IDE or Turbo Debugger.
-
- b. `RHGDB', a stand-alone version of GDB with a Turbo Vision user
- interface. `RHGDB' is part of the RHIDE distribution; it only supports
- part of GDB features.
-
- c. `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. Another advantage of `FSDB' is that
- you can easily debug programs that grab the screen, because it can
- switch between the debugger screen and the application screen. The main
- disadvantage of `FSDB' is that you cannot easily examine the contents of
- complex data structures. Remember to prepend an underscore `_' to the
- names of C identifiers when you use them with `FSDB'; for C++ programs
- you will have to find out the mangled names of static class variables
- and methods to make `FSDB' understand them.
-
- d. The GNU Debugger, `GDB' (get the file gdb416b.zip, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/gdb416b.zip. This is
- a powerful source-level debugger, but it uses a line-oriented user
- interface. People who are familiar with using `GDB' on Unix should know
- about the following important differences in its operation on MS-DOS:
-
- * The command-line arguments can be only passed to the debuggee from
- within the debugger (use the `set args' or `run' commands), not
- from the `GDB' command line.
-
- * You cannot rerun the debuggee when it exits. You must exit `GDB'
- and restart it.
-
- * `GDB' is currently configured for DJGPP in a way that makes loading
- a program and reading a source file when a breakpoint is hit
- *exceedingly* slow: it can take more than a minute for a very large
- program. Be patient and don't decide that `GDB' is wedged unless
- you've waited several minutes. A source-level patch to GDB was
- posted to the DJGPP News group, which corrects this problem; you
- can get this patch by searching the DJGPP mail archives.
-
- * `GDB' doesn't know about PC-specific keys, so you cannot use the
- arrow keys for command history editing. Use ASCII control keys
- instead (`^F' for forward character, `^B' for backward character,
- `^P' for previous line, `^N' for next line, etc.).
-
- * The debugger and the debuggee share their file handles. This means
- that if your program redirects or closes its `stdin' or `stdout',
- you will be unable to communicate with `GDB.'
-
- * The initial commands are read from a file named `gdb.ini' instead
- of `.gdbinit' which isn't a legal filename under MS-DOS.
-
- * `GDB' uses the GNU `readline' package for its input. The
- `readline' init file (`~/.inputrc' on Unix) is called `/inputrc' on
- MS-DOS and should be in the root directory of the current drive.
-
- e. `EDEBUG32' is the most basic debugger you can use with DJGPP. One case
- when you would need to use it is when you debug a DXE module (see
- explanation of what a DXE is in Section 22.13), because `GDB' doesn't
- support debugging DXEs.
-
-
- You invoke any debugger like this:
-
- <debugger-name> <program> <args...>
-
- Note that the `argv[0]' parameter under the debugger is *not* the full
- pathname of the debuggee, so programs which use `argv[0]' for their operation
- might behave differently under a debugger.
-
- 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 DJGPP debuggers. 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 from DJGPP v2.0 on a `.exe' program.
- That version of 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 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
-
- Debuggers which come with DJGPP v2.01 can debug COFF and .exe programs alike,
- so upgrading to v2.01 should solve this problem.
-
- 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 (graphics
- programs usually don't); 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 a low-level debugger.
- Press `Alt-F5' to switch between the two screens. Stock FSDB as distributed
- with DJGPP can only do this with text screens, but a modified version of FSDB
- with graphics support, e.g.
- ftp://ftp.delorie.com/pub/djgpp/contrib/gnudebug.zip is available that knows
- about many graphics modes (it can also be found on the Oulu repository, e.g.
- ftp://x2ftp.oulu.fi/pub/msdos/programming/djgpp2/gnudebug.zip).
-
- Future versions of RHIDE might allow debugging graphics programs, so try to
- find out whether such a version is available.
-
- 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. Be sure that you don't
- have some other TSR installed that catches screen writes and bypasses the
- BIOS functions, or else `MSHELL' won't help you. For example, changing the
- code page (with the DOS `CHCP' or `MODE' commands) might do this.
-
- 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 Can GDB print class members?
- =================================
-
- **Q*: It seems that GDB doesn't recognize C++ class members by their
- original, unmangled names. Do I really need to figure out the mangled names
- of all my class variables and methods to be able to debug them?*
-
- *A* : No, you don't. `GDB' *does* allow you to use the original names, it's
- just that it usually treats the `::' in their names as word delimiters.
- Include the name of the method or a class static variable in single quotes,
- and `GDB' will recognize them as a single word. For example, if your class
- `CMPForward' has a method named `go' which you need to put a breakpoint in,
- use the following command:
-
- b 'CMPForward::go'
-
- Other `GDB' features that might be useful in this context are the various
- demangling options, like `set print demangle', `set demangle-style' etc.;
- look them up in the GDB on-line docs.
-
- However, there are some cases where you won't be able to get GDB to demangle
- C++ function names no matter how hard you try. This is due to a lack of
- sufficient debugging information in the COFF files with SDB debug data.
- There's simply not enough info there for GDB to detect the source language
- and use C++-specific support. If you need a description of the GNU style of
- mangling C++ names (so you could demangle them yourself), look in the GDB or
- Libg++ source distribution, in the libiberty directory, for a file named
- `cplus-demangle.c'. If you really need full C++ support in DJGPP, you will
- have to recompile GCC with stabs debugging support. Robert Hoehne
- <Robert.Hoehne@Mathematik.tu-chemnitz.de>, who did that, reports that it is
- only necessary to change the configuration file `go32.h' in the GCC sources
- and rebuild `cc1.exe' and `cc1plus.exe'. Caveat emptor: `FSDB' and
- `EDEBUG32' don't understand stabs, so you will have to compile with `-gcoff'
- option to use these debuggers.
-
- Note that, as the debugger built into RHIDE uses GDB code, it will also
- sometimes have such problems with debugging C++ programs.
-
- 12.8 GDB cannot list source that was #include'd
- ===============================================
-
- **Q*: My source file #include's another source file, but I cannot set a
- breakpoint in that included code, because GDB says there is no such line, or
- no such source file...*
-
- **Q*: I cannot debug code produced by Flex, or Bison, or F2C, because GDB
- somehow messes up all the source file and line number info!*
-
- *A* : This is a genuine limitation of the COFF format used by DJGPP. It can
- only handle a single source file for a given object file. It does include
- correct line numbers, but the name of the source file is wrong, so debugging
- such files just doesn't work.
-
- For source files that include other source files, you can work around this by
- just inserting the included source with your editor while you debug the
- program. For code produced by other programs, like `F2C' or `Bison', you
- will have to delete the `#line' directives from the generated C source, and
- debug the generated code as regular C program.
-
- 12.9 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...*
-
- **Q*: When my program hits a breakpoint in GDB, the debugger reports SIGSEGV,
- but only under Windows...*
-
- *A* : There are currently a few limitations in debugging programs which use
- interrupts or exceptions. Programs compiled for profiling may crash under a
- debugger 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 FP hardware (unless
- you use `WMEMU' as your emulator, but even WMEMU doesn't solve all the
- problems). The reason for all these problems is that any exceptions or
- signals that happen when your program runs under a debugger will be caught by
- the debugger instead, and they won't get passed to the debuggee. To debug
- programs which hook hardware interrupts, you will have to chain the old
- real-mode interrupt handler to your new handler, which requires to write
- special debug version of the program.
-
- 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 where 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). Some programs (but
- not Emacs) will also treat the `Ctrl-2' keypress as `Ctrl-C'.
-
- Another known problem is that `GDB' GP Faults when the program hits a
- breakpoint under Windows 3.x (Windows 9x doesn't have this problem). This is
- because the breakpoint instruction causes a software interrupt (as opposed to
- an exception) under Windows 3.x, and the DJGPP debug support currently only
- catches debug exceptions. The only work-around is to use the *hardware*
- breakpoints (which use the special debug registers of the i386 and higher
- CPUs, and which do work with DJGPP on Windows 3), and never have more than 4
- of them active at the same time. `FSDB' will automatically use the hardware
- breakpoints for the first 4 breakpoints (so it works on Windows 3.x unless
- you set more than 4 breakpoints simultaneously), but with `GDB', you will
- have to explicitly use the `hbreak' and `thbreak' (instead of `break' and
- `hbreak') commands which set hardware breakpoints. This works with DJGPP
- ports of GDB 4.16 and later. Note that `GDB' uses the ordinary breakpoints
- to implement the `step', `next' and similar commands, so you can't use these
- on Windows 3.x; use the temporary hardware breakpoints instead. The above is
- also true for watchpoints (which watch for variables to change value): you
- need to use hardware watchpoints with GDB (the total number of breakpoints and
- watchpoints cannot exceed 4). Same considerations apply to the debugger
- built into RHIDE.
-
- 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.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu27b.zip.
-
- 13.2 Programs compiled with -pg crash when run
- ==============================================
-
- **Q*: I cannot profile my program: when I compile it with -pg, it crashes or
- wedges my machine!*
-
- *A* : DJGPP v2.01 has a bug in one of its library functions which is only
- linked into your program when it is compiled with the `-pg' option. A patch
- was posted to the DJGPP News group; you can find it by searching the DJGPP
- mail archives. A work-around is to run the program compiled with `-pg' on
- vanilla DOS configuration (no memory managers such as EMM386 or QEMM, and no
- Windows).
-
- 13.3 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' from DJGPP v2.0 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. Alternatively, upgrade to
- DJGPP v2.01, where all Binutils programs know about .exe executables.
-
- 13.4 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 the `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.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu27b.zip.
-
- 13.5 Why is `__dpmi_int' so heavily 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.
-
- 13.6 `gprof' doesn't produce output
- ===================================
-
- **Q*: Every time I run the profiler it says "gmon.out: no such file or
- directory" and no profile is produced. What is this `gmon.out' and why won't
- `gprof' compute the profile?*
-
- *A* : `gmon.out' is the file with raw execution counts and timing info that
- `gprof' needs to produce the profile. The file is written by the profiled
- program when it exits. If the file isn't created, it might be because one of
- the following reasons:
-
- * You didn't compile and/or link your program with the `-pg' switch. Note
- that *both* compilation and link need to be done with `-pg', because the
- functions that actually write the results to `gmon.out' are only linked
- in when `gcc' sees `-pg' on the link command line.
-
- * You have called `ld.exe' directly to link your program and forgot to
- mention the files and switches necessary for the profiled program
- operation. You should use `gcc' to link your program instead of calling
- the linker directly; a `-pg' switch to `gcc' is all that it takes to
- make sure that the linker will get all the necessary arguments. (If you
- absolutely need to call `ld.exe' directly, invoke `gcc' once with a `-v'
- switch and you will see what the arguments are that you should pass to
- the linker in your case.)
-
- * Your program exited abnormally. The function which generates `gmon.out'
- is registered with the `atexit' library function, and won't be called if
- the program was terminated in an abnormal way. Make sure that your
- program exits with a call to `exit' library function or with a `return'
- statement in your `main' function. For example, if your program dies
- with an exception or a signal, install a signal handler and make it call
- `exit.'
-
- 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 Comparing v2 with DJGPP v1.x
- =================================
-
- **Q*: I switched to v2 and my programs now run slower than when compiled with
- v1.x...*
-
- **Q*: I timed a test program and it seems that DJGPP v2.01 produces slower
- executables than v2.0, which in turn was slower than v1.x. Why are we giving
- up so much speed as we get newer versions?*
-
- *A* : In general, GCC 2.7.2 which comes with DJGPP v2.0 generates tighter,
- faster code, than GCC 2.6.3 which came with v1.x. But it sometimes produces
- buggy code when "strength reduction" optimizations are enabled. So DJGPP
- v2.0 by default disables this kind of optimization, which might sometimes
- yield slower code. If you need extra speed, first debug your program with
- default optimization options, and then recompile with `-fstrength-reduce'
- switch to see if that makes any difference; or upgrade to DJGPP v2.01 where
- GCC doesn't have this bug.
-
- Comparison between GCC 2.7.2 (in v2.0) and 2.7.2.1 (in v2.01) shows that
- 2.7.2.1 optimizes just as well as 2.7.2, but it takes a different combination
- of the optimization-related options to achieve the greatest speed in each
- compiler version. The default optimization options has also changed; for
- example, `--force-mem' is switched on by `-O2' in 2.7.2.1; it wasn't before.
- GCC offers a plethora of optimization options which might make your code
- faster or slower (see the GCC docs for a complete list); the best way to find
- the correct combination for a given program is to profile and experiment.
- Elliott Oti <e.oti@stud.warande.ruu.nl> suggests the following tips:
-
- * Compile your code with the ordinary compilation switches `-O2 -m486
- -fomit-frame-pointer -ffast-math'.
-
- * Profile your code and check which functions are "hot spots".
- Disassemble them, or compile with `-S', and examine the machine code.
-
- * If the disassenbly shows there aren't too many memory accesses inside
- the inner loops, try adding `-fforce-addr' option; it helps a lot if a
- couple of pointers are used heavily within a single loop. If there are
- a lot of memory references, try adding `-fno-force-mem', to prevent GCC
- from repeatedly copying variables from memory into registers.
-
- * Try adding `-funroll-loops' and `-funroll-all-loops' and profile the
- effect.
-
- * If different time-critical functions exhibit different behavior under
- some of the optimization options, try compiling them with the best
- combination for each one of them.
-
- 14.3 DJGPP programs on a Pentium
- ================================
-
- **Q*: Does DJGPP support Pentium-specific optimizations?*
-
- **Q*: I run the same program on a 486 and on a Pentium, and it's slower on a
- Pentium!!*
-
- *A* : DJGPP doesn't add to, or otherwise change the compiler features offered
- by GCC. DJGPP is just a port of GCC to MSDOS. Since GCC (as of version
- 2.7.2.1) doesn't support Pentium-specific optimizations, neither does DJGPP.
-
- A program might sometimes run slower on a Pentium due to alignment problems
- in DJGPP. GCC makes assumptions about how GAS (the assembler) handles
- alignment, but when GAS is built with the default DJGPP configuration, it
- treats alignment in a way that's different from what GCC assumes. The
- outcome of this is that longs are word-aligned, doubles are dword-aligned,
- etc. Depending on the DJGPP version, link order, library differences, you
- might get lucky (or unlucky) with a 50/50 chance to get an improper
- alignment. Different CPUs have different penalties for unaligned accesses,
- which may explain differences in speed.
-
- You might consider adding some slack static variables to induce changes in
- alignment; if any of the changes suddenly cause a significant change in the
- runtime performance, then alignment might be the reason.
-
- 14.4 My program's I/O is so slow!
- =================================
-
- **Q*: I measured the time required to read a 2 MByte file in DJGPP and in
- Borland C. It took the 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 the
- 1 MByte mark, where real-mode DOS can get at it. That 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 (including, for example, Windows programs when Windows is set to
- 386-Enhanced mode). 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).
-
- Some programs which only copy data between two files might gain significantly
- if you write your custom low-level I/O functions that avoid moving data to
- extended memory (only to move them back to the transfer buffer). However,
- these cases are rare.
-
- 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.5 My ported program runs much slower!
- ========================================
-
- **Q*: How come my program, which I ported from Borland/MS 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 news group by posting to the
- comp.os.msdos.djgpp news group, 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
- should try enabling some of the optimization options which aren't
- enabled by default.
-
-
- 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 in 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 Section 15.5, below). Under
- Windows 9x, the memory settings of the DOS Applications' Property Sheet
- define how much virtual memory a DJGPP program will get (see Win9x allocation
- details in Section 15.6, 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 blocks when the new size is more
- than the 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 before all memory is used
- ======================================================
-
- **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'!*
-
- **Q*: Why is my program dying with SIGSEGV under CWSDPMI when allocating a
- chunk of memory?*
-
- *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. The Windows 3.x behaves in the same way, and 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)' 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.
-
- If your program asks for memory in lots of small allocations, then it might
- crash when you use CWSDPMI as your DPMI host. This is because CWSDPMI runs
- out of its tables where it tracks memory allocations. If you use release 1
- of CWSDPMI, 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. Beginning
- with release 2, CWSDPMI defines a larger (6KB) default heap that is
- configurable by CWSPARAM program to be anywhere between 3K and 40K bytes,
- without recompiling CWSDPMI. You should upgrade to the latest CWSDPMI if you
- experience such problems.
-
- 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 peculiarities under Windows 9x
- =====================================================
-
- **Q*: I seem to be unable to get more than 16 MBytes of virtual memory under
- Windows 95, even though I have 32 MBytes of RAM installed on my machine, and
- a lot of disk space...*
-
- *A* : You must set the maximum amount of DPMI memory to 65535K in the DOS
- applications' property sheet. If you leave that setting at the default
- "Auto", you only get 16 MBytes. You must actually type 65535 inside the
- dialog box, as checking out the values from the list Windows offers will
- never get you past 16384 (i.e., 16MB).
-
- Note that you cannot allocate more than half the available memory in one
- chunk under Windows 9x, exactly as the things are under Win3.x, and you
- cannot have more than 64 MBytes of virtual memory available to DJGPP programs
- running on Windows.
-
- 15.7 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 have 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 versions of the 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 it should take over.
- You can use the `go32-v2' program to see what amount of extended memory your
- DJGPP programs will get.
-
- 15.8 How much memory do parent DJGPP programs leave for their child?
- ====================================================================
-
- **Q*: How much memory is available when I call the `system' library function?*
-
- *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 than it used to be with
- v1.x, except on machines with low amounts of installed RAM. A disadvantage
- is that if you spawn a real-mode program that uses XMS, the extended memory
- used up by your DJGPP program will be unavailable to it, unless you use a
- memory manager (as opposed to when CWSDPMI uses raw XMS or HIMEM). The only
- way around this problem is to buy more RAM, or to install a real memory
- manager.
-
- Note that if you use a memory manager such as EMM386 or QEMM386 with the
- NOEMS parameter, CWSDPMI will use the XMS (as opposed to VCPI) services to
- allocate extended memory, and will allocate all of the available XMS memory
- for itself. So if, while your DJGPP program runs, some resident software
- such as device driver or TSR will try to allocate XMS, the allocation will
- fail.
-
- 15.9 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 seems to overflow the stack, but only when I run it under a
- debugger...*
-
- **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 is going on??*
-
- *A* : DJGPP v2 programs get fixed-size stack which is allocated by the
- startup code and then stays fixed for the entire lifetime of the program;
- 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 the `STUBEDIT' program (change the parameter "Minimum
- amount of stack space"), or by setting the global variable `_stklen' in your
- program. Example:
-
- unsigned _stklen = 1048576; /* need a 1MB stack */
-
- The DJGPP startup code checks both the value in the stub info and the value
- of `_stklen', and uses the larger of these two. Therefore, programs that are
- known to require large stack size should set `_stklen' to make sure they will
- always work, even if somebody stub-edits them to a lower value. This
- technique is also safer when you need to debug your program with `gdb' (see
- below). However, you might need to use `STUBEDIT' with programs for which
- you don't have the sources.
-
- Programs which need an unusually large stack might crash with bogus stack
- traces, because part of the heap gets 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
- and recompile the program. (Some DPMI hosts will actually allocate the
- entire 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
- (e.g. if it has a wrong syntax).
-
- When you run a program as an un-stubbed COFF image under a debugger, the
- stack size comes from the debugger. So if your program needs a large stack
- and you run it under `gdb', be sure to stubedit `gdb' to enlarge its stack to
- at least the value your program needs to run safely.
-
- Under Windows, be sure you've allocated a sufficiently large swap file (let's
- say, 40MBytes) from the Windows' Control Panel, and 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 file `DOSPRMPT.PIF', which almost surely
- defines very low limits on these two, and your program might have problems
- getting the memory it needs for its stack.
-
- DJGPP v2.0 has a subtle bug in its startup code that is seen very rarely, and
- that manifests itself by a program crashing with Page Fault or SIGSEGV. If
- you are using v2.0 and enlarging the stack and the CWSDPMI heap size didn't
- help, try adding some (e.g., 4KB) static data to your program and see if that
- helps. But the best way to overcome this is to upgrade to DJGPP v2.01 or
- later.
-
- 16. Command-line Arguments Handling in DJGPP
- ********************************************
-
- DJGPP handles command-line arguments 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).
-
- Note that `*.*' only picks up files that actually have an extension. This is
- contrary to the usual DOS practice where it means *all* the files, with or
- without extension.
-
- 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 the 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* : These special characters on the command-line arguments are handled by
- the filename expansion ("globbing") code before they are passed to the `main'
- function (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 in order for them to be
- treated as literal characters. 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?). This is also different from what you get under a Unix shell.
-
- 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 it 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 environment method. This is the same as the `!proxy' method above,
- but the information about the long command line is stored in an
- environment variable called " !proxy" (with the leading blank and in
- lower-case). The reason for two similar, but different methods is that
- command-line arguments passed by `system' library functions should be
- globbed by the child, while the arguments passed by `spawnXX' and
- `execXX' family of functions should not; thus the former uses the
- environment method while the latter use the `!proxy' method.
-
- * 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
- the 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.
- However, if your environment is *very* large (some people need as much as 6KB
- to accommodate for all the variables used by the various packages installed
- on their machine), be sure to stub-edit the programs that spawn other
- programs to larger transfer buffer, or else they could fail.
-
- The above limit depends on the size of the transfer buffer, so check the size
- of the value recorded in the stub header of the *parent program* before you
- pass extremely long command lines to its children. GCC is the first program
- you should worry about, because the linker (`ld.exe') usually gets long
- command lines from GCC (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* : If you use Make 3.73, 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. One easy way to
- get rid of redirection characters without losing their effect is to use the
- `redir' program which comes with DJGPP. For example, the following command:
-
- frobnicate foo.bar > myfile.tmp
-
- can be re-written instead like this:
-
- redir -o myfile.tmp frobnicate foo.bar
-
- The port of Make 3.75 which comes with DJGPP v2.01 doesn't call `COMMAND.COM'
- in the above cases, but rather emulates pipes and redirection internally, so
- upgrading to v2.01 will solve such problems. If you think about using Make
- 3.75 with DJGPP v2.0, don't: invoking v2.0 programs from v2.01 programs will
- cause subtle and hard-to-debug problems due to incompatibilities between
- these two versions regarding the methods of invoking child programs (in
- particular, v2.0 doesn't support the environment method of passing long
- command lines described above).
-
- 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 some of GCC installations (on systems other
- than MS-DOS) 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-section.
-
- * 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 bnu27b.zip, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu27b.zip archive, then
- see 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.
-
- A guide is available which was written by Brennan Mr. Wacko Underwood
- <brennan@mack.rt66.com>; it describes how to use inline assembly programming
- with DJGPP and includes a tutorial on the AT&T assembly syntax. Check out
- the DJGPP inline assembly tutorial, at this URL:
-
- http://www.rt66.com/~brennan/djgpp/djgpp_asm.html
-
- Many people who used Intel syntax and then converted to the AT&T style say
- that they like the AT&T variant more. However, if you prefer to stick with
- the Intel syntax, download and install NASM, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/msdos/asmutl/nasm091.zip, which is a free
- portable assembler. It is compatible with DJGPP and accepts a syntax which
- is almost 100% compatible with the Intel style.
-
- 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 the 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 the phase of the moon is 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 news group 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 the DJGPP server, e.g.
- ftp://ftp.delorie.com/pub/djgpp/contrib/ta2asv08.zip and on the Oulu
- repository, e.g. ftp://x2ftp.oulu.fi/pub/msdos/programming/convert/ta2as.zip.
- `TA2AS' was written by Jan Oonk <jan@stack.urc.tue.nl>.
-
- Alternatively, here is what you can do to make your code linkable with DJGPP
- programs:
-
- * Get and install NASM, a portable x86 assembler which supports most of
- the Intel syntax and can generate DJGPP-compatible COFF object files (as
- well as lots of other formats, such as Microsoft 16-bit OBJ and Win32,
- a.out, and ELF). It also supports Pentium and Pentium Pro opcodes.
- NASM is free for non-commercial use (see the docs for commercial use
- restrictions) and can be compiled with DJGPP. You can get NASM from
- sunsite mirrors, e.g.
- ftp://sunsite.unc.edu/pub/Linux/devel/lang/asm/nasm-0.90.tar.gz. A
- pre-compiled MSDOS binary is available from SimTel.NET sites, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/msdos/asmutl/nasm091.zip. The author
- and maintainer of NASM is Simon Tatham <sgt20@cam.ac.uk>.
-
- * 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 a `-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 the `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 comp.os.msdos.djgpp
- news group, so that I can make the above instructions less vague.)
-
- * Use a disassembler to disassemble the object code, then convert it to
- the AT&T format either by hand or using `TA2AS'. One place to look for
- such a disassembler is on SimTel.NET mirrors, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/msdos/disasm/.
-
- 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 of the rules for protected-mode programming (see next question in
- Section 17.4).
-
- 17.4 Converted code GP Faults!
- ==============================
-
- **Q*: OK, I've succeeded in converting and compiling 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
- this 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
- available 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. (Note that mixing object
- files from different compilers usually won't work either, even if they both
- are in the `.obj' format.)
-
- Lately, an automated conversion tool called `OBJ2COFF' was written by the
- SPiRiT team, which can be used to convert `.obj' object files and `.lib'
- libraries to `COFF' format, provided that the original `.obj' files 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/convert/o2cv10.arj and from DJ
- Delorie's ftp server, e.g. ftp://ftp.delorie.com/pub/djgpp/contrib/o2cv06.arj.
- If you have any problems with it or questions about it, send them to its
- author, Rico <mb002@hi.ft.hse.nl> or to George van Venrooij
- <george@il.ft.hse.nl>. Note that the authors of `OBJ2COFF' have explicitly
- prohibited commercial use, so you shouldn't use `OBJ2COFF' for converting
- commercial object files.
-
- Another conversion tool you might try is `EMXAOUT' from the `emx/gcc'
- package. It also requires the code to be written for the flat-address memory
- model and will reportedly complain if you feed it with code written for
- segmented memory models. `EMXAOUT' is available from the SciTech Software
- FTP site, e.g. ftp://ftp.scitechsoft.com/devel/emxaout1.zip. If you need,
- you should be able to compile it with DJGPP; however, a precompiled binary is
- available in the above archive. Or you can get `EMXAOUT' from the EMX
- archives, e.g. ftp://ftp-os2.nmsu.edu/os2/unix/emx09b/emxrt.zip and the RSX
- extender (for running `EMXAOUT' under DPMI) from the RSX archives, e.g.
- ftp://ftp.uni-bielefeld.de/pub/systems/msdos/misc/rsx503rt.zip.
-
- Note that EMXAOUT produces object files in *a.out* format, whose support in
- DJGPP is not as full as that of *COFF*. For example, `ld.exe' (as of
- Binutils 2.7) doesn't support a.out object files inside `.a' libraries, so
- you will have to link them as `.o' files.
-
- 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* badly, 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 can probably also disassemble the code into a source
- form and submit it to `Gas').
-
- *Now* will you consider sticking with DJGPP? *Please??...*
-
- 17.7 What should I do with those "near" and "far" declarations?
- ===============================================================
-
- **Q*: I have this program that I need to port to DJGPP, but it is full of
- pointers and functions declared with the "near" and "far" keywords which GCC
- doesn't grok. What shall I do?*
-
- **Q*: A program written for a 16-bit compiler uses the MK_FP or _MK_FP macro,
- but DJGPP doesn't seem to have it. How should I port it?*
-
- *A* : In DJGPP you use a flat address space with no segmentation, so you
- don't need far pointers in the sense they are used in 16-bit code. Just
- define away those keywords and you will be fine:
-
- #define far
- #define near
- #define huge
- #define _far
- #define _near
- #define _huge
-
- Alternatively, you could add suitable `-D' switches to the GCC command line,
- like this:
-
- gcc -Dfar -Dnear -Dhuge -c myprog.c
-
- Macros that create far pointers from the segment and offset (usually called
- `MK_FP' or `_MK_FP') are mostly used in 16-bit code to access certain
- absolute addresses on memory-mapped peripheral devices, like the video RAM.
- These chores are done differently in DJGPP. Here's one possible way to
- express `MK_FP' in DJGPP (courtesy of Charles Sandmann
- <sandmann@clio.rice.edu>):
-
- #include <sys/nearptr.h>
- #include <crt0.h>
-
- void * MK_FP (unsigned short seg, unsigned short ofs)
- {
- if ( !(_crt0_startup_flags & _CRT0_FLAG_NEARPTR) )
- if (!__djgpp_nearptr_enable ())
- return (void *)0;
- return (void *) (seg*16 + ofs + __djgpp_conventional_base);
- }
-
- The above uses the DJGPP nearptr facility; if you prefer to use farptr
- functions (which are safer and work with all known DPMI hosts), you will need
- to rewrite the code that uses these macros, so don't bother writing a
- replacement for the macro itself. The details are described in Accessing
- absolute addresses in Section 18.4, below.
-
- Macros that extract the segment and the offset from a far pointer (called
- `FP_SEG' and `FP_OFF') are required in 16-bit code to pass addresses in
- registers when calling real-mode DOS or BIOS services, like functions of
- interrupt 21h. See How to call real-mode interrupt functions in Section
- 18.2, which describes how that should be done in DJGPP; here, too, you won't
- need to port the macros but instead rewrite the code that calls the DOS or
- BIOS service.
-
- 17.8 How to convert _AX pseudo-registers?
- =========================================
-
- **Q*: Since DJGPP doesn't recognize Borland-style pseudo-register variables
- like _AX, how should I port code which uses them to DJGPP?*
-
- *A* : These pseudo-variables are typically used in two different contexts:
-
- * When calling real-mode interrupt services.
-
- To port such code to DJGPP, use the fields of the `__dpmi_regs'
- structure (declared on the `dpmi.h' header file) to set the register
- values, and library function `__dpmi_int' to invoke the interrupt
- service. For example, consider the following code snippet:
-
- #include <dos.h>
- void _highcolor (void)
- {
- _AH = 0x10;
- _AL = 0x03;
- _BL = 0;
- geninterrupt (0x10);
- }
-
- (This calls the video BIOS interrupt 10h to allow bright background
- colors to be used instead of blinking characters. DJGPP has a library
- function, called `intensevideo', to do that, but let's assume we have
- reasons not to use it.)
-
- Here's one way to express this in DJGPP:
-
- #include <dpmi.h>
- void _highcolor (void)
- {
- __dpmi_regs r;
-
- r.h.ah = 0x10;
- r.h.al = 0x03;
- r.h.bl = 0;
- __dpmi_int (0x10, &r);
- }
-
- Please read How to call real-mode interrupt functions in Section 18.1,
- elsewhere in this document, for further details on how call real-mode
- services from DJGPP programs.
-
- * Immediately before or after an inline assembly code.
-
- GCC features extensive inline assembly facilities which allow you to
- assign values to, or read values from registers from the inline assembly
- code. See Inline Assembly code with GCC in Section 18.13, for further
- info.
-
- 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 programs
- requires a switch to real mode, so the `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.01/libc_411.html#SEC411. 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.01/libc_208.html#SEC208.
- `__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 (at least 2KB, 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, but it can be made as small as 2KB), 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 to 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 (however, it can never be less than
- 2KB, the size of the stub, because memory used by the stub is reused for the
- transfer buffer).
-
- 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. This stack is locked and is 4KB-long for any
- handling done in protected mode (such as real-mode callbacks), and at least
- 512 bytes in size for interrupts reflected into real mode. This is usually
- enough, but sometimes you'll need to use your own, larger stack, e.g., if you
- expect interrupts to nest, or if your handler needs a lot of stack space.
- (The DPMI spec indicates that you should *not* use the default stack if your
- procedure/interrupt handler uses more that 60 bytes, or 1/8 of the total
- stack space available by default.) In these cases you should point `SS' and
- `SP' to a larger buffer which is in conventional memory (possibly part of the
- transfer buffer).
-
- If `SS:SP' isn't zero, it will be used as the address of the stack for the
- interrupt handler, so if it points to a random location, your program will
- most certainly 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 a user-defined stack, it's
- easier to call the `__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 function 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* : Usually, memory-mapped devices or absolute addresses below 1MB mark are
- outside your program's address space, so you cannot access them directly.
- "Direct access", when you just dereference a pointer, means in DJGPP that you
- use your program's `DS' selector, and all the addresses are offsets relative
- to the base of that selector. So first, you will need a special selector
- that will allow you to access your device or absolute address. There are
- several methods you can get such a selector:
-
- * Use the selector that DJGPP creates for itself to access conventional
- memory. DJGPP makes this selector available to you via the `_dos_ds'
- macro (defined on `<go32.h>' header file). This selector has base
- address of 0 and a limit of 1MB, so you can use it to access any address
- in the conventional memory, but the relatively large limit allows a
- buggy program to overwrite portions of DOS memory. (Original release of
- DJGPP v2.01 makes the limit of `_dos_ds' be 4GB, which effectively
- disables memory protection when you use that selector. However, since
- no memory outside the first 1MB is properly mapped into your program's
- address space without additional DPMI calls, and the DPMI host is then
- free to put memory-mapped devices, such as Weitek I/O space or the
- linear frame buffer of an SVGA, on any address it sees fit, that huge
- limit is an unjustified security hole.) The advantage of `_dos_ds' is
- obviously that you don't have to create it, and that it is good for
- accessing every region in the first MByte range.
-
- * Create your own selector that spans only the region of memory that you
- want to access, and use that selector instead of `_dos_ds'. For
- example, here's a code snippet to set up a selector which provides
- access to 64KB of text-mode video memory at `0xB800:0000', courtesy of
- Bill Currie <bill_currie@blackmagic.tait.co.nz>:
-
- int TxtVRAMSetupSelector (void)
- {
- static char selectorData[8] = {
- 0xff, 0xff, 0x00, 0x80,
- 0x0b, 0xf3, 0x40, 0x00
- };
- int screenSelector = __dpmi_allocate_ldt_descriptors (1);
- if (__dpmi_set_descriptor (screenSelector, selectorData) < 0)
- abort ();
- return screenSelector;
- }
-
- The advantages of this method are that (1) you can set up the selector
- limit such that it only covers the memory region that you need, thus
- protection of the rest of memory is retained; and (2) you may set the
- base address to point to the beginning of the specific memory region you
- need to access, so that you don't have to add the base address for every
- access, making the access faster. For details about the contents of the
- 8-byte selector descriptor, see the documentation of the
- `__dpmi_get_descriptor' function in the library reference Info file.
-
- * Use the DPMI service which creates a selector to access a specific
- real-mode segment address. The DJGPP library has a function
- `__dpmi_segment_to_descriptor' which is a wrapper around that DPMI
- service. It is easier to use than the `__dpmi_set_descriptor' function
- above, since you don't have to mess with the 8-byte descriptor buffer,
- but it always defines a 64KB limit by default. Here is an example of
- code which gets a selector to access 64KB of video RAM beginning at
- `0xA000:0000':
-
- short video = __dpmi_segment_to_descriptor(0xa000);
-
- Note that descriptors created by this function should never be modified
- or freed. For this reason, you should use this function sparingly. For
- instance, if your program needs to examine various real mode addresses
- using the same selector, you should allocate a descriptor and change the
- base using the `__dpmi_set_segment_base_address' library function
- instead of using `__dpmi_segment_to_descriptor' to allocate separate
- descriptor for each address.
-
- Once you have a selector, you can use one of three methods to access your
- absolute addresses using that selector:
-
- * 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 `<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'
- or any other 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 the 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 you to 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 (they use `_dos_ds' internally).
-
- 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 to selectors other than `_dos_ds' (e.g., created by
- one of the methods explained above), use the `movedata' library
- function. It requires that you pass a selector and an offset for both
- the conventional memory address and for the buffer in your program's
- address space. Use the `_my_ds' function (note that it's a *function*,
- not a variable!) to get the selector of any variable in your program,
- and use the address of the variable (cast to an `int') as its "offset"
- or linear address. `movedata' is fast because it moves by 32-bit longs,
- but be careful with its use when moving data to and from peripheral
- cards: some 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 example, here is a code snippet that combines one of the methods for
- allocating a descriptor for video RAM access with a call to `movedata'
- to move a buffer to the graphics screen:
-
- short video = __dpmi_segment_to_descriptor(0xa000);
- movedata(_my_ds(), buffer, video, 0, 320*200);
-
- * For the fastest access to memory outside your usual address space, you
- might consider using the "nearptr" functions declared on the
- `<sys/nearptr.h>' header; see the 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.
- Linux's DOSEmu and Win/NT won't allow you to set such a huge limit on the
- memory segment, because these operating systems take memory protection
- seriously; in these cases `__djgpp_nearptr_enable' will return zero--a sign
- of a failure. CWSDPMI, QDPMI, Win 3.x and Win 9x all allow this technique
- (OS/2 Warp seems to allow it too, at least as of version 8.200), but some
- events break this scheme even for those DPMI hosts which will allow it. A
- call to `malloc' or any other library function which calls `sbrk' might
- sometimes change the base address of the `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 a result of some
- other events external to the executing code thread, like multitasking or
- debugger execution.
-
- You should also know that the `__djgpp_nearptr_enable' function in DJGPP v2.0
- didn't verify that the limit was properly set. So if the DPMI server would
- fail the call *silently*, the function won't detect it and will not return a
- failure indication. DJGPP v2.01 corrects this omission by always verifying
- that the DPMI host has honored the request, and returns a failure indication
- if it hasn't.
-
- 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.01/libc_122.html#SEC122.
-
- Another possibility is to use the DPMI function `0x508' that can map any
- range of physical memory addresses into a block that you allocate. Note that
- this is a DPMI 1.0 functionality which is *not* supported by most DPMI 0.9
- hosts (`CWSDPMI' does support it). There is a helper function
- `__djgpp_map_physical_memory' in the DJGPP C library that you can use to call
- these services.
-
- 18.7 Accessing absolute address above 1MB
- =========================================
-
- **Q*: How can I access memory-mapped peripheral devices (or any other
- absolute address) above 1 MByte mark?*
-
- *A* : You should use DPMI functions to allocate an LDT descriptor, and map
- it to an absolute physical address. You can then use the functions from
- <sys/farptr.h> to access that linear address. 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 a user-defined handler when
- certain events occur, which expects a far pointer to my function in the
- `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.' Here's a code fragment that shows
- how to do this:
-
-
- #include <dpmi.h>
- #include <go32.h>
-
- static __dpmi_regs callback_regs;
- static _go32_dpmi_seginfo callback_info;
-
- int install_mouse_handler (unsigned mask,
- void (*func)(__dpmi_regs *))
- {
- __dpmi_regs r;
-
- callback_info.pm_offset = (long)func;
- if (_go32_dpmi_allocate_real_mode_callback_retf(&callback_info,
- &callback_regs))
- return -1; /* failure */
-
- r.x.ax = 0xc;
- r.x.cx = mask;
- __dpmi_int (0x33, &r);
- return (r.x.flags & 1) ? -1 : 0;
- }
-
- The handler (`func' in the above example) will be called with a pointer to a
- `__dpmi_regs' structure which is filled by values found in the CPU registers
- when the mouse driver calls the handler. See the docs in the library
- reference Info file for further details about allocating wrapper functions.
-
- 18.9 How to hook hardware interrupts
- ====================================
-
- **Q*: How do I register my DJGPP function as a hardware interrupt handler?*
-
- *A* : The optimal setup 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 caught by the DPMI host and passed to protected mode first;
- only if unhandled, they are then 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 should consider installing a real-mode
- interrupt handler in addition to the protected-mode one. Such a real-mode
- handler will be called *before* the interrupt gets to the DPMI host, and
- handle the interrupt entirely in real mode, so it must be written in assembly
- and located in conventional memory (below the 1MB mark). If you need to hook
- an interrupt with both PM and RM handlers, 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 in the `pm_offset' field and the value of `_my_cs'
- in the `pm_selector' 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'
- code and data 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 not to page (i.e., only the physical
- memory is used). You might consider disabling virtual memory to make
- sure your program doesn't page. To accomplish this, either set the
- `_CRT0_FLAG_LOCK_MEMORY' bit in the `_crt0_startup_flags' variable, or
- use `CWSDPR0' or `PMODE/DJ' as your DPMI host. In fact, using one of
- these methods is the recommended way of debugging the first versions of
- a program that hooks hardware interrupts; only after you are sure that
- your basic machinery works should you move to testing it in a setup when
- paging might happen.
-
- Note that `_CRT0_FLAG_LOCK_MEMORY' is only recommended for small
- programs that run on a machine where enough physical memory is always
- available, because the startup code currently doesn't test if memory is
- indeed locked, and you can end up with unlocked, or partially unlocked
- memory, which will crash your program.
-
- 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 the `dosmemput' function. (You
- could also call one of the functions which allocate a 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
- sample code written by Bill Currie <bill_currie@MAIL.TAIT.CO.NZ>, the Sound
- Blaster interrupt-driven functions, the `mkkbd' package, and the `libhw'
- library, described under sample DJGPP packages in Section 22.2. Alaric B.
- Williams <alaric@abwillms.demon.co.uk> has written a tutorial on DJGPP
- interrupt handling, at this URL:
-
- http://www.abwillms.demon.co.uk/prog/djints.txt
-
- 18.10 Should I use _go32_XXX or __dpmi_YYY functions?
- =====================================================
-
- **Q*: In v1.x I was used to the `_go32_...' functions, but now comes v2 which
- also has `__dpmi_...' functions. Are there any differences between these two
- varieties?*
-
- **Q*: Do I need to convert my old v1.x code to use the new `__dpmi_...'
- functions?*
-
- *A* : These two groups of functions have different functionality, so don't
- just substitute the new ones for the older ones, because it usually won't
- work! The new `__dpmi_...' functions are just bare-bones wrappers of the
- DPMI API calls (see DPMI Specification in Section 22.4), generally unsuitable
- for use with handlers written in C, whereas the old `_go32_...' functions are
- intelligent helper functions which only make sense if your interrupt handlers
- are C functions. The problem with the `_go32_...' functions is that they
- don't lock all the code and data they (and your handlers) use, so they can
- crash on memory-tight machines and thus aren't suitable for
- production-quality code. But they are certainly useful in the initial stages
- of writing and debugging code that hooks hardware interrupts, and for
- migrating existing v1.x code to v2. Some of the old names were just
- `#define'd' to the new names where the functionality is identical.
-
- The bottom line is that it shouldn't be necessary to convert your code for it
- to work at least as well as it did in v1.x; but if you want it to be more
- stable, you should rewrite your handlers in assembly and use the new
- `__dpmi_...' functions (see How to install a hardware interrupt handler in
- Section 18.9).
-
- 18.11 Hardware interrupt hooking has its subtleties ...
- =======================================================
-
- **Q*: I did all the above, but my program occasionally still hangs...*
-
- *A* : Hooking hardware interrupts in DJGPP (and in protected mode in
- general) has a few subtle aspects. In general, hardware interrupt handling
- in DJGPP v2.x 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 systems).
-
- 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 many
- 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
- the interrupt handler to some other place. Use a ring 0 DPMI server such as
- `CWSDPR0' or `PMODE/DJ' which don't swap interrupt stacks--this will reduce
- the overhead of the interrupt reflection to some degree. 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, if the `_CRT0_FLAG_UNIX_SBRK' bit in the
- `_crt0_startup_flags' variable is 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.
-
- You should also keep in mind that the DPMI server can decide to handle some
- of the interrupts itself and not pass them to your program, although this is
- rare. For example, Win95 won't pass the Ctrl-Alt-Del combination to your
- keyboard interrupt handler, but will rather act on it itself; QDPMI sometimes
- processes Ctrl-C presses so that your program never sees them, etc.
- Sometimes, but not always, you can change some configuration option to make
- some keys get to your handler (e.g., the Alt-TAB setting on the Win3.x `.PIF'
- file).
-
- If the above still doesn't explain your problem, then post your code on
- comp.os.msdos.djgpp news group or the djgpp mailing list <djgpp@delorie.com>,
- tell there how it fails and somebody will usually have a solution or a
- work-around for you.
-
- 18.12 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.
-
- 18.13 Inline Assembly code with GCC
- ===================================
-
- **Q*: I am used to writing inline assembly with Borland C, but can't figure
- out the way to do it with GCC...*
-
- **Q*: How can I reference C variables from my inline assembly code?*
-
- *A* : GCC has extensive inline assembly facilities. They allow you to
- specify everything other compilers let you (like the registers where GCC will
- put specific results), but in a way that doesn't disable compiler
- optimizations of the C code that includes inline assembly. Because of this
- flexibility, the syntax of the inline assembly code is very different from
- the other DOS-based compilers. The GCC on-line docs describe these
- facilities in detail; to read the relevant sections, type this from the DOS
- prompt:
-
- info gcc "C Extensions" "Extended Asm"
-
- (Note the quotes: they are important.) You will, of course, need that the
- stand-alone info reader be installed on your system for the above command to
- work. If it is not already installed, get the file `txi390b.zip' from the
- DJGPP distribution and install it.
-
- If you read this FAQ via WWW, you can also read about the GCC inline assembly
- extensions with your Web browser, at this URL:
-
- http://www.delorie.com/gnu/docs/gcc/gcc_86.html#SEC89
-
- 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 about any legal restrictions
- when you compile your programs with DJGPP. Using the GNU C/C++ compiler
- 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 any
- 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') and the Standard
- Template Library (`libstdcx.a') which come with DJGPP allow you to use them
- 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). Only the library
- of additional C++ classes (`libgpp.a') 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.)
-
- 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
- are not as powerful, but are free from any restrictions).
-
- 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.
-
- Note that the above says nothing about the legal aspects of contributed
- packages, like `GRX' and others; you will need to read their docs to find out.
-
- 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 include 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 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 that you follow these rules:
-
- * You must redistribute DJGPP as a whole, with all its parts, including
- the sources to utilities and libraries that are part of DJGPP, unless
- other arrangements are first made with DJ Delorie <dj@delorie.com>.
-
- * Please make a good faith effort to stay up to date with the latest DJGPP
- versions, so people don't get old versions with bugs that are long ago
- solved, or, worse still, versions that are no longer supported.
-
- * 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 News groups
- ==========================================================
-
- **Q*: I post my problem to the "help-gcc" News group, but don't get any
- answers.*
-
- *A* : Is your problem likely to be special to the DJGPP port or to the DOS
- environment? If so, don't post to GNU Usenet groups, but to the
- comp.os.msdos.djgpp news group or to the DJGPP mailing list
- <djgpp@delorie.com>. People who read GNU News groups usually neither know
- nor care about DOS-specific problems. Post there only if the problem seems
- to be generic to 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 the 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 news
- group, 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 the 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
- the `djgpp-announce' by sending message to the list server
- <listserv@delorie.com> which says so:
-
- subscribe <your e-mail address> djgpp-announce
-
- The announcements which go to `djgpp-announce' get reflected to `djgpp', so
- you don't need 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
-
- Note that some mailers reject messages with too large size, so you might have
- trouble with the weekly digest. If you subscribe to it and don't get the
- digest, try the daily one instead, or switch to another mail software.
-
- 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 the 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 news
- group instead of subscribing to the mailing list, so that the load on DJ's
- list server will get lower. There is also a possibility of reading the news
- group (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 the 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
-
- When you unsubscribe, that stops *new* messages from being sent to you.
- Messages that are already in the mail queues of various mail programs between
- the DJGPP list server and the machine where you receive your mail--cannot be
- stopped. Therefore, allow some time before you decide that your unsubscribe
- message didn't work. In extreme cases, when one of the machines that are
- forwarding mail to you is down, you can get the messages upto 5 days after
- you've unsubscribed.
-
- If you think you have waited enough and the messages still keep coming, write
- to listserv administrator <djgpp-request@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
-
- Recently, DJ has added a mail archive browser to his Web site. With this
- tool, you can list and read the messages by year, month and day, as well as
- search the last few days for something you might have missed. This service
- is available via World-Wide Web, at this URL:
-
- http://www.delorie.com/djgpp/mail-archives/browse.cgi
-
- 20.5 If you don't see any message from the list ...
- ===================================================
-
- **Q*: I don't get any messages from the 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). Also, if your address begins
- to fail consistently (like "user unknown" or "unknown host"), DJ Delorie
- removes that address from the list, but cannot send a message to this effect,
- for obvious reasons. 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 hurts neither you, nor the list
- server).
-
- If you subscribe to the weekly digest, then the problem might be that your
- mailer rejects the huge message size. Try the daily digest, or switch to
- another mailer, and see if that helps.
-
- 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 have also 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 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 problem is caused by excessive load on the list
- server, so everybody who can please switch to reading the comp.os.msdos.djgpp
- news group and unsubscribe from the list.
-
- 20.7 DJGPP now has a news group!
- ================================
-
- **Q*: With so much daily traffic (about 30 messages a day), isn't it high
- time to create a Usenet News group?*
-
- *A* : Beginning June 1st, 1995, DJGPP *has* its News group! It is called
- *comp.os.msdos.djgpp*, and it is two-way gated to the venerable DJGPP mailing
- list. This means messages posted to either the mailing list or the news
- group will appear on both (once, let's hope ;-); you can read either one and
- post to either one, and everybody 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 news group instead, so that the load
- on the list server will get lower.
-
- 21. Version 2 vs v1.x
- *********************
-
- This chapter is for those who are used to working with DJGPP v1.x and want to
- know more about v2 while they consider switching.
-
- 21.1 New features in DJGPP v2
- =============================
-
- **Q*: What exciting new features will I find in v2 as opposed to v1.x?*
-
- *A* : DJGPP v2.x is a DPMI-only environment, and it includes a free DPMI
- host for those who don't have another DPMI provider installed. In addition,
- v2 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 Windows;
-
- * fixes of many bugs in hardware interrupts' and mixed-mode programming
- support;
-
- * support of long filenames on Windows 95;
-
- * 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 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.x
- ==============================
-
- **Q*: There's been this talk about v2 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, a minority 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
- 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 is 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 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 `djlsr201.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:
-
- `em1934s1.zip'
- `em1934s2.zip'
- `em1934s3.zip'
- All sources are shipped in ready-to-build form. Any diffs that come with the
- source distribution, like the files in the `diffs/' directory, have already
- been applied, and any configuration scripts and/or batch files have been run.
-
- 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 standard here is that different packages were ported to DJGPP by
- different people, as best as they saw fit.) After you've successfully built
- the program, make your fixes and build the program the same way you did
- before.
-
- Note that generally to build these programs, you must have the GNU Make
- program, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/mak375b.zip, and some
- makefiles require that you install additional utilities, like Sed
- ftp.simtel.net/pub/simtelnet/gnu/djgpp/sed118b.zip, e.g. ftp://. Sometimes
- the makefiles won't even run under `COMMAND.COM' (they require a smarter
- shell). In that case, either get a better shell, or 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. The port of
- Make 3.75 and later can be built so that it doesn't issue FP instructions,
- but you will have to get the sources and recompile Make first, as the stock
- version wasn't configured in that way.
-
- If you think that you found a bug in one of the programs or libraries written
- for DJGPP (e.g. the C library, CWSDPMI, symify, etc.) be sure to check the
- list of known bugs, at this URL:
-
- http://www.delorie.com/djgpp/doc/kb/kb_7.html#SEC4
-
- If your bug is not there, you can later submit it to the bug-tracking system,
- at this URL:
-
- http://www.delorie.com/djgpp/bugs/
-
- Before you submit a bug report, please make every effort to verify that your
- bug is not caused by incorrect usage, or by problems in your DJGPP
- installation. Reports such as "All DJGPP programs crash" or "I cannot
- compile any program" are clearly not bugs, because these things work for many
- hundreds of DJGPP users every day. If you can investigate the cause of the
- bug and find a solution that makes it go away, submit a bug report with all
- the details. If you cannot find the cause(s), I suggest posting your problem
- description to the news group and asking people to verify that it is indeed a
- bug, before you submit a bug report. The bug-tracking system includes a list
- of all known bugs, many of them with solutions or work-arounds; please check
- them before creating a new bug report.
-
- 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 it 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 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:
-
- - Alaric B. Williams <alaric@abwillms.demon.co.uk> maintains a
- library of utility functions and example handlers, useful for
- writing hardware interrupt handling code. You can get Alaric's
- library with your Web browser, at this URL:
-
- http://www.abwillms.demon.co.uk/prog/index.html
-
- - Bill Currie <bill_currie@MAIL.TAIT.CO.NZ> has written sample code
- for hardware interrupt handlers, e.g.
-
-
-
-
- ftp://ftp.delorie.com/pub/djgpp/contrib/sample-interrupt-handlers-v2.zip
- which should get you off the ground if you need to write your own
- handlers.
-
- - Martynas Kunigelis <martynas.kunigelis@vm.ktu.lt> donated a
- tutorial and a working code that installs a keyboard interrupt
- handler, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/mkkbd3.zip that
- can also serve as a good example of a hardware interrupt handler.
-
- - 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/Coast/msdos/c/pctime13.zip.
-
- - if you need a serial communications library, check out SVAsync,
- e.g. ftp://ftp.delorie.com/pub/djgpp/contrib/svasync.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.)
-
- - a port of WATTCP library, e.g.
- ftp://ftp.msen.com/pub/vendor/snsi/wattcp/gnu-c/.
-
- - a modified port of WATTCP library done by DJ Delorie
- <dj@delorie.com> is available from DJ's server, e.g.
- ftp://ftp.delorie.com/pub/djgpp/dj/.
-
- * Port of curses library to DJGPP:
-
- - download PDCurses package, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/pdc22.zip.
-
- * Dynamically loaded code:
-
- - Check out the DLM (Dynamic Link Modules) environment for DJGPP,
- written by "Ilya P. Ryzhenkov" <ilya@spy.isp.nsc.ru>, available from
- his machine, e.g. ftp://spy.isp.nsc.ru/sys/pub/dlm/.
-
- * 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 was developed by Antonio Costa <acc@asterix.inescn.pt> for
- DJGPP v1.x. It is also available on an alternative site, e.g.
- ftp://groucho.idt-isep.ipp.pt/pub/pc/djgpp/etc/X/ and on the DJGPP
- server, e.g. ftp://ftp.delorie.com/pub/djgpp/contrib/Xlibemu/.
-
- - the Xlib and Xt for DV/X environment, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v1tk/qddvx102.zip (you
- will also need qdlib102.zip and qdtkt102.zip from the same site).
-
- * Ports of various GNU utilities not included in DJGPP:
-
- - Many of these are now part of DJGPP, so first look on SimTel.NET
- mirrors with the rest of DJGPP, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/.
-
- - 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/.
-
- * GUI libraries:
-
- - SWORD (the System of Windows for the ORganization of the Desktop)
- is a Graphic User Interface library made with C++ objects, written
- and maintained by Eric Nicolas <nicolas@JUPITER.saclay.cea.fr>. The
- latest version 2.1 is available from the DJGPP v2tk subdirectory,
- e.g. ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/ as
- sw21_*.zip.
-
- - check out the BCGUI package, at this URL:
-
- http://www.delorie.com/djgpp/dl/contrib/
-
- or get BCGUI via FTP, e.g.
- ftp://ftp.delorie.com/pub/djgpp/contrib/bcguiNNN.zip or get 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
-
- - Another port of Turbo Vision library was done by Robert Hoehne
- <Robert.Hoehne@Mathematik.TU-Chemnitz.DE>, and can be downloaded
- via WWW, at this URL:
-
- http://www.tu-chemnitz.de/~rho/tvision.html
-
- , and also from the DJGPP distribution sites, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/tvisionb.zip
-
- * 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>. This library is
- best suited to multi-platform game programming, since it's portable
- to Linux.
-
- - Also see the Allegro game programming library, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk/alleg211.zip,
- written by Shawn Hargreaves <Shawn@talula.demon.co.uk>. It is also
- available from the Allegro home page, at this URL:
-
- http://www.talula.demon.co.uk/allegro/
-
- This library is best suited to DOS game programming.
-
- * 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.
-
- * Multi-tasking libraries:
-
- - The POSIX Pthreads library, e.g.
- ftp://ftp.cs.fsu.edu/pub/PART/PTHREADS/pthreads.zip is a portable,
- standard package supported on many platforms.
-
- 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 program's stub info block and 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].'
-
- If you use the DJGPP port of GNU Fileutils 3.13 or later, the `ln' program
- there can do the above steps for you if you say this (like on Unix):
-
- ln -s dj1.exe dj2.exe
-
- 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 the 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 `dpmip1.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.simtel.net/pub/simtelnet/msdos/info/inter53c.zip. Look at the
- functions of Interrupt 31h, or search the files for the word `DPMI.'
-
- You can also browse the DPMI spec on-line, at this URL:
-
- http://www.delorie.com/djgpp/doc/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 and news group traffic, plus
- other useful and interesting information about DJGPP. For instance, did you
- ever wonder how DJGPP got started and what DJ's original goals were?
- 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 news group 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.
-
- If you decide to upload, please send mail to the `djgpp-announce' list with a
- brief description of your program/patch. (The message will get reflected to
- both the news group 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 want to get such announcements and nothing
- else.)
-
- If your program is more than a patch or a beta version, you might consider
- uploading it to the DJGPP archives on SimTel.NET. 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.NET mirrors throughout the world, which makes it easier to get.
-
- DJ Delorie requests that all contributed packages uploaded to his server be
- source-only distributions; don't bother to include libraries or pre-compiled
- binaries, since DJ deletes them when he opens the zip archive. This is so
- there will be no danger of distributing programs infected by a virus (as
- there are no 32-bit virus-scanners yet). Please avoid uploading
- self-extracting archives because DJ extracts them on a Unix machine which
- can't run DOS executables.
-
- 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 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. This package is reportedly no longer
- supported, but if you have questions about it, you can send them to Jim
- Karpinski <jk55@cornell.edu>. You can also try to contact Kai Ruottu
- <karuottu@freenet.hut.fi>, who is the provider of DOS-hosed gcc-m68k.
-
- An "RPM" (Redhat Package Maintenance) distribution of the Linux to DOS
- cross-compiler is available, which is based on DJGPP v2.01 and includes
- everything you need to create DJGPP binaries on Linux (without running
- DOSEmu). This package has been built by James Soutter <cgjks1@lut.ac.uk>
- using the instructions below; you will need Linux and RPM 2.2.7. The RPM
- packaged cross-compiler is available from Redhat site, e.g.
- ftp://ftp.redhat.com/pub/incoming/djgpp-2.1-1.i386.rpm; the sources are also
- available, e.g. ftp://ftp.redhat.com/pub/incoming/djgpp-2.1-1/src.rpm.
-
- 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.)
-
- First, use the original FSF distributions for Gcc and Binutils, not the
- source distributions from DJGPP. That's because the DJGPP archives have
- sources patched to compile on MS-DOS and sometimes omit files that aren't
- necessary for DJGPP. In particular the GCC sources lack many files that the
- MS-DOS build doesn't need, to conserve space.
-
- 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-binutils
- cd X/dos-binutils
- configure --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
- cp ld.new /usr/local/i386-go32-msdos/bin/ld
-
- cd ../../..
- mkdir X/dos-gcc
- cd X/dos-gcc
- configure --target=i386-go32-msdos
- # Note: this produces errors building libgcc.a. Ignore them.
- # The libraries will come from the cross-compiler kit.
- 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, or get it from the `djcrx200.zip' archive.
-
- 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.' You
- might need to insert these two lines at the beginning of `stubify.c':
-
- `#include <sys/types.h>'
- `#include <unistd.h>'
-
- 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?*
-
- **Q*: I have a program that reads struct contents from a binary file. It
- works OK when compiled with BC, but reads garbage when compiled with DJGPP.
- This must be a bug in DJGPP, right?*
-
- *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 dword 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 the sizes of its fields. If you need to minimize 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:(Note that this still allows the struct to be padded at the end,
- though.)
-
- 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 a 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 with 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).
- Alternatively, you could declare any single structure to be packed, like so:
-
- struct {
- char name[7];
- unsigned long offset;
- double quality;
- } __attribute__ ((packed));
-
- However, note that the latter will only work when you compile it as a C
- source; C++ doesn't allow such syntax, and you will have to fall back to
- declaring each struct field with the packed attribute. Therefore, it's best
- to only use declarations such as above if you are *certain* it won't be ever
- compiled as a C++ source.
-
- The padding of struct fields should be considered when you read or write
- struct content from or to a disk file. In general, this should only be done
- if the file is read and written by the same program, because the exact layout
- of the struct fields depends on some subtle aspects of code generation and
- the compiler switches used, and these may differ between programs, even if
- they were compiled by the same compiler on the same system. If you do need
- this method, be aware of the struct field padding and don't assume that the
- number of the file bytes that the structure uses is equal to the sum of the
- fields' sizes, even if you instructed the compiler to pack structs: GCC still
- can add some padding after the last field. So always use `sizeof struct foo'
- to read and write a structure.
-
- Another problem with porting programs that read structs from binary files is
- that the size of some data types might be different under different
- compilers. Specifically, an `int' is 16-bit wide in most DOS-based
- compilers, but in DJGPP it's 32-bit wide.
-
- The best, most robust and portable way to read and write structs is through a
- `char' buffer, which your code then uses to move the contents into or out of
- the struct fields, one by one. This way, you always know what you are doing
- and your program will not break down if the padding rules change one day, or
- if you port it to another OS/compiler. The ANSI-standard `offsetof' macro
- comes in handy in many such cases.
-
- 22.10 C++ doesn't pack structs!
- ===============================
-
- **Q*: When I use `struct ffblk' from the header `dir.h' in a C++ program, I
- get garbage in some fields of the structure!*
-
- *A* : There is a known bug in GCC 2.7.2: the C++ compiler effectively
- ignores the `__attribute__((packed))' directives, so the structures end up
- being not packed. DJGPP v2.01 comes with GCC 2.7.2.1 which corrected that
- bug, so upgrade. As a work-around, surround the declaration of the structure
- that needs to be packed with `#pragma pack', like this:
-
- #ifdef __cplusplus
- #pragma pack(1)
- #endif
- .
- .
- .
- #ifdef __cplusplus
- #pragma pack()
- #endif
-
- 22.11 How to avoid "Abort, Retry, Fail" messages
- ================================================
-
- **Q*: How do I write a program that accesses floppy and CD-ROM drives, but
- avoids popping that "Abort, Retry, Fail?" message from DOS?*
-
- **Q*: Other DOS compilers supply a function named `harderr' or `_harderr' to
- hook the critical-error interrupt 24h, but DJGPP doesn't seem to have
- these...*
-
- *A* : Under DPMI, Int 24h is always hooked by the DPMI server, since Int 24h
- is issued by the real-mode DOS code, and it is not possible to terminate a
- DPMI client (like DJGPP program) from real mode, if you press `A' in response
- to that prompt. The default handler under most DPMI servers will just set
- `AL' register to 3 and do an `IRET', thus silently failing the DOS call that
- triggered Int 24h. The DJGPP startup code also hooks the protected-mode Int
- 24h with a handler that fails the DOS call as described above. So in most
- circumstances you won't see that DOS prompt at all; your program will just
- see a failed DOS call.
-
- However, some DPMI hosts (notably, QDPMI), will sometimes crash your program
- if it generates Int 24h, for instance when you access an empty floppy drive.
- In such cases, or when the default action of failing the DOS call is not good
- enough, you will have to hook Int 24h with your handler. This should be done
- in exactly the same manner as hooking hardware interrupts (see how to set an
- interrupt handler in Section 18.9), because Int 24h is one of the few
- software interrupts that, like all hardware interrupts, are always reflected
- to the protected-mode handler first. Note that `CWSDPMI' currently doesn't
- support hooking Int 24h; if you set an interrupt handler, it won't be called.
-
- There are ways to avoid program crashes due to Int 24h (under those DPMI
- hosts that exhibit this buggy behavior) other than to install a handler for
- it. For instance, you can test if the floppy drive is empty with a BIOS call
- before accessing it with DOS functions; there are also similar ways to check
- if a CD-ROM drive is empty. The library function `getmntent' (See getmntent
- in "libc.a reference", or point your Web browser to
- http://www.delorie.com/djgpp/doc/libc-2.01/libc_337.html#SEC337.) can be used
- to detect all the drives that can be safely accessed by DOS; or you can
- borrow some of the internal functions used by `getmntent' from the library
- source distribution, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/djlsr201.zip.
-
- 22.12 What is that `go32-v2.exe' program?
- =========================================
-
- **Q*: What is go32-v2 for?*
-
- *A* : The `go32-v2' program does the following:
-
- * With no command-line arguments, it prints the available physical and
- virtual memory, much like `go32' did in v1.x.
-
- * It can run unstubified v2 COFF images, like this:
-
- go32-v2 myprog
-
- * If you rename it to `go32.exe' and put on your `PATH' before the v1.x
- `go32.exe', it can also run a v1 COFF images, by loading the v1.x `go32'
- and letting it do the job. With this setup, you can run v2 programs
- from v1.x programs, because the v1.x program will load `go32-v2' (since
- it found it first on the PATH) which knows how to run v2 images, instead
- the original `go32' which cannot.
-
- 22.13 What is DXE?
- ==================
-
- **Q*: What is DXE?*
-
- **Q*: Can I make a DLL using the DXE support?*
-
- **Q*: Where can I find information or examples about writing/loading the DXE
- files?*
-
- *A* : DXE is a limited facility to dynamically load code which is rarely
- needed in DJGPP. An example is the floating-point emulator code (see the
- details of DJGPP FP emulator in Section 11.1) which is only used on those few
- machines that lack an FPU. The DXE design is intentionally limited to keep
- it as simple as possible, so that the code that loads a DXE could be small
- (it's a few hundreds bytes). Because of this, there are a number of
- limitations in the DXE mechanism that prevent using it for full-fledged
- dynamic linking (i.e., a DLL). For instance, the DXE module cannot access
- variables or functions in the main module. Unloading a DXE is also not
- supported (but I'm told you can add this by making afew simple changes in the
- C library).
-
- The only place you can find some docs and examples of writing and using a DXE
- is in the file `djtst201.zip' in the DJGPP "tests" distribution, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/djtst201.zip. The example
- there is *exceedingly* simplistic, but then so is the entire DXE mechanism...
-
- 22.14 Long Filenames Don't Work!
- ================================
-
- **Q*: I cannot make Info find some of its files under Win95...*
-
- **Q*: Why does Make behave as if some of the files were not there?*
-
- *A* : Are you running DJGPP v2.0 on Win95 with long filename support enabled
- (LFN=y in the environment)? If so, set LFN=n from the DOS prompt and try
- again. If the problems go away, they are probably due to known bugs in some
- v2.0 programs wrt the LFN support. Make and Info which came with DJGPP v2.0
- are two programs which are known to reveal these bugs. Before you decide
- that you are a victim of these bugs, though, make sure that all the files
- that your programs need to access have been renamed to their long names. For
- example, if Make needs to find a file called `ALongFileName.cc' (because the
- Makefile tells it to build `ALongFileName.o'), make sure there indeed is such
- a file in the directory. Sometimes people use archive tools (like `PKZIP')
- that truncate long names, even on Win95, when they open an archive, which
- leaves you with names like `alongfil.cc', which is not the same as the
- original name when LFN is supported. Be sure to use archivers that support
- long filenames, e.g. use `DJTAR' when you open `.tar.gz' archives, or rename
- all the files to their original long names after you open the archive.
-
- If the problems persist even though the filenames are correct, upgrade to
- DJGPP v2.01 or later, where all programs should support long filenames
- properly. If you cannot upgrade, you will have to disable LFN support (set
- LFN=n from the DOS prompt, setting it in `DJGPP.ENV' does not always work in
- DJGPP v2.0).
-
- 22.15 Make says "missing separator"
- ===================================
-
- **Q*: When I invoke Make, it refuses to do anything and prints this cryptic
- message:*
-
- makefile:10: *** missing separator. Stop.
-
- *Now what kind of excuse is that?*
-
- *A* : Unlike most other DOS Make programs which accept any whitespace
- character at the beginning of a command in a rule, GNU Make insists that
- every such line begins with a TAB. (Most other Unix Make programs also
- require TABs.) Make sure that the line whose number is printed in the error
- message (in this case, line 10) begins with a TAB.
-
- There are editors that replace TABs with spaces, so even a Makefile that used
- to work can become unworkable if you edit them with such an editor.
-
- Another, more rare, cause of the above error message is if you use static
- pattern rules (with the `%' character) incorrectly. Read the documentation
- that comes with Make carefully and try to find the error.
-
- 22.16 What is in that `zoneinfo' directory?
- ===========================================
-
- **Q*: When I installed DJGPP v2, it created a directory named `zoneinfo' with
- a lot of small files that take up 3.5MB of my disk space. What are they for?
- Can I delete them?*
-
- *A* : These files exist so that time-related library functions can correctly
- calculate the offset between the local time and the "UTC" (Universal
- Coordinated Time). This offset is required when you get files from another
- time-zone, like from the Internet, or when you download an archive that was
- compressed in another time-zone. If you don't care about file time stamps
- being incorrect in such cases, you can delete all those files and never look
- back.
-
- You might wonder why we need all these zoneinfo files when the UTC offset
- *is* required. Well, the simplest way to tell programs what the UTC offset
- is, is to have the user specify a single number which is the offset; but then
- this number needs to be changed twice a year, to accommodate for the daylight
- saving time. Another, not-quite-so-simple way is to have the user specify
- the current UTC offset and the DST rules; but this is a tedious and
- error-prone process, and many users get it wrong. Both of these methods have
- the drawback that if the rules change, programs misinterpret old time-stamps,
- since they treat them according to new rules. Using a table that is read from
- a file and includes the offset calculation rules for every year avoids all
- these problems and requires the user to point the `TZ' environment variable
- to the file that is pertinent to his/her time zone, which is easy:
-
- set TZ=c:/djgpp/zoneinfo/israel
-
- *or*
-
- set TZ=c:/djgpp/zoneinfo/us/alaska
-
- To find the rule suitable for your location, look into the `src' subdirectory
- of `zoneinfo' and browse the file whose name is your continent/part of the
- world. If no binary file exists with the name of your zone, you can create
- one with using the time-zone compiler `zic', whose source is also in the
- `src' subdirectory.
-
- A public domain time-zone database exists, and is updated from time to time
- with the latest world-wide changes to the offset calculation rules. (The
- rules change because politicians in different countries make laws that change
- the local clock settings.) The contents of the `zoneinfo' directory which
- comes with DJGPP is based on this database, but if you want the latest rules,
- you can download them from the net, e.g. ftp://elsie.nci.nih.gov/pub/ as
- `tzdata*.tar.gz'; `tzcode*.tar.gz' in the same directory includes the
- programs that can be used to generate the offset tables from their source in
- `tzdata*.tar.gz', the latest implementations of POSIX library functions that
- use time-zone information, and the man pages that document the rules and the
- software. The last update as of this writing was in May 1996.
-
- On any single machine, you don't need more than a single file from that
- directory, which is the file for your time zone; once you find that file, you
- can safely delete the rest. But if you distribute a program that uses the TZ
- setting, you will have to include all of the files, or tell your users how to
- get and install them.
-
- 22.17 Generating the FAQ in your favorite format
- ================================================
-
- **Q*: How can I generate the FAQ list in a format I'm used to?*
-
- *A* : First, you need to get the FAQ sources. The sources of the latest
- version of this FAQ list can always be found as `faqNNNs.zip' on DJ Delorie's
- server, e.g. ftp://ftp.delorie.com/pub/djgpp/v2faq/faq210s.zip and on
- SimTel.NET mirrors, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/faq210s.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
- `faqNNNb.zip' from DJ Delorie's server, e.g.
- ftp://ftp.delorie.com/pub/djgpp/v2faq/faq210b.zip or from SimTel.NET mirrors,
- e.g. ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/faq210b.zip. Currently,
- this includes the Info version, the text (ASCII) version and an HTML version
- as a single large `.html' file. More formats will be available as the tools
- for their generation are developed/tested.
-
- If none of these formats is good enough for you, here are some tools
- available to generate the FAQ list in other formats. If you know about any
- format not mentioned below that can be generated using widely available
- tools, please drop me a note so I could update this list and consider that
- format or those tools for inclusion in a future release of the FAQ. If you
- develop any such tools, consider uploading them to a site where they will be
- publicly available, and tell me about that site.
-
- Note that the FAQ source is a heavy user of the Texinfo macro facility, so
- any conversion program that doesn't support Texinfo macros will probably have
- hard time coping with the FAQ. When confronted with this problem try feeding
- the converter with the macro-expanded version of the FAQ (the Makefile in the
- source distribution has a special target for such cases).
-
- A program called `Makertf' can reportedly be used to convert a Texinfo
- sources of this FAQ to the "Rich File Format" which can then either be
- browsed by an RTF browser (such as Adobe Acrobat) or converted into a Windows
- Help file with a Windows Help compiler. `Makertf' is available from CCT
- mirrors, e.g. ftp://ftp.coast.net/Coast/win3/winhelp/mkrtf104.zip. The
- Windows Help Compiler is available via anonymous ftp from the Microsoft ftp
- site, e.g. ftp://ftp.microsoft.com/Softlib/MSFILES/HC305.EXE.
-
- There also a program called `INFNG' that can be used to convert the Info
- (*not* Texinfo) version of the FAQ to the Norton Guide format. `INFNG' can
- be downloaded from the DJGPP archive, e.g.
- ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2misc/infng100.zip.
-
- 23. About this FAQ
- ******************
-
- Maintainer: Eli Zaretskii <eliz@is.elta.co.il>.
-
- This FAQ is Copyright (C) 1994, 1995, 1996, 1997 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/news
- group 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:
-
- John M. Aldrich <fighteer@cs.com>
- Anthony Appleyard <A.APPLEYARD@fs2.mt.umist.ac.uk>
- John Bodfish <bodfish@austen.notis.com>
- Francois Charton <deef@pobox.oleane.com>
- Bill Currie <bill_currie@blackmagic.tait.co.nz>
- Bill Davidson <bdavidson@ra.isisnet.com>
- DJ Delorie <dj@delorie.com>
- Tom Demmer <Demmer@LStM.Ruhr-Uni-Bochum.De>
- Juergen Erhard <jae@laden.ilk.de>
- Jeremy Filliben <prime@UDel.Edu>
- James W. Haefner <Jim@anolis.bnr.usu.edu>
- Koen Van Herck <kvhk@barco.com>
- Robert Hoehne <Robert.Hoehne@Mathematik.TU-Chemnitz.DE>
- Gordon Hogenson <ghogenso@u.washington.edu>
- Harry Johnston <omega@es.co.nz>
- Martynas Kunigelis <martynas.kunigelis@vm.ktu.lt>
- Pieter Kunst <kunst@prl.philips.nl>
- Y. Lazarovitch <yitzg@haven.ios.com>
- Alexander Lehmann <lehmann@mathematik.th-darmstadt.de>
- Marty Leisner <leisner@sdsp.mc.xerox.com>
- Dave Love <d.love@dl.ac.uk>
- Rob Nader <naderr@topaz.cqu.edu.au>
- Eric Nicolas <nicolas@JUPITER.saclay.cea.fr>
- Elliott Oti <e.oti@stud.warande.ruu.nl>
- Esa A E Peuha <peuha@cc.helsinki.fi>
- Walter Prins <prins@quark.cs.sun.ac.za>
- Steve Salter <salters@admin.fanshawec.on.ca>
- Charles Sandmann <sandmann@clio.rice.edu>
- Terrel Shumway <Shumw001@Cerritos.edu>
- Andrew Szymkowiak <aes@solia.gsfc.nasa.gov>
- Launey Thomas <ljt@sierrasemi.com>
- Chris Tilbury <C.J.Tilbury@estate.warwick.ac.uk>
- Stephen Turnbull <turnbull@shako.sk.tsukuba.ac.jp>
- Santiago Vila <sanvila@pizarro.unex.es>
- Ronan Waide <waider@waider.ie>
- Morten Welinder <terra@diku.dk>
- Anthony Edward Wesley <awesley@galaxy.anutech.com.au>
- Mark H. Wood <mwood@mhw.OIT.IUPUI.EDU>
-
- 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.
- * "Far" declarations, porting to DJGPP: Section 17.7.
- * "Huge" declarations, porting to DJGPP: Section 17.7.
- * "Near" declarations, porting to DJGPP: Section 17.7.
- * -ansi switch and C++-style comments in C programs: Section 8.3.
- * -fconserve-space switch: Section 8.14.
- * -fstrength-reduce optimization, disabled by default: Section 14.2.
- * -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.
- * .o files from EMXAOUT can't be put into a library: 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.
- * ^Z character at end of DJGPP.ENV: Section 6.2.
- * __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.5.
- * __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.
- * __dpmi_YYY vs _go32_XXX, which one to use: Section 18.10.
- * __GO32__ pre-processor symbol: Section 8.6.
- * __pure_virtual, unresolved function: Section 8.12.
- * __tb, an alias for the address of transfer buffer: Section 18.2.
- * _AX variable, porting to DJGPP: Section 17.8.
- * _BP variable, porting to DJGPP: Section 17.8.
- * _BX variable, porting to DJGPP: Section 17.8.
- * _CX variable, porting to DJGPP: Section 17.8.
- * _DI variable, porting to DJGPP: Section 17.8.
- * _dos_ds, a selector to access conventional memory: Section 18.4.
- * _DS variable, porting to DJGPP: Section 17.8.
- * _DX variable, porting to DJGPP: Section 17.8.
- * _ES variable, porting to DJGPP: Section 17.8.
- * _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.
- * _go32_XXX vs __dpmi_YYY, which one to use: Section 18.10.
- * _SI variable, porting to DJGPP: Section 17.8.
- * _stklen, setting stack size: Section 15.9.
- * Accessing absolute addresses above 1MB: Section 18.7.
- * Accessing absolute addresses in conventional memory: Section 18.4.
- * Accessing absolute addresses with dedicated selector: Section 18.4.
- * Accessing C variables from inline assembly: Section 18.13.
- * Accessing VBE 2.0 linear frame buffer: Section 10.2.
- * Accessing video memory: Section 10.2.
- * Alignment of data by GAS can slow-down code: Section 14.3.
- * Allegro library, failure to compile: Section 8.19.
- * Announcements, mailing list: Section 20.3.
- * Archives, DJGPP mailing list/News group, how to search: Section 6.11.
- * argv[0] when program runs under a debugger: Section 12.1.
- * Asking for help: Section 6.12.
- * 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.7.
- * Automated downloading from a Unix box: Section 4.7.
- * Automated FTP from a Unix box: Section 4.7.
- * Automatic variables, how much memory: Section 15.9.
- * Bad format, profiler error message: Section 13.3.
- * 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: Section 7.1.
- * Breakpoints don't work in GDB under Windows: Section 12.9.
- * Browsing documentation: Section 5.1.
- * Buffered I/O, effect of buffer size on I/O speed: Section 14.4.
- * Bug report, how to submit: Section 22.1.
- * Bug-tracking system for DJGPP: Section 22.1.
- * Bugs, how to browse a list of known DJGPP problems: Section 22.1.
- * C library, legal restrictions: Section 19.2.
- * C programs compilation, recommended system RAM: Section 3.1.
- * C++ class variables under GDB: Section 12.7.
- * C++ debugging with stabs information: Section 12.7.
- * C++ method names under GDB: Section 12.7.
- * C++ programs compilation, recommended system RAM: Section 3.1.
- * C++ programs, large executable: Section 8.14.
- * C++ programs, problems with packed structs: Section 22.10.
- * C++ source, debugger cannot find: Section 12.6.
- * C++ STL library, not in lgp271b distribution: Section 8.7.
- * C++, missing header files: Section 8.2.
- * C++-style comments in C programs, GCC won't compile: Section 8.3.
- * Caldera OpenDOS, DPMI services crash DJGPP: Section 6.2.
- * Calling 16-bit code from DJGPP: Section 17.6.
- * calloc fails under EMM386 or HIMEM: Section 15.7.
- * calloc fails under QDPMI or Windows: Section 15.4.
- * calloc fails under Windows 3.x: Section 15.5.
- * calloc fails under Windows 95: Section 15.6.
- * calloc, effect on "Fat DS": Section 18.6.
- * Can't find node "Top", Info message: Info can't find ``Top''.
- * CCT mirrors' list: Section 4.2.
- * CD-ROM, getting DJGPP: Section 4.4.
- * Chaining interrupt: Section 18.9.
- * Changing GNU/DJGPP programs: Section 22.1.
- * Child processes, spawning under OS/2: Section 3.2.
- * Child programs, how much memory is left: Section 15.8.
- * Class method name in GDB: Section 12.7.
- * Class static variable name in GDB: Section 12.7.
- * Code is slow due to incorrect alignment by GAS: Section 14.3.
- * Code page change might prevent MSHELL from working: Section 12.5.
- * Code quality, GCC: Section 14.1.
- * Code speed, slower in v2.x: Section 14.2.
- * Code, DJGPP-specific: Section 8.6.
- * COFF output from linker, how to get: Section 12.3.
- * COFF output, required for profiling: Section 13.3.
- * Color text cannot be printed with `printf': Section 9.4.
- * 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 progress, GCC switch: Section 6.3.
- * Compilation speed: Section 7.1.
- * Compile-time problems: Chapter 8.
- * Compiler crashes, which subprogram of: Section 6.9.
- * Compiler speed: Chapter 7.
- * Compiling GCC and CPP: Section 3.8.
- * Compiling GCC and CPP, RAM disk: Section 3.9.
- * Compiling large programs, disk cache settings: Section 3.8.
- * Compiling large programs, RAM disk settings: Section 3.8.
- * Compiling large source files: Section 3.8.
- * Compiling Objective C sources: Section 8.5.
- * Complex class is not in libgpp.a: Section 8.11.
- * Complex class, porting to libgpp.a 2.7.1 and later: Section 8.11.
- * Complex template class: Section 8.11.
- * Compressing DJGPP executables: Section 8.15.
- * Configuration, for optimal performance: Section 3.9.
- * Configuration, reasonable: Section 3.8.
- * Configuration, the best: Section 3.7.
- * Conventional memory, moving data to/from: Section 18.4.
- * Conversion of the FAQ to different formats: Section 22.17.
- * 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.9.
- * Crashes, v2.0 programs: Section 9.1.
- * Critical error handling in DJGPP: Section 22.11.
- * Cross-compiling with DJGPP: Section 22.7.
- * crt0.o, GCC can't find: Section 8.1.
- * Ctrl-C in debugged programs: Section 12.9.
- * Curses library for DJGPP: Section 22.2.
- * Cygnus GCC port to Windows: Section 3.3.
- * Cygnus port of GCC for WinNT and Win95: Section 3.6.
- * DEADBEAF, use to spot uninitialized memory: Section 9.1.
- * Debugger cannot find C++ source: Section 12.6.
- * Debugger causes programs to overflow the stack: Section 15.9.
- * Debugger crashes on programs compiled for profiling: Section 12.9.
- * Debugger crashes on programs which use exceptions: Section 12.9.
- * Debugger crashes under QEMM/QDPMI: Section 12.2.
- * Debugger doesn't know about #include'd source: Section 12.8.
- * Debugger doesn't pass signals to debuggee: Section 12.9.
- * Debugger GP Faults on Windows 3.x: Section 12.9.
- * 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 C/C++ code generated by a program: Section 12.8.
- * Debugging graphics programs: Section 12.5.
- * Debugging issues: Chapter 12.
- * Debugging symbols, how to strip from executables: Section 8.15.
- * Debugging with GDB, needs COFF output: Section 12.3.
- * Description of GNU style of mangling C++ names: Section 12.7.
- * Development environments for DJGPP: Section 22.2.
- * Differences between SimTel and CCT ftp sites: Section 4.1.
- * Direct hardware access on Win/NT: Section 3.3.
- * Disabling globbing in filenames: Section 16.2.
- * Disabling QDPMI: Section 12.2.
- * Disabling virtual memory for CWSDPMI: Section 7.1.
- * Disabling wildcard expansion: Section 16.2.
- * Disk cache, influence on compilation speed: Section 7.1.
- * Disk cache, recommended settings: Section 3.9.
- * Disk cache, when compiling large programs: Section 3.8.
- * Disk space, required for installation: Section 3.1.
- * Disk space, using less of it: Section 4.7.
- * 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.11.
- * DJGPP as cross-compiler: Section 22.7.
- * DJGPP distribution, list of: Section 4.5.
- * 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 environment variable, how to set and test: Section 8.1.
- * DJGPP environment variable, setting under LFN: Section 8.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 mailing list/news group, read via WWW: Section 20.4.
- * DJGPP News group: Section 20.7.
- * DJGPP News group, reading via WWW: Section 20.3.
- * DJGPP programs, problems with: Chapter 6.
- * DJGPP programs, problems with DPMI host: Section 6.2.
- * DJGPP programs, profiling: Section 13.1.
- * DJGPP software, where to upload: Section 22.6.
- * DJGPP users, asking for help: Section 6.12.
- * DJGPP utilities, legal restrictions: Section 19.2.
- * DJGPP v2.x, alternative DPMI hosts: Section 21.2.
- * DJGPP won't run, prints "No DPMI": Section 6.1.
- * DJGPP, a list of packages: Section 4.5.
- * DJGPP, downloading via e-mail: Section 4.4.
- * DJGPP, downloading with FTP: Section 4.3.
- * DJGPP, downloading with Gopher: Section 4.4.
- * DJGPP, downloading with WWW: Section 4.4.
- * 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.
- * DJGPP.ENV syntax explained: Section 8.1.
- * DJGPP.ENV, trailing junk crashes Info: Section 6.2.
- * djgpp_first_ctor, unresolved by linker: Section 8.13.
- * djgpp_first_dtor, unresolved by linker: Section 8.13.
- * 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.4.
- * 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.
- * DOSEmu, incompatibilities with DJGPP: Section 3.4.
- * Downloading DJGPP via e-mail: Section 4.3.
- * Downloading DJGPP with FTP: Section 4.3.
- * Downloading DJGPP with WWW: Section 4.4.
- * DPMI host bugs, might crash DJGPP programs: Section 6.2.
- * 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.
- * DXE can be debugged with EDEBUG32: Section 12.1.
- * DXE description: Section 22.13.
- * DXE docs and examples: Section 22.13.
- * Dynamically loaded code for DJGPP: Section 22.2.
- * E-mail, downloading DJGPP: Section 4.4.
- * Emulation, floating-point: Chapter 11.
- * Emulator library: Section 11.1.
- * Emulator, floating-point inaccuracies: Section 11.6.
- * Environment size affects spawning child programs: Section 16.5.
- * Environment variables, DJGPP: Section 3.7.
- * Environment variables, linker: Section 8.9.
- * Error messages, redirecting to a file: Section 6.10.
- * Excessive paging, tuning CWSDPMI: Section 3.9.
- * EXE compressor for DJGPP: Section 8.15.
- * Executable size, how to make smaller: Section 8.15.
- * Executable, bloated by static array: Section 8.14.
- * Executable, how to strip off debugging symbols: Section 8.15.
- * FAQ, conversion to different formats: Section 22.17.
- * Far pointer memory access: Section 10.2.
- * Farptr functions, mask off 12 higher bits of address: Section 18.5.
- * Fatal signal, GCC message: Section 6.4.
- * 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.5.
- * Files, reading and writing: Section 9.3.
- * Files, required disk space: Section 4.6.
- * Floating-point emulation: Chapter 11.
- * Floating-point emulation doesn't work: Section 11.1.
- * Floating-point emulation under debugger: Section 12.9.
- * 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 exception in Objective-C program: Section 11.7.
- * Floating-point issues: Chapter 11.
- * Floating-point math functions, standard and high-quality: Section 8.7.
- * Floating-point, debugger support: Section 12.1.
- * FP_SEG and FP_OFF, porting to DJGPP: Section 17.7.
- * free doesn't change virtual memory: Section 15.2.
- * FTP, downloading DJGPP: Section 4.3.
- * FTP, downloading DJGPP in batch mode: Section 4.7.
- * Functions from libm.a crash with SIGFPE: Section 11.8.
- * 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 "Installation problem, cannot exec as": Section 6.4.
- * GCC aborts with "Internal compiler error": Section 6.4.
- * 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.9.
- * GCC hangs/crashes under Make: Section 6.7.
- * GCC says "Fatal signal X": Section 6.4.
- * Getting DJGPP <1>: Section 4.1.
- * Getting DJGPP: Chapter 4.
- * getting DJGPP from a CD-ROM: Section 4.4.
- * 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 News groups, don't post DJGPP problems: Section 20.1.
- * GNU packages, how to change: Section 22.1.
- * Gopher, downloading DJGPP: Section 4.4.
- * gotoxy doesn't work with `printf': Section 9.4.
- * GPL, effect on DJGPP: Section 19.1.
- * Graphics driver setup: Section 10.1.
- * Graphics issues: Chapter 10.
- * Graphics programs, debugging: Section 12.5.
- * Graphics screen messed up under Windows: Section 10.3.
- * Graphics, direct video access: Section 10.2.
- * Graphics, limitations on Win/NT: Section 3.3.
- * Gurus, asking for help: Section 6.12.
- * Hang, all DJGPP programs: Section 6.2.
- * Hang, DJGPP programs: Chapter 6.
- * harderr function, emulating under DJGPP: Section 22.11.
- * Hardware interrupt handler crashes: Section 18.11.
- * Hardware interrupts, hooking: Section 18.9.
- * Hardware interrupts, subtleties: Section 18.11.
- * 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.12.
- * HTML format, DJGPP documentation: Section 5.4.
- * I/O speed, DJGPP programs: Section 14.4.
- * i286: Section 3.5.
- * i386SX: Section 3.1.
- * Inaccuracies, using emulator: Section 11.6.
- * Including source code, problems with debugging: Section 12.8.
- * Incompatibilities, i286: Section 3.5.
- * Incompatibilities, Linux DOSEmu: 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: Info can't find ``Top''.
- * Inline assembly, how to write: Section 18.13.
- * Inline functions, linker won't find: Section 8.10.
- * inp function: Section 18.12.
- * Int 24h crashes DJGPP programs: Section 22.11.
- * int86 crashes program: Section 18.1.
- * int86x/intdosx, how to pass a buffer: Section 18.2.
- * intdos crashes program: Section 18.1.
- * Intel vs AT&T assembly syntax: Section 17.1.
- * Intel-style assembly code, using with DJGPP: Section 17.3.
- * Interactive programs, screen I/O: Section 9.4.
- * Internal compiler error, when compiling C++ programs: Section 6.4.
- * Interrupt 24h handling: Section 22.11.
- * Interrupt chaining: Section 18.9.
- * Interrupt frequency, maximum: Section 18.11.
- * Interrupt handlers, locking memory: Section 18.11.
- * Interrupt reflection: Section 18.9.
- * Interrupt reflection overhead: Section 18.11.
- * Interrupts handlers in DJGPP: Section 18.9.
- * Invoking v2 programs from v1.x programs: Section 22.12.
- * Keyboard interrupt cannot be hooked under debugger: Section 12.9.
- * Keystrokes don't get to keyboard handler: Section 18.11.
- * Known bugs in DJGPP, how to browse: Section 22.1.
- * ldexp crashes programs with FP exception: Section 11.8.
- * 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.
- * LFN API, not supported on Win/NT: Section 3.3.
- * LFN problems: Section 22.14.
- * LGPL, effect on DJGPP: Section 19.1.
- * libc2.tex, missing file: Section 5.3.
- * Libraries, converting to DJGPP: Chapter 17.
- * Libraries, GCC can't find: Section 8.1.
- * Libraries, optional, how to link: Section 8.7.
- * Libraries, order on compilation/link command line: Section 8.9.
- * Libraries, searching for functions: Section 8.8.
- * Library docs, missing libc2.tex: Section 5.3.
- * Library docs, problems in generating printed version: Section 5.3.
- * 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.
- * Linear frame buffer access: Section 10.2.
- * Link-time problems: Chapter 8.
- * Linker fails because of Win95 shortcut files: Section 8.16.
- * Linker fails for a.out files in a library: Section 8.18.
- * Linker fails for large libraries or object files: Section 8.18.
- * Linker fails for obj files converted by EMXAOUT: Section 8.18.
- * Linker fails to find crt0.o under Novell: Section 8.1.
- * Linker fails to produce executable under Novell: Section 8.17.
- * Linker speed: Chapter 7.
- * linker won't find djgpp_first_dtor symbol: Section 8.13.
- * 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.
- * Linking speed, improve by stub-editing ld.exe: Section 7.2.
- * Links, symbolic, simulation with DJGPP: Section 22.3.
- * Linux-to-DOS cross-compiling with DJGPP: Section 22.7.
- * List of DJGPP packages: Section 4.5.
- * Locking memory for hardware interrupt handlers: Section 18.9.
- * Locking memory for interrupt handlers: Section 18.11.
- * Long command lines: Section 16.4.
- * Long command lines, from Makefile: Section 16.6.
- * Long command lines, maximum length: Section 16.5.
- * long filename support, bugs: Section 22.14.
- * Long Filenames aren't supported on Win/NT: Section 3.3.
- * Long filenames in setting DJGPP env. variable: Section 8.1.
- * Low-level programming issues: Chapter 18.
- * Machines with low extended RAM, tuning CWSDPMI: Section 3.9.
- * Makefile, first character of every command must be TAB: Section 22.15.
- * 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.7.
- * malloc fails under QDPMI or Windows: Section 15.4.
- * malloc fails under Windows 3.x: Section 15.5.
- * malloc fails under Windows 95: Section 15.6.
- * malloc, effect on "Fat DS": Section 18.6.
- * Man pages, how to read: Section 5.6.
- * Math functions crash with SIGFPE: Section 11.8.
- * Maximum interrupt frequency: Section 18.11.
- * Maximum length of command line: Section 16.5.
- * Memory allocation fails under EMM386 or HIMEM: Section 15.7.
- * Memory allocation fails under QDPMI or Windows 95: Section 15.4.
- * Memory allocation fails under Windows 3.x: Section 15.5.
- * Memory allocation fails under Windows 95: Section 15.6.
- * Memory at run time: Chapter 15.
- * Memory locking for hardware interrupt handlers: Section 18.9.
- * Memory manager, settings for optimal performance: Section 3.9.
- * Memory size reported by go32-v2: Section 4.6.
- * Memory, how much is left for spawned programs: Section 15.8.
- * 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, accessing with dedicated selector: Section 18.4.
- * Memory-mapped devices, fast access: Section 18.6.
- * Memory-mapped devices, moving data to/from: Section 18.4.
- * Method name in C++, how to pass to GDB: Section 12.7.
- * 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 crt0.o: Section 8.1.
- * Missing header files: Section 8.1.
- * Missing libraries: Section 8.1.
- * Missing separator, Make error message: Section 22.15.
- * Mixing v2.0 GCC with CC1PLUS from v1.x, Unknown filetype message.: Section 6.5.
- * Mixing v2.x Make with v1.x programs hangs the machine: Section 6.7.
- * MK_FP macro, porting to DJGPP: Section 17.7.
- * 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, how to install 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.6.
- * MS-Windows programming under DJGPP: Section 3.6.
- * 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.8.
- * Network installation makes linking slow: Section 7.2.
- * New features in v2: Section 21.1.
- * No DPMI error message: Section 6.1.
- * No free XMS memory when NOEMS parameter is used: Section 15.8.
- * 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.5.
- * Novell NDOS, buggy DPMI services crash DJGPP: Section 6.2.
- * Novell, linker or STUBIFY don't produce executable: Section 8.17.
- * Null pointer dereference crashes v2.0 programs: Section 9.1.
- * Numeric exception, program crash: Section 11.5.
- * Objective C, compiling: Section 8.5.
- * Objective-C programs crash with FP exception: Section 11.7.
- * Old CWSDPMI, influence on compilation speed: Section 7.1.
- * Optimal performance, CWSDPMI tuning: Section 3.9.
- * Optimal performance, disk cache settings: Section 3.9.
- * Optimal performance, RAM disk settings: Section 3.9.
- * Optimal performance, system configuration: Section 3.9.
- * Optimization crashes GCC: Section 6.3.
- * Optimizing DJGPP programs: Section 13.1.
- * outp function: Section 18.12.
- * Overhead, interrupt reflection to protected mode: Section 18.11.
- * Packages, DJGPP, list of: Section 4.5.
- * Packages, ported to DJGPP: Section 22.2.
- * Packages, required disk space: Section 4.6.
- * Packages, which to download: Section 4.5.
- * Packed structs, C++ bug: Section 22.10.
- * Packing the structs: Section 22.9.
- * Page fault error message from CWSDPMI: Section 9.1.
- * Paging starts before all RAM is used: Section 15.7.
- * Peek/poke absolute address: Section 18.4.
- * Pentium-optimized code: Section 14.3.
- * 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.12.
- * Peripherals, moving data to/from: Section 18.4.
- * Pi, accurate computation: Section 11.6.
- * Port reading/writing: Section 18.12.
- * Ported programs run much slower: Section 14.5.
- * Posting problems, not to GNU News groups: 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.
- * printf cannot print color text: Section 9.4.
- * Printing DJGPP documentation: Section 5.3.
- * Problems with DJGPP programs: Chapter 6.
- * Problems, asking for help: Section 6.12.
- * Problems, searching for solution in DJGPP archives: Section 6.11.
- * Profiled programs crash under debugger: Section 12.9.
- * Profiler documentation: Section 13.4.
- * Profiler produces no output: Section 13.6.
- * Profiling DJGPP programs: Section 13.1.
- * Profiling DJGPP programs, need COFF output: Section 13.3.
- * Profiling issues: Chapter 13.
- * Profiling programs that terminate abnormally: Section 13.6.
- * Profiling, library routines: Section 13.5.
- * Program crashes accessing empty floppy/CD-ROM drives: Section 22.11.
- * Program crashes because of Int 24h: Section 22.11.
- * Program crashes in int86/intdos: Section 18.1.
- * Program crashes in v2.0, but not in v1.x: Section 9.1.
- * Program crashes while allocating memory: Section 15.4.
- * Programs crash when compiled for profiling: Section 13.2.
- * Programs crash with SIGSEGV due to small stack size: Section 15.9.
- * Programs crash, general troubleshooting: Section 6.9.
- * Programs crash, numeric exception: Section 11.5.
- * Programs crash, saving debugging output: Section 6.10.
- * Programs crash, searching DJGPP archives: Section 6.11.
- * Programs that exit abnormally, how to profile: Section 13.6.
- * Programs using nearptr fail on Windows/NT: Section 3.3.
- * Protected mode and converted assembly code: Section 17.4.
- * Protected-mode interrupt vector: Section 18.9.
- * Pseudo-register variables, porting to DJGPP: Section 17.8.
- * QEMM auto/off mode, conflicts with DJGPP: Section 6.6.
- * Quotes, how to pass them to programs: Section 16.3.
- * RAM disk, influence on compilation speed: Section 7.1.
- * RAM disk, recommended settings: Section 3.9.
- * RAM disk, when compiling large programs: Section 3.8.
- * RCS port to DJGPP: Section 22.2.
- * Read DJGPP traffic via WWW: Section 20.4.
- * Reading an int from a binary file: Section 22.9.
- * Reading documentation: Section 5.1.
- * Reading documentation with a Web browser: Section 5.2.
- * Reading documentation with text editor/viewer: Section 5.2.
- * Reading documentation, converting to plain ASCII: Section 5.2.
- * Reading structs from disk files: Section 22.9.
- * 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.2.
- * 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.10.
- * Redirection in Makefile, effect on long command lines: Section 16.6.
- * Redirection, using the REDIR program: Section 16.6.
- * Required hardware, general: Chapter 3.
- * Response file, passing long command lines: Section 16.4.
- * Run-time environment in v2.x: Section 21.2.
- * Run-time performance: Chapter 14.
- * Run-time problems: Chapter 9.
- * Runtime speed, slower in v2.x: Section 14.2.
- * sbrk, effect on "Fat DS": Section 18.6.
- * Screen contents not restored under Windows: Section 10.3.
- * Screen I/O: Section 9.4.
- * Searching DJGPP archives: Section 6.11.
- * setvbuf, effect on I/O speed: Section 14.4.
- * SHELL= variable in Makefile, effect on long command lines: Section 16.6.
- * Shortcut files under Win95 fail DJGPP linker: Section 8.16.
- * Signals in debugged programs: Section 12.9.
- * SimTel mirrors' list: Section 4.1.
- * Single-stepping doesn't work in GDB on Windows 3.x: Section 12.9.
- * Single-stepping doesn't work in RHIDE on Windows 3.x: Section 12.9.
- * Size of a struct under DJGPP: Section 22.9.
- * Slow code, due to bad alignment by GAS: Section 14.3.
- * Slow compilation: Section 7.1.
- * Slow compilation, tuning CWSDPMI: Section 3.9.
- * Slow linking, possible reasons: Section 7.2.
- * Slow-down, programs ported from other compilers: Section 14.5.
- * Software interrupts, need zero SS, SP and FLAGS: Section 18.3.
- * Solved problems, searching in DJGPP archives: Section 6.11.
- * Sound Blaster code for DJGPP: Section 22.2.
- * Source files, using as the best docs: Section 5.7.
- * Source language is not recognized by GDB in C++ programs: Section 12.7.
- * Spawned programs, how much memory is left: Section 15.8.
- * Spawning child processes, OS/2: Section 3.2.
- * Spawning child programs on Windows/NT and 95: Section 3.3.
- * Spawning programs, effect of environment size: Section 16.5.
- * Spawning v2 programs from v1.x programs: Section 22.12.
- * Spawning v2.x programs from v1.x programs doesn't work: Section 6.7.
- * Speed of compilation: Section 7.1.
- * Stack dump, how to read: Section 9.2.
- * Stack overflow under debugger: Section 15.9.
- * Stack size under DJGPP: Section 15.9.
- * Stack size, insufficient, causes programs to crash: Section 15.9.
- * Stand-alone DJGPP programs that don't need DPMI: Section 9.5.
- * Standard output/error stream, redirecting to a file: Section 6.10.
- * Static array enlarges C++ executable: Section 8.14.
- * STL library, not in lgp271b distribution: Section 8.7.
- * struct reading from a disk file: Section 22.9.
- * Struct, size in bytes under DJGPP: Section 22.9.
- * Structure packing, C++ bug: Section 22.10.
- * Structure padding: Section 22.9.
- * Subscription to DJGPP mailing list: Section 20.3.
- * Subsidiary programs, how much memory is left: Section 15.8.
- * SVGA types supported by GRX: Section 10.1.
- * Symbolic links, simulation with DJGPP: Section 22.3.
- * System configuration, the best: Section 3.7.
- * System RAM, minimum: Section 3.1.
- * Systems programming issues: Chapter 18.
- * TAB, must be the first character of every command: Section 22.15.
- * TABs replaced with spaces by a text editor: Section 22.15.
- * TCP/IP library for DJGPP: Section 22.2.
- * Text-mode video memory access: Section 10.2.
- * Timer interrupts code for DJGPP: Section 22.2.
- * Traceback, how to read: Section 9.2.
- * Tracing compilation progress with -Q: Section 6.3.
- * 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.9.
- * Turbo Vision, DJGPP port: Section 22.2.
- * TZ database updates, where to get: Section 22.16.
- * TZ variable, how to set: Section 22.16.
- * Uninitialized memory crashes v2.0 programs: Section 9.1.
- * Unix-like sbrk algorithm considered harmful for HW interrupts: Section 18.11.
- * Unix-to-DOS cross-compiling with DJGPP: Section 22.7.
- * Unknown filetype, GCC message: Section 6.5.
- * Unresolved __pure_virtual function in C++: Section 8.12.
- * Unresolved externals: Section 8.7.
- * Unresolved externals in C++ programs, use GXX: Section 8.7.
- * Unresolved externals, C++: Section 8.10.
- * unresolved externals, djgpp_first_ctor: Section 8.13.
- * 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 code slower than v1.x: Section 14.2.
- * V2, new features and bug fixes: Chapter 21.
- * v2.0, program crashes: Section 9.1.
- * v2.01 code slower than v2.0: Section 14.2.
- * V2.x, new environment: Section 21.2.
- * V86 mode, QEMM and CWSDPMI problems: Section 6.6.
- * VBE 2.0 linear frame buffer access: Section 10.2.
- * VESA support by GRX: Section 10.1.
- * VGA Mode-X graphics for DJGPP: Section 22.2.
- * Video memory, direct access: Section 10.2.
- * Virtual memory: Chapter 15.
- * Virtual memory exhausted, during compilation: Section 6.3.
- * Virtual memory under Windows 95: Section 15.6.
- * 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: Section 7.1.
- * 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.5.
- * Watchpoints don't work in GDB under Windows: Section 12.9.
- * Web site for DJGPP: Section 22.5.
- * Weekly digest, problems in receiving: Section 20.3.
- * Wildcards expansion: Section 16.1.
- * Wildcards expansion, disabling: Section 16.2.
- * Win32 programming with GCC: Section 3.6.
- * Windows applications with DJGPP: Section 3.6.
- * WinNT/Win95 programming with Cygnus GCC port: Section 3.6.
- * WWW services for DJGPP: Section 22.5.
- * WWW, downloading DJGPP: Section 4.4.
- * X emulation for DJGPP: Section 22.2.
- * Zoneinfo directory: Section 22.16.
-
- 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.10.
- * _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.11.
- * _crt0_startup_flags, Unix sbrk is incompatible with HW interrupts: Section 18.11.
- * _string.h, GCC can't find: Section 8.2.
- * AutoWinNet, automated downloading: Section 4.7.
- * BatchFTP, automated downloading from a Unix box: Section 4.7.
- * BCCBGI (from BCC2GRX) crashes with the default stack: Section 15.9.
- * Bison doesn't imply GPL/LGPL: Section 19.1.
- * Bison, debugging generated code: Section 12.8.
- * C compiler overflows its stack for large programs: Section 6.4.
- * C++ class libraries, legal restrictions: Section 19.1.
- * C++ compiler crashes for large programs: Section 15.9.
- * C++ compiler overflows its stack for large programs: Section 6.4.
- * Cawf, using to read man pages: Section 5.6.
- * CC1PLUS crashes with SIGSEGV: Section 15.9.
- * CHCP DOS command might prevent MSHELL from working: Section 12.5.
- * 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.8.
- * CPP, compiling, RAM disk: Section 3.9.
- * CTRL87, control numeric exceptions: Section 11.5.
- * CWSDPMI allows "Fat DS": Section 18.6.
- * CWSDPMI crashes programs allocating memory is small chunks: Section 15.4.
- * CWSDPMI crashes programs which dereference NULL pointers: Section 9.1.
- * CWSDPMI doesn't support hooking Int 24h: Section 22.11.
- * CWSDPMI runs out of virtual memory: Section 6.4.
- * CWSDPMI, alternative DPMI hosts: Section 21.2.
- * CWSDPMI, disabling virtual memory: Section 7.1.
- * CWSDPMI, legal restrictions: Section 19.2.
- * CWSDPMI, maximum available virtual memory: Section 15.1.
- * CWSDPMI, memory usage for nested programs: Section 15.8.
- * CWSDPMI, minimum required system RAM: Section 3.1.
- * CWSDPMI, old (beta) versions slow-down compilation: Section 7.1.
- * CWSDPMI, pages too early under EMM386: Section 15.7.
- * CWSDPMI, problems with QEMM auto/off mode: Section 6.6.
- * CWSDPMI, setting parameters for optimal performance: Section 3.9.
- * CWSDPMI, should be distributed with DJGPP programs: Section 9.5.
- * CWSDPR0 reduces interrupt reflection overhead: Section 18.11.
- * CWSDPR0, use for testing HW interrupt handlers: Section 18.9.
- * CWSPARAM, a program to tune CWSDPMI performance: Section 3.9.
- * DJGPP.ENV syntax explained: Section 8.1.
- * DJGPP.ENV, beware of blanks when setting: Section 8.1.
- * DJGPP.ENV, compiler environment variables: Section 8.1.
- * DJGPP.ENV, linker environment variables: Section 8.9.
- * DJP compressor supports DLM: Section 8.15.
- * DJP, an executable compressor for DJGPP: Section 8.15.
- * DLM compression, with DJP: Section 8.15.
- * DLM, a facility to load code at run time: Section 22.2.
- * DOSEMU doesn't allow "Fat DS": Section 18.6.
- * EDEBUG32 can debug a DXE: Section 12.1.
- * EMACS can be compiled with DJGPP: Section 22.2.
- * 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.7.
- * EMM386, effect on max interrupt frequency: Section 18.11.
- * EMM386, malloc/calloc fails: Section 15.7.
- * EMM386, settings for optimal performance: Section 3.9.
- * emTeX, printing the docs: Section 5.3.
- * emu387.dxe, distribution with DJGPP programs: Section 11.1.
- * EMX/GCC, writing Windows applications: Section 3.6.
- * EMXAOUT converter from .obj to COFF format: Section 17.5.
- * EMXAOUT output can't be put into a library: Section 17.5.
- * EMXAOUT produces a.out format: Section 17.5.
- * F2C, debugging generated code: Section 12.8.
- * Flex doesn't imply GPL/LGPL: Section 19.1.
- * Flex, debugging generated code: Section 12.8.
- * 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 crt0.o: Section 8.1.
- * GCC can't find headers: Section 8.1.
- * GCC can't find libraries: Section 8.1.
- * GCC cannot resolve djgpp_first_ctor symbol when linking: Section 8.13.
- * GCC crashes during optimization: Section 6.3.
- * GCC crashes, which subprogram of: Section 6.9.
- * GCC doesn't pack structs in C++ programs: Section 22.10.
- * 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 exhausts virtual memory: Section 6.3.
- * GCC from v2.x crashes under v1.x Make: Section 6.7.
- * GCC hangs under Make: Section 6.7.
- * 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.14.
- * 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.8.
- * GCC, compiling, RAM disk: Section 3.9.
- * GCC, environment variables: Section 8.1.
- * GCC, file source language recognition: Section 8.4.
- * GCC, I/O speed: Section 14.4.
- * GCC, inline assembly facilities: Section 18.13.
- * 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.10.
- * GCC, slow compilation: Section 7.1.
- * GDB cannot restart the debuggee: Section 12.1.
- * GDB causes stack overflow in a debuggee: Section 15.9.
- * GDB crashes under QEMM/QDPMI: Section 12.2.
- * GDB doesn't pass command-line arguments to debuggee: Section 12.1.
- * GDB doesn't recognize source language: Section 12.7.
- * GDB GP Faults on breakpoint/watchpoint under Windows: Section 12.9.
- * GDB needs COFF output: Section 12.3.
- * GDB, conflicts with file redirection: Section 12.1.
- * GDB, debugging DJGPP programs: Section 12.1.
- * GDB, debugging graphics programs: Section 12.5.
- * GDB, how is it different on MS-DOS: Section 12.1.
- * GDB, how to use C++ class variables' names: Section 12.7.
- * GDB, how to use C++ method names: Section 12.7.
- * GDB, init file name: Section 12.1.
- * GDB, name of the READLINE init file: Section 12.1.
- * GDB, slow loading of symbols and sources: Section 12.1.
- * go32-v2 reports the amount of memory and swap space: Section 4.6.
- * go32-v2 usage: Section 22.12.
- * go32-v2, use to find out how much memory is available to DJGPP: Section 15.7.
- * Gprof cannot find program: Section 13.3.
- * Gprof documentation: Section 13.4.
- * gprof produces no output: Section 13.6.
- * Gprof says "bad format": Section 13.3.
- * 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.
- * GRX, supported SVGA types: Section 10.1.
- * gxx driver, not in gcc272b distribution: Section 8.7.
- * gxx driver, searches C++ libraries automatically: Section 8.7.
- * HIMEM, malloc/calloc fails: Section 15.7.
- * INFNG, produces the FAQ in Norton Guides format: Section 22.17.
- * Info crashes due to ^Z or whitespace at end of DJGPP.ENV: Section 6.2.
- * Info crashes under QDPMI: Section 6.2.
- * Info won't display a file: Info can't find ``Top''.
- * 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.
- * ld fails for a.out files in a library: Section 8.18.
- * ld fails for large libraries and object files: Section 8.18.
- * ld fails for obj files converted by EMXAOUT: Section 8.18.
- * LD linker, linker script defines djgpp_first_ctor: Section 8.13.
- * ld, how to improve linking speed: Section 7.2.
- * Less, using to read man pages: Section 5.6.
- * Lex, debugging generated code: Section 12.8.
- * 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.
- * libstdc++ standard templates library: Section 8.7.
- * 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.
- * Linking against optional libraries: Section 8.7.
- * Linux doesn't allow "Fat DS": Section 18.6.
- * Linux, compatibility: Section 3.1.
- * Linux, needs a patch to run nested programs: Section 3.4.
- * Make crashes on DOSEmu: Section 3.4.
- * Make crashes on OS/2: Section 3.2.
- * Make error message "missing separator": Section 22.15.
- * Make requires floating point: Section 22.1.
- * Make, GCC hangs when invoked from it: Section 6.7.
- * 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.
- * MAKERTF, produces the FAQ in RTF format: Section 22.17.
- * 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.4.
- * MSHELL fails because of TSR programs: Section 12.5.
- * MSHELL, redirecting screen output: Section 12.5.
- * NASM, a portable assembler with Intel syntax support: Section 17.3.
- * NDOS, buggy DPMI services crash DJGPP: Section 6.2.
- * Netscape, downloading DJGPP: Section 4.4.
- * NM, printing library contents: Section 8.8.
- * Novell 3.x, linker doesn't find crt0.o: Section 8.1.
- * Novell NWDOS 7, buggy DPMI services: Section 3.1.
- * Novell NWDOS 7, compatibility: Section 3.1.
- * NWDOS, buggy DPMI services crash DJGPP: Section 6.2.
- * OBJ2COFF converter from .obj to COFF format: Section 17.5.
- * OBJ2COFF, commercial use is prohibited: Section 17.5.
- * OBJDUMP segment overrides bugs: Section 17.2.
- * Objective C, compilation problems: Section 8.5.
- * Objective-C, cannot run on machines without FPU: Section 11.7.
- * obstack package: Section 8.7.
- * OpenDOS, bug in DPMI services crash DJGPP: Section 6.2.
- * OS/2 Warp allows "Fat DS": Section 18.6.
- * OS/2, compatibility: Section 3.1.
- * OS/2, floating point emulation: Section 11.3.
- * OS/2, incompatibilities: Section 3.2.
- * PMODE/DJ reduces interrupt reflection overhead: Section 18.11.
- * PMODE/DJ, can be used to produce stand-alone programs: Section 9.5.
- * POVRAY, linker fails to link the library: Section 8.18.
- * Q87, an emulator compatible with DJGPP: Section 11.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 DJGPP programs when they cause Int 24h: Section 22.11.
- * QDPMI crashes Info: Section 6.2.
- * QDPMI fails to provide virtual memory: Section 15.3.
- * QDPMI, how to disable: Section 12.2.
- * QDPMI, malloc/calloc failure: Section 15.4.
- * QDPMI, memory usage for nested programs: Section 15.8.
- * QEMM crashes debugger: Section 12.2.
- * QEMM, auto/off mode, conflicts with CWSDPMI: Section 6.6.
- * QEMM386, settings for optimal performance: Section 3.9.
- * RCS port to DJGPP: Section 22.2.
- * REDIR, redirecting GCC messages to a file: Section 6.10.
- * REDIR, redirecting stack dump to a file: Section 9.2.
- * REDIR, use to get redirection and long command lines: Section 16.6.
- * regex package from GNU: Section 8.7.
- * Regex.h, GCC can't find: Section 8.2.
- * RHIDE debugger GP Faults on breakpoints under Windows: Section 12.9.
- * RHIDE, development environment for DJGPP: Section 22.2.
- * RHIDE, includes an integrated debugger: Section 12.1.
- * RSX extender: Section 3.6.
- * RSXNT toolkit for developing Win32 applications: Section 3.6.
- * RSXNTDJ causes linker to fail: Section 8.16.
- * RSXWDK2 Windows development kit: Section 3.6.
- * sbrk algorithm and QDPMI: Section 15.3.
- * sbrk, Unix-like algorithm is incompatible with HW interrupts: Section 18.11.
- * SCRIPT, redirecting GCC messages to a file: Section 6.10.
- * 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.
- * STRIP makes executables smaller: Section 8.15.
- * STUBEDIT, changing stack size: Section 15.9.
- * STUBEDIT, effect on memory left to spawned programs: Section 15.8.
- * STUBIFY fails to produce .EXE under Novell: Section 8.17.
- * STUBIFY.EXE, infected by a virus: Section 6.5.
- * 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.
- * UNIVBE, software VESA 2.0 emulation: Section 10.1.
- * Warp, compatibility: Section 3.1.
- * Warp, incompatibilities: Section 3.2.
- * Win/NT doesn't allow "Fat DS": Section 18.6.
- * Win/NT doesn't allow port I/O: Section 3.3.
- * Win95 long filenames and C++ headers: Section 8.2.
- * Win95, setting DJGPP environment variable: Section 8.1.
- * 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 doesn't allow more than 16MB virtual memory: Section 15.6.
- * Windows 95 DPMI server loses selectors calling spawnXX: Section 3.3.
- * Windows 95, shortcut files conflict with ld: Section 8.16.
- * Windows 9x allows "Fat DS": Section 18.6.
- * Windows 9x, compatibility: Section 3.1.
- * Windows applications, writing with EMX/GCC: Section 3.6.
- * Windows messes up graphics screen: Section 10.3.
- * Windows, malloc/calloc failure: Section 15.4.
- * Windows, memory usage for nested programs: Section 15.8.
- * Windows, setting memory parameters for DJGPP: Section 3.9.
- * Windows, stack size control: Section 15.9.
- * windows.h header file, where to get it: Section 3.6.
- * Windows/NT DPMI server loses selectors calling spawnXX: Section 3.3.
- * Windows/NT, compatibility: Section 3.1.
- * WinNT, setting DJGPP environment variable: Section 8.1.
- * WMEMU causes undefined references when linking: Section 11.1.
- * WMEMU, an alternative floating-point emulator: Section 11.1.
- * WMEMU, use when debugging FP programs on non-FPU machine: Section 12.9.
- * Yacc, debugging generated code: Section 12.8.
-
-
-
-