/*
ads56800.c

Command-line interface to a 56LC811 board.

Written by Motorola Inc.

Modified by Anna Yuan and Brian L. Evans at The University of
Texas at Austin.

Version at UT: @(#)ads56800.c	1.11	07/01/98
*/

/* The UT modifications must be include first. */
#include "utsim.h"

#include "simcom.h"
#include "simdev.h"
#include "simusr.h"
#include "protocom.h"
#include "proto568.h"
#include "driver.h"

extern struct dev_const dv_const;
extern struct sev_const sv_const;
extern struct sev_var *sv_var;

#define ADSP56800 0x99

/* main simulator entry point */
int main (int argc, char **argv)
{
    int i;
    int mode;
    int device;
    int macropos = 0;
    char *devp = NULL;
    char cmdstr[256];	/* Will hold command strings input from terminal */
    char startup[256];
    struct sev_cmd *cmd;

    dv_const.nodisplay = 1; /* 1 means to inhibit display on the I/O device */
    dv_const.revnum = ut_VersionIdentification;

    /* Set up ads host interface */
    if ((argc >= 3) && !strcmp (argv[1], "-d"))
    {
        devp = argv[2];

        if (argc == 4)
        {
            macropos = 3;
        }
    }
    else
    {
        devp = getenv ("ADMADDR");

        if (argc == 2)
        {
            macropos = 1;
        }
    }

    if (!devp)
    {
#if UNIX        
        devp = "/dev/mdsp0";
#else
#if MSDOS
        devp = "100";
#endif /* MSDOS */        
#endif /* UNIX */        
    }

#if (MSDOS)&(!WIN32)
    /* Attempt to increase file handles to 100 */
    (void) _grow_handles (100);
#endif

    if (!ads_startup (devp, ADSP56800))
    {
#if UNIX
        char buf[256];
        
        sprintf (buf, "ads56800 %s", devp);
        perror (buf);
#endif /* UNIX */        
        fprintf(stderr, "Unable to locate host interface board\n");
	fflush(stderr);
        exit (0);
    }

    /* Initialize simulator windows and global structures */
    dsp_startup ();

    /* Set GUI flags */
    sv_const.gui = 0;
    sv_const.waiting = 0;

    (void) dsp_new (0, "56811");

#if macintosh
    simw_macstartup ();
#endif

    sv_var->stat.executing = FALSE;

    /* Set up the default command converter */
    if (!dsp_cc_reset (0) || !dsp_status (0, &mode))
    {
        /* siml_display_error ("Unable to communicate with default device"); */
	fprintf (stderr, "Unable to communicate with default device\n"); 
	fflush(stderr);
    }
    else
    {
        if (mode) /* Debug mode */
        {
            if (!ads_cache_registers (0))
            {
	        /*siml_display_error ("Error reading registers"); */
		fprintf (stderr, "Error reading registers\n"); 
		fflush(stderr);
            }
        }
        else
        {
            sv_var->stat.executing = TRUE;
        }
    }

    /* Display the ads version on device 0 window */
    simw_wscr (dv_const.revnum, 1);

    /* Begin with execution of macro specified on command line, or
       with startup.cmd */
    if (macropos)
    {
        /* Execution of other macros <name>.cmd */
	sim_docmd (0, argv[macropos]);	
    }
    else if (dsp_spath ("startup", ".cmd", startup))
    {
        /* Handle startup.cmd macro file if it exists */
        sim_docmd (0, startup);
    }

    for (;;)
    {
        if (sv_const.in_macro)
        {
            /* get macro command */
            siml_clrbuff ();
            sim_gmcmd (sv_const.viewdev, cmdstr);
        }

        if (!sv_const.in_macro)
        {
            /* sim_gtcmd (sv_const.viewdev, cmdstr); */
	    int processCommand = TRUE;
	    char* input = ut_get_command(cmdstr, &processCommand);
	    if (processCommand) {
		siml_parse_cmd (input);
		siml_parse (input, TRUE);
	    }
	    else
	    {
		int i;
		for (i = 0; i < 256; i++) {
		    cmdstr[i] = ' ';
		}
		cmdstr[255] = 0;
	    }
        }

        cmd = &sv_const.cmd;

        /* If comment or macro */
        if (!cmd->gcsp)
        {
            sim_docmd (sv_const.viewdev, cmdstr);
        }
        else
        {
            /* If command does not handle devices itself */
            if (sv_const.commands[cmd->gce[1].xval[0]]->dev_flag
                != DSP_DEV_PASS)
            {
                /* Save off current default device number */
                device = sv_const.viewdev;
    
                for (i = 1; i <= cmd->devlist[0]; i++)
                {
                    siml_switch_to_device (cmd->devlist[i]);

                    if (sv_const.commands[cmd->gce[1].xval[0]]->exec_flag
                        == DSP_NO
                        && sv_var->stat.executing)
                    {
		         /*siml_display_error ("Device is not in debug mode");*/
			 fprintf (stderr, "Device is not in debug mode\n"); 
			 fflush(stderr);
                    }
                    else
                    {
                        sim_docmd (sv_const.viewdev, cmd->gcsp);
                    }
                }

                /* Restore original device structures */
                siml_switch_to_device (device);

                if (!sv_var->stat.executing ||
                    (sv_var->display_mode == REG_DISPLAY))
                {
                    simw_redo (device);
                }
            }

            else
            {
                if (sv_const.commands[cmd->gce[1].xval[0]]->exec_flag == DSP_NO
                    && sv_var->stat.executing)
                {
		    /* siml_display_error ("Device is not in debug mode"); */
		    fprintf (stderr, "Device is not in debug mode\n");
		    fflush(stderr);
                }
                else
                {
                    sim_docmd (sv_const.viewdev, cmd->gcsp);
                }
            }
        }
    }
    return(0);
}
