/****************************************************************************
 *FILE: test9p.c
 *
 *DESCRIPTION:
 *	Demonstration of how a DOS application can load and execute a program
 *	into the ARM,  then communicate with it using the synchronous block
 *	transfer routines
 *
 *COMPILER:  Mark Williams MWC86 Version 3.0.6
 *
 */
 
 
#include <dos.h>
#include <stdio.h>
#include <ctype.h>
#include "armintc.h"


/* Define TRUE and FALSE here.  Didn't want to include hfiles\stds.h */
typedef	int		BOOL;
#define TRUE	(BOOL)1
#define FALSE	(BOOL)0



/*****************************************************************************
 */
int		main( argc, argv )
int		argc;
char	*argv[];
	{

#	define SEND_BUFF_LEN 	256L
	char	  				send_buff[ SEND_BUFF_LEN ];
#	define RECEIVE_BUFF_LEN	1024L
	static char 			receive_buff[RECEIVE_BUFF_LEN];
	unsigned long int		num_to_send;
	unsigned long int		num_recieved;
	struct reg				sreg,	rreg;
	int		  				arg;
#	define ARMPROG 			"test9a"


	printf("test9p.c: Main of test9p.exe entered.\n");

	
	/* Read command line into a string.
	 */
	strcpy( send_buff, "" );
	for( arg = 1; arg < argc; arg++ )
		{
		strcat( send_buff, argv[arg] );
		strcat( send_buff, " " );
		}
	send_buff[ strlen( send_buff ) - 1 ] = '\0';	/* Remove trailing ' ' */

	num_to_send = strlen( send_buff ) + 1;



	/* Check for the ram resident interface software being loaded. 
	 */
	if (!chkrrsig())
		{
		printf( "test9p:  ARM interface sortware is not loaded.  Use arminit.\n" );
		return(1);
		}


	printf("test9p.c: Reset,  load and execute program '%s' in ARM\n",
				ARMPROG);

	sreg.r_ax = ARMEXEC;
	ptoreg(dsreg, sreg.r_dx, sreg.r_ds, ARMPROG);
	intcall(&sreg, &rreg, ARMINT);

	if (rreg.r_ax != FNOK)
		{
		printf("test9p: ARMEXEC failed:  error number = 0x%x\n", rreg.r_ax);
		printf("The program test9a.ax1 must be in the ARM's library path.\n");
		return( 1 );
		}

    printf("test9p: ARMEXEC succeeded\n" );


	/* Service the OSWORD 1 (read time) that the ARM C startup code generates
	 */
	sreg.r_ax = ARMSERV;
	intcall(&sreg, &rreg, ARMINT);
	if (rreg.r_ax != FNOK)
		{
		printf("test9p: ARMSERV failed:  error number = 0x%x\n", rreg.r_ax);
		return( 1 );
		}



	printf("test9p.c: Send block of data to ARM.  Size = %lx\n"
				, num_to_send);
	printf("test9p.c: Block is the string = '%s'\n", send_buff);

	sreg.r_ax = ARMBKR;
	ptoreg(dsreg, sreg.r_dx, sreg.r_ds, send_buff);
	sreg.r_bx = (unsigned int)(num_to_send);
	sreg.r_cx = (unsigned int)(num_to_send >> 16);
	intcall(&sreg, &rreg, ARMINT);

	if (rreg.r_ax != 0)
	{	
		printf("test9p.c: Send transfer failed,  error code 0x%x\n", rreg.r_ax);
	}

	printf("test9p.c: Send complete.\n");



	printf("test9p.c: Receive string back from ARM\n");

	sreg.r_ax = ARMBKW;
	ptoreg(dsreg, sreg.r_dx, sreg.r_ds, receive_buff);
	sreg.r_bx = (unsigned int)(RECEIVE_BUFF_LEN);
	sreg.r_cx = (unsigned int)(RECEIVE_BUFF_LEN >> 16);
	intcall(&sreg, &rreg, ARMINT);

	if (rreg.r_ax != 0)
	{	
		printf("test9p.c: Receive transfer failed,  error code 0x\%x\n", 
					rreg.r_ax);
 	}

	num_recieved = ((unsigned long)rreg.r_cx << 16) + rreg.r_bx;


	printf("test9p.c: Number of bytes recieved %lx\n", num_recieved);
	printf("test9p.c: Receive buffer contents = '%s'\n", receive_buff);
	


	printf("test9p.c: Exiting.\n");

	return(0);
	}


/*************************************************************************
 * Check that ram resident code signature is present.
 */
BOOL chkrrsig()
	{
	struct reg r;
	r.r_ax = GETVEC | ARMSINT;		/* Get old vector */
    intcall(&r, &r, DOSINT);
    if ((r.r_es == ARMSIG2) && (r.r_bx == ARMSIG1))
    	return( TRUE );
    else
    	return( FALSE );
	}

