
/* FAME Door Beginning Source
 *
 * $VER:TestDoor.c v1.0
 *
 * All you need are the includes and headers!
 *
 * Used tab size: 2
 */

/*
 * Includes:
 */

#include <FAME/FAMEPublic.h>

#ifdef LATTICE
int CXBRK(void) {return(0);} /* Disable Lattice CTRL-C handling */
int chkabort(void) {return(0);}
#endif

char *VerStr={"$VER: TestDoor.FIM 1.0 "__AMIGADATE__};

/*
 * _ProgramName contains the our name:
 */

extern char	*_ProgramName;

/*
 * Prototypes:
 */

void ShutDown(long ErrCode);
void UserSigHandle(ULONG UserSigs);
STATIC long OpenTimer(void);
STATIC void SetTimer(ULONG secs, ULONG micros);
STATIC void ClearTimer(void);

void __autoopenfail(void) { _XCEXIT(0);}

/* Variables for ReadArgs and Template.
 */

char 	ArgStr[]		= "NODENR/N/A";
long	ArgArray[]	= {0L};

/*
 * Global variables:
 */

struct FAMEBase			*FAMEBase			= NULL;
unsigned long				TimerSig;
struct timerequest	*TimerMsg			= NULL;
struct MsgPort			*TimerPort		= NULL;
short int						TimerRec			= 0;

/*
 * main() entry point:
 */

void main(int argc, char *argv[])
{
	struct  RDArgs	*rda						= NULL;
	long						NodeNr;
	char						StrBuffer[256];

	/* Use ReadArgs() for arguments.
	 */

	if(rda = ReadArgs(ArgStr,ArgArray,NULL)) {

		/* Node number.
		 */

		if(ArgArray[0]) {

			long *LDummy = (long *)ArgArray[0];
			NodeNr = (*LDummy);
		}

		FreeArgs(rda);
	} else {

    Printf("\nSorry, %s is a Door and must be called from FAME BBS!\n\n",_ProgramName);

		SetIoErr( ERROR_REQUIRED_ARG_MISSING );
		PrintFault(IoErr(),NULL);

    exit( RETURN_FAIL );
  }

	if( ! (FAMEBase = (struct FAMEBase *) OpenLibrary("FAME.library",0L)))
		ShutDown( RETURN_FAIL );

	if(OpenTimer()) {

		Printf("Error opening " TIMERNAME "\n");

		ShutDown( RETURN_ERROR );
	}

	TimerSig=1L<<TimerPort->mp_SigBit;

	GlobUserSigs |= TimerSig;

  SPrintf(FAMEDoorPort,"FAMEDoorPort%ld",NodeNr);

  if(FIMStart(0))
		exit( RETURN_ERROR );

/* Place your own code in here:
 */

	SetTimer(10UL,0UL);

	StrBuffer[0] = '\0';

	PutString("\r\nTimer set to 10 seconds.",0);

	PutString("\r\nTell me something>: ",0);

	GetString(StrBuffer,50);

	PutStringFormat("\r\n\nYou've said: %s\r\n",StrBuffer);

	if(TimerRec)
		PutString("Timer signal received after 10 seconds!\r\n\n",0);
	else
		PutString("Timer signal not received! You were faster!\r\n\n",0);

/* End Door:
 */

	FIMEnd(0);
}

STATIC long OpenTimer(void)
{
	if( ! (TimerPort	= CreateMsgPort()))
		return(-1);
	if( ! (TimerMsg		= (struct timerequest *)CreateIORequest(TimerPort,(long)sizeof(struct timerequest))))
		return(-2);

	TimerMsg -> tr_node . io_Message . mn_ReplyPort = TimerPort;

	return(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerMsg,0L));
}

STATIC void SetTimer(ULONG secs, ULONG micros)
{
	TimerMsg -> tr_node . io_Command							= TR_ADDREQUEST;	/* add a new timer request */
	TimerMsg -> tr_time . tv_secs									= secs;						/* seconds */
	TimerMsg -> tr_time . tv_micro								= micros;					/* microseconds */
	TimerMsg -> tr_node . io_Message.mn_ReplyPort	= TimerPort;

	SendIO((struct IORequest *)TimerMsg);														/* post the request to the timer device */
}

STATIC void ClearTimer(void)
{
	if( ! CheckIO((struct IORequest *)TimerMsg)) {

		AbortIO((struct IORequest *)TimerMsg);
		WaitIO((struct IORequest *)TimerMsg);
		ClrSignal(TimerSig);
	}
}

/*
 * This function has to be supplied by the door and will be called if any
 * error occures. It's up to the door to exit or continue the work, but
 * remember that the DoorPort and therefor the communication to FAME is
 * CLOSED ! The errcode contains the errorcode supplied by FAME, you may
 * use it to your own requirements.
 */

void ShutDown(long ErrCode)
{
	if(TimerMsg) {

		ClearTimer();

		CloseDevice((struct IORequest *)TimerMsg);
		DeleteIORequest((struct IORequest *)TimerMsg);

		TimerMsg	= NULL;
	}

	if(TimerPort)
		DeleteMsgPort(TimerPort);

	TimerPort	= NULL;

	if(FAMEBase)
		CloseLibrary((struct Library *)FAMEBase);

	FAMEBase = NULL;

	if(ErrCode < RETURN_OK ) {

		SetIoErr( ERROR_OBJECT_NOT_FOUND );
		PrintFault(IoErr(),NULL);

		ErrCode = RETURN_ERROR;
	}

	exit( ErrCode );
}

/*
 * This function has to be supplied by the door and will be called if any
 * user signal occures. User signals will be set via FIMHandlePort() in the
 * second argument "ULONG UserSigs". Use NULL here if you don't have any
 * signals to be supported. UserSigHandle() will be called if any user
 * signals are set and if FIMHandlePort() receives them. In this case
 * check the argument "UserSigs" in your UserSigHandle() function.
 *
 * You can also use the global variable "GlobUserSigs" to inform
 * FIMHandlePort() about your own additional signal bits.
 * In this case FIMHandlePort()'s second argument "ULONG UserSigs" has to
 * be always NULL, because this argument has the higher priority and
 * "GlobUserSigs" will not be used then.
 * "GlobUserSigs" is to handle your own signal bits more easy.
 * All support functions will pass NULL to FIMHandlePort() so usage of
 * "GlobUserSigs" is possible without doing any changes to the doorstartup
 * code.
 */

void UserSigHandle(ULONG UserSigs)
{
	if(UserSigs & TimerSig) {

		TimerRec = 1;
	}
}

