idechannel.java

来自「JPC: x86 PC Hardware Emulator. 牛津大学开发的一个」· Java 代码 · 共 1,951 行 · 第 1/5 页

JAVA
1,951
字号
		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.commandLBA48Transform(lba48);		currentDevice.requiredNumberOfSectors = 1;		currentDevice.sectorRead();		break;	    case IDEState.WIN_WRITE_EXT:		lba48 = true;	    case IDEState.WIN_WRITE:	    case IDEState.WIN_WRITE_ONCE:		currentDevice.commandLBA48Transform(lba48);		currentDevice.error = 0;		currentDevice.status = IDEState.SEEK_STAT | IDEState.READY_STAT;		currentDevice.requiredNumberOfSectors = 1;		currentDevice.transferStart(currentDevice.ioBuffer, 0, 512, IDEState.ETF_SECTOR_WRITE);		break;	    case IDEState.WIN_MULTREAD_EXT:		lba48 = true;	    case IDEState.WIN_MULTREAD:		if (currentDevice.multSectors == 0) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.commandLBA48Transform(lba48);		currentDevice.requiredNumberOfSectors = currentDevice.multSectors;		currentDevice.sectorRead();		break;	    case IDEState.WIN_MULTWRITE_EXT:		lba48 = true;	    case IDEState.WIN_MULTWRITE:		if (currentDevice.multSectors == 0) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.commandLBA48Transform(lba48);		currentDevice.error = 0;		currentDevice.status = IDEState.SEEK_STAT | IDEState.READY_STAT;		currentDevice.requiredNumberOfSectors = currentDevice.multSectors;		int n = currentDevice.nSector;		if (n > currentDevice.requiredNumberOfSectors)		    n = currentDevice.requiredNumberOfSectors;		currentDevice.transferStart(currentDevice.ioBuffer, 0, 512 * n, IDEState.ETF_SECTOR_WRITE);		break;	    case IDEState.WIN_READDMA_EXT:		lba48 = true;	    case IDEState.WIN_READDMA:	    case IDEState.WIN_READDMA_ONCE:		if (currentDevice.drive == null) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.commandLBA48Transform(lba48);		currentDevice.sectorReadDMA();		break;	    case IDEState.WIN_WRITEDMA_EXT:		lba48 = true;	    case IDEState.WIN_WRITEDMA:	    case IDEState.WIN_WRITEDMA_ONCE:		if (currentDevice.drive == null) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.commandLBA48Transform(lba48);		currentDevice.sectorWriteDMA();		break;	    case IDEState.WIN_READ_NATIVE_MAX_EXT:		lba48 = true;	    case IDEState.WIN_READ_NATIVE_MAX:		currentDevice.commandLBA48Transform(lba48);		currentDevice.setSector(currentDevice.drive.getTotalSectors() - 1);		currentDevice.status = IDEState.READY_STAT;		currentDevice.setIRQ();		break;	    case IDEState.WIN_CHECKPOWERMODE1:		currentDevice.nSector = 0xff; /* device active or idle */		currentDevice.status = IDEState.READY_STAT;		currentDevice.setIRQ();		break;	    case IDEState.WIN_SETFEATURES:		if (currentDevice.drive == null) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		/* XXX: valid for CDROM ? */		switch(currentDevice.feature) {		case (byte)0x02: /* write cache enable */		case (byte)0x82: /* write cache disable */		case (byte)0xaa: /* read look-ahead enable */		case (byte)0x55: /* read look-ahead disable */		    currentDevice.status = IDEState.READY_STAT | IDEState.SEEK_STAT;		    currentDevice.setIRQ();		    break;		case (byte)0x03: /* set transfer mode */		    int val = currentDevice.nSector & 0x07;		    switch (currentDevice.nSector >>> 3) {		    case 0x00: // pio default		    case 0x01: // pio mode			putLE16InByte(currentDevice.identifyData, 126, 0x07);			putLE16InByte(currentDevice.identifyData, 176, 0x3f);			break;		    case 0x04: /* mdma mode */			putLE16InByte(currentDevice.identifyData, 126, 0x07 | (1 << (val + 8)));			putLE16InByte(currentDevice.identifyData, 176, 0x3f);			break;		    case 0x08: /* udma mode */			putLE16InByte(currentDevice.identifyData, 126, 0x07);			putLE16InByte(currentDevice.identifyData, 176, 0x3f | (1 << (val + 8)));			break;		    default:			currentDevice.abortCommand();			currentDevice.setIRQ();			return;		    }		    currentDevice.status = IDEState.READY_STAT | IDEState.SEEK_STAT;		    currentDevice.setIRQ();		    break;		default:		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		break;	    case IDEState.WIN_FLUSH_CACHE:	    case IDEState.WIN_FLUSH_CACHE_EXT:		if (currentDevice.drive != null)		    System.err.println("Should flush BlockDevice - " + currentDevice.drive);		    //currentDevice.drive.flush();		currentDevice.status = IDEState.READY_STAT;		currentDevice.setIRQ();		break;	    case IDEState.WIN_STANDBYNOW1:	    case IDEState.WIN_IDLEIMMEDIATE:		currentDevice.status = IDEState.READY_STAT;		currentDevice.setIRQ();		break;		/* ATAPI commands */	    case IDEState.WIN_PIDENTIFY:		if (currentDevice.isCDROM) {		    currentDevice.atapiIdentify();		    currentDevice.status = IDEState.READY_STAT | IDEState.SEEK_STAT;		    currentDevice.transferStart(currentDevice.ioBuffer, 0, 512, IDEState.ETF_TRANSFER_STOP);		} else {		    currentDevice.abortCommand();		}		currentDevice.setIRQ();		break;	    case IDEState.WIN_DIAGNOSE:		currentDevice.setSignature();		currentDevice.status = 0x00;		currentDevice.error = 0x01;		break;	    case IDEState.WIN_SRST:		if (!currentDevice.isCDROM) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.setSignature();		currentDevice.status = 0x00; /* NOTE: READY is _not_ set */		currentDevice.error = 0x01;		break;	    case IDEState.WIN_PACKETCMD:		if (!currentDevice.isCDROM) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		/* overlapping commands not supported */		if ((currentDevice.feature & 0x02) != 0) {		    currentDevice.abortCommand();		    currentDevice.setIRQ();		    return;		}		currentDevice.atapiDMA = ((currentDevice.feature & 1) == 1);		currentDevice.nSector = 1;		currentDevice.transferStart(currentDevice.ioBuffer, 0, IDEState.ATAPI_PACKET_SIZE, IDEState.ETF_ATAPI_COMMAND);		break;	    default:		currentDevice.abortCommand();		currentDevice.setIRQ();		return;	    }	    	}    }    private int readIDE(int address)    {	address &= 0x7;	//boolean hob = (currentDevice.select & (1 << 7)) != 0;	boolean hob = false;	switch(address) {	case 0:	    return 0xff;	case 1:	    if (devices[0].drive == null && devices[1].drive == null)		return 0;	    else if (!hob) {		return currentDevice.error;	    } else		return currentDevice.hobFeature;	case 2:	    if (devices[0].drive == null && devices[1].drive == null)		return 0;	    else if (!hob) {		return currentDevice.nSector & 0xff;	    } else		return currentDevice.hobNSector;	case 3:	    if (devices[0].drive == null && devices[1].drive == null)		return 0;	    else if (!hob) {		return currentDevice.sector;	    } else		return currentDevice.hobSector;	case 4:	    if (devices[0].drive == null && devices[1].drive == null)		return 0;	    else if (!hob) {		return currentDevice.lcyl;	    } else		return currentDevice.hobLCyl;	case 5:	    if (devices[0].drive == null && devices[1].drive == null)		return 0;	    else if (!hob) {		return currentDevice.hcyl;	    } else		return currentDevice.hobHCyl;	case 6:	    if (devices[0].drive == null && devices[1].drive == null)		return 0;	    else {		return currentDevice.select;	    }	default:	case 7:	    if ((devices[0].drive == null && devices[1].drive == null) ||		(currentDevice != devices[0] && currentDevice.drive == null)) {		IDEChannel.this.irqDevice.setIRQ(IDEChannel.this.irq, 0);		return 0;	    } else {		IDEChannel.this.irqDevice.setIRQ(IDEChannel.this.irq, 0);		return currentDevice.status;	    }	}    }    private int readDataWord(int address)    {	int data = 0;	data |= 0xff & currentDevice.dataBuffer[currentDevice.dataBufferOffset++];	data |= 0xff00 & (currentDevice.dataBuffer[currentDevice.dataBufferOffset++] << 8);	if (currentDevice.dataBufferOffset >= currentDevice.dataBufferEnd)	    currentDevice.endTransfer(currentDevice.endTransferFunction);	return data;    }    private int readDataLong(int address)    {	int data = 0;	data |= 0xff & currentDevice.dataBuffer[currentDevice.dataBufferOffset++];	data |= 0xff00 & (currentDevice.dataBuffer[currentDevice.dataBufferOffset++] << 8);	data |= 0xff0000 & (currentDevice.dataBuffer[currentDevice.dataBufferOffset++] << 16);	data |= 0xff000000 & (currentDevice.dataBuffer[currentDevice.dataBufferOffset++] << 24);	if (currentDevice.dataBufferOffset >= currentDevice.dataBufferEnd)	    currentDevice.endTransfer(currentDevice.endTransferFunction);	return data;    }    private void writeDataWord(int address, int data)    {	currentDevice.dataBuffer[currentDevice.dataBufferOffset++] = (byte)(data);	currentDevice.dataBuffer[currentDevice.dataBufferOffset++] = (byte)(data >> 8);	if (currentDevice.dataBufferOffset >= currentDevice.dataBufferEnd)	    currentDevice.endTransfer(currentDevice.endTransferFunction);    }    private void writeDataLong(int address, int data)    {	currentDevice.dataBuffer[currentDevice.dataBufferOffset++] = (byte)(data);	currentDevice.dataBuffer[currentDevice.dataBufferOffset++] = (byte)(data >> 8);	currentDevice.dataBuffer[currentDevice.dataBufferOffset++] = (byte)(data >> 16);	currentDevice.dataBuffer[currentDevice.dataBufferOffset++] = (byte)(data >> 24);	if (currentDevice.dataBufferOffset >= currentDevice.dataBufferEnd)	    currentDevice.endTransfer(currentDevice.endTransferFunction);    }    private void clearHob()    {	/* any write clears HOB high bit of device control register */	devices[0].select &= ~(1 << 7);	devices[1].select &= ~(1 << 7);    }    class IDEState {	/* Bits of HD_STATUS */	public static final int ERR_STAT = 0x01;	public static final int INDEX_STAT = 0x02;	public static final int ECC_STAT = 0x04;/* Corrected error */	public static final int DRQ_STAT = 0x08;	public static final int SEEK_STAT = 0x10;	public static final int SRV_STAT = 0x10;	public static final int WRERR_STAT = 0x20;	public static final int READY_STAT = 0x40;	public static final int BUSY_STAT = 0x80;	/* Bits for HD_ERROR */	private static final int MARK_ERR = 0x01; /* Bad address mark */	private static final int TRK0_ERR = 0x02; /* couldn't find track 0 */	private static final int ABRT_ERR = 0x04; /* Command aborted */	private static final int MCR_ERR = 0x08; /* media change request */	private static final int ID_ERR = 0x10; /* ID field not found */	private static final int MC_ERR = 0x20; /* media changed */	private static final int ECC_ERR = 0x40; /* Uncorrectable ECC error */	private static final int BBD_ERR = 0x80; /* pre-EIDE meaning:  block marked bad */	private static final int ICRC_ERR = 0x80; /* new meaning:  CRC error during transfer */	public static final int IDE_CMD_RESET = 0x04;	public static final int IDE_CMD_DISABLE_IRQ = 0x02;	/* ATA/ATAPI Commands pre T13 Spec */	public static final int WIN_NOP = 0x00;	/*	 *      0x01->0x02 Reserved	 */	public static final int CFA_REQ_EXT_ERROR_CODE = 0x03; /* CFA Request Extended Error Code									 */	/*	 *      0x04->0x07 Reserved	 */	public static final int WIN_SRST = 0x08; /* ATAPI soft reset command */	public static final int WIN_DEVICE_RESET = 0x08;	/*	 *      0x09->0x0F Reserved	 */	public static final int WIN_RECAL = 0x10;	public static final int WIN_RESTORE = WIN_RECAL;	/*	 *      0x10->0x1F Reserved	 */	public static final int WIN_READ = 0x20; /* 28-Bit */	public static final int WIN_READ_ONCE = 0x21; /* 28-Bit without retries */	public static final int WIN_READ_LONG = 0x22; /* 28-Bit */	public static final int WIN_READ_LONG_ONCE = 0x23; /* 28-Bit without retries */	public static final int WIN_READ_EXT = 0x24; /* 48-Bit */	public static final int WIN_READDMA_EXT = 0x25; /* 48-Bit */	public static final int WIN_READDMA_QUEUED_EXT = 0x26; /* 48-Bit */	public static final int WIN_READ_NATIVE_MAX_EXT = 0x27; /* 48-Bit */	/*	 *      0x28	 */	public static final int WIN_MULTREAD_EXT = 0x29; /* 48-Bit */	/*	 *      0x2A->0x2F Reserved	 */	public static final int WIN_WRITE = 0x30; /* 28-Bit */	public static final int WIN_WRITE_ONCE                  = 0x31; /* 28-Bit without retries */	public static final int WIN_WRITE_LONG                  = 0x32; /* 28-Bit */	public static final int WIN_WRITE_LONG_ONCE             = 0x33; /* 28-Bit without retries */	public static final int WIN_WRITE_EXT                   = 0x34; /* 48-Bit */	public static final int WIN_WRITEDMA_EXT                = 0x35; /* 48-Bit */	public static final int WIN_WRITEDMA_QUEUED_EXT         = 0x36; /* 48-Bit */	public static final int WIN_SET_MAX_EXT                 = 0x37; /* 48-Bit */	public static final int CFA_WRITE_SECT_WO_ERASE         = 0x38; /* CFA Write Sectors without erase									 */	public static final int WIN_MULTWRITE_EXT               = 0x39; /* 48-Bit */	/*	 *      0x3A->0x3B Reserved	 */	public static final int WIN_WRITE_VERIFY                = 0x3C; /* 28-Bit */	/*	 *      0x3D->0x3F Reserved	 */	public static final int WIN_VERIFY                      = 0x40; /* 28-Bit - Read Verify Sectors */	public static final int WIN_VERIFY_ONCE                 = 0x41; /* 28-Bit - without retries */	public static final int WIN_VERIFY_EXT                  = 0x42; /* 48-Bit */	/*	 *      0x43->0x4F Reserved	 */

⌨️ 快捷键说明

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