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

📄 interruptcontroller.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    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, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.motherboard;import org.jpc.emulator.processor.*;import org.jpc.emulator.HardwareComponent;import java.io.*;/** * i8259 Programmable Interrupt Controller emulation. */public class InterruptController implements IOPortCapable, HardwareComponent{    private InterruptControllerElement master;    private InterruptControllerElement slave;    private Processor connectedCPU;    public InterruptController()    {	ioportRegistered = false;	master = new InterruptControllerElement(true);	slave = new InterruptControllerElement(false);    }    public void dumpState(DataOutput output) throws IOException    {        master.dumpState(output);        slave.dumpState(output);    }    public void loadState(DataInput input) throws IOException    {        ioportRegistered = false;        master.loadState(input);        slave.loadState(input);    }    private void updateIRQ()    {	int slaveIRQ, masterIRQ;	/* first look at slave irq */	slaveIRQ = slave.getIRQ();	if (slaveIRQ >= 0) {	    /* if irq request by slave pic, signal Master PIC */	    master.setIRQ(2,1);	    master.setIRQ(2,0);	}	/* look at requested IRQ */	masterIRQ = master.getIRQ();	if(masterIRQ >= 0) {	    connectedCPU.raiseInterrupt();	}    }    public void setIRQ(int irqNumber, int level)    {	switch (irqNumber >>> 3) {	case 0: //master	    master.setIRQ(irqNumber & 7, level);	    this.updateIRQ();	    break;	case 1: //slave	    slave.setIRQ(irqNumber & 7, level);	    this.updateIRQ();	    break;	default:	}    }    public int cpuGetInterrupt()    {	int masterIRQ, slaveIRQ;	/* read the irq from the PIC */	masterIRQ = master.getIRQ();	if (masterIRQ >= 0) {	    master.intAck(masterIRQ);	    if (masterIRQ == 2) {		slaveIRQ = slave.getIRQ();		if (slaveIRQ >= 0) {		    slave.intAck(slaveIRQ);		} else {		    /* spurious IRQ on slave controller */		    slaveIRQ = 7;		}		this.updateIRQ();		return slave.irqBase + slaveIRQ;		//masterIRQ = slaveIRQ + 8;	    } else {		this.updateIRQ();		return master.irqBase + masterIRQ;	    }	} else {	    /* spurious IRQ on host controller */	    masterIRQ = 7;	    this.updateIRQ();	    return master.irqBase + masterIRQ;	}    }    private int intAckRead()    {	int ret = master.pollRead(0x00);	if (ret == 2)	    ret = slave.pollRead(0x80) + 8;	master.readRegisterSelect = true;	return ret;    }    private class InterruptControllerElement    {	private byte lastInterruptRequestRegister; //edge detection	private byte interruptRequestRegister;	private byte interruptMaskRegister;	private byte interruptServiceRegister;	private int priorityAdd; // highest IRQ priority	private int irqBase;	private boolean readRegisterSelect;	private boolean poll;	private boolean specialMask;	private int initState;	private boolean fourByteInit;	private byte elcr; //(elcr) PIIX3 edge/level trigger selection	private byte elcrMask;	private boolean specialFullyNestedMode;	private boolean autoEOI;	private boolean rotateOnAutoEOI;	private int[] ioPorts;	public InterruptControllerElement(boolean master)	{	    if (master == true) {		ioPorts = new int[]{0x20, 0x21, 0x4d0};		elcrMask = (byte)0xf8;	    } else {		ioPorts = new int[]{0xa0, 0xa1, 0x4d1};		elcrMask = (byte)0xde;	    }	}        public void dumpState(DataOutput output) throws IOException        {            output.writeByte(lastInterruptRequestRegister);            output.writeByte(interruptRequestRegister);            output.writeByte(interruptMaskRegister);            output.writeByte(interruptServiceRegister);            output.writeInt(priorityAdd);            output.writeInt(irqBase);            output.writeBoolean(readRegisterSelect);            output.writeBoolean(poll);            output.writeBoolean(specialMask);            output.writeInt(initState);            output.writeBoolean(autoEOI);            output.writeBoolean(rotateOnAutoEOI);            output.writeBoolean(specialFullyNestedMode);            output.writeBoolean(fourByteInit);            output.writeByte(elcr);            output.writeByte(elcrMask);            output.writeInt(ioPorts.length);            for (int i=0; i< ioPorts.length; i++)                output.writeInt(ioPorts[i]);        }        public void loadState(DataInput input) throws IOException        {            lastInterruptRequestRegister = input.readByte();            interruptRequestRegister = input.readByte();            interruptMaskRegister = input.readByte();            interruptServiceRegister = input.readByte();            priorityAdd = input.readInt();            irqBase = input.readInt();            readRegisterSelect = input.readBoolean();            poll = input.readBoolean();            specialMask = input.readBoolean();            initState = input.readInt();            autoEOI = input.readBoolean();            rotateOnAutoEOI = input.readBoolean();            specialFullyNestedMode = input.readBoolean();            fourByteInit = input.readBoolean();            elcr = input.readByte();            elcrMask = input.readByte();            int len = input.readInt();            ioPorts = new int[len];            for (int i=0; i< len; i++)                ioPorts[i] = input.readInt();        }	/* BEGIN IOPortCapable Methods */	public int[] ioPortsRequested()	{	    return ioPorts;	}	public byte ioPortRead(int address)	{	    if(poll) {		poll = false;		return (byte)this.pollRead(address);	    }	    	    if ((address & 1) == 0) {		if (readRegisterSelect) {		    return interruptServiceRegister;		}		return interruptRequestRegister;	    }	    return interruptMaskRegister;	}	public byte elcrRead()	{	    return elcr;	}	public boolean ioPortWrite(int address, byte data) //t/f updateIRQ	{	    int priority, command, irq;	    address &= 1;	    if (address == 0) {		if (0 != (data & 0x10))                 {		    /* init */		    this.reset();		    connectedCPU.clearInterrupt();		    initState = 1;		    fourByteInit = ((data & 1) != 0);		    if (0 != (data & 0x02))			System.err.println("single mode not supported");		    if (0 != (data & 0x08))			System.err.println("level sensitive irq not supported");		}                 else if (0 != (data & 0x08))                 {		    if (0 != (data & 0x04))			poll = true;		    if (0 != (data & 0x02))			readRegisterSelect = ((data & 0x01) != 0);		    if (0 != (data & 0x40))			specialMask = (((data >>> 5) & 1) != 0);		}                 else                 {		    command = data >>> 5;		    switch(command) {		    case 0:		    case 4:			rotateOnAutoEOI = ((command >>> 2) != 0);			break;		    case 1: // end of interrupt		    case 5:			priority = this.getPriority(interruptServiceRegister);			if (priority != 8) {			    irq = (priority + priorityAdd) & 7;			    interruptServiceRegister = (byte)(interruptServiceRegister & ~(1 << irq));			    if (command == 5)				priorityAdd = (irq + 1) & 7;			    return true;			}			break;		    case 3:			irq = data & 7;			interruptServiceRegister = (byte)(interruptServiceRegister & ~(1 << irq));			return true;		    case 6:			priorityAdd = (data + 1) & 7;			return true;		    case 7:			irq = data & 7;			interruptServiceRegister = (byte)(interruptServiceRegister & ~(1 << irq));			priorityAdd = (irq + 1) & 7;			return true;		    default:			/* no operation */			break;

⌨️ 快捷键说明

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