/************************************************************************
**
**	Dinero III Cache Simulator 
**	$Header: /var/home/markhill/DistributeDineroIII/RCS/main.c,v 3.3 89/05/04 09:57:37 markhill Exp $
**	Similar to Version 3.1, Released 8/7/85
**
**	Mark D. Hill
**	Computer Sciences Dept.
**	Univ. of Wisconsin
**	Madison, WI 53706
**	markhill@cs.wisc.edu
**
**	Developed DineroIII While Affiliated With:
**
**	Computer Science Division
**	University of California
**	Berkeley, California 94720
**
**      Revised:
**      Erik Riedel
**      Electrical and Computer Engineering
**      Carnegie Mellon University
**      5000 Forbes Ave.
**      Pittsburgh, PA 15213
**      riedel@cs.cmu.edu
**
**	Source File:	main.c
**
************************************************************************/

/* 
**  Copyright 1985, 1989 Mark D. Hill
**
**  Permission to use, copy, modify, and distribute this
**  software and its documentation for any purpose and without
**  fee is hereby granted, provided that the above copyright
**  notice appear in all copies.  Mark D. Hill makes no
**  representations about the suitability of this software
**  for any purpose.  It is provided "as is" without expressed
**  or implied warranty.
*/  

#define PUBLIC
#include "global.h"

main(argc,argv)			/* Dinero III Cache Simulator (see doc.h). */
int argc;		/* < */
char *argv[];		/* < */
{
extern int init();
extern int outputmetric();
extern int srandom();	
POLICYTYPE policy;
METRICTYPE metric;
CTRLTYPE ctrl;
CACHETYPE cache;

printf("\n\n---Dinero III by Mark D. Hill.\n");

/*  for 370 port:
370
370	Print different banner.
370
*/
#ifdef IBM370
printf(    "---Version %s for IBM 3081, Released %s.\n", "3.3", "May 1989");
printf(    "---370 Comments: %s\n", 
	        "Use '-F FOO' to read from trace file 'FOO DIN.'"
	    );
printf(    "---370 Untested: %s\n", 
	        "srandom() and random() on 370."
	    );
#else
printf(    "---Version %s, Released %s.\n", "3.3", "May 1989");
#endif

printf("---Enhanced Version (Carnegie Mellon University), Sept. 1997.\n");


/*
**	Exit with extra messages if there are no args.
*/
if (argc==1) {
	printf(    "---User must specify (in bytes): %s\n", 
        	     		"cache size(s) and block size."
	    );
	printf(    "---E.g.: %s\n", 
        "dineroIII -i16K -d16384 -b16"
	    );
	/* add some more info on usage (copied from man/dinero.htm */
	printf("\n");
	printf(" -b block_size in bytes (256, 64k, 1M)  [required]\n");
	printf(" -u unified_cache_size\n");   
        printf(" -i instruction_cache_size\n");
	printf(" -d data_cache_size\n");
	printf("\n");
        printf(" -S subblock_size\n");
	printf(" -a associativity [1,2,...], default=1\n");
        printf(" -r replacement_policy [l=LRU,f=FIFO,r=RANDOM], default=l\n");
	printf(" -f fetch_policy [d,a,m,t,l,S], default=d\n");
	printf(" -p prefetch_distance [1,2,...], default=1\n");
	printf(" -P abort_prefetch_percent\n");
	printf(" -w write_policy [w=Write-through,c=Copy-back], default=c\n");
	printf(" -A write_allocation_policy [w,n], default=w\n");
	printf(" -D debug_flag [0,1,2]\n");
	printf(" -o output_style [0,1,2,3]\n");
	printf(" -Z skip_count\n");
	printf(" -z maximum_count, default=10000000\n");
	printf(" -Q flush_count\n");
	printf(" -W word_size in bytes, default=4\n");
	printf(" -B bus_width in bytes, default=block size\n");
	exit(1);
 }

printf(  "\n---Execution begins.\n");

init(argc,argv,&cache,&policy,&ctrl,&metric);

srandom(1);	

printf("\n---Simulation begins.\n");

mainloop(&cache,&policy,&ctrl,&metric);

printf("---Simulation complete.\n");

outputmetric(&cache,&policy,&ctrl,&metric);

printf("---Execution complete.\n");

} /* ****************************************************************** */



mainloop(                               /* Initiates fetch, & updates */
	 cachep,policyp,ctrlp,metricp)

CACHETYPE *cachep;                      /* <> */
register POLICYTYPE *policyp;           /* < */
register CTRLTYPE *ctrlp;               /* < */
register METRICTYPE *metricp;           /* <> */
{
extern int dumpaddr();
extern int dumpstate();
extern int fetch();
extern int outputmetric();
extern int update();
extern int flushcache();
DECODEDADDRTYPE decodedaddr;


/*
**  Repeat until:  
**	1) "max_count" trace addresses (i.e. demand references) have 
**	   been read.
**	2) the input trace has been exhausted.
**
**  For each address (including any prefetch addresses):  
**	1) call fetch() to get and interpret the address..
**  	2) call update() to find the address in the priority stacks,
**	   perform side-effects (like starting a prefetch), update
**	   priority stacks, and update metrics.
**	3) If debugging is enabled, print some information.
** 
*/
while (fetch(cachep,ctrlp,metricp,&decodedaddr)!=EOF) {

	update(cachep,policyp,ctrlp,metricp,&decodedaddr);

	if (ctrlp->debug>=DEBUG1) {
		dumpaddr(ctrlp->tracecount,&decodedaddr);
		if (ctrlp->debug>=DEBUG2) {
			outputmetric(cachep,policyp,ctrlp,metricp);
		}
		dumpstate(cachep,policyp);
	}

	if (ctrlp->output==VERBOSE && (ctrlp->tracecount % 500001==0)) {
		outputmetric(cachep,policyp,ctrlp,metricp);
	}

 } /* END OF MAIN LOOP */

/* flush cache at end of run */
flushcache(cachep,ctrlp,metricp);

if (ctrlp->tracecount > ctrlp->maxcount) {
	printf("---Maximum address count exceeded.\n");
 }

} /* ****************************************************************** */

