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

📄 idechannel.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		break;	    case GPCMD_REQUEST_SENSE:		maxLength = 0xff & buffer[4];		for (int i = 0; i < 18; i++)		    buffer[i] = 0;		buffer[0] = (byte)(0x70 | (1 << 7));		buffer[2] = senseKey;		buffer[7] = 10;		buffer[12] = asc;		atapiCommandReply(18, maxLength);		break;	    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:		if (drive.inserted()) {		    drive.setLock((buffer[4] & 1) != 0);		    atapiCommandOk();		} else {		    atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);		}		break;	    case GPCMD_READ_10:	    case GPCMD_READ_12:		{		    int numSectors;		    int lba;		    		    if (!drive.inserted()) {			atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);			break;		    }		    if (buffer[0] == GPCMD_READ_10)			numSectors = bigEndianBytesToShort(buffer, 7);		    else			numSectors = bigEndianBytesToInt(buffer, 6);		    lba = bigEndianBytesToInt(buffer, 2);		    if (numSectors == 0) {			atapiCommandOk();			break;		    }		    if ((((0xffffffffl & lba) + (0xffffffffl & numSectors)) << 2) > drive.getTotalSectors()) {			atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);			break;		    }		    atapiCommandRead(lba, numSectors, 2048);		}		break;	    case GPCMD_READ_CD:		{		    int numSectors, lba, transferRequest;		    		    if (!drive.inserted()) {			atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);			break;		    }		    numSectors = ((0xff & buffer[6]) << 16) | ((0xff & buffer[7]) << 8) | (0xff & buffer[8]);		    lba = bigEndianBytesToInt(buffer, 2);		    if (numSectors == 0) {			atapiCommandOk();			break;		    }		    if ((((0xffffffffl & lba) + (0xffffffffl & numSectors)) << 2) > drive.getTotalSectors()) {			atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);			break;		    }		    transferRequest = 0xff & buffer[9];		    switch(transferRequest & 0xf8) {		    case 0x00:			/* nothing */			atapiCommandOk();			break;		    case 0x10:			/* normal read */			atapiCommandRead(lba, numSectors, 2048);			break;		    case 0xf8:			/* read all data */			atapiCommandRead(lba, numSectors, 2352);			break;		    default:			atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);			break;		    }		}		break;	    case GPCMD_SEEK:		{		    int lba;		    if (!drive.inserted()) {			atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);			break;		    }		    lba = bigEndianBytesToInt(buffer, 2);		    if (((0xffffffffl & lba) << 2) > drive.getTotalSectors()) {			atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);			break;		    }		    atapiCommandOk();		}		break;	    case GPCMD_START_STOP_UNIT:		{		    		    boolean start = ((buffer[4] & 1) != 0); 		    boolean eject = ((buffer[4] & 2) != 0);		    		    if (eject && !start) {			/* eject the disk */			drive.close();		    }		    atapiCommandOk();		}		break;	    case GPCMD_MECHANISM_STATUS:		{		    maxLength = bigEndianBytesToShort(buffer, 8);		    shortToBigEndianBytes(buffer, 0, (short)0);		    /* no current LBA */		    buffer[2] = 0;		    buffer[3] = 0;		    buffer[4] = 0;		    buffer[5] = 1;		    shortToBigEndianBytes(buffer, 6, (short)0);		    atapiCommandReply(8, maxLength);		}		break;	    case GPCMD_READ_TOC_PMA_ATIP:		{		    int format, msf, startTrack, length;		    		    if (!drive.inserted()) {			atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);			break;		    }		    maxLength = bigEndianBytesToShort(buffer, 7);		    format = (0xff & buffer[9]) >>> 6;		    msf = (buffer[1] >>> 1) & 1;		    startTrack = 0xff & buffer[6];		    switch(format) {		    case 0:			length = cdromReadTOC((int)(drive.getTotalSectors() >>> 2), buffer, msf, startTrack);			if (length < 0) {			    atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);			    break;			}			atapiCommandReply(length, maxLength);			break;		    case 1:			/* multi session : only a single session defined */			for (int i = 0; i < 12; i++)			    buffer[i] = 0;			buffer[1] = 0x0a;			buffer[2] = 0x01;			buffer[3] = 0x01;			atapiCommandReply(12, maxLength);			break;		    case 2:			length = cdromReadTOCRaw((int)(drive.getTotalSectors() >>> 2), buffer, msf, startTrack);			if (length < 0) {			    atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);			    break;			}			atapiCommandReply(length, maxLength);			break;		    default:			atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);			break;		    }		}		break;	    case GPCMD_READ_CDVD_CAPACITY:		if (!drive.inserted()) {		    atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);		    break;		}		/* NOTE: it is really the number of sectors minus 1 */		intToBigEndianBytes(buffer, 0, (int)((drive.getTotalSectors() >>> 2) - 1));		intToBigEndianBytes(buffer, 4, 2048);		atapiCommandReply(8, 8);		break;	    case GPCMD_INQUIRY:		maxLength = 0xff & buffer[4];		buffer[0] = 0x05; /* CD-ROM */		buffer[1] = (byte)0x80; /* removable */		buffer[2] = 0x00; /* ISO */		buffer[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */		buffer[4] = 31; /* additionnal length */		buffer[5] = 0; /* reserved */		buffer[6] = 0; /* reserved */		buffer[7] = 0; /* reserved */		{		    byte[] temp = "JPC".getBytes();		    int i = 8;		    for (int j = 0; j < temp.length; i++, j++)			buffer[i] = temp[j];		    for (; i < 16; i++)			buffer[i] = 0;		}		{		    byte[] temp = "JPC CD-ROM".getBytes();		    int i = 16;		    for (int j = 0; j < temp.length; i++, j++)			buffer[i] = temp[j];		    for (; i < 32; i++)			buffer[i] = 0;		}		{		    byte[] temp = "1.0".getBytes();		    int i = 32;		    for (int j = 0; j < temp.length; i++, j++)			buffer[i] = temp[j];		    for (; i < 36; i++)			buffer[i] = 0;		}		atapiCommandReply(36, maxLength);		break;	    default:		atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE);		break;	    }	    	}		private void dummyTransferStop()	{	    this.dataBuffer = this.ioBuffer;	    this.dataBufferEnd = 0;	    this.ioBuffer[0] = (byte)0xff;	    this.ioBuffer[1] = (byte)0xff;	    this.ioBuffer[2] = (byte)0xff;	    this.ioBuffer[3] = (byte)0xff;	}	private void atapiCommandOk()	{	    this.error = 0;	    this.status = READY_STAT;	    this.nSector = (this.nSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;	    this.setIRQ();	}	private void atapiCommandError(int senseKey, int asc)	{	    this.error = (byte)(this.senseKey << 4);	    this.status = READY_STAT | ERR_STAT;	    this.nSector = (this.nSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;	    this.senseKey = (byte)senseKey;	    this.asc = (byte)asc;	    this.setIRQ();	}	private void atapiCommandReply(int size, int maxSize)	{	    size = Math.min(size, maxSize);	    this.lba = -1;	    this.packetTransferSize = size;	    this.elementaryTransferSize = 0;	    this.ioBufferIndex = 0;	    this.status = READY_STAT;	    atapiCommandReplyEnd();	}	private void atapiCommandRead(int lba, int numSectors, int sectorSize)	{	    if (this.atapiDMA)		atapiCommandReadDMA(lba, numSectors, sectorSize);	    else		atapiCommandReadPIO(lba, numSectors, sectorSize);	}	private void atapiCommandReadDMA(int lba, int numSectors, int sectorSize)	{	    this.lba = lba;	    this.packetTransferSize = numSectors * sectorSize;	    this.ioBufferIndex = sectorSize;	    this.cdSectorSize = sectorSize;	    	    this.status = READY_STAT | DRQ_STAT;	    dmaStart(IDF_ATAPI_READ_DMA_CB);	}	private void atapiCommandReadPIO(int lba, int numSectors, int sectorSize)	{	    this.lba = lba;	    this.packetTransferSize = numSectors * sectorSize;	    this.elementaryTransferSize = 0;	    this.ioBufferIndex = sectorSize;	    this.cdSectorSize = sectorSize;	    	    this.status = READY_STAT;	    atapiCommandReplyEnd();	}	private void atapiCommandReplyEnd()	{	    if (this.packetTransferSize <= 0) { //end of transfer		transferStop();		this.status = READY_STAT;		this.nSector = (this.nSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;		this.setIRQ();	    } else {		/* see if a new sector must be read */		if (this.lba != -1 && this.ioBufferIndex >= this.cdSectorSize) {		    cdReadSector(this.lba, this.ioBuffer, this.cdSectorSize);		    this.lba++;		    this.ioBufferIndex = 0;		}		if (this.elementaryTransferSize > 0) { // there is some data left to transmit in this elementary transfer		    int size = Math.min(this.cdSectorSize - this.ioBufferIndex, this.elementaryTransferSize);		    transferStart(this.ioBuffer, this.ioBufferIndex, size, ETF_ATAPI_COMMAND_REPLY_END);		    this.packetTransferSize -= size;		    this.elementaryTransferSize -= size;		    this.ioBufferIndex += size;		} else {		    /* a new transfer is needed */		    this.nSector = (this.nSector & ~7) | ATAPI_INT_REASON_IO;		    int byteCountLimit = (0xff & this.lcyl) | (0xff00 & (this.hcyl << 8));		    if (byteCountLimit == 0xffff)			byteCountLimit--;		    int size = this.packetTransferSize;		    if (size > byteCountLimit) {			/* byte count limit must be even if this case */			if ((byteCountLimit & 1) != 0)			    byteCountLimit--;			size = byteCountLimit;		    }		    this.lcyl = (byte)size;		    this.hcyl = (byte)(size >>> 8);		    this.elementaryTransferSize = size;		    /* we cannot transmit more than one sector at a time */		    if (this.lba != -1) {			size = Math.min(this.cdSectorSize - this.ioBufferIndex, size);		    }		    this.transferStart(this.ioBuffer, this.ioBufferIndex, size, ETF_ATAPI_COMMAND_REPLY_END);		    this.packetTransferSize -= size;		    this.elementaryTransferSize -= size;		    this.ioBufferIndex += size;		    this.setIRQ();		}	    }	    	}	private int atapiCommandReadDMACallback(int address, int size)	{	    int originalSize = size;	    while (size > 0) {		if (packetTransferSize <= 0)		    break;		int length = cdSectorSize - ioBufferIndex;		if (length <= 0) {		    cdReadSector(this.lba, this.ioBuffer, this.cdSectorSize);		    this.lba++;		    this.ioBufferIndex = 0;		    length = this.cdSectorSize;		}		if (length > size)		    length = size;		bmdma.writeMemory(address, ioBuffer, ioBufferIndex, length);		this.packetTransferSize -= length;		this.ioBufferIndex += length;		size -= length;		address += length;	    }	    if (packetTransferSize <= 0) {		this.status = READY_STAT;		this.nSector = (this.nSector & ~0x7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;		this.setIRQ();		return 0;	    }	    return originalSize - size;	}	private int cdromReadTOC(int nbSectors, byte[] buffer, int msf, int startTrack)	{	    if ((startTrack > 1) && (startTrack != 0xaa))		return -1;	    int bufferOffset = 2;	    buffer[bufferOffset++] = 1; // first session 	    buffer[bufferOffset++] = 1; // last session	    if (startTrack <= 1) {		buffer[bufferOffset++] = 0; // reserved		buffer[bufferOffset++] = 0x14; // ADR, control		buffer[bufferOffset++] = 1; // track number		buffer[bufferOffset++] = 0; // reserved		if (msf != 0) {		    buffer[bufferOffset++] = 0; // reserved		    lbaToMSF(buff

⌨️ 快捷键说明

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