/************************************************************************/
/* File name:	EVERCALL.S				Revision date:	1996.07.02		*/
/* Created by:	Ulf Ronald Andersson	Creation date:	1996.07.02		*/
/************************************************************************/

#include	<stdlib.h>
#include	<stdio.h>
#include	<string.h>
#include	<tos.h>
#include	<aes.h>
#include	<vdi.h>

typedef	unsigned long	ulong;
typedef unsigned int	uint;
typedef unsigned char	uchar;

#define	_cookies	((long **) 0x5A0L)

extern	int	_app;

#define	AES_single	0
#define	AES_MagiC	1
#define	AES_Geneva	2
#define	AES_MTOS	3
#define	AES_nAES	4
#define	AES_XaAES	5

#define	old_CH_EXIT	80	/* old code, used by Geneva. new code is 90 */

int		AES_type;

int		appl_id;
int		phys_handle;
int		work_handle;
int		gl_wchar,
		gl_hchar,
		gl_wbox,
		gl_hbox;

int		mesagbuf[8];
char	sprint_buf[256];
char	alert_buf[256];

char	AES_info_head[]= "[1][The found AES is of type ";
char	id_info_head[]= "[1][Process id of Everest was ";
char	msg_info_head[]= "[1][Mesag 0, 3 = ";
char	alert_tail[]= "][So what?]";

int		everest_id;
int		everest_value;
char	everest_path[]	= "C:\\SYSAID\\EVEREST.PRG";
char	start_alert[]	= "[1][I'm ready to call Everest.][Go Ahead]";
char	end_alert[]		= "[1][Everest's done, I'm quitting.][Go Ahead]";

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

int		identify_AES(void)
{	void	*old_SSP;
	long	search_id;
	long	*search_p;
	int		MiNT_flag = 0;
	int		retv = AES_single;

/* cookie search is made in Super mode to access any RAM */

	old_SSP = (void *) Super(0L);
	if ((search_p = *_cookies) == NULL)	goto exit_super;

search_loop:
	search_id = *search_p;
	if( search_id == 0L )	goto exit_super; /* search completed */
	if( search_id == 'MgMc'  ||  search_id == 'MagX' ) retv = AES_MagiC;
	if( search_id == 'nAES' ) retv = AES_nAES;
	if( search_id == 'Gnva' ) retv = AES_Geneva;
	if( search_id == 'MiNT' ) MiNT_flag = 1;
	search_p += 2;
	goto	search_loop
;
exit_super:
	Super(old_SSP);

	if
	(	retv == AES_single  &&  MiNT_flag
		&& ( _GemParBlk.global[1] > 1  ||  _GemParBlk.global[1] <0 )
	)
		if	(wind_get(0,'XA') == 'XA')
			retv = AES_XaAES;
		else
			retv = AES_MTOS;

	return( retv );
}	/* Ends:	int identify_AES(void) */

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

void	terminate(int termv)
{
	v_clsvwk(work_handle);
	appl_exit();
	exit(termv);
}	/* Ends:	void terminate(int termv) */

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

void	call_everest(void)
{
	int		waiting;

	waiting = 1;
	switch( AES_type )
	{
	case	AES_MagiC:
		everest_id = shel_write(1,1,100,everest_path,"");
		break;	/* Ends:	case AES_MagiC */

	case	AES_nAES:
	case	AES_XaAES:
		everest_id = shel_write(0,1,1,everest_path,"");
		break;	/* Ends:	case AES_nAES */

	case	AES_Geneva:
		everest_id = shel_write(1,1,1,everest_path,"");
		break;	/* Ends:	case AES_Geneva */

	case	AES_MTOS:
		everest_id = shel_write(0,1,1,everest_path,"");
		break;	/* Ends:	case AES_MTOS */

	case	AES_single:
/* I know of no legal way for a GEM program to start another without exiting */
/* I have just put a normal Pexec here for now, so replace it with your code */
		Pexec(0,everest_path,NULL,NULL);
		break;	/* Ends:	case AES_single */
	
	default:		/* some default method (MTOS?) for future multitaskers */
		break;	/* Ends:	default */

	}	/* Ends:	switch( AES_type ) */

		sprintf(sprint_buf,"%d",everest_id);
		strcpy(alert_buf,id_info_head);
		strcat(alert_buf,sprint_buf);
		strcat(alert_buf,alert_tail);
		form_alert(1,alert_buf);

	if( AES_type != AES_single && AES_type )
		do
		{	evnt_mesag(mesagbuf);
			sprintf(sprint_buf,"%d, %d",mesagbuf[0],mesagbuf[3]);
			strcpy(alert_buf,msg_info_head);
			strcat(alert_buf,sprint_buf);
			strcat(alert_buf,alert_tail);
			form_alert(1,alert_buf);

			switch( mesagbuf[0] )
			{
			case old_CH_EXIT:
				if	(	AES_type != AES_Geneva 
					&&	AES_type != AES_XaAES
					)
					break;
			case CH_EXIT:
				if( mesagbuf[3]==everest_id )
				{	everest_value = mesagbuf[4];
					waiting = 0;
				}
				break;

			case AP_TERM:
				terminate(0);

			}	/* Ends:	switch( mesagbuf[0] ) */

		}	while(waiting);

}	/* Ends:	void call_everest(void) */

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

void main(int argc,char **argv)
{
	int		work_in[11] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 };
	int		work_out[57];

	appl_id = appl_init();
	work_in[10] = 2;
	phys_handle = graf_handle( &gl_wchar, &gl_hchar, &gl_wbox,&gl_hbox );
	work_handle = phys_handle;
	v_opnvwk( work_in, &work_handle, work_out );

	AES_type = identify_AES();
	if( AES_type != AES_single ) shel_write(9,1,1,"","");

	sprintf(sprint_buf,"%d",AES_type);
	strcpy(alert_buf,AES_info_head);
	strcat(alert_buf,sprint_buf);
	strcat(alert_buf,alert_tail);
	form_alert(1,alert_buf);

	form_alert(1,start_alert);

	call_everest();

	form_alert(1,end_alert);

	terminate(0);
}	/* Ends:	void main(int argc,char **argv) */

/************************************************************************/
/* End of file:	EVERCALL.C												*/
/************************************************************************/
