示例#1
0
        /// <summary>
        /// Main constructor
        /// </summary>
        /// <param name="spectrum"></param>
        /// <param name="cpu"></param>
        public CPC6128(AmstradCPC cpc, Z80A cpu, List <byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
        {
            CPC = cpc;
            CPU = cpu;

            FrameLength = 79872;

            CRCT = new CRCT_6845(CRCT_6845.CRCTType.MC6845, this);
            //CRT = new CRTDevice(this);
            GateArray = new AmstradGateArray(this, AmstradGateArray.GateArrayType.Amstrad40007);
            PPI       = new PPI_8255(this);

            TapeBuzzer = new Beeper(this);
            TapeBuzzer.Init(44100, FrameLength);

            //AYDevice = new PSG(this, PSG.ay38910_type_t.AY38910_TYPE_8912, GateArray.PSGClockSpeed, 882 * 50);
            AYDevice = new AY38912(this);
            AYDevice.Init(44100, FrameLength);

            KeyboardDevice = new StandardKeyboard(this);

            TapeDevice = new DatacorderDevice(autoTape);
            TapeDevice.Init(this);

            UPDDiskDevice = new NECUPD765();
            UPDDiskDevice.Init(this);

            InitializeMedia(files);
        }
示例#2
0
            /*
             * /// <summary>
             * /// Moves the head across the disk cylinders
             * /// </summary>
             * /// <param name="direction"></param>
             * /// <param name="cylinderCount"></param>
             * public void MoveHead(SkipDirection direction, int cylinderCount)
             * {
             *  // get total tracks
             *  int trackCount = Disk.DiskTracks.Count();
             *
             *  int trk = 0;
             *
             *  switch (direction)
             *  {
             *      case SkipDirection.Increment:
             *          trk = (int)CurrentTrack + cylinderCount;
             *          if (trk >= trackCount)
             *          {
             *              // past the last track
             *              trk = trackCount - 1;
             *          }
             *          else if (trk < 0)
             *              trk = 0;
             *          break;
             *      case SkipDirection.Decrement:
             *          trk = (int)CurrentTrack - cylinderCount;
             *          if (trk < 0)
             *          {
             *              // before the first track
             *              trk = 0;
             *          }
             *          else if (trk >= trackCount)
             *              trk = trackCount - 1;
             *          break;
             *  }
             *
             *  // move the head
             *  CurrentTrack = (byte)trk;
             * }
             */

            /*
             *
             * /// <summary>
             * /// Finds a supplied sector
             * /// </summary>
             * /// <param name="resBuffer"></param>
             * /// <param name=""></param>
             * /// <param name=""></param>
             * /// <returns></returns>
             * public FloppyDisk.Sector FindSector(ref byte[] resBuffer, CommandParameters prms)
             * {
             *  int index =CurrentSector;
             *  int lc = 0;
             *  FloppyDisk.Sector sector = null;
             *
             *  bool found = false;
             *
             *  do
             *  {
             *      sector = Disk.DiskTracks[CurrentTrack].Sectors[index];
             *      if (sector != null && sector.SectorID == prms.Sector)
             *      {
             *          // sector found
             *          // check for data errors
             *          if ((sector.Status1 & 0x20) != 0 || (sector.Status2 & 0x20) != 0)
             *          {
             *              // data errors found
             *          }
             *          found = true;
             *          break;
             *      }
             *
             *      // sector doesnt match
             *      var c = Disk.DiskTracks[CurrentTrack].Sectors[index].TrackNumber;
             *      if (c == 255)
             *      {
             *          // bad cylinder
             *          resBuffer[RS_ST2] |= 0x02;
             *      }
             *      else if (prms.Cylinder != c)
             *      {
             *          // cylinder mismatch
             *          resBuffer[RS_ST2] |= 0x10;
             *      }
             *
             *      // increment index
             *      index++;
             *
             *      if (index >= Disk.DiskTracks[CurrentTrack].NumberOfSectors)
             *      {
             *          // out of bounds
             *          index = 0;
             *          lc++;
             *      }
             *
             *  } while (lc < 2);
             *
             *  if ((resBuffer[RS_ST2] & 0x02) != 0)
             *  {
             *      // bad cylinder set - remove no cylinder
             *      UnSetBit(SR2_WC, ref resBuffer[RS_ST2]);
             *  }
             *
             *  // update current sector
             *  CurrentSector = index;
             *
             *  if (found)
             *      return sector;
             *  else
             *      return null;
             * }
             *
             *
             * /// <summary>
             * /// Populates a result buffer
             * /// </summary>
             * /// <param name="resBuffer"></param>
             * /// <param name="chrn"></param>
             * public void FillResult(ref byte[] resBuffer, CHRN chrn)
             * {
             *  // clear results
             *  resBuffer[RS_ST0] = 0;
             *  resBuffer[RS_ST1] = 0;
             *  resBuffer[RS_ST2] = 0;
             *  resBuffer[RS_C] = 0;
             *  resBuffer[RS_H] = 0;
             *  resBuffer[RS_R] = 0;
             *  resBuffer[RS_N] = 0;
             *
             *  if (chrn == null)
             *  {
             *      // no chrn supplied
             *      resBuffer[RS_ST0] = ST0;
             *      resBuffer[RS_ST1] = 0;
             *      resBuffer[RS_ST2] = 0;
             *      resBuffer[RS_C] = 0;
             *      resBuffer[RS_H] = 0;
             *      resBuffer[RS_R] = 0;
             *      resBuffer[RS_N] = 0;
             *  }
             * }
             *
             *
             *
             * /// <summary>
             * /// Populates the result buffer with ReadID data
             * /// </summary>
             * /// <returns></returns>
             * public void ReadID(ref byte[] resBuffer)
             * {
             *  if (CheckDriveStatus() == false)
             *  {
             *      // drive not ready
             *      resBuffer[RS_ST0] = ST0;
             *      return;
             *  }
             *
             *  var track = Disk.DiskTracks.Where(a => a.TrackNumber == CurrentTrack).FirstOrDefault();
             *
             *  if (track != null && track.NumberOfSectors > 0)
             *  {
             *      // formatted track
             *
             *      // get the current sector
             *      int index = CurrentSector;
             *
             *      // is the index out of bounds?
             *      if (index >= track.NumberOfSectors)
             *      {
             *          // reset the index
             *          index = 0;
             *      }
             *
             *      // read the sector data
             *      var data = track.Sectors[index];
             *      resBuffer[RS_C] = data.TrackNumber;
             *      resBuffer[RS_H] = data.SideNumber;
             *      resBuffer[RS_R] = data.SectorID;
             *      resBuffer[RS_N] = data.SectorSize;
             *
             *      resBuffer[RS_ST0] = ST0;
             *
             *      // increment the current sector
             *      CurrentSector = index + 1;
             *      return;
             *  }
             *  else
             *  {
             *      // unformatted track?
             *      resBuffer[RS_C] = FDC.CommBuffer[CM_C];
             *      resBuffer[RS_H] = FDC.CommBuffer[CM_H];
             *      resBuffer[RS_R] = FDC.CommBuffer[CM_R];
             *      resBuffer[RS_N] = FDC.CommBuffer[CM_N];
             *
             *      SetBit(SR0_IC0, ref ST0);
             *      resBuffer[RS_ST0] = ST0;
             *      resBuffer[RS_ST1] = 0x01;
             *      return;
             *  }
             * }
             */

            /*
             *
             * /// <summary>
             * /// The drive performs a seek operation if necessary
             * /// Return value TRUE indicates seek complete
             * /// </summary>
             * public void DoSeek()
             * {
             *  if (CurrentState != DriveMainState.Recalibrate &&
             *      CurrentState != DriveMainState.Seek)
             *  {
             *      // no seek/recalibrate has been asked for
             *      return;
             *  }
             *
             *  if (GetBit(ID, FDC.StatusMain))
             *  {
             *      // drive is already seeking
             *      return;
             *  }
             *
             *  RunSeekCycle();
             * }
             *
             * /// <summary>
             * /// Runs a seek cycle
             * /// </summary>
             * public void RunSeekCycle()
             * {
             *  for (;;)
             *  {
             *      switch (SeekState)
             *      {
             *          // seek or recalibrate has been requested
             *          case SeekSubState.Idle:
             *
             *              if (CurrentState == DriveMainState.Recalibrate)
             *              {
             *                  // recalibrate always seeks to track 0
             *                  SeekingTrack = 0;
             *              }
             *              SeekState = SeekSubState.MoveInit;
             *
             *              // mark drive as busy
             *              // this should be cleared by SIS command
             *              SetBit(ID, ref FDC.StatusMain);
             *
             *              break;
             *
             *          // setup for the head move
             *          case SeekSubState.MoveInit:
             *
             *              if (CurrentTrack == SeekingTrack)
             *              {
             *                  // we are already at the required track
             *                  if (CurrentState == DriveMainState.Recalibrate &&
             *                      !FLAG_TRACK0)
             *                  {
             *                      // recalibration fail
             *                      SeekIntState = SeekIntStatus.Abnormal;
             *
             *                      // raise seek interrupt
             *                      FDC.ActiveInterrupt = InterruptState.Seek;
             *
             *                      // unset DB bit
             *                      UnSetBit(ID, ref FDC.StatusMain);
             *
             *                      // equipment check
             *                      SetBit(SR0_EC, ref FDC.Status0);
             *
             *                      SeekState = SeekSubState.PerformCompletion;
             *                      break;
             *                  }
             *
             *                  if (CurrentState == DriveMainState.Recalibrate &&
             *                      FLAG_TRACK0)
             *                  {
             *                      // recalibration success
             *                      SeekIntState = SeekIntStatus.Normal;
             *
             *                      // raise seek interrupt
             *                      FDC.ActiveInterrupt = InterruptState.Seek;
             *
             *                      // unset DB bit
             *                      UnSetBit(ID, ref FDC.StatusMain);
             *
             *                      SeekState = SeekSubState.PerformCompletion;
             *                      break;
             *                  }
             *              }
             *
             *              // check for error
             *              if (IntStatus >= IC_ABORTED_DISCREMOVED || Disk == null)
             *              {
             *                  // drive not ready
             *                  FLAG_READY = false;
             *
             *                  // drive not ready
             *                  SeekIntState = SeekIntStatus.DriveNotReady;
             *
             *                  // cancel any interrupt
             *                  FDC.ActiveInterrupt = InterruptState.None;
             *
             *                  // unset DB bit
             *                  UnSetBit(ID, ref FDC.StatusMain);
             *
             *                  SeekState = SeekSubState.PerformCompletion;
             *                  break;
             *              }
             *
             *              if (SeekCounter > 1)
             *              {
             *                  // not ready to seek yet
             *                  SeekCounter--;
             *                  return;
             *              }
             *
             *              if (FDC.SRT < 1 && CurrentTrack != SeekingTrack)
             *              {
             *                  SeekState = SeekSubState.MoveImmediate;
             *                  break;
             *              }
             *
             *              // head move
             *              SeekState = SeekSubState.HeadMove;
             *
             *              break;
             *
             *          case SeekSubState.HeadMove:
             *
             *              // do the seek
             *              SeekCounter = FDC.SRT;
             *
             *              if (CurrentTrack < SeekingTrack)
             *              {
             *                  // we are seeking forward
             *                  var delta = SeekingTrack - CurrentTrack;
             *                  MoveHead(SkipDirection.Increment, 1);
             *              }
             *              else if (CurrentTrack > SeekingTrack)
             *              {
             *                  // we are seeking backward
             *                  var delta = CurrentTrack - SeekingTrack;
             *                  MoveHead(SkipDirection.Decrement, 1);
             *              }
             *
             *              // should the seek be completed now?
             *              if (CurrentTrack == SeekingTrack)
             *              {
             *                  SeekState = SeekSubState.PerformCompletion;
             *                  break;
             *              }
             *
             *              // seek not finished yet
             *              return;
             *
             *          // seek emulation processed immediately
             *          case SeekSubState.MoveImmediate:
             *
             *              if (CurrentTrack < SeekingTrack)
             *              {
             *                  // we are seeking forward
             *                  var delta = SeekingTrack - CurrentTrack;
             *                  MoveHead(SkipDirection.Increment, delta);
             *
             *              }
             *              else if (CurrentTrack > SeekingTrack)
             *              {
             *                  // we are seeking backward
             *                  var delta = CurrentTrack - SeekingTrack;
             *                  MoveHead(SkipDirection.Decrement, delta);
             *              }
             *
             *              SeekState = SeekSubState.PerformCompletion;
             *              break;
             *
             *          case SeekSubState.PerformCompletion:
             *              SeekDone();
             *              SeekState = SeekSubState.SeekCompleted;
             *              break;
             *
             *          case SeekSubState.SeekCompleted:
             *              // seek has already completed
             *              return;
             *      }
             *  }
             * }
             *
             * /// <summary>
             * /// Called when a seek operation has completed
             * /// </summary>
             * public void SeekDone()
             * {
             *  SeekCounter = 0;
             *  SeekingTrack = CurrentTrack;
             *
             *  // generate ST0 register data
             *
             *  // get only the IC bits
             *  IntStatus &= IC_ABORTED_DISCREMOVED;
             *
             *  // drive ready?
             *  if (!FLAG_READY)
             *  {
             *      SetBit(SR0_NR, ref IntStatus);
             *      SetBit(SR0_EC, ref IntStatus);
             *
             *      // are we recalibrating?
             *      if (CurrentState == DriveMainState.Recalibrate)
             *      {
             *          SetBit(SR0_EC, ref IntStatus);
             *      }
             *  }
             *
             *  // set seek end
             *  SetBit(SR0_SE, ref IntStatus);
             *  /*
             *  // head address
             *  if (CurrentSide > 0)
             *  {
             *      SetBit(SR0_HD, ref IntStatus);
             *
             *      // drive only supports 1 head
             *      // set the EC bit
             *      SetBit(SR0_EC, ref IntStatus);
             *  }
             */
            /*
             * // UnitSelect
             * SetUnitSelect(ID, ref IntStatus);
             *
             * // move to none state
             * //CurrentState = DriveMainState.None;
             *
             * //SeekState = SeekSubState.SeekCompleted;
             *
             * // set the seek interrupt flag for this drive
             * // this will be cleared at the next successful senseint
             * FLAG_SEEK_INTERRUPT = true;
             *
             * //CurrentState = DriveMainState.None;
             *
             * }
             */

            #endregion

            #region Construction

            public DriveState(int driveID, NECUPD765 fdc)
            {
                ID  = driveID;
                FDC = fdc;
            }