📄 idechannel.java
字号:
public void setIRQ() { if ((this.command & IDE_CMD_DISABLE_IRQ) == 0) { if (bmdma != null) bmdma.setIRQ(); IDEChannel.this.irqDevice.setIRQ(IDEChannel.this.irq, 1); } } public void abortCommand() { this.status = READY_STAT | ERR_STAT; this.error = ABRT_ERR; } public void atapiIdentify() { if (identifySet) { System.arraycopy(identifyData, 0, ioBuffer, 0, identifyData.length); return; } byte[] temp; for (int i=0; i<512; i++) ioBuffer[i] = (byte)0; putLE16InByte(ioBuffer, 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0)); stringToBytes("JPC" + this.driveSerial, ioBuffer, 20, 20); putLE16InByte(ioBuffer, 40, 3); /* XXX: retired, remove ? */ putLE16InByte(ioBuffer, 42, 512); /* cache size in sectors */ putLE16InByte(ioBuffer, 44, 4); /* ecc bytes */ stringToBytes(HD_VERSION, ioBuffer, 46, 8); stringToBytes("JPC CD-ROM", ioBuffer, 54, 40); putLE16InByte(ioBuffer, 96, 1); /* dword I/O */ putLE16InByte(ioBuffer, 98, (1 << 9)); /* DMA and LBA supported */ putLE16InByte(ioBuffer, 106, 3); /* words 54-58, 64-70 are valid */ putLE16InByte(ioBuffer, 126, 0x103); putLE16InByte(ioBuffer, 128, 1); putLE16InByte(ioBuffer, 130, 0xb4); putLE16InByte(ioBuffer, 132, 0xb4); putLE16InByte(ioBuffer, 134, 0x12c); putLE16InByte(ioBuffer, 136, 0xb4); putLE16InByte(ioBuffer, 142, 30); putLE16InByte(ioBuffer, 144, 30); putLE16InByte(ioBuffer, 160, 0x1e); System.arraycopy(ioBuffer, 0, identifyData, 0, identifyData.length); identifySet = true; } public void setSector(long sectorNumber) { if ((this.select & 0x40) != 0) { if (!this.lba48) { this.select = (byte)((this.select & 0xf0) | (sectorNumber >>> 24)); this.hcyl = (byte)(sectorNumber >>> 16); this.lcyl = (byte)(sectorNumber >>> 8); this.sector = (byte)sectorNumber; } else { this.sector = (byte)sectorNumber; this.lcyl = (byte)(sectorNumber >>> 8); this.hcyl = (byte)(sectorNumber >>> 16); this.hobSector = (byte)(sectorNumber >>> 24); this.hobLCyl = (byte)(sectorNumber >>> 32); this.hobHCyl = (byte)(sectorNumber >>> 40); } } else { int cyl = (int)(sectorNumber / (this.heads * this.sectors)); int r = (int)(sectorNumber % (this.heads * this.sectors)); this.hcyl = (byte)(cyl >>> 8); this.lcyl = (byte)(cyl); this.select = (byte)((this.select & 0xf0) | ((r / this.sectors) & 0x0f)); this.sector = (byte)((r % this.sectors) + 1); } } public void sectorWriteDMA() { this.status = READY_STAT | SEEK_STAT | DRQ_STAT; int n = this.nSector; if (n > MAX_MULT_SECTORS) n = MAX_MULT_SECTORS; this.ioBufferIndex = 0; this.ioBufferSize = n * 512; this.dmaStart(IDF_WRITE_DMA_CB); } public void sectorReadDMA() { this.status = READY_STAT | SEEK_STAT | DRQ_STAT; this.ioBufferIndex = 0; this.ioBufferSize = 0; this.dmaStart(IDF_READ_DMA_CB); } public void sectorWrite() { this.status = READY_STAT | SEEK_STAT; long sectorNumber = this.getSector(); int n = this.nSector; if (n > this.requiredNumberOfSectors) n = this.requiredNumberOfSectors; drive.write(sectorNumber, this.ioBuffer, n); this.nSector -= n; if (this.nSector == 0) { this.transferStop(); } else { int n1 = this.nSector; if (n1 > this.requiredNumberOfSectors) n1 = this.requiredNumberOfSectors; this.transferStart(this.ioBuffer, 0, 512 * n1, ETF_SECTOR_WRITE); } this.setSector(sectorNumber + n); this.setIRQ(); } public void sectorRead() { this.status = READY_STAT | SEEK_STAT; this.error = 0; /* not needed by IDE spec, but needed by Windows */ long sectorNumber = this.getSector(); int n = this.nSector; if (n == 0) // no more sectors to read from disk this.transferStop(); else { n = Math.min(n, this.requiredNumberOfSectors); drive.read(sectorNumber, this.ioBuffer, n); this.transferStart(this.ioBuffer, 0, 512 * n, ETF_SECTOR_READ); this.setIRQ(); this.setSector(sectorNumber + n); this.nSector -= n; } } public void identify() { byte[] temp; if (identifySet) { System.arraycopy(identifyData, 0, ioBuffer, 0, identifyData.length); return; } for (int i=0; i<512; i++) ioBuffer[i] = (byte)0; putLE16InByte(ioBuffer, 0, 0x0040); putLE16InByte(ioBuffer, 2, this.cylinders); putLE16InByte(ioBuffer, 6, this.heads); putLE16InByte(ioBuffer, 8, 512 * this.sectors); /* XXX: retired, remove ? */ putLE16InByte(ioBuffer, 10, 512); /* XXX: retired, remove ? */ putLE16InByte(ioBuffer, 12, this.sectors); stringToBytes("JPC" + this.driveSerial, ioBuffer, 20, 20); putLE16InByte(ioBuffer, 40, 3); /* XXX: retired, remove ? */ putLE16InByte(ioBuffer, 42, 512); /* cache size in sectors */ putLE16InByte(ioBuffer, 44, 4); /* ecc bytes */ stringToBytes(HD_VERSION, ioBuffer, 46, 8); stringToBytes("JPC HARDDISK", ioBuffer, 54, 40); putLE16InByte(ioBuffer, 94, 0x8000 | MAX_MULT_SECTORS); putLE16InByte(ioBuffer, 96, 1); /* dword I/O */ putLE16InByte(ioBuffer, 98, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */ putLE16InByte(ioBuffer, 102, 0x200); /* PIO transfer cycle */ putLE16InByte(ioBuffer, 104, 0x200); /* DMA transfer cycle */ putLE16InByte(ioBuffer, 106, 1 | (1 << 1) | (1 << 2)); /* words 54-58, 64-70, 88 are valid */ putLE16InByte(ioBuffer, 108, this.cylinders); putLE16InByte(ioBuffer, 110, this.heads); putLE16InByte(ioBuffer, 112, this.sectors); int oldsize = this.cylinders * this.heads * this.sectors; putLE16InByte(ioBuffer, 114, oldsize); putLE16InByte(ioBuffer, 116, oldsize >>> 16); if (this.multSectors != 0) putLE16InByte(ioBuffer, 118, 0x100 | this.multSectors); putLE16InByte(ioBuffer, 120, (short)this.drive.getTotalSectors()); putLE16InByte(ioBuffer, 122, (short)(this.drive.getTotalSectors() >>> 16)); putLE16InByte(ioBuffer, 126, 0x07); // mdma0-2 supported putLE16InByte(ioBuffer, 130, 120); putLE16InByte(ioBuffer, 132, 120); putLE16InByte(ioBuffer, 134, 120); putLE16InByte(ioBuffer, 136, 120); putLE16InByte(ioBuffer, 160, 0xf0); // ata3 -> ata6 supported putLE16InByte(ioBuffer, 162, 0x16); // conforms to ata5 putLE16InByte(ioBuffer, 164, 1 << 14); putLE16InByte(ioBuffer, 166, (1 << 14) | (1 << 13) | (1 << 12)); //putLE16InByte(ioBuffer, 166, (1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); putLE16InByte(ioBuffer, 168, 1 << 14); putLE16InByte(ioBuffer, 170, 1 << 14); putLE16InByte(ioBuffer, 172, (1 << 14) | (1 << 13) | (1 << 12)); //putLE16InByte(ioBuffer, 172, (1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); putLE16InByte(ioBuffer, 174, 1 << 14); putLE16InByte(ioBuffer, 176, 0x3f | (1 << 13)); putLE16InByte(ioBuffer, 186, 1 | (1 << 14) | 0x2000); putLE16InByte(ioBuffer, 200, nSector); putLE16InByte(ioBuffer, 202, nSector >>> 16); putLE16InByte(ioBuffer, 204, /*nSector >>> 32*/ 0); putLE16InByte(ioBuffer, 206, /*nSector >>> 48*/ 0); System.arraycopy(ioBuffer, 0, identifyData, 0, identifyData.length); identifySet = true; } public void transferStart(byte[] buffer, int offset, int size, int endTransferFunction) { this.endTransferFunction = endTransferFunction; this.dataBuffer = buffer; this.dataBufferOffset = offset; this.dataBufferEnd = size + offset; this.status |= DRQ_STAT; } private void transferStop() { this.endTransferFunction = ETF_TRANSFER_STOP; this.dataBuffer = this.ioBuffer; this.dataBufferEnd = 0; this.dataBufferOffset = 0; this.status &= ~DRQ_STAT; } private void commandLBA48Transform(boolean lba48) { this.lba48 = lba48; if (!this.lba48) { if (this.nSector == 0) this.nSector = 256; } else { if ((this.nSector == 0) && (this.hobNSector == 0)) this.nSector = 65536; else { int lo = 0xff & this.nSector; int hi = 0xff & this.hobNSector; this.nSector = (hi << 8) | lo; } } } private long getSector() { if ((this.select & 0x40) != 0) { /* lba */ if (!this.lba48) { return ((this.select & 0x0fl) << 24) | ((0xffl & this.hcyl) << 16) | ((0xffl & this.lcyl) << 8) | (0xffl & this.sector); } else { return ((0xffl & this.hobHCyl) << 40) | ((0xffl & this.hobLCyl) << 32) | ((0xffl & this.hobSector) << 24) | ((0xffl & this.hcyl) << 16) | ((0xffl & this.lcyl) << 16) | (0xffl & this.sector); } } else { return ((((0xffl & this.hcyl) << 8) | (0xffl & this.lcyl)) * this.heads * this.sectors) + ((this.select & 0x0fl) * this.sectors) + ((0xffl & this.sector) - 1); } } private void dmaStart(int ideDMAFunction) { if (bmdma == null) return; bmdma.setIDEDevice(this); bmdma.setDMAFunction(ideDMAFunction); if ((bmdma.getStatus() & BMDMAIORegion.BM_STATUS_DMAING) != 0) { bmdma.ideDMALoop(); } } public void endTransfer(int mode) { switch (mode) { case ETF_TRANSFER_STOP: this.transferStop(); break; case ETF_SECTOR_WRITE: this.sectorWrite(); break; case ETF_SECTOR_READ: this.sectorRead(); break; case ETF_ATAPI_COMMAND: this.atapiCommand(); break; case ETF_ATAPI_COMMAND_REPLY_END: this.atapiCommandReplyEnd(); break; case ETF_DUMMY_TRANSFER_STOP: this.dummyTransferStop(); break; } } public void reset() { this.multSectors = MAX_MULT_SECTORS; this.select = (byte)0xa0; this.status = READY_STAT; this.setSignature(); this.endTransferFunction = ETF_DUMMY_TRANSFER_STOP; this.endTransfer(ETF_DUMMY_TRANSFER_STOP); } private void atapiCommand() { int maxLength; byte[] buffer = this.ioBuffer; switch(0xff & ioBuffer[0]) { case GPCMD_TEST_UNIT_READY: if (drive.inserted()) atapiCommandOk(); else atapiCommandError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); break; case GPCMD_MODE_SENSE_10: { maxLength = bigEndianBytesToShort(buffer, 7); int action = (0xff & buffer[2]) >>> 6; int code = buffer[2] & 0x3f; switch(action) { case 0: /* current values */ switch(code) { case 0x01: /* error recovery */ shortToBigEndianBytes(buffer, 0, (short)(16+6)); buffer[2] = 0x70; buffer[3] = 0; buffer[4] = 0; buffer[5] = 0; buffer[6] = 0; buffer[7] = 0; buffer[8] = 0x01; buffer[9] = 0x06; buffer[10] = 0x00; buffer[11] = 0x05; buffer[12] = 0x00; buffer[13] = 0x00; buffer[14] = 0x00; buffer[15] = 0x00; atapiCommandReply(16, maxLength); break; case 0x2a: shortToBigEndianBytes(buffer, 0, (short)(28+6)); buffer[2] = 0x70; buffer[3] = 0; buffer[4] = 0; buffer[5] = 0; buffer[6] = 0; buffer[7] = 0; buffer[8] = 0x2a; buffer[9] = 0x12; buffer[10] = 0x00; buffer[11] = 0x00; buffer[12] = 0x70; buffer[13] = 3 << 5; buffer[14] = (1 << 0) | (1 << 3) | (1 << 5); if (drive.locked()) buffer[6] |= 1 << 1; buffer[15] = 0x00; shortToBigEndianBytes(buffer, 16, (short)706); buffer[18] = 0; buffer[19] = 2; shortToBigEndianBytes(buffer, 20, (short)512); shortToBigEndianBytes(buffer, 22, (short)706); buffer[24] = 0; buffer[25] = 0; buffer[26] = 0; buffer[27] = 0; atapiCommandReply(28, maxLength); break; default: atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); } break; case 1: /* changeable values */ atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); break; case 2: /* default values */ atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); break; default: case 3: /* saved values */ atapiCommandError(SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED); break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -