               ____      _   _   _               _   _      _
              / ___| ___| |_| |_(_)_ __   __ _  | | | | ___| |_ __
             | |  _ / _ \ __| __| | '_ \ / _` | | |_| |/ _ \ | '_ \
             | |_| |  __/ |_| |_| | | | | (_| | |  _  |  __/ | |_) |
              \____|\___|\__|\__|_|_| |_|\__, | |_| |_|\___|_| .__/
                                         |___/               |_|



======================================
============ Introduction ============
======================================

   When things go wrong, it often seems like a good idea to ask other people 
   for help. Fortunately for people in this situation, it is hoped that I
   can either solve your problem or refer you to someone who can. There are,
   however, some things you can do to make this process more efficient.
   This document describes some steps to take whenever you have a problem 
   with a dzcomm program, suggesting ways that you can try to solve it 
   yourself, and also 
   giving some tips about when/how to ask for help. Following these 
   guidelines will make life easier both for the helper (because all the 
   relevant information will be presented to them in a concise and useful 
   way), and for the helpee (because they are more likely to get a prompt 
   and accurate reply).



======================================================
============ Part 1 - who is the culprit? ============
======================================================

   Is the problem a bug in dzcomm, or in your code? To find out, try 
   running the dzcomm examples programs. If you can't reproduce the problem 
   with any of these, it is more likely to be your fault, in which case 
   you should skip to part 3 below. 

   If the problem is related to DOS graphics modes, you should start by
   verifying that allegro works on its own without any dzcomm calls.


==========================================================
============ Part 2 - when dzcomm is at fault ============
==========================================================

   If you still think the problem lies with Allegro, send a system report 
   containing a description of the problem, what platform and library 
   version you are using, your hardware specs, and a list of exactly which 
   programs you were able to reproduce the problem with (it is important to 
   know not only what programs had trouble, but also which ones worked 
   correctly, if any).


============================================================
============ Part 3 - when your program crashes ============
============================================================

   When a djgpp program crashes, you will usually get a stack traceback 
   looking something like:

      Exiting due to signal SIGSEGV
      General Protection Fault at eip=00001eca
      [snip]

      Call frame traceback EIPs:
        0x00001eca
        0x00001590
        0x00001aea

   This information tells you exactly where the crash occurred. To make 
   sense of it, you should compile your program with debugging information 
   (using the -g switch), and then run "symify program.exe" while this 
   traceback is displayed onscreen. That will change the traceback to 
   something along the lines of:

      Call frame traceback EIPs:
        0x00001eca   _strcpy+14
        0x00001590   _main+56, line 7 of t.c
        0x00001aea   ___crt1_startup+138

   In this case, you can see that the crash occurred in the strcpy() 
   function, which was called at line 7 of the main() function in the t.c 
   source file. Now you just have to go to that line, have a look at 
   whatever you are doing there, and change it to be correct :-)

   Note: if the crash happens deep inside a dzcomm function, this 
   traceback may not be so useful. When this happens you can recompile 
   dzcomm with debugging information (see the readme file), and then 
   link your program with the debugging library version.

   Note 2: even when this crash traceback points to one of the dzcomm 
   functions, that does not necessarily mean the dzcomm routine is at 
   fault. Anything will crash if you pass it invalid parameters, so unless 
   you can duplicate the problem in one of the dzcomm example programs, you 
   should start out by assuming that it is a case of operator error and 
   double-check exactly what you are passing to the dzcomm function.



======================================================================
============ Part 4 - things people don't do (but should) ============
======================================================================

   One of the most common errors made by programmers is to neglect to check 
   the return value from a function that may fail. Such an error will often 
   lead to unexpected and downright unusual errors, making for a debugging 
   nightmare. There are many functions in and out of dzcomm that may or may 
   not work depending on varying circumstances. Many of them are, however, 
   nice enough to let you know whether or not they were successful through 
   documented return values.

   Whenever you call a function that might fail (and anything that loads 
   data from the disk), it is _essential_ that you check the return code 
   from this, and respond accordingly.

   Another commonly forgotten but important tool is to use whatever option 
   enables strict warnings for your compiler (gcc uses -Wall), when 
   compiling your code. Any warnings reported by this option will almost 
   certainly represent errors in your program, and should be fixed before 
   doing anything else. When using gcc, a useful trick is to compile with 
   the -O setting as well, because this causes gcc to examine the program's 
   actions in more detail, enabling more useful warnings. You should 
   normally disable optimisation while debugging, though. Although it gives 
   better compile time warnings, it is likely to upset any debugging tools 
   that you later try to use.



==================================================
============ Part 5 - asking for help ============
==================================================

   Ok, so you've tried everything described above, and your program still 
   doesn't work. You have no idea what to do next, so it is time to cast 
   yourself unto the mercies of the net, in hopes of finding some kind of 
   wise man, seer, or oracle that holds an answer for your question...

   The best place to ask is neil@robots.ox.ac.uk. Currently dzcomm is not
   really big enough to merit a mailing list of its own! Please remember
   that this is my personal email address.
   
   Problems relating to the C language or djgpp compiler belong in other 
   forums (comp.lang.c and comp.os.msdos.djgpp respectively).

   Problems relating to Allegro belong in the allegro users and developpers
   mailing lists (allegro and conductors@canvaslink.com respectively).

   Both the Allegro and djgpp mailing lists are archived, and can be 
   searched via their respective homepages. It is very likely that you will 
   be able to find a solution to your problem by looking through the answers 
   to past questions, which will save you needing to post a query at all.

   In accordance with proper netiquette, it is assumed that when you post to 
   any forum on the Internet you have at least consulted the relevant 
   documentation first, if not read it in its entirety. If the problem you 
   are having is worth asking hundreds of people the answer for, then it is 
   certainly worth taking a few minutes to try to solve the problem 
   yourself.
   


=========================================================
============ Part 6 - learn from my mistakes ============
=========================================================

   What not to do, Part One:

      "My program crashes. Please tell me why."

   Yes, people really do sometimes send me questions like this :-) Despite 
   years of practice I am still totally unable to read minds, so this is a 
   very pointless thing to ask. In order to get help with a problem you must 
   describe it in enough detail that other people will be able to understand 
   and reproduce it: this usually means posting some of your source code.


   What not to do, Part Two:

      "I've got a problem with my program. I'm attaching a 500k zip file 
      containing ten thousand lines of source code and all the graphics and 
      sound data: can you please debug it and tell me what the trouble is?"

   After wasting the time and phone bills to download such a huge file, it 
   is unlikely that anyone will even _want_ to help you, let alone invest 
   the amount of time it would take to read and understand such a huge mess 
   of information. You must try to isolate a smaller chunk of code that 
   demonstrates the trouble: the smaller you can make it, the more chance 
   that someone will be able to help you with it. Remember that you are 
   asking other people to do you a favour, so it is your responsibility to 
   make this process as easy for them as you possibly can.



====================================================
============ Part 7 - wording your plea ============
====================================================

   The most important thing is to include code that can be compiled and 
   tested by the person reading your message. Don't just post your entire 
   program: try to extract a small section that includes the specific lines 
   causing your problem, or reproduces the trouble in a simpler way (you 
   will often find that you can locate the error yourself in the process of 
   making this simpler version, so it is a good exercise in itself). This 
   code should be a small but complete program that can actually be compiled 
   and run, because it is very hard to debug incomplete code fragments.

   It is best to include the code directly in the text of your email 
   message, because it is easier for people to read this than if they have 
   to extract it from an attachment.

   Ideally your example should avoid using any external graphics and data 
   files. It is ok to include a small (max 2k) zip containing such 
   information, or failing that a description of what other files it needs 
   (eg. "put an input port description file called 'progprot.ini' into the 
   same directory as the program). If there is no way that you can simplify 
   things this far, you should upload the program and data to a website and 
   then just post that URL in your message.

   You should say what gcc command line you used to build the program, and 
   this should include the -Wall switch.

   Describe what you intended this program to do (it may not be instantly 
   obvious to other people), and also what it really does when you run it. 
   There is usually no need to post the actual crash traceback (other people 
   can duplicate this for themselves as long as they are able to compile and 
   run your code), but you should say whether you do get such a traceback, 
   or a lockup, or just incorrect results (and if so, in exactly what way 
   they differ from what you were expecting). It is useful to mark your 
   source with a comment to show what line the crash traceback points to.

   Any other information that you can include may also be useful. Most 
   importantly a brief machine description, information about any relevant 
   drivers, and your Allegro version (please don't just say "WIP", but give 
   the exact date if you are using anything other than an official numbered 
   release), 



========================================================
============ Part 8 - a model of perfection ============
========================================================

   For reference, here is an example of what I would consider to be an ideal 
   problem report:


   I'm having some trouble reading data on an input port with my code 
   although the example programs seem to work. I'm using dzcomm 0.9.4,
   Allegro 3.9.26 with djgpp 2.02 (gcc version 2.8.1) on a p166. The
   ports I am using are on a moxa c104 card and are all configured to 
   use interrupt 3 and addresses 0x300, 0x308, 0x310 etc

   This program is supposed to send a stream of data to the output port 
   and then read the input port. However, even with the output port wired 
   straight to the input port I get a crash just as I expect to start 
   reading the data.
   
   I compile it using "gcc -Wall t.c -o t.exe -lalleg -ldzcom", and don't 
   get any warnings.


   --- cut here, t.c ---

   Code of simplified programme which has problem goes here, it includes a 
   comment:

   /* It crashes during this line : */

   Immediately before the line which cases the crash.
   


