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

📄 floppyctrlr.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
📖 第 1 页 / 共 2 页
字号:
	  uint32_t cyl = sec / mediaInfo->secsPerCyl;	  sec -= (cyl *   mediaInfo->secsPerCyl);	  uint32_t hd = sec /  mediaInfo->secsPerTrack;	  sec -= (cyl *  mediaInfo->secsPerTrack);	  	  assert((ioCount % EROS_SECTOR_SIZE) == 0);		  /* move to cylinder of request */	  FdSeek(u, cyl, hd);      	  uint32_t xfer = ioCount;	  uint32_t topSec = sec + xfer / EROS_SECTOR_SIZE; 	  if (topSec > mediaInfo->secsPerTrack)	    topSec = mediaInfo->secsPerTrack;	  xfer = (topSec - sec) * EROS_SECTOR_SIZE;	  /* FIX: bad sectors may require a change of plans here. */	  if (!started)	    ior->CommitUnitRequest(uior);	  	  uint32_t xferSecs = 0;	 	  switch(ior->cmd) {	  case IOCMD::Read:	    {	     	      	      /* We hand it how much we want to move, it hands back how	       * much it WILL move:	       */	      xfer = DMA::read(FloppyDmaChan, ioAddr, xfer);	      assert ((xfer % EROS_SECTOR_SIZE) == 0); /* can't happen :-) */	      xferSecs = xfer / EROS_SECTOR_SIZE;	      FdReadWrite(false, u, cyl, hd, sec, xferSecs);		  	      DMA::flush(FloppyDmaChan);	      /* if unit or dma error, fail the request with error code */	      break;	    }	  case IOCMD::Write:	    {	    	      	      /* We hand it how much we want to move, it hands back how	       * much it WILL move:	       */	      xfer = DMA::write(FloppyDmaChan, ioAddr, xfer);	      assert ((xfer % EROS_SECTOR_SIZE) == 0); /* can't happen :-) */	      xferSecs = xfer / EROS_SECTOR_SIZE;	      FdReadWrite(true, u, cyl, hd, sec, xferSecs);	      DMA::flush(FloppyDmaChan);	      /* if unit or dma error, fail the request with error code */	      break;	    }	  case IOCMD::None:	    /* This should not happen! */	    break;	  case IOCMD::FormatTrack:	    /* temporary placeholder to keep compiler happy */	    assert(false);	    break;	  }	  ioCount -= xfer;	  ioAddr += xfer;	  ioSec += xferSecs;	}	ior->FinishUnitRequest(uior, IOR::OK);		unit[u]->RemoveRequest(uior);      }    }        printf("FloppyCtrlr going idle\n");    WakeUpAtTick(wakeTime);    SleepOn(IdleQ, Thread::Stall);    Yield(true);  }   }voidProbe(struct AutoConf* ac){  /*  Machine::WireInterrupt(IntFloppy, ... ); */  ac->present = false;}static void StartCtrlr(uint32_t /* unit */){  IdleQ.WakeAll();}static voidAttach(struct AutoConf* /* ac */){  TheFloppyCtrlr.unit[0] = new DiskUnit("fda0", StartCtrlr, 0);  TheFloppyCtrlr.unit[0]->bootMount = false;  /* assume first drive is a 1.44 */  TheFloppyCtrlr.unit[0]->mediaInfo  = &MediaParams[4];  for(int i= 1; i <=FloppyCtrlr::NUNITS;i++)    TheFloppyCtrlr.unit[i] = 0;        /* assume the other drives do */				       /* not exist */        TheFloppyCtrlr.Wakeup();}void FloppyCtrlr::FdSeek(uint32_t u, uint32_t cyl, uint32_t hd){  for(int tries = 0; tries < 2; tries++) {        /* Activate the drive control pins: */    dor &= ~3;    dor |= u;    outb(NECREG::DOR, dor);    Delay(1);			/* 1 ms settling time */        OutFloppyCtrlr(NECCMD::SEEK);    OutFloppyCtrlr((hd<<2)|u);    OutFloppyCtrlr(cyl);        WakeUpIn(500);		/* half-second timeout on floppy seeks */#if 0    SleepOn(IDT::GetInterruptQueue(IntFloppy), Thread::Stall);#endif    Yield();        /* verify correct track */    OutFloppyCtrlr(NECCMD::SENSEI);        if (GetResults() != 2) {      /* controller is hosed - resetting it should restart the requests. */            Reset();      fatal("FDC::seek_intr(): Floppy not responding");            return;    }    /* if failed, seek again...     * update current location info     */        uint32_t sr0 = results[0];        if ((sr0 & (SR0::EquipChk | SR0::IC | SR0::SeekEnd)) ==	SR0::SeekEnd) {             /* Completed successfully */      unit[u]->curCyl = results[1];        /* update the unit structure */      return;                              /* exit, we suceeded */    }#if 0    else {  /* recalibrate.  If this was the first try, we will try again. */    }#endif  }  /* if we made it here, we could not find the data */}void FloppyCtrlr::FdReadWrite(bool iswrite, uint32_t  u, uint32_t cyl, uint32_t hd,			 uint32_t sec, uint32_t /* xferSecs */){  bool done = true;  int  tries= 0;  do {    done = true;        /* Activate the drive control pins: */    dor &= ~3;    dor |= u;    outb(NECREG::DOR, dor);    Delay(1);  /* we would simply want to sleep here, right? */        OutFloppyCtrlr(iswrite? NECCMD::WRITE : NECCMD::READ);    OutFloppyCtrlr((hd<<2)|u);    OutFloppyCtrlr(cyl);    OutFloppyCtrlr(hd);    OutFloppyCtrlr(sec+1);    OutFloppyCtrlr(0x2u);		/* 512 byte sector size */    OutFloppyCtrlr(unit[u]->mediaInfo->secsPerTrack); /* sectors per track */    OutFloppyCtrlr(unit[u]->mediaInfo->fmt_gap);    OutFloppyCtrlr(0xff);		/* DTL?? */    /* check to see if it worked */    if (GetResults() != 7) {      /* controller is hosed - resetting it should restart the requests. */      Reset();      fatal("FDC::rw_intr(): Floppy not responding");      /* exit function */      return;                          }        uint32_t sr0 = results[0];#if 0        /* We should not have interrupted or run off the end of the     * drive. We should not have needed to seek.     */        if ((sr0 & SR0::IC) == 0) {      /* We now need to decide if we are done with the operation or       * not.  If the operation went over a track boundary, we need       * to hack track, head, sector, and nsec and start over:       */            unit[u]->mediaInfo->secsPerTrack -= secsToXfer;      if (unit[u]->mediaInfo->secsPerTrack) {		du.start += secsToXfer;	iokva += (secsToXfer * EROS_SECTOR_SIZE);    }    }#endif        /* FIX: Seeking is probably panicworthy. */    if (sr0 & (SR0::EquipChk | SR0::SeekEnd | SR0::IC))      fatal("FDC: Unexpected seek\n");        uint8_t sr1 = results[1];        /* A CRC error just means a bad sector.  We should retry: */    if (sr1 & (SR1::BadCrc | SR1::NoData)) {      done = false;    }#if 0    /* An overrun or going past end of cylinder is (for the moment)     * a fatal problem. Something is wrong with the kernel:     */    if (DMA::get_residue(DMAC::FLOPPY) ||	(sr1 & (SR1::Overrun | SR1::CylEnd)))      fatal(0,"DMA Overrun by fd%d\n", unit);#endif        tries++; }  while((tries < READ_WRITE_TRIES) && !done);}  /* DMAC is commented out, since I cannot find it. *//* void FloppyCtrlr::FdWrite(uint32_t /* u */, uint32_t /* cyl */, uint32_t /* hd */, * 			  uint32_t /* sec */, uint32_t /* xferSecs */) { * } */void FloppyCtrlr::OutFloppyCtrlr(uint8_t b){#ifdef FDCIODEBUG  printf("FDC::OutFDC(%x)\n", b);#endif  uint8_t r = 0;  for (int i = 0; i < 10000; i++) {    r = inb(NECREG::STATUS);    r &= (STATUS::Master | STATUS::ReqRead);        if (r == STATUS::Master) {      outb(NECREG::DATA, b);      return;    }  }    fatal("FDC::OutFDC() failed. Status Reg = %x\n", r);}int FloppyCtrlr::GetResults(){  int i, n = 0;    for (i = 0 ; i < 1000 ; i++) {    uint8_t r = inb(NECREG::STATUS);    r &= (STATUS::Master|STATUS::ReqRead|STATUS::CmdBusy);        if (r == STATUS::Master) {	  /* not busy, ready for commands */      return n;    }    if (r == (STATUS::Master|STATUS::ReqRead|STATUS::CmdBusy)) {      if (n >= 8) {	fatal("FDC::GetResults(): too many answers\n");	break;      }      results[n] = inb(NECREG::DATA);#ifdef FDCIODEBUG      printf("results[%d] = 0x%x\n", n, results[n]);#endif      n++;    }  }    fatal("FDC::getStatus(): couldn't get status\n");  return -1;}void FloppyCtrlr::Reset(/* unit */){ fatal("FloppyCtrlr::Reset(): Drive in unknown state, reset");}  /* reset the drive. *//* MOTOR (MIS)MANAGEMENT: */void FloppyCtrlr::StartMotor(uint32_t unit){  printf("Time to start motor, unit %d\n", unit);}void FloppyCtrlr::StopMotor(uint32_t unit){  printf("Time to stop motor, unit %d\n", unit);}#endif

⌨️ 快捷键说明

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