(c)  Copyright 1989 Commodore-Amiga, Inc.   All rights reserved.
The information contained herein is subject to change without notice, and 
is provided "as is" without warranty of any kind, either expressed or implied.  
The entire risk as to the use of this information is assumed by the user.



                        Joystick Port Output

                      Carolyn Scheppner - CATS



Each Amiga joystick port has three pins that can be easily configured as 
output lines and controlled through software.  This capability makes it 
possible to operate an external device under program control.  

By setting the appropriate system data bit to a 1, you can set the 
corresponding line in the joystick port high (approximately 4-5 volts).  
Setting the data bit to 0 will set the corresponding joystick line low 
(approximately 0 volts).

Both the left and right joystick ports can be used for output lines, but 
the left port is reserved for the Amiga mouse.  This article will focus on 
the use of the right port for output.


The pins on the Amiga's joystick port are numbered as follows.
   
                         1   2   3   4   5
                           6   7   8   9

                        Amiga Joystick Port


Pins 9, 5 and 6 can be configured as output lines.  Pin 8 is ground.

Pin     Name      Output Enable Bit     Data/Control Bit

Pin 9   POT Y       POTGO bit 15          POTGO bit 14
Pin 5   POT X       POTGO bit 13          POTGO bit 12
Pin 6   Fire      ciaa.ciaddra bit 7    ciaa.ciapra bit 7
Pin 8   Ground   


The POT X and POT Y pins are normally potentiometer inputs.  When set to 
output, these lines become digital outputs.  However, due to the large 
capacitors on them, it may take up to 300 microseconds for a line to 
change state.  

The POTGO bits which control the POT X and POT Y lines are allocated and 
set using potgo.resource functions.  This is illustrated in the program below.
First, the AllocPotBits() function is used to allocate the enable and data 
bits for the two POT pins of the right joystick port.  Next, WritePotgo() is
used to set the pins to output either high or low.  Finally, FreePotBits() is
used to free the bits before exiting.  

Using the SetPot program shown below to toggle the POT X and POT Y lines on 
a test machine, we measured 0 volts, low and approximately 3.8 volts, high on 
POT X and POT Y (pins 5 and 9) relative to ground (pin 8).
 
The Fire pin is attached to CIA A, Port A.  Unlike the POT bits, the CIA
bits for the Fire pin are manipulated directly since there is currently no 
system support for allocating or setting these particular CIA bits.  Take 
extra care to preserve the other bits in ciaa.ciaddra and ciaa.ciapra and not 
to overwrite the 8-bit registers when setting or clearing the Fire line.  

The program SetFire.c demonstrates how to set the Fire pin on the right port to 
an output line and how to toggle the line.  Running the SetFire program on a
test machine, we measured approximately 34 millivolts low and 4.7 volts high 
on the Fire pin (pin 6), relative to ground (pin 8).  

The ability to set up and control joystick lines as outputs makes a wide
variety of special applications possible.  Potential uses include data 
acquisition and control, machine control, robotics and other areas where a
micro offers an inexpensive solution to real-time problems.

--------------------------------------------------------------------------
/*
 * SetPot.c   C. Scheppner  CBM  01/89
 * Sets right joyport PotX and PotY pins (pins 5 and 9) to 0 and 1
 */

#include <exec/types.h>
#include <libraries/dos.h>
#include <resources/potgo.h>


#define V1_POINT_2   33

/* potgo bits */
#define START_B      0   
#define START_F      (1L << START_B)
#define OUTRY_B      15
#define OUTRY_F      (1L << OUTRY_B)
#define DATRY_B      14
#define DATRY_F      (1L << DATRY_B)
#define OUTRX_B      13
#define OUTRX_F      (1L << OUTRX_B)
#define DATRX_B      12
#define DATRX_F      (1L << DATRX_B)

/* We want the right port PotX and PotY direction and data bits */
#define OURBITS    (OUTRY_F|DATRY_F|OUTRX_F|DATRX_F)

/* Mask and bit combinations for setting and clearing the X and Y pots 
 * For mask,  affect both the direction and data bits  
 * For data,  CLR = (direction out,data 0)    SET = (direction out,data 1)
 */
#define POTRX_MSK  (OUTRX_F|DATRX_F)
#define POTRX_CLR  (OUTRX_F)
#define POTRX_SET  (OUTRX_F|DATRX_F)

#define POTRY_MSK  (OUTRY_F|DATRY_F)
#define POTRY_CLR  (OUTRY_F)
#define POTRY_SET  (OUTRY_F|DATRY_F)

struct PotgoBase *PotgoBase = NULL;

UWORD  ourpotbits = NULL; 

main(argc,argv)
int argc;
char **argv;
   {
   ULONG delay = 500;

   if(argc > 1)
      {
      if(argv[1][0]=='?')
         cleanexit("USAGE: SetPot  (demos setting of right joyport potx/y)\n");
      }

   if(!(PotgoBase=
     (struct PotgoBase *)OpenResource(POTGONAME,V1_POINT_2)))
       cleanexit("Can't open potgo\n",RETURN_FAIL);

   ourpotbits = AllocPotBits(OURBITS);
   if(ourpotbits != OURBITS)   cleanexit("Can't alloc potbits\n,RETURN_FAIL");

   /* We got our bits... Loop until done */
   printf("SetPot sets the right port POTX and POTY pins (5,9) to 0 and 1\n");
   printf("Use CTRL/C to exit...\n");
   while(!(SetSignal(0,0) & SIGBREAKF_CTRL_C))
      {
      /* We are setting both pots, so we use both X and Y, masks and data */
      printf("\nSetting right Potx and Poty to 0...  ");
      WritePotgo(POTRX_CLR|POTRY_CLR, POTRX_MSK|POTRY_MSK);
      Delay(delay);

      printf("Setting right Potx and Poty to 1...  ");
      WritePotgo(POTRX_SET|POTRY_SET, POTRX_MSK|POTRY_MSK);
      Delay(delay);
      }

   printf("\n");
   cleanup();
   exit(0);
   }

cleanexit(s,n)
char *s;
int n;
   {
   if(*s)  printf(s);
   cleanup();
   exit(n);
   }

cleanup()
   {
   if(ourpotbits)   FreePotBits(ourpotbits);
   }

/* end */

--------------------------------------------------------------------------
/*
 * SetFire.c   C. Scheppner  CBM  01/89
 * Sets right mouseport FIRE pin (pin 6) to 0 or 1
 */

#include <exec/types.h>
#include <hardware/cia.h>
#include <libraries/dos.h>

#define DELAY 500

extern struct CIA ciaa;

main(argc,argv)
int argc;
char **argv;
   {
   ULONG delay = 500;

   if(argc > 1)
      {
      if(argv[1][0]=='?')
         cleanexit("USAGE: SetFire (demos setting joy pin 6 to 1 or 0)\n",0);
      }

   printf("SetFire sets right mouseport pin 6 to ~0v and ~5v\n");
   printf("To exit, use CTRL/C\n");

   /* set right fire pin to output */
   ciaa.ciaddra = ciaa.ciaddra | CIAF_GAMEPORT1;

   /* loop until CTRL/C */
   while(!(SetSignal(0,0) & SIGBREAKF_CTRL_C))
      {
      /* turn off fire pin */
      ciaa.ciapra = ciaa.ciapra & (~CIAF_GAMEPORT1);
      printf("\nSet to 0...");
      Delay(delay);


      /* turn on fire pin */
      ciaa.ciapra = ciaa.ciapra | CIAF_GAMEPORT1;
      printf("  Set to 1...");
      Delay(delay);
      }

   printf("\n");
   /* set right fire pin back to input */
   ciaa.ciaddra = ciaa.ciaddra & (~CIAF_GAMEPORT1);
   exit(0);
   }

cleanexit(s,n)
char *s;
int n;
   {
   if(*s)  printf(s);
   exit(n);
   }

/* end */

