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

📄 rtc.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.peripheral.*;import org.jpc.support.*;import java.util.Calendar;import org.jpc.emulator.*;import java.io.*;/** * MC146818 RealTime Clock emulation */public class RTC extends AbstractHardwareComponent implements IOPortCapable{    private static final int RTC_SECONDS = 0;    private static final int RTC_SECONDS_ALARM = 1;    private static final int RTC_MINUTES = 2;    private static final int RTC_MINUTES_ALARM = 3;    private static final int RTC_HOURS = 4;    private static final int RTC_HOURS_ALARM = 5;    private static final int RTC_ALARM_DONT_CARE = 0xc0;    private static final int RTC_DAY_OF_WEEK = 6;    private static final int RTC_DAY_OF_MONTH = 7;    private static final int RTC_MONTH = 8;    private static final int RTC_YEAR = 9;    private static final int RTC_REG_EQUIPMENT_BYTE = 0x14;    private static final int RTC_REG_IBM_CENTURY_BYTE = 0x32;    private static final int RTC_REG_IBM_PS2_CENTURY_BYTE = 0x37;    private static final int RTC_REG_A = 10;    private static final int RTC_REG_B = 11;    private static final int RTC_REG_C = 12;    private static final int RTC_REG_D = 13;    private static final int REG_A_UIP = 0x80;    private static final int REG_B_SET = 0x80;    private static final int REG_B_PIE = 0x40;    private static final int REG_B_AIE = 0x20;    private static final int REG_B_UIE = 0x10;    private byte[] cmosData; //rowa    private byte cmosIndex; //rw    private int irq; //r    private Calendar currentTime; //rw    /* periodic timer */    private Timer periodicTimer;    private long nextPeriodicTime; //rw    /* second update */    private Timer secondTimer;    private Timer delayedSecondTimer;    private long nextSecondTime; //ri    private PeriodicCallback periodicCallback;    private SecondCallback secondCallback;    private DelayedSecondCallback delayedSecondCallback;    private InterruptController irqDevice;    private Clock timeSource;    private int ioPortBase, bootType;    private boolean ioportRegistered;    private boolean drivesInited;    private boolean floppiesInited;    public RTC(int ioPort, int irq)    {        bootType = -1;	ioportRegistered = false;	drivesInited = false;	floppiesInited = false;	ioPortBase = ioPort;	this.irq = irq;	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 void dumpState(DataOutput output) throws IOException    {        output.writeInt(cmosData.length);        output.write(cmosData);        output.writeByte(cmosIndex);        output.writeInt(irq);        //calendar        output.writeLong(nextSecondTime);        output.writeInt(ioPortBase);        output.writeInt(bootType);        output.writeBoolean(ioportRegistered);        output.writeBoolean(drivesInited);        output.writeBoolean(floppiesInited);        //timers        periodicTimer.dumpState(output);        secondTimer.dumpState(output);        delayedSecondTimer.dumpState(output);    }    public void loadState(DataInput input) throws IOException    {        ioportRegistered = false;        int len = input.readInt();        input.readFully(cmosData,0,len);        cmosIndex = input.readByte();        irq = input.readInt();        //calendar        nextSecondTime = input.readLong();        ioPortBase = input.readInt();        bootType = input.readInt();        ioportRegistered = input.readBoolean();        drivesInited = input.readBoolean();        floppiesInited = input.readBoolean();        //timers        periodicTimer = timeSource.newTimer(periodicCallback);        secondTimer = timeSource.newTimer(secondCallback);        delayedSecondTimer = timeSource.newTimer(delayedSecondCallback);        periodicTimer.loadState(input);        secondTimer.loadState(input);        delayedSecondTimer.loadState(input);    }    static final long scale64(long input, int multiply, int divide)    {	//return (BigInteger.valueOf(input).multiply(BigInteger.valueOf(multiply)).divide(BigInteger.valueOf(divide))).longValue();	long rl = (0xffffffffl & input) * multiply;	long rh = (input >>> 32) * multiply;		rh += (rl >> 32);		long resultHigh = 0xffffffffl & (rh / divide);	long resultLow = 0xffffffffl & ((((rh % divide) << 32) + (rl & 0xffffffffl)) / divide);		return (resultHigh << 32) | resultLow;    }        public void init()    {	Calendar now = Calendar.getInstance();	this.setTime(now);	int val = this.toBCD(now.get(Calendar.YEAR) / 100);	cmosData[RTC_REG_IBM_CENTURY_BYTE] = (byte)val;	cmosData[RTC_REG_IBM_PS2_CENTURY_BYTE] = (byte)val;		/* memory size */	val = 640; /* base memory in K */	cmosData[0x15] = (byte)val;	cmosData[0x16] = (byte)(val >>> 8);		int ramSize = PC.SYS_RAM_SIZE;	val = (ramSize / 1024) - 1024;	if (val > 65535) val = 65535;	cmosData[0x17] = (byte)val;	cmosData[0x18] = (byte)(val >>> 8);	cmosData[0x30] = (byte)val;	cmosData[0x31] = (byte)(val >>> 8);	if (ramSize > (16 * 1024 * 1024)) {	    val = (ramSize / 65536) - ((16 * 1024 * 1024) / 65536);	} else {	    val = 0;	}	if (val > 65535) val = 65535;	cmosData[0x34] = (byte)val;	cmosData[0x35] = (byte)(val >>> 8);	switch(bootType)         {	case DriveSet.FLOPPY_BOOT:	    cmosData[0x3d] = (byte)0x01; /* floppy boot */	    break;	default:	case DriveSet.HARD_DRIVE_BOOT:	    cmosData[0x3d] = (byte)0x02; /* hard drive boot */	    break;	case DriveSet.CD_BOOT:	    cmosData[0x3d] = (byte)0x03; /* CD-ROM boot */	    break;	}    }        public void cmosInitHD(DriveSet drives)    {	BlockDevice drive0 = drives.getHardDrive(0);	BlockDevice drive1 = drives.getHardDrive(1);	cmosData[0x12] = (byte)(((drive0 != null) ? 0xf0 : 0) | ((drive1 != null) ? 0x0f : 0));	if (drive0 != null) {	    cmosData[0x19] = (byte)47;	    cmosData[0x1b] = (byte)drive0.cylinders();	    cmosData[0x1b + 1] = (byte)(drive0.cylinders() >>> 8);	    cmosData[0x1b + 2] = (byte)drive0.heads();	    cmosData[0x1b + 3] = (byte)0xff;	    cmosData[0x1b + 4] = (byte)0xff;	    cmosData[0x1b + 5] = (byte)(0xc0 | ((drive0.heads() > 8) ? 0x8 : 0));	    cmosData[0x1b + 6] = (byte)drive0.cylinders();	    cmosData[0x1b + 7] = (byte)(drive0.cylinders() >>> 8);	    cmosData[0x1b + 8] = (byte)drive0.sectors();	}	if (drive1 != null) {	    cmosData[0x1a] = (byte)47;	    cmosData[0x24] = (byte)drive1.cylinders();	    cmosData[0x24 + 1] = (byte)(drive1.cylinders() >>> 8);	    cmosData[0x24 + 2] = (byte)drive1.heads();	    cmosData[0x24 + 3] = (byte)0xff;	    cmosData[0x24 + 4] = (byte)0xff;	    cmosData[0x24 + 5] = (byte)(0xc0 | ((drive1.heads() > 8) ? 0x8 : 0));	    cmosData[0x24 + 6] = (byte)drive1.cylinders();	    cmosData[0x24 + 7] = (byte)(drive1.cylinders() >>> 8);	    cmosData[0x24 + 8] = (byte)drive1.sectors();	}	int value = 0;	for (int i = 0; i < 4; i++) {	    if (drives.getHardDrive(i) != null) {		int translation;		if ((drives.getHardDrive(i).cylinders() <= 1024) &&		    (drives.getHardDrive(i).heads() <= 16) &&		    (drives.getHardDrive(i).sectors() <= 63)) {		    /* No Translation. */		    translation = 0;		} else {		    /* LBA Translation */		    translation = 1;		}		value |= translation << (i * 2);	    }	}	cmosData[0x39] = (byte)value;    }    public void cmosInitFloppy(FloppyController fdc)    {	int val = (cmosGetFDType(fdc, 0) << 4) | cmosGetFDType(fdc, 1);	cmosData[0x10] = (byte)val;	int num = 0;	val = 0;	if (fdc.getDriveType(0) < 3)	    num++;	if (fdc.getDriveType(1) < 3)	    num++;	switch (num) {	case 0:	    break;	case 1:	    val |= 0x01;	    break;	case 2:	    val |= 0x41;	    break;	}	val |= 0x02; // Have FPU	val |= 0x04; // Have PS2 Mouse	cmosData[RTC_REG_EQUIPMENT_BYTE] = (byte)val;    }    private int cmosGetFDType(FloppyController fdc, int drive)    {	switch (fdc.getDriveType(drive)) {	case 0:	    return 4;	case 1:	    return 5;	case 2:	    return 2;	default:	    return 0;	}    }    public int[] ioPortsRequested()    {	int base = ioPortBase;	return new int[]{base, base+1};    }    public int ioPortReadByte(int address)    {	return 0xff & cmosIOPortRead(address);    }    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)    {	cmosIOPortWrite(address, 0xff & data);    }    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);    }    private class PeriodicCallback extends AbstractHardwareComponent    {	public void timerCallback()

⌨️ 快捷键说明

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