DJGPP FAQ List 2.02


@ifclear html @ifinfo @format START-INFO-DIR-ENTRY * FAQ: (djgppfaq). The DJGPP FAQ list. END-INFO-DIR-ENTRY @end format @end ifinfo @end ifclear @finalout @setchapternewpage odd @titlepage @c use the new format for titles @title DJGPP Frequently-Asked Questions List @subtitle Edition @value{edition}, for DJGPP Version 2.0 @subtitle @value{update-month} @author by Eli Zaretskii @comment Include the Distribution inside the titlepage so @c that headings are turned off. @page @vskip 0pt plus 1filll Copyright @copyright{} 1994, 1995, 1996 Eli Zaretskii @end titlepage @ifinfo @htmltitle DJGPP Frequently-Asked Questions List @htmlsubtitle Edition @value{edition}, for DJGPP Version 2.0 @htmlsubtitle @value{update-month} @htmlauthor by Eli Zaretskii @paragraph{} @* @* This is the DJGPP Frequently-Asked Questions List. @paragraph{} Copyright (C) 1994, 1995, 1996 Eli Zaretskii @paragraph{} This is the second edition of the FAQ list,@* and is consistent with @w{version 2.0} of DJGPP. @paragraph{} 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. @end ifinfo @ifinfo @node Top, Urgent, (dir), (dir) @top DJGPP FAQ List In DJGPP (@pxref{DJGPP, DJGPP overview}), 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. @paragraph{} But because the DJGPP project is a product of a group of volunteers, there isn't always enough time (or patience, or money @b{;-)} 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. @paragraph{} 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 @b{;-)}. @paragraph{} This is Edition @value{edition} of the FAQ, last updated @w{@value{update-date},} for DJGPP Version 2.0. @paragraph{} Another place to look for DJGPP documentation is the @www{DJGPP Knowledge Base, www.delorie.com/djgpp/doc/kb/} @paragraph{} @mail{Brennan Underwood, brennan@@mack.rt66.com} maintains a home page which is another valuable source for @www{information about DJGPP, brennan.home.ml.org/djgpp} @paragraph{} You can browse the HTML version of this FAQ list on line at @www{the DJ Delorie's Web server, www.delorie.com/djgpp/v2faq/faq.html} @paragraph{} If you browse this FAQ at DJ Delorie's server now, you can get the @www{source distribution of the FAQ right here, www.delorie.com/djgpp/v2faq/faq@value{faq-version}s.zip} @paragraph{} Also available from the DJ's server: @www{FAQ in all the supported formats, www.delorie.com/djgpp/v2faq/faq@value{faq-version}b.zip} @paragraph{} A previous version of this FAQ was @ftp{translated into French, ftp.delorie.com/pub/djgpp/v2faq/frfaq.zip}, also available @www{through the WWW, www.delorie.com/djgpp/v2faq/frfaq.zip} @paragraph{} @ifclear text The following master menu lists the major topics in this FAQ list, including all the indices. @end ifclear @ifset text Table of Contents@* *****************@* @sp 2 @format @include contents.idx @end format @* @end ifset @end ifinfo @menu * Urgent:: If you are in a hurry. * DJGPP:: What is DJGPP? * Requirements:: Hardware and software requirements for DJGPP. * Getting DJGPP:: Where and what to download? * Docs:: Where the documentation is and how to read it. * Trouble:: When the compiler (or Make, or Info, or @dots{}) crashes * Compiler performance:: How fast is the compiler? * Compiling:: Compile-time and link-time problems. * Running:: Running compiled programs. * Graphics:: Graphics under DJGPP. * Floating point:: Floating-point programs and FP emulation. * Debugging:: Debugging DJGPP programs. * Profiling:: Optimizing your programs. * Performance:: Run-time performance of DJGPP programs. * Memory:: Run-time memory issues. * Command line:: Command-line arguments handling in DJGPP. * Converting:: How to convert DOS code to DJGPP? * Low-level:: Low-level and hardware-oriented programming. * Legalese:: Legal aspects of programming with DJGPP. * Help:: How to get more help. * v2:: New in DJGPP Version 2.0. * Miscellany:: More@dots{} * About:: Contributors to this FAQ. * Topic Index:: Search here by a problem description. * Program Index:: Search here by a program name. @end menu @node Urgent, DJGPP, Top, Top @comment node-name, next, previous, up @chapter If You Are In a Hurry @quest{Do you really mean I have to read this looongish FAQ list to get my answers?} @quest{I have this problem which I absolutely MUST solve NOW! What do I do?} @ans{} No, you don't need to read @emph{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 @ifinfo @ifset text Table of Contents, at the beginning of this document. @end ifset @ifclear text @ref{Top, Table of Contents}. @end ifclear @end ifinfo @iftex Table of Contents. @end iftex If that doesn't help, try the indices at the end of this manual. You can either look up your question @ref{Program Index, by program name}, or @ref{Topic Index, by topic name}. If you don't find anything appropriate, search this FAQ for words which are pertinent to your problem. For those in a @emph{real} hurry, here are some pointers to the most important topics in this FAQ list: @itemize @bullet @item How to ask experienced DJGPP users for help? @paragraph{} Use the DJGPP News group or mailing list. For most questions, you will have your answer in a day or two. @xref{Totally lost, the details on how to ask the gurus}. @paragraph{} @item What is the best configuration of my system for DJGPP? @paragraph{} This depends on your hardware and software. @xref{Config, system configuration guidelines}. @paragraph{} @item Some files I need seem to be missing. Where do I find them? @paragraph{} Check out the @ref{What to download, list of required and optional packages}. @paragraph{} @item How do I subscribe to or unsubscribe from the DJGPP mailing list? @paragraph{} @xref{Subscribing, subscription instructions}. @paragraph{} @item How can I search News group/mailing list traffic for some info? @paragraph{} This FAQ includes the @ref{Deja vu, description of DJGPP archive search servers}, set up by @Steve{} and @DJ{}. @end itemize @node DJGPP, Requirements, Urgent, Top @comment node-name, next, previous, up @chapter What is DJGPP? @cindex DJGPP, what it is @quest{What is DJGPP?} @ans{} 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 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, @w{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. With a few exceptions (notably, the C++ class library), DJGPP is @emph{free} which makes it ideal for developing free and commercial software alike. @DJ is the developer and principal maintainer of DJGPP, but anyone is welcome and encouraged to contribute. @node Requirements, Getting DJGPP, DJGPP, Top @comment node-name, next, previous, up @chapter Hardware and Software Requirements @cindex Hardware requirements @cindex Required hardware, general @cindex Compatibility, hardware, general @cindex Compatibility, operating systems, general This chapter describes what are the hardware and software which will allow you to use DJGPP. Minimum, ``reasonable'' and optimal system configurations are listed. @menu * Minimum:: You cannot run DJGPP unless you have this. * OS/2:: But it crashes under OS/2! * Windows/NT:: Is it compatible with Win/NT? * DOSEmu:: Can I run it on Linux? * i286:: Why not? * Windows apps:: Can I write Windows applications with DJGPP? * Optimal hardware:: Here is your dream machine description. * Reasonable hardware:: For the rest of us. * Config:: How best to configure your system software. @end menu @node Minimum, OS/2, Requirements, Requirements @comment node-name, next, previous, up @section The minimum system requirements for using DJGPP @cindex Minimal hardware requirements @cindex Hardware requirements, minimal @cindex i386SX @cindex Disk space, required for installation @cindex System RAM, minimum @cindex Minimum system RAM @cindex Minimum system RAM, CWSDPMI @cindex Recommended system RAM, for C programs compilation @cindex Recommended system RAM, for C++ programs compilation @cindex C programs compilation, recommended system RAM @cindex C++ programs compilation, recommended system RAM @cindex DPMI services, required to run DJGPP @cindex DPMI services, problems with Novell NWDOS 7 @cindex Compatibility, Windows 3.x @cindex Compatibility, Windows 9x @cindex Compatibility, OS/2 @cindex Compatibility, Warp @cindex Compatibility, Windows/NT @cindex Compatibility, Novell NWDOS 7 @cindex Compatibility, Linux @pindex Windows 3.x, compatibility @pindex Windows 9x, compatibility @pindex OS/2, compatibility @pindex Warp, compatibility @pindex Windows/NT, compatibility @pindex Novell NWDOS 7, compatibility @pindex Novell NWDOS 7, buggy DPMI services @pindex Linux, compatibility @pindex CWSDPMI, minimum required system RAM @quest{What are the minimum system requirements for using DJGPP?} @quest{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?} @ans{} DJGPP requires at least 386SX CPU and between 15 and 35 MB of free disk space (@pxref{Disk space, more details on this below}), 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). @paragraph{} DJGPP will run under native DOS; any other operating system is OK if it includes a DPMI server. Environments known to run DJGPP besides native DOS: Windows 3.1 & 3.11 DOS box, OS/2 (including Warp) DOS box, Windows 95/DOS 7, Novell NWDOS 7.x (but several people have found the DPMI services of NWDOS buggy, so they should probably be turned off and CWSDPMI used instead), and Linux DOSEmu environment. @node OS/2, Windows/NT, Minimum, Requirements @comment node-name, next, previous, up @section Does it really work under OS/2? @cindex Spawning child processes, OS/2 @cindex Child processes, spawning under OS/2 @cindex Incompatibilities, OS/2 @cindex Incompatibilities, OS/2 @cindex Incompatibilities, Warp @pindex OS/2, incompatibilities @pindex Warp, incompatibilities @pindex Make crashes on OS/2 @quest{You tell me it will work under OS/2, but I'm experiencing strange crashes after several compilations @dots{}} @quest{DJGPP Make crashes when I run it on OS/2!} @ans{} There was a bug in the DPMI server of the old OS/2 versions, which is triggered by spawning child processes (like GCC does when it invokes the various compiler passes). 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 @samp{DPMI_DOS_API.} Setting it to @samp{ENABLED} instead of the default @samp{AUTO} should solve the problem. I'm also told that experimenting with the value of @samp{DPMI_MEMORY_LIMIT} sometimes solves problems on OS/2. @paragraph{} If the above doesn't help, please post the details of the crashes you see to the DJGPP News group (@pxref{Newsgroup, description of the DJGPP news group}) or mailing list (@pxref{Mailing list, how to post to the mailing list}), and somebody will help you. @paragraph{} One thing that you should remember when you run DJGPP on OS/2 is to set the @samp{DOS_DPMI_INTERFACE} to ``Enabled'' instead of ``Auto'' in the DOS session settings' box. @node Windows/NT, DOSEmu, OS/2, Requirements @comment node-name, next, previous, up @section Will it work under Windows/NT? @cindex Incompatibilities, Windows/NT @cindex Long Filenames aren't supported on Win/NT @cindex LFN API, not supported on Win/NT @cindex Cygnus GCC port to Windows @cindex Graphics, limitations on Win/NT @cindex Direct hardware access on Win/NT @pindex Win/NT doesn't allow port I/O @quest{What about Windows NT?} @ans{} Current Windows NT versions support DPMI programs in the DOS box, so DJGPP programs should run fine under NT. Therefore, beginning with DJGPP v2.0, the distribution doesn't include real-mode @file{gcc.exe} anymore, as it is not needed. @paragraph{} Note that the long filename API for DOS box is not supported by current versions of Win/NT, so you cannot have long filenames there. (There is a rumor that the new version 4.0 of WinNT will support the LFN API, but I'm told that at least the current beta versions still don't.) @paragraph{} 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 @file{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 will support @dfn{DirectX} which is a method of accessing screen, audio and other peripherals directly, so it's possible to use full GRX graphics capabilities there. @paragraph{} The Cygnus Win32 project is another port of GCC and development tools to WinNT and Win95 platforms, which specifically targets development of Windows programs. It is available @ftp{from the Cygnus archives, ftp.cygnus.com/pub/sac/win32/} or @www{through the Web, www.cygnus.com/misc/gnu-win32/} @node DOSEmu, i286, Windows/NT, Requirements @comment node-name, next, previous, up @section Can it run under Linux? @cindex Incompatibilities, Linux DOSEmu @cindex DOSEmu, incompatibilities with DJGPP @pindex Make crashes on DOSEmu @pindex Linux, needs a patch to run nested programs @quest{You say it works on Linux, but I cannot seem to run the compiler from within Make@dots{}} @quest{I can run DJGPP on Linux, but Make crashes with SIGFPE on even the simplest Makefiles!} @ans{} 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 @www{from the DJGPP mail archives, 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 @ftp{on the DJGPP ftp server, ftp.delorie.com/pub/djgpp/contrib/dpmi-dosemu-djgpp.mail}. @paragraph{} You might also need to edit the RAM section of the @file{dosemu.conf} file to make it comfortable for DJGPP. I suggest setting @samp{dpmi} and @samp{xms} to 16MB and @samp{ems} to 4MB. @paragraph{} Some users reported that @samp{Make}, and possibly other programs which use floating point computations, crash in DOSEmu environment on systems without an FPU, even if you set the @var{387} and @var{EMU387} environment variables correctly (as explained in @ref{Emulation, Setting up the FP emulator}, 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. @paragraph{} If your only problem is to run GNU Make, get the latest DJGPP port of Make, since latest ports can be configured to not issue FP instructions at all. @node i286, Windows apps, DOSEmu, Requirements @comment node-name, next, previous, up @section Can I run it on a 286? @cindex i286 @cindex Incompatibilities, i286 @quest{Why can't I run DJGPP on my 286? It has protected mode also@dots{}} @ans{} 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 @strong{is} required. @c @c !!! Mention the activity to port GCC to 16-bit processors. @c @node Windows apps, Optimal hardware, i286, Requirements @comment node-name, next, previous, up @section MS-Windows applications and DJGPP @cindex MS-Windows programming under DJGPP @cindex MS-Windows header file windows.h, where to get it @cindex Windows applications with DJGPP @cindex Win32 programming with GCC @cindex WinNT/Win95 programming with Cygnus GCC port @cindex Cygnus port of GCC for WinNT and Win95 @pindex Windows applications, writing with EMX/GCC @pindex EMX/GCC, writing Windows applications @pindex RSX extender @pindex RSXWDK2 Windows development kit @pindex windows.h header file, where to get it @pindex RSXNT toolkit for developing Win32 applications @quest{Can I write MS-Windows applications with DJGPP?} @ans{} Currently, you can only run DJGPP programs under Windows as DOS apps (i.e. inside DOS Box). If you need to write true Windows apps, try using the RSX extender with EMX port of GCC and RSXWDK kit for Windows. You can get @ftp{RSX by anonymous ftp, ftp.uni-bielefeld.de/pub/systems/msdos/misc/}. People who tried this report that you must download and unzip the RSXWDK2 source archive, not only the binaries (otherwise you'll get General Protection Faults when you try to run DJGPP programs). If you cannot reach the above site (some people say that it has closed its anonymous access), try looking @ftp{on an alternative site, hermes.hrz.uni-bielefeld.de/pub/systems/msdos/misc/}. Other locations to look are @ftp{RSXWDK on Cica mirrors, ftp.winsite.com/pub/pc/win3/programr/rsxwdk2s.zip}, or @ftp{RSXWDK on any of the @TeX{} Archive Network sites, ftp.shsu.edu/tex-archive/systems/msdos/dpmigcc/}. @paragraph{} Another problem with RSXWDK is that the Makefiles there are written for @samp{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 @file{/rsxwdk.} You will also have to recompile the libraries as they were compiled with DJGPP v1.x, and hack the v2 startup file @file{crt0.s} along the same lines as the v1 version which comes with RSXWDK. (@file{crt0.s} comes with the DJGPP source distribution, @file{djlsr@value{djgpp-version}.zip}.) @paragraph{} Apart from RSXWDK, you will need a @file{windows.h} header file. One place to find it is with the @ftp{WINE distribution, 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 @file{windows.h} from a commercial compiler, which might get you into legal trouble. @paragraph{} You will also need a @ftp{help compiler, ftp.aiai.ed.ac.uk/pub/packages/tex2rtf/rtfutils/hcp505.zip}, or try at the @ftp{Microsoft ftp site, 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. @paragraph{} A resource compiler is also required. RSXNT (below) includes one such, but I didn't yet hear any success stories using it. Anybody? @paragraph{} 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). @paragraph{} As of this writing, nobody has reported any first-hand experience of using RSXWDK with DJGPP v2.0; the above is based on user reports under v1.x. If you try RSXWDK with v2.0, please post a summary of your experience. @paragraph{} 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) and does have debugging tools included, but it needs to be registered 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 @ftp{DJGPP-specific version of RSXNT on SimTel mirrors, @SimTel{}/pub/simtelnet/gnu/djgpp/v2tk/rsxntdj1.zip}. The sources of all the RSXNT utilities can be found in @file{rsxnt1.zip} archive on Cica mirrors, in the @file{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. @paragraph{} Another way to develop Windows applications is to use the @www{Cygnus GCC/GPP port, www.cygnus.com/gnu-win32/} You can also download it @ftp{via anonymous 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 @mail{Steve Chamberlain, sac@@rtl.cygnus.com}, for more details. @paragraph{} A better (but harder) way would be to volunteer to add Windows support to DJGPP. @node Optimal hardware, Reasonable hardware, Windows apps, Requirements @comment node-name, next, previous, up @section What you @emph{should} buy @dots{} @cindex Configuration, the best @cindex System configuration, the best @cindex Environment variables, DJGPP @quest{What is the optimal system configuration for running DJGPP?} @ans{} Here is the description of your dream machine (at least for the next 6 months @b{:-)}: @itemize @bullet{} @item Hardware: @itemize @minus{} @item the fastest CPU you can find (a 200 MHz Pentium-Pro as of this writing); @item at least 512KB second-level (off-chip) cache memory; @item 128 MByte RAM; @item motherboard built around fast 32-bit-wide bus (VLB or PCI); @item SCSI-II hard disk with bus-mastering controller; @end itemize @item Software: @itemize @minus{} @item DOS, device drivers and TSRs all loaded HIGH, leaving only 5K DOS footprint in lower (under 640K) memory; @item 8 MByte RAM disk installed, @code{TMPDIR} environment variable points to it (e.g., @kbd{set TMPDIR=e:}, if E: is the RAM drive letter); @item 8 MByte of disk cache, set to delayed-write operation; @end itemize @end itemize @node Reasonable hardware, Config, Optimal hardware, Requirements @comment node-name, next, previous, up @section What most of us will @emph{actually} buy @dots{} @cindex Configuration, reasonable @cindex Compiling large source files @cindex Compiling GCC and CPP @cindex Disk cache, when compiling large programs @cindex RAM disk, when compiling large programs @cindex Compiling large programs, disk cache settings @cindex Compiling large programs, RAM disk settings @pindex GCC, compiling, memory requirements @pindex CPP, compiling, memory requirements @quest{OK, I don't have this much money. What is the @strong{reasonable} configuration?} @ans{} If you have the following machine, you should be able to stop worrying about memory and compilation performance: @itemize @minus{} @item CPU: 486DX2-66 with 256 KB off-chip cache; @item RAM: 16 MByte; @item Disk: 12 ms IDE with VLB controller, or SCSI; @item 4 MByte RAM disk; @item 3 MByte disk cache; @end itemize 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 @emph{very} large source files, either reduce the disk cache so you can give more to RAM disk, or point @code{TMPDIR} to your hard disk and make the disk cache larger, if you can. @node Config, , Reasonable hardware, Requirements @comment node-name, next, previous, up @section How to configure your system for DJGPP? @cindex Configuration, for optimal performance @cindex Optimal performance, system configuration @cindex Disk cache, recommended settings @cindex RAM disk, recommended settings @cindex Optimal performance, disk cache settings @cindex Optimal performance, RAM disk settings @cindex Optimal performance, CWSDPMI tuning @cindex Memory manager, settings for optimal performance @cindex Compiling GCC and CPP, RAM disk @cindex Slow compilation, tuning CWSDPMI @cindex Machines with low extended RAM, tuning CWSDPMI @cindex Excessive paging, tuning CWSDPMI @cindex Tuning CWSDPMI for optimal performance @pindex GCC, compiling, RAM disk @pindex CPP, compiling, RAM disk @pindex EMM386, settings for optimal performance @pindex QEMM386, settings for optimal performance @pindex CWSDPMI, setting parameters for optimal performance @pindex CWSPARAM, a program to tune CWSDPMI performance @pindex Windows, setting memory parameters for DJGPP @quest{How do I configure my system to get optimal performance under DJGPP?} @ans{} That depends on the amount of RAM you have installed in your machine. Below are some guidelines to help you. @enumerate a @item If you have 2 MBytes or less RAM installed: @itemize @bullet{} @item Don't use @strong{any} memory manager. @item Use of @samp{CWSDPMI} as your DPMI host is highly recommended. @item Remove any TSR and device drivers you don't absolutely need (like @file{SETVER.EXE}, @file{HIMEM.SYS} etc.) from your @file{CONFIG.SYS} and @file{AUTOEXEC.BAT.} @item Do @strong{not} install disk cache or RAM disk; point your @code{TMPDIR} environment variable to a directory on your hard disk. Put a sufficiently large @samp{BUFFERS=} statement into your @file{CONFIG.SYS} (I recommend setting @samp{BUFFERS=40,8}) to make DOS file operations faster. @item If you use @samp{CWSDPMI} as your DPMI host, get the @samp{CWSPARAM} program (from the @file{csdpmi@value{csdpmi-version}p.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.) @item 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. @end itemize With this configuration, GCC will run out of free physical RAM and page when compiling almost any C program and all C++ programs. If you are serious about DJGPP development, you need to buy more RAM @strong{urgently}. @item If you have 2-4 MBytes of RAM installed: @itemize @bullet{} @item Don't use @strong{any} memory manager. @item Remove any TSR and device driver you don't absolutely need (like @file{SETVER.EXE}, @file{HIMEM.SYS}) from your @file{CONFIG.SYS} and @file{AUTOEXEC.BAT.} @item 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. @item Do @strong{not} install a RAM disk; point your @code{TMPDIR} environment variable to a directory on your hard disk. @item 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. @end itemize With this configuration, GCC will still run out of free physical RAM and page when compiling large C programs and most C++ programs. Plan to buy more RAM as soon as you can. @item If you have 5-8 MBytes of RAM installed: @itemize @bullet{} @item 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. @item Load DOS, device drivers and TSRs @strong{HIGH}. @item Give your disk cache 1 MByte of RAM. Enable its delayed-write (aka write-back) feature. @item Do @strong{not} install a RAM disk; point your @code{TMPDIR} environment variable to a directory on your hard disk. @item 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. @item 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. @end itemize @item If you have more than 8 MBytes of RAM: @itemize @bullet{} @item Use a memory manager to load DOS, TSRs and device drivers @strong{HIGH}. @item 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. @item If you have more than 5 MBytes left, install a RAM disk with a size of at least 1.5 MBytes and point your @code{TMPDIR} environment variable to it. If your RAM disk is less than 4 MBytes, GCC might run out of space there for @emph{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. @end itemize @end enumerate Some people disable the delayed-write feature for safety reasons, to avoid losing files due to system crashes. In such cases, 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 @samp{SmartDrv} disk cache, this is achieved by specifying @samp{/N/F} switches instead of @samp{/X}. @paragraph{} A tutorial is available on @www{how to set up and get started with DJGPP, remus.rutgers.edu/~avly/djgpp.html} @node Getting DJGPP, Docs, Requirements, Top @comment node-name, next, previous, up @chapter Where and What to Download? @cindex DJGPP, how to get it @cindex Getting DJGPP This chapter explains where and how can you get DJGPP, and recommends which parts of the archive you should download. @menu * Where to find:: Pick up from your nearest SimTel mirror. * CCT:: Or look on one of the CCT mirrors. * How to download:: Anonymous FTP, of course! * DJGPP by WWW:: For those who use Netscape/Mosaic only. * What to download:: Look here to decide what packages you need. * Disk space:: How much disk storage do you need? * DJGPP = Fatware:: Can I do with less MBytes? @end menu @node Where to find, CCT, Getting DJGPP, Getting DJGPP @comment node-name, next, previous, up @section Where can I get DJGPP? @cindex Getting DJGPP @cindex DJGPP, where to download @cindex SimTel mirrors' list @cindex Differences between SimTel and CCT ftp sites @quest{Where can I get DJGPP?} @ans{} Look on any SimTel mirror in the pub/simtelnet/gnu/djgpp/ subdirectory. @paragraph{} Lately, there has been considerable confusion caused by the fact that the repository which was long known by the name @dfn{SimTel} is no longer called that; its new name is @dfn{CCT}. The name SimTel has moved (along with its originator and long-time manager, @mail{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 (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. @paragraph{} This section lists the SimTel mirrors; see @ref{CCT, below}, for the list of CCT sites. @table @i @titem The primary SimTel site is: @ftpdir{@SimTel{}, /pub/simtelnet/gnu/djgpp} @paragraph{} @titem Here is a list of hosts by countries that offer mirror sites: @sp 1 @titem Australia: @ftpdir{ftp.bhp.com.au, /pub/simtelnet/gnu/djgpp} @titem Newcastle, Australia: @ftpdir{ftp.iniaccess.net.au, /pub/simtelnet/gnu/djgpp} @titem Australia: @ftpdir{ftp.tas.gov.au, /pub/simtelnet/gnu/djgpp} @titem Australia: @ftpdir{sunsite.anu.edu.au, /pub/simtelnet/gnu/djgpp} @titem Austria: @ftpdir{ftp.univie.ac.at, /mirror/simtelnet/gnu/djgpp} @titem Brussels, Belgium: @ftpdir{ftp.linkline.be, /mirror/simtelnet/gnu/djgpp} @titem Aarshot, Belgium: @ftpdir{ftp.tornado.be, /pub/simtelnet/gnu/djgpp} @titem Sao Paulo, Brazil: @ftpdir{ftp.unicamp.br, /pub/simtelnet/gnu/djgpp} @titem Brazil: @ftpdir{ftp.iis.com.br, /pub/simtelnet/gnu/djgpp} @titem Bulgaria: @ftpdir{ftp.eunet.bg, /pub/simtelnet/gnu/djgpp} @titem Ottawa, Canada: @ftpdir{ftp.crc.doc.ca, /systems/ibmpc/simtelnet/gnu/djgpp} @titem Vancouver, Canada: @ftpdir{ftp.direct.ca, /pub/simtelnet/gnu/djgpp} @titem Chile: @ftpdir{sunsite.dcc.uchile.cl, /pub/Mirror/simtelnet/gnu/djgpp} @titem Beijing, China: @ftpdir{ftp.pku.edu.cn, /pub/simtelnet/gnu/djgpp} @titem Czech Republic: @ftpdir{ftp.eunet.cz, /pub/simtelnet/gnu/djgpp} @titem Prague, Czech Republic: @ftpdir{pub.vse.cz, /pub/simtelnet/gnu/djgpp} @titem Czech Republic: @ftpdir{ftp.zcu.cz, /pub/simtelnet/gnu/djgpp} @titem Espoo, Finland: @ftpdir{ftp.funet.fi, /mirrors/ftp.simtel.net/pub/simtelnet/gnu/djgpp} @titem Neuilly, France: @ftpdir{ftp.grolier.fr, /pub/simtelnet/gnu/djgpp} @titem Paris, France: @ftpdir{ftp.ibp.fr, /pub/simtelnet/gnu/djgpp} @titem Germany: @ftpdir{ftp.mpi-sb.mpg.de, /pub/simtelnet/gnu/djgpp} @titem Bochum, Germany: @ftpdir{ftp.rz.ruhr-uni-bochum.de, /pub/simtelnet/gnu/djgpp} @titem Chemnitz, Germany: @ftpdir{ftp.tu-chemnitz.de, /pub/simtelnet/gnu/djgpp} @titem Heidelberg, Germany: @ftpdir{ftp.uni-heidelberg.de, /pub/simtelnet/gnu/djgpp} @titem Magdeburg, Germany: @ftpdir{ftp.uni-magdeburg.de, /pub/simtelnet/gnu/djgpp} @titem Paderborn, Germany: @ftpdir{ftp.uni-paderborn.de, /pub/simtelnet/gnu/djgpp} @titem Trier, Germany: @ftpdir{ftp.uni-trier.de, /pub/pc/mirrors/simtelnet/gnu/djgpp} @titem Wuerzburg, Germany: @ftpdir{ftp.rz.uni-wuerzburg.de, /pub/pc/simtelnet/gnu/djgpp} @titem Athens, Greece: @ftpdir{ftp.ntua.gr, /pub/pc/simtelnet/gnu/djgpp} @titem Hong Kong: @ftpdir{sunsite.ust.hk, /pub/simtelnet/gnu/djgpp} @titem Hong Kong: @ftpdir{ftp.hkstar.com, /pub/simtelnet/gnu/djgpp} @titem Hong Kong: @ftpdir{ftp.cs.cuhk.hk, /pub/simtelnet/gnu/djgpp} @titem Jerusalem, Israel: @ftpdir{ftp.huji.ac.il, /pub/simtelnet/gnu/djgpp} @titem Naples, Italy: @ftpdir{ftp.unina.it, /pub/simtelnet/gnu/djgpp} @titem Italy: @ftpdir{cis.utovrm.it, /simtelnet/gnu/djgpp} @titem Italy: @ftpdir{ftp.flashnet.it, /pub/simtelnet/gnu/djgpp} @titem Italy: @ftpdir{mcftp.mclink.it, /pub/simtelnet/gnu/djgpp} @titem Saitama, Japan: @ftpdir{ftp.saitama-u.ac.jp, /pub/simtelnet/gnu/djgpp} @titem Saitama, Japan: @ftpdir{ftp.riken.go.jp, /pub/simtelnet/gnu/djgpp} @titem Japan: @ftpdir{ftp.iij.ad.jp, /pub/simtelnet/gnu/djgpp} @titem Japan: @ftpdir{ftp.u-aizu.ac.jp, /pub/PC/simtelnet/gnu/djgpp} @titem Japan: @ftpdir{ring.aist.go.jp, /pub/simtelnet/gnu/djgpp} @titem Japan: @ftpdir{ring.asahi-net.or.jp, /pub/simtelnet/gnu/djgpp} @titem Latvia: @ftpdir{ftp.lanet.lv, /pub/mirror/simtelnet/gnu/djgpp} @titem Malaysia: @ftpdir{ftp.jaring.my, /pub/simtelnet/gnu/djgpp} @titem Malaysia: @ftpdir{ftp.mimos.my, /pub/simtelnet/gnu/djgpp} @titem Mexico: @ftpdir{ftp.gdl.iteso.mx, /pub/simtelnet/gnu/djgpp} @titem Netherlands: @ftpdir{ftp.euro.net, /d5/simtelnet/gnu/djgpp/} @titem Utrecht, Netherlands: @ftpdir{ftp.nic.surfnet.nl, /mirror-archive/software/simtelnet/gnu/djgpp} @titem Wellington, New Zealand: @ftpdir{ftp.vuw.ac.nz, /pub/simtelnet/gnu/djgpp} @titem Bergen, Norway: @ftpdir{ftp.bitcon.no, /pub/simtelnet/gnu/djgpp} @titem Krakow, Poland: @ftpdir{ftp.cyf-kr.edu.pl, /pub/mirror/Simtel.Net/gnu/djgpp} @titem Poznan, Poland: @ftpdir{ftp.man.poznan.pl, /pub/simtelnet/gnu/djgpp} @titem Warsaw, Poland: @ftpdir{ftp.icm.edu.pl, /pub/simtelnet/gnu/djgpp} @titem Aveiro, Portugal: @ftpdir{ftp.ua.pt, /pub/simtelnet/gnu/djgpp} @titem Portugal: @ftpdir{ftp.ip.pt, /pub/simtelnet/gnu/djgpp} @titem Romania: @ftpdir{ftp.sorostm.ro, /pub/simtelnet/gnu/djgpp} @titem Slovakia: @ftpdir{ftp.uakom.sk, /pub/simtelnet/gnu/djgpp} @titem Slovenia: @ftpdir{ftp.arnes.si, /software/simtelnet/gnu/djgpp} @titem Johannesburg, South Africa: @ftpdir{ftp.is.co.za, /pub/simtelnet/gnu/djgpp} @titem Stellenbosch, South Africa: @ftpdir{ftp.sun.ac.za, /pub/simtelnet/gnu/djgpp} @titem Seoul, South Korea: @ftpdir{ftp.nuri.net, /pub/simtelnet/gnu/djgpp} @titem South Korea: @ftpdir{ftp.sogang.ac.kr, /pub/simtelnet/gnu/djgpp} @titem South Korea: @ftpdir{sunsite.snu.ac.kr, /pub/simtelnet/gnu/djgpp} @titem Spain: @ftpdir{ftp.rediris.es, /mirror/simtelnet/gnu/djgpp} @titem Stockholm, Sweden: @ftpdir{ftp.sunet.se, /pub/simtelnet/gnu/djgpp} @titem Zurich, Switzerland: @ftpdir{ftp.switch.ch, /mirror/simtelnet/gnu/djgpp} @titem Chung-Li, Taiwan: @ftpdir{ftp.ncu.edu.tw, /Packages/simtelnet/gnu/djgpp} @titem Taipei, Taiwan: @ftpdir{nctuccca.edu.tw, /PC/simtelnet/gnu/djgpp} @titem Nonthaburi, Thailand: @ftpdir{ftp.nectec.or.th, /pub/mirrors/simtelnet/gnu/djgpp} @titem Edinburgh, UK: @ftpdir{emwac.ed.ac.uk, /mirror/simtelnet/gnu/djgpp} @titem Lancaster, UK: @ftpdir{micros.hensa.ac.uk, /pub/simtelnet/gnu/djgpp} @titem London, UK: @ftpdir{sunsite.doc.ic.ac.uk, /packages/simtelnet/gnu/djgpp} @titem London, UK: @ftpdir{ftp.demon.co.uk, /pub/simtelnet/gnu/djgpp} @titem Concord, California, USA: @ftpdir{ftp.cdrom.com, /pub/simtelnet/gnu/djgpp} @titem California, USA: @ftpdir{ftp.digital.com, /pub/simtelnet/gnu/djgpp/} @titem Urbana, Illinois, USA: @ftpdir{uarchive.cso.uiuc.edu, /pub/systems/pc/simtelnet/gnu/djgpp} @titem Massachusets, USA @ftpdir{ftp.bu.edu, /pub/mirrors/simtelnet/gnu/djgpp/} @titem Rochester, Michigan, USA: @ftpdir{OAK.Oakland.Edu, /pub/simtelnet/gnu/djgpp} @titem New York, NY, USA: @ftpdir{ftp.rge.com, /pub/systems/simtelnet/gnu/djgpp/} @titem Oklahoma, USA: @ftpdir{ftp.ou.edu, /pub/simtelnet/gnu/djgpp/} @titem Corvallis, Oregon, USA: @ftpdir{ftp.orst.edu, /pub/simtelnet/gnu/djgpp} @titem Utah, USA: @ftpdir{ftp.cyber-naut.com, /pub/simtelnet/gnu/djgpp} @titem Virginia, USA: @ftpdir{mirrors.aol.com, /pub/simtelnet/gnu/djgpp/} @paragraph{} @end table @node CCT, How to download, Where to find, Getting DJGPP @comment node-name, next, previous, up @section CCT sites @cindex CCT mirrors' list @quest{Where can I find the nearest CCT site?} @ans{} 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 repository, so the CCT mirrors are in the process of renaming their directories to @file{Coast.} Therefore, if you don't find the directories listed below, replace ``SimTel'' by ``Coast'' and try again. @paragraph{} @table @i @titem The primary CCT site is in Detroit, Michigan, USA: @ftpdir{@CCT{}, /Coast/vendors/djgpp/}. @paragraph{} @titem Here is a list of hosts by countries that offer mirror sites: @sp 1 @titem Canberra, Australia: @ftpdir{archie.au, /micros/pc/SimTel/vendors/djgpp} @titem Edmonton, AB, Canada: @ftpdir{ftp.agt.net, /pub/SimTel/vendors/djgpp} @titem Prague, Czech Republic: @ftpdir{pub.vse.cz, /pub/simtel/vendors/djgpp} @titem London, England: @ftpdir{src.doc.ic.ac.uk, /pub/packages/simtel/vendors/djgpp} @titem Liverpool, England: @ftpdir{ftp.mersinet.co.uk, /pub/ibmpc/coast/vendors/djgpp} @titem London, England: @ftpdir{ftp.demon.co.uk, /pub/mirrors/simtel/vendors/djgpp} @titem Chemnitz, Germany: @ftpdir{ftp.tu-chemnitz.de, /pub/simtel/vendors/djgpp} @titem Mainz, Germany: @ftpdir{ftp.uni-mainz.de, /pub/pc/mirrors/simtel/vendors/djgpp} @titem Tuebingen, Germany: @ftpdir{ftp.uni-tuebingen.de, /pub/simtel/vendors/djgpp} @titem Hong Kong: @ftpdir{ftp.cs.cuhk.hk, /pub/simtel/vendors/djgpp} @titem Hong Kong: @ftpdir{sunsite.ust.hk, /pub/simtel/vendors/djgpp} @titem Dublin, Ireland: @ftpdir{ftp.hea.ie, /pub/simtel/vendors/djgpp} @titem Haifa, Israel: @ftpdir{ftp.technion.ac.il, /pub/unsupported/simtel/vendors/djgpp} @titem Naples, Italy: @ftpdir{ftp.unina.it, /pub/simtel/vendors/djgpp} @titem Pisa, Italy: @ftpdir{cnuce-arch.cnr.it, /pub/msdos/simtel/vendors/djgpp} @titem Rome, Italy: @ftpdir{ftp.flashnet.it, /mirror/simtel/vendors/djgpp} @titem Rome, Italy: @ftpdir{cis.utovrm.it, /SimTel/vendors/djgpp} @titem Tokyo, Japan: @ftpdir{ftp.crl.go.jp, /pub/pc/archives/simtel/vendors/djgpp} @titem Tokyo, Japan: @ftpdir{ftp.web.ad.jp, /pub/mirrors/Coast/vendors/djgpp} @titem Tokyo, Japan: @ftpdir{ring.aist.go.jp, /pub/coast/vendors/djgpp} @titem Tokyo, Japan: @ftpdir{ring.asahi-net.or.jp, /pub/coast/vendors/djgpp} @titem Seoul, Korea: @ftpdir{ftp.kornet.nm.kr, /pub/SimTel/vendors/djgpp} @titem Seoul, Korea: @ftpdir{ftp.nowcom.co.kr, /pub/SimTel/vendors/djgpp} @titem Utrecht, Netherlands: @ftpdir{ftp.nic.surfnet.nl, /mirror-archive/software/simtel-vendors/djgpp} @titem Poznan, Poland: @ftpdir{ftp.man.poznan.pl, /mirror/simtel/vendors/djgpp} @titem Warsaw, Poland: @ftpdir{ftp.icm.edu.pl, /pub/simtel/vendors/djgpp} @titem Moscow, Russia: @ftpdir{ftp.radio-msu.net, /mirror/Coast/vendors/djgpp} @titem Singapore: @ftpdir{ftp.singnet.com.sg, /pub/mirrors/SimTel/vendors/djgpp} @titem Slovak Republic: @ftpdir{ftp.uakom.sk, /pub/SimTel/vendors/djgpp} @titem Taipei, Taiwan: @ftpdir{nctuccca.edu.tw, /PC/simtel/vendors/djgpp} @titem Bangkok, Thailand: @ftpdir{ftp.bu.ac.th, /pub/SimTel/vendors/djgpp} @titem Sunnyvale, CA, USA: @ftpdir{ftp.drcdrom.com, /Coast/vendors/djgpp} @end table Note that DJGPP was moved to the @file{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 @emph{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. @node How to download, DJGPP by WWW, CCT, Getting DJGPP @comment node-name, next, previous, up @section How do I download DJGPP? @cindex Downloading DJGPP with FTP @cindex Downloading DJGPP via e-mail @cindex DJGPP, downloading with FTP @cindex FTP, downloading DJGPP @quest{How do I download files from these sites?} @ans{} FTP to the nearest site, log in as @kbd{anonymous}, give your full e-mail address as password, and chdir to the @file{djgpp} subdirectory (the exact path to it might be different on different mirrors, check out @ref{Where to find, the DJGPP archive path}, for your nearest mirror.) Then issue the @kbd{binary} command and download files you need (@pxref{What to download, the list of required files}) with the @kbd{get} command. @node DJGPP by WWW, What to download, How to download, Getting DJGPP @comment node-name, next, previous, up @section What if I don't know what @samp{FTP} is? @cindex Downloading DJGPP with WWW @cindex DJGPP, downloading with WWW @cindex WWW, downloading DJGPP @cindex DJGPP, downloading with Gopher @cindex Gopher, downloading DJGPP @cindex DJGPP, downloading via e-mail @cindex E-mail, downloading DJGPP @cindex getting DJGPP from a CD-ROM @cindex CD-ROM, getting DJGPP @pindex Netscape, downloading DJGPP @pindex Mosaic, downloading DJGPP @quest{What is that @samp{FTP} thing? I only use @samp{Mosaic} for Internet access.} @ans{} OK, here are some URLs for your Web browser: @sp 2 @itemize @minus{} @item @www{The main SimTel site, www.simtel.net/simtel.net/gnu/djgpp/} @item @www{The main CCT site, www.coast.net/Coast/vendors/djgpp/} @item @www{The CCT mirror in Rochester\, MI, www.acs.oakland.edu/oak/SimTel/vendors/djgpp/} @item @www{The CCT mirror in St. Louis\, MO, wuarchive.wustl.edu/systems/msdos/simtel/vendors/djgpp/} @end itemize You can also convert any of the mirrors' addresses listed in @ref{Where to find, the list of SimTel mirrors}, above to a valid URL by prepending @samp{ftp://} to it. For example, here is the URL for FTP from the @ftp{primary CCT FTP site, @CCT{}/Coast/vendors/djgpp/}. @paragraph{} Gopher users can access CCT files @gopher{through a Gopher client, gopher.oakland.edu}. @paragraph{} 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 @mail{CCT list server, listserv@@SimTel.Coast.NET} with this command in the message body: @example get simtel-mailserver.info @end example @node What to download, Disk space, DJGPP by WWW, Getting DJGPP @comment node-name, next, previous, up @section What Files to Download? @cindex Files, minimum set to download @cindex Packages, which to download @cindex DJGPP, a list of packages @cindex List of DJGPP packages @cindex Packages, DJGPP, list of @cindex DJGPP distribution, list of @quest{What's the minimum set of @file{.zip} files I need to download?} @ans{} This depends on what you are planning to use DJGPP for. @sp 1 @itemize @bullet{} @item To only run DJGPP-compiled programs, you MUST download all of these: @footnote{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 @news{comp.os.msdos.djgpp}.} @paragraph{} @table @file @titem v2/readme.1st This explains how to install DJGPP and get started with using it. @titem v2/faq@value{faq-version}b.zip The latest edition of this FAQ list. Use it whenever you have problems installing and using DJGPP. @titem v2misc/csdpmi@value{csdpmi-version}b.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.) @titem v2misc/pmode@value{pmode-version}b.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. @end table @paragraph{} @item For developing C programs (no C++), you MUST download all of the above, plus the following: @paragraph{} @table @file @titem v2gnu/bnu@value{bnu-version}b.zip The GNU Binutils, including @code{as}, the GNU assembler; @code{ld}, the GNU linker; and their docs. @titem v2/djdev@value{djgpp-version}.zip C header files, minimal development environment, DJGPP-specific utilities and documentation. @titem v2/djtst@value{djgpp-version}.zip A set of example programs to test your installation. @titem v2gnu/gcc@value{gcc-version}b.zip The GNU C Compiler binaries and docs (including the docs for the C++ compiler). @titem v2gnu/txi@value{txi-version}b.zip Info, a stand-alone program to read GNU hypertext documentation files, and an environment to produce such files. Without @samp{info}, you cannot read the docs included with the GNU software tools. @end table @paragraph{} @item For developing C++ programs, you will need all of the above, plus the following: @paragraph{} @table @file @titem v2gnu/gpp@value{gcc-version}b.zip The GNU C++ compiler binary (the docs are part of the gccNNNb.zip package, see above). @titem v2gnu/lgp@value{lgpp-version}b.zip The C++ header files and the GNU classes libraries, and their docs. @titem v2gnu/obc@value{gcc-version}b.zip If you want to develop Objective-C programs, you will need this file, which includes the Objective-C compiler and header files. @end table @paragraph{} @item The following are some optional packages which you might want: @paragraph{} @itemize @minus{} @item Debugging: @paragraph{} @table @file @titem v2gnu/gdb@value{gdb-version}b.zip GDB, the GNU Debugger and its docs. (Note that the @code{djdev} distribution includes two simpler debuggers, @code{edebug} and @code{fsdb.} The latter presents a user interface similar to that of Turbo Debugger.) @end table @paragraph{} @item Additional development tools (consider getting at least the Make distribution): @paragraph{} @table @file @titem v2apps/rhideb.zip The RHIDE integrated development environment for DJGPP, written by @mail{Robert Hoehne, Robert.Hoehne@@Mathematik.TU-Chemnitz.DE}. @titem v2/djlsr@value{djgpp-version}.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 it, so you can easily fix possible library bugs. @titem v2gnu/flx@value{flx-version}b.zip Flex, a Lex-like lexical analyzer generator, and its docs. @titem v2gnu/bsn@value{bsn-version}b.zip Bison, a Yacc-like parser generator, and its docs. @titem v2gnu/dif@value{dif-version}b.zip GNU Diffutils (diff, cmp, diff3, sdiff), and their docs. @titem v2gnu/mak@value{mak-version}b.zip GNU Make program with its docs. @titem v2gnu/pat@value{pat-version}b.zip GNU Patch program and docs. @titem v2gnu/sed@value{sed-version}b.zip GNU Sed program and its docs. @end table @paragraph{} @item Developing text-mode and graphics GUI applications: @paragraph{} @table @file @titem v2tk/grx@value{grx-version}.zip The DJGPP graphics library. @titem v2tk/bcc2grx.zip The interface library to convert Borland graphics calls to GRX library calls. @titem v2tk/pdc@value{pdc-version}.zip Public-domain Curses library. @end table @paragraph{} @c @item @c Fortran to C converter: @c @paragraph{} @c @table @file @c @titem f2c@value{f2c-version}.zip @c The djgpp port of the f2c converter and its support libraries. @c @end table @end itemize For description of additional files not mentioned here, get the file @file{00_index.txt}; it contains a full list of the distribution files and a short description of every file. @end itemize @node Disk space, DJGPP = Fatware, What to download, Getting DJGPP @comment node-name, next, previous, up @section How much disk space will I need? @cindex Files, required disk space @cindex Packages, required disk space @quest{Wow, that's a lot of files. How much disk storage will I need?} @ans{} The following lists the approximate disk space required for several major configurations, and additional storage required for some optional packages: @display Execution-only environment..................300 KBytes Developing C programs.......................13 MBytes Developing C++ programs.....................17 MBytes Developing Objective-C programs.............15 MBytes Additional storage for DJGPP sources........10 MBytes Additional storage for GDB..................1.1 MBytes Additional storage for Flex.................280 KBytes Additional storage for Bison................310 KBytes Additional storage for Diffutils............560 KBytes Additional storage for Make.................520 KBytes Additional storage for Patch................120 KBytes Additional storage for Sed..................73 KBytes Additional storage for Graphics libraries...4 MBytes @end display 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. @paragraph{} 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 @file{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; @samp{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 @ref{How much memory, explained below}. @node DJGPP = Fatware, , Disk space, Getting DJGPP @comment node-name, next, previous, up @section Can I get away with less megabytes? @cindex Disk space, using less of it @cindex FTP, downloading DJGPP in batch mode @c @pindex EZ-GCC, a minimal DJGPP development environment @c @cindex Minimal DJGPP development environment @c @cindex Development environment, minimal @pindex AutoWinNet, automated downloading @cindex Automated downloading from a PC @cindex Automated downloading from a Unix box @cindex Automated FTP from a Unix box @pindex BatchFTP, automated downloading from a Unix box @quest{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 @strong{fatware} disease@dots{}} @quest{Pulling that many megabytes through the net from my overloaded SimTel mirror is almost impossible. Can't you prepare a ZIP archive which only includes stuff I can't do without?} @c @ans{} A minimal installation called @samp{EZ-GCC}, courtesy of @c @mail{Anton Helm, tony@@nt.tuwien.ac.at}, is available by a WWW or @c anonymous ftp. If you have WWW access, please start with the @c @www{EZ-GCC Info Page, dictator/nt.tuwien.ac.at/ezgcc/} and get all @c further info from there. All others can obtain @ftpusr{EZ-GCC from @c Charles Sandmann's server, riceng.rice.edu, ezgcc, ezgcc}; please start by @c downloading and reading the file @file{EZ-GCC.TXT} first. @c @paragraph{} @c This minimal installation requires only 3 1.44MB diskettes for fully @c functional C/C++ development environment (including an editor), and an @c additional one each for GDB, a full set of LIBGRX fonts, and Objective C. @c @paragraph{} @ans{} 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 @ftp{2mNN.zip, @CCT{}/Coast/msdos/diskutil/2m30.zip}. @paragraph{} To make downloading DJGPP easier, download and compile the @samp{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 @samp{login refused} etc.) and also is nice to the remote server by sleeping for some time between login attempts. @samp{BatchFTP} is free software and can be found on @ftp{many FTP sites, oak.oakland.edu/pub/unix-c/networks/batchftp.tar.Z}. @paragraph{} @samp{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 @samp{AutoWinNet} (get the file @ftp{autownNN.zip from your nearest CCT mirror,@CCT{}/Coast/win3/winsock/autown19.zip}). @paragraph{} As for the minimal DJGPP installation, volunteers are welcome to prepare such an archive and make it publicly available, in the same spirit as @samp{EZ-GCC} did for DJGPP v1.x. @node Docs, Trouble, Getting DJGPP, Top @comment node-name, next, previous, up @chapter The DJGPP Documentation @cindex DJGPP Documentation This chapter explains where to find and how to read DJGPP documentation, and how to solve occasional problems with the docs system. @menu * Where is the docs:: Where to find the docs and how to read them. * No Info:: For those who can't stand Info. * Printed docs:: How to produce a printed manual. * Ready PS:: Where to find printer-ready manuals. * Can't find docs:: For some programs it's tricky @dots{} * Man pages:: How to read these. * Last resort:: Look in the source, of course! @end menu @node Where is the docs, No Info, Docs, Docs @comment node-name, next, previous, up @section Where are the documentation files? @cindex DJGPP documentation, where to find it @cindex Getting documentation @cindex Reading documentation @cindex Browsing documentation @cindex Documentation, reading @pindex Info, a stand-alone docs browser @pindex Emacs, reading Info files @pindex Emacs, reading docs @quest{I don't see any documentation files@dots{}} @ans{} The documentation files are in the @file{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: @enumerate a @item Use the stand-alone @samp{Info} reader. @paragraph{} Get the file @ftp{txi@value{txi-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/txi@value{txi-version}b.zip}, which includes @file{INFO.EXE} and its docs. Unzip it and run @samp{Info.} It will bring up a (hopefully) self-explanatory online help system. Confused? Press @kbd{?} to see the list of all Info commands. Still confused? Press @kbd{h} to have @samp{Info} take you on a guided tour through its commands and features. @paragraph{} @item Use the @samp{Info} command of your favorite Emacs-like editor. @paragraph{} If you use Emacs, you already know about @samp{Info.} (What's that? You don't? Type @kbd{C-h @key{i}} and you will get the top-level menu of all the Info topics.) @paragraph{} @end enumerate @node No Info, Printed docs, Where is the docs, Docs @comment node-name, next, previous, up @section How to read the docs without @samp{Info?} @cindex DJGPP documentation, reading as ASCII file @cindex Documentation, converting to plain ASCII @cindex Reading documentation, converting to plain ASCII @cindex Reading documentation with text editor/viewer @pindex Makeinfo, using to convert Info files to plain ASCII @quest{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??} @ans{} Info files are almost plain ASCII files, so you should be able to browse them with your favorite text file browser or editor. You will lose the hypertext structure and you might have 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. @paragraph{} @mail{Anthony Appleyard, A.APPLEYARD@@fs2.mt.umist.ac.uk} has translated the Info files for GNU C/C++ Compiler (@file{gcc.iNN}) and GNU C Preprocessor (@file{cpp.iNN}) into ISO-8859 (aka plain ASCII), and @Steve{} has made them available on his anonymous ftp and WWW server. You can get them as @file{gcc.txt} and @file{preprocessor.txt} by @ftp{anonymous ftp, turnbull.sk.tsukuba.ac.jp/pub/djgpp/doc/}; or get them @www{with your Web browser, turnbull.sk.tsukuba.ac.jp/pub/djgpp/doc/} @paragraph{} You can also produce pure ASCII files yourself, if you have their Texinfo sources. These are usually called @file{*.txi} or @file{*.tex} and should be included with the source distribution of every package. To produce an ASCII file @file{foo.txt} from the Texinfo file @file{foo.txi}, invoke the @samp{Makeinfo} program like this: @smallexample makeinfo --no-split --no-headers --output foo.txt foo.txi @end smallexample The @samp{Makeinfo} program is part of the Texinfo distribution which is available in @ftp{txi@value{txi-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/txi@value{txi-version}b.zip}. @node Printed docs, Ready PS, No Info, Docs @comment node-name, next, previous, up @section How to print the docs? @cindex DJGPP documentation, printing @cindex Documentation, converting to PostScript format @cindex PostScript documentation @cindex Printing DJGPP documentation @cindex Library docs, missing libc2.tex @cindex libc2.tex, missing file @pindex TeX, printing the docs @pindex LaTeX, printing the docs @pindex emTeX, printing the docs @pindex TEXI2PS, converting docs to crude PostScript @quest{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?} @ans{} You will need to get and install a program called @TeX{} or its work-alike, like La@TeX{} or em@TeX{}. (They are NOT part of DJGPP.) Then run your @TeX{} work-alike on the docs' @emph{source} files (called @file{*.txi} or @file{*.tex}) which you get with the source distribution of every package you download. You will get a @file{.dvi} file which you can print; or you can run a DVI-to-PostScript converter such as @samp{DVIPS} to produce a PostScript output. @samp{DVIPS} is a free program; you can find it @ftp{on SimTel mirrors, @SimTel{}/pub/simtelnet/msdos/postscrp/dvips@value{dvips-version}.zip}. @paragraph{} DJGPP comes with a program called @samp{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. @paragraph{} If @TeX{} won't run, check that you have the file @file{texinfo.tex} which defines the @TeX{} macros specific to Texinfo files. If you don't, get the GNU or DJGPP Texinfo distribution which includes that file. @paragraph{} If you'd like to produce printed docs of the library reference, @TeX{} will complain that it cannot find a file named @file{libc2.tex}. This file is generated from all the @file{*.txh} files in the DJGPP source distribution (@file{djlsr@value{djgpp-version}.zip}). In order to build this file, you need to go to @file{src/libc} and type this from the DOS command prompt: @example make doc @end example @paragraph{} Note that some docs files (notably, those for GCC) will produce voluminous print-outs. You @emph{have} been warned! @node Ready PS, Can't find docs, Printed docs, Docs @comment node-name, next, previous, up @section Where can I find docs in PostScript? @cindex DJGPP documentation, in PostScript format @cindex Documentation, in PostScript format @cindex PostScript documentation, ready-to-print @cindex DJGPP documentation, reading with a Web browser @cindex HTML format, DJGPP documentation @quest{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?} @ans{} They are @strong{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. @paragraph{} However, some @emph{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, @samp{zip} and @samp{tar.gz} format by anonymous ftp from @ftp{phi.sinica.edu.tw, phi.sinica.edu.tw/pub/aspac/gnu/}; they are all for A4 paper. Other places to look for PostScript versions of GNU documentation are: @table @asis @titem @ftp{In European A4 format, liasun.epfl.ch/pub/gnu/ps-doc/}. @titem @ftp{In US letter format, primus.com/pub/gnu-ps/}. @end table @sp 1 @paragraph{} Many GNU manuals in @samp{HTML} (hypertext) format, suitable for reading with your Web browser, can be viewed at the @www{DJGPP Web site, www.delorie.com/gnu/docs/} @paragraph{} DJGPP includes a utility called @samp{TEXI2PS} which converts the Texinfo source files to crude PostScript; try it. @node Can't find docs, Man pages, Ready PS, Docs @comment node-name, next, previous, up @section Some docs are nowhere to be found@dots{} @cindex DJGPP documentation, look in source distributions @cindex Documentation, inside source distribution archives @pindex Sed, documentation @pindex Gprof, documentation @quest{I looked in my @file{info/} subdirectory, but I can't find docs for some of the utilities, like @samp{Sed} or @samp{Gprof.}} @ans{} Download the source archive (@file{*s.zip}) for that package and look inside it, usually in the directory called @file{man} or @file{doc.} @node Man pages, Last resort, Can't find docs, Docs @comment node-name, next, previous, up @section What are these @file{foo.1} files? @cindex DJGPP documentation, in man page format @cindex Documentation, in man page format @cindex Man pages, how to read @pindex Man program for DJGPP docs @pindex Less, using to read man pages @pindex More, using to read man pages @pindex Groff, using to read man pages @pindex Groff, port to DJGPP @pindex Cawf, using to read man pages @pindex Info, using to read man pages @pindex Emacs, using to read man pages @quest{Some docs files are called @file{foo.1} or @file{bar.man} or @file{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?} @ans{} That weird format is the @samp{troff} format which is used for writing Unix manual pages. The Unix command @kbd{man} converts them to formatted text files which are usually displayed with a program like @samp{more} or @samp{less} (and here @samp{less} is considered to be more than @samp{more} @b{:-)}). 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: @itemize @bullet{} @item Get and install a DOS port of the @samp{groff} package, or port it yourself (a very difficult task). The latest @samp{groff} distribution can be found on the @ftp{GNU ftp archive, 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 @ftp{from the DJGPP ftp server, ftp.delorie.com/pub/djgpp/contrib/groff.zip}. @item Get and install @samp{CAWF}, a DOS program which knows about most of the @samp{troff} formatting commands. @samp{CAWF} can be found on one of the @ftp{CCT mirrors, @CCT{}/Coast/msdos/textutil/cawf404.zip}. @item Write or port a @samp{man} clone. Source for one such clone was posted to the DJGPP news group, so you can @www{get it there, www.delorie.com/djgpp/mail-archives/djgpp/1995/06/19/12:57:43} You can also download this port @ftp{from the DJGPP ftp server, ftp.delorie.com/pub/djgpp/contrib/man-pc.zip}. @item Format the file on any Unix machine, and download the results to your PC. Under Unix, typing @kbd{catman -p} will print the commands which are required to do this; you can then run those commands on your @file{*.1} @samp{troff} source files. @end itemize @paragraph{} 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 @ftp{a DOS port of GNU Less, @CCT{}/Coast/msdos/textutil/less291x.zip}, which uses colors to show bold and underlined letters. A DJGPP port of @samp{Less} should be available from the usual DJGPP distribution sites. Another possibility is to get the latest @ftp{official GNU Less distribution, ftp.gnu.ai.mit.edu/pub/gnu/less-@value{less-version}.tar.gz} which can be compiled out of the box with the Microsoft C and Borland C compilers. (Future versions of @samp{Less} will also compile with DJGPP.) @paragraph{} 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. @paragraph{} Beginning with version 3.6, the stand-alone @samp{Info} program can also read man pages (it invokes a subsidiary program @samp{man} to format them, then displays its output; see the file @file{readme.dj} in the DJGPP Texinfo distribution for more details on how to set this up). So if you have the DJGPP Texinfo distribution, you can read man pages with @samp{Info} already; if not, just @ftp{download Texinfo, @SimTel{}/pub/simtelnet/gnu/djgpp/txi@value{txi-version}b.zip}. @paragraph{} 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. @node Last resort, , Man pages, Docs @comment node-name, next, previous, up @section What if the docs don't say enough? @cindex DJGPP documentation, see source files @cindex Source files, using as the best docs @quest{OK, I've got the docs and have read them, but I still can't figure out some details.} @ans{} Download the sources and look there, or ask on the net---either the DJGPP News group or an appropriate GNU News group. @node Trouble, Compiler performance, Docs, Top @comment node-name, next, previous, up @chapter When the Compiler (or @samp{Make}, or @samp{Info}, or @dots{}) Crashes@dots{} @cindex DJGPP programs, problems with @cindex Problems with DJGPP programs @cindex Crash, DJGPP programs @cindex Hang, DJGPP programs @cindex Reboot, when running DJGPP programs This chapter explains how to deal with certain problems which may prevent DJGPP programs from running on your machine. The first 8 @ifinfo items on the next menu @end ifinfo @iftex sections @end iftex describe specific problems; if yours doesn't go away with these techniques, read the description of @ref{General trouble, the general debugging procedure}. @menu * No DPMI:: You must have or install a DPMI server. * Buggy DPMI:: It might crash all of your v2.x programs. * GCC optimizations:: GCC sometimes crashes when optimizing. * Fatal signal:: GCC says @strong{``Fatal signal X''}. * Unknown filetype:: GCC says @strong{``Unknown filetype''}. * QEMM AUTO:: Can't use this with DJGPP. * Make hangs:: Compiler hangs, but only under Make. * Info can't find ``Top'':: Info won't display some files. * General trouble:: Look here for any problem not covered above. * Redirect:: How to redirect GCC messages to a file. * Deja vu:: Look up your problem in the @strong{comp.os.msdos.djgpp} archives. * Totally lost:: When nothing seems to help, ask on the net. @end menu @node No DPMI, Buggy DPMI, Trouble, Trouble @comment node-name, next, previous, up @section GCC says ``No DPMI'' @cindex No DPMI error message @cindex DJGPP won't run, prints ``No DPMI'' @quest{I'm trying to run @samp{gcc}, but all I get is a message saying ``Load error: no DPMI''. What am I doing wrong?} @ans{} 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 @samp{gcc} in a DOS box under Windows) or download and install CWSDPMI (@file{csdpmi@value{csdpmi-version}b.zip}) which is a free DPMI server written for DJGPP. @node Buggy DPMI, GCC optimizations, No DPMI, Trouble @comment node-name, next, previous, up @section Buggy DPMI host or junk in DJGPP.ENV can crash v2.x programs @cindex DJGPP programs, problems with DPMI host @cindex DPMI host bugs, might crash DJGPP programs @cindex Reboot, every DJGPP program @cindex Hang, all DJGPP programs @cindex Novell NDOS, buggy DPMI services crash DJGPP @cindex DJGPP.ENV, trailing junk crashes Info @cindex ^Z character at end of DJGPP.ENV @pindex NWDOS, buggy DPMI services crash DJGPP @pindex NDOS, buggy DPMI services crash DJGPP @pindex QDPMI crashes Info @pindex Info crashes under QDPMI @pindex Info crashes due to ^Z or whitespace at end of DJGPP.ENV @quest{When I try to run Info, it crashes immediately@dots{}} @quest{I cannot run v2.0 applications: they all hang or reboot my system, while v1.x apps run OK. Is this what v2.0 is all about---getting me out of the DJGPP community?} @ans{} No, believe it or not, we don't want to oust you. Your problems might be caused by a buggy @dfn{DPMI} (@pxref{DPMI Spec, DOS Protected Mode Interface}) host installed on your machine. One DPMI host which is particularly known to be a source of trouble is the DPMI server which comes with Novell NWDOS. Please see if v2.0 programs run when you disable DPMI services of your usual configuration (DJGPP will then use the CWSDPMI program supplied with DJGPP). @paragraph{} 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 @samp{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. @paragraph{} Another cause of crashes in @samp{Info} might be trailing whitespace in the @file{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 DJGPP program can crash in this way, but since the last section of stock @file{DJGPP.ENV} belongs to @samp{Info}, it is the one which suffers most from this bug. Make sure your @file{DJGPP.ENV} doesn't have a @kbd{^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. @node GCC optimizations, Fatal signal, Buggy DPMI, Trouble @comment node-name, next, previous, up @section GCC can crash during optimization @cindex Optimization crashes GCC @cindex Tracing compilation progress with -Q @cindex Compilation progress, GCC switch @pindex GCC crashes during optimization @quest{When I compile my program, the compiler crashes, but the problem seems to go away if I compile without optimization.} @ans{} For some programs, this can be caused by an insufficient stack. Some source files make @file{cc1.exe} or @file{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 @file{cc1.exe} was able to compile it with optimizations!) Try stubediting the compiler to enlarge its stack, as described elsewhere in this FAQ, @ref{Fatal signal, how to enlarge the stack}, before you try any other remedies in this section. @paragraph{} 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 @samp{#if 0 @dots{} #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. @paragraph{} An undocumented GCC switch can sometimes help you zero in on the code fragment that causes GCC to crash. If you add @samp{-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. @paragraph{} You can also try to disable the strength-reduction optimizations of GCC by using the @samp{-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 @file{lib/specs} file.) @paragraph{} As an extreme measure, don't optimize at all, if that's the only way to make your program work. @paragraph{} 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. @paragraph{} Yet another cause for such crashes can be connected with excess memory and/or stack usage that GCC needs when compiling certain programs. For details about this, see @ref{Fatal signal, CWSDPMI allocation problems}, in the next section. @node Fatal signal, Unknown filetype, GCC optimizations, Trouble @comment node-name, next, previous, up @section What does ``Fatal signal X'' mean? @cindex Fatal signal, GCC message @cindex GCC says ``Fatal signal X'' @cindex GCC aborts with ``Internal compiler error'' @cindex Internal compiler error, when compiling C++ programs @pindex CWSDPMI runs out of virtual memory @pindex C++ compiler overflows its stack for large programs @pindex C compiler overflows its stack for large programs @quest{I get ``fatal signal 2'' when I run GCC.} @quest{GCC aborts with ``Internal compiler error'' when compiling a large C++ program.} @ans{} 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'' (dig out your DOS reference for other error codes). This means GCC couldn't find some program it needs to run to compile your source. Check the @code{COMPILER_PATH} environment variable or what the @code{COMPILER_PATH} line in the @file{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: @file{cpp.exe}, @file{cc1.exe}, @file{cc1plus.exe}, @file{cxxfilt.exe}, @file{gasp.exe}, @file{as.exe}, @file{ld.exe}, and (for Objective-C) @file{cc1obj.exe.} You can use the @samp{-v} switch to GCC to see what programs it invokes and which one of them causes the fatal error. @paragraph{} 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 @ftp{CWSDPMI heap-fix patch, 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. @paragraph{} You can also run @samp{stubedit} on @file{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 @file{cc1.exe.} @paragraph{} For a program that you wrote, another work-around is to use an alternative algorithm for @code{sbrk}, by putting the following somewhere in your program: @example @ifset html #include <crt0.h> @end ifset @ifclear html #include @end ifclear int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK; @end example Note that the unixy sbrk algorithm might cause trouble in programs that hook hardware interrupts. @node Unknown filetype, QEMM AUTO, Fatal signal, Trouble @comment node-name, next, previous, up @section What does ``Unknown filetype'' mean? @cindex Unknown filetype, GCC message @cindex Mixing v2.0 GCC with CC1PLUS from v1.x, Unknown filetype message. @cindex Virus infection cause ``Not COFF'' message @cindex Not COFF error message from DJGPP programs @pindex STUBIFY.EXE, infected by a virus @quest{I get error messages saying ``Unknown filetype'' from GCC.} @quest{Since a few days ago, whenever I try to run most of the DJGPP programs, they print a message @ifset html ``C:\\DJGPP\\BIN\\prog.exe: not COFF'' @end ifset @ifclear html ``C:\\\\DJGPP\\\\BIN\\\\prog.exe: not COFF'' @end ifclear and just terminate. Help!!!} @ans{} It might be that your @file{STUBIFY.EXE} is infected by a virus. (This is @emph{not} a joke! It did happen to a few of us and can happen even to you.) As the DOS stub prepended to the DJGPP programs is very small, most viruses cannot attach themselves to it without overwriting the beginning of the DJGPP COFF image, therefore triggering this error from the code in the stub that loads the COFF image. @paragraph{} Another possible cause of the ``Unknown filetype'' message is that you mix a v2.0 @file{gcc.exe} driver with @file{cc1plus.exe}, @file{cc1.exe} or other programs from an old v1.x distribution. @node QEMM AUTO, Make hangs, Unknown filetype, Trouble @comment node-name, next, previous, up @section You can't use @samp{QEMM} auto/off mode with DJGPP @cindex QEMM auto/off mode, conflicts with DJGPP @cindex V86 mode, QEMM and CWSDPMI problems @pindex QEMM, auto/off mode, conflicts with CWSDPMI @pindex CWSDPMI, problems with QEMM auto/off mode @quest{Why do I get error message from @samp{CWSDPMI} if I keep QEMM in auto/off mode and run DJGPP?} @ans{} 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: @smallexample "Error: Using XMS switched the CPU into V86 mode." @end smallexample @paragraph{} 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: @example c:\qemm\qemm on @end example (that assumes your QEMM directory is @file{c:\\qemm}). @node Make hangs, Info can't find ``Top'', QEMM AUTO, Trouble @comment node-name, next, previous, up @section Compiler hangs, but only when invoked from Make @cindex GCC hangs/crashes under Make @cindex Mixing v2.x Make with v1.x programs hangs the machine @cindex Spawning v2.x programs from v1.x programs doesn't work @pindex GCC hangs under Make @pindex Make, GCC hangs when invoked from it @pindex GCC from v2.x crashes under v1.x Make @quest{My compiles run OK from the command line, but hang when I invoke the compiler from Make.} @ans{} 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 @file{make.exe} is found earlier on your @code{PATH} than the Make which came with DJGPP. @paragraph{} If you use Make compiled under DJGPP v1.x, you will also experience all kinds of trouble when invoking programs compiled under DJGPP v2.0. That's because v1.x programs cannot spawn v2.0 programs directly (the v1.x program sees that the child is a DJGPP program and tries to call @code{go32} to run it, but @code{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 @code{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 @code{go32-v2} to work around this limitation (@pxref{go32-v2, description of go32-v2}, below), but I suggest doing that only if you absolutely cannot upgrade to v2's @code{Make.} @paragraph{} 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. @node Info can't find ``Top'', General trouble, Make hangs, Trouble @comment node-name, next, previous, up @section Info doesn't like some files @cindex Can't find node ``Top'', Info message @cindex Info won't display a file @pindex Info won't display a file @quest{When I run the Info browser, it tells me it cannot find the node ``Top''.} @ans{} Check your installation of info files. The file @file{DJGPP.ENV} in the root of your DJGPP installation mentions the variable @code{INFOPATH} which should point to the directory where Info looks for its files. It must find there a file named @file{dir}, the file you are trying to read, and other files with @file{.iNN} or @file{.NN} extension, where @file{NN} is a number. @paragraph{} Assuming the above checks OK, and all the necessary info files are indeed installed in those directories (did you remember to give that @samp{-d} switch to @samp{PKUNZIP?}), it might be that some of the files were edited with a DOS-based editor, which converted the @key{Newline} characters to the @key{CR}/@key{LF} pairs. Some DOS ports of Info don't like this, because this invalidates the tag tables included with the files which Info uses to quickly find the various nodes. @paragraph{} 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). @paragraph{} If you cannot upgrade for some reason, run @file{DTOU.EXE} on the offending files; it will strip the extra @key{CR} characters to make Info happy. DTOU is in the @file{bin/} subdirectory of your main DJGPP directory. @paragraph{} @node General trouble, Redirect, Info can't find ``Top'', Trouble @comment node-name, next, previous, up @section My problem isn't mentioned above! @cindex Programs crash, general troubleshooting @cindex Crashes, general troubleshooting @cindex Compiler crashes, which subprogram of @cindex GCC crashes, which subprogram of @pindex GCC crashes, which subprogram of @quest{I've installed DJGPP just like explained in the @file{README.*} files, but when I run gcc, my machine crashes/hangs/needs cold boot.} @quest{When I compile my program, gcc says ``Segmentation violation'' and prints all kinds of funny numbers and registers.} @quest{I get errors I can't figure out when I try to compile something.} @ans{} Add the @samp{-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. @paragraph{} 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 isn't. (This kind of problem usually happens on memory-starved machines.) Check out the @ref{Config, system configuration advice}, in this FAQ list and configure your system accordingly. @node Redirect, Deja vu, General trouble, Trouble @comment node-name, next, previous, up @section I can't keep up with the error messages @cindex Programs crash, saving debugging output @cindex Redirecting GCC messages to a file @cindex Standard output/error stream, redirecting to a file @cindex Error messages, redirecting to a file @pindex GCC, redirecting messages to a file @pindex 4DOS, redirecting GCC messages to a file @pindex SCRIPT, redirecting GCC messages to a file @pindex REDIR, redirecting GCC messages to a file @quest{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?} @quest{When I add @samp{-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?} @quest{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?} @ans{} There are several alternatives: @enumerate a @item You can use a shell smarter then @file{COMMAND.COM}, such as @samp{4DOS}, which knows how to redirect standard error stream to a file. 4DOS is shareware and can be found @ftp{on CCT mirrors, @CCT{}/Coast/msdos/4dos/}. @item You can also run your program under any one of the programs which save the output of programs they spawn in a file. I suggest using a program called @samp{SCRIPT}, which is similar to its Unix namesake. It has an advantage of saving everything which goes to screen @emph{and} showing it on the screen at the same time. You can find @ftp{SCRIPT on CCT mirrors, @CCT{}/Coast/msdos/screen/script11.zip}. @item Or you can use the @samp{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. @end enumerate @node Deja vu, Totally lost, Redirect, Trouble @comment node-name, next, previous, up @section How to search DJGPP archives for similar problems @cindex Programs crash, searching DJGPP archives @cindex Solved problems, searching in DJGPP archives @cindex Searching DJGPP archives @cindex Problems, searching for solution in DJGPP archives @cindex DJGPP archives, how to search @cindex Archives, DJGPP mailing list/News group, how to search @quest{OK, I have all this voluminous output of @samp{gcc -v}, but I still have no clue.} @ans{} Your problem might be one which has already been posted and solved on the DJGPP News group. @DJ has set up a searchable News group archive on @www{his Web server, www.delorie.com/djgpp/mail-archives/} You can search the @emph{entire} mailing list archives in just a few seconds. DJ's archives are always up to date, as they receive and store all posted messages automatically, but the index is updated every 24 hours, so the last day might not be searchable yet. To search the DJGPP archives at DJ's, point your Web browser to the above URL and specify a list of keywords pertinent to your problem. You will get a list of messages which include those keywords; clicking on any of the messages will get the full text of that message. @paragraph{} @Steve{} has set up another search engine which you can use to @www{search the entire news group archive for an arbitrary regular expression, turnbull.sk.tsukuba.ac.jp/cgi-bin/search} @sp 1 Point your Web browser to that URL and do whatever the instructions you get tell you. You will receive a list of lines in the archive which contain your regexp, with a two-line surrounding context. You can use this to decide which parts of the archive you need to download and read. @paragraph{} Steve's archives can also be @www{fast-searched,turnbull.sk.tsukuba.ac.jp/yaseppochi-gumi.html#djgpp} using any Web browser supporting @samp{ISINDEX} capabilities. This is faster, but supports only simple keyword searches, not regular expressions. @paragraph{} You can also download @samp{gzip}'ed copies of DJGPP correspondence split up by months (the most recent month might not be up-to-date) from the anonymous ftp server set up by @Steve{}. They are available at @ftp{turnbull.sk.tsukuba.ac.jp,turnbull.sk.tsukuba.ac.jp/pub/djgpp/list-archive/}. If you look for the traffic from a specific time period, you should look for files named @file{djgpp.YYMM.gz} (they are around 250K bytes each), where YY is the year and MM is the month number. E.g., for February 1996 traffic get the file @file{djgpp.9602.gz.} Alternatively, look for the file which holds list traffic for the year and the month you need with @www{your Web browser, turnbull.sk.tsukuba.ac.jp/pub/djgpp/list-archive/} Once you have the news group archives, or a relevant portion(s) thereof, search for your problem by using some keywords specific to your problem, like ``crash'', ``violation'', etc. The archive is just a text file, so any text file viewer/editor with search capability can do it. @paragraph{} Note that Steve's archives have fallen behind lately to some degree, due to him being busy with other matters; therefore, you could find that the archives aren't entirely up to date. Steve says that he will return to regular maintenance of the archives later this year. @node Totally lost, , Deja vu, Trouble @comment node-name, next, previous, up @section How to ask DJGPP gurus for help @cindex Problems, asking for help @cindex Gurus, asking for help @cindex DJGPP users, asking for help @cindex Asking for help @cindex Help, asking for @quest{I've searched the news group archives, but didn't find anything helpful. I am totally lost. @strong{Help!!!}} @quest{I don't have time to download all these huge files, not to mention looking through them. Can't you DJGPP gurus help me? @strong{Please??}} @ans{} DJGPP is famous for its outstandingly fast and effective 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: @itemize @bullet{} @item At the DOS command prompt, type @kbd{set > environ.lst}, then press @key{Enter}. @item Invoke the @samp{go32-v2} program (it's in your @file{bin/} subdirectory) and save its output. @item Post to the @news{comp.os.msdos.djgpp} or write to the @mail{DJGPP mailing list, djgpp@@delorie.com} and put into your message the description of your calamity, the contents of the file @file{ENVIRON.LST}, the output of @samp{go32-v2}, the contents of your @file{AUTOEXEC.BAT} and @file{CONFIG.SYS}, and what GCC printed during compilation with the @samp{-v} switch (if your problem is that GCC won't work). @item If your problem involves a program that crashes and prints a stack dump, please post that stack dump. It's best to run @code{symify} on the stack dump, and post the output of @code{symify}: @example symify -o dumpfile yourprog @end example (@xref{Crash traceback, detailed description of symify}, for more details about @code{symify.}) @item Allow for 2-3 days (more on weekends) for all the reply messages to come in, then act according to what they recommend. @end itemize 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. @node Compiler performance, Compiling, Trouble, Top @comment node-name, next, previous, up @chapter Compiler and Linker Performance @cindex Compiler speed @cindex Linker speed 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 @samp{-v} to your GCC command line and run it again. With the @samp{-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. @menu * Slow compiler:: Are your compiles slow? * Slow linker:: How to boost the linking speed. @end menu @node Slow compiler, Slow linker, Compiler performance, Compiler performance @comment node-name, next, previous, up @section Slow Compilation @cindex Compilation speed @cindex Speed of compilation @cindex Slow compilation @cindex Old CWSDPMI, influence on compilation speed @cindex BIOS setup, influence on compilation speed @cindex Disk cache, influence on compilation speed @cindex RAM disk, influence on compilation speed @cindex Disabling virtual memory for CWSDPMI @cindex Virtual memory, how to disable it for CWSDPMI @pindex GCC, slow compilation @pindex CWSDPMI, old (beta) versions slow-down compilation @pindex CWSDPMI, disabling virtual memory @quest{Why GCC is compiling sooo slooowww?} @ans{} 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: @example | Without optimization | With -O2 -----------+------------------------+------------ C++ source | 200 | 100 -----------+------------------------+------------ C source | 430 | 250 @end example @paragraph{} (Btw, these numbers are about 20% faster than you will get on a 40MHz Sparc2 box.) On machines faster or slower than 486DX2-66, scale these numbers appropriately. When comparing to this table, don't forget to count header files your program @code{#include's} in the total line count. And @strong{don't} check compilation speed on very short programs (like the classic @samp{"Hello, world!"}), because the overhead of loading the multiple passes of the compiler will completely hide the compiler performance. @paragraph{} 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 @emph{significantly} lower, you may indeed have a problem; read on. @paragraph{} 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 @samp{CWSDPMI}, use the @samp{CWSDPR0} as your DPMI host, or get the @samp{CWSPARAM} program and change the swap filename to point to a non-existent drive), or use @samp{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 @emph{is} paging. @paragraph{} 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 (@pxref{Reasonable hardware, the description of reasonable configuration}). Also see @ref{Config, recommendations for optimal software configuration}. @paragraph{} 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. In such cases, 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 @samp{SmartDrv} disk cache, this is achieved by specifying @samp{/N/F} switches instead of @samp{/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. @paragraph{} If you had some of the beta releases of v2.0 installed during the beta-testing period, be sure to upgrade your @samp{CWSDPMI} to the latest version. The memory allocation scheme has been changed halfway through the beta-testing, which made old versions of @samp{CWSDPMI} @emph{awfully} slow when used with programs linked against the new versions of the library. @paragraph{} 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: @display 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 @end display 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. @paragraph{} @DJ 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). @paragraph{} @node Slow linker, , Slow compiler, Compiler performance @comment node-name, next, previous, up @section Slow Linking @cindex Linking speed, improve by stub-editing ld.exe @cindex Network installation makes linking slow @cindex Slow linking, possible reasons @pindex ld, how to improve linking speed @quest{The compiler finishes in a few seconds, but then the linker grinds away for more than a minute, even on a very short program@dots{}} @ans{} Try linking the trivial @samp{"Hello, world!"} program; it should take no more than 7-10 seconds. If you see much slower linking on your system, then the following advice might help you. @paragraph{} A few users have reported that they got much faster linking after they've stub-edited @file{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. @paragraph{} 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. In such cases, 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 @samp{SmartDrv} disk cache, this is achieved by specifying @samp{/N/F} switches instead of @samp{/X}. @paragraph{} For very large (several MBytes) executables which are built from a large number of small source files, the link stage might be the one which needs more RAM than you have free, and thus be the bottleneck of the time it takes to build your program. Check that the size of the executable isn't larger than the amount of your free RAM. If it is, then it might make sense to use a smaller (or even no) disk cache, and allow the linker as much physical RAM as it needs. Be sure that the linker wasn't stub-edited to make its transfer buffer too small. @paragraph{} Another reason for slow linking might be that the @file{DJGPP.ENV} file by default sets @code{TMPDIR} to a @file{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 @code{TMPDIR} to a directory on your local drive, or to a RAM disk, would probably make linking faster. @node Compiling, Running, Compiler performance, Top @comment node-name, next, previous, up @chapter Compile-time and Link-time Problems @cindex Compile-time problems @cindex 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. @paragraph{} This chapter explains how to solve some of those problems which tend to appear when compiling and linking your programs. @menu * Missing headers/libraries:: GCC can't find header files/libraries. * Missing C++ headers:: GCC can't find C++ header files. * C++ comments:: Avoid C++ comments in C programs. * Which language:: GCC resolves it by looking at filename extensions. * Objective C:: Can't use ObjC 2.6.0. * DJGPP-specific:: How to write DJGPP-specific fragments. * Unresolved externals:: Where are those library functions? * Which library:: Which library has which functions? * Libraries' order:: Which libraries to put first? * Still unresolved:: C++ misses complex and iostream functions. * Class Complex:: It is now a complex template class. * Pure virtual:: Problems with pure virtual functions in C++. * djgpp_first_ctor:: Why are these unresolved? * Large image:: Static arrays bloat C++ program image. * Large executable:: Why is DJGPP .EXE so large? * Win95 LNK files:: These can cause DJGPP Linker to fail. * No EXE:: Novell Netware fails STUBIFY. * Large object files:: Linker fails for large objects/libraries. @end menu @node Missing headers/libraries, Missing C++ headers, Compiling, Compiling @comment node-name, next, previous, up @section GCC can't find headers or libraries @cindex Header files, GCC can't find @cindex Libraries, GCC can't find @cindex crt0.o, GCC can't find @cindex Missing header files @cindex Missing libraries @cindex Missing crt0.o @cindex Linker fails to find crt0.o under Novell @cindex DJGPP environment variable, how to set and test @cindex Long filenames in setting DJGPP env. variable @cindex DJGPP environment variable, setting under LFN @cindex DJGPP.ENV syntax explained @pindex GCC can't find headers @pindex GCC can't find libraries @pindex GCC can't find crt0.o @pindex GCC, environment variables @pindex DJGPP.ENV syntax explained @pindex DJGPP.ENV, compiler environment variables @pindex DJGPP.ENV, beware of blanks when setting @pindex Novell 3.x, linker doesn't find crt0.o @pindex Win95, setting DJGPP environment variable @pindex WinNT, setting DJGPP environment variable @quest{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?} @quest{When I link my programs, ld.exe complains that it cannot open crt0.o, although that file exists in the lib subdirectory@dots{}} @ans{} 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: @example set DJGPP=c:/djgpp/djgpp.env @end example and it should point to the correct path of the file @file{DJGPP.ENV} on your system (the file itself comes with the file @ftp{djdev@value{djgpp-version}.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2/djdev@value{djgpp-version}.zip} in the DJGPP distribution). In the above example it is assumed to be in the @file{C:/DJGPP} directory, but you should set it as appropriate for your installation. @paragraph{} Sometimes, people make errors in their @file{AUTOEXEC.BAT} that cause the @var{DJGPP} variable to be defined incorrectly, or not defined at all (some of the more common causes are listed below). To check what is the actual setting, type from the DOS prompt: @example set > env.lst @end example then examine the contents of the file @file{env.lst}. You should see there a line like this: @example DJGPP=c:/djgpp/djgpp.env @end example If a line such as this isn't there, you should investigate the cause for this (see below for some of the possibilities). @paragraph{} Many problems with setting @var{DJGPP} happen when people put excess blanks around the @kbd{=} 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. @paragraph{} Another possible cause of @var{DJGPP} variable not being set is that you invoke another batch file from your @file{AUTOEXEC.BAT} before the line that sets @var{DJGPP}. Make sure such batch files are invoked with the @code{CALL} statement, because otherwise the batch file will never return (that's a ``feature'' of DOS batch file processing). @paragraph{} The code that processes @file{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. @emph{Do NOT move DJGPP.ENV to any other directory!} @paragraph{} 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 @strong{cannot} use long names of the directories in the pathname of @file{DJGPP.ENV} when you set the above variable in the environment; you should use their 8+3 names instead. First, some of these systems (such as WinNT) do not even support the LFN API for DOS programs. But even if LFN API @emph{is} supported, e.g. on Win95, DJGPP won't know that it should support LFN until @emph{after} it read @file{DJGPP.ENV}---it's a chicken-and-egg problem. For example, the following setting @strong{won't work}: @example set DJGPP=c:/programs/Development/Djgpp/djgpp.env @end example If the DJGPP variable is set correctly, then check the following possible causes of this misbehavior: @itemize @bullet{} @item You have edited the file @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 @file{DJGPP.ENV} before you edit it. The DJGPP server has a page with a @www{description of the DJGPP.ENV syntax, www.delorie.com/djgpp/doc/kb/kb_7.html#SEC7} @item Some older versions of Novell Netware cause the linker to fail if the libraries or the startup file @file{crt0.o} reside on a networked drive. This is due to a peculiarity of Novell that happens to fail the library function @code{stat} in some cases. The exact reason of the failure has been identified, and the next release of the library will include a version of @samp{stat} that works around that problem, so future releases of the linker will be free of this bug. As a temporary work-around, move all the libraries and @file{crt0.o} to a local drive. @footnote{Don't forget to add that directory to the @samp{LIBRARY_PATH} line on @file{DJGPP.ENV.}} Another solution would be to upgrade your Novell software; version 4.x is reportedly free of this problem. @item You renamed the @file{gcc.exe} driver to some other name. In this case, you should edit the file @file{DJGPP.ENV} to add a section named after the new name of GCC, which is an exact duplicate of the section called @samp{[gcc].} DJGPP start-up code uses this file to find environment variables which it should put into the environment before your @code{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. @item Your @samp{FILES=} setting in @file{CONFIG.SYS} is insufficient, so GCC runs out of available handles. @paragraph{} You should have at least @samp{FILE=15} in your @file{CONFIG.SYS.} @item Your DJGPP directory is on a networked drive, and the network redirector doesn't have enough available handles in its configuration. @paragraph{} 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. @item You passed the @samp{-B} switch to GCC. This overrides the default location of @file{crt0.o} and if you follow @samp{-B} with a directory other than that where @file{crt0.o} resides, the linker won't find it. @paragraph{} You should not need to use the @samp{-B} or @samp{-L} switches at all if your installation is correct and the @code{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 @samp{-L} or @samp{-B}, check out above for the possible causes. @end itemize @node Missing C++ headers, C++ comments, Missing headers/libraries, Compiling @comment node-name, next, previous, up @section GCC can't find C++ headers @cindex Header files, C++, GCC can't find @cindex Missing C++ header files @cindex C++, missing header files @pindex iostream.h, GCC can't find @pindex _string.h, GCC can't find @pindex Regex.h, GCC can't find @pindex Complex.h, GCC can't find @pindex stdiostream.h, GCC can't find @pindex streambuf.h, GCC can't find @pindex GCC can't find C++ headers @pindex Win95 long filenames and C++ headers @quest{I installed all the packages, but GCC complains it can't find @file{iostream.h}, @file{_string.h} and other C++ headers. Where can I find those header files?} @quest{GCC complains about being unable to find @file{Complex.h}, @file{Regex.h} and other header files which start with a capital letter, and I indeed don't see them in my @file{lang/cxx/} directory. Where are they?} @quest{My C++ program needs header files whose filenames exceed the 8+3 DOS filename restrictions, like @file{stdiostream.h} and @file{streambuf.h}, and GCC cannot find those files. How in the world can I write portable C++ programs??} @ans{} C++ include files are in the file @ftp{lgp@value{lgpp-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/lgp@value{lgpp-version}b.zip}. Files whose names usually start with a capital letter, on MS-DOS have an underscore `_' prepended so they can be distinguished from @file{complex.h}, @file{regex.h} and the like under case-insensitive DOS. Change @code{Complex.h} to @code{_complex.h} in your source, and GCC will find them. @paragraph{} One possible cause for problems with C++ include files is that your source file has a @file{.c} extension. GCC then thinks that this is a C program and doesn't search the C++ include directories. Rename your file to @file{.cc} or @file{.cpp} extension, or call GCC with the @samp{-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 @ref{Which language, list of language-specific suffixes}, elsewhere in this FAQ. @paragraph{} 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 @dfn{Long File Names} (LFN) support in DJGPP, by setting the @code{LFN} environment variable to @code{No}, like this: @example set LFN=n @end example (DJGPP comes with LFN disabled by default on the @file{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: @itemize @bullet{} @item From the ``Start'' menu select ``Run'' and type @samp{regedit}, to start the Registry Editor. @item Expand the @code{HKEY_LOCAL_MACHINE} branch of the registry until you see in the left pane an item called @code{HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\FileSystem}, then click on it. @item The right pane now shows the list of values assigned to the @code{FileSystem} key. If you don't see an item there called @code{NameNumericTail}, select ``New'', ``Binary Value'' from the ``Edit'' menu, then type @samp{NameNumericTail} and it will appear. Now double-click on @code{NameNumericTail} and enter a value of 0. @item Restart Windows 95. @end itemize If the @code{NameNumericTail} set to 0 breaks some programs, you can restore its original setting after you've renamed the files as described above. @code{NameNumericTail} only affects the short names of new files being created, it has no effect on the files that already exist. @node C++ comments, Which language, Missing C++ headers, Compiling @comment node-name, next, previous, up @section GCC barfs on C++-style comments in C programs @cindex C++-style comments in C programs, GCC won't compile @cindex Comments, C++-style in C programs @cindex -ansi switch and C++-style comments in C programs @cindex -traditional switch and C++-style comments in C programs @pindex GCC won't compile C++-style comments in C programs @quest{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.} @ans{} 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 @samp{-ansi} or @samp{-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 (@pxref{Which language, list of language-specific suffixes}), or use @samp{-x c++} switch. If it's a C program, but you want to compile it as C++ anyway, try @samp{-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++: @example @ifset html #include <stdio.h> @end ifset @ifclear html #include @end ifclear int main () @{ printf ("%d \n" 10 //* / 2 //*/ 1 ); return 0; @} @end example (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.) @paragraph{} If you must have both @samp{-ansi} and C++-style comments, you can use the @samp{-lang-c-c++-comments} preprocessor switch. Gcc doesn't accept the @samp{-lang-XXX} switches on its command line, so you will have to use the @samp{-Wp} option, like this: @example gcc -c -Wp,-lang-c-c++-comments myprog.c @end example Alternatively, you can add @samp{-lang-c-c++-comments} to the @code{*cpp:} section of your @file{lib/specs} file (but that will make it permanent). @paragraph{} 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 @samp{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: @smallexample sed "s?//\(.*\)?/*\1 */?" file.c > newfile.c @end smallexample Sed can be found @ftp{in the DJGPP distribution, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/sed@value{sed-version}b.zip}. @node Which language, Objective C, C++ comments, Compiling @comment node-name, next, previous, up @section How does GCC recognize the source language? @cindex GCC can't recognize file format @cindex GCC can't recognize source language @cindex File format not recognized by GCC @cindex Letter case in filenames submitted to GCC @cindex Compilation messages, bogus @pindex GCC, file source language recognition @pindex GCC doesn't recognize file format @pindex GCC, @samp{-v} switch shows the compilation passes @quest{I type @kbd{GCC PROG.CC} and GCC complains that it can't recognize @file{PROG.CC}'s file format. How come a C++ compiler doesn't recognize a C++ source??} @quest{I type @kbd{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.} @ans{} That's because you typed your source file extension in @emph{upper} case. GCC is @emph{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: @table @file @ifclear html @titem .cc @end ifclear @ifset html @titemx .cc @end ifset @titemx .C @titemx .cxx @titeml .cpp C++ source (passed through cpp). @titem .c C source that must be passed through cpp first. @titem .i Raw C source (no cpp pass). @titem .ii Raw C++ source (not to be preprocessed). @titem .m Objective-C source. @titem .S Assembler that must be passed through cpp first. @titem .s Raw assembler source (no cpp pass). @end table Any other file is passed to the linker, under the assumption that it's an object file. In the examples above, @file{PROG.C} is taken as a C++ program, not a C one, and @file{PROG.CC} is passed to the linker as if it were an object file. You can see what GCC does by adding the @samp{-v} switch to the GCC command line; if you see that it's invoking @file{cc1plus.exe} (the C++ compiler) instead of @file{cc1.exe} (the C compiler), or calling @file{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 @samp{-v}, see @ref{Redirect, how to capture GCC output}, in this FAQ. @paragraph{} You can override the default rules gcc uses to decide how each input file should be treated, with the help of the @samp{-x LANGUAGE} switch. For instance, the command @example gcc -x c++ prog.c @end example compiles @file{prog.c} as C++ source. @extref{Overall Options, @w{-x LANGUAGE} switch description, gcc, The GNU C Compiler Manual, www.delorie.com/gnu/docs/gcc/gcc_8.html#SEC11}, for more info on @samp{-x} options. @node Objective C, DJGPP-specific, Which language, Compiling @comment node-name, next, previous, up @section Problems with Objective C @cindex Compiling Objective C sources @cindex Objective C, compiling @pindex Objective C, compilation problems @quest{How do I tell gcc my .cc file is to be compiled as Objective-C source?} @quest{I compile an Objective-C program, but get unresolved symbols.} @quest{I can't compile the Objective-C test program which came with DJGPP.} @ans{} Give your sources the @file{.m} extension, or use @w{@samp{-x objective-c}} switch to GCC, so it will @emph{know} you mean to compile with @w{Objective C}. @paragraph{} 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. @node DJGPP-specific, Unresolved externals, Objective C, Compiling @comment node-name, next, previous, up @section Writing codes fragments which are specific to DJGPP @cindex DJGPP-specific code @cindex Code, DJGPP-specific @cindex Pre-processor symbols, DJGPP-specific @cindex __DJGPP__ pre-processor symbol @cindex __GO32__ pre-processor symbol @quest{I must put a DJGPP-specific code fragment into my program. What symbol should I use in the @code{#ifdef} directive to make it only visible under DJGPP?} @ans{} Use @code{__DJGPP__}, like this: @example #ifdef __DJGPP__ ... DJGPP-specific code ... #else ... not seen under DJGPP ... #endif @end example @code{__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: @example #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 @end example Another DJGPP-specific pre-processor symbol which DJGPP defines is @code{__GO32__}; but it is only provided for compatibility with previous versions of DJGPP (v1.x) and its use should be discouraged. @node Unresolved externals, Which library, DJGPP-specific, Compiling @comment node-name, next, previous, up @section Unresolved externals when linking programs @cindex Unresolved externals @cindex Unresolved externals in C++ programs, use GXX @cindex Linking programs, unresolved library functions @cindex Linking C++ programs, use the GXX driver @cindex Library functions, linker won't find @cindex Floating-point math functions, standard and high-quality @cindex C++ STL library, not in lgp271b distribution @cindex STL library, not in lgp271b distribution @pindex Linker can't find library functions @pindex iostream library, why use it @pindex obstack package @pindex regex package from GNU @pindex libgpp library @pindex libg++ library @pindex libstdc++ standard templates library @pindex math library, default ANSI/ISO and high-quality functions @pindex gxx driver, searches C++ libraries automatically @pindex gxx driver, not in gcc272b distribution @quest{Why do I get so many unresolved symbols when linking my programs?} @ans{} By default, GCC instructs the linker to only look in two libraries: @file{libgcc.a} and @file{libc.a.} Some functions aren't included there, so the linker can't find them. GPL library routines, like obstack and regex packages are in @file{libgpl.a} library; append @samp{-lgpl} to the link command line to use them. To use C++ classes in the @file{libgpp.a} (it's called @file{libg++.a} on Unix systems), append @samp{-lgpp.} The Standard C++ Template classes are in @file{libstdcx.a} (it's called @file{libstdc++.a} on Unix); append @samp{-lstdcxx.} @paragraph{} When linking C++ programs, you can use the @samp{gxx} instead of @samp{gcc} command; it will then instruct the linker to also scan the C++ libraries automatically, so you don't have to remember doing that yourself. @paragraph{} Note that the first release of DJGPP v2.0 didn't include @file{gxx.exe} and the C++ STL library @file{libstdcx.a.} If you cannot find them on your machine, download the latest @file{gcc272b.zip} and @file{lgp271b.zip} archives that are dated 22-Feb-96 or later. @paragraph{} If your program uses a lot of floating-point math, or needs math functions beyond those specified in the ANSI/ISO standard, consider appending @kbd{-lm} to your link command line. The basic math functions required by ANSI/ISO standard are included in the @file{libc.a} library, but @file{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. @node Which library, Libraries' order, Unresolved externals, Compiling @comment node-name, next, previous, up @section How not to lose your head with all these libraries @cindex Libraries, searching for functions @cindex Functions, which is in what library @pindex NM, printing library contents @quest{I'm lost with all those different libraries. How in the world can I find out which functions are included in which library?} @ans{} You can use the @samp{nm} program to check what functions are included in a library. Run it with the @samp{-C} option and with the library as its argument and look in the output for the name of your function (the @samp{-C}, or @samp{--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 @code{T} before their name. For example, the following is a fragment from the listing produced by @samp{nm}: @example 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. . . . @end example Here we see that the module @file{stdio.o} defines the functions @code{clearerr}, @code{feof}, @code{ferror}, @code{fileno}, @code{getc}, @code{getchar}, @code{putc} and @code{putchar}, and calls functions @code{_filbuf} and @code{_flsbuf} which aren't defined on this module. @paragraph{} Alternatively, you can call @samp{nm} with the @samp{-s} or @samp{--print-armap}, which will print an index of what symbols are included in what modules. For instance, for @file{libc.a}, we will see: @example c:\djgpp\lib> nm --print-armap libc.a . . . _feof in stdio.o _ferror in stdio.o _fileno in stdio.o . . . @end example which tells us that the functions @code{feof}, @code{ferror} and @code{fileno} are defined in the module @file{stdio.o.} @paragraph{} @samp{nm} is fully described in the GNU docs. @extref{nm, the Binutils package docs, binutils, GNU Binutils Manual, www.delorie.com/gnu/docs/binutils/binutils_6.html#SEC5}. @node Libraries' order, Still unresolved, Which library, Compiling @comment node-name, next, previous, up @section DJGPP uses a one-pass linker @cindex Libraries, order on compilation/link command line @cindex Linking programs, unresolved library functions, libraries' order @cindex Library functions, linker won't find, libraries' order @cindex Library functions, linker won't find in non-default directories @cindex Environment variables, linker @pindex Linker can't find library functions in non-default directories @pindex Linker, order of libraries in the command line @pindex DJGPP.ENV, linker environment variables @pindex Linker, environment variables @quest{I give all the libraries to gcc, but I still get unresolved externals when I link. What gives?} @ans{} @samp{Ld} is a one-pass linker: it only scans each library once looking for unresolved externals it saw @emph{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 @emph{after} all the object files, and in this order: @example -lgpp -lstdcxx -lgpl -lm @end example E.g., to link files main.o and sub.o into a C++ library, use the following command line: @example gcc -o main.exe main.o sub.o -lgpp -lstdcxx -lgpl @end example or, if you compile and link in one command: @example gcc -o main.exe main.cc sub.cc -lgpp -lstdcxx -lgpl -lm @end example If you have any libraries of your own, put them @emph{before} the above system libraries, like this: @example gcc -o main.exe main.cc sub.cc -lmylib -lgpp -lstdcxx -lgpl -lm @end example When you use the @samp{gxx} compilation driver to compile a C++ program, it names the C++ libraries in the correct order. @paragraph{} If your installation tree is different from the default, i.e., if you keep the libraries @strong{not} in the default @file{lib/} subdirectory, then you should add that directory to the line in the @samp{[gcc]} section of your @file{DJGPP.ENV} file which starts with @samp{LIBRARY_PATH}, or put into your environment a variable called @code{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 @code{LIBRARY_PATH} will have no effect, because this variable is only known to the gcc driver. So if you must call @samp{ld} directly, use the @samp{-L} option to tell it where to look for the libraries. @node Still unresolved, Class Complex, Libraries' order, Compiling @comment node-name, next, previous, up @section C++ functions still not found @cindex Unresolved externals, C++ @cindex Linking programs, unresolved C++ library functions @cindex Library functions, C++, linker won't find @cindex Inline functions, linker won't find @pindex Linker can't find some C++ library functions @pindex iostream functions, linker can't find @pindex complex.h functions, linker can't find @pindex GCC won't find inline functions without -O @quest{I put all the libraries in the above order, but the linker still can't find some C++ functions from @file{complex.h} and @file{iostream.h.}} @ans{} These functions are declared @code{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 @samp{-O.} @node Class Complex, Pure virtual, Still unresolved, Compiling @comment node-name, next, previous, up @section Where is class Complex? @cindex Complex class is not in libgpp.a @cindex Complex template class @cindex Complex class, porting to libgpp.a 2.7.1 and later @quest{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?} @quest{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?} @ans{} The latest Draft C++ Standard has changed its notion of complex numbers, and the latest versions of Libg++ have followed suit. Instead of @code{class Complex} there is now a @emph{template} @code{class complex}, and @code{Complex} is now a typedef which uses that template class. Look into the headers @file{lang/cxx/_complex.h} and @file{lang/cxx/std/complext.h} and you will see that change. Part of the code found previously on @file{complex.cc} in the Libg++ source distribution is now found on @file{cdinst.cc} source file in the STL sources (look inside @file{libstdcx.a}), another part is scattered between the various files included at compile time (such as @file{lang/cxx/std/dcomplex.h} and @file{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 @file{libgpp.a.} Programs that use class Complex need to be edited to replace every instance of @code{class Complex} to either just @code{Complex} or @code{class complex.} @paragraph{} 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. @node Pure virtual, djgpp_first_ctor, Class Complex, Compiling @comment node-name, next, previous, up @section The linker complains about __pure_virtual function. @cindex Unresolved __pure_virtual function in C++ @cindex __pure_virtual, unresolved function @quest{When I link a C++ program, the linker complains about ``__pure_virtual'' being an unresolved symbol. What should I do?} @ans{} This problem is caused by a @file{libgcc.a} library which lacks a module called @code{___pure_virtual} (yes, with @emph{three} leading underscores!). You should get an updated version of that library which includes such a module. @file{libgcc.a} comes with the Gcc distribution, so look in the latest @file{gccNNNb.zip} file. @paragraph{} If, for some reason, you cannot find @file{libgcc.a} with that module, you can add it yourself. To this end, create a file called @file{pure.c} with this content: @example #define MESSAGE "pure virtual method called\n" void __pure_virtual() @{ write(2, MESSAGE, sizeof(MESSAGE) - 1); _exit(-1); @} @end example Compile this file and put the object file into @file{libgcc.a}, like this: @display gcc -c pure.c ar rvs libgcc.a pure.o @end display That's all! @node djgpp_first_ctor, Large image, Pure virtual, Compiling @comment node-name, next, previous, up @section Unresolved djgpp_first_ctor @cindex djgpp_first_ctor, unresolved by linker @cindex djgpp_first_dtor, unresolved by linker @cindex linker won't find djgpp_first_dtor symbol @cindex unresolved externals, djgpp_first_ctor @pindex GCC cannot resolve djgpp_first_ctor symbol when linking @pindex LD linker, linker script defines djgpp_first_ctor @quest{I do everything like your praised FAQ says, but the linker complains about unresolved symbols with strange names like @samp{djgpp_first_ctor}, @samp{djgpp_last_dtor}, etc. I looked in every library with @code{nm}, and I cannot find these creatures. Where in the world are they??} @ans{} These symbols are defined by the @file{djgpp.lnk} linker script that should be in your @file{lib/} subdirectory. When you call @samp{gcc} to link a program, it invokes @file{ld.exe} with the option @samp{-Tdjgpp.lnk.} If you invoke @samp{ld} directly (this is generally not recommended), be sure to include that switch. If you did invoke it through @samp{gcc}, maybe your linker is set up incorrectly. Add @samp{-v} to the GCC switches and check that the command line that GCC gives to LD includes that switch, that your @file{lib/} subdirectory includes that script file, and that the script file is intact and includes the definition of the above symbols. @paragraph{} Another reason might be that you have edited your @file{DJGPP.ENV} file in a way that prevents the linker from finding its @file{djgpp.lnk} script. @paragraph{} 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. @node Large image, Large executable, djgpp_first_ctor, Compiling @comment node-name, next, previous, up @section C++ programs yield large @file{.exe} file @cindex C++ programs, large executable @cindex Static array enlarges C++ executable @cindex Executable, bloated by static array @cindex -fconserve-space switch @pindex GCC, -fconserve-space switch @quest{It seems that declaring a large @code{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?} @ans{} This only happens in C++ programs and is a (mis-)feature of GCC. You can use the @samp{-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 @samp{-fconserve-space} switch is described in the GCC docs, @extref{C++ Dialect Options, GNU C Compiler docs, gcc, GNU C Compiler Manual, www.delorie.com/gnu/docs/gcc/gcc_11.html#SEC14}. @paragraph{} If the downside of using this switch doesn't deter you, you can even add this switch to your @file{lib/specs} file to make it permanent. @node Large executable, Win95 LNK files, Large image, Compiling @comment node-name, next, previous, up @section Why are DJGPP @file{.exe} files so large? @cindex Executable size, how to make smaller @cindex Compressing DJGPP executables @cindex EXE compressor for DJGPP @cindex Debugging symbols, how to strip from executables @cindex Executable, how to strip off debugging symbols @pindex DJP, an executable compressor for DJGPP @pindex STRIP makes executables smaller @quest{I compiled a trivial ``Hello world'' program and got a 32KB executable file. That's ridiculously bloated!} @quest{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?} @ans{} 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: @itemize @bullet{} @item Part of the code that used to be inside @samp{go32} is now part of the library and thus gets linked into every program. @item The v2 startup code is much more powerful, but also larger. @end itemize 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. @paragraph Apart from getting to protected-mode, the DJGPP startup code also includes such functionality as command-line argument 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 handling, FPU detection and emulator loading, which were part of @samp{go32} in v1.x, are now also part of the startup code. @paragraph{} 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 @code{__crt0_glob_function}, @code{__crt0_load_environment_file}, and @code{__crt0_setup_arguments.} By defining empty substitutes for all three of these, you can make the ``Hello'' program be 18KB on disk. @paragraph{} You can make your program image still smaller by compressing it with @code{DJP} which is a DJGPP-specific @ftp{executable compressor, @SimTel{}/pub/simtelnet/gnu/djgpp/v2misc/mlp104b.zip}. It is fast and has no memory overhead. @paragraph{} And of course, don't forget to link with @samp{-s} switch to @samp{gcc}, or to run @samp{strip} on the COFF output of the linker. This strips off the debugging symbols and makes the executable quite a lot smaller (not recommended except when distributing production programs, because this makes debugging very hard indeed). @paragraph{} 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. @node Win95 LNK files, No EXE, Large executable, Compiling @comment node-name, next, previous, up @section Linker complains about @file{djgpp.lnk} @cindex Linker fails because of Win95 shortcut files @cindex Shortcut files under Win95 fail DJGPP linker @pindex Windows 95, shortcut files conflict with ld @quest{I run DJGPP under Windows 95, but the linker complains about @file{djgpp.lnk} file@dots{}} @ans{} Do you have a shortcut to DJGPP in your current directory? If so, and if you call that shortcut @code{djgpp}, Windows will create a file @file{djgpp.lnk} in your working directory. In that case, when @file{ld.exe} looks for its linking script, it will find this file instead, and will be totally confused by its format and contents. @node No EXE, Large object files, Win95 LNK files, Compiling @comment node-name, next, previous, up @section Linker fails to produce the EXE program under Novell @cindex Linker fails to produce executable under Novell @cindex Novell, linker or STUBIFY don't produce executable @pindex STUBIFY fails to produce .EXE under Novell @quest{When I link my program, it fails to produce the .EXE executable, but only if I do this on a networked drive@dots{}} @quest{I run STUBIFY on a networked drive under Novell, but it doesn't produce a .EXE file. How come?} @ans{} 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 @samp{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 @samp{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: @enumerate @item You can remove the other files, rename them, or move them to another directory that isn't searched by Novell. @item You can rename the program you are trying to link. @item You can change the way Novell searches for files (aka @dfn{the search mode}), so that it won't look in the directories on your PATH. @item 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. @item You can change the search mode for @samp{STUBIFY} and the linker (or for any other program that gives you that trouble) by running commands like these: @example SMODE stubify.exe 2 SMODE ld.exe 2 @end example @end enumerate @node Large object files, , No EXE, Compiling @comment node-name, next, previous, up @section Linker fails for large object files or large libraries @cindex Linker fails for large libraries or object files @pindex ld fails for large libraries and object files @quest{Whenever I define very large static arrays in my program, the linker fails saying ``could not read symbols: Bad value''. Huh??} @quest{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?} @ans{} This is a known bug in @file{ld.exe} from GNU Binutils 2.5.2. Until it is corrected in some future version, these are your alternatives for a work-around: @itemize @bullet{} @item In case of a large library, split it into several smaller ones. @item For a module that defines large data structures, move some of the static data to other files, or allocate the space at runtime with @code{calloc.} @end itemize @node Running, Graphics, Compiling, Top @comment node-name, next, previous, up @chapter Running Compiled Programs @cindex Run-time problems This chapter discusses various problems which may happen when running DJGPP programs under different environments, and gives solutions to them. @menu * v2.x crash:: Program which was OK in v1.x bombs in v2.0. * Crash traceback:: How to make sense out of stack dumps. * File data corrupted:: The DOS @emph{TEXT}/@emph{BINARY} file issue. * Screen I/O:: Beware of the buffering! * Distributing:: DJGPP programs are @strong{not} self-contained. @end menu @node v2.x crash, Crash traceback, Running, Running @comment node-name, next, previous, up @section My program crashes only in v2.0! @cindex Program crashes in v2.0, but not in v1.x @cindex Uninitialized memory crashes v2.0 programs @cindex v2.0, program crashes @cindex DEADBEAF, use to spot uninitialized memory @cindex Null pointer dereference crashes v2.0 programs @cindex Crashes, v2.0 programs @cindex Page fault error message from CWSDPMI @pindex CWSDPMI crashes programs which dereference NULL pointers @quest{I have this program which runs fine when compiled with DJGPP v1.12, but crashes and burns in v2.0. Isn't it obvious that you guys blew it with v2.0?} @quest{My v2.0 program crashes, but only under CWSDPMI; it runs OK under other DPMI hosts like Windows, OS/2 or QDPMI. Is this a bug in CWSDPMI?} @ans{} Not necessarily so, it could still be a bug in your program which just went unnoticed in v1.12. One area where such things can happen is use of uninitialized memory. In v1.x, memory first allocated to the stack or by a call to @code{malloc} is always zeroed, but v2.0 doesn't behave this way, so your program might exhibit erratic behavior or crash with @code{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. @paragraph{} To check whether this is the source of your grief, include the header @code{crt0.h} in your @code{main} and set @code{_crt0_startup_flags} to @code{_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 @code{_crt0_startup_flags} to @code{_CRT0_FLAG_FILL_DEADBEAF} @i{(don't laugh!)}; this will cause the sbrk()'ed memory to be filled with the value @code{0xdeadbeaf} (@code{-559838801} in decimal) which is easy to spot with a debugger. Any variable which has this value was used without initializing it first. @paragraph{} 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 @dfn{NULL pointer protection}). This feature can be disabled by setting the @code{_CRT0_FLAG_NULLOK} bit in @code{_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. @paragraph{} An insufficient stack size can also be a cause of your program's demise, see @ref{Stack size, setting the stack size}, below. @node Crash traceback, File data corrupted, v2.x crash, Running @comment node-name, next, previous, up @section What is that gibberish printed when my program crashes? @cindex Traceback, how to read @cindex Crash traceback, how to read @cindex Stack dump, how to read @pindex SYMIFY, a program to read crash traceback @pindex REDIR, redirecting stack dump to a file @quest{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?} @ans{} Those ``funny-looking numbers'' @emph{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 @samp{SYMIFY} program (it is included in the @ftp{djdev@value{djgpp-version}.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2/djdev@value{djgpp-version}.zip}, and should be in your @file{bin/} subdirectory). To this end, make sure that your program was compiled with the @samp{-g} switch, linked @strong{without} the @samp{-s} switch and @strong{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: @example symify your-program-name @end example You will see the list of source files and line numbers right next to their hex addresses. Now you can start debugging. @paragraph{} You can ask @samp{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: @example symify -o problem.dmp yourprog @end example You can also save the raw stack trace (without source info) to a disk file and submit it to @samp{SYMIFY} later, like this: @example symify -i core.dmp yourprog @end example 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 @ref{Redirect, redirect the stack trace to a file}, e.g., with the @samp{REDIR} program which comes with DJGPP. @paragraph{} But what if you @emph{didn't} compile your program with @samp{-g}, and you aren't sure how to recreate the problem which crashed it, after you recompile? Well, you can submit the stack dump @emph{after} you recompile your program. Just press that PrintScreen key or otherwise save the stack trace, then submit it to @samp{SYMIFY} from a file as described above, after you've recompiled the program. Be sure to give gcc all the compilation switches (sans @samp{-s}) that you gave it when you originally compiled your program (in addition to @samp{-g}), including the optimization switches, or else the addresses shown in the stack trace might be invalid. @node File data corrupted, Screen I/O, Crash traceback, Running @comment node-name, next, previous, up @section Reading and writing binary files @cindex Files, reading and writing @cindex Binary data I/O @quest{I'm reading/writing data files, but the data gets corrupted.} @quest{When I read a file I get only a small portion of it.} @ans{} Are your data files binary? The default file type in DOS is ``text'', even when you use the @code{read} and @code{write} library functions. Text files get their Newlines converted to @key{CR}-@key{LF} pairs on write and vice versa on read; reading in ``text'' mode stops at the first @key{^Z} character. You must tell the system that a file is binary through the @code{b} flag in @code{fopen}, or @code{O_BINARY} in @code{open}, or use the @code{setmode} library function. You can also use the low-level @code{_read} and @code{_write} library functions which give you the direct interface to the DOS file I/O. @node Screen I/O, Distributing, File data corrupted, Running @comment node-name, next, previous, up @section Buffered screen I/O surprises @cindex Screen I/O @cindex Interactive programs, screen I/O @cindex gotoxy doesn't work with `printf' @cindex Color text cannot be printed with `printf' @cindex printf cannot print color text @quest{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.} @quest{Help! I cannot make `gotoxy' work! The text I print appears on the screen in incorrect locations after I use `gotoxy'!} @quest{Why does the text appear in the default colors even though I call `textcolor' and `textbackground'?} @ans{} Do you write to screen using buffered I/O (@code{fprintf}, @code{fputs} and the like) functions, or send your output to the C++ @code{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. @paragraph{} It is usually a bad idea to use buffered I/O in interactive programs; you should instead use screen-oriented functions like @code{cprintf} and @code{cputs.} If you must use buffered I/O, you should be sure that both @code{stdout} and @code{stderr} are line-buffered or unbuffered (you can change the buffering by calling the @code{setvbuf} library function); another solution would be to @code{fflush} the output stream before calling any input function, which will ensure all pending output is written to the operating system. While this will work under DOS and DJGPP, note that some operating systems (including some DOS extenders) might further buffer your output, so sometimes a call like @code{sync} would be needed to actually cause the output be delivered to the screen. @paragraph{} The functions that set text attributes only affect the screen-oriented output (aka @dfn{conio}) functions (@code{cputs}, @code{cprintf} etc.), the text written by @code{fprintf} and other @dfn{stdio} functions doesn't change. This is unlike some 16-bit DOS compilers where @code{stdio} functions can also print colored text. @node Distributing, , Screen I/O, Running @comment node-name, next, previous, up @section What do DJGPP programs need to run? @cindex Distributing DJGPP programs @cindex DPMI, required to run DJGPP programs @cindex DJGPP-compiled programs can't find DPMI @cindex Stand-alone DJGPP programs that don't need DPMI @pindex CWSDPMI, should be distributed with DJGPP programs @pindex PMODE/DJ, can be used to produce stand-alone programs @quest{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?} @ans{} No, you don't. You can either (1) bring the @file{CWSDPMI.EXE} free DPMI host to the target machine and put it in the same directory as your compiled program or somewhere along the @code{PATH}, or (2) install another DPMI host (such as QDPMI, 386Max, Windows, etc.) on the target machine. Note that the author of CWSDPMI, @CWS{}, requests a notification by mail or acknowledged e-mail in case you distribute CWSDPMI with a commercial or shareware product. @paragraph{} 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. @xref{Emulation, floating-point emulation issues}. @paragraph{} Future DJGPP releases might have a way to bind your executable with @samp{CWSDPMI} to produce a stand-alone program. If you need such a feature @strong{now} and if you need it @strong{badly}, write to @CWS{} and ask him about a modified stub code that creates an image of CWSDPMI if none is found first time the program is run. @paragraph{} You can bind @samp{PMODE/DJ} with your program, but remember that @samp{PMODE/DJ} doesn't support virtual memory, so such programs will only run on machines with enough free physical RAM. @node Graphics, Floating point, Running, Top @comment node-name, next, previous, up @chapter Writing and Running Graphics Programs @cindex Graphics issues This chapter discusses some problems and explains some subtle points related to graphics programming under DJGPP. @paragraph{} A tutorial is available on @www{graphics programming with DJGPP, remus.rutgers.edu/~avly/djgpp.html} @menu * Which driver:: What driver to use with your SVGA? * Direct access:: Under protected-mode it is (almost) forbidden. * GRX and Windows:: Windows can mess up your graphics screen. @end menu @node Which driver, Direct access, Graphics, Graphics @comment node-name, next, previous, up @section What GRX driver to use with your SVGA @cindex Graphics driver setup @cindex SVGA types supported by GRX @cindex VESA support by GRX @pindex GRX, supported SVGA types @pindex UNIVBE, software VESA 2.0 emulation @quest{Why won't GRX work with my SVGA adapter in any resolution but the standard VGA?} @quest{How do I tell GRX which driver to use with my SVGA?} @ans{} In order for GRX to work with your SVGA, you should set the @code{GRX20DRV} environment variable, like this: @example set GRX20DRV=et4000 gw 1024 gh 768 nc 256 @end example 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: @table @samp @titem ati28800 The ATi 28800 chip-set. @titem cl5426 Cirrus Logic CL-GD5426 or higher (like CL-GD5428) chip-set. @titem et4000 Tzeng Labs ET4000 chip-set. @titem mach64 The ATi Mach-64 SVGA. @titem stdega The standard EGA adapter. @titem stdvga The standard VGA adapter. @titem VESA For any VESA-compatible adapter. @end table After you set the @code{GRX20DRV} variable, run @file{modetest.exe} to see what modes you have available. @paragraph{} If your chip-set is not one of the above, try the @samp{VESA} driver because many adapters support the VESA BIOS extensions. If yours doesn't, try installing a VESA BIOS emulator, like @ftp{UNIVBE, @CCT{}/Coast/msdos/graphics/univbe51.zip}. @node Direct access, GRX and Windows, Which driver, Graphics @comment node-name, next, previous, up @section Accessing the video memory @cindex Accessing video memory @cindex Video memory, direct access @cindex Graphics, direct video access @cindex Text-mode video memory access @cindex Far pointer memory access @cindex Accessing VBE 2.0 linear frame buffer @cindex Linear frame buffer access @cindex VBE 2.0 linear frame buffer access @quest{I try to access the video memory at @code{0xa0000}, but get ``Segmentation violation'' @dots{}} @quest{How can I access the text-mode video memory of my VGA?} @ans{} 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 @code{_farpeekb} and @code{_farpokew}; they are described in the C Library reference. @xref{Xfer, more details on using ``farptr'' functions to access absolute addresses in low memory}, below. @paragraph{} For text-mode screen updates, you can also use the @code{ScreenUpdate} and @code{ScreenUpdateLine} library functions to quickly update the screen from a text buffer. @paragraph{} Using the @code{_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), @xref{Xfer, using the ``nearptr'' access facilities}, as described below. @paragraph{} 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 @ftp{VBE example code by Charles Sandmann, ftp.neosoft.com/pub/users/s/sandmann/vbe.zip}. You can also reach this file @www{via the Web, www.rt66.com/~brennan/djgpp/vbe.zip} @node GRX and Windows, , Direct access, Graphics @comment node-name, next, previous, up @section Graphics screen restoring under Windows @cindex Screen contents not restored under Windows @cindex Graphics screen messed up under Windows @pindex Windows messes up graphics screen @quest{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?} @ans{} Windows only saves the VGA screen in standard VGA modes (1..13h) when you switch away from a DOS application. In any other mode it only saves/restores the video mode @emph{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. @paragraph{} The only reasonable thing to do is to dedicate a ``hotkey'' in your application (e.g., @kbd{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 @code{GrSetMode}, as there are a few bad Windows video drivers which do not restore SVGA graphics modes properly upon the switch back. @node Floating point, Debugging, Graphics, Top @comment node-name, next, previous, up @chapter Floating Point Issues and FP Emulation @cindex Floating-point emulation @cindex Floating-point issues @cindex Emulation, floating-point This chapter deals with issues pertaining to floating-point code and floating-point emulation under DJGPP. @menu * Emulation:: What are your emulation options. * Other emulators:: You can't use them. * OS/2 emulation:: It doesn't serve DJGPP programs. * -msoft-float:: This GCC switch isn't supported. * Numeric exceptions:: Don't give us these NaN's! * Emulator accuracy:: Not always as good as we'd like. * SIGFPE with ObjC:: Objective C cannot run without FPU. * SIGFPE in ldexp:: Some libm functions bomb. @end menu @node Emulation, Other emulators, Floating point, Floating point @comment node-name, next, previous, up @section Floating code without 80387 @cindex Emulator library @cindex Library, floating-point emulation @cindex Distributing DJGPP programs, FP emulator @cindex Floating-point emulation doesn't work @pindex libemu.a FP emulation library @pindex emu387.dxe, distribution with DJGPP programs @pindex WMEMU, an alternative floating-point emulator @pindex WMEMU causes undefined references when linking @quest{I don't have an 80387. How do I compile and run floating point programs?} @quest{What shall I install on a target machine which lacks hardware floating-point support?} @ans{} Programs which use floating point computations and could be run on machines without an 80387 should either be linked with the @file{libemu.a} emulation library (add @samp{-lemu} to your link command line) or be allowed to dynamically load the @file{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 @file{.exe} file (the emulator functions will be used only if no hardware floating point support is detected at runtime). You should @strong{always} do one of the above when you distribute floating-point programs. @paragraph{} A few users reported that the emulation won't work for them unless they explicitly tell DJGPP there is no x87 hardware, like this: @example set 387=N set emu387=c:/djgpp/bin/emu387.dxe @end example 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 @CWS{} and ask him for guidance. @paragraph{} There is an alternative FP emulator called @samp{WMEMU} (get the file @file{v2misc/wmemu@value{wmemu-version}b.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 @file{wmemu387.dxe}, or distribute the source or objects to your entire program, if you link it with @file{libwmemu.a}). Its advantage is that with @samp{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 @file{libwmemu.a} without recompiling it.) Note, however, that even @samp{WMEMU} doesn't solve all the problems of debugging FP programs on a non-FPU machine (e.g., emulating flags doesn't work). @node Other emulators, OS/2 emulation, Emulation, Floating point @comment node-name, next, previous, up @section Other FP emulators cannot be used with DJGPP @cindex Floating-point emulation, non-DJGPP emulators @cindex Non-DJGPP floating-point emulators @quest{I have an 80387 emulator installed in my @file{AUTOEXEC.BAT}, but DJGPP-compiled floating point programs still doesn't work. Why?} @ans{} DJGPP switches the CPU to @emph{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 @emph{must} use emulators which are designed for DJGPP. @node OS/2 emulation, -msoft-float, Other emulators, Floating point @comment node-name, next, previous, up @section Floating-point emulation under OS/2 @cindex Floating-point emulation, under OS/2 @pindex OS/2, floating point emulation @quest{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?} @ans{} OS/2 installs an emulator for native OS/2 images, but does not provide FPU emulation for DOS sessions. @node -msoft-float, Numeric exceptions, OS/2 emulation, Floating point @comment node-name, next, previous, up @section DJGPP doesn't support @samp{-msoft-float} @cindex -msoft-float switch to GCC @cindex Floating-point emulation, -msoft-float switch @pindex GCC, -msoft-float switch @quest{I've read in the GCC Info file that gcc has a @samp{-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?} @ans{} The GCC Info file also says that the library required by @samp{-msoft-float} is @strong{not} part of the GNU C compiler. As nobody wrote such a library for DJGPP (yet), this option currently isn't supported. @node Numeric exceptions, Emulator accuracy, -msoft-float, Floating point @comment node-name, next, previous, up @section Numeric exceptions---sometimes @cindex Numeric exception, program crash @cindex Crash, numeric exception @cindex Programs crash, numeric exception @cindex Coprocessor setup, change with _control87 @pindex CTRL87, control numeric exceptions @pindex _control87, change coprocessor setup @quest{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?} @ans{} 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 @dfn{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. There is a program called @ftp{ctrl87.c, ftp.delorie.com/pub/djgpp/contrib/ctrl87.zip}, which enables this kind of diddling of the 80x87 control word; check it out. There is also a library function called @code{_control87} which can be used from within a program to set the coprocessor to a non-default state. @node Emulator accuracy, SIGFPE with ObjC, Numeric exceptions, Floating point @comment node-name, next, previous, up @section Floating point inaccuracies when using emulator @cindex Inaccuracies, using emulator @cindex Emulator, floating-point inaccuracies @cindex Pi, accurate computation @cindex atan, inaccuracies with FP emulator @quest{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 @strong{not} using a buggy Pentium CPU.)} @ans{} 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 @code{atan} function. So if you use @code{atan(1.)} to get the value of @samp{Pi}, that might be your problem. Solution: make @samp{Pi} a constant, as God intended. The header file @code{} includes the constant @code{M_PI} which you can use; or get the value of @www{@b{Pi} from the net, www.diku.dk/~terra/pi.html} @node SIGFPE with ObjC, SIGFPE in ldexp, Emulator accuracy, Floating point @comment node-name, next, previous, up @section Floating point exception in Objective-C programs @cindex Objective-C programs crash with FP exception @cindex Floating-point exception in Objective-C program @pindex Objective-C, cannot run on machines without FPU @quest{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@dots{}} @ans{} 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 @www{in the DJGPP mail archives, www.delorie.com/djgpp/mail-archives/djgpp/1996/05/05/11:05:21} You will have to get the GCC source distribution @file{gcc272s.zip}, install the above patch, rebuild @file{cc1obj.exe}, and then recompile @file{libobjc.a} to make the problem go away. @node SIGFPE in ldexp, , SIGFPE with ObjC, Floating point @comment node-name, next, previous, up @section Floating point exception in libm functions @cindex ldexp crashes programs with FP exception @cindex Functions from libm.a crash with SIGFPE @cindex Math functions crash with SIGFPE @quest{When I use the @code{ldexp} function, my program crashes with SIGFPE. What's wrong?} @ans{} There is a bug in the scaling code in @file{libm.a} library released with DJGPP v2.0 which affects several library functions such as @code{ldexp}. A work-around is to link without @samp{-lm} switch; this will cause @samp{GCC} to use math functions from @file{libc.a}. If you need math functions which are only in @file{libm.a}, or if you need @file{libm.a} for better numerical performance, @ftp{a patched version of libm is available, ftp.lstm.ruhr-uni-bochum.de/pub/djgpp/libm.zip}, courtesy of @mail{Tom Demmer, Demmer@@LStM.Rurh-Uni-Bochum.De}. DJGPP v2.01 corrects this bug, so upgrade to that version if and when it's available to you. @node Debugging, Profiling, Floating point, Top @comment node-name, next, previous, up @chapter Debugging DJGPP Programs @cindex Debugging issues This chapter discusses the debuggers you can use with DJGPP and answers some of the questions you might have when debugging DJGPP programs. @menu * How to debug:: What should you do to debug a program. * Old QDPMI:: Some QDPMI versions will crash the debugger. * GDB needs COFF:: GDB can't use the @b{.exe} program. * Transfer buffer:: Beware---debuggers use the transfer buffer. * Debug graphics:: Debugging GUI programs. * GDB and C++ source:: Problems with non-@b{.cc} extensions. * C++ classes in GDB:: Class members' names in GDB. * Included source:: Debuggers have problems with included files. * Debugging woes:: Some programs which cannot be debugged. @end menu @node How to debug, Old QDPMI, Debugging, Debugging @comment node-name, next, previous, up @section How to run a DJGPP program under debugger @cindex Debugger, usage @cindex Debuggers for DJGPP programs @cindex Compilation for debugging @cindex Floating-point, debugger support @cindex DXE can be debugged with EDEBUG32 @cindex argv[0] when program runs under a debugger @pindex GDB, debugging DJGPP programs @pindex FSDB, the full-screen debugger @pindex GCC, compiling for debugging @pindex GDB, how is it different on MS-DOS @pindex GDB, init file name @pindex GDB, name of the READLINE init file @pindex GDB cannot restart the debuggee @pindex GDB doesn't pass command-line arguments to debuggee @pindex GDB, slow loading of symbols and sources @pindex GDB, conflicts with file redirection @pindex EDEBUG32 can debug a DXE @quest{How do I debug my programs?} @ans{} First, remember to use the @samp{-g} switch when you compile and link. This puts debugging information into your executable. When linking, don't use the @samp{-s} switch, and give the name of the output file @emph{without the .exe extension}, so that @samp{gcc} will leave both the COFF output and the DOS executable after the link stage. Here are a few examples of compilation and link command lines when you intend to debug a program: @example 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 @end example (Note that with @samp{gcc}, you can use optimization switches when compiling with @samp{-g.}) Then, to debug the program, use a command line like this (here for @samp{gdb}): @example gdb myprog @end example You can use one of several available debuggers with DJGPP: @enumerate a @item @samp{FSDB}, the full-screen debugger, from the @samp{djdev} distribution. This presents a user interface like that of Borland's Turbo Debugger, but unlike TD, @strong{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 @samp{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 @samp{FSDB} is that you cannot easily examine the contents of complex data structures. Remember to prepend an underscore @kbd{_} to the names of C identifiers when you use them with @samp{FSDB}; for C++ programs you will have to find out the mangled names of static class variables and methods to make @samp{FSDB} understand them. @item The GNU Debugger, @samp{GDB} (get the file @ftp{gdb@value{gdb-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/gdb@value{gdb-version}b.zip}. This is a powerful source-level debugger, but it uses a line-oriented user interface. People who are familiar with using @samp{GDB} on Unix should know about the following important differences in its operation on MS-DOS: @itemize @bullet{} @item The command-line arguments can be only passed to the debuggee from within the debugger (use the @samp{set args} or @samp{run} commands), not from the @samp{GDB} command line. @item You cannot rerun the debuggee when it exits. You must exit @samp{GDB} and restart it. @item @samp{GDB} is currently configured for DJGPP in a way that makes loading a program and reading a source file when a breakpoint is hit @strong{exceedingly} slow: it can take more than a minute for a very large program. Be patient and don't decide that @samp{GDB} is wedged unless you've waited several minutes. @item @samp{GDB} doesn't know about PC-specific keys, so you cannot use the arrow keys for command history editing. Use ASCII control keys instead (@kbd{^F} for forward character, @kbd{^B} for backward character, @kbd{^P} for previous line, @kbd{^N} for next line, etc.). @item The debugger and the debuggee share their file handles. This means that if your program redirects or closes its @code{stdin} or @code{stdout}, you will be unable to communicate with @samp{GDB.} @item The initial commands are read from a file named @file{gdb.ini} instead of @file{.gdbinit} which isn't a legal filename under MS-DOS. @item @samp{GDB} uses the GNU @samp{readline} package for its input. The @samp{readline} init file (@file{~/.inputrc} on Unix) is called @file{inputrc} on MS-DOS and should be in the root directory of the current drive. @end itemize @item @samp{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 (@pxref{DXE, explanation of what a DXE is}), because @samp{GDB} doesn't support debugging DXEs. @end enumerate You invoke any debugger like this: @ifset html @example <debugger-name> <program> <args...> @end example @end ifset @ifclear html @example @end example @end ifclear Note that the @code{argv[0]} parameter under the debugger is @emph{not} the full pathname of the debuggee, so programs which use @code{argv[0]} for their operation might behave differently under a debugger. @node Old QDPMI, GDB needs COFF, How to debug, Debugging @comment node-name, next, previous, up @section You need QEMM 7.53 or later @cindex Debugger crashes under QEMM/QDPMI @cindex Disabling QDPMI @pindex QEMM crashes debugger @pindex QDPMI crashes debugger @pindex QDPMI, how to disable @pindex GDB crashes under QEMM/QDPMI @pindex FSDB crashes under QEMM/QDPMI @quest{Whenever I call any DJGPP debugger to debug my program, it crashes immediately.} @ans{} Are you running under Quarterdeck's QDPMI? Then you should upgrade to QEMM 7.5 patch-level #3 or later. That patch corrects a subtle problem in QDPMI which was triggered by the debugger. If you cannot or wouldn't upgrade, for money or love, turn OFF the DPMI services of QDPMI and use @samp{CWSDPMI} as your DPMI host. To disable QEMM DPMI services either uninstall QDPMI, or go to the QEMM directory and issue the following command: @example qdpmi off @end example @node GDB needs COFF, Transfer buffer, Old QDPMI, Debugging @comment node-name, next, previous, up @section GDB won't debug unless it sees COFF output @cindex Debugging with GDB, needs COFF output @cindex COFF output from linker, how to get @pindex GDB needs COFF output @pindex Linker, how to get COFF output @quest{I try invoking GDB on my program, but it says: ``not in executable format: File format not recognized.'' Huh?} @ans{} Most probably, you've invoked GDB on a @file{.exe} program. GDB needs to be called with the name of un-stubbed COFF executable as its argument. To get both a @file{.exe} and a COFF file, you should make your link command line look this way: @example gcc -o foo foo.o @end example instead of @example gcc -o foo.exe foo.o @end example (the latter will only produce @file{foo.exe}, while the former produces both @file{foo}, the COFF executable which gdb needs, and @file{foo.exe}). To produce a COFF file from a @file{.exe} program, use the @file{EXE2COFF} program which comes with DJGPP, like this: @example exe2coff foo.exe @end example @node Transfer buffer, Debug graphics, GDB needs COFF, Debugging @comment node-name, next, previous, up @section Debuggers use the transfer buffer. @cindex Debuggers use transfer buffer @cindex Transfer buffer, use when debugging @quest{My program corrupts files and screen writes, and otherwise behaves strangely when run under a debugger.} @ans{} 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. @paragraph{} To work around this, don't step with the debugger through your functions which use the transfer buffer. @paragraph{} 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. @node Debug graphics, GDB and C++ source, Transfer buffer, Debugging @comment node-name, next, previous, up @section How to debug a graphics program @cindex Debugging graphics programs @cindex Graphics programs, debugging @cindex Monochrome monitor, redirecting screen output @cindex Code page change might prevent MSHELL from working @pindex GDB, debugging graphics programs @pindex MSHELL, redirecting screen output @pindex MSHELL fails because of TSR programs @pindex CHCP DOS command might prevent MSHELL from working @quest{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.} @ans{} Redirect the debugger output to your printer, like this: @ifset html @example gdb myprog > prn @end example @end ifset @ifclear html @example gdb myprog > prn @end example @end ifclear This will only work if the program itself doesn't write to stdout (this is usually the case with graphics programs); otherwise the debugger output will get mixed up with your program's output. @paragraph{} 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 @kbd{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 @ftp{FSDB with graphics support, ftp.delorie.com/pub/djgpp/contrib/gnudebug.zip} is available that knows about many graphics modes (it can also be found @ftp{on the Oulu repository, x2ftp.oulu.fi/pub/msdos/programming/djgpp2/gnudebug.zip}). @paragraph{} As yet another possibility, consider using the @samp{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. @samp{MSHELL} was written by @DJ and is available as @ftp{mshell10.zip, 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 @samp{MSHELL} won't help you. For example, changing the code page (with the DOS @samp{CHCP} or @samp{MODE} commands) might do this. @node GDB and C++ source, C++ classes in GDB, Debug graphics, Debugging @comment node-name, next, previous, up @section GDB finds only @file{.cc} source @cindex Debugging C++ programs @cindex Debugger cannot find C++ source @cindex C++ source, debugger cannot find @pindex GCC, assumes C++ source is @file{.cc} @quest{When I try to debug my C++ programs, the debugger claims it can't find the source file:} @example file.cc: No such file or directory. @end example @emph{The source file @strong{is} there, but it's called @file{file.cpp}, not @file{file.cc.} Why does this happen?} @ans{} It's a bug in GCC. It erroneously assumes that a C++ source always has a @file{.cc} extension. Until this bug is corrected in some future version of GCC, you're better off calling your C++ files @file{*.cc.} If this is unacceptable, then you can work around this bug by invoking @samp{cc1plus} and the assembler pass manually. The bug in GCC manifests itself in that @samp{cc1plus} is called with the option @samp{@w{-dumpbase file.cc}.} If you replace this with @samp{@w{-dumpbase file.cpp}} (or whatever your extension is), the debugger will happily find your sources. @node C++ classes in GDB, Included source, GDB and C++ source, Debugging @comment node-name, next, previous, up @section Can GDB print class members? @cindex Class method name in GDB @cindex Class static variable name in GDB @cindex Method name in C++, how to pass to GDB @cindex C++ class variables under GDB @cindex C++ method names under GDB @pindex GDB, how to use C++ method names @pindex GDB, how to use C++ class variables' names @quest{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?} @ans{} No, you don't. @samp{GDB} @emph{does} allow you to use the original names, it's just that it usually treats the @kbd{::} in their names as word delimiters. Include the name of the method or a class static variable in single quotes, and @samp{GDB} will recognize them as a single word. For example, if your class @code{CMPForward} has a method named @code{go} which you need to put a breakpoint in, use the following command: @example b 'CMPForward::go' @end example Other @samp{GDB} features that might be useful in this context are the various demangling options, like @samp{set print demangle}, @samp{set demangle-style} etc.; look them up in the GDB on-line docs. @node Included source, Debugging woes, C++ classes in GDB, Debugging @comment node-name, next, previous, up @section GDB cannot list source that was #include'd @cindex Debugger doesn't know about #include'd source @cindex Including source code, problems with debugging @cindex Debugging C/C++ code generated by a program @pindex Flex, debugging generated code @pindex Bison, debugging generated code @pindex Yacc, debugging generated code @pindex Lex, debugging generated code @pindex F2C, debugging generated code @quest{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@dots{}} @quest{I cannot debug code produced by Flex, or Bison, or F2C, because GDB somehow messes up all the source file and line number info!} @ans{} 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 @samp{F2C} or @samp{Bison}, you will have to delete the @code{#line} directives from the generated C source, and debug the generated code as regular C program. @node Debugging woes, , Included source, Debugging @comment node-name, next, previous, up @section Debuggers choke on some programs @dots{} @cindex Signals in debugged programs @cindex Debugger crashes on programs which use exceptions @cindex Floating-point emulation under debugger @cindex Ctrl-C in debugged programs @cindex Debugger crashes on programs compiled for profiling @cindex Profiled programs crash under debugger @cindex Keyboard interrupt cannot be hooked under debugger @cindex Debugger doesn't pass signals to debuggee @pindex WMEMU, use when debugging FP programs on non-FPU machine @pindex GDB GP Faults on breakpoint under Windows @quest{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)!} @quest{I cannot debug any program which catches signals!!??} @quest{I compiled my program with @samp{-pg} switch, and now I cannot debug it@dots{}} @quest{When my program hits a breakpoint in GDB, the debugger reports SIGSEGV, but only under Windows@dots{}} @ans{} There are currently a few limitations in debugging programs which use interrupts or exceptions. Programs compiled for profiling may crash with SIGSEGV or a GPF, with no addresses that @code{symify} can identify; programs using @code{alarm} or @code{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 @samp{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. @paragraph{} 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 @kbd{Ctrl-C} keypress to go to the debuggee instead of the debugger: use the @kbd{Alt-Numeric-3} (that is, simultaneously press the @kbd{Alt} key and the @kbd{3} key on the numeric keypad, then release the @kbd{Alt} key). @paragraph{} Several users reported that @samp{GDB} GP Faults when the program hits a breakpoint under Windows. The only work-around is to use @samp{FSDB} which works in that environment. @node Profiling, Performance, Debugging, Top @comment node-name, next, previous, up @chapter Profiling DJGPP Programs @cindex Profiling issues This chapter explains how to optimize your program for speed using the profiler, and discusses some problems you might have with it. @menu * How to profile:: What should you do to profile a program. * Gprof needs COFF:: Gprof doesn't like @b{.exe} executable. * Gprof docs:: Look on Gprof man page for its docs. * I/O bound programs:: How their profiles look. * No profile:: Where is the profile? @end menu @node How to profile, Gprof needs COFF, Profiling, Profiling @comment node-name, next, previous, up @section How to profile a DJGPP program @cindex Profiling DJGPP programs @cindex DJGPP programs, profiling @cindex Optimizing DJGPP programs @pindex Gprof, the GNU profiler @quest{How can I profile my program to see where it spends most of its run time?} @ans{} DJGPP includes a profiling facility. To use it, compile and link with @samp{-pg} option, run your program as you usually would, then run a program called @samp{gprof}: @example gprof myprog @end example (change @samp{myprog} to whatever name your program is). This will print an execution profile. @paragraph{} @samp{Gprof} is part of @ftp{GNU Binutils distribution, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/bnu@value{bnu-version}b.zip}. @node Gprof needs COFF, Gprof docs, How to profile, Profiling @comment node-name, next, previous, up @section Gprof won't work unless it can find COFF executable @cindex Profiling DJGPP programs, need COFF output @cindex COFF output, required for profiling @cindex Bad format, profiler error message @pindex Gprof cannot find program @pindex Gprof says ``bad format'' @quest{When I run @samp{Gprof}, it complains that it cannot find my program. But I've just run it!!} @quest{I run @samp{Gprof} on my program, and it says: ``bad format''.} @ans{} @samp{Gprof} needs the original COFF file the linker produced. If you delete it, or feed @samp{Gprof} with the @file{.exe} file instead, it will be most unhappy. The way to produce the COFF output is explained in the @ref{GDB needs COFF, section dealing with GDB}, above. @node Gprof docs, I/O bound programs, Gprof needs COFF, Profiling @comment node-name, next, previous, up @section Where is Gprof docs? @cindex Documentation, the profiler @cindex Profiler documentation @pindex Gprof documentation @quest{What about all those @samp{Gprof} options? Where can I find their docs?} @quest{I can't figure out some of the info in the @samp{Gprof} report @dots{}} @ans{} @samp{Gprof} is only documented on a man page, @file{gprof.1.} If you don't have one, you will have to look for it in the @ftp{Binutils distribution, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/bnu@value{bnu-version}b.zip}. @node I/O bound programs, No profile, Gprof docs, Profiling @comment node-name, next, previous, up @section Why is @code{__dpmi_int} so heavy used? @cindex Profiling, library routines @cindex __dpmi_int, high in program's profile @quest{I've profiled my program and found that the routine which takes 60% of the running time is some obscure library function called @code{__dpmi_int.} Can't you guys make your library right?} @ans{} 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 @code{__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. @node No profile, , I/O bound programs, Profiling @comment node-name, next, previous, up @section @samp{gprof} doesn't produce output @cindex Profiler produces no output @cindex Profiling programs that terminate abnormally @cindex Programs that exit abnormally, how to profile @pindex gprof produces no output @quest{Every time I run the profiler it says ``gmon.out: no such file or directory'' and no profile is produced. What is this @file{gmon.out} and why won't @samp{gprof} compute the profile?} @ans{} @file{gmon.out} is the file with raw execution counts and timing info that @samp{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: @itemize @bullet{} @item You didn't compile and/or link your program with the @samp{-pg} switch. Note that @strong{both} compilation and link need to be done with @samp{-pg}, because the functions that actually write the results to @file{gmon.out} are only linked in when @samp{gcc} sees @samp{-pg} on the link command line. @item You have called @file{ld.exe} directly to link your program and forgot to mention the files and switches necessary for the profiled program operation. You should use @samp{gcc} to link your program instead of calling the linker directly; a @samp{-pg} switch to @samp{gcc} is all that it takes to make sure that the linker will get all the necessary arguments. @footnote{If you absolutely need to call @file{ld.exe} directly, invoke @samp{gcc} once with a @samp{-v} switch and you will see what the arguments are that you should pass to the linker in your case.} @item Your program exited abnormally. The function which generates @file{gmon.out} is registered with the @code{atexit} library function, which won't be called if the program was terminated in an abnormal way. Make sure that your program exits with a call to @code{exit} or with a @code{return} statement in your @code{main} function. For example, if your program dies with an exception or a signal, install a signal handler and make it call @code{exit.} @end itemize @node Performance, Memory, Profiling, Top @comment node-name, next, previous, up @chapter Run-time Performance of DJGPP Programs @cindex Performance issues @cindex Run-time performance This chapter deals with issues pertinent to run-time performance of DJGPP programs. @menu * How fast:: What code quality should you expect. * Faster v1:: Is v1.x faster than v2? * Pentium:: Is v2 slower on a Pentium? * I/O speed:: Is I/O @emph{really} so slow in protected mode? * Slow-down:: What if your ported program runs slower? @end menu @node How fast, Faster v1, Performance, Performance @comment node-name, next, previous, up @section How efficient is DJGPP-generated code? @cindex Code quality, GCC @cindex Mode switches, effect on program speed @pindex GCC, code efficiency @quest{How does DJGPP compare with other DOS-based C compilers in terms of efficiency of generated code?} @quest{Won't my program run @strong{much} slower when compiled by DJGPP, due to all those CPU cycles wasted in switches between protected and real mode?} @ans{} The quality of code generated by GCC with optimization turned on (@samp{-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. @node Faster v1, Pentium, How fast, Performance @comment node-name, next, previous, up @section Comparing v2 with DJGPP v1.x @cindex Code speed, slower than in v1.x @cindex -fstrength-reduce optimization, disabled by default @cindex v2 code slower than v1.x @cindex Runtime speed, slower than in v1.x @quest{I switched to v2 and my programs now run slower than when compiled with v1.x@dots{}} @ans{} In general, GCC 2.7.2 which comes with DJGPP v2.0 generates tighter, faster code. But it sometimes produces buggy code when @dfn{strength reduction} optimizations are enabled. So DJGPP 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 @samp{-fstrength-reduce} switch to see if that makes any difference. @paragraph{} GCC has a plethora of other optimization options which might make your code faster; the best way to know is to profile and experiment. @node Pentium, I/O speed, Faster v1, Performance @comment node-name, next, previous, up @section Comparing v2 code on i486 vs Pentium @cindex Alignment of data by GAS can slow-down code @cindex Code is slow due to incorrect alignment by GAS @cindex Slow code, due to bad alignment by GAS @quest{I run the same program on a 486 and on a Pentium, and it's slower on a Pentium!!} @ans{} This might be 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 what you see. @paragraph{} 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. @node I/O speed, Slow-down, Pentium, Performance @comment node-name, next, previous, up @section My program's I/O is so slow! @cindex I/O speed, DJGPP programs @cindex Buffered I/O, effect of buffer size on I/O speed @cindex setvbuf, effect on I/O speed @pindex GCC, I/O speed @quest{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 @strong{horribly} slow performance??} @quest{I tried to improve DJGPP I/O throughput by defining a 64KB-large buffer for buffered I/O with a call to @code{setvbuf}, but that had no effect. Why is that?} @ans{} 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. This area in the low memory is called the @dfn{transfer buffer}. This data shuffling means that some I/O speed degradation is inevitable in any protected-mode program which runs under DOS. By default, DJGPP moves data in chunks of 16 KB, so defining a buffer larger than that won't gain anything. The size of transfer buffer is customizable up to a maximum of 64 KB, so if your program really reads a lot of large files, you might be better off enlarging it (with the @samp{STUBEDIT} program). @paragraph{} That said, I would like to point out that waiting another 0.5@dmn{sec} 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@dots{} Besides, most programs read and write files which are only a few hundreds of kilobytes, and those will suffer only a negligible slow-down. @node Slow-down, , I/O speed, Performance @comment node-name, next, previous, up @section My ported program runs much slower! @cindex Slow-down, programs ported from other compilers @cindex Ported programs run much slower @quest{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? } @ans{} Explore the following possible causes for this: @enumerate a @item Your program extensively calls services other than I/O which require mode switch (like BIOS Int 10h, mouse services, etc.). @paragraph{} 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 @code{__dpmi_int} (which calls real-mode DOS/BIOS services) and @code{__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). @paragraph{} @item 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 @samp{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 @news{comp.os.msdos.djgpp}, so this could be fixed by people who maintain the library. @paragraph{} @item If your program spends most of its time in a certain innermost loop, you might try enabling the strength-reduction optimizations. This is disabled by default, because GCC has a known bug which sometimes causes it to generate incorrect code when this kind of optimization is enabled. If you decide to enable it, examine the behavior and the output of your program carefully, to be sure you didn't hit that bug. @paragraph{} @end enumerate @node Memory, Command line, Performance, Top @comment node-name, next, previous, up @chapter Run-Time Memory Issues @cindex Memory at run time @cindex Virtual memory This chapter answers questions which are related to DJGPP run-time memory allocation. @menu * How much memory:: How much can you use? * Confusing alloc:: Allocation mechanism peculiarities. * QDPMI VM:: QDPMI doesn't provide virtual memory. * QDPMI alloc:: QDPMI/Win 95 memory allocation peculiarities. * Windows alloc:: VM issues under Windows 3.x. * Win9x alloc:: VM peculiarities under Win9x. * EMM386 alloc:: Some versions of EMM386 are limited to 32 MBytes. * Swap out:: How much VM do spawned program have? * Stack size:: How large is the stack and how to enlarge it? @end menu @node How much memory, Confusing alloc, Memory, Memory @comment node-name, next, previous, up @section How much virtual memory do you have? @cindex Virtual memory, maximum available @cindex Memory, virtual, maximum available @pindex CWSDPMI, maximum available virtual memory @quest{How much virtual memory can I use in DJGPP programs?} @ans{} 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 @code{malloc(50*1024*1024)} some day. @paragraph{} With other DPMI hosts, your mileage may vary. Quarterdeck's QDPMI, for instance, has a bug in some of its versions which effectively disables virtual memory under DJGPP (described under @ref{QDPMI VM, QDPMI VM bug}, 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 @file{.pif} file settings for the program you run (see @ref{Windows alloc, Windows allocation subtleties}, below). Under Windows 9x, the memory settings of the DOS Applications' Property Sheet define how much virtual memory a DJGPP program will get (see @ref{Win9x alloc, Win9x allocation details}, below). @node Confusing alloc, QDPMI VM, How much memory, Memory @comment node-name, next, previous, up @section It seems @code{malloc}/@code{free} don't affect virtual memory@dots{} @cindex Virtual memory, malloc doesn't change @cindex Virtual memory, free doesn't change @cindex Memory, virtual, malloc doesn't change @cindex Memory, virtual, free doesn't change @cindex malloc doesn't change virtual memory @cindex free doesn't change virtual memory @cindex __dpmi_get_memory_information, doesn't change after free/malloc @cindex _go32_remaining_physical_memory, doesn't change after free/malloc @quest{I did @code{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?} @quest{I @code{malloc}'ed a large chunk of memory, but when I check values returned by @code{_go32_remaining_physical_memory} or @code{__dpmi_get_memory_information}, I don't see any change@dots{}} @quest{When I @code{free} allocated RAM, @code{_go32_remaining_physical_memory} reports there was no change in the available RAM.} @ans{} CWSDPMI (and, possibly, other DPMI hosts) only pages in memory when it is actually accessed. If you only @code{malloc} it, but don't actually access it, it won't grab those pages. Try @code{calloc} and see the @strong{big} difference. @paragraph{} When you call @code{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''. @node QDPMI VM, QDPMI alloc, Confusing alloc, Memory @comment node-name, next, previous, up @section Failure to get more memory than is physically installed @cindex Virtual memory, QDPMI failure @cindex Memory, virtual, QDPMI failure @cindex Virtual memory, failure to allocate @cindex Memory, virtual, failure to allocate @pindex QDPMI fails to provide virtual memory @pindex QDPMI and _crt0_startup_flags settings @pindex 386Max, how to ensure virtual memory @pindex 386Max, speeding up DJGPP start-up @pindex sbrk algorithm and QDPMI @pindex _crt0_startup_flags settings and QDPMI @quest{When I try to access more memory than the free physical RAM, @code{malloc} returns a @code{NULL} pointer, or I get some cryptic error message like this:} @example DPMI: Not enough memory (0x00860000 bytes) @end example @emph{or like this:} @example 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 @end example @ans{} 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, @ref{Old QDPMI, disable or uninstall QDPMI}, and use CWSDPMI instead. @paragraph{} 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 @code{sbrk} behavior by setting @code{_crt0_startup_flags} to @code{_CRT0_FLAG_UNIX_SBRK} (QEMM 8.0 and later can allocate virtual memory with both types of @code{sbrk} algorithm). @paragraph{} If you use another DPMI host, make sure that virtual memory is enabled. E.g., for 386Max, include the @samp{swapfile=} parameter to establish a virtual memory swap file; you can make it permanent (this will speed up DJGPP start-up) with the @samp{/p} option. @node QDPMI alloc, Windows alloc, QDPMI VM, Memory @comment node-name, next, previous, up @section Memory allocation fails before all memory is used @cindex Memory allocation fails under QDPMI or Windows 95 @cindex malloc fails under QDPMI or Windows @cindex calloc fails under QDPMI or Windows @cindex Program crashes while allocating memory @pindex QDPMI, malloc/calloc failure @pindex Windows, malloc/calloc failure @pindex CWSDPMI crashes programs allocating memory is small chunks @quest{OK, I've changed my program to never allocate more memory than is physically available, to work around that @ref{QDPMI VM, QDPMI VM bug}, but my program still gets a @code{NULL} pointer from @code{malloc/calloc}!} @quest{Why is my program dying with SIGSEGV under CWSDPMI when allocating a chunk of memory?} @ans{} 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. @paragraph{} With some DPMI providers, this behavior might be triggered by a small overhead of each @code{malloc} call: you might ask for half of available memory, but the DJGPP implementation of @code{malloc} adds the overhead and then rounds the amount of memory to the next power of 2 before calling @code{sbrk}; thus @code{malloc(@w{8MB + 1})} will actually request 16MBytes from the DPMI host. When in doubt, call @code{sbrk} directly, especially if you don't plan to free that memory during execution. @paragraph{} 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 memory 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 @ftp{CWSDPMI heap-fix patch, 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. @node Windows alloc, Win9x alloc, QDPMI alloc, Memory @comment node-name, next, previous, up @section Memory allocation fails under Windows @cindex Memory allocation fails under Windows 3.x @cindex malloc fails under Windows 3.x @cindex calloc fails under Windows 3.x @pindex Windows 3.x, malloc/calloc fails @quest{I'm running under Windows 3.x DOS box, but DJGPP complains about there not being enough DPMI memory, although virtual memory is enabled.} @ans{} 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 @example PageOverCommit=n @end example in the @samp{[386Enh]} section of your @file{SYSTEM.INI} file. The parameter @samp{n} is 4 by default, but can be set to be as large as 20. @node Win9x alloc, EMM386 alloc, Windows alloc, Memory @comment node-name, next, previous, up @section Memory allocation peculiarities under Windows 9x @cindex Memory allocation fails under Windows 95 @cindex malloc fails under Windows 95 @cindex calloc fails under Windows 95 @cindex Virtual memory under Windows 95 @pindex Windows 95 doesn't allow more than 16MB virtual memory @quest{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@dots{}} @ans{} 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). @paragraph{} 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. @node EMM386 alloc, Swap out, Win9x alloc, Memory @comment node-name, next, previous, up @section Memory allocation fails under EMM386 or HIMEM @cindex Memory allocation fails under EMM386 or HIMEM @cindex malloc fails under EMM386 or HIMEM @cindex calloc fails under EMM386 or HIMEM @cindex Paging starts before all RAM is used @pindex EMM386, cannot use all free memory @pindex EMM386, malloc/calloc fails @pindex HIMEM, malloc/calloc fails @pindex CWSDPMI, pages too early under EMM386 @pindex go32-v2, use to find out how much memory is available to DJGPP @quest{My machine has 48 MBytes of RAM, but when I run DJGPP programs, they start paging after 32 MBytes have been used@dots{}} @quest{I have 5 MBytes of free RAM on my machine, but DJGPP programs start paging after only 256KBytes of memory were used??} @ans{} 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. @paragraph{} If your programs start paging after only 256KBytes of memory were used, most probably you are using EMM386 and CWSDPMI, and your @file{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 @samp{go32-v2} program to see what amount of extended memory your DJGPP programs will get. @node Swap out, Stack size, EMM386 alloc, Memory @comment node-name, next, previous, up @section How much memory do parent DJGPP programs leave for their child? @cindex Child programs, how much memory is left @cindex Nested programs, how much memory is left @cindex Spawned programs, how much memory is left @cindex Subsidiary programs, how much memory is left @cindex Memory, how much is left for spawned programs @pindex QDPMI, memory usage for nested programs @pindex CWSDPMI, memory usage for nested programs @pindex Windows, memory usage for nested programs @pindex STUBEDIT, effect on memory left to spawned programs @quest{How much memory is available when I call the @code{system} library function?} @ans{} 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 @code{system} (like in recursive invocation of @samp{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 @code{STUBEDIT}), the amount of free conventional RAM will change accordingly. @paragraph{} Extended memory management is left to the DPMI server; DJGPP does nothing special about XMS when @code{system} is called. This means that all the extended memory used by the parent program is @strong{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 @code{go32} extender would completely page out the parent before starting the child.) The advantage of this is that spawning a child or shelling out is much faster in v2.0 than it used to be with v1.x, 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. @node Stack size, , Swap out, Memory @comment node-name, next, previous, up @section How much stack can I have in DJGPP programs? @cindex Stack size under DJGPP @cindex Automatic variables, how much memory @cindex _stklen, setting stack size @cindex Programs crash with SIGSEGV due to small stack size @cindex Stack size, insufficient, causes programs to crash @cindex Stack overflow under debugger @cindex Debugger causes programs to overflow the stack @pindex C++ compiler crashes for large programs @pindex CC1PLUS crashes with SIGSEGV @pindex STUBEDIT, changing stack size @pindex Windows, stack size control @pindex BCCBGI (from BCC2GRX) crashes with the default stack @pindex GDB causes stack overflow in a debuggee @quest{My program bombs when I use very large automatic arrays.} @quest{How much stack space do I have in my program?} @quest{My program seems to overflow the stack, but only when I run it under a debugger@dots{}} @quest{My program crashes with SIGSEGV, but the traceback makes no sense: it points to something called ___djgpp_exception_table@dots{} When I try to debug this, the traceback mysteriously changes to some innocent library function, like getc(). The same program works flawlessly when compiled with DJGPP v1.x What's going on??} @ans{} DJGPP v2.0 programs impose a limit on the maximum stack size; this is a bug/feature of the DPMI 0.9 specification. By default, you have a 256KB-long stack, but some programs which use large automatic arrays, or are deeply recursive, might need more. If the default stack size is not enough, you can change it with the @samp{STUBEDIT} program (change the parameter ``Minimum amount of stack space''), or by setting the global variable @code{_stklen} in your program. Example: @smallexample unsigned _stklen = 1048576; /* need a 1MB stack */ @end smallexample The DJGPP startup code checks both these values and uses the largest of the two. Therefore, programs that are known to require large stack size should set @code{_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 @code{gdb} (see below). However, you might need to use @samp{STUBEDIT} with programs for which you don't have the sources. @paragraph{} Programs which needs 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 @samp{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 @code{_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.) @paragraph{} Some users have reported that they needed to enlarge the stack size of the C++ compiler, @file{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 @file{bccbgi.exe} from the @samp{BCC2GRX} package. @paragraph{} After you've used @samp{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 @samp{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. @paragraph{} 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 @code{gdb} (which always requires a COFF image of the debuggee), be sure to stubedit @code{gdb} to enlarge its stack to at least the value your program needs to run safely. @paragraph{} 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 @file{.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 @file{.PIF} file for this program? Then Windows uses the default file @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. @paragraph{} 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 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. @node Command line, Converting, Memory, Top @comment node-name, next, previous, up @chapter Command-line Arguments Handling in DJGPP @cindex Command-line arguments 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. @menu * Filename globbing:: Wildcard expansion under DJGPP * Disable globbing:: You can disable globbing if you don't need it. * Special chars:: How to pass arguments with special chars. * Long commands:: DJGPP can pass very long command lines. * How long:: Look here to find out how long. * Makefiles:: Makefiles can disable long command lines. @end menu @node Filename globbing, Disable globbing, Command line, Command line @comment node-name, next, previous, up @section Filename wildcards expansion under DJGPP @cindex Wildcards expansion @cindex Filename wildcards expansion @cindex Filename globbing @cindex Globbing in filenames @cindex Command line, filename expansion/globbing @quest{Can I do filename globbing with DJGPP?} @quest{I call my program with an argument @samp{x*y} and it complains about something called @samp{xyzzy}??@dots{}} @ans{} The filename globbing in DJGPP is done by the start-up code, before your @code{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 @samp{x*y} above was expanded to a file called @file{xyzzy} which was probably present in the current working directory. (If you don't want the default expansion, see @ref{Disable globbing, how to disable globbing}.) @paragraph{} 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: @table @samp @titem ? any single character. @titem * zero or more arbitrary characters, including a dot `.' @titem [aA_] any one of characters `a', `A', or `_'. @titem [a-d] any one of characters `a', `b', `c', or `d'. @titem [!a-z] anything @emph{but} a lowercase letter. @titem ... all the subdirectories, recursively (VMS aficionados, rejoice!). @titem .../* all the files in all subdirectories, recursively. @end table Unlike DOS, the @samp{*} and @samp{?} meta-characters can appear @emph{anywhere} in the filename pattern, like in @samp{[a-z]*[0-9].*pp.} You can also use @samp{*} instead of directories, like in @samp{*/*/*.c}, but @strong{not} on drive letters (e.g., @samp{[a-c]:/} won't work). @paragraph{} Note that @samp{*.*} only picks up files that actually have an extension. This is contrary to the usual DOS practice where it means @emph{all} the files, with or without extension. @paragraph{} 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 @samp{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 (@samp{sh}, @samp{ksh}, and @samp{bash}). @node Disable globbing, Special chars, Filename globbing, Command line @comment node-name, next, previous, up @section How to disable filename wildcards expansion @cindex Wildcards expansion, disabling @cindex Disabling wildcard expansion @cindex Disabling globbing in filenames @cindex Filename wildcards, disabling expansion @cindex Filename globbing, disabling @cindex Globbing in filenames, disabling @cindex Command line, disabling filename expansion/globbing @cindex __crt0_glob_function, disable filename globbing @quest{OK, but I don't want my program to glob its arguments (they aren't files at all, but they include characters like @samp{*} and @samp{?}). What should I do?} @ans{} You have these alternatives: @itemize @bullet{} @item Surround your arguments with single or double quotes (this is what you would do under a Unix shell). @item Disable globbing for your program by linking it with your custom version of the function with the special name @code{__crt0_glob_function} and make it always return a @code{NULL} pointer. See the documentation of this function in the library reference. @end itemize @node Special chars, Long commands, Disable globbing, Command line @comment node-name, next, previous, up @section How to pass command-line arguments with quotes or @key{@@} @cindex Quotes, how to pass them to programs @cindex @@ character, how to pass it to programs @cindex Command line, escaping special characters @quest{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 @dots{}} @quest{How do I pass a command-line argument which contains double quotes? } @quest{How do I pass an argument which begins with the @key{@@} character?} @ans{} These special characters on the command-line arguments are handled by the filename expansion (``globbing'') code before they are passed to the @code{main} function (@pxref{Filename globbing, description of filename expansion}), 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 @file{myfile.c'v}, type it as @samp{myfile.c\\'v} when you call your program. If you have single quotes in your program arguments @emph{and} you don't want those arguments to be expanded, then surround them by double quotes, like this: @samp{"*.c\\'v".} The program will get the string @samp{*.c'v} with the double quotes stripped away. @paragraph{} 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?). @paragraph{} The @key{@@} character serves to signal a @dfn{response file} (@pxref{Long commands, the description of response file method}), so it's also special. To pass an argument whose first character is @key{@@}, 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. @node Long commands, How long, Special chars, Command line @comment node-name, next, previous, up @section How to pass command lines longer than 126 characters @cindex Long command lines @cindex Makefiles with long command lines @cindex !proxy method of passing long command lines @cindex Command lines, longer than 126 characters @cindex Response file, passing long command lines @quest{Can I invoke my program with a command line longer than the infamous DOS 126-character limit?} @quest{I have a Makefile of Unix origin which contains some @strong{very} long command lines. Will it work with DJGPP?} @ans{} 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: @itemize @bullet{} @item The @samp{!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. @paragraph{} 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 @code{system}, @code{spawnXX} and @code{execXX} on the parent program side, and by the start-up code on the child side. @footnote{In case you wonder, the name @samp{!proxy} comes from the the string which identifies the use of this method: instead of getting the actual command line, the program gets @samp{!proxy} followed by the address of the actual command line.} @paragraph{} @item The response file method. Any argument which starts with a @key{@@} character (like in @samp{myprog @@file}) will cause the named @samp{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 @samp{Gawk} or @samp{Sed} without @samp{-f} option). @paragraph{} Note that this method makes @key{@@} 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 (@pxref{Special chars, how to pass the @b{@@} character}). @end itemize Of course, if the start-up code doesn't see any of the above methods, it will use the command line by default. @node How long, Makefiles, Long commands, Command line @comment node-name, next, previous, up @section What is the maximum length of command line under DJGPP @cindex Long command lines, maximum length @cindex Length of command line @cindex Maximum length of command line @cindex Environment size affects spawning child programs @cindex Spawning programs, effect of environment size @pindex Make, maximum length of command line to pass to GCC @pindex GCC, maximum length of command line in Makefiles @quest{What is the longest command line I can pass to gcc when it is invoked by @samp{Make}?} @ans{} 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 @samp{!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 @emph{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. @paragraph{} 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 @emph{parent program} before you pass extremely long command lines to its children. GCC is the first program you should worry about, because the linker (@file{ld.exe}) usually gets long command lines from GCC (they include the list of all the object files and libraries to be linked). @node Makefiles, , How long, Command line @comment node-name, next, previous, up @section Why Make passes only 126 characters to programs? @cindex Long command lines, from Makefile @cindex Makefile, passing long command lines @cindex SHELL= variable in Makefile, effect on long command lines @cindex Redirection in Makefile, effect on long command lines @cindex Redirection, using the REDIR program @pindex Make, passing long command lines via Makefile @pindex GCC, passing long command lines via Makefile @pindex REDIR, use to get redirection and long command lines @quest{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 @samp{!proxy} method?} @ans{} Check your Makefile for @code{SHELL = command.com} statements, or for commands which include pipe or redirection characters like @samp{>}, @samp{|}, etc. If Make sees any such statements, it will invoke @file{COMMAND.COM} to run GCC, and @file{COMMAND.COM} can't pass more than 126 characters to GCC. To work around, comment-out the @code{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 @samp{redir} program which comes with DJGPP. For example, the following command: @example frobnicate foo.bar > myfile.tmp @end example can be re-written instead like this: @example redir -o myfile.tmp frobnicate foo.bar @end example @node Converting, Low-level, Command line, Top @comment node-name, next, previous, up @chapter Converting DOS Programs/Libraries to DJGPP @cindex Converting DOS code to DJGPP @cindex DOS programs, converting to DJGPP @cindex Libraries, converting 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. @menu * Syntax:: The (AT&T) syntax of Gas is different. * Gas bugs:: Don't trust Gas! * Converting ASM:: Automated conversion tool. * ASM GPF:: When converted code crashes. * OBJ and LIB:: You can't use them with GCC. * 16-bit code:: @dots{}or can you? * NEAR and FAR:: How to convert these to DJGPP. @end menu @node Syntax, Gas bugs, Converting, Converting @comment node-name, next, previous, up @section GCC/Gas won't accept valid assembly code @dots{} @cindex Assembly source, GCC/Gas syntax @cindex AT&T vs Intel assembly syntax @cindex Intel vs AT&T assembly syntax @cindex Assembly syntax @quest{I have some code written in assembly which compiles under @samp{MASM} and @samp{TASM}, but GCC gives me a long list of error messages.} @ans{} The GNU Assembler (@file{as.exe}), or @samp{Gas} called by GCC accepts @dfn{AT&T} syntax, which is different from @dfn{Intel} syntax. Notable differences between the two syntaxes are: @itemize @bullet{} @item AT&T immediate operands are preceded by @code{$}; Intel immediate operands are undelimited (Intel @code{push 4} is AT&T @code{pushl $4}). @item AT&T register operands are preceded by @code{%}; Intel register operands are undelimited. AT&T absolute (as opposed to PC-relative) @code{jump}/@code{call} operands are prefixed by @code{*}; they are undelimited in Intel syntax. @item AT&T and Intel syntax use the opposite order for source and destination operands. Intel @code{@w{add eax, 4}} is @code{@w{addl $4, %eax}} in AT&T syntax. The @code{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. @item In AT&T syntax, the size of memory operands is determined from the last character of the opcode name. Opcode suffixes of @code{b}, @code{w}, and @code{l} specify byte (8-bit), word (16-bit), and long (32-bit) memory references. Intel syntax accomplishes this by prefixing memory operands (@emph{not} the opcodes themselves) with @code{`byte ptr'}, @code{`word ptr'}, and @code{`dword ptr'.} Thus, Intel @code{@w{mov al, byte ptr FOO}} is @code{@w{movb FOO, %al}} in AT&T syntax. @item Immediate form long jumps and calls are @code{@w{lcall/ljmp $SECTION, $OFFSET}} in AT&T syntax; the Intel syntax is @code{@w{call/jmp far SECTION:OFFSET}.} Also, the far return instruction is @code{@w{lret $STACK-ADJUST}} in AT&T syntax; Intel syntax is @code{@w{ret far STACK-ADJUST}.} @item 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. @c @c ... Insert reminder than you don't need separate segments under @c DJGPP? @c @item An Intel syntax indirect memory reference of the form @example SECTION:[BASE + INDEX*SCALE + DISP] @end example is translated into the AT&T syntax @example SECTION:DISP(BASE, INDEX, SCALE) @end example @end itemize Examples: @example @strong{Intel:} [ebp - 4] @strong{AT&T:} -4(%ebp) @strong{Intel:} [foo + eax*4] @strong{AT&T:} foo(,%eax,4) @strong{Intel:} [foo] @strong{AT&T:} foo(,1) @strong{Intel:} gs:foo @strong{AT&T:} %gs:foo @end example For a complete description of the differences, get and unzip the files named @file{as.iN} (where @file{N} is a digit) from the @ftp{bnu@value{bnu-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/bnu@value{bnu-version}b.zip} archive, then see @extref{i386-Dependent, i386-dependent features, as, GNU assembler documentation, 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: @example info as machine i386 @end example You will see a menu of @samp{Gas} features specific to x86 architecture. @paragraph{} A guide is available which was written by @mail{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 @www{DJGPP inline assembly tutorial, www.rt66.com/~brennan/djgpp/djgpp_asm.html} @node Gas bugs, Converting ASM, Syntax, Converting @comment node-name, next, previous, up @section Double-check code produced by Gas @cindex Assembly source, code produced by Gas @pindex Gas can introduce errors into assembly code @pindex OBJDUMP segment overrides bugs @quest{My assembly code gets corrupted by @samp{Gas}!} @ans{} When writing assembly code, you should remember @strong{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 @samp{objdump} from GNU Binutils doesn't always treat segment overrides correctly). The following lists some guidelines for safer machine-language programming with @samp{Gas}: @enumerate a @item Use explicit sizing. E.g., use @code{movl} instead of @code{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 @samp{Gas.} @item Write code segment overrides as @code{.byte} constants, not as e.g. @code{%cs:.} According to @CWS{}, @samp{Gas} uses the current phase of the moon in deciding whether to ignore your prefixes. So unless you know @emph{exactly} what the phase of the moon is at the moment of assembly, use @code{.byte} constants. @item Make sure the operands match the instructions. Don't assume that if they don't, you'll get an error message from the assembler. @end enumerate @node Converting ASM, ASM GPF, Gas bugs, Converting @comment node-name, next, previous, up @section Converting Intel ASM syntax to AT&T syntax @cindex Assembly source, converting to AT&T syntax @cindex Intel assembly syntax, converting to AT&T @pindex Sed script to convert ASM to AT&T syntax @pindex TA2AS, a converter from Intel to AT&T assembly syntax @quest{Where can I find an automated conversion tool to convert my @samp{Intel}-style assembly code into a code acceptable by @samp{Gas}?} @ans{} A @samp{Sed} script which should do most of the conversion was posted to the DJGPP news group in the past. You can find it @www{in the DJGPP archives, www.delorie.com/djgpp/mail-archives/djgpp/1995/06/06/05:48:34} A conversion program called @samp{TA2AS} which can convert TASM assembly source to the AT&T format, can be found on the Oulu repository and @ftp{on the DJGPP server, ftp.delorie.com/pub/djgpp/contrib/ta2asv08.zip} and @ftp{on the Oulu repository, x2ftp.oulu.fi/pub/msdos/programming/convert/ta2as.zip}. @samp{TA2AS} was written by @mail{Jan Oonk, jan@@stack.urc.tue.nl}. @paragraph{} Alternatively, here is what you can do to convert your code: @itemize @bullet{} @item For a small number of relatively short files, consider converting them with a smart editor (like Emacs or its work-alikes). @item Obtain a copy of Microsoft MASM 6.11. It has a @samp{-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 @samp{LIB32} librarian from Microsoft C8 to convert object files to COFF by putting them into a @file{.lib} library, then extracting them as COFF files. @footnote{If you use MASM or LIB32, please post your experiences to @news{comp.os.msdos.djgpp}, so that I can make the above instructions less vague.} @item Use a disassembler to disassemble the object code, then convert it to the AT&T format either by hand or using @samp{TA2AS}. One place to look for such a disassembler is @ftp{on SimTel mirrors, @SimTel{}/pub/simtelnet/msdos/disasm/}. @end itemize @paragraph{} 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 (@pxref{ASM GPF, next question}). @node ASM GPF, OBJ and LIB, Converting ASM, Converting @comment node-name, next, previous, up @section Converted code GP Faults! @cindex Assembly source, converting to protected mode @cindex Protected mode and converted assembly code @quest{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?} @ans{} In DJGPP, your program runs in @strong{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. @paragraph{} 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: @itemize @bullet{} @item Loading arbitrary values into segment registers, then using them to reference code or data. @item Referencing code with data segment register, or vice versa. @item Assuming certain locations (like BIOS area or video memory) will be found at certain absolute addresses. @item Calling DOS or BIOS services with @code{INT NN} instruction. @end itemize @node OBJ and LIB, 16-bit code, ASM GPF, Converting @comment node-name, next, previous, up @section I want to use a @file{.obj} or @file{.lib} code with DJGPP @cindex DOS libraries, using with GCC @cindex DOS object files, using with GCC @cindex .lib libraries, using with GCC @cindex .obj object files, using with GCC @cindex Converting DOS .obj/.lib files to GCC @pindex GCC doesn't recognize .obj object files @pindex GCC doesn't recognize .lib libraries @pindex OBJ2COFF converter from .obj to COFF format @pindex EMXAOUT converter from .obj to COFF format @quest{I have a set of useful functions in a @file{.obj} format, but no source code. Can I use them with my DJGPP program?} @quest{I have this @file{ACMELUXE.LIB} library of functions which I want to use. I've extracted all the @file{.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?} @quest{I've got a bunch of @file{.obj} files I want to use. I've ran AR to make a GCC-style @file{.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?} @ans{} Sorry, you probably can't. The GNU linker called by GCC doesn't understand the format of @file{.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. @footnote{Note that mixing object files from different compilers usually won't work, even if they both are in the @file{.obj} format.} @paragraph{} Lately, an automated conversion tool called @samp{OBJ2COFF} was written by the SPiRiT team, which can be used to convert @file{.obj} object files and @file{.lib} libraries to @samp{COFF} format, provided that the original @file{.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@dots{} (@xref{ASM GPF, previous question}.) @paragraph{} @samp{OBJ2COFF} is available @ftp{from the Oulu repository, x2ftp.oulu.fi/pub/msdos/programming/convert/o2cv10.arj} and @ftp{from DJ Delorie's ftp server, ftp.delorie.com/pub/djgpp/contrib/o2cv06.arj}. If you have any problems with it or questions about it, send them to @mail{its author\, Rico, mb002@@hi.ft.hse.nl} or to @mail{George van Venrooij, george@@il.ft.hse.nl}. @paragraph{} Another conversion tool you might try is @samp{EMXAOUT} from the @samp{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. @samp{EMXAOUT} is available @ftp{from the SciTech Software FTP site, 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 @samp{EMXAOUT} @ftp{from the EMX archives, ftp-os2.nmsu.edu/os2/unix/emx09b/emxrt.zip} and the RSX extender (for running @samp{EMXAOUT} under DPMI) @ftp{from the RSX archives, ftp.uni-bielefeld.de/pub/systems/msdos/misc/rsx503rt.zip}. @node 16-bit code, NEAR and FAR, OBJ and LIB, Converting @comment node-name, next, previous, up @section I @strong{must} use my 16-bit code with DJGPP!! @cindex DOS code, using with GCC @cindex 16-bit code, using with DJGPP @cindex Calling 16-bit code from DJGPP @quest{If that's how it is, then I would have to give up using DJGPP. I simply cannot live without these @file{.obj} files. Are you @strong{really} sure there is nothing I can do??} @ans{} If you need your old code @emph{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 @code{spawnXX} function call. You can also call 16-bit functions directly with the library function called @code{__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 @code{__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 @samp{Gas}). @paragraph{} @emph{Now} will you consider sticking with DJGPP? @emph{Please??@dots{}} @node NEAR and FAR, , 16-bit code, Converting @comment node-name, next, previous, up @section What should I do with those ``near'' and ``far'' declarations? @cindex ``Far'' declarations, porting to DJGPP @cindex ``Near'' declarations, porting to DJGPP @cindex ``Huge'' declarations, porting to DJGPP @cindex MK_FP macro, porting to DJGPP @cindex FP_SEG and FP_OFF, porting to DJGPP @quest{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?} @quest{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?} @ans{} 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: @example #define far #define near #define huge #define _far #define _near #define _huge @end example Alternatively, you could add suitable @code{-D} switches to the GCC command line, like this: @example gcc -Dfar -Dnear -Dhuge -c myprog.c @end example Macros that create far pointers from the segment and offset (usually called @code{MK_FP} or @code{_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; the details are described in @ref{Xfer, accessing absolute addresses}, below. You will need to rewrite the code that uses these macros, so don't bother writing a replacement for the macro itself. @paragraph{} Macros that extract the segment and the offset from a far pointer (called @code{FP_SEG} and @code{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 @ref{Pointer segment, How to call real-mode interrupt functions}, which describes how that should be done in DJGPP; here, too, you won't need to port the above macros. @node Low-level, Legalese, Converting, Top @comment node-name, next, previous, up @chapter Low-level DOS/BIOS and Hardware-oriented Programming @cindex Low-level programming issues @cindex Systems programming issues @cindex Hardware-oriented programming This chapter sheds some light on a few aspects of writing DJGPP programs which interact with hardware or use interrupts. @menu * int86:: It doesn't always work. * Pointer segment:: Some interrupts require it, but how do you get it? * Zero SP:: If you don't, your program crashes. * Xfer:: Moving data to and from conventional memory. * 20 bits:: You should mask off the upper 12 bits when unused. * Fat DS:: Fast direct access to memory-mapped devices. * Above 1MB:: Interact with memory-mapped devices above 1MB. * RMCB:: How to let DOS/BIOS call your code. * Hardware interrupts:: How to hook HW interrupts from DJGPP. * _go32 vs __dpmi:: Which functions should you use? * HW Int pitfalls:: Does your machine wedge? Here are some reasons. * Ports:: Reading and writing I/O ports in DJGPP. * Inline Asm:: How to write inline assembly with GCC. @end menu @node int86, Pointer segment, Low-level, Low-level @comment node-name, next, previous, up @section Got ``Unsupported INT 0xNN'' calling @code{int86} @cindex Unsupported INT message @cindex Unsupported DOS request message @cindex int86 crashes program @cindex intdos crashes program @cindex Program crashes in int86/intdos @cindex DOS service calls @cindex BIOS service calls @cindex __dpmi_int, calling DOS/BIOS services @quest{Why does my program crash with ``Unsupported DOS request 0xNN'' or ``Unsupported INT 0xNN'' when I call @code{int86} or @code{intdos} functions to invoke a software interrupt?} @ans{} Calling real-mode DOS or BIOS services from protected-mode programs requires a switch to real mode, so the @code{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 @code{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 @code{int86} supports many of these services, it doesn't support all of them. The supported functions are listed in the library reference. @extref{int86, int86 library reference, libc.inf, libc.a reference, www.delorie.com/djgpp/doc/libc-2.00/libc_394.html#SEC394}. For those it doesn't support, you will have to call the @code{__dpmi_int} library function instead. It is also documented in the library reference, @extref{__dpmi_int, __dpmi_int, libc.inf, libc.a reference, www.delorie.com/djgpp/doc/libc-2.00/libc_196.html#SEC196}. @code{__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 (@xref{Pointer segment, how to use buffers with DOS/BIOS services}, below). @node Pointer segment, Zero SP, int86, Low-level @comment node-name, next, previous, up @section How to use buffers with DOS/BIOS services @cindex DOS service calls which need buffers @cindex BIOS service calls which need buffers @cindex int86x/intdosx, how to pass a buffer @cindex __dpmi_int, how to pass buffers @cindex Transfer buffer, using to call DOS/BIOS @cindex __tb, an alias for the address of transfer buffer @quest{I want to call a DOS/BIOS function which requires a pointer to a buffer in, e.g. @samp{ES:DI} (or any other) register pair. How do I get the segment to put into the @samp{ES} register?} @ans{} If you use @code{int86x} or @code{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 (@code{regs.x.di}) and forget about the segment. These functions are processed specially by the library, which will take care of the rest. @paragraph{} If you call @code{__dpmi_int}, then you must put into that register pair an address of some buffer in @emph{conventional} memory (in the first 1 MByte). If the size of that buffer doesn't have to be larger than the size of transfer buffer used by DJGPP (16KB by default), then the easiest way is to use the transfer buffer. (Library functions don't assume its contents to be preserved across function calls, so you can use it freely.) That buffer is used for all DOS/BIOS services supported by DJGPP, and it resides in conventional memory. DJGPP makes the address and the size of the transfer buffer available for you in the @code{_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: @smallexample 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; @end smallexample For your convenience, the header file @code{} defines a macro @code{__tb} which is an alias for @code{_go32_info_block.linear_address_of_transfer_buffer.} @paragraph{} 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 @code{__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 @code{exit.} @paragraph{} 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 @samp{STUBEDIT} program without your knowledge. @node Zero SP, Xfer, Pointer segment, Low-level @comment node-name, next, previous, up @section How to call software interrupt functions @cindex Software interrupts, need zero SS, SP and FLAGS @cindex __dpmi_simulate_real_mode_interrupt, need zero SS, SP and FLAGS @cindex __dpmi_int, use to invoke software interrupts @quest{My program crashes/doesn't do what it should when I call @code{__dpmi_simulate_real_mode_interrupt.}} @ans{} You should zero out some of the fields of the @code{__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 @samp{SS}, @samp{SP} and @samp{FLAGS.} When @samp{SS} and @samp{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. @footnote{The DPMI spec indicates that you should @emph{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 @samp{SS} and @samp{SP} to a larger buffer which is in conventional memory (possibly part of the transfer buffer). @paragraph{} If @samp{SS:SP} isn't zero, it will be used as the address of the stack you want to be used by the interrupt handler, so if it points to a random location, your program will crash. A non-zero @samp{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!). @paragraph{} If you don't have any reason to set @samp{SS:SP} to your stack, it's easier to call the @code{__dpmi_int} library function, which zeroes out the stack pointer and the @samp{FLAGS} fields for you (and also doesn't force you to type long function names!). @node Xfer, 20 bits, Zero SP, Low-level @comment node-name, next, previous, up @section How to move data between your program and conventional memory? @cindex Transfer buffer, moving data @cindex Accessing absolute addresses in conventional memory @cindex Moving data to and from transfer buffer @cindex Moving data to and from conventional memory @cindex Conventional memory, moving data to/from @cindex Memory-mapped devices, moving data to/from @cindex Peripherals, moving data to/from @cindex Peek/poke absolute address @cindex nearptr method of direct memory access @quest{How can I move data between my program and the transfer buffer?} @quest{How do I access my peripheral card which is memory-mapped to an address between 640K and 1M?} @quest{How can I read or change a value of one of the variables in the BIOS data area?} @quest{How can I peek at an address whose far pointer I get from an @w{INT 21h} call?} @ans{} Depending on your specific needs, you can use one of three methods: @itemize @bullet{} @item If you want to access a byte, a 16-bit word, or a 32-bit double word, use the ``far pointer'' functions declared on the the @code{} header file. You should convert any real-mode far pointer segment:offset pair into a @dfn{linear address} (i.e., segment*16 + offset), and use the @code{_dos_ds} macro to get the selector which allows access to conventional memory, like this: @smallexample unsigned char value = _farpeekb(_dos_ds, segment*16 + offset); @end smallexample Use @code{_farpeekw} to peek at 16-bit shorts and @code{_farpeekl} to peek at 32-bit longs. If you need to access several (non-contiguous) values in a loop, use the corresponding @code{_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). @paragraph{} There is a corresponding set of @code{_farpokeX} and @code{_farnspokeX} functions to poke (change the values of) such memory locations. @paragraph{} 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. @item If you need to access more than 4 contiguous bytes, use @code{dosmemget} and @code{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. @paragraph{} Note that some memory-mapped peripheral devices might require 16-bit word accesses to work properly, so if @code{dosmemXXX} yields garbled results, try @code{dosmemXXXw} or ``farptr'' functions. @item For moving buffers larger than a few tens of bytes, it's best to use @code{movedata} library function. It requires that you pass selector and offset for both the conventional memory address and for the buffer in your program's address space. Use the @code{_my_ds} function to get the selector of any variable in your program, and use the address of the variable (cast to an @code{int}) as its ``offset'' or linear address. @code{movedata} is faster 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 @code{movedatab} and @code{movedataw} are provided for moving by bytes and by 16-bit words, respectively. @item For the fastest access to memory outside your usual flat address space, you might consider using the ``nearptr'' functions declared on the @code{} header; see the library reference for more details. Also see the description of how to get the @ref{Fat DS, fastest direct access to peripheral devices}, below. @end itemize @node 20 bits, Fat DS, Xfer, Low-level @comment node-name, next, previous, up @section Conventional-memory addresses use only 20 bits @cindex Transfer buffer, mask off 12 higher bits of address @cindex Linear address, mask off 12 higher bits @cindex movedata, mask off 12 higher bits of address @cindex Farptr functions, mask off 12 higher bits of address @cindex Nearptr functions, mask off 12 higher bits of address @quest{I call @code{movedata} to pass data between my program and the transfer buffer, but get bogus values or General Protection Fault.} @ans{} Valid conventional-memory addresses are only 20 bit-wide. However, the value stored in the variable @code{_go32_info_block.linear_address_of_transfer_buffer} (or its alias, @code{__tb}) is not guaranteed to have the higher 12 bits zeroed, and @code{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 @code{@dots{}_linear_address_@dots{}} fields in DJGPP structures, whenever that address references a conventional memory location, before you call @emph{any} of the functions from the @code{movedataX} family, the ``farptr'' or the ``nearptr'' functions. @node Fat DS, Above 1MB, 20 bits, Low-level @comment node-name, next, previous, up @section Fast access to memory-mapped devices or absolute addresses @cindex Peripheral devices, fast access @cindex Memory-mapped devices, fast access @cindex sbrk, effect on ``Fat DS'' @cindex Nearptr functions @cindex malloc, effect on ``Fat DS'' @cindex calloc, effect on ``Fat DS'' @cindex realloc, effect on ``Fat DS'' @pindex CWSDPMI allows ``Fat DS'' @pindex QDPMI allows ``Fat DS'' @pindex Windows 3.x allows ``Fat DS'' @pindex Windows 9x allows ``Fat DS'' @pindex OS/2 Warp allows ``Fat DS'' @pindex Linux doesn't allow ``Fat DS'' @pindex DOSEMU doesn't allow ``Fat DS'' @pindex Win/NT doesn't allow ``Fat DS'' @quest{The ``farptr'' functions are too slow for my application which @strong{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! @t{:(}} @ans{} The following so-called @b{Fat DS} method was suggested by @mail{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 @Steve{} has put it: @quotation @strong{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. @end quotation @paragraph{} Having said that, here is the trick: you change the limit of the segment descriptor stored in @samp{DS} to @code{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 @code{__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 @code{malloc} or any other library function which calls @code{sbrk} might sometimes change the base address of the @samp{DS} selector and break this method unless the base address is recomputed after @code{sbrk} call. (The ``nearptr'' functions support this recomputation by providing you with the @code{__djgpp_conventional_base} variable, but it is your responsibility to use it.) The same change happens when you call @code{system}, and as a result of some other events external to the executing code thread, like multitasking or debugger execution. @paragraph{} You should also know that the @code{__djgpp_nearptr_enable} function currently doesn't verify that the limit was properly set. So if the DPMI server would fail the call @strong{silently}, the function won't detect it and will not return a failure indication (but we don't know about any such DPMI server). @paragraph{} 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. @paragraph{} Confused about how exactly should you go about using this technique in your program? Look at the docs of the ``nearptr'' functions, @extref{__djgpp_nearptr_enable, __djgpp_nearptr_enable, libc.inf, libc.a reference, www.delorie.com/djgpp/doc/libc-2.00/libc_111.html#SEC111}. @paragraph{} Another possibility is to use the DPMI function @code{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 @strong{not} supported by most DPMI 0.9 hosts (@samp{CWSDPMI} does support it). There is a helper function @code{__djgpp_map_physical_memory} in the DJGPP C library that you can use to call these services. @node Above 1MB, RMCB, Fat DS, Low-level @comment node-name, next, previous, up @section Accessing absolute address above 1MB @cindex Peripheral devices above 1MB @cindex Memory-mapped devices above 1MB @cindex Accessing absolute addresses above 1MB @quest{How can I access memory-mapped peripheral devices (or any other absolute address) above 1 MByte mark?} @ans{} Use the @code{__dpmi_physical_address_mapping} library function. It returns a linear address which can be used to access a given absolute physical address. You can then use the functions from to access that linear address. If you prefer to create the mapping yourself, these are the DPMI calls that you will have to use: @itemize @minus{} @item allocate an LDT descriptor (Int 31h/AX=0); @item map selector to physical address (Int 31h/AX=0800h); @item lock linear address (Int 31h/AX=0600h); @item set segment base address (Int 31h/AX=7); @item set segment limit (Int 31h/AX=8). @end itemize All of these DPMI calls have @code{__dpmi__XXX} wrappers in the DJGPP library. @node RMCB, Hardware interrupts, Above 1MB, Low-level @comment node-name, next, previous, up @section How to make DOS/BIOS call your function @cindex Real-mode call-back @cindex Real-mode services, calling DJGPP functions @cindex Mouse handler with DJGPP @quest{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 @samp{ES:DX} register pair.} @ans{} 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 @code{_go32_dpmi_allocate_real_mode_callback_retf} or the @code{_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 @code{__dpmi_int.} See the docs in the library reference Info file for further details about allocating wrapper function. @node Hardware interrupts, _go32 vs __dpmi, RMCB, Low-level @comment node-name, next, previous, up @section How to hook hardware interrupts @cindex Hardware interrupts, hooking @cindex Interrupts handlers in DJGPP @cindex Interrupt reflection @cindex __dpmi_get_real_mode_interrupt_vector @cindex __dpmi_get_protected_mode_interrupt_vector @cindex _go32_dpmi_allocate_iret_wrapper @cindex _go32_dpmi_chain_protected_mode_interrupt_vector @cindex Real-mode interrupt vector @cindex Protected-mode interrupt vector @cindex Chaining interrupt @cindex Interrupt chaining @cindex Locking memory for hardware interrupt handlers @cindex Memory locking for hardware interrupt handlers @pindex CWSDPR0, use for testing HW interrupt handlers @quest{How do I register my DJGPP function as a hardware interrupt handler?} @ans{} The optimal set-up depends on the interrupt frequency and on the amount of processing it requires. Therefore, only some basic considerations and techniques are listed below. What combination of these is best for your application is up to you to decide. @paragraph{} First, some background. Hardware interrupts can occur when the processor is either in real mode (like when your program calls some DOS service) or in protected mode. When your program runs under a DPMI host, hardware interrupts are always passed to protected mode first, and only if unhandled are they reflected to real mode. Therefore, in DPMI mode you can get away with installing only a protected-mode handler. However, if the interrupts happen at a high frequency (say, more than 10 KHz), then the overhead of the interrupt reflection from real to protected mode might be too painful, and you might consider installing a real-mode interrupt handler in addition to the protected-mode one. If you do, you must hook the PM interrupt first, then the RM one (because hooking the PM interrupt modifies the RM one). Also, you should know that some DPMI hosts don't allow you to hook the RM interrupt (CWSDPMI does); the only way to be sure is to try. @paragraph{} To install a protected-mode interrupt handler, you do this: @paragraph{} @itemize @bullet{} @item 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 (@pxref{DPMI Spec, DOS Protected Mode Interface Specification}). To install assembly handler, you should do this: @paragraph{} @itemize @minus{} @item Call @code{__dpmi_get_protected_mode_interrupt_vector} and save the structure it returns (to restore the previous handler address before your program exits). @item Lock all the memory your handler touches with a series of calls to @code{__dpmi_lock_linear_region.} @item Finally, call @code{__dpmi_set_protected_mode_interrupt_vector} passing it the pointer to a @code{__dpmi_paddr} structure filled with @code{_my_cs} in the @code{selector} field and the address of your function in the @code{offset32} field. @end itemize @paragraph{} @item If your handler function is written in C, you should generally call the @code{_go32_dpmi_XXX} functions instead of the bare-bones API wrappers whose names start with @code{__dpmi_.} Specifically: @paragraph{} @itemize @minus{} @item Call @code{_go32_dpmi_get_protected_mode_interrupt_vector.} This function puts the selector and offset of the specified interrupt vector into the @code{pm_selector} and @code{pm_offset} fields of the structure pointed to by its second argument. This data should be saved and later passed to @code{_go32_dpmi_get_protected_mode_interrupt_vector} to restore the vector on exit. @item Call @code{_go32_dpmi_allocate_iret_wrapper,} passing it the address of your functions in the @code{pm_offset} field and the value of @code{_my_cs} in the @code{pm_selector} field. The @code{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 @code{_interrupt} keyword in some DOS-based compilers. @item If you want your handler to chain to the previous handler, call @code{_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 @code{pm_offset} field and the value of @code{_my_cs} into the @code{pm_selector} field of the @code{_go32_dpmi_seginfo} structure and pass a pointer to it to this function. @item You then call @code{_go32_dpmi_set_protected_mode_interrupt_vector} with the address of the @code{_go32_dpmi_seginfo} structure you got either from @code{_go32_dpmi_allocate_iret_wrapper} or from @code{_go32_dpmi_chain_protected_mode_interrupt_vector.} @end itemize @paragraph{} 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 @code{_CRT0_FLAG_LOCK_MEMORY} bit in the @code{_crt0_startup_flags} variable, or use @samp{CWSDPR0} or @samp{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. @paragraph{} Note that @code{_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. @end itemize @paragraph{} To install a real-mode interrupt handler, you do this: @paragraph{} @itemize @bullet{} @item Call @code{__dpmi_get_real_mode_interrupt_vector} and save the structure it returns (to restore the previous handler address before your program exits). @item Allocate some conventional memory with @code{__dpmi_allocate_dos_memory} and put the code of your handler there with the @code{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?) @item Put the address which @code{__dpmi_allocate_dos_memory} returned into a @code{__dpmi_raddr} structure (the lower 4 bits into @code{offset16} field, the rest into @code{segment} field), then call @code{__dpmi_set_real_mode_interrupt_vector.} @end itemize @paragraph{} For examples of installing and using hardware interrupt handlers, see the sample code written by @mail{Bill Currie, bill_currie@@MAIL.TAIT.CO.NZ}, the Sound Blaster interrupt-driven functions, the @samp{mkkbd} package, and the @samp{libhw} library, described under @ref{Samples, sample DJGPP packages}. @mail{Alaric B. Williams, @@abwillms.demon.co.uk} has written a @www{tutorial on DJGPP interrupt handling, www.abwillms.demon.co.uk/prog/djints.txt} @node _go32 vs __dpmi, HW Int pitfalls, Hardware interrupts, Low-level @comment node-name, next, previous, up @section Should I use _go32_XXX or __dpmi_YYY functions? @cindex _go32_XXX vs __dpmi_YYY, which one to use @cindex __dpmi_YYY vs _go32_XXX, which one to use @quest{In v1.x I was used to the @code{_go32_@dots{}} functions, but now comes v2 which also has @code{__dpmi_@dots{}} functions. Are there any differences between these two varieties?} @quest{Do I need to convert my old v1.x code to use the new @code{__dpmi_@dots{}} functions?} @ans{} 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 @code{__dpmi_@dots{}} functions are just bare-bones wrappers of the DPMI API calls (@pxref{DPMI Spec, DPMI Specification}), generally unsuitable for use with handlers written in C, whereas the old @code{_go32_@dots{}} functions are intelligent helper functions which only make sense if your interrupt handlers are C functions. The problem with the @code{_go32_@dots{}} 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 @code{#define'd} to the new names where the functionality is identical. @paragraph{} 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 @code{__dpmi_@dots{}} functions (@pxref{Hardware interrupts, How to install a hardware interrupt handler}). @node HW Int pitfalls, Ports, _go32 vs __dpmi, Low-level @comment node-name, next, previous, up @section Hardware interrupt hooking has its subtleties @dots{} @cindex Hardware interrupts, subtleties @cindex Hardware interrupt handler crashes @cindex Interrupt frequency, maximum @cindex Maximum interrupt frequency @cindex Interrupt handlers, locking memory @cindex Locking memory for interrupt handlers @cindex Unix-like sbrk algorithm considered harmful for HW interrupts @cindex Keystrokes don't get to keyboard handler @cindex Overhead, interrupt reflection to protected mode @cindex Interrupt reflection overhead @pindex EMM386, effect on max interrupt frequency @pindex _crt0_startup_flags, setting to lock memory @pindex _crt0_startup_flags, Unix sbrk is incompatible with HW interrupts @pindex sbrk, Unix-like algorithm is incompatible with HW interrupts @pindex CWSDPR0 reduces interrupt reflection overhead @pindex PMODE/DJ reduces interrupt reflection overhead @quest{I did all the above, but my program occasionally still hangs@dots{}} @ans{} Hooking hardware interrupts in DJGPP (and in protected mode in general) has a few subtle aspects. In general, hardware interrupt handling in DJGPP v2.0 is rock solid @strong{if you play by the rules}. Unfortunately, the rules are a bit tricky. @paragraph{} 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 @code{__dpmi_lock_linear_region} library function. This also means in practice that you should write your handler in assembly, as described in @ref{Hardware interrupts, how to set an interrupt handler}, above. You can disable virtual memory, or put @code{_CRT0_FLAG_LOCK_MEMORY} into @code{_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). @paragraph{} 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 @samp{CWSDPR0} or @samp{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. @paragraph{} 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. @paragraph{} Still another possibility is that you use a non-default @code{sbrk} algorithm in your program (check if the header file @file{crt0.h} is included anywhere in the program, and if so, if the @code{_CRT0_FLAG_UNIX_SBRK} bit in the @code{_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. @paragraph{} 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 @file{.PIF} file). @paragraph{} If the above still doesn't explain your problem, then post your code on @news{comp.os.msdos.djgpp} or the @mail{djgpp mailing list, djgpp@@delorie.com}, tell there how it fails and somebody will usually have a solution or a work-around for you. @node Ports, Inline Asm, HW Int pitfalls, Low-level @comment node-name, next, previous, up @section How to read and write ports @cindex Peripheral devices, reading/writing ports @cindex Port reading/writing @cindex inp function @cindex outp function @quest{I need to read from and write to PC ports, and I'm accustomed to using the @code{inp} and @code{outp} functions. But I hear they aren't available in DJGPP?} @ans{} They are in v2.x. Just @ifset html @code{@w{#include <pc.h>}} @end ifset @ifclear html @code{@w{#include }} @end ifclear 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 @w{dword-long} access (e.g., @code{inportl} for reading a 32-bit dword), as well as functions to read/write sequences of bytes and words, like @code{inportsb} and @code{outportsw}; these are DJGPP-specific. @node Inline Asm, , Ports, Low-level @comment node-name, next, previous, up @section Inline Assembly code with GCC @cindex Inline assembly, how to write @cindex Accessing C variables from inline assembly @pindex GCC, inline assembly facilities @quest{I am used to writing inline assembly with Borland C, but can't figure out the way to do it with GCC@dots{}} @quest{How can I reference C variables from my inline assembly code?} @ans{} 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 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: @example info gcc "C Extensions" "Extended Asm" @end example (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 @file{txi@value{txi-version}b.zip} from the DJGPP distribution and install it. @paragraph{} If you read this FAQ via WWW, you can also @www{read about the GCC inline assembly extensions with your Web browser, www.delorie.com/gnu/docs/gcc/gcc_86.html#SEC89} @node Legalese, Help, Low-level, Top @comment node-name, next, previous, up @chapter Legal Aspects @cindex Legal aspects of DJGPP programming @cindex Copyright issues This chapter answers some questions about various legal aspects of writing programs with DJGPP. @menu * Applications:: Legal restrictions of applications written with DJGPP. * Redistribution:: Legal aspects of redistributing DJGPP itself. @end menu @node Applications, Redistribution, Legalese, Legalese @comment node-name, next, previous, up @section Legal (un)restrictions on DJGPP applications @cindex GPL, effect on DJGPP @cindex LGPL, effect on DJGPP @cindex GNU Copyleft, effect on DJGPP @cindex Copyleft, effect on DJGPP @cindex Legal restrictions on DJGPP apps @cindex DJGPP applications, legal restrictions @cindex Commercial programs, writing with DJGPP @pindex libgpp.a, legal restrictions @pindex libiostream.a, legal restrictions @pindex C++ class libraries, legal restrictions @pindex Flex doesn't imply GPL/LGPL @pindex Bison doesn't imply GPL/LGPL @quest{Can you explain in plain English the legal restrictions of distributing programs compiled with DJGPP?} @quest{Can I write commercial programs with DJGPP?} @ans{} 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 @emph{any} restrictions. The C library which comes with DJGPP is @emph{free}, which means you are free to use it in any way you like (but please observe @ref{Redistribution, basic rules of courtesy}.) So, if you write C programs, you have absolutely nothing to worry about. The basic C++ @samp{iostream} class library (@file{libiostr.a}) and the Standard Template Library (@file{libstdcx.a}) which come with DJGPP allow you to use them binary-wise (i.e., without changing library sources) in your C++ programs @emph{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 (@file{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 @file{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.) @paragraph{} Note that @file{libiostr.a} library doesn't place your program under GPL or LGPL, so if you only use C++ classes included in that library, make your compilations use @file{libiostr.a} instead of @file{libgpp.a.} (That's the only reason for having @file{libiostream.a} as a separate file, because @file{libgpp.a} includes everything @file{libiostream.a} does, so you never need both of them.) @paragraph{} Two GNU packages, @samp{Flex} and @samp{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 @samp{Flex} and parsers produced by @samp{Bison} do @strong{not} imply GPL/LGPL. @paragraph{} If you @strong{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 @samp{getopt} or @samp{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 @samp{regex} and @samp{getopt} from the DJGPP C library (which is free). @paragraph{} You may ship any of the utilities developed specifically for DJGPP (e.g., the floating-point emulator or the CWSDPMI DPMI host) @emph{as distributed by DJ Delorie} with your program with no other requirement besides telling your customers how to get DJGPP for themselves. @paragraph{} Note that the above says nothing about the legal aspects of contributed packages, like @samp{GRX} and others; you will need to read their docs to find out. @node Redistribution, , Applications, Legalese @comment node-name, next, previous, up @section Legal restrictions of DJGPP utilities and libraries @cindex Legal restrictions, DJGPP utilities @cindex DJGPP utilities, legal restrictions @cindex C library, legal restrictions @pindex CWSDPMI, legal restrictions @quest{Can I redistribute djgpp, and if so, how?} @quest{I run a business that sells shareware for distribution costs. Can I include djgpp on my CD-ROM?} @quest{I want to include djgpp in a product that happens to need a compiler provided with it. Can I do this?} @quest{Is DJGPP GNU software?} @quest{Is DJGPP public domain software?} @quest{Is DJGPP shareware?} @ans{} DJGPP is @strong{not} public domain, neither is it shareware (you @emph{don't} have to pay a license fee to use DJGPP). Parts of DJGPP (the compiler and some of the development tools) @emph{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. @paragraph{} 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 you follow these rules: @paragraph{} @itemize @bullet{} @item 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{}. @item 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. @item You must call it @strong{DJGPP} and nothing else. @item You may @strong{not} take credit for it, and you must @strong{not} remove any notices in DJGPP that give credit to those who worked on it. @item 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. @w{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. @item Distributing CWSDPMI with shareware or commercial programs requires notification of its author @CWS{} by mail or acknowledged e-mail. @end itemize @paragraph{} In addition, it would be a courtesy to inform @DJ that you are including DJGPP in your product, in case this information is obsolete. A token sample of your distribution would be nice also. @node Help, v2, Legalese, Top @comment node-name, next, previous, up @chapter Getting Help @cindex Getting more help @cindex More help, how to get This chapter tells you how to get answers to questions you didn't find in this FAQ. @menu * DJGPP isn't GNU:: Do @strong{not} post to GNU News groups. * Mailing list:: How to post to DJGPP mailing list. * Subscribing:: You can see every posted article. * Unsubscribing:: When it's too much to read@dots{} * Silent list:: Is the list alive? * Duplicates:: If you get duplicate messages. * Newsgroup:: We prefer you use it instead of the mailing list. @end menu @node DJGPP isn't GNU, Mailing list, Help, Help @comment node-name, next, previous, up @section Don't post DJGPP-specific problems to GNU News groups @cindex GNU News groups, don't post DJGPP problems @cindex Posting problems, not to GNU News groups @quest{I post my problem to the ``help-gcc'' News group, but don't get any answers.} @ans{} 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 @news{comp.os.msdos.djgpp} or to the @mail{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 a generic one in one of the FSF utilities. For most problems, this can be deduced only after either tracing a problem in the source code or testing it on some non-DOS platform. As a general rule, always post to the DJGPP group first. @node Mailing list, Subscribing, DJGPP isn't GNU, Help @comment node-name, next, previous, up @section How to post to the mailing list @cindex DJGPP mailing list, how to post @cindex Posting to DJGPP mailing list @quest{How do I post to the DJGPP mailing list?} @ans{} Send mail to the @mail{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. @node Subscribing, Unsubscribing, Mailing list, Help @comment node-name, next, previous, up @section How to become a subscriber to the mailing list @cindex DJGPP mailing list, how to subscribe @cindex Subscription to DJGPP mailing list @cindex Announcements, mailing list @cindex DJGPP-ANNOUNCE mailing list @cindex DJGPP News group, reading via WWW @cindex DJGPP mailing list, in digest form @cindex Weekly digest, problems in receiving @quest{How do I subscribe to the DJGPP mailing list?} @ans{} Send mail to the @mail{list server, listserv@@delorie.com} (NOT to djgpp@@!!), leave the subject line empty and in the body write: @quotation subscribe djgpp @end quotation 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 @samp{djgpp-announce} by sending message to the @mail{list server, listserv@@delorie.com} which says so: @quotation subscribe djgpp-announce @end quotation The announcements which go to @samp{djgpp-announce} get reflected to @samp{djgpp}, so you don't have to subscribe to both these lists. @paragraph{} 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: @quotation subscribe djgpp-digest-daily @end quotation or @quotation subscribe djgpp-digest-weekly @end quotation 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. @paragraph{} You can also subscribe to DJGPP-related mailing lists @www{through DJ Delorie's WWW server, www.delorie.com/mailing-lists/subscribe.html} @paragraph{} 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. @paragraph{} If you have a Usenet feed, consider reading the @news{comp.os.msdos.djgpp} instead, 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 @gopher{Mercury Gopher server at Michigan State University, gopher.msu.edu:3441/chronological%20comp.os.msdos.djgpp} @node Unsubscribing, Silent list, Subscribing, Help @comment node-name, next, previous, up @section How to unsubscribe from the mailing list @cindex DJGPP mailing list, how to unsubscribe @cindex Unsubscribing from the DJGPP mailing list @cindex Read DJGPP traffic via WWW @cindex DJGPP mailing list/news group, read via WWW @quest{Whew! There's too much traffic on the djgpp mailing list (at least the SysAdmin glaring over my shoulder thinks so@dots{} ;-). How do I unsubscribe myself?} @quest{I've been trying for days to unsubscribe from the djgpp mailing list. What am I doing wrong?} @ans{} You should be sending your unsubscribe messages to the @mail{list server, listserv@@delorie.com} @emph{(not djgpp@@delorie.com!),} with the contents being just this: @quotation unsubscribe djgpp @end quotation When you unsubscribe, that stops @emph{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. @paragraph{} If you think you have waited enough and the messages still keep coming, write to @mail{listserv administrator, djgpp-request@@delorie.com} and ask him to help you. @paragraph{} You can also unsubscribe yourself from any of the DJGPP-related mailing lists @www{through DJ Delorie's WWW server, www.delorie.com/djgpp/mailing-lists/subscribe.html} @paragraph{} 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 @www{via World-Wide Web, www.delorie.com/djgpp/mail-archives/browse.cgi} @paragraph{} @node Silent list, Duplicates, Unsubscribing, Help @comment node-name, next, previous, up @section If you don't see any message from the list @dots{} @cindex DJGPP mailing list, no messages @cindex No messages from the mailing list @quest{I don't get any messages from the DJGPP list for several days. Is the list alive?} @ans{} 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 consistently fails (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 @www{through DJ Delorie's WWW server, 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 @mail{listserv, listserv@@delorie.com}, or @www{via DJ's server, www.delorie.com/djgpp/mailing-lists/subscribe.html} When in doubt, re-subscribe anyway (it hurts neither you, nor the list server). @paragraph{} 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. @node Duplicates, Newsgroup, Silent list, Help @comment node-name, next, previous, up @section Why do I get every message more than once? @cindex DJGPP mailing list, duplicate messages @cindex Duplicate messages from DJGPP mailing list @quest{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??} @ans{} First, check the headers to make sure that all of the duplicate messages have their @samp{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 @samp{Cc:} (the @dfn{carbon copy}) one via djgpp list server. This is normal behavior. @paragraph{} 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 @www{through DJ's server, www.delorie.com/djgpp/mailing-lists/subscribe.html} @sp 1 Look out for multiple subscriptions, possibly under different names/addresses. You could also write to @DJ{}, and ask him to investigate. @paragraph{} 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 @samp{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. @paragraph{} Many times this kind of problem is caused by excessive load on the list server, so everybody who can please switch to reading the @news{comp.os.msdos.djgpp} and unsubscribe from the list. @node Newsgroup, , Duplicates, Help @comment node-name, next, previous, up @section DJGPP now has a news group! @cindex DJGPP News group @quest{With so much daily traffic (about 30 messages a day), isn't it high time to create a Usenet News group?} @ans{} Beginning June 1st, 1995, DJGPP @emph{has} its News group! It is called @strong{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 @b{;-)}; you can read either one and post to either one, and everyone eventually sees everything. The entire traffic ends up in the mail archives on the DJ's Web server within 24 hours, and is available for @www{searching, 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. @node v2, Miscellany, Help, Top @comment node-name, next, previous, up @chapter Version 2.0 vs v1.x @cindex V2.0, new features and bug fixes This chapter is for those who are used to working with DJGPP v1.x and want to know more about v2.0 while they consider switching. @menu * New and improved:: What's new in v2.0? * Environment:: How v2.0 environment is different from v1. @end menu @node New and improved, Environment, v2, v2 @comment node-name, next, previous, up @section New features in DJGPP v2.0 @cindex New features in v2.0 @quest{What exciting new features will I find in v2.0 as opposed to v1.x?} @ans{} DJGPP v2.0 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.0 features the following major improvements upon v1.1x: @itemize @bullet{} @item much faster extender (the free DPMI host) and library functions; @item very low memory footprint of the DPMI host below 640KB; @item the DPMI server is loaded only once: no more problems with spawning child programs (e.g., almost unlimited recursive Make's); @item ANSI- and POSIX-compliant libraries and header files, which should make porting Unix programs a lot easier; @item support for signals; @item 387 emulation under DPMI; @item graphics which works in @emph{any} setup, including under Windows; @item fixes of many bugs in hardware interrupts' and mixed-mode programming support; @item ability to build all of DJGPP without commercial products (like Turbo C required to compile go32 in v1.x); @end itemize @paragraph{} 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. @node Environment, , New and improved, v2 @comment node-name, next, previous, up @section DJGPP environment in v2.0 @cindex V2.0, new environment @cindex Run-time environment in v2.0 @cindex DPMI hosts, commercially available @cindex DJGPP v2.0, alternative DPMI hosts @pindex CWSDPMI, alternative DPMI hosts @quest{There's been this talk about v2 and about @samp{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?} @ans{} In v1.x of DJGPP, the @samp{go32} extender was responsible for the following: @itemize @bullet{} @item Loading and running the application in protected mode. @item Managing protected-mode and virtual memory. @item ``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.) @item Handling of hardware interrupts which happen while the CPU is in protected mode. @item Loading 387 emulator (if required). @item Loading the graphics driver and working with VGA bank-switching to create an illusion of a linear video memory. @item Command-line and wild-card expansion in a Unix-like fashion. @end itemize In v2.x, most of these functions are done by a DPMI host, which is a memory-resident software required to run protected-mode programs under MS-DOS. There are a few commercial DPMI hosts (like Quarterdeck's @samp{QDPMI}, Qualitas @samp{386Max}, MS-Windows 3.x and Win95, OS/2, even Linux), but DJGPP v2 comes with a free DPMI host called @samp{CWSDPMI} for those who don't have one already. Loading the application into protected-mode memory (a function done in v1.x by @samp{go32}) is handled by a 2KB-long real-mode stub which runs at start-up, before the application's @code{main} functions is called (the stub will also load @samp{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. @paragraph{} @samp{CWSDPMI} can be loaded as a TSR, even loaded @samp{HIGH} into the HMA/UMB, which will make applications load much faster. @node Miscellany, About, v2, Top @comment node-name, next, previous, up @chapter Miscellany This chapter is a hodgepodge of questions which don't belong to any of the other chapters. @menu * Changing:: How to change any DJGPP package? * Samples:: Where to find sample/ported code for DJGPP? * Symlinks:: Yes, DJGPP allows them (well, almost@dots{}) * DPMI Spec:: Where to look for DPMI specifications. * WWW:: The DJGPP Web site. * Upload:: Where to upload your DJGPP packages. * Cross-DJGPP:: You can use DJGPP for cross-development. * 0xfe+0x20:: Is this a bug? * Struct size:: What is the size of a struct under DJGPP? * Struct packing:: C++ compiler doesn't pack structs. * Int 24h:: Catching those ``Abort, Retry'' messages. * go32-v2:: What is go32-v2 for? * DXE:: What are those @file{.dxe} files? * LFN:: LFN support has some subtle bugs. * Missing separator:: What does Make mean by that? * Zoneinfo:: What's in that @strong{zoneinfo/} directory? * FAQ format:: How to convert this FAQ to other formats. @end menu @node Changing, Samples, Miscellany, Miscellany @comment node-name, next, previous, up @section How to change a DJGPP package? @cindex Changing GNU/DJGPP programs @cindex GNU packages, how to change @cindex Recompiling GCC @cindex Known bugs in DJGPP, how to browse @cindex Bugs, how to browse a list of known DJGPP problems @cindex Bug report, how to submit @cindex Bug-tracking system for DJGPP @pindex GCC, recompiling @pindex Sed requires floating point @pindex Make requires floating point @quest{I want to change cc1. How do I do this?} @quest{How do I fix a bug/add a feature to one of the DJGPP programs?} @ans{} First, get the sources. These are called @file{*s.zip} in the DJGPP distribution. The C Library sources are in @file{djlsr@value{djgpp-version}.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: @table @file @titem gcc263s1.zip @titem gcc263s2.zip @titem gcc263s3.zip @titem gcc263s4.zip @titem gcc263s5.zip @titem gcc263s6.zip @end table @paragraph{} All sources are shipped in ready-to-build form. Any diffs that come with the source distribution, like the files in the @file{diffs/} directory, have already been applied. @paragraph{} Next, try to build the program without changing it. Some packages will have a @file{CONFIGUR.BAT} file; if so, run it first. If there is a @file{MAKE.BAT} file, run it; if not, look for a file named @file{MAKEFILE.DJ} or @file{MAKEFILE.DJG}; sometimes these will be in a subdirectory called @file{dos/}, or @file{msdos/}, or @file{pc/.} If there is such a file, then type, e.g., @kbd{make -f makefile.djg}, if not, just say @kbd{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. @paragraph{} Note that generally you must have the GNU @samp{Make} program to build these programs (get the file @ftp{mak@value{mak-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/v2gnu/mak@value{mak-version}b.zip}), and some makefiles require that you install additional utilities, like Sed (get @ftp{sed@value{sed-version}b.zip, @SimTel{}/pub/simtelnet/gnu/djgpp/sed@value{sed-version}b.zip}). Sometimes the makefiles won't even run under @file{COMMAND.COM} (they require a smarter shell). In that case, either get a better shell, convert the makefile to be runnable by @samp{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 @samp{-n} switch and see what it would have done. @paragraph{} 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, @ref{Emulation, FP Emulation}. @paragraph{} 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 @www{list of known bugs, www.delorie.com/djgpp/doc/kb/kb_7.html#SEC4} If your bug is not there, you can later @www{submit it to the bug-tracking system, www.delorie.com/djgpp/bugs/} Before you submit a bug report, please make every effort to verify that your bug is not caused 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. @node Samples, Symlinks, Changing, Miscellany @comment node-name, next, previous, up @section Where to find sample DJGPP code or a package ported to DJGPP? @cindex DJGPP, sample code @cindex Packages, ported to DJGPP @cindex Sound Blaster code for DJGPP @cindex Timer interrupts code for DJGPP @cindex TCP/IP library for DJGPP @cindex Curses library for DJGPP @cindex X emulation for DJGPP @cindex GNU development utilities, port to DJGPP @cindex Turbo Vision, DJGPP port @cindex Game programming, libraries and techniques for DJGPP @cindex VGA Mode-X graphics for DJGPP @cindex RCS port to DJGPP @cindex Development environments for DJGPP @pindex RCS port to DJGPP @pindex RHIDE, development environment for DJGPP @pindex EMACS can be compiled with DJGPP @quest{Where can I find an example of XXXX / a package doing YYYY ?} @ans{} @Steve{} 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. @www{Check out Steve's list, turnbull.sk.tsukuba.ac.jp/public-ftp/djgpp/doc/documentation.list.html} @paragraph{} Here is a list of places you might look into for examples of frequently needed code fragments, or for packages people keep asking about: @itemize @bullet{} @item Interrupt-driven support of peripheral devices and hooking hardware interrupts: @itemize @minus{} @item @mail{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 @www{with your Web browser, www.abwillms.demon.co.uk/prog/libhw.zip} @item @mail{Bill Currie, bill_currie@@MAIL.TAIT.CO.NZ} has written @ftp{sample code for hardware interrupt handlers, 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. @item @mail{Martynas Kunigelis, martynas.kunigelis@@vm.ktu.lt} donated a tutorial and a working @ftp{code that installs a keyboard interrupt handler, @SimTel{}/pub/simtelnet/gnu/djgpp/v2tk/mkkbd3.zip} that can also serve as a good example of a hardware interrupt handler. @item you can look at the latest version of @ftp{Sound Blaster support library at the Oulu repository, x2ftp.oulu.fi/pub/msdos/programming/djgpp2/sb05_dj2.zip} or @ftp{at the DJGPP server, ftp.delorie.com/pub/djgpp/contrib/sb05_dj2.zip}; this package is maintained by @mail{Joel Hunter, jhunter@@kendaco.telebyte.net}. @item check out the example of @ftp{hooking the timer interrupt, @CCT{}/Coast/msdos/c/pctime13.zip}. @item if you need a serial communications library, check out @ftp{SVAsync, ftp.delorie.com/pub/djgpp/contrib/svasync.zip}. @end itemize @item Network support libraries: @itemize @minus{} @item the @ftp{TCPLIB library, 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.) @item a port of @ftp{WATTCP library, ftp.msen.com/pub/vendor/snsi/wattcp/gnu-c/}. @end itemize @item Port of curses library to DJGPP: @itemize @minus{} @item download @ftp{PDCurses package, @SimTel{}/pub/simtelnet/gnu/djgpp/v2tk/pdc@value{pdc-version}.zip}. @end itemize @item X library: @itemize @minus{} @item the @ftp{Xlibemu library, asterix.inescn.pt/pub/PC/X/} includes @samp{Xt} and @samp{Xmu} toolkits, a 3D version of the @samp{AW} toolkit, a few demo applications (e.g. @samp{xmine}), and can be used to compile @samp{Tcl}/@samp{Tk} and GNU Emacs with X support. Xlibemu is based on X11R5 and was developed by @mail{Antonio Costa, acc@@asterix.inescn.pt} for DJGPP v1.x. It is also available @ftp{on an alternative site, groucho.idt-isep.ipp.pt/pub/pc/djgpp/etc/X/} and @ftp{on the DJGPP server, ftp.delorie.com/pub/djgpp/contrib/Xlibemu/}. @item the @ftp{Xlib and Xt for DV/X environment, @SimTel{}/pub/simtelnet/gnu/djgpp/v1tk/qddvx102.zip} (you will also need qdlib102.zip and qdtkt102.zip from the same site). @end itemize @item Ports of various GNU utilities not included in DJGPP (like Fileutils, Grep, Less, etc.): @itemize @minus{} @item Look on SimTel mirrors @ftp{in the GNUish, @SimTel{}/pub/simtelnet/gnu/gnuish/dos_only/} and @ftp{Textutil, @SimTel{}/pub/simtelnet/msdos/textutil/} directories. These are 16-bit ports. @item @mail{Marc Singer, elf@@netcom.com} maintains a @ftp{port of RCS\, the Revision Control System\, to DJGPP, ftp.netcom.com/pub/el/elf/rcsdos/}. @end itemize @item Development environments: @itemize @minus{} @item Try the RHIDE system by @mail{Robert Hoehne, Robert.Hoehne@@Mathematik.TU-Chemnitz.DE}. RHIDE is in the last stages of beta-testing and is available @www{via WWW, www.tu-chemnitz.de/~rho/rhide.html} and also @ftp{from the DJGPP disribution sites, @SimTel{}/pub/simtelnet/gnu/djgpp/v2apps/} @item If you want the ultimate editing power, you might as well go for the best, which is of course the one-and-only GNU Emacs! The latest version of Emacs is available @ftp{from the GNU ftp sites, ftp.gnu.ai.mit.edu/pub/gnu/emacs-@value{emacs-version}.tar.gz} and will compile out of the box with DJGPP v2. The DJGPP version supports menus, mouse, color syntax highlighting and many Emacs packages (like @samp{ps-print} and @samp{ediff}) that previously didn't work on MS-DOS. On Windows 95, Emacs compiled with DJGPP supports long filenames. @c @c Mention 2 patches (to is_exec and sigaction) needed to fix DJGPP @c bugs revealed by Emacs? @c @end itemize @item GUI libraries: @itemize @minus{} @item 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 @mail{Eric Nicolas, nicolas@@JUPITER.saclay.cea.fr}. The latest version 2.1 is available from the @ftp{DJGPP v2tk subdirectory, @SimTel{}/pub/simtelnet/gnu/djgpp/v2tk/} as sw21_*.zip. @item check out the @www{BCGUI package, www.delorie.com/djgpp/dl/contrib/} @sp 1 or @ftp{get BCGUI via FTP, ftp.delorie.com/pub/djgpp/contrib/bcguiNNN.zip} or @ftp{get BCGUI at Stephen Turnbull's server, turnbull.sk.tsukuba.ac.jp/pub/djgpp/packages/bcguiNNN.zip}. @item If you actually have the original Borland Turbo Vision, then you might want to get @ftp{patches to compile Turbo Vision under DJGPP, ftp.uni-stuttgart.de/pub/systems/os2/programming/support/}. For more info on this port, visit the @www{TVPlus site, www.zeta.org.au/~grove/tvhome.html} @item Another port of Turbo Vision library was done by @mail{Robert Hoehne, Robert.Hoehne@@Mathematik.TU-Chemnitz.DE}, and can be downloaded @www{via WWW, www.tu-chemnitz.de/~rho/tvision.html}, and also @ftp{from the DJGPP distribution sites, @SimTel{}/pub/simtelnet/gnu/djgpp/v2tk/tvisionb.zip} @end itemize @item Game programming: @itemize @minus{} @item Try the @ftp{Jlib gaming/graphics library, x2ftp.oulu.fi/pub/msdos/programming/djgpp2/jlib_NNN.zip} written by @mail{J P Griffiths, jpg@@cs.waikato.ac.nz}. @item Also see the @ftp{Allegro game programming library, x2ftp.oulu.fi/pub/msdos/programming/djgpp2/alleg21.zip}, written by @mail{Shawn Hargreaves, slh100@@mailer.york.ac.uk}. It is also available @ftp{from the DJGPP archives, @SimTel{}/pub/simtelnet/gnu/djgpp/v2tk/alleg21.zip}. @end itemize @item VGA Mode-X graphics: @itemize @minus{} @item @mail{Paul Fenwick, bg914@@FreeNet.Carleton.CA} wrote an X-Mode package @ftp{Xlib, ftp.delorie.com/pub/djgpp/contrib/xlibdj24.zip} or @ftp{Xlib at Oulu, x2ftp.oulu.fi/pub/msdos/programming/djgpp2/xlibdj24.zip}. @end itemize @end itemize @node Symlinks, DPMI Spec, Samples, Miscellany @comment node-name, next, previous, up @section How to create symbolic links to programs @cindex Symbolic links, simulation with DJGPP @cindex Links, symbolic, simulation with DJGPP @quest{How do I create symbolic links?} @quest{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??} @ans{} 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 @file{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 @file{dj1.exe} and we want to make a link called @file{dj2.exe} that really calls @file{dj1.exe.} First, generate a stub under the name @file{dj2.exe.} Next, run @samp{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 @file{dj1}: @smallexample C:\USR\BIN> stubify -g dj2.exe C:\USR\BIN> stubedit dj2.exe runfile=dj1 @end smallexample Voila! Now, when you run @samp{dj2}, it tells the stub to load the image of @samp{dj1}, but pass ``dj2'' in @code{argv[0].} @node DPMI Spec, WWW, Symlinks, Miscellany @comment node-name, next, previous, up @section Where to find the DPMI specification? @cindex DPMI spec, where to get it @quest{Where can I find the specifications for the DPMI functions?} @ans{} You can find the DPMI 0.9 spec by anonymous ftp to one of the following sites: @paragraph{} @ftp{At the Quarterdeck ftp site, qdeck.com/pub/memory/dpmispec.zip}. @paragraph{} @ftp{At the Oulu repository of PC-specific programming info, x2ftp.oulu.fi/pub/msdos/programming/specs/dpmispec.arj}. @paragraph{} The DPMI 1.0 specs are available by anonymous ftp from the @ftp{Intel anonymous ftp site, ftp.intel.com/pub/IAL/software_specs/dpmiv1.txt}. (The file @file{dpmip1.zip} at the same location is the PostScript version of this spec.) @paragraph{} Some information about the DPMI API is also found in the @ftp{Ralf Brown's Interrupt List, @SimTel{}/pub/simtelnet/msdos/info/inter@value{inter-version}c.zip}. Look at the functions of Interrupt 31h, or search the files for the word @kbd{DPMI.} @paragraph{} You can also @www{browse the DPMI spec on-line, www.delorie.com/djgpp/doc/dpmi/} @node WWW, Upload, DPMI Spec, Miscellany @comment node-name, next, previous, up @section The DJGPP Web site. @cindex Web site for DJGPP @cindex WWW services for DJGPP @quest{Where is the DJGPP Web site?} @ans{} Yes, DJGPP has its own home on the Internet, set up and maintained by (who else?) @DJ{}. 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 @www{the story of DJGPP genesis, www.delorie.com/djgpp/history.html} @paragraph{} To visit, point your Web browser to @www{the DJGPP Web site, www.delorie.com/djgpp/} @node Upload, Cross-DJGPP, WWW, Miscellany @comment node-name, next, previous, up @section Where to upload your contributions to DJGPP @cindex DJGPP software, where to upload @cindex Uploading DJGPP software @quest{I wrote a program using DJGPP. How can I make it available to others?} @quest{I found and corrected a bug in one of the programs distributed with DJGPP. Where should I put it?} @ans{} If the program/patches are small enough, consider posting it to the mailing list or the @news{comp.os.msdos.djgpp} as uuencoded compressed archive (to conserve space). @paragraph{} 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 @ftp{DJ Delorie's FTP server, ftp.delorie.com/incoming/}. This directory is write-only, and it gets purged every couple of days, so be sure to write to @DJ about your upload; he will then move it to the @file{/pub/djgpp/contrib} directory. (There used to be another place, a directory on @file{omnigate.clarkson.edu} which was writable by anonymous, but it was being used for malicious purposes and the sysadmins there decided to close it @t{:-(}.) @paragraph{} If you decide to upload, please send mail to the @samp{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.) @paragraph{} If your program is more than a patch or a beta version, you might consider uploading it to the DJGPP archives on SimTel. If you decide to do it, write to @DJ and ask him for uploading instructions. Material uploaded there gets automatically distributed to all of the SimTel mirrors throughout the world, which makes it easier to get. @paragraph{} 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. @node Cross-DJGPP, 0xfe+0x20, Upload, Miscellany @comment node-name, next, previous, up @section DJGPP as cross-compiler @cindex DJGPP as cross-compiler @cindex Cross-compiling with DJGPP @cindex 68K targets, cross-compiling with DJGPP @cindex Motorola 68K targets, cross-compiling with DJGPP @cindex Unix-to-DOS cross-compiling with DJGPP @quest{I want to use DJGPP as a cross-compiler for Motorola 68K targets. How should I proceed about this?} @quest{I want to build GCC as a Unix-to-DOS cross-compiler. What should I do?} @ans{} If you want a cross-compiler for m68k on a DOS machine, you need is DJGPP configured as @samp{host=i386-go32}, and @samp{target=m68k-coff.} This @ftp{has been done already, 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 @mail{Jim Karpinski, jk55@@cornell.edu}. @paragraph{} 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.) @paragraph{} 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. @paragraph{} Unpack Gcc and Binutils into a directory, let's call it @file{X/.} Thus, you have, say, @file{X/gcc-2.7.0} and @file{X/binutils-2.5.2.} The following sequence of commands should make the job: @example 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 @end example Unzip the DJDev and Gcc distributions in, say, /usr/local/djgpp. Ideally, build libgcc.a on a DOS machine, or get it from the @file{djcrx200.zip} archive. @paragraph{} Remove all @kbd{^M} characters from include files (you can compile DTOU.c on the Unix box to make this easier). Alternatively, use the @samp{-a} switch to UnZip when unzipping the archives. @paragraph{} Change lib/djgpp.lnk to use ``coff-i386'' instead of ``coff-go32'' and remove the @kbd{^M} characters from that file also. @example 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/* . @end example Build @file{stubify} and install it in @file{/usr/local/i386-go32-msdos/bin.} You might need to insert these two lines at the beginning of @file{stubify.c}: @example @ifset html @code{@w{#include <sys/types.h>}} @code{@w{#include <unistd.h>}} @end ifset @ifclear html @code{@w{#include }} @code{@w{#include }} @end ifclear @end example That's it! To build a program for DOS, say something like this: @example gcc-dos hello.c -o hello.exe @end example @node 0xfe+0x20, Struct size, Cross-DJGPP, Miscellany @comment node-name, next, previous, up @section GCC says ``garbage at end of number'' @cindex Garbage at end of number, GCC message @pindex GCC says ``garbage at end of number'' @quest{There is a severe bug in GCC: it says ``garbage at end of number'' for this line:} @example i = 0xfe+0x20; @end example @paragraph{} @emph{Ain't it silly that such a great compiler would fail so miserably?} @ans{} That's not a bug, that's a feature of the @emph{ANSI C language definition.} By ANSI rules, the above expression is a single @dfn{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 @samp{-traditional} compiler switch to turn this feature off (together with a plethora of other ANSI features; see the GCC docs for details). @node Struct size, Struct packing, 0xfe+0x20, Miscellany @comment node-name, next, previous, up @section What should sizeof (struct xyzzy) return? @cindex Size of a struct under DJGPP @cindex Struct, size in bytes under DJGPP @cindex Structure padding @cindex Packing the structs @cindex Reading structs from disk files @cindex Reading an int from a binary file @cindex struct reading from a disk file @pindex sizeof, result when called on a structure @quest{When I call @samp{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?} @quest{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?} @ans{} 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: @example struct my_struct @{ char name[7]; unsigned long offset; double quality; @}; @end example To make such a struct use the least number of bytes, rearrange the fields, like this:@footnote{Note that this still allows the struct to be padded at the end, though.} @example struct my_struct @{ double quality; unsigned long offset; char name[7]; @}; @end example If the layout of the structure cannot be changed (e.g., when it must match some external specification, like a block of data returned by some system call), you can use the @code{__attribute__((packed))} extension of GCC (@extref{Type Attributes, the Gcc docs, gcc, GNU C/C++ Manual, 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. @paragraph{} Beginning from version 2.7.0, GCC has a command-line option @samp{-fpack-struct} which causes GCC to pack all members of all structs together without any holes, just as if you used @code{__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 @strong{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). @paragraph{} 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 @code{sizeof struct foo} to read and write a structure. @paragraph{} 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 @code{int} is 16-bit wide in most DOS-based compilers, but in DJGPP it's 32-bit wide. @paragraph{} The best, most robust and portable way to read and write structs is through a @code{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. @node Struct packing, Int 24h, Struct size, Miscellany @comment node-name, next, previous, up @section C++ doesn't pack structs! @cindex Structure packing, C++ bug @cindex Packed structs, C++ bug @cindex C++ programs, problems with packed structs @pindex GCC doesn't pack structs in C++ programs @quest{When I use @code{struct ffblk} from the header @file{dir.h} in a C++ program, I get garbage in some fields of the structure!} @ans{} There is a known bug in GCC 2.7.2: the C++ compiler effectively ignores the @code{__attribute__((packed))} directives, so the structures end up being not packed. As a work-around, surround the declaration of the structure that needs to be packed with @code{#pragma pack}, like this: @example #ifdef __cplusplus #pragma pack(1) #endif . . . #ifdef __cplusplus #pragma pack() #endif @end example @node Int 24h, go32-v2, Struct packing, Miscellany @comment node-name, next, previous, up @section How to avoid ``Abort, Retry, Fail'' messages @cindex Interrupt 24h handling @cindex Int 24h crashes DJGPP programs @cindex harderr function, emulating under DJGPP @cindex Critical error handling in DJGPP @cindex Program crashes because of Int 24h @cindex Program crashes accessing empty floppy/CD-ROM drives @pindex QDPMI crashes DJGPP programs when they cause Int 24h @pindex CWSDPMI doesn't support hooking Int 24h @quest{How do I write a program that accesses floppy and CD-ROM drives, but avoids popping that ``Abort, Retry, Fail?'' message from DOS?} @quest{Other DOS compilers supply a function named @code{harderr} or @code{_harderr} to hook the critical-error interrupt 24h, but DJGPP doesn't seem to have these...} @ans{} 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 @kbd{A} in response to that prompt. The default handler under most DPMI servers will just set @code{AL} register to 3 and @code{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. @paragraph{} 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 (@pxref{Hardware interrupts, how to set an interrupt handler}), 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 @code{CWSDPMI} currently doesn't support hooking Int 24h; if you set an interrupt handler, it won't be called. @paragraph{} 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 @code{getmntent} (@extref{getmntent, getmntent, libc.inf, libc.a reference, www.delorie.com/djgpp/doc/libc-2.00/libc_111.html#SEC111}.) 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 @code{getmntent} from the @ftp{library source distribution, @SimTel{}/pub/simtelnet/gnu/djgpp/v2/djlsr@value{djgpp-version}.zip}. @node go32-v2, DXE, Int 24h, Miscellany @comment node-name, next, previous, up @section What is that @file{go32-v2.exe} program? @cindex Invoking v2 programs from v1.x programs @cindex Spawning v2 programs from v1.x programs @pindex go32-v2 usage @quest{What is go32-v2 for?} @ans{} The @code{go32-v2} program does the following: @itemize @bullet{} @item With no command-line arguments, it prints the available physical and virtual memory, much like @code{go32} did in v1.x. @item It can run unstubified v2 COFF images, like this: @example go32-v2 myprog @end example @item If you rename it to @file{go32.exe} and put on your @code{PATH} before the v1.x @file{go32.exe}, it can also run a v1 COFF images, by loading the v1.x @code{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 @code{go32-v2} (since it found it first on the PATH) which knows how to run v2 images, instead the original @code{go32} which cannot. @end itemize @node DXE, LFN, go32-v2, Miscellany @comment node-name, next, previous, up @section What is DXE? @cindex DXE description @cindex DXE docs and examples @quest{What is DXE?} @quest{Can I make a DLL using the DXE support?} @quest{Where can I find information or examples about writing/loading the DXE files?} @ans{} DXE is a limited facility to dynamically load code which is rarely needed in DJGPP. An example is the floating-point emulator code (@pxref{Emulation, the details of DJGPP FP emulator}) 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 simple changes in the C library). @paragraph{} The only place you can find some docs and examples of writing and using a DXE is in the file @file{djtst@value{djgpp-version}.zip} in the @ftp{DJGPP ``tests'' distribution, @SimTel{}/pub/simtelnet/gnu/djgpp/v2/djtst@value{djgpp-version}.zip}. The example there is @emph{exceedingly} simplistic, but then so is the entire DXE mechanism@dots{} @node LFN, Missing separator, DXE, Miscellany @comment node-name, next, previous, up @section Long Filenames Don't Work! @cindex LFN problems @cindex long filename support, bugs @quest{I cannot make Info find some of its files under Win95...} @quest{Why does Make behave as if some of the files were not there?} @ans{} Are you running DJGPP under 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 DJGPP programs wrt the LFN support. Make and Info 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 @file{ALongFileName.cc} (because the Makefile tells it to build @file{ALongFileName.o}), make sure there indeed is such a file in the directory. Many times people use archive tools (like @code{PKZIP}) that truncate long names, even on Win95, when they open an archive, which leaves you with names like @file{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 @samp{DJTAR} when you open @file{.tar.gz} archives, or rename all the files to their original long names after you open the archive. @paragraph{} If the problems persist even though the filenames are correct, you will have to disable LFN support (set LFN=n from the DOS prompt, setting it in @file{DJGPP.ENV} does not always works) until these problems are fixed in some future version of DJGPP. @node Missing separator, Zoneinfo, LFN, Miscellany @comment node-name, next, previous, up @section Make says ``missing separator'' @cindex Missing separator, Make error message @cindex Makefile, first character of every command must be TAB @cindex TAB, must be the first character of every command @cindex TABs replaced with spaces by a text editor @pindex Make error message ``missing separator'' @quest{When I invoke Make, it refuses to do anything and prints this cryptic message:} @example makefile:10: *** missing separator. Stop. @end example @emph{Now what kind of excuse is that?} @ans{} 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. @paragraph{} 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. @paragraph{} Another, more rare, cause of the above error message is if you use static pattern rules (with the @code{%} character) incorrectly. Read the documentation that comes with Make carefully and try to find the error. @node Zoneinfo, FAQ format, Missing separator, Miscellany @comment node-name, next, previous, up @section What is in that @file{zoneinfo} directory? @cindex Zoneinfo directory @cindex TZ variable, how to set @cindex TZ database updates, where to get @quest{When I installed DJGPP v2, it created a directory named @file{zoneinfo} with a lot of small files that take up 3.5MB of my disk space. What are they for? Can I delete them?} @ans{} These files exist so that time-related library functions can correctly calculate the offset between the local time and the @dfn{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. @paragraph{} You might wonder why we need all these zoneinfo files when the UTC offset @emph{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 @code{TZ} environment variable to the file that is pertinent to his/her time zone, which is easy: @example set TZ=c:/djgpp/zoneinfo/israel @end example @emph{or} @example set TZ=c:/djgpp/zoneinfo/us/alaska @end example To find the rule suitable for your location, look into the @file{src} subdirectory of @file{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 @samp{zic}, whose source is also in the @file{src} subdirectory. @paragraph{} 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 @file{zoneinfo} directory which comes with DJGPP is based on this database, but if you want the latest rules, you can @ftp{download them from the net, elsie.nci.nih.gov/pub/} as @file{tzdata*.tar.gz}; @file{tzcode*.tar.gz} in the same directory includes the programs that can be used to generate the offset tables from their source in @file{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. @paragraph{} 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. @paragraph{} @node FAQ format, , Zoneinfo, Miscellany @comment node-name, next, previous, up @section Generating the FAQ in your favorite format @cindex FAQ, conversion to different formats @cindex Conversion of the FAQ to different formats @pindex MAKERTF, produces the FAQ in RTF format @pindex INFNG, produces the FAQ in Norton Guides format @quest{How can I generate the FAQ list in a format I'm used to?} @ans{} First, you need to get the FAQ sources. The sources of the latest version of this FAQ list can always be found as @file{faq@value{faq-version}s.zip} @ftp{on DJ Delorie's server, ftp.delorie.com/pub/djgpp/v2faq/faq@value{faq-version}s.zip} and @ftp{on SimTel mirrors, @SimTel{}/pub/simtelnet/gnu/djgpp/v2/faq@value{faq-version}s.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 @file{faq@value{faq-version}b.zip} @ftp{from DJ Delorie's server, ftp.delorie.com/pub/djgpp/v2faq/faq@value{faq-version}b.zip} or @ftp{from SimTel mirrors, @SimTel{}/pub/simtelnet/gnu/djgpp/v2/faq@value{faq-version}b.zip}. Currently, this includes the Info version, the text (ASCII) version and an HTML version as a single large @file{.html} file. More formats will be available as the tools for their generation are developed/tested. @paragraph{} 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. @paragraph{} 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). @paragraph{} A program called @samp{Makertf} can reportedly be used to convert a Texinfo sources of this FAQ to the @dfn{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. @samp{Makertf} is available @ftp{from CCT mirrors, @CCT{}/Coast/win3/winhelp/mkrtf104.zip}. The Windows Help Compiler is available via anonymous ftp @ftp{from the Microsoft ftp site, ftp.microsoft.com/Softlib/MSFILES/HC305.EXE}. @paragraph{} There also a program called @samp{INFNG} that can be used to convert the Info (@strong{not} Texinfo) version of the FAQ to the Norton Guide format. @samp{INFNG} can be downloaded from @ftp{the DJGPP archive, @SimTel{}/pub/simtelnet/gnu/djgpp/v2misc/infng100.zip}. @paragraph{} @node About, Topic Index, Miscellany, Top @comment node-name, next, previous, up @chapter About this FAQ Maintainer: @mail{Eli Zaretskii, eliz@@is.elta.co.il}. @paragraph{} This FAQ is Copyright @copyright{} 1994, 1995, 1996 by @mail{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. @paragraph{} 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). @paragraph{} 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: @display @mail{John M. Aldrich, fighteer@@cs.com} @mail{Anthony Appleyard, A.APPLEYARD@@fs2.mt.umist.ac.uk} @mail{John Bodfish, bodfish@@austen.notis.com} @mail{Bill Davidson, bdavidson@@ra.isisnet.com} @mail{Francois Charton, deef@@pobox.oleane.com} @mail{Bill Currie, bill_currie@@MAIL.TAIT.CO.NZ} @DJ{} @mail{Juergen Erhard, jae@@laden.ilk.de} @mail{Jeremy Filliben, prime@@UDel.Edu} @mail{James W. Haefner, Jim@@anolis.bnr.usu.edu} @mail{Koen Van Herck, kvhk@@barco.com} @mail{Robert Hoehne, Robert.Hoehne@@Mathematik.TU-Chemnitz.DE} @mail{Gordon Hogenson, ghogenso@@u.washington.edu} @mail{Harry Johnston, omega@@es.co.nz} @mail{Martynas Kunigelis, martynas.kunigelis@@vm.ktu.lt} @mail{Pieter Kunst, kunst@@prl.philips.nl} @mail{Y. Lazarovitch, yitzg@@haven.ios.com} @mail{Alexander Lehmann, lehmann@@mathematik.th-darmstadt.de} @mail{Marty Leisner, leisner@@sdsp.mc.xerox.com} @mail{Dave Love, d.love@@dl.ac.uk} @mail{Rob Nader, naderr@@topaz.cqu.edu.au} @mail{Eric Nicolas, nicolas@@JUPITER.saclay.cea.fr} @mail{Elliott Oti, e.oti@@stud.warande.ruu.nl} @mail{Esa A E Peuha, peuha@@cc.helsinki.fi} @mail{Walter Prins, prins@@quark.cs.sun.ac.za} @mail{Steve Salter, salters@@admin.fanshawec.on.ca} @CWS{} @mail{Terrel Shumway, Shumw001@@Cerritos.edu} @mail{Andrew Szymkowiak, aes@@solia.gsfc.nasa.gov} @mail{Launey Thomas, ljt@@sierrasemi.com} @mail{Chris Tilbury, C.J.Tilbury@@estate.warwick.ac.uk} @Steve{} @mail{Santiago Vila, sanvila@@pizarro.unex.es} @mail{Ronan Waide, waider@@waider.ie} @mail{Morten Welinder, terra@@diku.dk} @mail{Anthony Edward Wesley, awesley@@galaxy.anutech.com.au} @mail{Mark H. Wood, mwood@@mhw.OIT.IUPUI.EDU} @end display @node Topic Index, Program Index, About, Top @comment node-name, next, previous, up @chapter 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). @ifset html

@*

    @* @include concepts.idx @*
@* @end ifset @ifclear html @printindex cp @end ifclear @node Program Index, , Topic Index, Top @comment node-name, next, previous, up @chapter 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. @ifset html

@*

    @* @include programs.idx @*
@* @end ifset @ifclear html @printindex pg @end ifclear @contents @bye @c Local Variables: @c time-stamp-line-limit:15 @c time-stamp-start:"^@set update-date " @c time-stamp-end:"$" @c time-stamp-format:"%d %b %y" @c eval:(require 'time-stamp) @c eval:(add-hook 'write-file-hooks 'time-stamp) @c End:

This document was generated on November 6, 2024 using texi2html 5.0.