/*
 * debug.c
 *
 * MILO debugger/monitor main program
 *
 * This file is subject to the terms and conditions of the
 * GNU General Public License. See the file COPYING in the
 * main directory of this archive for more details.
 *
 * Copyright (C) 1995 by Andreas Busse
 */
#include <stand/stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>

#include <arc/arc.h>
#include <stand/debug.h>

/*
 * Local Prototypes
 */
int main(int argc, char **argv);
int debug(void);
int nop(void);
int help(void);
void prompt(void);

/*
 * Command table
 */
static struct cmdent {
    char    *cmd_name;
    int     (*cmd_fctn)();
} cmdtbl[] = {
    CMD_DUMP, dump,
    CMD_DUMPTLB, dumptlb,
    CMD_FILL, fill,
    CMD_PROBE, probe,
    CMD_STRINGS, strings,
    CMD_HELP, help,
    CMD_NOP, nop,			/* must be the last command */
};

#define NUMCMDS ((sizeof(cmdtbl)/sizeof(cmdtbl[0]))-1)

/*
 * main()
 * (Used only for standalone version)
 */
#ifdef STANDALONE
main(int argc, char *argv[])
{
    debug();
}
#endif

/*
 * debug()
 * Debugger/Monitor main loop
 */
int debug(void)
{
  char line[MAXBUFLEN];
  char **argp = NULL;
  char *cp;
  int	 argnum, i;
    
  /*
   * Now get commands one at a time and execute the
   * appropriate routine to deal with them.
   */

  printf("\r\n\r\nMILO built-in Debugger/Monitor (quit to continue boot process)\r\n\r\n");
  
  for (;;)
    {
      prompt();

#ifdef STANDALONE      
      if (fgets(line, sizeof(line), stdin) == NULL)
#else
	if (gets(line) == NULL)
#endif	  
	  break;

      /*
       * Strip trailing CR-LF
       */
      cp = line + strlen(line) - 1;
      while (cp >= line && (*cp == '\n' || *cp == '\r'))
	*cp-- = '\0';

      /*
       * Null command
       */
      if ((argnum = parsit(line, &argp)) == 0)
	continue;

      /*
       * a motion to adjourn is always in order
       */

      if (!strcasecmp(argp[0], "quit"))
	break;

      for (i = 0; i < NUMCMDS; ++i)
	if (!strcasecmp(cmdtbl[i].cmd_name, argp[0]))
	  break;

      if (i < NUMCMDS)
	{
	  (*cmdtbl[i].cmd_fctn)(argnum, argp);
	}
      else
	{
	  printf("Unrecognized command.\r\n");
	  (void) fflush(stdout);
	}
    }

  return 0;
}

/*
 * nop()
 * NOP Function, only for debugging purposes.
 */
int nop(void)
{
    return 0;
}

/*
 * help()
 * Print info about available commands
 */
int help(void)
{
    printf("\r\nKnown commands:\r\n\r\n");
    printf("dump [-b|h|w] start [end]\t\tdump memory contents\r\n");
    printf("dumptlb [all] [filename]\t\tdump TLB contents\r\n");
    printf("fill [-b|h|w] start [end] val\t\tfill memory with value\r\n");
    printf("probe vaddr\t\t\t\tprobe TLB for a virtual address\r\n");
    printf("strings start [end]\t\t\tsearch memory for printable strings\r\n");
    printf("quit\t\t\t\t\tquit debugger\r\n");
    printf("\r\n\r\n");
    return(0);
}

/*
 * prompt()
 * Prompt for a new command
 */
void prompt(void)
{
    printf("> ");
    fflush(stdout);
}
