📄 interruptcontroller.java
字号:
} } } else { switch(initState) { case 0: /* normal mode */ interruptMaskRegister = data; return true; case 1: irqBase = data & 0xf8; initState = 2; break; case 2: if (fourByteInit) { initState = 3; } else { initState = 0; } break; case 3: specialFullyNestedMode = (((data >>> 4) & 1) != 0); autoEOI = (((data >>> 1) & 1) != 0); initState = 0; break; } } return false; } public void elcrWrite(byte data) { elcr = (byte)(data & elcrMask); } /* END IOPortCapable Methods */ private int pollRead(int address) { int ret = this.getIRQ(); if (ret < 0) { InterruptController.this.updateIRQ(); return 0x07; } if (0 != (address >>> 7)) { InterruptController.this.masterPollCode(); } interruptRequestRegister = (byte)(interruptRequestRegister & ~(1 << ret)); interruptServiceRegister = (byte)(interruptServiceRegister & ~(1 << ret)); if (0 != (address >>> 7) || ret != 2) InterruptController.this.updateIRQ(); return ret; } public void setIRQ(int irqNumber, int level) { int mask; mask = (1 << irqNumber); if(0 != (elcr & mask)) { /* level triggered */ if (0 != level) { interruptRequestRegister = (byte)(interruptRequestRegister | mask); lastInterruptRequestRegister = (byte)(lastInterruptRequestRegister | mask); } else { interruptRequestRegister = (byte)(interruptRequestRegister & ~mask); lastInterruptRequestRegister = (byte)(lastInterruptRequestRegister & ~mask); } } else { /* edge triggered */ if (0 != level) { if ((lastInterruptRequestRegister & mask) == 0) { interruptRequestRegister = (byte)(interruptRequestRegister | mask); } lastInterruptRequestRegister = (byte)(lastInterruptRequestRegister | mask); } else { lastInterruptRequestRegister = (byte)(lastInterruptRequestRegister & ~mask); } } } private int getPriority(int mask) { if ((0xff & mask) == 0) { return 8; } int priority = 0; while ((mask & (1 << ((priority + priorityAdd) & 7))) == 0) { priority++; } return priority; } public int getIRQ() { int mask, currentPriority, priority; mask = interruptRequestRegister & ~interruptMaskRegister; priority = this.getPriority(mask); if (priority == 8) { return -1; } /* compute current priority. If special fully nested mode on the master, the IRQ coming from the slave is not taken into account for the priority computation. */ mask = interruptServiceRegister; if (specialFullyNestedMode && this.isMaster()) { mask &= ~(1 << 2); } currentPriority = this.getPriority(mask); if (priority < currentPriority) { /* higher priority found: an irq should be generated */ return (priority + priorityAdd) & 7; } else { return -1; } } private void intAck(int irqNumber) { if (autoEOI) { if (rotateOnAutoEOI) priorityAdd = (irqNumber + 1) & 7; } else { interruptServiceRegister = (byte)(interruptServiceRegister | (1 << irqNumber)); } /* We don't clear a level sensitive interrupt here */ if (0 == (elcr & (1 << irqNumber))) interruptRequestRegister = (byte)(interruptRequestRegister & ~(1 << irqNumber)); } private boolean isMaster() { if (InterruptController.this.master == this) return true; else return false; } private void reset() { //zero all variables except elcrMask lastInterruptRequestRegister = (byte)0x0; interruptRequestRegister = (byte)0x0; interruptMaskRegister = (byte)0x0; interruptServiceRegister = (byte)0x0; priorityAdd = 0; irqBase = 0x0; readRegisterSelect = false; poll = false; specialMask = false; autoEOI = false; rotateOnAutoEOI = false; specialFullyNestedMode = false; initState = 0; fourByteInit = false; elcr = (byte)0x0; //(elcr) PIIX3 edge/level trigger selection } public String toString() { if (isMaster()) { return (InterruptController.this).toString() + ": [Master Element]"; } else { return (InterruptController.this).toString() + ": [Slave Element]"; } } } /* BEGIN IOPortCapable Defined Methods */ public int[] ioPortsRequested() { int[] masterIOPorts = master.ioPortsRequested(); int[] slaveIOPorts = slave.ioPortsRequested(); int[] temp = new int[masterIOPorts.length + slaveIOPorts.length]; System.arraycopy(masterIOPorts, 0, temp, 0, masterIOPorts.length); System.arraycopy(slaveIOPorts, 0, temp, masterIOPorts.length, slaveIOPorts.length); return temp; } public int ioPortReadByte(int address) { switch (address) { case 0x20: case 0x21: return 0xff & master.ioPortRead(address); case 0xa0: case 0xa1: return 0xff & slave.ioPortRead(address); case 0x4d0: return 0xff & master.elcrRead(); case 0x4d1: return 0xff & slave.elcrRead(); default: } return 0; } public int ioPortReadWord(int address) { return (0xff & ioPortReadByte(address)) | (0xff00 & (ioPortReadByte(address + 1) << 8)); } public int ioPortReadLong(int address) { return (0xffff & ioPortReadWord(address)) | (0xffff0000 & (ioPortReadWord(address + 2) << 16)); } public void ioPortWriteByte(int address, int data) { switch (address) { case 0x20: case 0x21: if (master.ioPortWrite(address, (byte)data)) this.updateIRQ(); break; case 0xa0: case 0xa1: if (slave.ioPortWrite(address, (byte)data)) this.updateIRQ(); break; case 0x4d0: master.elcrWrite((byte)data); break; case 0x4d1: slave.elcrWrite((byte)data); break; default: } } public void ioPortWriteWord(int address, int data) { this.ioPortWriteByte(address, data); this.ioPortWriteByte(address + 1, data >>> 8); } public void ioPortWriteLong(int address, int data) { this.ioPortWriteWord(address, data); this.ioPortWriteWord(address + 2, data >>> 16); } /* END IOPortCapable Defined Methods */ private void masterPollCode() { master.interruptServiceRegister = (byte)(master.interruptServiceRegister & ~(1 << 2)); master.interruptRequestRegister = (byte)(master.interruptRequestRegister & ~(1 << 2)); } private boolean ioportRegistered; public void reset() { master.reset(); slave.reset(); ioportRegistered = false; connectedCPU = null; } public boolean initialised() { return ((connectedCPU != null) && ioportRegistered); } public boolean updated() { return (ioportRegistered); } public void updateComponent(HardwareComponent component) { if (component instanceof IOPortHandler) { ((IOPortHandler)component).registerIOPortCapable(this); ioportRegistered = true; } } public void acceptComponent(HardwareComponent component) { if (component instanceof Processor) connectedCPU = (Processor)component; if ((component instanceof IOPortHandler) && component.initialised()) { ((IOPortHandler)component).registerIOPortCapable(this); ioportRegistered = true; } } public void timerCallback() {} public String toString() { return "Intel i8259 Programmable Interrupt Controller"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -