⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
字号:
/*  * main.c -- * *  Main program for "dlxview" simulator for DLX architecture. * *  This file is part of DISC.  It was modified by Yinong Zhang  *  (yinong@ecn.purdue.edu) from the file "main.c" in the distribution *  of "dlxsim" available at: *     ftp://max.stanford.edu/pub/hennessy-patterson.software/dlx.tar.Z * *  The original source code is copyright as follows: * * Copyright 1989 Regents of the University of California * 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.  The University of California * makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without * express or implied warranty. * */#include <stdio.h>#include <tcl.h>#include <tk.h>#include <signal.h>#include "dlx.h"#include "purdue.h"/* * Declarations for various library procedures and variables (don't want * to include tkInt.h or tkConfig.h here, because people might copy this * file out of the Tk source directory to make their own modified versions). */extern void		exit ();extern int		isatty ();extern int		read ();extern char *		strrchr ();/* * Global variables used by the main program: */static Tk_Window mainWindow;	/* The main window for the application.  If				 * NULL then the application no longer				 * exists. */static Tcl_Interp *interp;	/* Interpreter for this application. */static Tcl_DString command;	/* Used to assemble lines of terminal input				 * into Tcl commands. */static int tty;			/* Non-zero means standard input is a				 * terminal-like device.  Zero means it's				 * a file. */static char errorExitCmd[] = "exit 1";static DLX *machPtr;/* * Command-line options: */static int synchronize = 0;static char *fileName = NULL;static char *name = NULL;static char *display = NULL;static char *geometry = NULL;static Tk_ArgvInfo argTable[] = {    {"-file", TK_ARGV_STRING, (char *) NULL, (char *) &fileName,	"File from which to read commands"},    {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry,	"Initial geometry for window"},    {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display,	"Display to use"},    {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name,	"Name to use for application"},    {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize,	"Use synchronous mode for display server"},    {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,	(char *) NULL}};/* * Declaration for Tcl command procedure to create demo widget.  This * procedure is only invoked if SQUARE_DEMO is defined. */extern int SquareCmd _ANSI_ARGS_((ClientData clientData,	Tcl_Interp *interp, int argc, char *argv[]));/* * Forward declarations for procedures defined later in this file: */static void		Prompt (Tcl_Interp *, int);static void		StdinProc (ClientData, int);static void 		Interrupt(int);/* *---------------------------------------------------------------------- * * main -- * *	Top-level procedure for dlxview simulator. * * Results: *	None. * * Side effects: *	Tons:  read the user manual for details. * *---------------------------------------------------------------------- */intmain(argc, argv)    int argc;				/* Number of arguments. */    char **argv;			/* Array of argument strings. */{    char *p, *msg;    int code;    char *tcl_RcFileName;    interp = Tcl_CreateInterp();    /*     * Parse command-line arguments.     */    if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, argTable, 0)	    != TCL_OK) {	fprintf(stderr, "%s\n", interp->result);	exit(1);    }    if (name == NULL) {	if (fileName != NULL) {	    p = fileName;	} else {	    p = argv[0];	}	name = strrchr(p, '/');	if (name != NULL) {	    name++;	} else {	    name = p;	}    }    /*     * If a display was specified, put it into the DISPLAY     * environment variable so that it will be available for     * any sub-processes created by us.     */    if (display != NULL) {	Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY);    }    /*     * Initialize the Tk application.     */#if defined(TK40)    mainWindow = Tk_CreateMainWindow(interp, display, name, "Tk");    if (mainWindow == NULL) {      fprintf(stderr, "%s\n", interp->result);	   exit(1);    }#endif    if (synchronize) {	   XSynchronize(Tk_Display(mainWindow), True);    }#if defined(TK40)    Tk_GeometryRequest(mainWindow, 200, 200); #endif    /*     * Set the "tcl_interactive" variable.     */    tty = isatty(0);    Tcl_SetVar(interp, "tcl_interactive",	    ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);    /*     * Add a few application-specific commands to the application's     * interpreter.     */    /*     * Invoke application-specific initialization.     */    if (Tcl_Init(interp) != TCL_OK) {	fprintf(stderr, "Tcl_Init failed: %s\n", interp->result);    }    if (Tk_Init(interp) != TCL_OK) {	fprintf(stderr, "Tk_Init failed: %s\n", interp->result);    }    tcl_RcFileName = "~/.dlxviewrc";    machPtr = Sim_Create(interp);      (void) signal(SIGINT, Interrupt);    Tk_DefineBitmap(interp, Tk_GetUid("purdue"), (char *)pur_bits, pur_width, pur_height);#ifdef SCRIPT    code = Tcl_VarEval(interp, "source dlxview.tcl", (char *) NULL);	if (code != TCL_OK) {	    goto error;	} #else     Script_Read(interp);#endif     Sim_Initialize(machPtr);    /*     * Set the geometry of the main window, if requested.     */    if (geometry != NULL) {	code = Tcl_VarEval(interp, "wm geometry . ", geometry, (char *) NULL);	if (code != TCL_OK) {	    fprintf(stderr, "%s\n", interp->result);	}    }    /*     * Invoke the script specified on the command line, if any.     */    if (fileName != NULL) {	code = Tcl_VarEval(interp, "source ", fileName, (char *) NULL);	if (code != TCL_OK) {	    goto error;	}	tty = 0;    } else {	/*	 * Commands will come from standard input, so set up an event	 * handler for standard input.  If the input device is aEvaluate the	 * .rc file, if one has been specified, set up an event handler	 * for standard input, and print a prompt if the input	 * device is a terminal.	 *//*	if (tcl_RcFileName != NULL) {	    Tcl_DString buffer;	    char *fullName;	    FILE *f;    	    fullName = Tcl_TildeSubst(interp, tcl_RcFileName, &buffer);	    if (fullName == NULL) {		fprintf(stderr, "%s\n", interp->result);	    } else {		f = fopen(fullName, "r");		if (f != NULL) {		    code = Tcl_EvalFile(interp, fullName);		    if (code != TCL_OK) {			fprintf(stderr, "%s\n", interp->result);		    }		    fclose(f);		}	    }	    Tcl_DStringFree(&buffer);	}*/	Tk_CreateFileHandler(0, TK_READABLE, StdinProc, (ClientData) 0);	if (tty) {	    Prompt(interp, 0);	}    }    fflush(stdout);    Tcl_DStringInit(&command);    /*     * Loop infinitely, waiting for commands to execute.  When there     * are no windows left, Tk_MainLoop returns and we exit.     */    Tk_MainLoop();    /*     * Don't exit directly, but rather invoke the Tcl "exit" command.     * This gives the application the opportunity to redefine "exit"     * to do additional cleanup.     */    Tcl_Eval(interp, "exit");    exit(1);error:    msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);    if (msg == NULL) {	msg = interp->result;    }    fprintf(stderr, "%s\n", msg);    Tcl_Eval(interp, errorExitCmd);    return 1;			/* Needed only to prevent compiler warnings. */}/* *---------------------------------------------------------------------- * * StdinProc -- * *	This procedure is invoked by the event dispatcher whenever *	standard input becomes readable.  It grabs the next line of *	input characters, adds them to a command being assembled, and *	executes the command if it's complete. * * Results: *	None. * * Side effects: *	Could be almost arbitrary, depending on the command that's *	typed. * *---------------------------------------------------------------------- */    /* ARGSUSED */static voidStdinProc(clientData, mask)    ClientData clientData;		/* Not used. */    int mask;				/* Not used. */{#define BUFFER_SIZE 4000    char input[BUFFER_SIZE+1];    static int gotPartial = 0;    char *cmd;    int code, count;    count = read(fileno(stdin), input, BUFFER_SIZE);    if (count <= 0) {	if (!gotPartial) {	    if (tty) {		Tcl_Eval(interp, "exit");		exit(1);	    } else {		Tk_DeleteFileHandler(0);	    }	    return;	} else {	    count = 0;	}    }    cmd = Tcl_DStringAppend(&command, input, count);    if (count != 0) {	if ((input[count-1] != '\n') && (input[count-1] != ';')) {	    gotPartial = 1;	    goto prompt;	}	if (!Tcl_CommandComplete(cmd)) {	    gotPartial = 1;	    goto prompt;	}    }    gotPartial = 0;    /*     * Disable the stdin file handler while evaluating the command;     * otherwise if the command re-enters the event loop we might     * process commands from stdin before the current command is     * finished.  Among other things, this will trash the text of the     * command being evaluated.     */    Tk_CreateFileHandler(0, 0, StdinProc, (ClientData) 0);    code = Tcl_RecordAndEval(interp, cmd, 0);    Tk_CreateFileHandler(0, TK_READABLE, StdinProc, (ClientData) 0);    Tcl_DStringFree(&command);    if (*interp->result != 0) {	if ((code != TCL_OK) || (tty)) {	    printf("%s\n", interp->result);	}    }    /*     * Output a prompt.     */    prompt:    if (tty) {	Prompt(interp, gotPartial);    }}/* *---------------------------------------------------------------------- * * Prompt -- * *	Issue a prompt on standard output, or invoke a script *	to issue the prompt. * * Results: *	None. * * Side effects: *	A prompt gets output, and a Tcl script may be evaluated *	in interp. * *---------------------------------------------------------------------- */static voidPrompt(interp, partial)    Tcl_Interp *interp;			/* Interpreter to use for prompting. */    int partial;			/* Non-zero means there already					 * exists a partial command, so use					 * the secondary prompt. */{    char *promptCmd;    int code;    promptCmd = Tcl_GetVar(interp,	partial ? "tcl_prompt2" : "tcl_prompt1", TCL_GLOBAL_ONLY);    if (promptCmd == NULL) {	defaultPrompt:	if (!partial) {	    fputs("(dlxview) ", stdout);	}    } else {	code = Tcl_Eval(interp, promptCmd);	if (code != TCL_OK) {	    Tcl_AddErrorInfo(interp,		    "\n    (script that generates prompt)");	    fprintf(stderr, "%s\n", interp->result);	    goto defaultPrompt;	}    }    fflush(stdout);}/* *---------------------------------------------------------------------- * * Interrupt -- * *	This procedure is invoked when the interrupt key is typed: *	it causes the simulation to stop. * * Results: *	None. * * Side effects: *	Causes simultor to stop after next instruction. * *---------------------------------------------------------------------- */static voidInterrupt(dumb)    int dumb;{    fprintf( stderr, "interrupt\n" );    Sim_Stop(machPtr);}/* *---------------------------------------------------------------------- * * Main_QuitCmd -- * *	This procedure is invoked to process the "quit" Tcl command. *	See the user documentation for details on what it does. * * Results: *	None:  this command never returns. * * Side effects:  *	The program exits. * *---------------------------------------------------------------------- *//* ARGSUSED */intMain_QuitCmd(clientData, interp, argc, argv)    ClientData clientData;    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    exit(0);    return TCL_OK;			/* Never gets executed. */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -