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

📄 idechannel.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*    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.pci.peripheral;import org.jpc.emulator.motherboard.*;import org.jpc.support.*;import org.jpc.emulator.*;import java.io.*;public class IDEChannel implements IOPortCapable{    private IDEState[] devices;    private IDEState currentDevice;    private int ioBase, ioBaseTwo, irq;    private InterruptController irqDevice;    private int nextDriveSerial;    public void dumpState(DataOutput output) throws IOException    {        output.writeInt(ioBase);        output.writeInt(ioBaseTwo);        output.writeInt(irq);        output.writeInt(nextDriveSerial);        for (int i = 0; i < devices.length; i++)            devices[i].dumpState(output);        int currentDeviceIndex = -1;        for (int i=0; i< devices.length; i++)            if (currentDevice == devices[i])                currentDeviceIndex = i;        output.writeInt(currentDeviceIndex);    }    public void loadState(DataInput input) throws IOException    {        ioBase = input.readInt();        ioBaseTwo = input.readInt();        irq = input.readInt();        nextDriveSerial = input.readInt();        for (int i = 0; i < devices.length; i++)        {            devices[i].loadState(input);        }        int currentDeviceIndex = input.readInt();        currentDevice = devices[currentDeviceIndex];    }    public void reset() {}    public boolean initialised() {return true;}    public boolean updated() {return true;}        public void updateComponent(org.jpc.emulator.HardwareComponent component) {}    public void acceptComponent(org.jpc.emulator.HardwareComponent component) {}    private static void shortToBigEndianBytes(byte[] buffer, int offset, short val)    {	buffer[offset + 0] = (byte)(val >> 8);	buffer[offset + 1] = (byte)(val);    }        private static void intToBigEndianBytes(byte[] buffer, int offset, int val)    {	buffer[offset + 0] = (byte)(val >> 24);	buffer[offset + 1] = (byte)(val >> 16);	buffer[offset + 2] = (byte)(val >> 8);	buffer[offset + 3] = (byte)(val);    }        private static int bigEndianBytesToInt(byte[] buffer, int offset)    {	int val = 0;	val |= ((buffer[offset + 0] << 24) & 0xff000000);	val |= ((buffer[offset + 1] << 16) & 0x00ff0000);	val |= ((buffer[offset + 2] << 8)  & 0x0000ff00);	val |= ((buffer[offset + 3] << 0)  & 0x000000ff);	return val;    }    private static short bigEndianBytesToShort(byte[] buffer, int offset)    {	short val = 0;	val |= ((buffer[offset + 0] << 8) & 0xff00);	val |= ((buffer[offset + 1] << 0) & 0x00ff);	return val;    }    private static void lbaToMSF(byte[] buffer, int offset, int lba)    {	lba += 150;	buffer[offset + 0] = (byte)((lba / 75) / 60);	buffer[offset + 1] = (byte)((lba / 75) % 60);	buffer[offset + 2] = (byte)(lba % 75);    }    private static void putLE16InByte(byte[] dest, int offset, int data)    {	dest[offset + 0] = (byte)data;	dest[offset + 1] = (byte)(data >>> 8);    }        private static void stringToBytes(String text, byte[] dest, int start, int length)    {	    byte[] temp = text.getBytes();	    int i = 0;	    for (; i < Math.min(temp.length, length); i++)		dest[(start + i) ^ 1] = temp[i];	    for (; i < length; i++)		dest[(start + i) ^ 1] = 0x20;    }    public IDEChannel() {}    public IDEChannel(int irq, InterruptController irqDevice, int ioBase, int ioBaseTwo, BlockDevice[] drives, BMDMAIORegion bmdma)    {	this.irq = irq;	this.irqDevice = irqDevice;	this.ioBase = ioBase;	this.ioBaseTwo = ioBaseTwo;	this.nextDriveSerial = 1;	devices = new IDEState[2];	devices[0] = new IDEState(drives[0]); // master	devices[1] = new IDEState(drives[1]); // slave	devices[0].bmdma = bmdma;	devices[1].bmdma = bmdma;	this.currentDevice = devices[0];    }    public void setDrives(BlockDevice[] drives)    {        devices[0].setDrive(drives[0]);        devices[1].setDrive(drives[1]);    }    public void ioPortWriteByte(int address, int data)    {	if (address == ioBaseTwo) {	    this.writeCommand(data);	    return;	} else {	    this.writeIDE(address, data);	    return;	}    }    public void ioPortWriteWord(int address, int data)    {	switch(address - ioBase) {	case 0:	case 1:	    this.writeDataWord(address, data);	    break;	default:	    this.ioPortWriteByte(address, data);	    this.ioPortWriteByte(address + 1, data >>> 8);	    break;	}    }    public void ioPortWriteLong(int address, int data)    {	switch(address - ioBase) {	case 0:	case 1:	case 2:	case 3:	    this.writeDataLong(address, data);	    break;	default:	    this.ioPortWriteWord(address, data);	    this.ioPortWriteWord(address + 2, data >>> 16);	    break;	}    }    public int ioPortReadByte(int address)    {	if (address == ioBaseTwo) {	    return this.readStatus();	} else {	    return this.readIDE(address);	}    }    public int ioPortReadWord(int address)    {	switch(address - ioBase) {	case 0:	case 1:	    return this.readDataWord(address);	default:	    return (0xff & ioPortReadByte(address)) | 		(0xff00 & (ioPortReadByte(address + 1) << 8));	}    }    public int ioPortReadLong(int address)    {	switch (address - ioBase) {	case 0:	case 1:	case 2:	case 3:	    return this.readDataLong(address);	default:	    return (0xffff & ioPortReadWord(address)) | 		(0xffff0000 & (ioPortReadWord(address + 2) << 16));	}    }    public int[] ioPortsRequested()    {	if (ioBaseTwo == 0)	    return new int[]{ioBase, ioBase + 1,				 ioBase + 2, ioBase + 3,				 ioBase + 4, ioBase + 5,				 ioBase + 6, ioBase + 7};	else	    return new int[]{ioBase, ioBase + 1,				 ioBase + 2, ioBase + 3,				 ioBase + 4, ioBase + 5,				 ioBase + 6, ioBase + 7,				 ioBaseTwo};    }    private void writeCommand(int data)    {	/* common for both drives */	if (((devices[0].command & IDEState.IDE_CMD_RESET) == 0) &&	    ((data & IDEState.IDE_CMD_RESET) != 0)) {	    /* reset low to high */	    devices[0].status = (byte)(IDEState.BUSY_STAT | IDEState.SEEK_STAT);	    devices[0].error = 0x01;	    devices[1].status = (byte)(IDEState.BUSY_STAT | IDEState.SEEK_STAT);	    devices[1].error = 0x01;	} else if (((devices[0].command & IDEState.IDE_CMD_RESET) != 0) &&	    ((data & IDEState.IDE_CMD_RESET) == 0)) {	    /* reset high to low */	    for (int i = 0; i < 2; i++) {		if (devices[i].isCDROM)		    devices[i].status = 0x00; /* NOTE: READY is not set */		else		    devices[i].status = (byte)(IDEState.READY_STAT | IDEState.SEEK_STAT);		devices[i].setSignature();	    }	}	devices[0].command = (byte)data;	devices[1].command = (byte)data;    }    private int readStatus()    {	if (((devices[0].drive == null) && (devices[1].drive == null)) ||	    ((currentDevice != devices[0]) && (currentDevice.drive == null))) {	    return 0;	} else {	    return currentDevice.status;	}    }    private void writeIDE(int address, int data)    {	boolean lba48 = false;	address &= 7;	switch (address) {	case 0:	    break;	case 1:	    clearHob();	    /* NOTE: data is written to the two drives */	    devices[0].hobFeature = devices[0].feature;	    devices[1].hobFeature = devices[1].feature;	    devices[0].feature = (byte)data;	    devices[1].feature = (byte)data;	    break;	case 2:	    clearHob();	    devices[0].hobNSector = (byte)devices[0].nSector;	    devices[1].hobNSector = (byte)devices[1].nSector;	    devices[0].nSector = 0xff & data;	    devices[1].nSector = 0xff & data;	    break;	case 3:	    clearHob();	    devices[0].hobSector = devices[0].sector;	    devices[1].hobSector = devices[1].sector;	    devices[0].sector = (byte)data;	    devices[1].sector = (byte)data;	    break;	case 4:	    clearHob();	    devices[0].hobLCyl = devices[0].lcyl;	    devices[1].hobLCyl = devices[1].lcyl;	    devices[0].lcyl = (byte)data;	    devices[1].lcyl = (byte)data;	    break;	case 5:	    clearHob();	    devices[0].hobHCyl = devices[0].hcyl;	    devices[1].hobHCyl = devices[1].hcyl;	    devices[0].hcyl = (byte)data;	    devices[1].hcyl = (byte)data;	    break;	case 6:	    // FIXME: HOB readback uses bit 7	    devices[0].select = (byte)((data & ~0x10) | 0xa0);	    devices[1].select = (byte)(data | 0x10 | 0xa0);	    /* select drive */	    currentDevice = devices[(data >> 4) & 1];	    break;	default:	case 7:	    /* ignore commands to non existant slave */	    if (currentDevice != devices[0] && currentDevice.drive == null) 		break;	    switch(data) {	    case IDEState.WIN_IDENTIFY:		if ((currentDevice.drive != null) && !currentDevice.isCDROM) {		    currentDevice.identify();		    currentDevice.status = (byte)(IDEState.READY_STAT | IDEState.SEEK_STAT);		    currentDevice.transferStart(currentDevice.ioBuffer, 0, 512, IDEState.ETF_TRANSFER_STOP);		} else {		    if (currentDevice.isCDROM) {			currentDevice.setSignature();		    }		    currentDevice.abortCommand();		}		currentDevice.setIRQ();		break;	    case IDEState.WIN_SPECIFY:	    case IDEState.WIN_RECAL:		currentDevice.error = 0;		currentDevice.status = (byte)(IDEState.READY_STAT | IDEState.SEEK_STAT);		currentDevice.setIRQ();		break;	    case IDEState.WIN_SETMULT:		if (currentDevice.nSector > IDEState.MAX_MULT_SECTORS || 		    currentDevice.nSector == 0 ||		    (currentDevice.nSector & (currentDevice.nSector - 1)) != 0) {		    currentDevice.abortCommand();		} else {		    currentDevice.multSectors = currentDevice.nSector;		    currentDevice.status = IDEState.READY_STAT;		}		currentDevice.setIRQ();		break;	    case IDEState.WIN_VERIFY_EXT:		lba48 = true;	    case IDEState.WIN_VERIFY:	    case IDEState.WIN_VERIFY_ONCE:		currentDevice.commandLBA48Transform(lba48);		/* do sector number check ? */		currentDevice.status = IDEState.READY_STAT;		currentDevice.setIRQ();		break;	    case IDEState.WIN_READ_EXT:		lba48 = true;	    case IDEState.WIN_READ:	    case IDEState.WIN_READ_ONCE:		if (currentDevice.drive == null) {

⌨️ 快捷键说明

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