/*
 * This file is part of SIS.
 * 
 * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European
 * Space Agency
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option)
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, see <http://www.gnu.org/licenses/>.
 * 
 */

#include "config.h"
#include <signal.h>
#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h>
#include <time.h>
#include <sys/fcntl.h>
#include "sis.h"
#include <dis-asm.h>
#include "sim-config.h"

#define	VAL(x)	strtol(x,(char **)NULL,0)

/* Structures and functions from readline library */

typedef struct {
  char *line;
  char *data;
} HIST_ENTRY;

extern char *	readline PARAMS ((char *prompt));
extern void	using_history PARAMS ((void));
extern void	add_history PARAMS ((char *string));
extern HIST_ENTRY *remove_history PARAMS ((int which));



/* Command history buffer length - MUST be binary */
#define HIST_LEN	64

extern struct disassemble_info dinfo;
extern struct pstate sregs;
extern struct estate ebase;

extern int      ctrl_c;
extern int      nfp;
extern int      ift;
extern int      wrp;
extern int      rom8;
extern int      uben;
extern int      sis_verbose;
extern char    *sis_version;
extern struct estate ebase;
extern struct evcell evbuf[];
extern struct irqcell irqarr[];
extern int      irqpend, ext_irl;
extern int      termsave;
extern int      sparclite;
extern int      dumbio;
extern char     uart_dev1[];
extern char     uart_dev2[];
extern uint32   last_load_addr;

#ifdef ERA
extern int era;
#endif

int
run_sim(sregs, icount, dis)
    struct pstate  *sregs;
    uint64          icount;
    int             dis;
{
    int             irq, mexc, deb, asi;

    sregs->starttime = time(NULL);
    init_stdio();
    if (sregs->err_mode) icount = 0;
    deb = dis || sregs->histlen || sregs->bptnum;
    irq = 0;
    while (icount > 0) {

	if (sregs->psr & 0x080)
	    asi = 9;
   	else
	    asi = 8;
	mexc = memory_read(asi, sregs->pc, &sregs->inst, 2, &sregs->hold);
	sregs->icnt = 1;
	if (sregs->annul) {
	    sregs->annul = 0;
	    sregs->pc = sregs->npc;
	    sregs->npc = sregs->npc + 4;
	} else {
	    sregs->fhold = 0;
	    if (ext_irl) irq = check_interrupts(sregs);
	    if (!irq) {
		if (mexc) {
		    sregs->trap = I_ACC_EXC;
		} else {
		    if (deb) {
	    		if ((sregs->bphit = check_bpt(sregs)) != 0) {
            		    restore_stdio();
	    		    return (BPT_HIT);
	    		}
		        if (sregs->histlen) {
			    sregs->histbuf[sregs->histind].addr = sregs->pc;
			    sregs->histbuf[sregs->histind].time = ebase.simtime;
			    sregs->histind++;
			    if (sregs->histind >= sregs->histlen)
			        sregs->histind = 0;
		        }
		        if (dis) {
			    printf(" %8u ", ebase.simtime);
			    dis_mem(sregs->pc, 1, &dinfo);
		        }
		    }
		    dispatch_instruction(sregs);
		    icount--;
		}
	    }
	    if (sregs->trap) {
		irq = 0;
		sregs->err_mode = execute_trap(sregs);
        	if (sregs->err_mode) {
	            error_mode(sregs->pc);
	            icount = 0;
	        }
	    }
	}
	advance_time(sregs);
	if (ctrl_c || (sregs->tlimit <= ebase.simtime)) {
	    icount = 0;
	    if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1;
	}
    }
    sregs->tottime += time(NULL) - sregs->starttime;
    restore_stdio();
    if (sregs->err_mode)
	return (ERROR);
    if (ctrl_c) {
	ctrl_c = 0;
	return (CTRL_C);
    }
    return (TIME_OUT);
}

int
main(argc, argv)
    int             argc;
    char          **argv;
{

    int             cont = 1;
    int             stat = 1;
    int             freq = 14;
    int             copt = 0;

    char           *cfile, *bacmd;
    char           *cmdq[HIST_LEN];
    int             cmdi = 0;
    int             i;

    cfile = 0;
    for (i = 0; i < 64; i++)
	cmdq[i] = 0;
    printf("\n SIS - SPARC instruction simulator %s,  copyright Jiri Gaisler 1995\n", sis_version);
    printf(" Bug-reports to jgais@wd.estec.esa.nl\n\n");
    while (stat < argc) {
	if (argv[stat][0] == '-') {
	    if (strcmp(argv[stat], "-v") == 0) {
		sis_verbose = 1;
	    } else if (strcmp(argv[stat], "-c") == 0) {
		if ((stat + 1) < argc) {
		    copt = 1;
		    cfile = argv[++stat];
		}
	    } else if (strcmp(argv[stat], "-nfp") == 0)
		nfp = 1;
	    else if (strcmp(argv[stat], "-ift") == 0)
		ift = 1;
	    else if (strcmp(argv[stat], "-wrp") == 0)
		wrp = 1;
	    else if (strcmp(argv[stat], "-rom8") == 0)
		rom8 = 1;
	    else if (strcmp(argv[stat], "-uben") == 0)
		uben = 1;
	    else if (strcmp(argv[stat], "-uart1") == 0) {
		if ((stat + 1) < argc)
		    strcpy(uart_dev1, argv[++stat]);
	    } else if (strcmp(argv[stat], "-uart2") == 0) {
		if ((stat + 1) < argc)
		    strcpy(uart_dev2, argv[++stat]);
	    } else if (strcmp(argv[stat], "-freq") == 0) {
		if ((stat + 1) < argc)
		    freq = VAL(argv[++stat]);
	    } else if (strcmp(argv[stat], "-sparclite") == 0) {
		sparclite = 1;
#ifdef ERA
	    } else if (strcmp(argv[stat], "-era") == 0) {
		era = 1;
#endif
            } else if (strcmp(argv[stat], "-dumbio") == 0) {
		dumbio = 1;
	    } else {
		printf("unknown option %s\n", argv[stat]);
		usage();
		exit(1);
	    }
	} else {
	    last_load_addr = bfd_load(argv[stat]);
	}
	stat++;
    }
    if (nfp)
	printf("FPU disabled\n");
#ifdef ERA
    if (era)
	printf("ERA ECC emulation enabled\n");
#endif
    sregs.freq = freq;

    INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
    dinfo.endian = BFD_ENDIAN_BIG;

    termsave = fcntl(0, F_GETFL, 0);
    using_history();
    init_signals();
    ebase.simtime = 0;
    reset_all();
    init_bpt(&sregs);
    init_sim();
#ifdef STAT
    reset_stat(&sregs);
#endif

    if (copt) {
	bacmd = (char *) malloc(256);
	strcpy(bacmd, "batch ");
	strcat(bacmd, cfile);
	exec_cmd(&sregs, bacmd);
    }
    while (cont) {

	if (cmdq[cmdi] != 0) {
#if 0
	    remove_history(cmdq[cmdi]);
#else
	    remove_history(cmdi);
#endif
	    free(cmdq[cmdi]);
	    cmdq[cmdi] = 0;
	}
	cmdq[cmdi] = readline("sis> ");
	if (cmdq[cmdi] && *cmdq[cmdi])
	    add_history(cmdq[cmdi]);
	if (cmdq[cmdi])
	    stat = exec_cmd(&sregs, cmdq[cmdi]);
	else {
	    puts("\n");
	    exit(0);
	}
	switch (stat) {
	case OK:
	    break;
	case CTRL_C:
	    printf("\b\bInterrupt!\n");
	case TIME_OUT:
	    printf(" Stopped at time %d (%.3f ms)\n", ebase.simtime, 
	      ((double) ebase.simtime / (double) sregs.freq) / 1000.0);
	    break;
	case BPT_HIT:
	    printf("breakpoint at 0x%08x reached\n", sregs.pc);
	    sregs.bphit = 1;
	    break;
	case ERROR:
	    printf("IU in error mode (%d)\n", sregs.trap);
	    stat = 0;
	    printf(" %8d ", ebase.simtime);
	    dis_mem(sregs.pc, 1, &dinfo);
	    break;
	default:
	    break;
	}
	ctrl_c = 0;
	stat = OK;

	cmdi = (cmdi + 1) & (HIST_LEN - 1);

    }
    return 0;
}

