[comp.sys.amiga] gameport woes

ds@milob.UUCP (David Sanborn) (05/28/87)

hi, this is my first posting so please forgive if i violate any customs.

reading the hardware manual i am led to believe that i can write to POTGO
and by doing this redefine the function of the pot pins, thereby having
two I/O pins for my use(just the right port). i have tried this directly,
allocating resources, Disable/Enable, and Forbid/Permit with no results,
the signals on the pins just stay where they were before(other than a spike
at times). the only way i have been able to get the signals to work is by 
a tight loop, which doesn't seem to be what the manual infers. 
	what am i missing??

gclark@utcsri.UUCP (06/01/87)

(Forgive this posting - I couldn't find a mail path)
>hi, this is my first posting so please forgive if i violate any customs.
I can't think of any, except that it would be helpful for you to include
your email address at the end of the posting (consult local gurus to find
this).
>reading the hardware manual i am led to believe that i can write to POTGO
>and by doing this redefine the function of the pot pins, thereby having
>two I/O pins for my use(just the right port). i have tried this directly,
>allocating resources, Disable/Enable, and Forbid/Permit with no results,
>the signals on the pins just stay where they were before(other than a spike
>at times). the only way i have been able to get the signals to work is by 
>a tight loop, which doesn't seem to be what the manual infers. 
>	what am i missing??
I had this problem too.  You must use the WritePotgo routine (described in
the RKM) to set and reset the PotGo bits.  I think that if you write to them
directly then they will be reset to their previous values whenever any other
task calls WritePotGo (e.g. Intuition talking to the mouse).  If this doesn't
solve your problem, then I'll send you some sample code.

Graeme Clark -- Dept. of Computer Science, Univ. of Toronto, Canada M5S 1A4
old: {allegra,cornell,decvax,ihnp4,linus,utzoo}!utcsri!gclark
new: gclark@utcsri.toronto.edu

carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner CATS) (06/02/87)

In article <430@milob.UUCP> ds@milob.UUCP (David Sanborn) writes:
>[]
>reading the hardware manual i am led to believe that i can write to POTGO
>and by doing this redefine the function of the pot pins, thereby having
>two I/O pins for my use(just the right port). i have tried this directly,
>allocating resources, Disable/Enable, and Forbid/Permit with no results,
>the signals on the pins just stay where they were before(other than a spike
>at times). the only way i have been able to get the signals to work is by 
>a tight loop, which doesn't seem to be what the manual infers. 

   You don't mention WHICH pins on WHICH port.  Are you using AllocPotBits ?
Depending on what pins you are using, Intuition may be reseting the pins.
Or, if they are potentiometer pins, you need to be synchronized with the
beam.

Here's an example that may help.
-----------------------------------------------------------------------------

here is a little hack to read the port0/1 prop joysticks AND
be (sort of) system compatible.

/*****************************************************************************/
/******************************************************************************
*
*	Source Control
*	--------------
*	$Header: propjoy.c,v 34.1 85/11/24 17:59:44 bart Exp $
*
*	$Locker:  $
*
*	$Log:	propjoy.c,v $
*   Revision 34.1  85/11/24  17:59:44  bart
*   be system compatible
*   
*   Revision 34.0  86/11/21  16:35:51  bart
*   added to rcs for updating
*   
*
******************************************************************************/

/* main.c - test program for add/rem tof task - bart - 05.19.86 */
/* propjoy.c modified program for proportional controller - bart - 11.21.86 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/execbase.h>
#include <exec/execname.h>

#include <graphics/gfxbase.h>
#include <graphics/graphint.h>

#include <hardware/cia.h>
#include <hardware/custom.h>
#include <hardware/intbits.h>

#include <resources/potgo.h>

/* #define DEBUGDEBUG */

#define DEBUG
#ifdef DEBUG
#define printf kprintf
#endif

#define V1_POINT_2	33

#define NUM_SERVERS	2

#define MAX_COUNT	(UWORD)~1		/* do it for a while */

/* use system defined hard addresses */

extern struct Custom custom;

/* use system defined addresses for potgo and pot1dat */

#define POTGO		&custom.potgo
#define POT0DAT		&custom.pot0dat
#define POT1DAT		&custom.pot1dat

/* vertical blank interrupt server priority   */

#define HIGHINTPRI 127L 	/* needs to be replaced with priority relative */
#define LOWINTPRI -127L 	/* needs to be replaced with priority relative */

/* bit number defines for potgo ... */

#define START_B		0	

#define DATRX_B		8	
#define DATRY_B		10

#define DATLX_B		12	
#define DATLY_B		14

/* masks ... */

#define START_F		(1L << START_B)
#define DATRX_F		(1L << DATRX_B)
#define DATRY_F		(1L << DATRY_B)	
#define DATLX_F		(1L << DATLX_B)
#define DATLY_F		(1L << DATLY_B)	

#define RPOTX		(START_F | DATRX_F) 
#define RPOTY		(START_F | DATRY_F) 
#define RPOTXY		(START_F | DATRX_F | DATRY_F) 

#define LPOTX		(START_F | DATLX_F) 
#define LPOTY		(START_F | DATLY_F) 
#define LPOTXY		(START_F | DATLX_F | DATLY_F) 

struct ExecBase *ExecBase = NULL;
struct GfxBase *GfxBase = NULL;
struct PotgoBase *PotgoBase = NULL;

/* global storage for potdat */

UWORD oldbits = NULL;
UWORD potbits = NULL;
ULONG potdat = NULL;

/* create server-task to read the proportional joysticks,*/ 
/* update potdat, and then poke potgo to start next data read */

/* reserve space for the interrupt servers */
struct Isrvstr server[NUM_SERVERS] = {NULL};

first_server(i)
int i;
{
	/* read previous proportional joystick values */
	potdat = *(ULONG *)POT0DAT;

	/* poke potgo, restore old bits */
	WritePotgo(oldbits,((~1)<<8)|oldbits);

	/* be nice -- let other servers run, too */
	return(NULL);
}

second_server(i)
int i;
{
	/* poke potgo, start prop joystick read  */
	WritePotgo(potbits,((~1)<<8)|potbits);

	/* be nice -- let other servers run, too */
	return(NULL);
}


main()
{
LONG error = FALSE;
struct Isrvstr *iserver[NUM_SERVERS];
LONG i;


#ifdef DEBUG
	printf("main: entering main...\n");
	printf("main: POT0DAT = %08lx...\n",POT0DAT);
#ifdef DEBUGDEBUG
	Debug();
#endif
#endif

	/* set server priorities */ 
	server[0].is_Node.ln_Pri = HIGHINTPRI;	
	server[1].is_Node.ln_Pri = LOWINTPRI;	

	/* set up server pointers */
	iserver[0] = &server[0];
	iserver[1] = &server[1];

#ifdef DEBUG
	printf("main: open exec.library...\n");
#endif

	if((ExecBase = (struct ExecBase *)OpenLibrary(EXECNAME,V1_POINT_2)) != NULL)
	{

#ifdef DEBUG
		printf("main: open graphics.library...\n");
#endif

		if((GfxBase = (struct GfxBase *)
			OpenLibrary("graphics.library",V1_POINT_2)) != NULL)
		{

#ifdef DEBUG
			printf("main: open potgo.resource...\n");
#endif
			if((PotgoBase = OpenResource(POTGONAME,V1_POINT_2)) != NULL)
			{

				/* remember currently used bits */
				oldbits = ~(AllocPotBits(~1));

				/* restore previous state of bit allocation */
				FreePotBits(~oldbits);

				/* now attempt to allocate start potbit */
				potbits = AllocPotBits(START_F);

#ifdef DEBUG
				printf("main: oldbits = %04lx...\n",oldbits);
				printf("main: potbits = %04lx...\n",potbits);
#ifdef DEBUGDEBUG
	Debug();
#endif
#endif

				Forbid();	

				/* add interrupt servers */
#ifdef DEBUG
				printf("\nmain: call addtof(%lx,%lx,%lx)...\n",
				iserver,first_server,0);
#endif

				AddTOF(iserver[0],first_server,0);

#ifdef DEBUG
				printf("\nmain: call addtof(%lx,%lx,%lx)...\n",
				iserver,second_server,1);
#endif

				AddTOF(iserver[1],second_server,1);

				Permit();

				/* loop until done */

				for(i=0; i < MAX_COUNT; i++)
				{
					/* wait for server to update pot values */
					WaitTOF();

					/* only output information once every second */
					if(!(i %  ExecBase->VBlankFrequency))
					{
#ifdef DEBUG
						printf("\nmain: pot0/1dat == %08lx...\n",potdat);
#endif
					}
				}

				Forbid();	

				for(i=0; i < NUM_SERVERS; i++)
				{
#ifdef DEBUG
					printf("\nmain: call remtof(%lx)...\n",iserver[i]);
#endif
					RemTOF(iserver[i]);
				}

				Permit();

				/* free potbits */

				FreePotBits(potbits);

				CloseLibrary(GfxBase);
			}
			else
			{
#ifdef DEBUG
				printf("\nmain: no potgo.resource...\n");
#endif
				error = TRUE;
			}
		}
		else
		{
#ifdef DEBUG
				printf("\nmain: no graphics.library...\n");
#endif
				error = TRUE;
		}

		CloseLibrary(ExecBase);

	}
	else
	{
#ifdef DEBUG
	printf("\nmain: no exec.library...\n");
#endif
		error = TRUE;
	}

#ifdef DEBUG
	printf("\nmain: exiting main...\n");
#endif

	/* return error code */
	exit(error);
}

/*****************************************************************************/


please feel free to improve on this... note the use of SYSTEM constants
for hardware registers... (phillip, this is better than hard coding for
future revisions) and for VBlankFrequency.

the two interrupt servers must sandwich the existing gameport interrupt.

yours,
bart


-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Carolyn Scheppner -- CBM   >>Amiga Technical Support<<
                     UUCP  ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn 
                     PHONE 215-431-9180
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=