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

📄 floppycontroller.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	/* IO based transfer: calculate len */	raiseIRQ(0x00);	return;    }    private void stopTransfer(byte status0, byte status1, byte status2)    {	FloppyDrive drive = getCurrentDrive();		fifo[0] = (byte)(status0 | (drive.head << 2) | currentDrive);	fifo[1] = status1;	fifo[2] = status2;	fifo[3] = (byte)drive.track;	fifo[4] = (byte)drive.head;	fifo[5] = (byte)drive.sector;	fifo[6] = SECTOR_SIZE_CODE;	dataDirection = DIRECTION_READ;	if ((state & CONTROL_BUSY) != 0) {	    dma.releaseDREQ(DMA_CHANNEL & 3);	    state &= ~CONTROL_BUSY;	}	setFIFO(7, true);    }    private void startTransferDelete(int direction)    {	stopTransfer((byte)0x60, (byte)0x00, (byte)0x00);    }    private void formatSector()    {	System.err.println("Cannot Format Sector");    }    private static int memcmp(byte[] a1, byte[] a2, int offset, int length)    {	for (int i = 0; i < length; i++) {	    if (a1[i] != a2[i + offset])		return a1[i] - a2[i + offset];	}	return 0;    }	       public int transferHandler(int nchan, int pos, int size)    {	byte status0 = 0x00, status1 = 0x00, status2 = 0x00;		if ((state & CONTROL_BUSY) == 0)	    return 0;	FloppyDrive drive = getCurrentDrive();	if ((dataDirection == DIRECTION_SCANE) || (dataDirection == DIRECTION_SCANL) || (dataDirection == DIRECTION_SCANH))	    status2 = 0x04;	size = Math.min(size, dataLength);	if (drive.device == null) {	    if (dataDirection == DIRECTION_WRITE)		stopTransfer((byte)0x60, (byte)0x00, (byte)0x00);	    else		stopTransfer((byte)0x40, (byte)0x00, (byte)0x00);	    return 0;	}	int relativeOffset = dataOffset % SECTOR_LENGTH;	int startOffset;	for (startOffset = dataOffset; dataOffset < size;) {	    int length = Math.min(size - dataOffset, SECTOR_LENGTH - relativeOffset);	    if ((dataDirection != DIRECTION_WRITE) || (length < SECTOR_LENGTH) || (relativeOffset != 0)) {		/* READ & SCAN commands and realign to a sector for WRITE */		if (drive.read(drive.currentSector(), fifo, 1) < 0) {		    /* Sure, image size is too small... */		    for (int i = 0; i < Math.min(fifo.length, SECTOR_LENGTH); i++)			fifo[i] = (byte)0x00;		}	    }	    switch (dataDirection) {	    case DIRECTION_READ:		/* READ commands */		dma.writeMemory (nchan, fifo, relativeOffset,				 dataOffset, length);		break;	    case DIRECTION_WRITE:		/* WRITE commands */		dma.readMemory (nchan, fifo, relativeOffset,				dataOffset, length);		if (drive.write(drive.currentSector(), fifo, 1) < 0) {		    stopTransfer((byte)0x60, (byte)0x00, (byte)0x00);		    return length;		}		break;	    default:		/* SCAN commands */		{		    byte[] tempBuffer = new byte[SECTOR_LENGTH];		    dma.readMemory (nchan, tempBuffer, 0,				    dataOffset, length);		    int ret = memcmp(tempBuffer, fifo, relativeOffset, length);		    if (ret == 0) {			status2 = 0x08;			length = dataOffset - startOffset;			if (dataDirection == DIRECTION_SCANE || dataDirection == DIRECTION_SCANL || dataDirection == DIRECTION_SCANH)			    status2 = 0x08;			if ((dataState & STATE_SEEK) != 0)			    status0 |= 0x20;			dataLength -= length;			//    if (dataLength == 0)			stopTransfer(status0, status1, status2);			return length;		    }		    if ((ret < 0 && dataDirection == DIRECTION_SCANL) || (ret > 0 && dataDirection == DIRECTION_SCANH)) {			status2 = 0x00;						length = dataOffset - startOffset;			if (dataDirection == DIRECTION_SCANE || dataDirection == DIRECTION_SCANL || dataDirection == DIRECTION_SCANH)			    status2 = 0x08;			if ((dataState & STATE_SEEK) != 0)			    status0 |= 0x20;			dataLength -= length;			//    if (dataLength == 0)			stopTransfer(status0, status1, status2);						return length;		    }		}		break;	    }	    dataOffset += length;	    relativeOffset = dataOffset % SECTOR_LENGTH;	    if (relativeOffset == 0) {		/* Seek to next sector */		/* XXX: drive.sect >= drive.last_sect should be an		   error in fact */		if ((drive.sector >= drive.lastSector) ||		    (drive.sector == eot)) {		    drive.sector = 1;		    if ((dataState & STATE_MULTI) != 0) {			if ((drive.head == 0) && ((drive.flags & FloppyDrive.DOUBLE_SIDES) != 0)) {				    drive.head = 1;			} else {			    drive.head = 0;			    drive.track++;			    if ((drive.flags & FloppyDrive.DOUBLE_SIDES) == 0)				break;			}		    } else {			drive.track++;			break;		    }		} else {		    drive.sector++;		}	    }	}		int length = dataOffset - startOffset;	if (dataDirection == DIRECTION_SCANE || dataDirection == DIRECTION_SCANL || dataDirection == DIRECTION_SCANH)	    status2 = 0x08;	if ((dataState & STATE_SEEK) != 0)	    status0 |= 0x20;	dataLength -= length;	//    if (dataLength == 0)	stopTransfer(status0, status1, status2);		return length;    }            static class FloppyDrive    {	static final int DRIVE_144  = 0x00;   // 1.44 MB 3"5 drive	static final int DRIVE_288  = 0x01;   // 2.88 MB 3"5 drive	static final int DRIVE_120  = 0x02;   // 1.2  MB 5"25 drive	static final int DRIVE_NONE = 0x03;   // No drive connected		static final int MOTOR_ON   = 0x01; // motor on/off	static final int REVALIDATE = 0x02; // Revalidated	static final int DOUBLE_SIDES  = 0x01;	BlockDevice device;	int drive;	int driveFlags;	int perpendicular;	int head;	int track;	int sector;	int direction;	int readWrite;	int flags;	int lastSector;	int maxTrack;	int bps;	int readOnly;	FloppyFormat format;		public FloppyDrive(BlockDevice device)	{	    this.device = device;	    drive = DRIVE_NONE;	    driveFlags = 0;	    perpendicular = 0;	    lastSector = 0;	    maxTrack = 0;	}        public void dumpState(DataOutput output) throws IOException        {            output.writeInt(drive);            output.writeInt(driveFlags);            output.writeByte(perpendicular);            output.writeByte(head);            output.writeByte(track);            output.writeByte(sector);            output.writeByte(direction);            output.writeByte(readWrite);            output.writeInt(flags);            output.writeByte(lastSector);            output.writeInt(maxTrack);            output.writeInt(bps);            output.writeInt(readOnly);        }        public void loadState(DataInput input) throws IOException        {            drive = input.readInt();            driveFlags = input.readInt();            perpendicular = input.readByte();            head = input.readByte();            track = input.readByte();            sector = input.readByte();            direction = input.readByte();            readWrite = input.readByte();            flags = input.readInt();            lastSector = input.readByte();            maxTrack = input.readInt();            bps = input.readInt();            readOnly = input.readInt();        }        public void setDrive(org.jpc.support.BlockDevice drive)        {            device = drive;        }	public void start()	{	    driveFlags |= MOTOR_ON;	}	public void stop()	{	    driveFlags &= ~MOTOR_ON;	}	public int seek(int seekHead, int seekTrack, int seekSector, int enableSeek)	{	    if ((seekTrack > maxTrack) || (seekHead != 0 && (flags & DOUBLE_SIDES) == 0))		return 2;	    	    if (seekSector > lastSector)		return 3;	    	    int fileSector = calculateSector(seekHead, seekTrack, seekSector, lastSector);	    if (fileSector != currentSector()) {		if (enableSeek == 0)		    return 4;				head = seekHead;		if (track != seekTrack) {		    track = seekTrack;		    sector = seekSector;		    return 1;		}				sector = seekSector;	    }	    return 0;	}	public int currentSector()	{	    return calculateSector(head, track, sector, lastSector);	}	private static int calculateSector(int head, int track, int sector, int lastSector)	{	    return ((((0xff & track) * 2) + (0xff & head)) * (0xff & lastSector)) + (0xff & sector) - 1;	}	public void recalibrate()	{	    head = 0;	    track = 0;	    sector = 1;	    direction = 1;	    readWrite = 0;	}	public int read(int sector, byte[] buffer, int length)	{	    return device.read(0xffffffffl & sector, buffer, length);	}	public int write(int sector, byte[] buffer, int length)	{	    return device.write(0xffffffffl & sector, buffer, length);	}	public void reset()	{	    stop();	    recalibrate();	}	public void revalidate()	{	    driveFlags &= ~REVALIDATE;	    if (device != null && device.inserted()) {		format = FloppyFormat.findFormat(device.getTotalSectors(), drive);		if (format.heads() == 1) {		    flags &= ~DOUBLE_SIDES;		} else {		    flags |= DOUBLE_SIDES;		}		maxTrack = format.tracks();		lastSector = (byte)format.sectors();		readOnly = device.readOnly() ? 0x1 : 0x0;		drive = format.drive();	    } else {		lastSector = 0;		maxTrack = 0;		flags &= ~DOUBLE_SIDES;	    }	    driveFlags |= REVALIDATE;	}	public String toString()	{	    return (device == null) ? "<none>" : format.toString();	}    }    private boolean ioportRegistered;    public void reset()    {	irqDevice = null;	clock = null;	resultTimer = null;	dma = null;	//Really Empty?	ioportRegistered = false;	fifo = new byte[SECTOR_LENGTH];	config = (byte)0x60; /* Implicit Seek, polling & fifo enabled */	drives = new FloppyDrive[2];		state = CONTROL_ACTIVE;       	    }    public boolean initialised()    {	return ((irqDevice != null) && (clock != null) && (dma != null) && (drives[0] != null) && ioportRegistered);    }    public void acceptComponent(HardwareComponent component)    {	if ((component instanceof InterruptController) && component.initialised())	    irqDevice = (InterruptController)component;	if ((component instanceof Clock) && component.initialised()) {	    clock = (Clock)component;	    resultTimer = clock.newTimer(this);	}	if ((component instanceof IOPortHandler) && component.initialised()) {	    ((IOPortHandler)component).registerIOPortCapable(this);	    ioportRegistered = true;	}	if ((component instanceof DMAController) && component.initialised()) {	    if (((DMAController)component).isFirst()) {		if (DMA_CHANNEL != -1) {		    dma = (DMAController)component;		    dmaEnabled = true;		    dma.registerChannel(DMA_CHANNEL & 3, this);		}	    }	}	if ((component instanceof DriveSet) && component.initialised()) {	    drives[0] = new FloppyDrive(((DriveSet)component).getFloppyDrive(0));	    drives[1] = new FloppyDrive(((DriveSet)component).getFloppyDrive(1));	    //Change CB (like in hard drive)	}	if (initialised()) {	    reset(false);	    for (int i = 0; i < 2; i++)		if (drives[i] != null) drives[i].revalidate();	}    }    public boolean updated()    {	return (irqDevice.updated() && clock.updated() && dma.updated() &&		drivesUpdated && ioportRegistered);    }    public void updateComponent(HardwareComponent component)    {        //	if ((component instanceof Clock)  && component.updated())         //        {            //	    clock = (Clock)component;        //	    resultTimer = clock.newTimer(this);        //	}	if ((component instanceof IOPortHandler) && component.updated())         {	    ((IOPortHandler)component).registerIOPortCapable(this);	    ioportRegistered = true;	}        if ((component instanceof DMAController) && component.updated())         {            if (((DMAController)component).isFirst())             {                if (DMA_CHANNEL != -1)                 {		    //dma = (DMAController)component;                    dmaEnabled = true;                    dma.registerChannel(DMA_CHANNEL & 3, this);                }            }        }	if ((component instanceof DriveSet) && component.updated())         {	    drives[0].setDrive(((DriveSet)component).getFloppyDrive(0));	    drives[1].setDrive(((DriveSet)component).getFloppyDrive(1));	    drivesUpdated = true;	}        //	if (initialised())         //        {        //	    reset(false);        //	    for (int i = 0; i < 2; i++)        //		if (drives[i] != null) drives[i].revalidate();        //	}    }    public String toString()    {	return "Intel 82078 Floppy Controller [" + drives[0].toString() + ", " + drives[1].toString() + "]";    }}

⌨️ 快捷键说明

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