📄 intervaltimer.java
字号:
{ if (0 != countLatched) { outputLatch = this.getCount(); countLatched = rwMode; } } private void latchStatus() { if (!statusLatched) { status = ((getOut(IntervalTimer.this.getTimingSource().getTime()) << 7) | (nullCount ? 0x40 : 0x00) | (rwMode << 4) | (mode << 1) | bcd); statusLatched = true; } } public void write(int data) { switch(writeState) { default: case RW_STATE_LSB: nullCount = true; loadCount(0xff & data); break; case RW_STATE_MSB: nullCount = true; loadCount((0xff & data) << 8); break; case RW_STATE_WORD: //null count setting is delayed until after second byte is written inputLatch = data; writeState = RW_STATE_WORD_2; break; case RW_STATE_WORD_2: nullCount = true; loadCount((0xff & inputLatch) | ((0xff & data) << 8)); writeState = RW_STATE_WORD; break; } } public void writeControlWord(int data) { int access = (data >>> 4) & 3; if (access == 0) { latchCount(); //counter latch command } else { nullCount = true; rwMode = access; readState = access; writeState = access; mode = (data >>> 1) & 7; bcd = (data & 1); /* XXX: update irq timer ? */ } } public void setGate(boolean value) { switch(mode) { default: case MODE_INTERRUPT_ON_TERMINAL_COUNT: case MODE_SOFTWARE_TRIGGERED_STROBE: /* XXX: just disable/enable counting */ break; case MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT: case MODE_HARDWARE_TRIGGERED_STROBE: if (!gate && value) { /* restart counting on rising edge */ countStartTime = IntervalTimer.this.getTimingSource().getTime(); irqTimerUpdate(countStartTime); } break; case MODE_RATE_GENERATOR: case MODE_SQUARE_WAVE: if (!gate && value) { /* restart counting on rising edge */ countStartTime = IntervalTimer.this.getTimingSource().getTime(); irqTimerUpdate(countStartTime); } /* XXX: disable/enable counting */ break; } this.gate = value; } private int getCount() { long now = scale64(IntervalTimer.this.getTimingSource().getTime() - countStartTime, PIT_FREQ, (int)IntervalTimer.this.getTimingSource().getTickRate()); switch(mode) { case MODE_INTERRUPT_ON_TERMINAL_COUNT: case MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT: case MODE_SOFTWARE_TRIGGERED_STROBE: case MODE_HARDWARE_TRIGGERED_STROBE: return (int)((countValue - now) & 0xffffl); case MODE_SQUARE_WAVE: return (int)(countValue - ((2 * now) % countValue)); case MODE_RATE_GENERATOR: default: return (int)(countValue - (now % countValue)); } } private int getOut(long currentTime) { long now = scale64(currentTime - countStartTime, PIT_FREQ, (int)IntervalTimer.this.getTimingSource().getTickRate()); switch(mode) { default: case MODE_INTERRUPT_ON_TERMINAL_COUNT: if (now >= countValue) return 1; else return 0; case MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT: if (now < countValue) return 1; else return 0; case MODE_RATE_GENERATOR: if (((now % countValue) == 0) && (now != 0)) { return 1; } else return 0; case MODE_SQUARE_WAVE: if ((now % countValue) < ((countValue + 1) >>> 1)) return 1; else return 0; case MODE_SOFTWARE_TRIGGERED_STROBE: case MODE_HARDWARE_TRIGGERED_STROBE: if (now == countValue) return 1; else return 0; } } private long getNextTransitionTime(long currentTime) { long nextTime; long now = scale64(currentTime - countStartTime, PIT_FREQ, (int)IntervalTimer.this.getTimingSource().getTickRate()); switch(mode) { default: case MODE_INTERRUPT_ON_TERMINAL_COUNT: case MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT: { if (now < countValue) nextTime = countValue; else return -1; } break; case MODE_RATE_GENERATOR: { long base = (now / countValue) * countValue; if ((now - base) == 0 && now != 0) nextTime = base + countValue; else nextTime = base + countValue + 1; } break; case MODE_SQUARE_WAVE: { long base = (now / countValue) * countValue; long period2 = ((countValue + 1) >>> 1); if ((now - base) < period2) nextTime = base + period2; else nextTime = base + countValue; } break; case MODE_SOFTWARE_TRIGGERED_STROBE: case MODE_HARDWARE_TRIGGERED_STROBE: { if (now < countValue) nextTime = countValue; else if (now == countValue) nextTime = countValue + 1; else return -1; } break; } /* convert to timer units */ nextTime = countStartTime + scale64(nextTime, (int)IntervalTimer.this.getTimingSource().getTickRate(), PIT_FREQ); /* fix potential rounding problems */ /* XXX: better solution: use a clock at PIT_FREQ Hz */ if (nextTime <= currentTime) nextTime = currentTime + 1; return nextTime; } private void loadCount(int value) { nullCount = false; if (value == 0) value = 0x10000; countStartTime = IntervalTimer.this.getTimingSource().getTime(); countValue = value; this.irqTimerUpdate(countStartTime); } private void irqTimerUpdate(long currentTime) { if (irqTimer == null) return; long expireTime = this.getNextTransitionTime(currentTime); int irqLevel = this.getOut(currentTime); IntervalTimer.this.getInterruptController().setIRQ(irq, irqLevel); nextTransitionTimeValue = expireTime; if (expireTime != -1) irqTimer.setExpiry(expireTime); else irqTimer.setStatus(false); } public void timerCallback() { this.irqTimerUpdate(nextTransitionTimeValue); } public void reset(int i) { mode = MODE_SQUARE_WAVE; gate = (i != 2); loadCount(0); nullCount = true; } private void setIRQTimer(Timer object) { irqTimer = object; } public void setIRQ(int irq) { this.irq = irq; } public boolean initialised() {return true;} public void acceptComponent(HardwareComponent component){} public void reset(){} } public boolean initialised() { return ((irqDevice != null) && (timingSource != null)) && ioportRegistered; } public boolean updated() { return (irqDevice.updated() && timingSource.updated()) && ioportRegistered; } public void updateComponent(HardwareComponent component) { if (component instanceof IOPortHandler) { ((IOPortHandler)component).registerIOPortCapable(this); ioportRegistered = true; } if (this.updated() && !madeNewTimer) { channels[0].setIRQTimer(timingSource.newTimer(channels[0])); madeNewTimer = true; } } public void acceptComponent(HardwareComponent component) { if ((component instanceof InterruptController) && component.initialised()) irqDevice = (InterruptController)component; if ((component instanceof Clock) && component.initialised()) timingSource = (Clock)component; if ((component instanceof IOPortHandler) && component.initialised()) { ((IOPortHandler)component).registerIOPortCapable(this); ioportRegistered = true; } if (this.initialised() && (channels == null)) { channels = new TimerChannel[3]; for (int i = 0; i < channels.length; i++) { channels[i] = new TimerChannel(i); } channels[0].setIRQTimer(timingSource.newTimer(channels[0])); channels[0].setIRQ(irq); } } public void timerCallback() {} public String toString() { return "Intel i8254 Interval Timer"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -