home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / rmfiles.zip / mitsrc.zip / CDREADY.C < prev    next >
C/C++ Source or Header  |  1994-07-13  |  20KB  |  490 lines

  1. #define INCL_DOSINFOSEG
  2. #define INCL_NOPMAPI
  3. #define INCL_NO_SCB
  4. #define INCL_INITRP_ONLY
  5.  
  6. #include <os2.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <dos.h>
  10. #include <sas.h>
  11. #include "devcmd.h"
  12.  
  13. #include "iorb.h"
  14. #include "reqpkt.h"
  15. #include "addcalls.h"
  16. #include "dskinit.h"
  17.  
  18. #include <scsi.h>
  19. #include <cdbscsi.h>
  20. #include <cmd.h>
  21. #include <devhelp.h>
  22. #include <cdb.h>
  23. #include "proto.h"
  24.  #include <string.h>
  25.  #include <memory.h>
  26.  
  27.  
  28.  extern PGINFOSEG near PGinfo;
  29.  extern ULONG near DevHlp;
  30.  extern PUCHAR near Read_IOBuffer;
  31.  extern USHORT near IrqNum;
  32.  extern USHORT near DrvBlockSize;
  33.  UCHAR PreviousOpCode,PreviousStatus;
  34.  extern UCHAR near Mode;
  35.  
  36.  
  37.       TOCINFO TOCInfoArea[101] = { {0,},};
  38.       UCHAR  bPlayFlag = FALSE ;
  39.       UCHAR  bPauseFlag = FALSE ;
  40.       UCHAR  bChangeFlag ;
  41.       UCHAR  bInfoFlag = 0 ;
  42.       UCHAR  bMedChgFlag = CHANGED ;
  43.       UCHAR  bMedChkFlag = FALSE ;
  44.       UCHAR  bMedChkCalled = FALSE ;
  45.       UCHAR  bStatus =0;
  46.       USHORT  bStatusFlag=0;
  47.       extern UCHAR near bCFlag, near last_data_byte;
  48.       UCHAR TOC_Cache=0;
  49.       UCHAR  bMinTno=0, bMaxTno =0,bChanged=0;
  50.       ULONG  ulVSSize =0;
  51.       ULONG  ulLeadOut =0;
  52.       UCHAR  CD_ID=0;
  53.       USHORT wBlkLen =0;
  54.       ULONG  Specialbuffer=NULL;
  55.  
  56. BOOL GetTocInfo()
  57. {
  58. USHORT i=0,state,First_Track_in_Session,Last_Track_in_Session,count,Status,q,Delta=0;
  59. CDROMSTAT Data ;
  60. BOOL Flag=FALSE,SeekRunning,ModeSetState;
  61. ULONG Clock=0L,Addr;
  62. UCHAR m,s,f;
  63. #define NoneFound  0
  64. #define FirstFound 1
  65. #define LastFound  2
  66. #define AllFound   3
  67. #define MaxFound   7
  68. #define LowTrack  0xa0
  69. #define HighTrack 0xa1
  70. #define BridgeTrk 0xb0
  71. #define MaxTrack 0x99
  72.  
  73.         CD_ID=0;
  74.         Addr=MinFrame;
  75.  
  76.         newloop:;
  77.  
  78.         SeekRunning=FALSE;
  79.         ModeSetState=FALSE;
  80.  
  81.         for(i=0; i<5; i++)
  82.           {
  83.           DPRINTF(("Seeking to %08lX\n",Addr));
  84.           bStatusFlag=DriveCommand(Seek,Addr,NULL,NULL,(USHORT)NULL);
  85.           DPRINTF(("Seeking to %08lX status=%04X\n",Addr,bStatusFlag));
  86.           if( !COMMANDCHECK(bStatusFlag) && !TIMEOUT(bStatusFlag))
  87.             {
  88.             SeekRunning=TRUE;
  89.             break;
  90.             } /* end if */
  91.           else
  92.             {
  93.             DUMMYWAIT;
  94.             if(i==3)
  95.               {
  96.               bStatusFlag=DriveCommand(Stop,NULL,NULL,NULL,(USHORT)NULL);
  97.               bStatusFlag=DriveCommand(SetDriveMode,(ULONG)MuteData,NULL,NULL,(USHORT)NULL);
  98.               goto newloop;
  99.               } /* end if */
  100.             }
  101.           } /* end for */
  102.  
  103.         if(SeekRunning)
  104.           {
  105.           for(i=0; i<8; i++)
  106.             {
  107.             DPRINTF(("Setting Drive mode\n"));
  108.             bStatusFlag=DriveCommand(SetDriveMode,(ULONG)(MuteData|TocData),NULL,NULL,(USHORT)NULL);
  109.             if(!COMMANDCHECK(bStatusFlag))
  110.               {
  111.               ModeSetState=TRUE;
  112.               break;
  113.               } /* end if */
  114.             } /* end for */
  115.           }
  116.  
  117.         DUMMYWAIT;
  118.  
  119.         if(SeekRunning)
  120.           {
  121.           DPRINTF(("Starting Track search for tracks %d thru %d\n", bMinTno+Delta,bMaxTno));
  122.           for(state=NoneFound,count=400,i=bMinTno+Delta;i<=bMaxTno && count ; count--)
  123.             {
  124.             DUMMYWAIT;
  125.             while(TIMEOUT(bStatusFlag=(UCHAR)(Status=DriveCommand(ReadSubQ,NULL,NULL,&Data,sizeof(Data.TrackInfo)))))
  126.               DUMMYWAIT;
  127.             DPRINTF(("SubqLoop status=%04X\n",bStatusFlag));
  128.             if(!TIMEOUT(Status))
  129.               {
  130.               if(!COMMANDCHECK(bStatusFlag) && !DISCCHANGE(bStatusFlag) && DISCIN(bStatusFlag) && !READERROR(bStatusFlag))
  131.                 {
  132.                 DPRINTF((" Q Status = %04X\n", bStatusFlag));
  133.                 DPRINTF(("Track Q info TNO = %02X, AMin= %02X, Index = %02X ADR=%02X\n",
  134.                                 Data.TrackInfo.TNO,
  135.                                 BCD2Bin(Data.TrackInfo.AMin),
  136.                                 Data.TrackInfo.Index,
  137.                                 Data.TrackInfo.S.ADR));
  138.                 if(Data.TrackInfo.TNO==0)
  139.                   {
  140.                   if(state!=MaxFound)
  141.                     {
  142.                     if(state!=AllFound)
  143.                       {
  144.                       if(Data.TrackInfo.Index==LowTrack)
  145.                         {
  146.                         if(!(state & FirstFound))
  147.                           {
  148.                           if(BCD2Bin(Data.TrackInfo.AMin)==i)
  149.                             {
  150.                             DPRINTF(("firsttrack index found = %d\n",BCD2Bin(Data.TrackInfo.AMin)));
  151.                             First_Track_in_Session=BCD2Bin(Data.TrackInfo.AMin);
  152.                             DPRINTF(("First=%d\n",First_Track_in_Session));
  153.                             state |= FirstFound;
  154.                             } /* end if */
  155.                           } /* end if */
  156.                         } /* end if */
  157.                       else if(Data.TrackInfo.Index==HighTrack)
  158.                         {
  159.                         if(!(state & LastFound))
  160.                           {
  161.                           DPRINTF(("lasttrack index found = %d\n",BCD2Bin(Data.TrackInfo.AMin)));
  162.                           Last_Track_in_Session=BCD2Bin(Data.TrackInfo.AMin);
  163.                           DPRINTF(("Last=%d\n",Last_Track_in_Session));
  164.                           state |= LastFound;
  165.                           } /* end if */
  166.                         } /* end else */
  167.                       } /* end if */
  168.                     else
  169.                       {
  170.                       if(Data.TrackInfo.Index<=MaxTrack)
  171.                         {
  172.                         if(i==BCD2Bin(Data.TrackInfo.Index))
  173.                           {
  174.                           DPRINTF(("Saving track info for Track %d\n",BCD2Bin(Data.TrackInfo.Index)));
  175.                           TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].Control=Data.TrackInfo.S.Control;
  176.                           TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].ADR=Data.TrackInfo.S.ADR;
  177.                           TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].min=BCD2Bin(Data.TrackInfo.AMin);
  178.                           TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].sec=BCD2Bin(Data.TrackInfo.ASec);
  179.                           TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].frame=BCD2Bin(Data.TrackInfo.AFrame);
  180.                           TOCInfoArea[BCD2Bin(Data.TrackInfo.Index)].start= MAKEULONG( MAKEUSHORT( BCD2Bin(Data.TrackInfo.AFrame),
  181.                                                                                              BCD2Bin(Data.TrackInfo.ASec ) ),
  182.                                                                                        MAKEUSHORT( BCD2Bin(Data.TrackInfo.AMin),
  183.                                                                                                    0 ) ) ;
  184.                           DevHelp_RAS( 184 ,i , sizeof(TOCINFO), &TOCInfoArea[i]);
  185.                           if(i==Last_Track_in_Session)                   // if last track in this session
  186.                             {                           // go for more
  187.                             state=MaxFound;
  188.                             DPRINTF(("Max Track in session found\n"));
  189.                             Delta=i;
  190.                             } /* end if */
  191.                           i++;
  192.                           } /* end if */
  193.                         } /* end if */
  194.                       } /* end else */
  195.                     } /* end if */
  196.                   else if(Data.TrackInfo.Index==BridgeTrk)
  197.                     {
  198.                     f =BCD2Bin(Data.TrackInfo.Frame);
  199.                     s =BCD2Bin(Data.TrackInfo.Sec);
  200.                     m =BCD2Bin(Data.TrackInfo.Min);
  201.                     s +=2;          // go two seconds into new area
  202.                     if(s>=60)       // if new seconds is >one minute would allow
  203.                       {
  204.                       m++;          // adjust minutes
  205.                       s-=60;        // adjust downward seconds
  206.                       } /* end if */
  207.                     Addr=MAKEULONG( MAKEUSHORT(f,s ),
  208.                                     MAKEUSHORT(m,0));
  209.                     DPRINTF(("Bridge track found = %08lX\n",Addr));
  210.                     while(TIMEOUT(DriveCommand(SetDriveMode,(ULONG)MuteData,NULL,NULL,(USHORT)NULL)));
  211.                     DUMMYWAIT;
  212.                     DUMMYWAIT;
  213.                     DUMMYWAIT;
  214.                     DUMMYWAIT;
  215.                     DUMMYWAIT;
  216.                     DUMMYWAIT;
  217.                     DUMMYWAIT;
  218.                     DUMMYWAIT;
  219.                     DPRINTF(("Seeking to last session now for tracks %d thru %d status=%04X\n",i,bMaxTno,bStatusFlag));
  220.                     goto newloop;
  221.                     } /* end if */
  222.                   } /* end if */
  223.                 } /* end if */
  224.               else
  225.                 {
  226.                 DevHelp_RAS( 183 ,0xaa , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  227.                 DPRINTF(("Aborting track search Status=%04X\n",bStatusFlag));
  228.                 break;
  229.                 } /* end else */
  230.               } /* end if */
  231.             else
  232.               {
  233.               DevHelp_RAS( 183 ,0xab , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  234.               DPRINTF(("Aborting track search timeout Status=%04X\n",bStatusFlag));
  235.               break;
  236.               }
  237.             } /* end for */
  238.           }
  239.         bStatusFlag=DriveCommand(SetDriveMode,(ULONG)MuteData,NULL,NULL,(USHORT)NULL);
  240. //      bStatusFlag=DriveCommand(Stop,0,NULL,NULL,NULL);
  241.         if(count==0 && i<bMaxTno)
  242.           {
  243.           goto newloop;
  244.           } /* end if */
  245.         if(state==MaxFound)
  246.           {
  247.           DevHelp_RAS( 184 ,0xaa , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  248.           Flag=TRUE;
  249.           } /* end if */
  250.         return Flag;
  251. }
  252.  
  253. BOOL CacheTOC(PCDROMSTAT Data,UCHAR checksum)
  254. {
  255. BOOL Flag=TRUE;
  256.         DPRINTF(("Caching TOC\n"));
  257.         bInfoFlag &= CLR_VS;                    // clear the flag just to make sure
  258.         TOC_Cache=0;                            // clear toc indicator, just in case
  259.         ulVSSize = AdrRed2Hsg(MAKEULONG( MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutFrame),
  260.                                          BCD2Bin(Data->TOC.LeadoutSec ) ),
  261.                              MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutMin),
  262.                                          0 ) ) )-1;
  263.         bMinTno   =BCD2Bin(Data->TOC.FirstTrack);
  264.         bMaxTno   =BCD2Bin(Data->TOC.LastTrack);
  265.         DPRINTF(("FirstTrack=%d LastTrack=%d\n",bMinTno,bMaxTno));
  266.         TOCInfoArea[0].min=BCD2Bin(Data->TOC.LeadoutMin);
  267.         TOCInfoArea[0].sec=BCD2Bin(Data->TOC.LeadoutSec );
  268.         TOCInfoArea[0].frame=BCD2Bin(Data->TOC.LeadoutFrame);
  269.         TOCInfoArea[0].ADR =0;
  270.         TOCInfoArea[0].Control=AUDIODISC(bStatusFlag) ? TCI_AUDIO : TCI_DATA;
  271.         DPRINTF((" Low & high track = %d %d status=%02X\n",bMinTno,bMaxTno,bStatusFlag));
  272.         ulLeadOut = MAKEULONG( MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutFrame),
  273.                                          BCD2Bin(Data->TOC.LeadoutSec ) ),
  274.                              MAKEUSHORT( BCD2Bin(Data->TOC.LeadoutMin),
  275.                                          0 ) ) ;
  276.  
  277.         TOCInfoArea[bMaxTno+1].start=ulLeadOut;     // start after last track, used in read SRD
  278.         TOCInfoArea[bMaxTno+1].Control=TCI_DATA;    // start after last track, used in read SRD
  279.         DPRINTF(("Getting TrackInfo\n"));
  280.         SetDataMode(SuspendData);
  281.         if(GetTocInfo())
  282.           {
  283.           DPRINTF(("TrackInfo completed ok\n"));
  284.           bInfoFlag |= SET_VS ;
  285.           TOC_Cache=checksum;
  286.           Flag=FALSE;
  287.           if(TOCInfoArea[bMinTno].Control & TCI_DATA)
  288.             {
  289.             while(TIMEOUT(DriveCommand( DriveConfig,MODEFLAG ,0, 0, 0)))
  290.               DUMMYWAIT;
  291.             while(TIMEOUT(DriveCommand( DriveConfig,IRQFLAG ,IrqNum?(PreIrq|ErrIrq):0, 0, 0)))
  292.               DUMMYWAIT;
  293.             while(TIMEOUT(DriveCommand( SetDriveMode,MuteData ,0, 0, 0)))
  294.               DUMMYWAIT;
  295.             #ifndef TEST
  296.             #ifndef DEBUG
  297.             TryIrq(FALSE);
  298.             SpecialRead();
  299.             #endif
  300.             #endif
  301.             } /* end if */
  302.           }
  303.         else
  304.           {
  305.           DPRINTF(("TrackInfo failed\n"));
  306.           }
  307.      return Flag;
  308. }
  309.  
  310. BOOL ReadyHardware( PIORBH pIORB, USHORT OpCode )
  311. {
  312.       USHORT CmdCode = pIORB->CommandCode ;
  313.       USHORT SubCmd  = pIORB->CommandModifier ;
  314.       CDROMSTAT Data ;
  315.       UCHAR i,temp ;
  316.       PUCHAR t;
  317.  
  318.       for(i=1; i<15; i++)
  319.         {
  320.         bStatusFlag=DriveStatus(Spincount);       // get drives status
  321.  
  322.         if(COMMANDCHECK(bStatusFlag) || TIMEOUT(bStatusFlag) ||
  323.           ((PreviousOpCode==SCSI_MODE_SELECT) && (LOBYTE(bStatusFlag)==0) && (PreviousStatus!=0))
  324.           )
  325.           {
  326.           DevHelp_RAS( 160 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  327.           DUMMYWAIT;
  328.           } /* end if */
  329.         else
  330.           {
  331.           break;
  332.           } /* end else */
  333.         } /* end for */
  334.       PreviousOpCode=OpCode;
  335.       PreviousStatus=LOBYTE(bStatusFlag);
  336.       DevHelp_RAS( 160 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  337.       if(!COMMANDCHECK(bStatusFlag))            // no command error
  338.         {
  339.         if(DISCIN(bStatusFlag))                 // is there a disc in the drive?
  340.           {                                     // calculate checksum of toc data, should be only one match possible
  341.                                                 // get TOC
  342.           if(!(bInfoFlag & SET_VS))
  343.             {
  344.             bPlayFlag   = bPauseFlag = FALSE ;
  345.             bStatusFlag=DriveCommand(ReadToc,NULL,NULL,&Data,sizeof(Data.TOC));
  346.             if(!COMMANDCHECK(bStatusFlag) && !READERROR(bStatusFlag) && (Data.TOC.LastTrack<MaxTrack))
  347.               {
  348.               DevHelp_RAS( 184 ,0 , sizeof(Data.TOC), &Data);
  349.               DPRINTF(("Disk in drive\n"));
  350.               for(i=1,t=(PUCHAR)&Data,temp=*t,t++;i<sizeof(Data.TOC) ; i++,t++)
  351.                 {
  352.                 temp^=*t;
  353.                 } /* end for */
  354.               DPRINTF(("Checksum=%02X==Saved=%02X\n",temp,TOC_Cache));
  355. //            if(temp==TOC_Cache)                   // does the checksum matched the saved one?
  356. //              {
  357. //              DPRINTF(("Checksums match\n"));
  358. //              bInfoFlag |= SET_VS ;               // same disk as last time
  359. //              } /* end if */
  360. //            else
  361. //              {
  362.                 DPRINTF(("Checksums do NOT match\n"));
  363.                 IORB_CmdErr(IOERR_MEDIA_CHANGED, pIORB,SCSI_SK_UNITATTN,ASC_MEDIUM_CHANGED);
  364.                 if(CacheTOC(&Data,temp))            // did caching go ok?
  365.                   {
  366.                   DPRINTF(("Caching failed?\n"));
  367.                   switch (OpCode)                   // no failures for some non-disk dependant opcodes
  368.                     {
  369.                     case SCSI_READ_CAPACITY:
  370.                     case SCSI_MODE_SELECT:
  371.                     case SCSI_MODE_SENSE:
  372.                        break;
  373.                     default:
  374.                        IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
  375.                        DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  376.                        return TRUE;
  377.                        break;
  378.                     } /* endswitch */
  379.                   } /* end if */
  380. //              } /* end else */
  381.               } /* end if */
  382.             else
  383.               {
  384.               DPRINTF(("TOC failed status=%02X\n",bStatusFlag));
  385.               DevHelp_RAS( 183 ,0xaa , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  386.               IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
  387.               DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  388.               return TRUE;
  389.               } /* end else */
  390.             } /* end if */
  391.           } /* end if */
  392.         else
  393.           {
  394.           DPRINTF(("NO Disk in drive\n"));
  395.           bPlayFlag   = bPauseFlag = FALSE ;
  396.           switch (OpCode)                       // no failures for some non-disk dependant opcodes
  397.             {
  398.             case SCSI_MODE_SELECT:
  399.             case SCSI_MODE_SENSE:
  400.             case SCSI_LOCK_UNLOCK:
  401.             case SCSI_START_STOP_UNIT:
  402.             case ADD_READ_DISK_INFO:           //rme - fix for photo CD
  403.                break;
  404.             default:
  405.                IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, pIORB,SCSI_SK_NOTRDY,0);
  406.                DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag ,sizeof(PGinfo->msecs), &(PGinfo->msecs) );
  407.                return TRUE;
  408.                break;
  409.             } /* endswitch */
  410.           } /* end else */
  411.         } /* end if */
  412.       else                                      // no disc present
  413.         {
  414.         DPRINTF(("Drive Status Command failed %02X\n",bStatusFlag));
  415.         switch (OpCode)                         // no failures for some non-disk dependant opcodes
  416.           {
  417.           case SCSI_READ_CAPACITY:
  418.           case SCSI_MODE_SELECT:
  419.           case SCSI_MODE_SENSE:
  420.              break;
  421.           default:
  422.              IORB_CmdErr(IOERR_UNIT_NOT_READY, pIORB,SCSI_SK_NOTRDY,0);
  423.              DevHelp_RAS( 162 ,OpCode<<8 | bStatusFlag , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  424.              return TRUE;
  425.              break;
  426.           } /* endswitch */
  427.         } /* end else */
  428.  
  429.       return FALSE;
  430. }
  431.  
  432. void SpecialRead( void)
  433. {
  434. USHORT Status,i;
  435. CDROMSTAT c;
  436. UCHAR CurrentMode=Mode1;
  437. #define SpecialAddr 0x00000210L
  438. PRawSector SpecialBuffer;
  439.  
  440.         do
  441.           {
  442.           DUMMYWAIT;
  443.           Status=DriveCommand( ModeSet,Mode1 ,0, 0, 0);          // set mode 1 first
  444.           Mode = Mode1;
  445.           } while (TIMEOUT(Status)); /* end do */
  446.         DriveCommand( SetDriveMode,DataLength|EccBit|MuteData ,0, 0, 0);
  447.         if(!Specialbuffer)
  448.           {
  449. #if defined(DEBUG) | defined(TEST)
  450.           Specialbuffer=malloc(sizeof(RawSector));
  451. #else
  452.           DevHelp_AllocPhys(sizeof(RawSector),0, (PULONG)&Specialbuffer);
  453. #endif
  454.           } /* end if */
  455.         if(Specialbuffer)
  456.           {
  457. #if defined(DEBUG) | defined(TEST)
  458.           SpecialBuffer=(PRawSector)Specialbuffer;
  459. #else
  460.           DevHelp_PhysToGDT((ULONG)Specialbuffer, sizeof(RawSector), FP_SEG(Read_IOBuffer));
  461.           SpecialBuffer=(PRawSector)Read_IOBuffer;
  462. #endif
  463.           for(i=0; i<2; i++)
  464.             {
  465.             Status=DriveCommand( Read, SpecialAddr, 1,(PCDROMSTAT)SpecialBuffer ,sizeof(RawSector));   // read
  466.             if(!READERROR(Status) && !COMMANDCHECK(Status) && !TIMEOUT(Status))
  467.               {
  468.               if(Mode==Mode2)
  469.                 {
  470.                 DriveCommand( SetDriveMode,TestMode|MuteData ,0, 0, 0);
  471.                 while(TIMEOUT(DriveCommand( DriveConfig,BLOCKSIZE ,DrvBlockSize, 0, 0)))
  472.                   DUMMYWAIT;
  473.                 break;
  474.                 } /* end if */
  475.               else
  476.                 {
  477.                 Status=DriveCommand( ModeSet,Mode1 ,0, 0, 0);  // try mode 2 now
  478.                 DriveCommand( SetDriveMode,MuteData ,0, 0, 0);
  479.                 break;
  480.                 } /* end else */
  481.               } /* end if */
  482.             else
  483.               {
  484.               Mode=Mode2;
  485.               Status=DriveCommand( ModeSet,Mode2 ,0, 0, 0);  // try mode 2 now
  486.               } /* end else */
  487.             } /* end for */
  488.           } /* end if */
  489. }
  490.