コード例 #1
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
  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();
  }
コード例 #2
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
     }
   }
 }
コード例 #3
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
   }
 }
コード例 #4
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
   }
 }
コード例 #5
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
   }
 }
コード例 #6
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
  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();
    }
  }
コード例 #7
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
       }
     }
   }
 }
コード例 #8
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
 }
コード例 #9
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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;
 }
コード例 #10
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 /*
  * 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;
 }
コード例 #11
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
   }
 }
コード例 #12
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
   }
 }
コード例 #13
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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;
   }
 }
コード例 #14
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
     }
   }
 }
コード例 #15
0
ファイル: FDC8272.java プロジェクト: rexut/jkcemu
 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();
     }
   }
 }