subroutine TopDrive_MainSolver
    
  
    use SimulationVariables
  
    IMPLICIT NONE
    
    
    
    CALL TopDrive_Inputs
    
    
    if ( (data%State%TDS%PowerState==-1) ) then  !FWD
            
        data%State%TDS%SoundBlower = .true.
        data%State%TDS%PowerLed    = 1 
        
        data%State%TDS%N_new = (data%State%TDS%RpmKnob/250.d0)*965.d0          ! 0<data%State%TDS%RpmKnob<250  , 0<data%State%TDS%N_ref(truction motor)<965
                    
        !===> Top Drive Malfunction ----> Drive Motor Failure
        if ( data%State%TDS%MotorFaileMalf==1 ) then
            data%State%TDS%N_new = 0.d0
        end if
                    
        !========================== Top Drive Rate limit ==========================
        if (((data%State%TDS%N_new-data%State%TDS%N_old)/data%State%TDS%time_step)>data%State%TDS%RateChange) then
            data%State%TDS%N_ref = (data%State%TDS%RateChange*data%State%TDS%time_step)+data%State%TDS%N_old
        else if (((data%State%TDS%N_old-data%State%TDS%N_new)/data%State%TDS%time_step)>data%State%TDS%RateChange) then
            data%State%TDS%N_ref = (-data%State%TDS%RateChange*data%State%TDS%time_step)+data%State%TDS%N_old
        else
            data%State%TDS%N_ref = data%State%TDS%N_new
        end if
        !==========================================================================
        
        CALL TopDrive_Solver
        
    else if ( (data%State%TDS%PowerState==1) ) then   !REV
        
        data%State%TDS%SoundBlower = .true.
        data%State%TDS%PowerLed    = 1
                        
        data%State%TDS%N_new = (data%State%TDS%RpmKnob/250.d0)*965.d0
                    
        !===> Top Drive Malfunction ----> Drive Motor Failure
        if ( data%State%TDS%MotorFaileMalf==1 ) then
            data%State%TDS%N_new = 0.d0
        end if
                    
        !========================== Top Drive Rate limit ==========================
        if (((data%State%TDS%N_new-data%State%TDS%N_old)/data%State%TDS%time_step)>data%State%TDS%RateChange) then
            data%State%TDS%N_ref =(data%State%TDS%RateChange*data%State%TDS%time_step)+data%State%TDS%N_old
        else if (((data%State%TDS%N_old-data%State%TDS%N_new)/data%State%TDS%time_step)>data%State%TDS%RateChange) then
            data%State%TDS%N_ref = (-data%State%TDS%RateChange*data%State%TDS%time_step)+data%State%TDS%N_old
        else
            data%State%TDS%N_ref = data%State%TDS%N_new
        end if
        !==========================================================================
                    
        CALL TopDrive_Solver
        
    else
        
        if( (data%State%TDS%PowerState /= 0) ) then
            data%State%TDS%SoundBlower = .true.
            data%State%TDS%PowerLed = 1
        else
            data%State%TDS%SoundBlower = .false.
            data%State%TDS%PowerLed = 0
        end if
            
        Call TopDrive_OffMode
        
    end if
        
        
    Call TopDrive_Outputs
    
    data%State%TDS%N_old = data%State%TDS%N_ref
    
    
    
    
end subroutine TopDrive_MainSolver