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

📄 rtc.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	{	    RTC.this.periodicUpdate();	}        public boolean initialised() {return true;}        public void acceptComponent(HardwareComponent component){}        public void reset(){}        public void dumpState(DataOutput output) throws IOException {}        public void loadState(DataInput input) throws IOException {}    }    private class SecondCallback extends AbstractHardwareComponent    {	public void timerCallback()	{	    RTC.this.secondUpdate();	}        public boolean initialised() {return true;}        public void acceptComponent(HardwareComponent component){}        public void reset(){}        public void dumpState(DataOutput output) throws IOException {}        public void loadState(DataInput input) throws IOException {}    }    private class DelayedSecondCallback extends AbstractHardwareComponent    {	public void timerCallback()	{	    RTC.this.delayedSecondUpdate();	}        public boolean initialised() {return true;}        public void acceptComponent(HardwareComponent component){}        public void reset(){}        public void dumpState(DataOutput output) throws IOException {}        public void loadState(DataInput input) throws IOException {}    }    private void periodicUpdate()    {	this.timerUpdate(nextPeriodicTime);	cmosData[RTC_REG_C] |= 0xc0;	irqDevice.setIRQ(irq, 1);    }    private void secondUpdate()    {	if ((cmosData[RTC_REG_A] & 0x70) != 0x20) {	    nextSecondTime += timeSource.getTickRate();	    secondTimer.setExpiry(nextSecondTime);	} else {	    this.nextSecond();	    	    if (0 == (cmosData[RTC_REG_B] & REG_B_SET)) /* update in progress bit */		cmosData[RTC_REG_A] |= REG_A_UIP;	    /* should be 244us = 8 / 32768 second, but currently the timers do not have the necessary resolution. */	    long delay = (timeSource.getTickRate() * 1) / 100;	    if (delay < 1)		delay = 1;	    delayedSecondTimer.setExpiry(nextSecondTime + delay);	}    }    private void delayedSecondUpdate()    {	if (0 == (cmosData[RTC_REG_B] & REG_B_SET))	    this.timeToMemory();		/* check alarm */	if (0 != (cmosData[RTC_REG_B] & REG_B_AIE)) {	    if (((cmosData[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||		 cmosData[RTC_SECONDS_ALARM] == currentTime.get(Calendar.SECOND)) &&		((cmosData[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 || 		 cmosData[RTC_MINUTES_ALARM] == currentTime.get(Calendar.MINUTE)) &&		((cmosData[RTC_HOURS_ALARM] & 0xc0) == 0xc0 || 		 cmosData[RTC_HOURS_ALARM] == currentTime.get(Calendar.HOUR_OF_DAY))) {				cmosData[RTC_REG_C] |= 0xa0;		irqDevice.setIRQ(irq, 1);	    }	}		/* update ended interrupt */	if (0 != (cmosData[RTC_REG_B] & REG_B_UIE)) {	    cmosData[RTC_REG_C] |= 0x90;	    irqDevice.setIRQ(irq, 1);	}		/* clear update in progress bit */	cmosData[RTC_REG_A] &= ~REG_A_UIP;	nextSecondTime += timeSource.getTickRate();        secondTimer.setExpiry(nextSecondTime);    }    private void timerUpdate(long currentTime)    {	int periodCode = cmosData[RTC_REG_A] & 0x0f;	if ((periodCode != 0) && (0 != (cmosData[RTC_REG_B] & REG_B_PIE)))         {	    if (periodCode <= 2)		periodCode += 7;	    /* period in 32 kHz cycles */	    int period = 1 << (periodCode -1);	    /* compute 32 kHz clock */	    long currentClock = scale64(currentTime, 32768, (int)timeSource.getTickRate());	    long nextIRQClock = (currentClock & ~(period - 1)) + period;	    nextPeriodicTime = scale64(nextIRQClock, (int)timeSource.getTickRate(), 32768) + 1;	    periodicTimer.setExpiry(nextPeriodicTime);	}         else	    periodicTimer.setStatus(false);    }    private void nextSecond()    {        //currentTime = Calendar.getInstance();	currentTime.add(Calendar.SECOND,1);    }    private void cmosIOPortWrite(int address, int data)    {	if ((address & 1) == 0) {            cmosIndex = (byte)(data & 0x7f);	} else {	    switch(this.cmosIndex) {	    case RTC_SECONDS_ALARM:	    case RTC_MINUTES_ALARM:	    case RTC_HOURS_ALARM:		/* XXX: not supported */		cmosData[this.cmosIndex] = (byte)data;		break;	    case RTC_SECONDS:	    case RTC_MINUTES:	    case RTC_HOURS:	    case RTC_DAY_OF_WEEK:	    case RTC_DAY_OF_MONTH:	    case RTC_MONTH:	    case RTC_YEAR:		cmosData[this.cmosIndex] = (byte)data;		/* if in set mode, do not update the time */		if (0 == (cmosData[RTC_REG_B] & REG_B_SET)) 		    this.memoryToTime();		break;	    case RTC_REG_A:		/* UIP bit is read only */		cmosData[RTC_REG_A] = (byte)((data & ~REG_A_UIP) | (cmosData[RTC_REG_A] & REG_A_UIP));		this.timerUpdate(timeSource.getTime());		break;	    case RTC_REG_B:		if (0 != (data & REG_B_SET)) {		    /* set mode: reset UIP mode */		    cmosData[RTC_REG_A] &= ~REG_A_UIP;		    data &= ~REG_B_UIE;		} else {		    /* if disabling set mode, update the time */		    if (0 != (cmosData[RTC_REG_B] & REG_B_SET))			this.memoryToTime();		}		cmosData[RTC_REG_B] = (byte)data;		this.timerUpdate(timeSource.getTime());		break;	    case RTC_REG_C:	    case RTC_REG_D:		/* cannot write to them */		break;	    default:		cmosData[this.cmosIndex] = (byte)data;		break;	    }	}    }        private int cmosIOPortRead(int address)    {	if ((address & 1) == 0)	    return 0xff;        else {	    switch(this.cmosIndex)  {	    case RTC_SECONDS:	    case RTC_MINUTES:	    case RTC_HOURS:	    case RTC_DAY_OF_WEEK:	    case RTC_DAY_OF_MONTH:	    case RTC_MONTH:	    case RTC_YEAR:		return cmosData[this.cmosIndex];	    case RTC_REG_A:		return cmosData[this.cmosIndex];	    case RTC_REG_C:		int ret = cmosData[this.cmosIndex];		irqDevice.setIRQ(irq, 0);		cmosData[RTC_REG_C] = (byte)0x00;		return ret;	    default:		return cmosData[this.cmosIndex];	    }	}    }        private void setTime(Calendar date)    {	this.currentTime = Calendar.getInstance(date.getTimeZone());        this.currentTime.setTime(date.getTime());	this.timeToMemory();    }        private void memoryToTime()    {	currentTime.set(Calendar.SECOND, this.fromBCD(cmosData[RTC_SECONDS]));	currentTime.set(Calendar.MINUTE, this.fromBCD(cmosData[RTC_MINUTES]));	currentTime.set(Calendar.HOUR_OF_DAY, this.fromBCD(cmosData[RTC_HOURS] & 0x7f));	if (0 == (cmosData[RTC_REG_B] & 0x02) && 0 != (cmosData[RTC_HOURS] & 0x80))	    currentTime.add(Calendar.HOUR_OF_DAY, 12);		currentTime.set(Calendar.DAY_OF_WEEK, this.fromBCD(cmosData[RTC_DAY_OF_WEEK]));	currentTime.set(Calendar.DAY_OF_MONTH, this.fromBCD(cmosData[RTC_DAY_OF_MONTH]));	currentTime.set(Calendar.MONTH, this.fromBCD(cmosData[RTC_MONTH]) - 1);	currentTime.set(Calendar.YEAR, this.fromBCD(cmosData[RTC_YEAR]) + 2000); //is this offset correct?    }        private void timeToMemory()    {	cmosData[RTC_SECONDS] = (byte)this.toBCD(currentTime.get(Calendar.SECOND));	cmosData[RTC_MINUTES] = (byte)this.toBCD(currentTime.get(Calendar.MINUTE));		if (0 != (cmosData[RTC_REG_B] & 0x02)) /* 24 hour format */	    cmosData[RTC_HOURS] = (byte)this.toBCD(currentTime.get(Calendar.HOUR_OF_DAY));	else { /* 12 hour format */	    cmosData[RTC_HOURS] = (byte)this.toBCD(currentTime.get(Calendar.HOUR));	    if(currentTime.get(Calendar.AM_PM) == Calendar.PM)		cmosData[RTC_HOURS] |= 0x80;	}		cmosData[RTC_DAY_OF_WEEK] = (byte)this.toBCD(currentTime.get(Calendar.DAY_OF_WEEK));	cmosData[RTC_DAY_OF_MONTH] = (byte)this.toBCD(currentTime.get(Calendar.DAY_OF_MONTH));	cmosData[RTC_MONTH] = (byte)this.toBCD(currentTime.get(Calendar.MONTH) + 1);	cmosData[RTC_YEAR] = (byte)this.toBCD(currentTime.get(Calendar.YEAR) % 100);    }    private int toBCD(int a) //Binary Coded Decimal    {	if (0 != (cmosData[RTC_REG_B] & 0x04)) 	    return a;        else	    return ((a / 10) << 4) | (a % 10);    }    private int fromBCD(int a) //Binary Coded Decimal    {	if (0 != (cmosData[RTC_REG_B] & 0x04))	    return a;	else 	    return ((a >> 4) * 10) + (a & 0x0f);    }        public boolean initialised()    {	return ((irqDevice != null) && (timeSource != null) && ioportRegistered && drivesInited && floppiesInited && (bootType >= 0));    }        public void reset()    {	irqDevice = null;	timeSource = null;	ioportRegistered = false;	drivesInited = false;	floppiesInited = false;	bootType = -1;	cmosData = new byte[128];	cmosData[RTC_REG_A] = 0x26;	cmosData[RTC_REG_B] = 0x02;	cmosData[RTC_REG_C] = 0x00;	cmosData[RTC_REG_D] = (byte)0x80;	periodicCallback = new PeriodicCallback();	secondCallback = new SecondCallback();	delayedSecondCallback = new DelayedSecondCallback();    }    public boolean updated()    {	return (irqDevice.updated() && timeSource.updated() && ioportRegistered);    }    public void updateComponent(HardwareComponent component)    {	if ((component instanceof IOPortHandler) && component.updated())         {	    ((IOPortHandler)component).registerIOPortCapable(this);	    ioportRegistered = true;	}    }    public void acceptComponent(HardwareComponent component)    {	if ((component instanceof InterruptController)	    && component.initialised())	    irqDevice = (InterruptController)component;	if ((component instanceof Clock)	    && component.initialised())	    timeSource = (Clock)component;	if ((component instanceof IOPortHandler)	    && component.initialised()) {	    ((IOPortHandler)component).registerIOPortCapable(this);	    ioportRegistered = true;	}	if ((component instanceof DriveSet)	    && component.initialised()) {	    this.cmosInitHD((DriveSet)component);	    drivesInited = true;	}	if ((component instanceof FloppyController)	    && component.initialised()) {	    this.cmosInitFloppy((FloppyController)component);	    floppiesInited = true;	}        if (component instanceof DriveSet)            bootType = ((DriveSet) component).getBootType();	if (this.initialised())         {            init();	    periodicTimer = timeSource.newTimer(periodicCallback);	    secondTimer = timeSource.newTimer(secondCallback);	    delayedSecondTimer = timeSource.newTimer(delayedSecondCallback);	    	    nextSecondTime = timeSource.getTime() + (99 * timeSource.getTickRate())/100;	    delayedSecondTimer.setExpiry(nextSecondTime);	}    }    public String toString()    {	return "MC146818 RealTime Clock";    }}

⌨️ 快捷键说明

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