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

📄 cop0.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
字号:
/*  * cop0.c -- * *  This file implements a subset of the DLX's coprocessor 0 *  facilities for DlXsim.  Right now only enough is implemented *  to handle simple I/O interrupts. * *  This file is part of DISC. It came from the file "cop0.c" in  *  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 "dlx.h"#define VECTOR_ADDRESS		0x80/* * Forward declarations for procedures defined later in this file: */static void	Interrupt(DLX *);/* *---------------------------------------------------------------------- * * Cop0_Init -- * *	This procedure is called when a machine is created to *	initialize its coprocessor 0 state. * * Results: *	None. * * Side effects: *	Whatever it takes to initialize the state. * *---------------------------------------------------------------------- */voidCop0_Init(machPtr)    register DLX *machPtr;		/* Machine being created. */{    int i;    machPtr->cop0.cause = 0;    machPtr->cop0.status = 0;    machPtr->cop0.epc = 0;    for (i = 0; i < COP0_NUM_LEVELS; i++) {	machPtr->cop0.pending[i] = 0;    }    machPtr->cop0.pendingMask = 0;}/* *---------------------------------------------------------------------- * * Cop0_IntPending -- * *	This procedure is called to register a change in the pending *	status of interrupts. * * Results: *	None. * * Side effects: *	The number of pending interrupts at level "level" is incremented *	by "change".  If the new number is greater than zero and the *	corresponding interrupt level is enabled, then an I/O interrupt *	will occur. * *---------------------------------------------------------------------- */voidCop0_IntPending(machPtr, level, change)    register DLX *machPtr;		/* Machine to manipulate. */    int level;				/* Interrupt level (0-5). */    int change;				/* 1 means a new interrupt source					 * has just become ready;  -1 means					 * an interrupt source has become					 * no longer ready. */{    int old, new;    old = machPtr->cop0.pending[level];    new = old + change;    machPtr->cop0.pending[level] = new;    if (new < 0) {	printf("Hey, level %d just went negative!\n", level);    }    if ((old <= 0) && (new > 0)) {	machPtr->cop0.pendingMask |= COP0_STATUS_IMASK0 << level;	if (machPtr->cop0.status & machPtr->cop0.pendingMask) {	    Sim_CallBack(machPtr, 0, Interrupt, (ClientData) machPtr);	}    } else if ((old > 0) && (new <= 0)) {	machPtr->cop0.pendingMask &= ~(COP0_STATUS_IMASK0 << level);    }}/* *---------------------------------------------------------------------- * * Interrupt -- * *	This is a Sim_CallBack procedure that is invoked at times *	when there MAY be an interrupt pending.  This procedure *	checks to see if an interrupt really should be delivered; *	if so, it delivers it. * * Results: *	None. * * Side effects: *	The state of the machine may be updated to reflect the *	delivery of an interrupt. * *---------------------------------------------------------------------- */static voidInterrupt(machPtr)    register DLX *machPtr;	/* Machine to check for interrupts. */{    if (!(machPtr->cop0.status & COP0_STATUS_IEC)) {	return;    }    if ((machPtr->cop0.status & machPtr->cop0.pendingMask) == 0) {	return;    }    machPtr->cop0.cause = (machPtr->cop0.status & machPtr->cop0.pendingMask)	    | COP0_CAUSE_CODE_INT;    if (machPtr->branchSerial == (machPtr->insCount-1)) {	machPtr->cop0.epc = machPtr->branchPC;	machPtr->cop0.cause |= COP0_CAUSE_BD;    } else {	machPtr->cop0.epc = Sim_GetPC(machPtr);    }    if (machPtr->cop0.status & COP0_STATUS_IEP) {	machPtr->cop0.status |= COP0_STATUS_IE0;    } else {	machPtr->cop0.status &= ~COP0_STATUS_IE0;    }    if (machPtr->cop0.status & COP0_STATUS_IEC) {	machPtr->cop0.status |= COP0_STATUS_IEP;    } else {	machPtr->cop0.status &= ~COP0_STATUS_IEP;    }    machPtr->cop0.status &= ~COP0_STATUS_IEC;    machPtr->regs[PC_REG] = ADDR_TO_INDEX(VECTOR_ADDRESS);    machPtr->regs[NEXT_PC_REG] = machPtr->regs[PC_REG] + 1;}

⌨️ 快捷键说明

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