 Joystick: A unit for reading the joysticks & buttons.
           Written 1996 William H. Decorie.
           Released into the public domain; modify as you wish.

  This unit reads the joystick ports directly and therefore bypasses the
  BIOS, which is normally not a good thing.  However, since so many
  machines don't have BIOS support or only limited support, and due to the
  nature of this particular hardware, it is OK in this case.  See my
  driver TSR which provides "BIOS" support for joystick functions for those
  programs which require BIOS services.  The purpose of this unit is for
  Pascal programs you are writing that will work on any machine.

  Information is returned in the global variable STICK.  STICK is made up
  of two StickRec structures, which are defined below.  They hold the
  X and Y positions of the stick, the minima and maxima, the points for
  simulating digital movement, and the center points.  They also hold the
  status of the A and B buttons for the stick.  (Of course, the current
  position and button status are only valid right after issuing a call to
  Read_Sticks or Read_Buttons.)

  Digital joysticks are like those found on the game machines and Ataris of
  old.  Instead of returning an analog position along the X and Y axes,
  they simply have four switches.  Push up and the up switch closes; push
  down and the down switch closes.  Diagonal movement causes one vertical
  and one horizontal switch to close.  A call to Read_Sticks_Digital
  interprets your analog joystick's position as if it were a digital stick;
  the return value is a word with the first stick in the low byte.  The
  byte is interpreted as follows: b0 is up, b1 is down, b2 is left, b3 is
  right.  If the stick is moved in a particular direction, then that bit
  is set, otherwise it is clear.  (This is exactly the same as the old
  Atari, except the bits are inverted.)

  The buttons are just boolean variables; pressed is true and released is
  false.  There are two buttons for each stick.

  Since joysticks are analog devices, and every stick is different (and
  the same stick behaves differently on different machines!), there has
  to be a way to calibrate the stick for the current machine.  You may
  have seen this in games that tell you to move the stick to the upper
  left, then the lower right etc...  These routines auto-calibrate, but
  they require full range movement to do so.  Just set the variable
  Cal_Flag to true, and every time one of the stick reading functions is
  called the stick values are updated.  See the accompanying test program
  for an example.  Calibrating does add to execution time.  Note that in
  order to use the digital function, the stick must already be calibrated.

  These routines are general purpose and are therefore by definition slow.
  One major speedup would be to break the main routines into four smaller
  routines, one for each stick and direction.  As it is written now, both
  directions of both sticks are read during each call.  On my 486/80, I
  make this out to be about 30 calls per second while doing nothing else.
  Definitely room for improvement.

  It is a good idea to periodically call Center_Sticks.  This routine
  determines the midpoint for both axes of the stick.  Some sticks drift
  during use, so after a while the stick will appear to be constantly off
  center.  Note that this routine does take some time.  You should call
  this routine at least once before actually using the stick data.

  To determine whether or not a given stick is present, just call the
  Stick_n_Present routine, where 'n' is 'a' or 'b'.  This just returns a
  boolean value representing the state of the stick.  Note that sticks can
  be plugged in while the machine is running, so you may want to check
  these periodically.

  As always, I accept no liability for anything this program does.  Use at
  your own risk!  Modify as you want, just don't blame me for anything.

