private void execSenseInterruptStatus() { this.results[0] = 0; // Zylinder this.results[1] = 0x80; // Invalid Command Issue int driveMask = 0x01; for (int i = 0; i < this.seekStatus.length; i++) { int v = this.seekStatus[i]; if (v >= 0) { if ((v & 0xF8) != 0) { this.results[1] = v | i; FloppyDiskDrive drive = getDrive(i); if (drive != null) { this.results[0] = drive.getCylinder(); } this.statusRegMain &= ~driveMask; this.seekStatus[i] = -1; break; } this.results[1] = 0; } driveMask <<= 1; } this.resultIdx = 1; setResultMode(); }
private void execIOReadSectorForWrite() { SectorData sector = null; FloppyDiskDrive drive = this.executingDrive; if (drive != null) { AbstractFloppyDisk disk = drive.getDisk(); if (disk != null) { sector = drive.readSectorByID( getArgHead(), 0, this.sectorIdCyl, this.sectorIdHead, this.sectorIdRec, this.sectorIdSizeCode); } } drive = getExecutingDrive(); if (drive != null) { if (sector != null) { this.curSector = sector; this.dataPos = 0; setByteWritable(true); } else { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg1 |= ST1_NO_DATA; this.statusReg1 |= ST1_MISSING_ADDRESS_MARK; stopExecution(); } } }
private void startReadTrack() { setExecutionMode(); clearRegs012(); this.sectorIdCyl = this.args[2]; this.sectorIdHead = this.args[3]; this.sectorIdRec = 1; this.sectorIdSizeCode = this.args[5]; this.curSectorReader = null; this.curSectorIdx = 0; this.tcEnabled = true; boolean done = false; FloppyDiskDrive drive = getArgDrive(); if (drive != null) { if (drive.isReady()) { this.dataLen = getArgDataLen(); this.executingDrive = drive; startIOTask( IOTaskCmd.READ_SECTOR_BY_INDEX, Math.max(this.tStatesPerRotation - this.tStateRotationCounter, 0)); done = true; } } if (!done) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg0 |= ST0_EQUIPMENT_CHECK; this.statusReg0 |= ST0_NOT_READY; this.statusReg0 |= (this.args[1] & HEAD_DRIVE_MASK); stopExecution(); } }
private void startReadID() { setExecutionMode(); clearRegs012(); clearSectorID(); boolean done = false; FloppyDiskDrive drive = getArgDrive(); if (drive != null) { if (drive.isReady()) { int idx = getSectorIndexByCurHeadPos(drive); if (idx >= 0) { this.executingDrive = drive; this.sectorIdRec = idx + 1; startIOTask(IOTaskCmd.READ_SECTOR_BY_INDEX, 0); done = true; } } } if (!done) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg0 |= ST0_EQUIPMENT_CHECK; this.statusReg0 |= ST0_NOT_READY; this.statusReg0 |= (this.args[1] & HEAD_DRIVE_MASK); stopExecution(); } }
private void startFormatTrack() { setExecutionMode(); clearRegs012(); clearSectorID(); boolean done = false; FloppyDiskDrive drive = getArgDrive(); if (drive != null) { if (drive.isReady()) { if (drive.isReadOnly()) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg1 |= ST1_NOT_WRITABLE; } else { setDataBuf(this.args[3] * 4); this.dataPos = -1; this.formatStatus = FormatStatus.WAIT_FOR_HOLE; this.executingDrive = drive; done = true; } } } if (!done) { if ((this.statusReg0 & ST0_ERROR_MASK) == 0) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg0 |= ST0_EQUIPMENT_CHECK; this.statusReg0 |= ST0_NOT_READY; } this.statusReg0 |= (this.args[1] & HEAD_DRIVE_MASK); stopExecution(); } }
private void execIOFormatTrack() { boolean done = false; int srcIdx = 0; FloppyDiskDrive drive = getExecutingDrive(); if (drive != null) { if (this.dataBuf != null) { int nSectors = this.dataPos / 4; if ((nSectors > 0) && ((nSectors * 4) <= this.dataBuf.length)) { int n = this.args[2] & 0x0F; int sectorSize = 128; if (n > 0) { sectorSize = (128 << n); } byte[] contentBuf = new byte[sectorSize]; Arrays.fill(contentBuf, (byte) this.args[5]); SectorID[] sectors = new SectorID[nSectors]; int dstIdx = 0; while (((srcIdx + 3) < this.dataBuf.length) && (dstIdx < sectors.length)) { int cyl = (int) this.dataBuf[srcIdx++] & 0xFF; int head = (int) this.dataBuf[srcIdx++] & 0xFF; int rec = (int) this.dataBuf[srcIdx++] & 0xFF; int sizeCode = (int) this.dataBuf[srcIdx++] & 0xFF; sectors[dstIdx++] = new SectorID(cyl, head, rec, sizeCode); } done = drive.formatTrack((this.args[1] >> 2) & 0x01, sectors, contentBuf); } } } drive = getExecutingDrive(); if (drive != null) { if (this.dataBuf.length >= 4) { this.sectorIdCyl = (int) this.dataBuf[0] & 0xFF; this.sectorIdHead = (int) this.dataBuf[0] & 0xFF; this.sectorIdRec = (int) this.dataBuf[0] & 0xFF; this.sectorIdSizeCode = (int) this.dataBuf[0] & 0xFF; } if (done) { srcIdx -= 4; if ((srcIdx + 3) < this.dataBuf.length) { this.sectorIdCyl = (int) this.dataBuf[srcIdx++] & 0xFF; this.sectorIdHead = (int) this.dataBuf[srcIdx++] & 0xFF; this.sectorIdRec = ((int) this.dataBuf[srcIdx++] & 0xFF) + 1; this.sectorIdSizeCode = (int) this.dataBuf[srcIdx] & 0xFF; } } else { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; if (this.executingDrive.isReadOnly()) { this.statusReg1 |= ST1_NOT_WRITABLE; } else { this.statusReg1 |= ST1_DATA_ERROR; this.statusReg2 |= ST2_DATA_ERROR_IN_DATA_FIELD; } } stopExecution(); } }
private void execIOWriteSector() { FloppyDiskDrive drive = this.executingDrive; boolean done = false; SectorData sector = this.curSector; if (drive != null) { if ((sector != null) && (this.dataBuf != null) && (this.dataPos >= 0)) { this.curSector = null; while ((this.dataPos < this.dataLen) && (this.dataPos < this.dataBuf.length)) { this.dataBuf[this.dataPos++] = (byte) 0; } done = drive.writeSector( getArgHead(), sector, this.dataBuf, this.dataLen, this.curCmd == Command.WRITE_DELETED_DATA); this.dataPos = -1; drive = this.executingDrive; if (drive != null) { if (done) { incSectorNum(); synchronized (this.ioTaskThread) { if (this.tcFired) { stopExecution(); } else { startIOTask(IOTaskCmd.READ_SECTOR_FOR_WRITE, this.tStatesPerRotation); } } } else { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; if (drive.isReadOnly()) { this.statusReg1 |= ST1_NOT_WRITABLE; } else { this.statusReg1 |= ST1_DATA_ERROR; this.statusReg2 |= ST2_DATA_ERROR_IN_DATA_FIELD; } stopExecution(); } } } else { if (this.tcFired) { stopExecution(); } } } }
private void execSenseDriveStatus() { this.statusReg3 = (this.args[1] & HEAD_DRIVE_MASK); FloppyDiskDrive drive = getArgDrive(); if (drive != null) { this.statusReg3 |= ST3_TWO_SIDE; if (drive.getCylinder() == 0) { this.statusReg3 |= ST3_TRACK_0; } if (drive.isReady()) { this.statusReg3 |= ST3_READY; } if (drive.isReadOnly()) { this.statusReg3 |= ST3_WRITE_PROTECTED; } } this.results[0] = this.statusReg3; this.resultIdx = 0; setResultMode(); }
private int getSectorIndexByCurHeadPos(FloppyDiskDrive drive) { int idx = -1; if (drive != null) { AbstractFloppyDisk disk = drive.getDisk(); if (disk != null) { int head = getArgHead(); int cyl = drive.getCylinder(); int spc = disk.getSectorsOfCylinder(cyl, head); int tpr = this.tStatesPerRotation; if ((spc > 0) && (tpr > 0) && (head < disk.getSides()) && (cyl < disk.getCylinders())) { idx = Math.round((float) this.tStateRotationCounter / (float) tpr * (float) spc); if (idx >= spc) { idx = spc - 1; } } if (idx < 0) { idx = 0; } } } return idx; }
/* * Die Methode fuehrt einen Schrittimpuls aus. * Bei Erreichen des Zielzylinders werden die entsprechenden Bits * im Hauptstatusregister hier noch nicht zurueckgesetzt, * sondern erst beim Sense-Interrupt-Status-Befehl. */ private void execSeekStep() { boolean seekMode = false; int driveMask = 0x01; for (int i = 0; i < this.remainSeekSteps.length; i++) { boolean driveSeekMode = false; if (this.remainSeekSteps[i] > 0) { FloppyDiskDrive drive = getDrive(i); if (drive != null) { --this.remainSeekSteps[i]; if (drive.seekStep()) { this.seekStatus[i] |= ST0_SEEK_END; this.interruptReq = true; } else { if (this.remainSeekSteps[i] > 0) { driveSeekMode = true; } else { this.seekStatus[i] |= ST0_ABNORMAL_TERMINATION; this.seekStatus[i] |= ST0_SEEK_END; this.seekStatus[i] |= ST0_EQUIPMENT_CHECK; this.interruptReq = true; } } } else { this.seekStatus[i] |= ST0_ABNORMAL_TERMINATION; this.seekStatus[i] |= ST0_SEEK_END; this.seekStatus[i] |= ST0_NOT_READY; this.interruptReq = true; } } if (driveSeekMode) { seekMode = true; } else { this.remainSeekSteps[i] = 0; } driveMask <<= 1; } this.seekMode = seekMode; }
private void startWriteData() { setExecutionMode(); clearRegs012(); this.sectorIdCyl = this.args[2]; this.sectorIdHead = this.args[3]; this.sectorIdRec = this.args[4]; this.sectorIdSizeCode = this.args[5]; this.curSector = null; this.tcEnabled = true; boolean done = false; FloppyDiskDrive drive = getArgDrive(); if (drive != null) { if (drive.isReady()) { if (drive.isReadOnly()) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg1 |= ST1_NOT_WRITABLE; } else { if (!this.dmaMode) { this.statusRegMain |= STM_NON_DMA_MODE; } setDataBuf(getArgDataLen()); this.dataPos = -1; this.executingDrive = drive; startIOTask(IOTaskCmd.READ_SECTOR_FOR_WRITE, 0); done = true; } } } if (!done) { if ((this.statusReg0 & ST0_ERROR_MASK) == 0) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg0 |= ST0_EQUIPMENT_CHECK; this.statusReg0 |= ST0_NOT_READY; } this.statusReg0 |= (this.args[1] & HEAD_DRIVE_MASK); stopExecution(); } }
private void startReadDataOrScan() { setExecutionMode(); clearRegs012(); this.sectorIdCyl = this.args[2]; this.sectorIdHead = this.args[3]; this.sectorIdRec = this.args[4]; this.sectorIdSizeCode = this.args[5]; this.curSectorReader = null; this.tcEnabled = true; boolean done = false; FloppyDiskDrive drive = getArgDrive(); if (drive != null) { if (drive.isReady()) { if ((this.curCmd == Command.SCAN_EQUAL) || (this.curCmd == Command.SCAN_LOW_OR_EQUAL) || (this.curCmd == Command.SCAN_HIGH_OR_EQUAL)) { this.dataLen = 128; this.args[5] &= 0x0F; if (this.args[5] > 0) { this.dataLen = (128 << this.args[5]); } this.statusReg2 |= ST2_SCAN_EQUAL_HIT; } else { this.dataLen = getArgDataLen(); } this.executingDrive = drive; startIOTask(IOTaskCmd.READ_SECTOR_BY_ID, 0); done = true; } } if (!done) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg0 |= ST0_EQUIPMENT_CHECK; this.statusReg0 |= ST0_NOT_READY; this.statusReg0 |= (this.args[1] & HEAD_DRIVE_MASK); stopExecution(); } }
private void seek(int driveNum, int head, int cyl) { this.statusRegMain &= ~STM_BUSY; this.statusReg0 = 0; if ((driveNum >= 0) && (driveNum < this.seekStatus.length)) { this.seekStatus[driveNum] = ((head << 2) & HEAD_MASK) | driveNum; FloppyDiskDrive drive = getDrive(driveNum); if (drive != null) { if (drive.getCylinder() == cyl) { this.seekStatus[driveNum] |= ST0_SEEK_END; this.interruptReq = true; } else { if (driveNum > 0) { this.statusRegMain |= (1 << driveNum); } else { this.statusRegMain |= 0x01; } drive.setSeekMode(head, cyl); this.remainSeekSteps[driveNum] = 77; if (!this.seekMode) { this.tStateStepCounter = 0; this.seekMode = true; } } } else { this.seekStatus[driveNum] |= ST0_ABNORMAL_TERMINATION; this.seekStatus[driveNum] |= ST0_NOT_READY; this.seekStatus[driveNum] |= ST0_SEEK_END; this.interruptReq = true; } } else { this.statusReg0 |= ST0_ABORT_BECAUSE_READY_CHANGED; this.statusReg0 |= ST0_SEEK_END; this.statusReg0 |= ST0_NOT_READY; this.statusReg0 |= ((head << 2) & HEAD_MASK); this.statusReg0 |= (driveNum & DRIVE_MASK); this.interruptReq = true; } }
private void execIOReadSectorByIndex() { SectorData sector = null; FloppyDiskDrive drive = this.executingDrive; if (drive != null) { sector = drive.readSectorByIndex(getArgHead(), this.sectorIdRec - 1); } drive = getExecutingDrive(); if (drive != null) { if (sector != null) { this.curSector = sector; this.curSectorReader = sector.reader(); this.remainBytes = this.dataLen; if (this.curCmd == Command.READ_TRACK) { setByteReadable(); } else { this.sectorIdCyl = sector.getCylinder(); this.sectorIdHead = sector.getHead(); this.sectorIdRec = sector.getSectorNum(); this.sectorIdSizeCode = sector.getSizeCode(); if (sector.isEmpty()) { this.statusReg1 |= ST1_MISSING_ADDRESS_MARK; this.statusReg2 |= ST2_MISSING_DATA_ADDRESS_MARK; } stopExecution(); } } else { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; if (this.sectorIdRec == 1) { this.statusReg1 |= ST1_NO_DATA; this.statusReg1 |= ST1_MISSING_ADDRESS_MARK; } else { this.statusReg1 |= ST1_END_OF_CYLINDER; } stopExecution(); } } }
private void execIOReadSectorByID() { boolean cmAbort = false; SectorData sector = null; FloppyDiskDrive drive = this.getExecutingDrive(); if (drive != null) { AbstractFloppyDisk disk = drive.getDisk(); if (disk != null) { int head = getArgHead(); if (disk.supportsDeletedSectors()) { int startIdx = getSectorIndexByCurHeadPos(drive); if (startIdx >= 0) { boolean loop = true; int endIdx = -1; int curIdx = startIdx; while (loop && ((curIdx < endIdx) || (endIdx < 0))) { sector = drive.readSectorByIndex(head, curIdx); if ((sector == null) && (startIdx > 0)) { // zum Spuranfang springen endIdx = startIdx; startIdx = 0; curIdx = 0; } else { loop = false; if (sector != null) { if (this.curCmd == Command.READ_DELETED_DATA) { if (!sector.isDeleted()) { this.statusReg2 |= ST2_CONTROL_MARK; if ((this.args[0] & ARG0_SK_MASK) != 0) { curIdx++; loop = true; } else { cmAbort = true; } } } else { if (sector.isDeleted()) { this.statusReg2 |= ST2_CONTROL_MARK; if ((this.args[0] & ARG0_SK_MASK) != 0) { curIdx++; loop = true; } else { cmAbort = true; } } } if (!loop && ((sector.getCylinder() != this.sectorIdCyl) || (sector.getHead() != this.sectorIdHead) || (sector.getSectorNum() != this.sectorIdRec) || (sector.getSizeCode() != this.sectorIdSizeCode))) { curIdx++; loop = true; } } } } } } else { sector = drive.readSectorByID( head, 0, this.sectorIdCyl, this.sectorIdHead, this.sectorIdRec, this.sectorIdSizeCode); } } } drive = getExecutingDrive(); if (drive != null) { if (sector != null) { if (sector.checkError()) { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; this.statusReg1 |= ST1_DATA_ERROR; this.statusReg2 |= ST2_DATA_ERROR_IN_DATA_FIELD; } this.curSector = sector; this.curSectorReader = sector.reader(); this.remainBytes = this.dataLen; startIOReqTimer(); } else { this.statusReg0 |= ST0_ABNORMAL_TERMINATION; if (!cmAbort) { if ((this.sectorIdCyl == this.args[2]) && (this.sectorIdHead == this.args[3]) && (this.sectorIdRec == this.args[4])) { this.statusReg1 |= ST1_NO_DATA; this.statusReg1 |= ST1_MISSING_ADDRESS_MARK; } else { this.statusReg1 |= ST1_END_OF_CYLINDER; } } stopExecution(); } } }