/*
 * Copyright (c) 1990-1998 by The MathWorks, Inc. All Rights Reserved.
 * File: simstruc.h     $Revision: 1.121 $
 *
 * Abstract:
 *      Data structures and access methods for S-functions.
 *
 *      A Simulink model is an S-function.  The SimStruct contains all entry
 *      points within the S-function (e.g. mdlOutputs) as well any data
 *      associated with the S-function.
 *
 *      This file contains details of SimStruct (Simulink data structure)
 *      which is used to store attributes of the model such as pointers to
 *      storage vectors.
 *
 *      Multiple SimStructs are, in general, used by a model. These SimStruct's
 *      are arranged as a "tree". The "root" SimStruct is used by
 *      the Simulink model. There is one child SimStruct for each S-function
 *      block with in the model.
 *
 *      The SimStruct can be used in three environments:
 *        o With MATLAB/Simulink (MATLAB_MEX_FILE)
 *        o With Real-Time Workshop in nonreal-time (NRT)
 *        o With Real-Time Workshop in real-time (RT)
 *
 * Defines:
 *      One of the following must be defined.
 *        MATLAB_MEX_FILE    - Must be defined when compiling as a MEX file,
 *                             otherwise must not be defined.
 *        NRT                - Define if creating non-real-time executable
 *        RT                 - Define if creating real-time executable.
 *
 *      Defines which must be declared by the Real-Time Workshop
 *      generated model source.
 *        Simulink_NAME="name"
 *        NSAMPLE_TIMES=n
 *
 *      Defines for use with the Real-Time Workshop (these are configured
 *	by the template makefile, do not add directly to make command):
 *        MULTITASKING       - Optional (use MT for a synonym).
 *        NUMST=n            - Number of sample times in the root SimStruct.
 *        TID01EQ=1 or 0     - Optional. Only define to 1 if sample time task
 *                             id's 0 and 1 have equal rates.
 */


#ifndef __SIMSTRUC__
#define __SIMSTRUC__


#if defined(MathWorks_h)
/* SimStruct being used within Simulink itself */
# define MATLAB_MEX_FILE
#endif

/*============================*
 * Configure S-function level *
 *============================*/
#if defined(S_FUNCTION_LEVEL)
# if S_FUNCTION_LEVEL != 1 && S_FUNCTION_LEVEL != 2
#  error Invalid S_FUNCTION_LEVEL
# endif
#else
#  if !defined(S_FUNCTION_NAME)
#    define S_FUNCTION_LEVEL 2  /* for models */
#  else
#    define S_FUNCTION_LEVEL 1  /* Backwards compatibility for Simulink 2.1
                                   and previous S-functions                  */
#  endif
#endif

/*=================*
 * Nested includes *
 *=================*/
#include <limits.h>
#include <string.h>
#include "tmwtypes.h"
#include "simstruc_types.h"

/*
 * Include headers for MATLAB API function prototypes (e.g. mxGetPr)
 */
#if defined(MATLAB_MEX_FILE)
# include <stdlib.h>
# include <stdarg.h>
# if !defined(MathWorks_h)
#   include "mex.h"     /* User written S-function */
#   if !defined(S_FUNCTION_NAME)
#     define _S_FUNCTION_NAME_NOT_DEFINED_BEFORE_SIMSTRUCT
#   endif
# else
#   include "matrix.h"  /* Using within Simulink itself */
# endif
#elif defined(S_FUNCTION_NAME)
#   include "rt_matrx.h" /* S-function is being usd with Real-Time Workshop */
#else
# if !defined(TYPEDEF_MX_ARRAY)
#  define TYPEDEF_MX_ARRAY
    typedef real_T mxArray; /* Run-time interface for Real-Time Workshop */
# endif
#endif

/*========================*
 * Setup for multitasking *
 *========================*/

/*
 * Let MT be synonym for MULTITASKING (to shorten command line for DOS)
 */
#if defined(MT)
# if MT == 0
#   undef MT
# else
#   define MULTITASKING 1
# endif
#endif

#if defined(MULTITASKING) && MULTITASKING == 0
# undef MULTITASKING
#endif

#if defined(MULTITASKING) && !defined(TID01EQ)
# define TID01EQ 0
#endif

/*
 * Undefine MULTITASKING if there is only one task or there are two
 * tasks and the sample times are equal (case of continuous and one discrete
 * with equal rates).
 */
#if defined(NUMST) && defined(MULTITASKING)
# if NUMST == 1 || (NUMST == 2 && TID01EQ == 1)
#  undef MULTITASKING
# endif
#endif


/*===============================*
 * Defines for S-function blocks *
 *===============================*/

/*
 * DYNAMICALLY_SIZED - Specify for sizes entries that inherit their values
 * from the block that drives them.
 *
 * DYNAMICALLY_TYPED - Specify for input/output port data types that can
 * accept a variety of data types.
 *
 * SIMSTRUCT_VERSION - An integer which is the sizeof the SimStruct times
 * 10000 plus the version times 100. When updating version numbers within the
 * Matlab image, increment both level 1 and level 2 S-functions. Level 1
 * version cannot be in range 220 to 229.  This was the level 2 version in
 * Simulink 2.20 (R10)
 */

#define DYNAMICALLY_SIZED            (-1)
#define DYNAMICALLY_TYPED            (-1)
#define SIMSTRUCT_VERSION_LEVEL1     (sizeof(SimStruct)*10000 + 214)
#define SIMSTRUCT_VERSION_LEVEL2     (sizeof(SimStruct)*10000 + 229)

/*
 * INHERITED_SAMPLE_TIME      - Specify for blocks that inherit their sample
 *                              time from the block that feeds their input.
 *
 * CONTINUOUS_SAMPLE_TIME     - A continuous sample time indicates that the
 *                              block executes every simulation step.
 *
 * VARIABLE_SAMPLE_TIME       - Specifies that this sample time is discrete
 *                              with a varying period.
 *
 * FIXED_IN_MINOR_STEP_OFFSET - This can be specified for the offset of either
 *                              the inherited or continuous sample time
 *                              indicating that the output does not change
 *                              in minor steps.
 */

#define INHERITED_SAMPLE_TIME      ((real_T)-1.0)
#define CONTINUOUS_SAMPLE_TIME     ((real_T)0.0)
#define VARIABLE_SAMPLE_TIME       ((real_T)-2.0)

#define FIXED_IN_MINOR_STEP_OFFSET ((real_T)1.0)

/*
 * Task ID's ordering
 *      Continuous task
 *      Continuous but fixed in minor step task
 *      Discrete task 1
 *         ...
 *      Discrete task N
 *      Variable sample time task(s), offset is instance number.
 *
 * If continuous task is present then it's task ID is 0, otherwise the
 * first discrete task ID will be 0 if it is present, etc.
 * All blocks with varying sample times have same sample task period of -2,
 * and the offset is the instance number.
 *
 * The triggered blocks are not in the sample time table and have a task ID
 * of -1.
 */

#define TRIGGERED_TID           (-1)
#define CONSTANT_TID            (-2)


/*
 * ssSetNumSampleTimes(S,PORT_BASED_SAMPLE_TIMES) - Indicates that the sample
 * times are assigned on a per port basis.
 */
#if S_FUNCTION_LEVEL > 1
# define PORT_BASED_SAMPLE_TIMES -1
#endif


/*===============================================*
 * General defines used only by the macros below *
 *===============================================*/

/*
 * TID_EQUALS_SAMPLE_TIME_INDEX -
 *     The model will function correctly if this define is false, however if
 *     this define is true the model's performance may be increased depending
 *     upon whether or not the model has fast to slow rate transitions.
 */
#if defined(MathWorks_h)
# define TID_EQUALS_SAMPLE_TIME_INDEX     1
#else
# define TID_EQUALS_SAMPLE_TIME_INDEX     0   /* assume FALSE */
# if defined(NUMST) && defined(NSAMPLE_TIMES)
#  if NUMST < NSAMPLE_TIMES
#    error NUMST specified incorrectly
#  elif NUMST == NSAMPLE_TIMES
#    undef  TID_EQUALS_SAMPLE_TIME_INDEX
#    define TID_EQUALS_SAMPLE_TIME_INDEX    1
#  endif
# endif
#endif

/*
 * Define mxMAXNAM if it has not been defined.
 */
#ifndef mxMAXNAM
#define mxMAXNAM 32
#endif

#if defined(MATLAB_MEX_FILE) && (defined(applec) || defined(__MC68K__))
# define SS_DO_FCN_CALL_ON_MAC 1
#else
# define SS_DO_FCN_CALL_ON_MAC 0
#endif


/*========================================================================*
 * Verify one of the required RT, NRT, MATLAB_MEX_FILE defines is present *
 *========================================================================*/

#if (defined(RT) + defined(NRT) + defined(MATLAB_MEX_FILE) != 1)
# error must define one of RT, NRT, MATLAB_MEX_FILE
#endif

#if (defined(NRT) && defined(MULTITASKING))
# error NRT does not support MULTITASKING
#endif

#if (defined(MATLAB_MEX_FILE) && defined(MULTITASKING))
# error MATLAB/Simulink does not support MULTITASKING
#endif



/*=================================================================*
 * Defines used by Simulink.c when calling the S-function routines *
 *=================================================================*/
#if defined(MATLAB_MEX_FILE)
# define SS_CALL_MDL_INITIALIZE_SAMPLE_TIMES        101
# define SS_CALL_MDL_INITIALIZE_CONDITIONS          102
# define SS_CALL_MDL_GET_TIME_OF_NEXT_VAR_HIT       103
# define SS_CALL_MDL_OUTPUTS                        104
# define SS_CALL_MDL_UPDATE                         105
# define SS_CALL_MDL_DERIVATIVES                    106
# define SS_CALL_MDL_TERMINATE                      107
# define SS_CALL_MDL_ZERO_CROSSINGS                 108
# define SS_CALL_MDL_GET_INPUT_PORT_WIDTH           109
# define SS_CALL_MDL_GET_OUTPUT_PORT_WIDTH          110
# define SS_CALL_MDL_SET_WORK_WIDTHS                111
# define SS_CALL_MDL_CHECK_PARAMETERS               112
# define SS_CALL_MDL_SET_INPUT_PORT_DATA_TYPE       113
# define SS_CALL_MDL_SET_OUTPUT_PORT_DATA_TYPE      114
# define SS_CALL_MDL_SET_INPUT_PORT_WIDTH           115
# define SS_CALL_MDL_SET_OUTPUT_PORT_WIDTH          116
# define SS_CALL_MDL_START                          117
# define SS_CALL_MDL_PROCESS_PARAMETERS             118
# define SS_CALL_MDL_RTW                            119
# define SS_CALL_MDL_SET_INPUT_PORT_COMPLEX_SIGNAL  120
# define SS_CALL_MDL_SET_OUTPUT_PORT_COMPLEX_SIGNAL 121
# define SS_CALL_MDL_SET_INPUT_PORT_SAMPLE_TIME     122
# define SS_CALL_MDL_SET_OUTPUT_PORT_SAMPLE_TIME    123
# define SS_CALL_RTW_GENERATED_ENABLE               124
# define SS_CALL_RTW_GENERATED_DISABLE              125
#endif



/*==================================*
 * Structures with in the SimStruct *
 *==================================*/

#ifndef _SIMSTRUCT
#  define _SIMSTRUCT
   /*
    * Use incomplete type for function prototypes within SimStruct itself
    */
   typedef struct SimStruct_tag SimStruct;
#endif

typedef enum {                  /* What happens when a zero crossings occurs */
    DISCONTINUITY_AT_ZC,
    CONTINUITY_AT_ZC,
    TRIGGERED_DISCON_AT_ZC
} ZCType;


typedef enum {
    MINOR_TIME_STEP,
    MAJOR_TIME_STEP
} SimTimeStep;




/*
 * _ssSizes - valid in all SimStruct's. There is one sizes for a level-1
 * S-function and another sizes for a level 2 S-function.
 */

struct _ssSizes {
  int_T numContStates;     /* number of continuous states                    */
  int_T numDiscStates;     /* number of discrete states                      */
  union {
    int_T numOutputPorts;  /* number of output ports for S-functions         */
    int_T numY;            /* Length of the external output vector for models
                              i.e. the sum of the widths of the outports.
                              For level 1 S-functions, this is the output
                              port width.                                    */
  } out;
  union {
    int_T numInputPorts;   /* number of input ports for S-functions          */
    int_T numU;            /* Length of the external input vector for models
                              i.e. the sum of the widths of the inports.
                              For level 1 S-functions, this is the input
                              port width.                                    */
  } in;
  int_T reserved;          /* reserved for use by Simulink mex api           */

  int_T sysDirFeedThrough; /* Not used by s-functions - only for root models */


  int_T numSampleTimes;    /* # of different sample times and/or time offsets*/
  int_T numSFcnParams;     /* number of external matrices passed in          */

                           /* -------- Work vectors ------------------------ */
  int_T numIWork;          /* size of integer work vector                    */
  int_T numRWork;          /* size of real_T precision work vector           */
  int_T numPWork;          /* size of pointer work vector                    */

                           /* -------- Block counts ------------------------ */
  int_T numBlocks;         /* number of Blocks in the model                  */
  int_T numSFunctions;     /* number of S-Functions                          */

                           /* -------- Model bookkeeping ------------------- */
  int_T numBlockIO;        /* number of block outputs                        */
  int_T numBlockParams;    /* number of block parameters                     */
  uint32_T checksum0;      /* Checksum 0 of model                            */
  uint32_T checksum1;      /* Checksum 1 of model                            */
  uint32_T checksum2;      /* Checksum 2 of model                            */
  uint32_T checksum3;      /* Checksum 3 of model                            */

                           /* -------- Version ----------------------------- */
  int32_T simStructVer;    /* SimStruct version                              */

                           /* -------- Zero Crossings ---------------------- */
  int_T numNonsampledZCs;  /* number of nonsampled zero crossings            */
  int_T numZCEvents;       /* number of zero crossing events                 */

                           /* -------- Modes ------------------------------- */
  int_T numModes;          /* number of modes                                */

                           /* -------- Configuration options --------------- */
  uint32_T options;        /* General options                                */


                           /* -------- Vector Sizes In Bytes  -------------- */

  int_T sizeofY;           /* Sizeof of external input, Y, in bytes          */
  int_T sizeofU;           /* Sizeof of external input, U, in bytes          */
  int_T sizeofBlockIO;     /* size of block outputs (number of bytes)        */

  int_T nDWorksUsedAsDStates;/*total number of dwork elements to be logged   */

  int_T numDWork;          /* size of data type work vectors                 */
  int_T sizeofDWork;       /* Size of data type work vector. Depends on
                              dwork data types, complex signals, and
                              num dworks.                                    */
  int_T RTWGeneratedSFcn;  /* Flag which is set for rtw generated s-function */
                           /* Remove once all dstates are changed to dworks  */
                           /* ------------- Reserved ------------------------*/
  int_T reservedForFuture[7];
};

#define SIZES_LENGTH  (sizeof(struct _ssSizes)/sizeof(int_T))

/*
 * _ssPortInfo (S->portInfo), this is only used by level 2 S-functions.
 *
 */

typedef const void      * const * InputPtrsType;
 
typedef const real_T    * const * InputRealPtrsType;
typedef const real32_T  * const * InputReal32PtrsType;
typedef const int8_T    * const * InputInt8PtrsType;
typedef const uint8_T   * const * InputUInt8PtrsType;
typedef const int16_T   * const * InputInt16PtrsType;
typedef const uint16_T  * const * InputUInt16PtrsType;
typedef const int32_T   * const * InputInt32PtrsType;
typedef const uint32_T  * const * InputUInt32PtrsType;
typedef const boolean_T * const * InputBooleanPtrsType;

typedef void *                 OutputVectType;

#define DTINFO(id, complexSignal) ((complexSignal)?((id) | 0x10000):(id))
#define GET_DATA_TYPE(dt)  ((dt) & 0xFFFF)
#define GET_COMPLEX_SIGNAL(dt) (((dt) & 0x10000) != 0)

#define INVALID_DTYPE_ID       (-10)
#define INVALID_DTYPE_SIZE     (-1)
#define INVALID_PORT_IDX       (-1)
enum {
COMPLEX_INHERITED = -1,
COMPLEX_NO,
COMPLEX_YES
};

typedef int_T ComplexSignal;  /* xxx remove before shipping */
typedef int_T CSignal_T;

struct _ssDTypeArray{
    int_T     width;
    DTypeId   dataTypeId;
    CSignal_T complexSignal;
    void      *array;
    char_T    *name;
    int_T     usedAsDState;   /* 0 => no, 1 => yes */
};


/* Registration returns 1 for success and 0 for failure */
typedef int_T (*_ssRegNumInputPortsFcn) (void * arg1, int_T nInputPorts);
typedef int_T (*_ssRegNumOutputPortsFcn) (void * arg1, int_T nOutputPorts);

struct _ssPortInputs {
    int_T          width;               /* Number of elements in input
                                           port                          */
    int_T          directFeedThrough;   /* Direct feedthrough for input
                                           port                          */
    DTypeId        dataTypeId;          /* Data type of input port.      */
    CSignal_T      complexSignal;       /* Complex signal (-1=either,
                                           0=no, or 1=yes)?              */
    InputPtrsType  signalPtrs;          /* Pointers to the input
                                           signals                       */
    int_T          connected;           /* Are there signals entering
                                           the input port of the Sfcn?   */
    struct {
        unsigned int overWritable :  1;
        unsigned int reusable     :  2;
    } attributes;

    real_T         sampleTime;          /* Sample and offset time when   */
    real_T         offsetTime;          /* block specifies port based ts */
    void           *reservedForFutureVoid;

    int_T          bufferDstPort;

    int_T          sampleTimeIndex;     /* Sample time index when using
                                           port based sample times       */
    int_T          reservedSize;
};

struct _ssPortOutputs {
    int_T          width;               /* Number of elements in output
                                           port                          */
    DTypeId        dataTypeId;          /* Data type of outputs          */
    CSignal_T      complexSignal;       /* Complex signal (-1=either,
                                           0=no, or 1=yes)?              */
    void           *signalVect;         /* Output signal                 */
    int_T          connected;           /* Are the signals leaving the
                                           Sfcn driving other blocks?    */
    struct {
        unsigned int reusable    :  2;
    } attributes;

    real_T         sampleTime;          /* Sample and offset time when   */
    real_T         offsetTime;          /* block specifies port based ts */
    void           *reservedForFutureVoid;
    int_T          sampleTimeIndex;     /* Sample time index when using
                                           port based sample times       */
    int_T          reservedForFutureInt;
    int_T          reservedSize;
};

struct _ssPortInfo {

    _ssRegNumInputPortsFcn  regNumInputPortsFcn;
    void                    *regNumInputPortsFcnArg;
    _ssRegNumOutputPortsFcn regNumOutputPortsFcn;
    void                    *regNumOutputPortsFcnArg;

    struct _ssPortInputs    *inputs;    /* Info for each input port of blk  */
    struct _ssPortOutputs   *outputs;   /* Info for each output port of blk */
};


/* Masks for determining the parameter attributes (see ssSfcnParams struct). */
#define SFCNPARAM_NOT_TUNABLE (1 << 0x0)
#define SFCNPARAM_CALCULATED  (1 << 0x1)

struct _ssSFcnParams {
  int_T         count;        /* Number of S-function parameters passed in   */
  const mxArray **params;     /* The S-function parameters                   */
  uint_T        *attribs;     /* Disable parameter changes during simulation?*/
  void          **reservedForFuture[2];
};


struct _ssWork {
  int_T                     *iWork;       /* integer work vector             */
  real_T                    *rWork;       /* real work vector                */
  void                      **pWork;      /* pointer work vector             */
  int_T                     *modeVector;  /* mode work vector                */
  void                      *userData;    /* User/application specific data  */
  union {
    struct  _ssDTypeArray   *vect;        /* data type work vector           */
    void                    *strucPtr;
  }                         dWork;
  void                      *reservedForFuture[2];
};



/*
 * The _ssBlkInfo structure can by used by S-function blocks to determine
 * status about the model in which they reside.
 */

struct _ssBlkInfo {
  int_T        inputConnected;  /* Is input connected to a nonvirtual block? */
  int_T        outputConnected; /* Is output connected to a nonvirtual block?*/
  const char_T *placementGroup; /* Name of group to place block in. Only
                                   applies to sources and sinks. Blocks with
                                   same group name will appear adjacent in
                                   the sorted list.                          */
  void         *reservedForFutureVoid[2];
  int_T        reservedForFutureInt[2];
};

typedef enum {
  SS_SIMMODE_NORMAL,           /* Running a "normal" Simulink simulation     */
  SS_SIMMODE_SIZES_CALL_ONLY,  /* Block edit eval to obtain number of ports  */
  SS_SIMMODE_RTWGEN,           /* Generating code                            */
  SS_SIMMODE_EXTERNAL          /* External mode simulation                   */
} SS_SimMode;

/*==================================================================*
 * Mode of simulation - single vs multitaking. Note, variable       *
 * step solvers ignore this property and are always singletasking   *
 *==================================================================*/
typedef enum {
    SOLVER_MODE_AUTO,          /* only occurs in 
                                  mdlInitializeSizes/mdlInitializeSampleTimes */
    SOLVER_MODE_SINGLETASKING, 
    SOLVER_MODE_MULTITASKING
} SolverMode;

#if defined(MATLAB_MEX_FILE)
  /* following return 1 on success and 0 on failure */
  typedef int_T (*_WriteRTWStrFcn)(              void         *writeRTWFcnArg,
                                                 const char_T *str);

  typedef int_T (*_WriteRTWNameValuePairFcn)(    void         *writeRTWFcnArg,
                                                 int_T        type,
                                                 const char_T *name,
                                                 const void   *value,
                                                 DTypeId      dataTypeId,
                                                 int_T        nRows,
                                                 int_T        nCols);

  typedef int_T (*_WriteRTWParameterFcn)(        void         *writeRTWFcnArg,
                                                 int_T        type,
                                                 const char_T *name,
                                                 const char_T *str,
                                                 const void   *value,
                                                 DTypeId      dataTypeId,
                                                 int_T        nRows,
                                                 int_T        nCols);
#endif

/*
 * The _ssMdlInfo structure is "valid" in the root SimStruct only.  All child
 * SimStruct's point to the root SimStruct mdlInfo field.  Care must be taken
 * to use the correct mapping of tid's when accessing some of mdlInfo fields
 * (e.g. t, sample hits, sample times, etc). from child SimStruct's (use macros
 * below).
 */

struct _ssMdlInfo {
  SS_SimMode  simMode;         /* For MATLAB_MEX_FILE, this field indicates
                                  whether or not we are running a simulation
                                  or generating the model.rtw file */

  time_T      *t;              /* The current time for each task. This is
                                  of dimension sizes.numSampleTimes         */

  int_T       *sampleHits;     /* sample hits - does tid have a hit?  This is
                                  of dimension sizes.numSampleTimes         */

  time_T      tStart;          /* Model execution start time                 */
  time_T      tFinal;          /* Final model execution stop time            */
  time_T      timeOfLastOutput;/* Time of last model "output"                */
  time_T      reservedTime;

  void        *timingData;     /* Data used by execution or simulation engine*/

  SimTimeStep simTimeStep;     /* Simulation time step "mode"                */

  int_T       stopRequested;   /* True if a "stop" has been requested        */
  int_T       logOutput;       /* Log output?                                */

  time_T      *outputTimes;    /* Times at which to log data                 */
  int_T       outputTimesIndex;/* Where we are in the OutputTimes vector     */
  int_T       numOutputTimes;  /* Length of OutputTimes                      */
  int_T       outputTimesOnly; /* Save [t,x,y] & continuous blocks at
                                  specified times only?                      */
  int_T       needOutputAtTPlusTol; /* Flag integrator to output at t+tol.   */

  const char_T *solverName;    /* Name of solver/integration alogrithm       */
  int_T       variableStepSolver;/* true=variable or false=fixed step solver */
  void        *solverData;     /* Work area for solver                       */
  time_T      solverStopTime;  /* Solver stop time                           */
  time_T      stepSize;        /* The integration step size                  */
  int_T       solverNeedsReset;/* Do we need to reset the integrator?        */
  int_T       zcCacheNeedsReset;    /* recompute zc value left?              */
  int_T       derivCacheNeedsReset; /* recompute derivatives?                */
  int_T       solverRefineFactor;   /* state & output refinement factor      */
  real_T      solverRelTol;    /* Integration relative tolerance             */
  real_T      *solverAbsTol;   /* abs tol for each continuous state          */
  time_T      maxStepSize;     /* variable StepSize is always <= MaxStepSize */
  int_T       solverMaxOrder;  /* Maximum order for ode15s                   */
  time_T      fixedStepSize;   /* Step size for fixed-step integrators       */

  /*
   * The following are used by the engine to determine when to reset the
   * variable step solvers due to a change in a sampled signal which
   * is being integrated.
   */
  int_T       numSampledDerivInputs;
  real_T      **sampledDerivInputPtrs;
  real_T      *prevSampledDerivInputs;

  real_T      *dataStoreMem;   /* Data store memory                          */


  /* Logging info for Real-Time Workshop (not for use by S-functions) */

  RTWLogInfo        *rtwLogInfo;   /* What RTW should be logging             */
  void              *logInfo;      /* Pointer to a book keeping structure    *
                                    * used in rtwlog.c                       */
  LogSignalPtrsType logXSignalPtrs;/* Pointers to the memory location        *
                                    * of the data to be logged into the      *
                                    * states structure. Not used if logging  *
                                    * data in matrix format.                 */
  LogSignalPtrsType logYSignalPtrs;/* Pointers to the memory location        *
                                    * of the data to be logged into the      *
                                    * outputs structure. Not used if logging *
                                    * data in matrix format.                 */
  void              *reservedVoidPtr1;
  int_T             reservedInts[2];
  void              *reservedVoidPtr2;

  /* Block IO and parameter vectors for use with Real-Time Workshop */

  void   *blockIO;            /* block inputs/outputs                        */
  real_T *blockParam;         /* block parameter vector  (local copy)        */
  real_T *defaultParam;       /* Default parameter vector.                   */
                              /* Note: DefaultParam points to global storage;
                                 common to all instances of this model       */
  const void   *mappingInfo;  /* Used by RTW for providing external access
                                 to the parameters, block I/O, etc vectors   */


  /*
   * Function pointers used in mdlRTW which write fields in the model.rtw file.
   */
# if defined(MATLAB_MEX_FILE)
    _WriteRTWStrFcn           writeRTWStrFcn;
    _WriteRTWNameValuePairFcn writeRTWNameValuePairFcn;
    _WriteRTWParameterFcn     writeRTWParameterFcn;

    void                      *writeRTWFcnArg;

    void                      *reservedForFutureMLFcns[4];
    void                      *reservedForFutureMLArgs[4];
# endif

  int_T   reserved2;                /* reserved for use by Simulink mex api */
  char_T  reservedString[mxMAXNAM];

  void         *reservedForFutureVoid[7];
# if defined(MULTITASKING) || defined(MATLAB_MEX_FILE)
  int_T       *perTaskSampleHits; /* Matrix of dimension number of sample times
                                     by number of sample times giving sample
                                     hits as viewed in each task. Used by
                                     ssIsSpecialSampleHit within MEX files. */
# endif

  SolverMode   solverMode;          /* Simulation solver mode */
  int_T        reservedForFutureInt[3];

  real_T       mexApiReal1;         /* reserved for use by Simulink mex api */
  real_T       mexApiReal2;         /* reserved for use by Simulink mex api */


  const void *constBlockIO;         /* Pointer to invariant signals */
  real_T     *reservedDoubleVect[3];

}; /* end struct _ssMdlInfo */


/* returns 1 on success and 0 on failure */
typedef int_T (*SysOutputFcn) (void *, int_T, int_T);

struct _ssCallSys {
  int_T                *outputs; /* Which output elements call a system    */
  void                 **args1;  /* 1st Argument(s) for system output fcn  */
  int_T                *args2;   /* 2nd Argument(s) for system output fcn  */
  SysOutputFcn         *fcns;    /* System output functions                */
};


typedef DTypeId        (*RegisterDataType)(void *, char_T *);
typedef int_T          (*SetDataTypeSize) (void *, DTypeId, int_T );
typedef int_T          (*GetDataTypeSize) (void *, DTypeId);
typedef int_T          (*SetDataTypeZero) (void *, DTypeId, void *);
typedef const void *   (*GetDataTypeZero) (void *, DTypeId);
typedef const char_T * (*GetDataTypeName) (void *, DTypeId);
typedef DTypeId        (*GetDataTypeId)   (void *, char_T  *);
typedef int_T          (*SetNumDWork)     (void *, int_T);



struct _ssRegDataType {
  void               *arg1;         /* 1st Argument for Register Data Type  */
  RegisterDataType   registerFcn;   /* Register Data Type Function          */
  SetDataTypeSize    setSizeFcn;    /* Set Data Type Size Function          */
  GetDataTypeSize    getSizeFcn;    /* Get Data Type Size Function          */

  SetDataTypeZero    setZeroFcn;    /* Set Data Type Zero representation    */
  GetDataTypeZero    getZeroFcn;    /* Get Data Type Zero representation    */

  GetDataTypeName    getNameFcn;    /* Get Data Type Name Function          */
  GetDataTypeId      getIdFcn;      /* Get Data Type Id   Function          */

  SetNumDWork        setNumDWorkFcn;/* Set num data type work vector        */
};



struct _ssStInfo {
  time_T    *sampleTimes;       /* Sampling periods in seconds               */
  time_T    *offsetTimes;       /* Task delay for discrete systems
                                   (0 <= OffsetTime < SampleTime)            */
  time_T    tNext;              /* Time of next hit for M,MEX S-functions    */
  int_T     tNextTid;           /* For M,MEX S-fcns, negative if not present */
  int_T     *sampleTimeTaskIDs; /* Maps local sample time index to the
                                   root SimStruct task ID (root sti)         */
};



/*
 * Level 2 S-function methods:
 *
 *=> mdlInitializeSizes         -  Initialize SimStruct sizes array
 *   [mdlSetInputPortWidth]     -  Optional routine. Check and set input and
 *                                 optionally other port widths.  Can
 *                                 only be in a C MEX S-function.
 *   [mdlSetOutputPortWidth]    -  Optional routine. Check and set output
 *                                 and optionally other port widths. Can
 *                                 only be in a C MEX S-function.
 *=> mdlInitializeSampleTimes   -  Initialize sample times.
 *   [mdlSetWorkWidths]         -  Optional routine. Set the state, iwork,
 *                                 rwork, pwork, etc sizes. Can only be in a
 *                                 C MEX S-function.
 *
 *   [mdlRTW]                   -  Optional routine.  Only called when
 *                                 generating code to add information to the
 *                                 model.rtw file which is used by the
 *                                 Real-Time Workshop.
 *
 *   <<End mdl function calls when generating code by the Real-Time Workshop>>
 *
 *   [mdlInitializeConditions]  -  Initialize model parameters (usually
 *                                 states). Will not be called if your
 *                                 S-function does not have an intialize
 *                                 conditions routine.
 *   [mdlStart]                 -  Optional routine. Preform actitons such
 *                                 as allocating memory and attaching to pwork
 *                                 elements.  Can only be in a C MEX
 *                                 S-function.
 *   [mdlCheckParameters]       -  Optional routine. Will be called at
 *                                 any time during the simulation loop when
 *                                 parameters change. Can only be used in a
 *                                 C MEX S-function.
 *   SimulationLoop:
 *        [mdlProcessParameters]   -  Optional routine. Called during
 *                                    simulation after parameters have been
 *                                    changed and verified to be okay by
 *                                    mdlCheckParameters. The processing is
 *                                    done at the "top" of the simulation loop
 *                                    when it is safe to process the changed
 *                                    parameters. Can only be used in a C MEX
 *                                    S-function.
 *        [mdlGetTimeOfNextVarHit] -  Optional routine. If your S-function
 *                                    has a variable step sample time, then
 *                                    this routine will be called.
 *        [mdlIntializeConditions] -  Optional routine. Only called if your
 *                                    S-function resides in an enabled
 *                                    subsystem configured to reset states,
 *                                    and the subsystem has just enabled.
 *     => mdlOutputs               -  Major output call (usually updates
 *                                    output signals).
 *        [mdlUpdate]              -  Update the discrete states, etc.
 *        [mdlDerivatives]         -  Compute the derivatives.
 *   EndLoop
 *   mdlTerminate               -  End of model housekeeping - free memory,
 *                                 etc.
 */

typedef void (*mdlInitializeSizesFcn)(SimStruct *S);

#if defined(MATLAB_MEX_FILE)

  typedef void (*mdlSetInputPortWidthFcn)(SimStruct *S, int_T portIdx,
                                          int_T width);
  typedef void (*mdlSetOutputPortWidthFcn)(SimStruct *S, int_T portIdx,
                                           int_T width);

  typedef int_T (*mdlGetInputPortWidthLevel1Fcn)(SimStruct *S,
                                                 int_T outputWidth);
  typedef int_T (*mdlGetOutputPortWidthLevel1Fcn)(SimStruct *S,
                                                  int_T inputWidth);

  typedef void  (*mdlSetInputPortDataTypeFcn)(SimStruct *S,
                                              int_T     portIdx,
                                              DTypeId   inputPortDataType);
  typedef void  (*mdlSetOutputPortDataTypeFcn)(SimStruct *S,
                                               int_T     portIdx,
                                               DTypeId   outputPortDataType);
  typedef void  (*mdlSetInputPortComplexSignalFcn)(SimStruct *S,
                                              int_T      portIdx,
                                              CSignal_T  iPortComplexSignal);
  typedef void  (*mdlSetOutputPortComplexSignalFcn)(SimStruct *S,
                                              int_T      portIdx,
                                              CSignal_T  oPortComplexSignal);
#endif

typedef void  (*RTWGeneratedEnableFcn)(SimStruct *S);
typedef void  (*RTWGeneratedDisableFcn)(SimStruct *S);

typedef void (*mdlInitializeSampleTimesFcn)(SimStruct *S);

# if defined(MATLAB_MEX_FILE)
  typedef void (*mdlSetInputPortSampleTimeFcn)(SimStruct *S,
                                               int       portIdx,
                                               real_T    sampleTime,
                                               real_T    offsetTime);
  typedef void (*mdlSetOutputPortSampleTimeFcn)(SimStruct *S,
                                                int       portIdx,
                                                real_T    sampleTime,
                                                real_T    offsetTime);
  typedef void  (*mdlSetWorkWidthsFcn)(SimStruct *S);
  typedef void  (*mdlRTWFcn)(SimStruct *S);
#endif

typedef void (*mdlInitializeConditionsFcn)(SimStruct *S);
typedef void (*mdlInitializeConditionsLevel1Fcn)(real_T *x0, SimStruct *S);

typedef void (*mdlStartFcn)(SimStruct *S);

#if defined(MATLAB_MEX_FILE)
  typedef void  (*mdlCheckParametersFcn)(SimStruct *S);
  typedef void (*mdlProcessParametersFcn)(SimStruct *S);
#endif

#if defined(MATLAB_MEX_FILE) || defined(NRT)
  typedef void (*mdlGetTimeOfNextVarHitFcn)(SimStruct *S);
#endif

typedef void (*mdlOutputsFcn)(SimStruct *S, int_T tid);
typedef void (*mdlOutputsLevel1Fcn)(real_T *y, const real_T *x,
                                    const real_T *u,
                                    SimStruct *S, int_T tid);

typedef void (*mdlUpdateFcn)(SimStruct *S, int_T tid);
typedef void (*mdlUpdateLevel1Fcn)(real_T *x, const real_T *u, SimStruct *S,
                                   int_T tid);

typedef void (*mdlDerivativesFcn)(SimStruct *S);
typedef void (*mdlDerivativesLevel1Fcn)(real_T *dx, const real_T *x,
                                        const real_T *u,
                                        SimStruct *S, int_T tid);

#if defined(MATLAB_MEX_FILE) || defined(NRT)
  typedef void (*mdlZeroCrossingsFcn)(SimStruct *S);
#endif

typedef void (*mdlTerminateFcn)(SimStruct *S);





struct _ssSFcnModelMethods {

  mdlInitializeSizesFcn               mdlInitializeSizes;

#if defined(MATLAB_MEX_FILE)
  mdlGetInputPortWidthLevel1Fcn       mdlGetInputPortWidthLevel1;
  mdlGetOutputPortWidthLevel1Fcn      mdlGetOutputPortWidthLevel1;

  mdlSetInputPortWidthFcn             mdlSetInputPortWidth;
  mdlSetOutputPortWidthFcn            mdlSetOutputPortWidth;

  mdlSetInputPortDataTypeFcn          mdlSetInputPortDataType;
  mdlSetOutputPortDataTypeFcn         mdlSetOutputPortDataType;
#endif

  mdlInitializeSampleTimesFcn         mdlInitializeSampleTimes;

# if defined(MATLAB_MEX_FILE)
  mdlSetInputPortSampleTimeFcn        mdlSetInputPortSampleTime;
  mdlSetOutputPortSampleTimeFcn       mdlSetOutputPortSampleTime;
  mdlSetWorkWidthsFcn                 mdlSetWorkWidths;
  mdlRTWFcn                           mdlRTW;
# endif

  union {
    mdlInitializeConditionsFcn        level2;
    mdlInitializeConditionsLevel1Fcn  level1;
  }                                   mdlInitializeConditions;

  mdlStartFcn                         mdlStart;

# if defined(MATLAB_MEX_FILE)
  mdlCheckParametersFcn               mdlCheckParameters;
  mdlProcessParametersFcn             mdlProcessParameters;
# endif

# if defined(MATLAB_MEX_FILE) || defined(NRT)
  mdlGetTimeOfNextVarHitFcn           mdlGetTimeOfNextVarHit;
# endif

  union {
    mdlOutputsFcn                     level2;
    mdlOutputsLevel1Fcn               level1;
  }                                   mdlOutputs;

  union {
    mdlUpdateFcn                      level2;
    mdlUpdateLevel1Fcn                level1;
  }                                   mdlUpdate;

  union {
    mdlDerivativesFcn                 level2;
    mdlDerivativesLevel1Fcn           level1;
  }                                   mdlDerivatives;
# if defined(MATLAB_MEX_FILE) || defined(NRT)
    mdlZeroCrossingsFcn               mdlZeroCrossings;
# endif

  mdlTerminateFcn                     mdlTerminate;

#if defined(MATLAB_MEX_FILE) && defined(MathWorks_h)
    /*Simulink itself*/
  union {
    mdlSetInputPortComplexSignalFcn   mdlSetInputPortComplexSignal;
    RTWGeneratedEnableFcn             mdlEnable;
  }                                   fcnInEnable;
  union {
    mdlSetOutputPortComplexSignalFcn  mdlSetOutputPortComplexSignal;
    RTWGeneratedDisableFcn            mdlDisable;
  }                                   fcnOutDisable;
#elif defined(MATLAB_MEX_FILE) && !defined(RTW_GENERATED_S_FUNCTION)
    /* User S-Function */
  union {
  mdlSetInputPortComplexSignalFcn     mdlSetInputPortComplexSignal;
  }                                   fcnInEnable;
  union {
  mdlSetOutputPortComplexSignalFcn    mdlSetOutputPortComplexSignal;
  }                                   fcnOutDisable;
#elif defined(MATLAB_MEX_FILE) && defined(RTW_GENERATED_S_FUNCTION)
    /* RTW generated S-Function */
  union {
    mdlSetInputPortComplexSignalFcn   mdlSetInputPortComplexSignal;
    RTWGeneratedEnableFcn             mdlEnable;
  }                                   fcnInEnable;
  union {
    mdlSetOutputPortComplexSignalFcn  mdlSetOutputPortComplexSignal;
    RTWGeneratedDisableFcn            mdlDisable;
  }                                   fcnOutDisable;
#else
    /* RTW executable (grt) */
  union {
    RTWGeneratedEnableFcn             mdlEnable;
  }                                   fcnInEnable;
  union {
    RTWGeneratedDisableFcn            mdlDisable;
  }                                   fcnOutDisable;
#endif
};

typedef real_T const * const * UPtrsType;

struct _ssStates {
  union {
    void      *vect;
    UPtrsType uPtrs;
  } U;                                  /* Inputs for level 1 S-functions    */

  void            *Y;                   /* Output for level 1 S-functions    */

  real_T          *contStates;          /* Continuous state vector           */
  real_T          *discStates;          /* Discrete state vector             */

  int_T           reserved1;
  int_T           reserved2;

  real_T          *dX;                  /* Derivative vector                 */
  int_T           *contStateDisabled;   /* Entry for each cont state         */

  ZCSigState      *prevZCSigState;      /* Used for detecting zc events      */

  real_T          *nonsampledZCs;       /* Nonsampled zero crossing signals  */
  ZCDirection     *nonsampledZCDirs;    /* Nonsampled zc directions          */

  void            *reserved3;
  void            *reserved4;
  int_T           reservedSize;
};



/*===========*
 * SimStruct *
 *===========*/

struct SimStruct_tag {

  const char_T           *modelName;  /* Name of the Simulink model/Sfunc    */

  const char_T           *path;       /* Full "Simulink path" to this s-fcn  */

  SimStruct              *parent;     /* Parent SimStruct                    */
  SimStruct              *root;       /* Root level SimStruct                */

  const char_T           *errorStatus; /* Execution status. Setting to non-NULL
                                         during any mdlFunction will stop the
                                         simulation and the "status" message
                                         will be displayed.                  */
  struct _ssSizes        sizes;        /* Sizes (returned when flag==0)      */

  struct _ssPortInfo     portInfo;    /* Input and output port properties
                                         such as width and direct feedthrough
                                         setting.                            */

  struct _ssSFcnParams   sfcnParams;  /* S-function parameters passed in
                                         P1,...,Pn                           */

  struct _ssStates       states;      /* Input, output, state, derivative,
                                         etc. vectors                        */

  struct _ssWork         work;        /* Various work areas (rwork, iwork,
                                         pwork, user data, block I/O,
                                         block params, etc.)                 */

  struct _ssBlkInfo      blkInfo;     /* Information about S-function blocks */

  struct _ssMdlInfo      *mdlInfo;    /* Model-wide info. All children
                                         SimStruct point to root mdlInfo     */

  struct _ssCallSys      callSys;     /* For use when S-function calls a
                                         "function-call" subsystems          */

  struct _ssRegDataType  regDataType; /* For Registering Data type           */

  struct _ssStInfo       stInfo;      /* Sample time, offset time, etc.      */

  struct {
      struct _ssSFcnModelMethods sFcn; /* For S-functions                    */
  } modelMethods;

  struct SimStruct_tag   **sFunctions;/* SimStruct's for S-Functions
                                         referenced via S-Function blocks.
                                         Used only with RT and NRT.          */
};



/*======================================*
 * SimStruct Get and Set Access methods *
 *======================================*/

/*-------------------------------- S->modelName -----------------------------*/

/*
 * ModelName - This is the name of the S-function. When the SimStruct
 *   is being used with the Real-Time Workshop, then the "root" SimStruct
 *   model name corresponds to the name of the Simulink model.
 */
#define ssGetModelName(S) \
          (S)->modelName                                  /* (const char_T*) */
#define _ssSetModelName(S, name) \
          (S)->modelName = (name)
#if !defined(S_FUNCTION_NAME)
#define ssSetModelName(S,name) _ssSetModelName(S,name)
#else
#define ssSetModelName(S,name) ssSetModelName_cannot_be_used_in_SFunctions
#endif

/*-------------------------------- S->path ----------------------------------*/
/*
 * Path - This is the full path to the S-function. When the SimStruct
 *   is being used with the Real-Time Workshop, then the "root" SimStruct
 *   path corresponds to the name of the Simulink model.
 */
#define ssGetPath(S) \
          (S)->path                                       /* (const char_T*) */
#define _ssSetPath(S, pathPtr) \
          (S)->path = (pathPtr)
#if !defined(S_FUNCTION_NAME)
#define ssSetPath(S,pathPtr) _ssSetPath(S,pathPtr)
#else
#define ssSetPath(S,pathPtr) ssSetPath_cannot_be_used_in_SFunctions
#endif

/*-------------------------------- S->parent --------------------------------*/
/*
 * ParentSS - There is one SimStruct for each S-function in your model.
 *   There is also a SimStruct for the model itself. The SimStruct's are
 *   arranged as a tree with the model SimStruct as the root. The ParentSS
 *   field is used to get at the model SimStruct. User written S-functions
 *   should not use the ssGetParentSS macro directly.
 */
#define ssGetParentSS(S) \
          (S)->parent                                     /*   (SimStruct *) */
#define _ssSetParentSS(S,parentSS) \
          (S)->parent = (parentSS)
#if !defined(S_FUNCTION_NAME)
#define ssSetParentSS(S,parentSS) _ssSetParentSS(S,parentSS)
#else
#define ssSetParentSS(S,parentSS) ssSetParentSS_cannot_be_used_in_SFunctions
#endif

/*-------------------------------- S->root ----------------------------------*/
/*
 * RootSS - This is the "root" SimStruct corresponding to the Simulink
 *   model.
 */
#define ssGetRootSS(S) \
          (S)->root                                       /*   (SimStruct *) */
#define _ssSetRootSS(S,rootSS) \
          (S)->root = (rootSS)
#if !defined(S_FUNCTION_NAME)
#define ssSetRootSS(S,rootSS) _ssSetRootSS(S,rootSS)
#else
#define ssSetRootSS(S,rootSS) ssSetRootSS_cannot_be_used_in_SFunctions
#endif


/*-------------------------------- S->errorStatus ---------------------------*/

/* ErrorStatus - For improved performance and error handling, your S-function
 *   should do:
 *      ssSetErrorStatus(S, "error message");
 *      return;
 *   as opposed to calling mexErrMsgTxt.
 *
 *   Be careful when using ssSetErrorStatus in your S-function. Sometimes you
 *   may wish to use sprintf to format the message. In this case, you
 *   need to allocate memory for the message as opposed to using the stack.
 */
#define ssGetErrorStatus(S) \
          ssGetRootSS(S)->errorStatus                     /* (const char_T*) */
#define ssSetErrorStatus(S, string) \
          ssGetRootSS(S)->errorStatus = (string)


/*-------------------------------- S->sizes ---------------------------------*/

/* SizesPtr - This is an integer pointer of length SIZES_LENGTH. The
 *   fields in the sizes pointers are defined in the _ssSizes structure
 *   (above).
 */
#define ssGetSizesPtr(S) \
          ((int_T *)&(S)->sizes)                          /*   (int_T *)     */

/* NumContStates - This is the number of continuous states within your
 *   S-function. The root SimStruct contains the number of continuous states
 *   within the model itself (including all blocks and S-functions).
 */
#define ssGetNumContStates(S) \
          (S)->sizes.numContStates                        /*   (int_T)       */
#define ssSetNumContStates(S,nContStates) \
          (S)->sizes.numContStates = (nContStates)

/* NumDiscStates - This is the number of discrete states within your
 *   S-function. The root SimStruct contains the number of discrete states
 *   within the model itself (including all blocks and S-functions).
 */
#define ssGetNumDiscStates(S) \
          (S)->sizes.numDiscStates                        /*   (int_T)       */
#define ssSetNumDiscStates(S,nDiscStates) \
          (S)->sizes.numDiscStates = (nDiscStates)

/* NumTotalStates - This is the number of continuous plus discrete states
 *   within your S-function. The root SimStruct contains the number of
 *   continuous plus discrete states within the model itself (including all
 *   blocks and S-functions).
 */
#if S_FUNCTION_LEVEL == 1 || !defined(S_FUNCTION_NAME)
# define ssGetNumTotalStates(S) \
          (ssGetNumContStates(S) + ssGetNumDiscStates(S)) /*   (int_T)       */
#endif


/* NumOutputPorts - This is the number of the output ports of your
 * S-function block.
 */
#if S_FUNCTION_LEVEL == 2
# define ssGetNumOutputPorts(S) \
          (S)->sizes.out.numOutputPorts                   /*   (int_T)       */
# define _ssSetNumOutputPorts(S,nOutputPorts) \
          (S)->sizes.out.numOutputPorts = (nOutputPorts)
# if defined(S_FUNCTION_NAME)
#   if SS_DO_FCN_CALL_ON_MAC
      static int_T ssSetNumOutputPorts(SimStruct *S, int_T nOutputPorts)
      {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
            (*(S)->portInfo.regNumOutputPortsFcn)(
                (S)->portInfo.regNumOutputPortsFcnArg,nOutputPorts);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
      }
#   elif defined(MATLAB_MEX_FILE)
#     define ssSetNumOutputPorts(S,nOutputPorts) \
            (*(S)->portInfo.regNumOutputPortsFcn)( \
                (S)->portInfo.regNumOutputPortsFcnArg,nOutputPorts)
#   else /* RTW S-function block */
#     define ssSetNumOutputPorts(S,nOutputPorts) \
            ((_ssSetNumOutputPorts(S,nOutputPorts)) >= 0)
#   endif
# else /* Simulink or RTW model/run-time interface code */
#   define ssSetNumOutputPorts(S, nOutputPorts) \
            ((_ssSetNumOutputPorts(S,nOutputPorts)) >= 0)
# endif
# define ssSetPortInfoForOutputs(S,ptr) \
             (S)->portInfo.outputs = (ptr)
# define ssGetPortInfoForOutputs(S) \
             (S)->portInfo.outputs
#endif


/* NumInputPorts - This is the number of the input ports of your
 * S-function block.
 */
#if S_FUNCTION_LEVEL == 2
# define ssGetNumInputPorts(S) \
          (S)->sizes.in.numInputPorts                     /*   (int_T)       */
# define _ssSetNumInputPorts(S,nInputPorts) \
          (S)->sizes.in.numInputPorts = (nInputPorts)
# if defined(S_FUNCTION_NAME)
#   if SS_DO_FCN_CALL_ON_MAC
      static int_T ssSetNumInputPorts(SimStruct *S, int_T nInputPorts)
      {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
            (*(S)->portInfo.regNumInputPortsFcn)(
                (S)->portInfo.regNumInputPortsFcnArg,nInputPorts);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
      }
#   elif defined(MATLAB_MEX_FILE)
#     define ssSetNumInputPorts(S,nInputPorts) \
            (*(S)->portInfo.regNumInputPortsFcn)( \
                (S)->portInfo.regNumInputPortsFcnArg,nInputPorts)
#   else /* RTW S-function block */
#     define ssSetNumInputPorts(S,nInputPorts) \
             ((_ssSetNumInputPorts(S,nInputPorts)) >= 0)
#   endif
# else /* Simulink or RTW model/run-time interface code */
#   define ssSetNumInputPorts(S, nInputPorts) \
             ((_ssSetNumInputPorts(S,nInputPorts)) >= 0)
# endif
# define ssSetPortInfoForInputs(S,ptr) \
             (S)->portInfo.inputs = (ptr)
# define ssGetPortInfoForInputs(S) \
             (S)->portInfo.inputs
#endif


#if S_FUNCTION_LEVEL == 2 && !defined(S_FUNCTION_NAME) /* Root Model or SL */

 /* NumY, SizeofY - This is the length of the root output
  * vector, Y, which is the sum of all the widths of the root outport blocks.
  */
# define ssGetNumY(S) \
          (S)->sizes.out.numY                             /*   (int_T)       */
# define ssSetNumY(S,ny) \
          (S)->sizes.out.numY = (ny)

# define ssGetSizeofY(S) \
          (S)->sizes.sizeofY                              /*   (int_T)       */
# define ssSetSizeofY(S,nbytes) \
          (S)->sizes.sizeofY = (nbytes)

 /* NumU, SizeofU - This is the length of the root input
  * vector, U, which is the sum of all the widths of the root inport blocks.
  */
# define ssGetNumU(S) \
          (S)->sizes.in.numU                              /*   (int_T)       */
# define ssSetNumU(S,nu) \
          (S)->sizes.in.numU = (nu)

# define ssGetSizeofU(S) \
          (S)->sizes.sizeofU                              /*   (int_T)       */
# define ssSetSizeofU(S,nbytes) \
          (S)->sizes.sizeofU = (nbytes)

# if !defined(MathWorks_h)
   /* for backwards compatibility with RTW run-time interface */
#  define ssGetNumInputs(S)           ssGetNumU(S)
#  define ssSetNumInputs(S,nInputs)   ssSetNumU(S,nInputs)
#  define ssGetNumOutputs(S)          ssGetNumY(S)
#  define ssSetNumOutputs(S,nOutputs) ssSetNumY(S,nOutputs)
# endif

#endif



#if S_FUNCTION_LEVEL == 1 || defined(RTW_GENERATED_S_FUNCTION)
 /* NumOutputs - This is the size of the output port of your S-function.
  */
# define ssGetNumOutputs(S) \
          (S)->sizes.out.numY                             /*   (int_T)       */
# define ssSetNumOutputs(S,nOutputs) \
          (S)->sizes.out.numY = (nOutputs)

 /* NumInputs - This is the size of the input port of your S-function.
  */
# define ssGetNumInputs(S) \
          (S)->sizes.in.numU                              /*   (int_T)       */
# define ssSetNumInputs(S,nInputs) \
          (S)->sizes.in.numU = (nInputs)

#elif !defined(S_FUNCTION_NAME)

# define ssGetNumOutputsLevel1(S) \
          (S)->sizes.out.numY                             /*   (int_T)       */
# define ssSetNumOutputsLevel1(S,nOutputs) \
          (S)->sizes.out.numY = (nOutputs)

# define ssGetNumInputsLevel1(S) \
          (S)->sizes.in.numU                              /*   (int_T)       */
# define ssSetNumInputsLevel1(S,nInputs) \
          (S)->sizes.in.numU = (nInputs)

#endif

#if S_FUNCTION_LEVEL == 2 && defined(S_FUNCTION_NAME) && \
    !defined(RTW_GENERATED_S_FUNCTION)
# define ssGetNumOutputs(S) \
          ssGetNumOutputs_cannot_be_used_in_level2_SFunctions
# define ssSetNumOutputs(S) \
          ssGetNumOutputs_cannot_be_used_in_level2_SFunctions
# define ssGetNumInputs(S) \
          ssGetNumInputs_cannot_be_used_in_level2_SFunctions
# define ssSetNumInputs(S) \
          ssSetNumInputs_cannot_be_used_in_level2_SFunctions
#endif


#define ssGetReserved(S) \
          (S)->sizes.reserved                             /*   (int_T)       */
#define ssSetReserved(S,val) \
          (S)->sizes.reserved = (val)

#if S_FUNCTION_LEVEL == 2

# if defined(S_FUNCTION_NAME)
#   define ssIsDirectFeedThrough(S) \
          ssIsDirectFeedThrough_cannot_be_used_in_level2_SFunctions
#   define ssSetDirectFeedThrough(S,dirFeed) \
          ssSetDirectFeedThrough_cannot_be_used_in_level2_SFunctions
# else
#   define ssIsDirectFeedThrough(S) \
          (S)->sizes.sysDirFeedThrough                    /*   (int_T)       */
#   define ssSetDirectFeedThrough(S,dirFeed) \
          (S)->sizes.sysDirFeedThrough = (dirFeed)
# endif

#else
 /* DirectFeedThrough - Does your Level 1 S-function use ssGetU (i.e. u
  *   argument)in mdlOutputs?  For the root SimStruct, this field indicates
  *   whether or not the external input vector is used when executing the
  *   Output function (i.e. MdlOutputs) for the model.
  */
# define ssIsDirectFeedThrough(S) \
          (S)->sizes.sysDirFeedThrough                    /*   (int_T)       */
# define ssSetDirectFeedThrough(S,dirFeed) \
          (S)->sizes.sysDirFeedThrough = (dirFeed)
#endif

/* NumBlockIO - Number of elements in the model-wide Block IO vector. Only
 *   valid for the root SimStruct. S-function blocks should not use this
 *   field (i.e. set it to 0).
 */
#define ssGetNumBlockIO(S) \
          (S)->sizes.numBlockIO                           /*   (int_T)       */
#define ssSetNumBlockIO(S,nBlockIO) \
          (S)->sizes.numBlockIO = (nBlockIO)

/* NumBlockParams - Number of parameter elements in the model-wide parameter
 *   vector. Only valid for the root SimStruct. S-function blocks should not
 *   use this field (i.e. set it to 0).
 */
#define ssGetNumBlockParams(S) \
          (S)->sizes.numBlockParams                       /*   (int_T)       */
#define ssSetNumBlockParams(S,nBlockParams) \
          (S)->sizes.numBlockParams = (nBlockParams)

/* Checksum fields - The checksum fields are primarily used by the root
 *   SimStruct to maintain consistency between Simulink external mode and
 *   the code generated from the Real-Time Workshop. In general, user
 *   written S-function should not use this field.
 */
#define ssGetChecksum0(S) \
          (S)->sizes.checksum0                            /*   (uint32_T)    */
#define ssSetChecksum0(S,val) \
          (S)->sizes.checksum0 = (val)

#define ssGetChecksum1(S) \
          (S)->sizes.checksum1                            /*   (uint32_T)    */
#define ssSetChecksum1(S,val) \
          (S)->sizes.checksum1 = (val)

#define ssGetChecksum2(S) \
          (S)->sizes.checksum2                            /*   (uint32_T)    */
#define ssSetChecksum2(S,val) \
          (S)->sizes.checksum2 = (val)

#define ssGetChecksum3(S) \
          (S)->sizes.checksum3                            /*   (uint32_T)    */
#define ssSetChecksum3(S,val) \
          (S)->sizes.checksum3 = (val)

/* RWork - This is the size of the real work vector of your S-function.
 *   The root SimStruct contains the total number of real work elements
 *   used within the model.
 */
#define ssGetNumRWork(S) \
          (S)->sizes.numRWork                             /*   (int_T)       */
#define ssSetNumRWork(S,nRWork) \
          (S)->sizes.numRWork = (nRWork)

/* IWork - This is the size of the integer work vector of your S-function.
 *   The root SimStruct contains the total number of integer work elements
 *   used within the model.w
 */
#define ssGetNumIWork(S) \
          (S)->sizes.numIWork                             /*   (int_T)       */
#define ssSetNumIWork(S,nIWork) \
          (S)->sizes.numIWork = (nIWork)

/* PWork - This is the size of the pointer work vector of your S-function.
 *   The root SimStruct contains the total number of pointer work elements
 *   used within the model.
 */
#define ssGetNumPWork(S) \
          (S)->sizes.numPWork                             /*   (int_T)       */
#define ssSetNumPWork(S,nPWork) \
          (S)->sizes.numPWork = (nPWork)

/* NumSFcnParams - This is the number of expected parameters your S-function
 *   block expects. This field is not used by the root SimStruct.
 */
#define ssGetNumSFcnParams(S) \
          (S)->sizes.numSFcnParams                        /*   (int_T)       */
#define ssSetNumSFcnParams(S,nSFcnParams) \
          (S)->sizes.numSFcnParams = (nSFcnParams)

/* NumSampleTimes - This is the number of sample times your S-function has.
 *   The root SimStruct contains the total number of sample times within
 *   the model.
 */
#define ssGetNumSampleTimes(S) \
          (S)->sizes.numSampleTimes                       /*   (int_T)       */
#define ssSetNumSampleTimes(S,nSampleTimes) \
          (S)->sizes.numSampleTimes = (nSampleTimes)

/* NumSFunctions - This field is used by the root SimStruct to keep track
 *   of the number of child SimStruct's corresponding to S-function blocks.
 *   This field should not be used by S-function blocks (i.e. should be 0).
 */
#define ssGetNumSFunctions(S) \
          (S)->sizes.numSFunctions                        /*   (int_T)       */
#define ssSetNumSFunctions(S,nSFunctions) \
          (S)->sizes.numSFunctions = (nSFunctions)

/* NumBlocks - This field is used by the root SimStruct to keep track of
 *   the number of nonvirtual blocks within the model. This field should
 *   not be used by S-function blocks (i.e. should be 0).
 */
#define ssGetNumBlocks(S) \
          (S)->sizes.numBlocks                            /*   (int_T)       */
#define ssSetNumBlocks(S,nBlocks) \
          (S)->sizes.numBlocks = (nBlocks)

/* Version - This field should not be used by S-function blocks directly.
 *   The the simulink.c include file at the bottom of your S-function block
 *   uses this field. It is also used by root SimStruct for versioning.
 */
#define ssGetVersion(S) \
          (S)->sizes.simStructVer                         /*   (int_T)       */
#define ssSetVersion(S,ver) \
          (S)->sizes.simStructVer = (ver)

#define ssGetSFcnLevel(S) \
          ((S)->sizes.simStructVer == SIMSTRUCT_VERSION_LEVEL2? 2: 1)

/* NumNonsampledZCs - This is the number of nonsampled zero crossings your
 *   S-function has. The root SimStruct contains the total number of nonsampled
 *   zero crossings within your model.
 */
#define ssGetNumNonsampledZCs(S) \
          (S)->sizes.numNonsampledZCs                     /*   (int_T)       */
#define ssSetNumNonsampledZCs(S,nNonsampledZCs) \
          (S)->sizes.numNonsampledZCs = (nNonsampledZCs)

/* NumZCEvents - This is the number of zero crossing events within your model.
 *   This field is not for use by S-functions (i.e. should be 0).
 */
#define ssGetNumZCEvents(S) \
          (S)->sizes.numZCEvents                          /*   (int_T)       */
#define ssSetNumZCEvents(S,nZCEvents) \
          (S)->sizes.numZCEvents = (nZCEvents)

/*
 * NumModes - This is the number of mode vector elements within your
 *   S-function. In the root SimStruct, this field contains the total
 *   number of mode vector elements within your model.
 */
#define ssGetNumModes(S) \
          (S)->sizes.numModes                             /*   (int_T)       */
#define ssSetNumModes(S,n) \
          (S)->sizes.numModes = (n)

/* SizeofBlockIO - This is the size of the block I/O vector in bytes.
 *  These should not be used by S-functions (accelerated models need to
 *  set the size though).
 */
#define ssGetSizeofBlockIO(S) \
          (S)->sizes.sizeofBlockIO                        /*   (int_T)       */
#define ssSetSizeofBlockIO(S,n) \
          (S)->sizes.sizeofBlockIO = (n)

/* nDWorksUsedAsStates - This is the number of elements of data type work
 *   vectors of your S-function which have built-in data types, and must be
 *   used as discrete states.
 *   The root SimStruct contains the total number of data type work vectors
 *   used within the model which is used as state and have built-in data type.
 */
#define ssGetNumDWorksUsedAsDStates(S) \
          (S)->sizes.nDWorksUsedAsDStates                 /*   (int_T)       */
#define ssSetNumDWorksUsedAsDStates(S,val) \
          ((S)->sizes.nDWorksUsedAsDStates = (val))

/* DWork - This is the number of the data type work vector of your S-function.
 *   The root SimStruct contains the total number of data type work vectors
 *   used within the model.
 */
#define ssGetNumDWork(S) \
          (S)->sizes.numDWork                             /*   (int_T)       */
#define _ssSetNumDWork(S,nDWork) \
          ((S)->sizes.numDWork = (nDWork))

/* SizeofDWork - This is the size of the data type work vector in bytes.
 *  These should not be used by S-functions (accelerated models need to
 *  set the size though).
 */
#define ssGetSizeofDWork(S) \
          (S)->sizes.sizeofDWork                     /*   (int_T)       */
#define ssSetSizeofDWork(S,n) \
          (S)->sizes.sizeofDWork = (n)

/* RTWGeneratedSFcn - This is the flag which is set for rtw generated
 * s-function.  Can be removed once all dstates are changed to dworks
 */
#define ssGetRTWGeneratedSFcn(S) \
          (S)->sizes.RTWGeneratedSFcn                /*   (int_T)       */
#define ssSetRTWGeneratedSFcn(S,n) \
          (S)->sizes.RTWGeneratedSFcn = (n)

/* ------------------------------- S->portInfo ------------------------------*/

#if S_FUNCTION_LEVEL == 2

 /* InputPortWidth - Input port width for level 2 s-functions which can
  *  have multiple ports. Each port must have a non-zero positive width or
  *  it can be specified as DYNAMICALLY_SIZED during the set. Latter get's
  *  will return the resolved size for use during simulation.
  */
# define ssGetInputPortWidth(S,port) \
          (S)->portInfo.inputs[(port)].width              /*   (int_T)       */
# define ssSetInputPortWidth(S,port,val) \
          (S)->portInfo.inputs[(port)].width = (val)

 /* InputPortDirectFeedthrough -  port width for level 2 s-functions which can
  *  have multiple ports.
  */
# define ssGetInputPortDirectFeedThrough(S,port) \
          (S)->portInfo.inputs[(port)].directFeedThrough  /*   (int_T)       */
# define ssSetInputPortDirectFeedThrough(S,port,dirFeed) \
          (S)->portInfo.inputs[(port)].directFeedThrough = (dirFeed)

 /* InputDataType - For each input port of your S-function block, this is the
  *   data type. If no data types is specified, then the default is real_T.
  */
# define ssGetInputPortDataType(S,port) \
          (S)->portInfo.inputs[(port)].dataTypeId         /*     (DTypeId)   */
# define ssSetInputPortDataType(S,port,dTypeId) \
          ((S)->portInfo.inputs[(port)].dataTypeId = (dTypeId))

 /* InputComplexSignal - For each input port or your S-function block, this is
  *   whether or not the incomming signal is complex, where (-1=either, 0=no,
  *   1=yes).
  */
# define ssGetInputPortComplexSignal(S,port) \
          (S)->portInfo.inputs[(port)].complexSignal      /*   (CSignal_T)    */
# define ssSetInputPortComplexSignal(S,port,val) \
          (S)->portInfo.inputs[(port)].complexSignal = (val)

 /* InputPortSignalPtrs - This is the pointers to the signal vector for each
  *   input port. For example to access all inputs:
  *       nInputPorts = ssGetNumInputPorts(S);
  *       for (i = 0; i < nInputPorts; i++) {
  *         InputPtrsType u  = ssGetInputPortSignalPtrs(S,i);
  *         int_T         nu = ssGetInputPortWidth(S,i);
  *         for (j = 0; j < nu; j++) {
  *           UseInputInSomeFunction(*u[i]);
  *         }
  *       }
  *   If you know that the input's are always real_T's signals, then the
  *   ssGetInputPortSignalPtrs line would be:
  *     InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S,i);
  */
# define ssGetInputPortSignalPtrs(S,port) \
          (S)->portInfo.inputs[(port)].signalPtrs         /* (InputPtrsType) */
# define ssGetInputPortRealSignalPtrs(S,port) \
           ((InputRealPtrsType)(S)->portInfo.inputs[ \
                                  (port)].signalPtrs)  /* (InputRealPtrsType)*/

# define _ssSetInputPortSignalPtrs(S,port,ptrs) \
          (S)->portInfo.inputs[(port)].signalPtrs = (ptrs)
# if !defined(S_FUNCTION_NAME)
#   define ssSetInputPortSignalPtrs(S,port,ptrs) \
          _ssSetInputPortSignalPtrs(S,port,ptrs)
# else
#   define ssSetInputPortSignalPtrs(S,port,ptrs) \
          ssSetInputPortSignalPtrs_cannot_be_used_in_SFunctions
# endif


 /* InputPortConnected - Is the input connected to a nonvirtual block (i.e.
  *   are there signals entering the S-function block)?
  */
# define ssGetInputPortConnected(S,port) \
          (S)->portInfo.inputs[(port)].connected              /* (int_T) */
# define _ssSetInputPortConnected(S,port,val) \
          (S)->portInfo.inputs[(port)].connected = (val)
# if !defined(S_FUNCTION_NAME)
#   define ssSetInputPortConnected(S,port,val) \
            _ssSetInputPortConnected(S,port,val)
# else
#   define ssSetInputPortConnected(S,port,val) \
            ssSetInputPortConnected_cannot_be_used_in_SFunctions
# endif

 /* InputPortOverWritable - Is the memory occupied by the signals driving this
  *   input port over writiable by (one of the) output ports of the sfunction?
  *
  */
# define ssGetInputPortOverWritable(S,port) \
       ((S)->portInfo.inputs[(port)].attributes.overWritable == 1U)
# define ssSetInputPortOverWritable(S,port,val) \
       ((S)->portInfo.inputs[(port)].attributes.overWritable = (val) ? 1U : 0U)

 /* InputPortReusable - If this is set to false (which is the default value),
  *  then the memory allocated to the signals driving this input port are both
  *  globally visible and persistent. However, if this is set to true then this
  *  signal may be reused by other block outputs (and hence its value will not
  *  be persistent) and may be declared as a local variable in the generated
  *  code when using RTW.
  */
# define ssGetInputPortReusable(S,port) \
       ((S)->portInfo.inputs[(port)].attributes.reusable == 1U)
# define ssSetInputPortReusable(S,port,val) \
       ((S)->portInfo.inputs[(port)].attributes.reusable = (val) ? 1U : 0U)

 /* InputPortBufferDstPort - If an input port and some output port on an
  *   S-Function are *not* test points, and in addition,  if this input port is
  *   overwritable, then one of the "untest-pointed" output ports of this
  *   S-Function mignt reuse the same buffer as the input port! If this happens,
  *   then after compilation, the following macro returns the index of the
  *   output port that reuses the specified input port's buffer. If none of the
  *   S-Function's output ports reuse this input port buffer, then this macro
  *   returns INVALID_PORT_IDX ( = -1).
  */
# define ssGetInputPortBufferDstPort(S,port) \
          ((S)->portInfo.inputs[(port)].bufferDstPort)             /* (int_T) */
# define _ssSetInputPortBufferDstPort(S,port,val) \
          (S)->portInfo.inputs[(port)].bufferDstPort = (val)
# if !defined(S_FUNCTION_NAME)
#   define ssSetInputPortBufferDstPort(S,port,val) \
            _ssSetInputPortBufferDstPort(S,port,val)
# else
#   define ssSetInputPortBufferDstPort(S,port,val) \
            ssSetInputPortBufferDstPort_cannot_be_used_in_SFunctions
# endif

 /* InputPortSampleTime/InputPortOffsetTime - The sample and offset time of
  *   the input port. This should only be used when PORT_BASED_SAMPLE_TIMES
  *   have been specified for ssSetNumSampleTimes in mdlInitializeSizes.
  * InputPortSampleTimeIndex - index of the sample time for the port to
  *   be used in mdlOutputs, mdlUpdate when checing for sample hits.
  */
# define ssGetInputPortSampleTime(S,port) \
          ((S)->portInfo.inputs[(port)].sampleTime)         /* (real_T)      */
# define ssSetInputPortSampleTime(S,port,val) \
          (S)->portInfo.inputs[(port)].sampleTime = (val)   /* (real_T)      */
# define ssGetInputPortOffsetTime(S,port) \
          ((S)->portInfo.inputs[(port)].offsetTime)         /* (real_T)      */
# define ssSetInputPortOffsetTime(S,port,val) \
          (S)->portInfo.inputs[(port)].offsetTime = (val)   /* (real_T)      */

# define ssGetInputPortSampleTimeIndex(S,port) \
          (S)->portInfo.inputs[(port)].sampleTimeIndex      /* (int_T)       */
# if !defined(S_FUNCTION_NAME)
#   define ssSetInputPortSampleTimeIndex(S,port,idx) \
          (S)->portInfo.inputs[(port)].sampleTimeIndex = (idx) /* (int_T)    */
# endif

 /* OutputPortWidth - Output port width for level 2 s-functions which can
  *  have multiple ports. Each port must have a non-zero positive width or
  *  it can be specified as DYNAMICALLY_SIZED during the set. Latter get's
  *  will return the resolved size for use during simulation.
  */
# define ssGetOutputPortWidth(S,port) \
          (S)->portInfo.outputs[(port)].width             /*   (int_T)       */
# define ssSetOutputPortWidth(S,port,val) \
          (S)->portInfo.outputs[(port)].width = (val)

 /* OutputPortReusable - If this is set to false (which is the default value),
  *  then the memory allocated to this output port is both globally visible,
  *  and persistent. However, if you set this to true in the mdlInitializeSizes
  *  function then the memory allocated for this signal may be reused by other
  *  block outputs (hence its value will not be persistent) and may be declared
  *  as a local variable in the generated code when using RTW.
  */
# define ssGetOutputPortReusable(S,port) \
         ((S)->portInfo.outputs[(port)].attributes.reusable == 1U)
# define ssSetOutputPortReusable(S,port,val) \
         ((S)->portInfo.outputs[(port)].attributes.reusable = (val) ? 1U : 0U)

 /* OutputDataType - For each output port of your S-function block, this is the
  *   data type. If no data types is specified, then the default is real_T.
  */
# define ssGetOutputPortDataType(S,port) \
          (S)->portInfo.outputs[(port)].dataTypeId          /* (DTypeId)     */
# define ssSetOutputPortDataType(S,port,dTypeId) \
          ((S)->portInfo.outputs[(port)].dataTypeId= (dTypeId))


 /* OutputComplexSignal - For each input port or your S-function block, this is
  *   whether or not the outgoing signal is complex, where (-1=either, 0=no,
  *   1=yes).
  */
# define ssGetOutputPortComplexSignal(S,port) \
          (S)->portInfo.outputs[(port)].complexSignal         /* (CSignal_T)  */
# define ssSetOutputPortComplexSignal(S,port,val) \
          (S)->portInfo.outputs[(port)].complexSignal = (val)

 /* OutputPortSignal - This is the pointers to the signal vector for each
  *   input port.  For example to write to all outputs:
  *       nOutputPorts = ssGetNumOutputPorts(S);
  *       for (i = 0; i < nOutputPorts; i++) {
  *         void  *y  = ssGetOutputPortSignal(S,i);
  *         int_T ny = ssGetOutputPortWidth(S,i);
  *         for (j = 0; j < ny; j++) {
  *           SomeFunctionToFillInOutput(&y[j]);
  *         }
  *       }
  *   If you know that the output is always a real_T, then the
  *   ssGetOutputPortSignal line would be:
  *       real_T *y  = ssGetOutputPortRealSignal(S,i);
  */
# define ssGetOutputPortSignal(S,port) \
           (S)->portInfo.outputs[(port)].signalVect       /* (void *)        */
# define ssGetOutputPortRealSignal(S,port) \
           ((real_T*)(S)->portInfo.outputs[ \
                                     (port)].signalVect)  /* (real_T*)       */
# define _ssSetOutputPortSignal(S,port,vect) \
           (S)->portInfo.outputs[(port)].signalVect = (vect)
# if !defined(S_FUNCTION_NAME)
#   define ssSetOutputPortSignal(S,port,vect) \
           _ssSetOutputPortSignal(S,port,vect)
# else
#   define ssSetOutputPortSignal(S,port,vect) \
           ssSetOutputPortSignal_cannot_be_used_in_SFunctions
# endif

 /* OutputPortConnected - Is the output connected to a nonvirtual block (i.e.
  *   are the signals leaving the S-function block driving other blocks)?
  */
# define ssGetOutputPortConnected(S,port) \
          (S)->portInfo.outputs[(port)].connected             /* (int_T) */
# define _ssSetOutputPortConnected(S,port,val) \
          (S)->portInfo.outputs[(port)].connected = (val)
# if !defined(S_FUNCTION_NAME)
#   define ssSetOutputPortConnected(S,port,val) \
            _ssSetOutputPortConnected(S,port,val)
# else
#   define ssSetOutputPortConnected(S,port,val) \
            ssSetOutputPortConnected_cannot_be_used_in_SFunctions
# endif

 /* OutputPortSampleTime/OutputPortOffsetTime - The sample and offset time of
  *   the output port. This should only be used when PORT_BASED_SAMPLE_TIMES
  *   have been specified for ssSetNumSampleTimes in mdlInitializeSizes.
  * OutputPortSampleTimeIndex - index of the sample time for the port to
  *   be used in mdlOutputs, mdlUpdate when checing for sample hits.
  */
# define ssGetOutputPortSampleTime(S,port) \
          ((S)->portInfo.outputs[(port)].sampleTime)        /* (real_T)      */
# define ssSetOutputPortSampleTime(S,port,val) \
          (S)->portInfo.outputs[(port)].sampleTime = (val)  /* (real_T)      */
# define ssGetOutputPortOffsetTime(S,port) \
          ((S)->portInfo.outputs[(port)].offsetTime)        /* (real_T)      */
# define ssSetOutputPortOffsetTime(S,port,val) \
          (S)->portInfo.outputs[(port)].offsetTime = (val)  /* (real_T)      */

# define ssGetOutputPortSampleTimeIndex(S,port) \
          (S)->portInfo.outputs[(port)].sampleTimeIndex     /* (int_T)       */
# if !defined(S_FUNCTION_NAME)
#   define ssSetOutputPortSampleTimeIndex(S,port,idx) \
          (S)->portInfo.outputs[(port)].sampleTimeIndex = (idx) /* (int_T)   */
# endif

 /*
  * Routines to setup the fcn and arg which allow the S-function to register
  * the input/output port properties.
  */
# define ssSetRegNumInputPortsFcn(S,fcn) \
            (S)->portInfo.regNumInputPortsFcn = fcn;
# define ssSetRegNumInputPortsFcnArg(S,arg) \
            (S)->portInfo.regNumInputPortsFcnArg = arg;
# define ssSetRegNumOutputPortsFcn(S,fcn) \
            (S)->portInfo.regNumOutputPortsFcn = fcn;
# define ssSetRegNumOutputPortsFcnArg(S,arg) \
            (S)->portInfo.regNumOutputPortsFcnArg = arg;
#endif


/*
 * Set any S-function options which must be OR'd together.
 * For example:  ssSetOption(S, SS_OPTION_EXCEPTION_FREE_CODE
 *                              SS_OPTION_DISCRETE_VALUED_OUTPUT);
 *
 * The available options are:
 * SS_OPTION_EXCEPTION_FREE_CODE - if your S-function does not use
 *   mexErrMsgTxt, mxCalloc, or any other routines which can throw an
 *   exception when called, you can set this option for improved
 *   performance.
 *
 * SS_OPTION_RUNTIME_EXCEPTION_FREE_CODE - Similar to
 *   SS_OPTION_EXCEPTION_FREE_CODE except it only applies to the "run-time"
 *   routines: mdlGetTimeOfNextVarHit, mdlOutputs, mdlUpdate, and
 *   mdlDerivatives.
 *
 * SS_OPTION_DISCRETE_VALUED_OUTPUT - This should be specified if your
 *   S-function has a discrete valued outputs.  This is checked when
 *   your S-function is placed within an algebraic loop. If your S-function
 *   has discrete valued outputs, then its outputs will not be assigned
 *   algebraic variables.
 *
 * SS_OPTION_PLACE_ASAP - This is used to specify that your S-function
 *   should be placed as soon as possible. This is typically used by
 *   devices connecting to hardware.
 *
 * SS_OPTION_ALLOW_INPUT_SCALAR_EXPANSION - This is used to specify
 *   that the input to your S-function input ports can be either 1 or
 *   the size specified by the port which is usually referred to as
 *   the block width.
 *
 * SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME - This is used to disable
 *   your S-function block from inheriting a constant sample time.
 *
 * SS_OPTION_ASYNCHRONOUS - This option applies only to S-functions that
 *   have no input ports and 1 output port.  The output port must be
 *   configured to perform function calls on every element.  If any of
 *   these requirements are not met, the SS_OPTION_ASYNCHRONOUS is
 *   ignored.  Use this option when driving function-call subsystems that
 *   will be attached to interupt service routines.
 *
 * SS_OPTION_ASYNC_RATE_TRANSITION - Use this when your s-function converts a
 *   signal from one rate to another rate.
 *
 * SS_OPTION_RATE_TRANSITION - Use this why your S-function is behaving
 *   as a unit delay or ZOH. This option is only supported for these two
 *   operations. An unit delay operation is identified by the presence
 *   of mdlUpdate and if not present then the operation is ZOH.
 *
 * SS_OPTION_NONSTANDARD_PORT_WIDTHS - If your S-function has mdl
 *   set input/output port routines with dynamically sized ports and the port
 *   widths don't follow the standard rules of scalar exapansion or
 *   vector collapsing, then you may need to set this flag for Simulink.
 *   This usually occurs when the output width is not 1 and not equal to the
 *   maximum of the input widths.
 *
 * SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED - Use this when you have
 *   registered multiple sample times (ssSetNumSampleTimes > 1) to
 *   specify the rate at when each input and output port is running at.
 *   The simulation engine needs this information when checking for
 *   illegal rate transitions.
 *
 * SS_OPTION_SFUNCTION_INLINED_FOR_RTW - Set this if you have a .tlc file
 *   for your S-function and do not have a mdlRTW method. Setting option
 *   has no effect if you have a mdlRTW method.
 */
#if S_FUNCTION_LEVEL == 1 || !defined(S_FUNCTION_NAME)
# define SS_OPTION_USING_ssGetUPtrs              0x00000001
#endif
#define SS_OPTION_EXCEPTION_FREE_CODE            0x00000002
#define SS_OPTION_DISCRETE_VALUED_OUTPUT         0x00000004

#if S_FUNCTION_LEVEL == 2
# define SS_OPTION_PLACE_ASAP                    0x00000008
# define SS_OPTION_ALLOW_INPUT_SCALAR_EXPANSION  0x00000010
# define SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME 0x00000020
# define SS_OPTION_ASYNCHRONOUS                  0x00000040
# define SS_OPTION_ASYNC_RATE_TRANSITION         0x00000080
# define SS_OPTION_RUNTIME_EXCEPTION_FREE_CODE   0x00000100
# define SS_OPTION_RATE_TRANSITION               0x00000200
# define SS_OPTION_NONSTANDARD_PORT_WIDTHS       0x00000400
# define SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED    0x00000800
# define SS_OPTION_SFUNCTION_INLINED_FOR_RTW     0x00001000
#endif

/*
 * SS_OPTION_SUPPORTS_MULTITASKING is a flag for Simulink and is *not* to
 * be used by S-functions.
 */
#define SS_OPTION_SUPPORTS_MULTITASKING         0x00002000

#define SS_HAVEOPT(S,opt) ((ssGetOptions(S) & opt) != 0)

#define ssGetOptions(S) \
          (S)->sizes.options                      /*   (uint_T)      */
#define ssSetOptions(S,opts) \
          (S)->sizes.options = (opts)


/*-------------------------------- S->sfcnParams ---------------------------*/

/*
 * ssGetSFcnParamsCount is provided for use by S-functions to determine
 * the number of parameters entered by the user in the S-function dialog box.
 */

#define ssGetSFcnParamsCount(S) \
          (S)->sfcnParams.count                          /*   (int_T)       */
#define _ssSetSFcnParamsCount(S,n) \
          (S)->sfcnParams.count = (n)
#if !defined(S_FUNCTION_NAME)
#define ssSetSFcnParamsCount(S,n) _ssSetSFcnParamsCount(S,n)
#else
#define ssSetSFcnParamsCount(S,n) \
          ssSetSFcnParamsCount_cannot_be_used_in_SFunctions
#endif

/* SFcnParams - This is a list of mwArray pointers corresponding to the
 *   S-function parameters supplied to your S-function. This is not
 *   used by the root SimStruct.
 */
#define ssGetSFcnParamsPtr(S) \
          (S)->sfcnParams.params                         /*   (mxArray **)  */
#define _ssSetSFcnParamsPtr(S,ptr) \
          (S)->sfcnParams.params = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetSFcnParamsPtr(S,ptr) _ssSetSFcnParamsPtr(S,ptr)
#else
#define ssSetSFcnParamsPtr(S,ptr) \
         ssSetSFcnParamsPtr_cannot_be_used_in_SFunctions
#endif

/* Use ssGetSFcnParam(S,index) to access S-function parameters from within
 * S-functions. The index starts at 0, which corresponds to the (index+1)'th
 * parameter.
 */
#define ssGetSFcnParam(S,index) \
          (S)->sfcnParams.params[index]                  /*   (mxArray *)   */
#define _ssSetSFcnParam(S,index,mat) \
          (S)->sfcnParams.params[index] = (mat)
#if !defined(S_FUNCTION_NAME)
#define ssSetSFcnParam(S,index,mat) _ssSetSFcnParam(S,index,mat)
#else
#define ssSetSFcnParam(S,index,mat) ssSetSFcnParam_cannot_be_used_in_SFunctions
#endif



/* ssSetSFcnParamNotTunable - This should be used by S-function blocks
 *   when a parameter cannot be changed during simulation.
 */
#if defined(MATLAB_MEX_FILE)
# define ssSetSFcnParamNotTunable(S,index) \
          (S)->sfcnParams.attribs[index] = \
            ((S)->sfcnParams.attribs[index] | SFCNPARAM_NOT_TUNABLE)
# define ssSetSFcnParamsCalculated(S,index) \
          (S)->sfcnParams.attribs[index] = \
            ((S)->sfcnParams.attribs[index] | SFCNPARAM_CALCULATED)
#else /* RT or NRT */
# define ssSetSFcnParamNotTunable(S,index) /* do nothing */
#endif

#if defined(MATLAB_MEX_FILE) && (!defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION))
# define ssGetSFcnParamsNotTunable(S,index) \
          ((S)->sfcnParams.attribs[index] & SFCNPARAM_NOT_TUNABLE)
# define ssGetSFcnParamAttribsPtr(S) \
          (S)->sfcnParams.attribs
# define ssSetSFcnParamAttribsPtr(S,ptr) \
          (S)->sfcnParams.attribs = (ptr)
# define ssGetSFcnParamsCalculated(S,index) \
          ((S)->sfcnParams.attribs[index] & SFCNPARAM_CALCULATED)
#endif

/*-------------------------------- S->states --------------------------------*/



/* U - This is the input to your S-function providing you have not specified
 *   the SS_OPTION_USING_ssGetUPtrs. For the root SimStruct this
 *   is the external input vector.
 */
#define _ssGetU(S) \
          ((real_T*)(S)->states.U.vect)                   /*   (real_T *)    */
#if S_FUNCTION_LEVEL == 1 || !defined(S_FUNCTION_NAME) || \
    defined(RTW_GENERATED_S_FUNCTION)
# define ssGetU(S) \
          _ssGetU(S)
# define _ssSetU(S,u) \
          (S)->states.U.vect = (u)
# if !defined(S_FUNCTION_NAME)
#   define ssSetU(S,u) _ssSetU(S,u)
# else
#   define ssSetU(S,u) ssSetU_cannot_be_used_in_SFunctions
# endif
#endif

#if S_FUNCTION_LEVEL == 2 && !defined(S_FUNCTION_NAME)
# define ssGetExternalU(S) \
          ((S)->states.U.vect)
#endif


/* UPtrs - This returns an array of input pointers (UPtrsType) to your
 *   S-function block. This should only be used when using the
 *   SS_OPTION_USING_ssGetUPtrs (level 1 S-functions only).
 */
#if S_FUNCTION_LEVEL == 1 || !defined(S_FUNCTION_NAME) || \
    defined(RTW_GENERATED_S_FUNCTION)
# define ssGetUPtrs(S) \
          (S)->states.U.uPtrs                            /* (UPtrsType)      */
# define _ssSetUPtrs(S,uptrs) \
          (S)->states.U.uPtrs = (uptrs)
# if !defined(S_FUNCTION_NAME)
#   define ssSetUPtrs(S,uptrs) _ssSetUPtrs(S,uptrs)
# else
#   define ssSetUPtrs(S,uptrs) ssSetUPtrs_cannot_be_used_in_SFunctions
# endif
#endif


/* Y - This is the output vector for your S-function block. For the root
 *   SimStruct, this is the external output vector. The length of this
 *   vector is ssGetNumOutputs.
 */
#define _ssGetY(S) \
           ((real_T *)((S)->states.Y))                   /*   (real_T *)    */
#if S_FUNCTION_LEVEL == 1 || !defined(S_FUNCTION_NAME) || \
    defined(RTW_GENERATED_S_FUNCTION)
# define ssGetY(S) \
           _ssGetY(S)
# define _ssSetY(S,y) \
          (S)->states.Y = ((void *)(y))
# if !defined(S_FUNCTION_NAME)
#   define ssSetY(S,y) _ssSetY(S,y)
# else
#   define ssSetY(S,y) ssSetY_cannot_be_used_in_SFunctions
# endif
#endif

#if S_FUNCTION_LEVEL == 2 && !defined(S_FUNCTION_NAME)
# define ssGetExternalY(S) \
          (S)->states.Y
#endif



#if S_FUNCTION_LEVEL == 1
 /* X - This is the state vector for your S-function block. The length of
  *  vector is ssGetNumTotalStates. The first part of the vector
  *  is for the continuous state elements consisting of ssGetNumContStates
  *  and the second part of the vector is the discrete state elements
  *  consisting of ssGetNumDiscStates. For the root model, SimStruct, this
  *  contains the states of all blocks with in the model.
  */
# define ssGetX(S) \
          (S)->states.contStates                          /*   (real_T *)    */
# define _ssSetX(S,x) \
          (S)->states.contStates = (x)
# if !defined(S_FUNCTION_NAME)
#   define ssSetX(S,x) _ssSetX(S,x)
# else
#   define ssSetX(S,x) ssSetX_cannot_be_used_in_SFunctions
# endif

#else /* level 2 s-function */

/*
 * ContStates - continuous state vector for your S-function. There is
 *   no guarantee that if you have both continuous and discrete states
 *   that they will be contiguous
 */
# define ssGetContStates(S) \
          (S)->states.contStates                          /*   (real_T *)    */
# define _ssSetContStates(S,contX) \
          (S)->states.contStates = (contX)
# if !defined(S_FUNCTION_NAME)
#   define ssGetX(S)                ssGetContStates(S)
#   define ssSetContStates(S,contX) _ssSetContStates(S,contX)
# else
#   define ssSetContStates(S,x) ssSetContStates_cannot_be_used_in_SFunctions
# endif

/*
 * DiscStates - discrete state vector for your S-function.
 */
# define ssGetDiscStates(S)      ((S)->states.discStates) /*   (real_T *)    */

# define ssGetRealDiscStates(S)  ssGetDiscStates(S)       /*   (real_T *)    */

# define _ssSetDiscStates(S,discX) \
          (S)->states.discStates = (discX)
# if !defined(S_FUNCTION_NAME)
#   define ssSetDiscStates(S,discX) _ssSetDiscStates(S,discX)
# else
#   define ssSetDiscStates(S,x) ssSetDiscStates_cannot_be_used_in_SFunctions
# endif

#endif


/* dX - This is the continuous state derivative vector for your S-function
 *  block. The length of this vector is ssGetNumContStates. This pointer
 *  changes as the solver evaluates different integration stages to compute
 *  the integral. For the root model SimStruct, this contains the derivatives
 *  for all continuous states of all blocks with in the model.
 */
#define ssGetdX(S) \
          (S)->states.dX                                  /*   (real_T *)    */
#define _ssSetdX(S,dx) \
          (S)->states.dX = (dx)
#if !defined(S_FUNCTION_NAME)
#define ssSetdX(S,dx) _ssSetdX(S,dx)
#else
#define ssSetdX(S,dx) ssSetdX_cannot_be_used_in_SFunctions
#endif


/* ContStateDisabled - This vector is of length ssGetNumContStates and
 *   is a boolean vector indicating whether or not the states in your
 *   S-function block should be integrated. Generally this should not
 *   be modified by your S-function. It will automatically be set and
 *   cleared when your block is within and enabled subsystem during
 *   disables and enables of the subsystem block. For the root model
 *   SimStruct, this contains the boolean values for all continuous states
 *   with in the model.
 */
#define ssGetContStateDisabled(S) \
          (S)->states.contStateDisabled                   /*   (int_T *) */
#define _ssSetContStateDisabled(S,ptr) \
          (S)->states.contStateDisabled = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetContStateDisabled(S,ptr) _ssSetContStateDisabled(S,ptr)
#else
#define ssSetContStateDisabled(S,ptr) \
          ssSetContStateDisabled_cannot_be_used_in_SFunctions
#endif


/* PrevZCSigState - This vector is of length ssGetNumZCEvents. It is
 *   provided for the root model SimStruct. S-function must specify
 *   NumZCEvents as 0.
 */
#define _ssGetPrevZCSigState(S) \
          (S)->states.prevZCSigState                      /* (int_T *)       */
#if !defined(S_FUNCTION_NAME)
#define ssGetPrevZCSigState(S) _ssGetPrevZCSigState(S)
#else
#define ssGetPrevZCSigState(S) \
          ssGetPrevZCSigState_cannot_be_used_in_SFunctions
#endif
#define _ssSetPrevZCSigState(S,ptr) \
          (S)->states.prevZCSigState = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetPrevZCSigState(S,ptr) _ssSetPrevZCSigState(S,ptr)
#else
#define ssSetPrevZCSigState(S,ptr) \
          ssSetPrevZCSigState_cannot_be_used_in_SFunctions
#endif

/* NonsampledZCs - This is vector is of length ssGetNumNonsampledZCs and
 *  is the vector for the nonsampled zero crossings in your S-function.
 *  The mdlZeroCrossings method is used to fill in the nonsampled
 *  zero crossings. For the root SimStruct, this vector contains all
 *  nonsampled zero crossings in the model.
 */
#define ssGetNonsampledZCs(S) \
          (S)->states.nonsampledZCs                       /*   (real_T *)    */
#define _ssSetNonsampledZCs(S,ptr) \
          (S)->states.nonsampledZCs = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetNonsampledZCs(S,ptr) _ssSetNonsampledZCs(S,ptr)
#else
#define ssSetNonsampledZCs(S,ptr) \
          ssSetNonsampledZCs_cannot_be_used_in_SFunctions
#endif

/* NonsampledZCDirs - This is the zero crossing direction for the nonsampled
 *  zero crossings. It is of length ssGetNumNonsampledZCs. The default
 *  is ANY_ZERO_CROSSING.
 */
#define ssGetNonsampledZCDirs(S) \
          (S)->states.nonsampledZCDirs                    /* (ZCDirection*)  */
#define _ssSetNonsampledZCDirs(S,ptr) \
          (S)->states.nonsampledZCDirs = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetNonsampledZCDirs(S,ptr) _ssSetNonsampledZCDirs(S,ptr)
#else
#define ssSetNonsampledZCDirs(S,ptr) \
          ssSetNonsampledZCDirs_cannot_be_used_in_SFunctions
#endif



/*-------------------------------- S->work ----------------------------------*/


/* IWork - This is the integer work vector of length ssGetNumIWork for your
 *   S-function. For the root SimStruct, this is the integer work vector
 *   for all blocks in the model.
 */
#define ssGetIWork(S) \
          (S)->work.iWork                                 /*   (int_T *)     */
#define _ssSetIWork(S,iwork) \
          (S)->work.iWork = (iwork)
#if !defined(S_FUNCTION_NAME)
#define ssSetIWork(S,iwork) _ssSetIWork(S,iwork)
#else
#define ssSetIWork(S,iwork) ssSetIWork_cannot_be_used_in_SFunctions
#endif

#define ssGetIWorkValue(S,iworkIdx) \
          (S)->work.iWork[iworkIdx]                       /*   (int_T)       */
#define ssSetIWorkValue(S,iworkIdx,iworkValue) \
          (S)->work.iWork[iworkIdx] = (iworkValue)

/* RWork - This is the real work vector of length ssGetNumRWork for your
 *   S-function. For the root SimStruct, this is the real work vector
 *   for all blocks in the model.
 */
#define ssGetRWork(S) \
          (S)->work.rWork                                 /*   (real_T *)    */
#define _ssSetRWork(S,rwork) \
          (S)->work.rWork = (rwork)
#if !defined(S_FUNCTION_NAME)
#define ssSetRWork(S,rwork) _ssSetRWork(S,rwork)
#else
#define ssSetRWork(S,rwork) ssSetRWork_cannot_be_used_in_SFunctions
#endif

#define ssGetRWorkValue(S,rworkIdx) \
          (S)->work.rWork[rworkIdx]                       /*   (real_T)      */
#define ssSetRWorkValue(S,rworkIdx,rworkValue) \
          (S)->work.rWork[rworkIdx] = (rworkValue)

/* PWork - This is the pointer work vector of length ssGetNumPWork for your
 *   S-function. For the root SimStruct, this is the pointer work vector
 *   for all blocks in the model.
 */
#define ssGetPWork(S) \
          (S)->work.pWork                                 /*   (void **)     */
#define _ssSetPWork(S,pwork) \
          (S)->work.pWork = (pwork)
#if !defined(S_FUNCTION_NAME)
#define ssSetPWork(S,pwork) _ssSetPWork(S,pwork)
#else
#define ssSetPWork(S,pwork) ssSetPWork_cannot_be_used_in_SFunctions
#endif

#define ssGetPWorkValue(S,pworkIdx) \
          (S)->work.pWork[pworkIdx]                       /*   (void *)      */
#define ssSetPWorkValue(S,pworkIdx,pworkValue) \
          (S)->work.pWork[pworkIdx] = (pworkValue)

/* DWork - This is the data type work vector of length ssGetNumDWork for your
 *   S-function.
 */

#define ssGetDWorkVectors(S) \
          ((S)->work.dWork.vect)                          /* (_ssDTypeArray *)*/
#define _ssSetDWorkVectors(S,dwork) \
          (S)->work.dWork.vect = (dwork)
#if !defined(S_FUNCTION_NAME)
#define ssSetDWorkVectors(S,dwork) _ssSetDWorkVectors(S,dwork)
#else
#define ssSetDWorkVectors(S,dwork) \
          ssSetDWorkVectors_cannot_be_used_in_SFunctions
#endif

/*
 * Get the DWork array.
 */

#define ssGetDWork(S,index) \
          ((S)->work.dWork.vect[(index)].array)                /*   (void *)  */
#define _ssSetDWork(S,index,dwork) \
          (S)->work.dWork.vect[index].array = (dwork)

#if !defined(S_FUNCTION_NAME)
#define ssSetDWork(S,index,dwork) _ssSetDWork(S,index,dwork)
#else
#define ssSetDWork(S,index,dwork) ssSetDWork_cannot_be_used_in_SFunctions
#endif


/*
 * Get the DWork width.
 */
#define ssGetDWorkWidth(S,index) \
          ((S)->work.dWork.vect[(index)].width)                  /* (void *)  */
#define ssSetDWorkWidth(S,index,val) \
          (S)->work.dWork.vect[index].width = (val)
/*
 * Get the DWork data type.
 */
#define ssGetDWorkDataType(S,index) \
          ((S)->work.dWork.vect[(index)].dataTypeId)             /* (DTypeId) */
#define ssSetDWorkDataType(S,index,val) \
          (S)->work.dWork.vect[index].dataTypeId = (val)
/*
 * Get the DWork complex signal.
 */
#define ssGetDWorkComplexSignal(S,index) \
          ((S)->work.dWork.vect[(index)].complexSignal)        /* (CSignal_T) */
#define ssSetDWorkComplexSignal(S,index,val) \
          (S)->work.dWork.vect[index].complexSignal = (val)

/*
 * Get the DWork name.
 */
#define ssGetDWorkName(S,index) \
          ((S)->work.dWork.vect[(index)].name)                  /* (char_T *) */
#define ssSetDWorkName(S,index,val) \
          (S)->work.dWork.vect[index].name = val

/*
 * Get the DWork usedAsDState.
 */
#define ssGetDWorkUsedAsDState(S,index) \
          ((S)->work.dWork.vect[(index)].usedAsDState)         /* (int_T *) */
#define ssSetDWorkUsedAsDState(S,index,val) \
          (S)->work.dWork.vect[index].usedAsDState = val

/*
 * DWorkStruct - point to the Real-Time Workshop data type work structure.
 *   When the generated code (e.g. real-time malloc code format) sets up
 *   a dwork struct, the above DWork macros on the vect cannot be used.
 */
#if !defined(S_FUNCTION_NAME)
#define ssGetDWorkStruct(S) \
          ((S)->work.dWork.strucPtr)
#define ssSetDWorkStruct(S,val) \
          (S)->work.dWork.strucPtr = (val)
#endif



/* ModeVector - This is the mode vector of length ssGetNumModes for your
 *   S-function. For the root SimStruct, this is the mode vector
 *   for all blocks in the model.
 */
#define ssGetModeVector(S) \
          (S)->work.modeVector                            /*   (int_T *)     */
#define _ssSetModeVector(S,vect) \
          (S)->work.modeVector = (vect)
#if !defined(S_FUNCTION_NAME)
#define ssSetModeVector(S,vect) _ssSetModeVector(S,vect)
#else
#define ssSetModeVector(S,vect) ssSetModeVector_cannot_be_used_in_SFunctions
#endif

#define ssGetModeVectorValue(S,idx) \
          (S)->work.modeVector[idx]                       /*   (int_T)       */
#define ssSetModeVectorValue(S,idx,val) \
          (S)->work.modeVector[idx] = (val)

/* UserData - This is a void pointer to which you can attach a data object
 *   for your S-function.
 */
#define ssGetUserData(S) \
          (S)->work.userData                              /*   (void *)      */
#define ssSetUserData(S,userDataPtr) \
          (S)->work.userData = (userDataPtr)

/*-------------------------------- S->blkInfo -------------------------------*/

/* InputConnected - True/false are any inputs to the S-function connected
 *   to nonvirtual blocks?
 */
#if S_FUNCTION_LEVEL==1 || defined(MathWorks_h)
# define ssGetInputConnected(S) \
          (S)->blkInfo.inputConnected                    /* (int_T)      */
# define _ssSetInputConnected(S,setting) \
          (S)->blkInfo.inputConnected = (setting)
# if !defined(S_FUNCTION_NAME)
#  define ssSetInputConnected(S,setting) _ssSetInputConnected(S,setting)
# else
#  define ssSetInputConnected(S,setting) \
          ssSetInputConnected_cannot_be_used_in_SFunctions
# endif
#else
# define ssGetInputConnected(S) \
          ssGetInputConnected_cannot_be_used_in_Level2_SFunctions
#endif

/* OutputConnected - True/false are any outputs of the S-function connected
 *   to nonvirtual blocks?
 */
#define ssGetOutputConnected(S) \
          (S)->blkInfo.outputConnected                   /* (int_T)      */
#define _ssSetOutputConnected(S,setting) \
          (S)->blkInfo.outputConnected = (setting)
#if !defined(S_FUNCTION_NAME)
#define ssSetOutputConnected(S,setting) _ssSetOutputConnected(S,setting)
#else
#define ssSetOutputConnected(S,setting) \
          ssSetOutputConnected_cannot_be_used_in_SFunctions
#endif

/* PlacementGroup - This is an advanced features for S-functions which
 *   can be applied to source (i.e. no input port) or sink (i.e. no output
 *   port) S-function. Any S-functions which the same placement group
 *   will be placed adjacent to each other in the sorted list.
 */
#define ssGetPlacementGroup(S) \
          (S)->blkInfo.placementGroup                    /* (const char_T *) */
#define ssSetPlacementGroup(S,name) \
          (S)->blkInfo.placementGroup = (name)


/*-------------------------------- S->mdlInfo -------------------------------*/
#define ssGetMdlInfoPtr(S) \
          (S)->mdlInfo                              /* (struct _ssMdlInfo *) */
#define _ssSetMdlInfoPtr(S,ptr) \
          (S)->mdlInfo = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetMdlInfoPtr(S,ptr) _ssSetMdlInfoPtr(S,ptr)
#else
#define ssSetMdlInfoPtr(S,ptr) ssSetMdlInfoPtr_cannot_be_used_in_SFunctions
#endif

#define ssGetSimMode(S) \
          (S)->mdlInfo->simMode                           /* (SS_SimMode)    */
#define _ssSetSimMode(S,mode) \
          (S)->mdlInfo->simMode = (mode)
#if !defined(S_FUNCTION_NAME)
#define ssSetSimMode(S,mode) _ssSetSimMode(S,mode)
#else
#define ssSetSimMode(S,mode) ssSetSimMode_cannot_be_used_in_SFunctions
#endif

#define ssGetTPtr(S) \
          (S)->mdlInfo->t                                 /*   (time_T *)    */
#define _ssSetTPtr(S,t_ptr) \
          (S)->mdlInfo->t = (t_ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetTPtr(S,t_ptr) _ssSetTPtr(S,t_ptr)
#else
#define ssSetTPtr(S,t_ptr) ssSetTPtr_cannot_be_used_in_SFunctions
#endif

#define ssGetT(S) \
          (S)->mdlInfo->t[0]                              /*   (time_T)      */
#define _ssSetT(S,time) \
          (S)->mdlInfo->t[0] = (time)
#if !defined(S_FUNCTION_NAME)
#define ssSetT(S,time) _ssSetT(S,time)
#else
#define ssSetT(S,time) ssSetT_cannot_be_used_in_SFunctions
#endif

#define ssGetTaskTime(S,sti) \
          (S)->mdlInfo->t[ssGetSampleTimeTaskID(S,sti)]   /*   (time_T)      */
#define _ssSetTaskTime(S,sti,time) \
          (S)->mdlInfo->t[sti]=(time)
#if !defined(S_FUNCTION_NAME)
#define ssSetTaskTime(S,sti,time) _ssSetTaskTime(S,sti,time)
#else
#define ssSetTaskTime(S,sti,time) ssSetTaskTime_cannot_be_used_in_SFunctions
#endif

#define ssGetSampleHitPtr(S) \
          (S)->mdlInfo->sampleHits                        /*   (int_T *) */
#define _ssSetSampleHitPtr(S,ptr) \
          (S)->mdlInfo->sampleHits = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetSampleHitPtr(S,ptr) _ssSetSampleHitPtr(S,ptr)
#else
#define ssSetSampleHitPtr(S,ptr) ssSetSampleHitPtr_cannot_be_used_in_SFunctions
#endif

#define ssGetTStart(S) \
          (S)->mdlInfo->tStart                            /*   (time_T)      */
#define _ssSetTStart(S,tstart) \
          (S)->mdlInfo->tStart = (tstart)
#if !defined(S_FUNCTION_NAME)
#define ssSetTStart(S,tstart) _ssSetTStart(S,tstart)
#else
#define ssSetTStart(S,tstart) ssSetTStart_cannot_be_used_in_SFunctions
#endif

#define ssGetTFinal(S) \
          (S)->mdlInfo->tFinal                            /*   (time_T)      */
#define _ssSetTFinal(S,tfinal) \
          (S)->mdlInfo->tFinal = (tfinal)
#if !defined(S_FUNCTION_NAME)
#define ssSetTFinal(S,tfinal) _ssSetTFinal(S,tfinal)
#else
#define ssSetTFinal(S,tfinal) ssSetTFinal_cannot_be_used_in_SFunctions
#endif

/* TimeOfLastOutput - This is reserved for use by RTW and Simulink. However,
 *   S-function can look at this within their continuous task. It is
 *   the time of the last output for the model - not the s-function
 *   itself.
 */
#define ssGetTimeOfLastOutput(S) \
          (S)->mdlInfo->timeOfLastOutput                  /*   (time_T)      */
#define _ssSetTimeOfLastOutput(S,tlast) \
          (S)->mdlInfo->timeOfLastOutput = (tlast)
#if !defined(S_FUNCTION_NAME)
#define ssSetTimeOfLastOutput(S,tlast) _ssSetTimeOfLastOutput(S,tlast)
#else
#define ssSetTimeOfLastOutput(S,tlast) \
          ssSetTimeOfLastOutput_cannot_be_used_in_SFunctions
#endif

#define _ssGetTimingData(S) \
          (S)->mdlInfo->timingData                        /*   (void *)      */
#if !defined(S_FUNCTION_NAME)
#define ssGetTimingData(S) _ssGetTimingData(S)
#else
#define ssGetTimingData(S) ssGetTimingData_cannot_be_used_in_SFunctions
#endif
#define _ssSetTimingData(S,d) \
          (S)->mdlInfo->timingData = (d)
#if !defined(S_FUNCTION_NAME)
#define ssSetTimingData(S,d) _ssSetTimingData(S,d)
#else
#define ssSetTimingData(S,d) ssSetTimingData_cannot_be_used_in_SFunctions
#endif

#define ssIsMinorTimeStep(S) \
          ((S)->mdlInfo->simTimeStep == MINOR_TIME_STEP)  /*  (int_T)    */

#define ssIsMajorTimeStep(S) \
          ((S)->mdlInfo->simTimeStep == MAJOR_TIME_STEP)  /*  (int_T)    */

#define ssGetSimTimeStep(S) \
          (S)->mdlInfo->simTimeStep                       /*  (SimTimeStep)  */
#define _ssSetSimTimeStep(S,stepType) \
          (S)->mdlInfo->simTimeStep = (stepType)
#if !defined(S_FUNCTION_NAME)
#define ssSetSimTimeStep(S,stepType) _ssSetSimTimeStep(S,stepType)
#else
#define ssSetSimTimeStep(S,stepType) \
          ssSetSimTimeStep_cannot_be_used_in_SFunctions
#endif

#define ssGetStopRequested(S) \
          (S)->mdlInfo->stopRequested                     /*   (int_T)   */
#define ssSetStopRequested(S,val) \
          (S)->mdlInfo->stopRequested = (val)

#define ssGetLogOutput(S) \
          (S)->mdlInfo->logOutput                         /*    (int_T)  */
#define _ssSetLogOutput(S,setting) \
          (S)->mdlInfo->logOutput = setting
#if !defined(S_FUNCTION_NAME)
#define ssSetLogOutput(S,setting) _ssSetLogOutput(S,setting)
#else
#define ssSetLogOutput(S,setting) ssSetLogOutput_cannot_be_used_in_SFunctions
#endif

#define _ssGetOutputTimes(S) \
          (S)->mdlInfo->outputTimes                       /*   (time_T*)     */
#if !defined(S_FUNCTION_NAME)
#define ssGetOutputTimes(S) _ssGetOutputTimes(S)
#else
#define ssGetOutputTimes(S) ssGetOutputTimes_cannot_be_used_in_SFunctions
#endif
#define _ssSetOutputTimes(S,ptr) \
          (S)->mdlInfo->outputTimes = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetOutputTimes(S,ptr) _ssSetOutputTimes(S,ptr)
#else
#define ssSetOutputTimes(S,ptr) ssSetOutputTimes_cannot_be_used_in_SFunctions
#endif

#define _ssGetNextOutputTime(S) \
          (S)->mdlInfo->outputTimes[ \
             (S)->mdlInfo->outputTimesIndex]              /*   (time_T)      */
#if !defined(S_FUNCTION_NAME)
#define ssGetNextOutputTime(S) _ssGetNextOutputTime(S)
#else
#define ssGetNextOutputTime(S) ssGetNextOutputTime_cannot_be_used_in_SFunctions
#endif

#define _ssGetOutputTimesIndex(S) \
          (S)->mdlInfo->outputTimesIndex                  /*   (int_T)       */
#if !defined(S_FUNCTION_NAME)
#define ssGetOutputTimesIndex(S) _ssGetOutputTimesIndex(S)
#else
#define ssGetOutputTimesIndex(S) \
          ssGetOutputTimesIndex_cannot_be_used_in_SFunctions
#endif
#define _ssSetOutputTimesIndex(S,index) \
          (S)->mdlInfo->outputTimesIndex = (index)
#if !defined(S_FUNCTION_NAME)
#define ssSetOutputTimesIndex(S,index) _ssSetOutputTimesIndex(S,index)
#else
#define ssSetOutputTimesIndex(S,index) \
          ssSetOutputTimesIndex_cannot_be_used_in_SFunctions
#endif

#define _ssGetNumOutputTimes(S) \
          (S)->mdlInfo->numOutputTimes                    /*   (int_T)       */
#if !defined(S_FUNCTION_NAME)
#define ssGetNumOutputTimes(S) _ssGetNumOutputTimes(S)
#else
#define ssGetNumOutputTimes(S) ssGetNumOutputTimes_cannot_be_used_in_SFunctions
#endif
#define _ssSetNumOutputTimes(S,n) \
          (S)->mdlInfo->numOutputTimes = (n)
#if !defined(S_FUNCTION_NAME)
#define ssSetNumOutputTimes(S,n) _ssSetNumOutputTimes(S,n)
#else
#define ssSetNumOutputTimes(S,n) \
          ssSetNumOutputTimes_cannot_be_used_in_SFunctions
#endif

#define _ssGetOutputTimesOnly(S) \
          (S)->mdlInfo->outputTimesOnly                   /*   (int_T)   */
#if !defined(S_FUNCTION_NAME)
#define ssGetOutputTimesOnly(S) _ssGetOutputTimesOnly(S)
#else
#define ssGetOutputTimesOnly(S) \
          ssGetOutputTimesOnly_cannot_be_used_in_SFunctions
#endif
#define _ssSetOutputTimesOnly(S,setting) \
          (S)->mdlInfo->outputTimesOnly = (setting)
#if !defined(S_FUNCTION_NAME)
#define ssSetOutputTimesOnly(S,setting) _ssSetOutputTimesOnly(S,setting)
#else
#define ssSetOutputTimesOnly(S,setting) \
          ssSetOutputTimesOnly_cannot_be_used_in_SFunctions
#endif

#define _ssGetNeedOutputAtTPlusTol(S) \
          (S)->mdlInfo->needOutputAtTPlusTol              /*   (int_T)   */
#if !defined(S_FUNCTION_NAME)
#define ssGetNeedOutputAtTPlusTol(S) _ssGetNeedOutputAtTPlusTol(S)
#else
#define ssGetNeedOutputAtTPlusTol(S) \
          ssGetNeedOutputAtTPlusTol_cannot_be_used_in_SFunctions
#endif
#define _ssSetNeedOutputAtTPlusTol(S,b) \
          (S)->mdlInfo->needOutputAtTPlusTol = (b)
#if !defined(S_FUNCTION_NAME)
#define ssSetNeedOutputAtTPlusTol(S,b) _ssSetNeedOutputAtTPlusTol(S,b)
#else
#define ssSetNeedOutputAtTPlusTol(S,b) \
          ssSetNeedOutputAtTPlusTol_cannot_be_used_in_SFunctions
#endif

#define ssGetSolverName(S) \
          (S)->mdlInfo->solverName                        /*   (char_T *)    */
#define _ssSetSolverName(S,name) \
          (S)->mdlInfo->solverName = (name)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverName(S,name) _ssSetSolverName(S,name)
#else
#define ssSetSolverName(S,name) ssSetSolverName_cannot_be_used_in_SFunctions
#endif

#define ssIsVariableStepSolver(S) \
          (S)->mdlInfo->variableStepSolver               /*   (int_T *)  */
#define _ssSetVariableStepSolver(S,s) \
          (S)->mdlInfo->variableStepSolver = (s)
#if !defined(S_FUNCTION_NAME)
#define ssSetVariableStepSolver(S,s) _ssSetVariableStepSolver(S,s)
#else
#define ssSetVariableStepSolver(S,s) \
          ssSetVariableStepSolver_cannot_be_used_in_SFunctions
#endif

#define _ssGetSolverData(S) \
          (S)->mdlInfo->solverData                        /*   (void *)      */
#if !defined(S_FUNCTION_NAME)
#define ssGetSolverData(S) _ssGetSolverData(S)
#else
#define ssGetSolverData(S) ssGetSolverData_cannot_be_used_in_SFunctions
#endif
#define _ssSetSolverData(S,solverDataPtr) \
          (S)->mdlInfo->solverData = (solverDataPtr)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverData(S,solverDataPtr) _ssSetSolverData(S,solverDataPtr)
#else
#define ssSetSolverData(S,solverDataPtr) \
          ssSetSolverData_cannot_be_used_in_SFunctions
#endif

# define ssGetSolverStopTime(S) \
          (S)->mdlInfo->solverStopTime                    /*   (time_T)      */
# define _ssSetSolverStopTime(S,stoptime) \
          (S)->mdlInfo->solverStopTime = (stoptime)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverStopTime(S,stoptime) _ssSetSolverStopTime(S,stoptime)
#else
#define ssSetSolverStopTime(S,stoptime) \
          ssSetSolverStopTime_cannot_be_used_in_SFunctions
#endif

#define ssGetStepSize(S) \
          (S)->mdlInfo->stepSize                          /*   (time_T)      */
#define _ssSetStepSize(S,size) \
          (S)->mdlInfo->stepSize=(size)
#if !defined(S_FUNCTION_NAME)
#define ssSetStepSize(S,size) _ssSetStepSize(S,size)
#else
#define ssSetStepSize(S,size) ssSetStepSize_cannot_be_used_in_SFunctions
#endif

#define ssGetSolverNeedsReset(S) \
          (S)->mdlInfo->solverNeedsReset                  /*  (int_T)    */
#define ssSetSolverNeedsReset(S) \
          (S)->mdlInfo->solverNeedsReset = ((int_T)1);
#define _ssClearSolverNeedsReset(S) \
          (S)->mdlInfo->solverNeedsReset = ((int_T)0);
#if !defined(S_FUNCTION_NAME)
#define ssClearSolverNeedsReset(S) _ssClearSolverNeedsReset(S)
#else
#define ssClearSolverNeedsReset(S) \
          ssClearSolverNeedsReset_cannot_be_used_in_SFunctions
#endif

#define ssGetZCCacheNeedsReset(S) \
          (S)->mdlInfo->zcCacheNeedsReset                 /*  (int_T)    */
#define ssSetZCCacheNeedsReset(S,setting) \
          (S)->mdlInfo->zcCacheNeedsReset = (setting);

#define ssGetDerivCacheNeedsReset(S) \
          (S)->mdlInfo->derivCacheNeedsReset              /*  (int_T)    */
#define ssSetDerivCacheNeedsReset(S,setting) \
          (S)->mdlInfo->derivCacheNeedsReset = (setting);

#define ssGetSolverRefineFactor(S) \
          (S)->mdlInfo->solverRefineFactor                /*   (int_T)       */
#define _ssSetSolverRefineFactor(S,fact) \
          (S)->mdlInfo->solverRefineFactor = (fact)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverRefineFactor(S,fact) _ssSetSolverRefineFactor(S,fact)
#else
#define ssSetSolverRefineFactor(S,fact) \
          ssSetSolverRefineFactor_cannot_be_used_in_SFunctions
#endif

#define ssGetSolverRelTol(S) \
          (S)->mdlInfo->solverRelTol                      /*   (real_T)      */
#define _ssSetSolverRelTol(S,rtol) \
          (S)->mdlInfo->solverRelTol = (rtol)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverRelTol(S,rtol) _ssSetSolverRelTol(S,rtol)
#else
#define ssSetSolverRelTol(S,rtol) \
          ssSetSolverRelTol_cannot_be_used_in_SFunctions
#endif

#define ssGetSolverAbsTol(S) \
          (S)->mdlInfo->solverAbsTol                      /*   (*real_T)     */
#define _ssSetSolverAbsTol(S,atol) \
          (S)->mdlInfo->solverAbsTol = (atol)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverAbsTol(S,atol) _ssSetSolverAbsTol(S,atol)
#else
#define ssSetSolverAbsTol(S,atol) \
          ssSetSolverAbsTol_cannot_be_used_in_SFunctions
#endif

#define ssGetSolverMaxOrder(S) \
          (S)->mdlInfo->solverMaxOrder                    /*   (real_T)      */
#define _ssSetSolverMaxOrder(S,maxOrder) \
          (S)->mdlInfo->solverMaxOrder = (maxOrder);
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverMaxOrder(S,maxOrder) _ssSetSolverMaxOrder(S,maxOrder)
#else
#define ssSetSolverMaxOrder(S,maxOrder) \
          ssSetSolverMaxOrder_cannot_be_used_in_SFunctions
#endif

/* ssGetSolverMode - This can return SOLVER_MODE_AUTO in mdlInitializeSizes.
 *   However, in mdlSetWorkWidths and any methods called after mdlSetWorkWidths,
 *   solver mode will be either SOLVER_MODE_SINGLETASKING or 
 *   SOLVER_MODE_MULTITASKING.
 */
#define ssGetSolverMode(S) \
          (S)->mdlInfo->solverMode                       /*   (SolverMode)   */
#define _ssSetSolverMode(S,mode) \
          (S)->mdlInfo->solverMode=(mode)
#if !defined(S_FUNCTION_NAME)
#define ssSetSolverMode(S,mode) _ssSetSolverMode(S,mode)
#else
#define ssSetSolverMode(S,mode) ssSetSolverMode_cannot_be_used_in_SFunctions
#endif

#define ssGetMaxStepSize(S) \
          (S)->mdlInfo->maxStepSize                       /*   (time_T)      */
#define _ssSetMaxStepSize(S,size) \
          (S)->mdlInfo->maxStepSize=(size)
#if !defined(S_FUNCTION_NAME)
#define ssSetMaxStepSize(S,size) _ssSetMaxStepSize(S,size)
#else
#define ssSetMaxStepSize(S,size) ssSetMaxStepSize_cannot_be_used_in_SFunctions
#endif

#define ssGetFixedStepSize(S) \
          (S)->mdlInfo->fixedStepSize                     /*   (time_T)      */
#define _ssSetFixedStepSize(S,size) \
          (S)->mdlInfo->fixedStepSize=(size)
#if !defined(S_FUNCTION_NAME)
#define ssSetFixedStepSize(S,size) _ssSetFixedStepSize(S,size)
#else
#define ssSetFixedStepSize(S,size) \
          ssSetFixedStepSize_cannot_be_used_in_SFunctions
#endif

#define _ssGetNumSampledDerivInputs(S) \
          (S)->mdlInfo->numSampledDerivInputs             /*   (real_T)      */
#if !defined(S_FUNCTION_NAME)
#define ssGetNumSampledDerivInputs(S) _ssGetNumSampledDerivInputs(S)
#else
#define ssGetNumSampledDerivInputs(S) \
          ssGetNumSampledDerivInputs_cannot_be_used_in_SFunctions
#endif
#define _ssSetNumSampledDerivInputs(S,num) \
          (S)->mdlInfo->numSampledDerivInputs = (num)
#if !defined(S_FUNCTION_NAME)
#define ssSetNumSampledDerivInputs(S,num) _ssSetNumSampledDerivInputs(S,num)
#else
#define ssSetNumSampledDerivInputs(S,num) \
          ssSetNumSampledDerivInputs_cannot_be_used_in_SFunctions
#endif

#define _ssGetSampledDerivInputPtrs(S) \
          (S)->mdlInfo->sampledDerivInputPtrs             /*   (real_T**)   */
#if !defined(S_FUNCTION_NAME)
#define ssGetSampledDerivInputPtrs(S) _ssGetSampledDerivInputPtrs(S)
#else
#define ssGetSampledDerivInputPtrs(S) \
         ssGetSampledDerivInputPtrs__cannot_be_used_in_SFunctions
#endif
#define _ssSetSampledDerivInputPtrs(S,ptr) \
          (S)->mdlInfo->sampledDerivInputPtrs = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetSampledDerivInputPtrs(S,ptr) _ssSetSampledDerivInputPtrs(S,ptr)
#else
#define ssSetSampledDerivInputPtrs(S,ptr) \
          ssSetSampledDerivInputPtrs_cannot_be_used_in_SFunctions
#endif

#define _ssGetPrevSampledDerivInputs(S) \
          (S)->mdlInfo->prevSampledDerivInputs            /*   (real_T*)     */
#if !defined(S_FUNCTION_NAME)
#define ssGetPrevSampledDerivInputs(S) _ssGetPrevSampledDerivInputs(S)
#else
#define ssGetPrevSampledDerivInputs(S) \
          ssGetPrevSampledDerivInputs_cannot_be_used_in_SFunctions
#endif
#define _ssSetPrevSampledDerivInputs(S,ptr) \
          (S)->mdlInfo->prevSampledDerivInputs = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetPrevSampledDerivInputs(S,ptr) _ssSetPrevSampledDerivInputs(S,ptr)
#else
#define ssSetPrevSampledDerivInputs(S,ptr) \
          ssSetPrevSampledDerivInputs_cannot_be_used_in_SFunctions
#endif

#if defined(MULTITASKING) || defined(MATLAB_MEX_FILE)

# define ssGetPerTaskSampleHitsPtr(S) \
          (S)->mdlInfo->perTaskSampleHits                 /*   (int_T *) */

# define _ssSetPerTaskSampleHitsPtr(S, hitsMatrix) \
          (S)->mdlInfo->perTaskSampleHits = (hitsMatrix)
# if !defined(S_FUNCTION_NAME)
# define ssSetPerTaskSampleHitsPtr(S, hitsMatrix) \
           _ssSetPerTaskSampleHitsPtr(S, hitsMatrix)
# else
# define ssSetPerTaskSampleHitsPtr(S, hitsMatrix) \
           ssSetPerTaskSampleHitsPtr_cannot_be_used_in_SFunctions
# endif

#endif


#define ssGetDataStoreMem(S) \
          (S)->mdlInfo->dataStoreMem                      /*  (real_T*)      */
#define _ssSetDataStoreMem(S,dsMem) \
          (S)->mdlInfo->dataStoreMem = (dsMem)
#if !defined(S_FUNCTION_NAME)
#define ssSetDataStoreMem(S,dsMem) _ssSetDataStoreMem(S,dsMem)
#else
#define ssSetDataStoreMem(S,dsMem) \
          ssSetDataStoreMem_cannot_be_used_in_SFunctions
#endif

#if !defined(S_FUNCTION_NAME)
/*
 * The following logging macros are for use by the Real-Time Workshop and
 * should not be used by S-functions.
 */
# define ssSetRTWLogInfo(S,ptr) \
         (S)->mdlInfo->rtwLogInfo = (ptr)                  /* (RTWLogInfo *)  */

# define ssGetLogFormat(S) \
         (S)->mdlInfo->rtwLogInfo->logFormat               /* (int_T)         */
# define ssSetLogFormat(S,val) \
         (S)->mdlInfo->rtwLogInfo->logFormat = (val)

# define ssGetLogMaxRows(S) \
         (S)->mdlInfo->rtwLogInfo->logMaxRows              /* (int_T)         */
# define ssSetLogMaxRows(S,num) \
         (S)->mdlInfo->rtwLogInfo->logMaxRows = (num)

# define ssGetLogDecimation(S) \
         (S)->mdlInfo->rtwLogInfo->logDecimation           /* (int_T)         */
# define ssSetLogDecimation(S,num) \
         (S)->mdlInfo->rtwLogInfo->logDecimation = (num)

# define ssGetLogVarNameModifier(S) \
         (S)->mdlInfo->rtwLogInfo->logVarNameModifier      /* (const char_T*) */
# define ssSetLogVarNameModifier(S,name) \
         (S)->mdlInfo->rtwLogInfo->logVarNameModifier = (name)

# define ssGetLogT(S) \
         (S)->mdlInfo->rtwLogInfo->logT                    /* (const char_T*) */
# define ssSetLogT(S,name) \
         (S)->mdlInfo->rtwLogInfo->logT = (name)

# define ssGetLogX(S) \
         (S)->mdlInfo->rtwLogInfo->logX                    /* (const char_T*) */
# define ssSetLogX(S,name) \
         (S)->mdlInfo->rtwLogInfo->logX = (name)

# define ssGetLogXFinal(S) \
         (S)->mdlInfo->rtwLogInfo->logXFinal               /* (const char_T*) */
# define ssSetLogXFinal(S,name) \
         (S)->mdlInfo->rtwLogInfo->logXFinal = (name)

# define ssGetLogXSignalPtrs(S) \
         (S)->mdlInfo->logXSignalPtrs                  /* (LogSignalPtrsType) */
# define ssSetLogXSignalPtrs(S,ptr) \
         (S)->mdlInfo->logXSignalPtrs = (ptr)

# define ssGetLogXSignalInfo(S) \
         (S)->mdlInfo->rtwLogInfo->logXSignalInfo     /* (RTWLogSignalInfo *) */
# define ssSetLogXSignalInfo(S,ptr) \
         (S)->mdlInfo->rtwLogInfo->logXSignalInfo = (ptr)

# define ssGetLogY(S) \
         (S)->mdlInfo->rtwLogInfo->logY                    /* (const char_T*) */
# define ssSetLogY(S,name) \
         (S)->mdlInfo->rtwLogInfo->logY = (name)

# define ssGetLogYNCols(S)  NULL                           /* obsolete        */

# define ssGetLogYSignalInfo(S) \
         (S)->mdlInfo->rtwLogInfo->logYSignalInfo     /* (RTWLogSignalInfo *) */
# define ssSetLogYSignalInfo(S,ptr) \
         (S)->mdlInfo->rtwLogInfo->logYSignalInfo = (ptr)

# define ssGetLogYSignalPtrs(S) \
         (S)->mdlInfo->logYSignalPtrs                  /* (LogSignalPtrsType) */
# define ssSetLogYSignalPtrs(S,ptr) \
         (S)->mdlInfo->logYSignalPtrs = (ptr)

# define ssGetLogInfo(S) \
         (S)->mdlInfo->logInfo                       /* (void *)              */
# define ssSetLogInfo(S,ptr) \
         (S)->mdlInfo->logInfo = (ptr)

#endif /* !defined(S_FUNCTION_NAME) */

/* BlockIO vector - used by the Real-Time Workshop and Simulink. This
 *  is starting address of the block input/output vector. All nonvirtual
 *  output ports have a slot into which they write their output.
 *
 *  User written S-functions should not access this field.
 */
#define _ssGetBlockIO(S) \
         ((real_T *)((S)->mdlInfo->blockIO))             /*  (real_T *)       */
#if !defined(S_FUNCTION_NAME)
#define ssGetBlockIO(S) _ssGetBlockIO(S)
#else
#define ssGetBlockIO(S) ssGetBlockIO_cannot_be_used_in_SFunctions
#endif
#define _ssSetBlockIO(S,io) \
          (S)->mdlInfo->blockIO = ((void *)(io))
#if !defined(S_FUNCTION_NAME)
#define ssSetBlockIO(S,io) _ssSetBlockIO(S,io)
#else
#define ssSetBlockIO(S,io) ssSetBlockIO_cannot_be_used_in_SFunctions
#endif


/* ConstBlockIO vector - used by the Real-Time Workshop.
 *
 *  User written S-functions should not access this field.
 */
#define _ssGetConstBlockIO(S) \
         ((const void *)((S)->mdlInfo->constBlockIO)) /* (const void *) */
#if !defined(S_FUNCTION_NAME)
#define ssGetConstBlockIO(S) _ssGetConstBlockIO(S)
#else
#define ssGetConstBlockIO(S) ssGetConstBlockIO_cannot_be_used_in_SFunctions
#endif
#define _ssSetConstBlockIO(S,io) \
          (S)->mdlInfo->constBlockIO = ((const void *)(io))
#if !defined(S_FUNCTION_NAME)
#define ssSetConstBlockIO(S,io) _ssSetConstBlockIO(S,io)
#else
#define ssSetConstBlockIO(S,io) ssSetConstBlockIO_cannot_be_used_in_SFunctions
#endif


/* BlockParam vector - Used by the Real-Time Workshop. This points to the
 *  currently active parameter vector.
 */
#define _ssGetBlockParam(S) \
          (S)->mdlInfo->blockParam                        /*   (real_T *)    */
#if !defined(S_FUNCTION_NAME)
#define ssGetBlockParam(S) _ssGetBlockParam(S)
#else
#define ssGetBlockParam(S) ssGetBlockParam_cannot_be_used_in_SFunctions
#endif
#define _ssSetBlockParam(S,paramVector) \
          (S)->mdlInfo->blockParam = (paramVector)
#if !defined(S_FUNCTION_NAME)
#define ssSetBlockParam(S,paramVector) _ssSetBlockParam(S,paramVector)
#else
#define ssSetBlockParam(S,paramVector) \
          ssSetBlockParam_cannot_be_used_in_SFunctions
#endif

#define _ssGetBlockParamValue(S,paramIdx) \
          (S)->mdlInfo->blockParam[paramIdx]              /*   (real_T)      */
#if !defined(S_FUNCTION_NAME)
#define ssGetBlockParamValue(S,paramIdx) _ssGetBlockParamValue(S,paramIdx)
#else
#define ssGetBlockParamValue(S,paramIdx) \
          ssGetBlockParamValue_cannot_be_used_in_SFunctions
#endif
#define _ssSetBlockParamValue(S,paramIdx,paramValue) \
          (S)->mdlInfo->blockParam[paramIdx] = (paramValue)
#if !defined(S_FUNCTION_NAME)
#define ssSetBlockParamValue(S,paramIdx,paramValue) \
          _ssSetBlockParamValue(S,paramIdx,paramValue)
#else
#define ssSetBlockParamValue(S,paramIdx,paramValue) \
          ssSetBlockParamValue_cannot_be_used_in_SFunctions
#endif

#define _ssGetDefaultParam(S) \
          (S)->mdlInfo->defaultParam                      /*   (real_T *)    */
#if !defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION)
#define ssGetDefaultParam(S) _ssGetDefaultParam(S)
#else
#define ssGetDefaultParam(S) ssGetDefaultParam_cannot_be_used_in_SFunctions
#endif

/*
 * ssSetDefaultParam - Used by the Real-Time Workshop. This contains
 * a pointer to all the model's parameters.
 */

#define _ssSetDefaultParam(S,paramVector) \
          (S)->mdlInfo->defaultParam = (paramVector)
#if !defined(S_FUNCTION_NAME)
#define ssSetDefaultParam(S,paramVector) _ssSetDefaultParam(S,paramVector)
#else
#define ssSetDefaultParam(S,paramVector) \
          ssSetDefaultParam_cannot_be_used_in_SFunctions
#endif

#define _ssGetDefaultParamValue(S,paramIdx) \
          (S)->mdlInfo->defaultParam[paramIdx]            /*   (real_T)      */
#if !defined(S_FUNCTION_NAME)
#define ssGetDefaultParamValue(S,paramIdx) _ssGetDefaultParamValue(S,paramIdx)
#else
#define ssGetDefaultParamValue(S,paramIdx) \
          ssGetDefaultParamValue_cannot_be_used_in_SFunctions
#endif
#define _ssSetDefaultParamValue(S,paramIdx,paramValue) \
          (S)->mdlInfo->defaultParam[paramIdx] = (paramValue)
#if !defined(S_FUNCTION_NAME)
#define ssSetDefaultParamValue(S,paramIdx,paramValue) \
          _ssSetDefaultParamValue(S,paramIdx,paramValue)
#else
#define ssSetDefaultParamValue(S,paramIdx,paramValue) \
          ssSetDefaultParamValue_cannot_be_used_in_SFunctions
#endif

/*
 * ssSetModelMappingInfo - Used by the Real-Time Workshop. This contains
 * a pointer to all the model's mapping information which is used by
 * external applications to "probe" the models, parameter, block I/O, etc
 * vectors.
 */

#define _ssSetModelMappingInfo(S,mapInfo) \
          (S)->mdlInfo->mappingInfo = (void *) (mapInfo)
#if !defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION)
#define ssSetModelMappingInfo(S,mapInfo) _ssSetModelMappingInfo(S,mapInfo)
#else
#define ssSetModelMappingInfo(S,paramVector) \
          ssSetModelMappingInfo_cannot_be_used_in_SFunctions
#endif

#define _ssGetModelMappingInfo(S) \
          (S)->mdlInfo->mappingInfo                      /*   (void*)    */
#if !defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION)
#define ssGetModelMappingInfo(S) _ssGetModelMappingInfo(S)
#else
#define ssGetModelMappingInfo(S) \
          ssGetModelMappingInfo_cannot_be_used_in_SFunctions
#endif


#if !defined(S_FUNCTION_NAME) && defined(MATLAB_MEX_FILE)
# define ssSetWriteRTWStrFcn(S,fcn) \
          (S)->mdlInfo->writeRTWStrFcn = (fcn)
# define ssSetWriteRTWNameValuePairFcn(S,fcn) \
          (S)->mdlInfo->writeRTWNameValuePairFcn = (fcn)
# define ssSetWriteRTWParameterFcn(S,fcn) \
          (S)->mdlInfo->writeRTWParameterFcn = (fcn)
# define ssSetWriteRTWFcnArg(S,fcnarg) \
          (S)->mdlInfo->writeRTWFcnArg = (fcnarg)
#endif

#if defined(MATLAB_MEX_FILE) && defined(S_FUNCTION_NAME)

# define SSWRITE_VALUE_STR              0
# define SSWRITE_VALUE_QSTR             1
# define SSWRITE_VALUE_VECT_STR         2
# define SSWRITE_VALUE_NUM              3
# define SSWRITE_VALUE_VECT             4
# define SSWRITE_VALUE_2DMAT            5
# define SSWRITE_VALUE_DTYPE_NUM        6
# define SSWRITE_VALUE_DTYPE_VECT       7
# define SSWRITE_VALUE_DTYPE_2DMAT      8
# define SSWRITE_VALUE_DTYPE_ML_VECT    9
# define SSWRITE_VALUE_DTYPE_ML_2DMAT   10

  extern DTypeId ssGetDTypeIdFromMxArray(const mxArray *m);

  extern int_T ssWriteRTWStr(               SimStruct *S,
                                            const char_T *str);

  extern int_T ssWriteRTWNameValuePair(     SimStruct    *S,
                                            int_T        type,
                                            const char_T *name,
                                            const void   *value, ...);

  extern int_T ssWriteRTWParamSettings(     SimStruct *S,
                                            int_T nParams, ...);

  extern int_T ssWriteRTWParameters(        SimStruct *S,
                                            int_T nParams, ...);

  extern int_T ssWriteRTWWorkVect(          SimStruct *S,
                                            const char_T *vectName,
                                            int_T nNames, ...);

# define ssWriteRTWStrParam(S,n,v) \
         ssWriteRTWNameValuePair(S,SSWRITE_VALUE_QSTR,n,v)
# define ssWriteRTWStrVectParam(S,n,v,len) \
         ssWriteRTWNameValuePair(S,SSWRITE_VALUE_VECT_STR,n,v,len)
# define ssWriteRTWVectParam(S,n,v,dt,len) \
         ssWriteRTWNameValuePair(S,SSWRITE_VALUE_DTYPE_VECT,n,v,dt,len)
# define ssWriteRTW2dMatParam(S,n,v,dt,nr,nc) \
         ssWriteRTWNameValuePair(S,SSWRITE_VALUE_DTYPE_2DMAT,n,v,dt,nr,nc)

extern int_T ssWriteRTWMxVectParam(SimStruct    *S,
                                   const char_T *name,
                                   const void   *rVal,
                                   const void   *iVal,
                                   int_T        dtInfo,
                                   int_T        numEl);

extern int_T ssWriteRTWMx2dMatParam(SimStruct    *S,
                                    const char_T *name,
                                    const void   *rVal,
                                    const void   *iVal,
                                    int_T        dtInfo,
                                    int_T        nRows,
                                    int_T        nCols);
#endif

/*
 * Reserved2/MexApiReal1/MexApiReal2 used by the mex api (simulink.c)
 */
#define ssGetReserved2(S) \
          (S)->mdlInfo->reserved2                         /*   (int_T)       */
#define ssSetReserved2(S,val) \
          (S)->mdlInfo->reserved2 = (val)

#define ssGetMexApiReal1(S) \
          (S)->mdlInfo->mexApiReal1                       /*   (real_T)      */
#define ssSetMexApiReal1(S,val) \
          (S)->mdlInfo->mexApiReal1 = (val)               /*   (real_T)      */

#define ssGetMexApiReal2(S) \
          (S)->mdlInfo->mexApiReal2                       /*   (real_T)      */
#define ssSetMexApiReal2(S,val) \
          (S)->mdlInfo->mexApiReal2 = (val)               /*   (real_T)      */


/*---------------------------- S->callSys  ----------------------------------*/

/*
 * ssSetCallSystemOutput -
 *   S-functions should use this in mdlInitializeSampleTimes to specify
 *   which output port elements of the first output port are connected
 *   to function-call subsystems. The S-function can then execute
 *   the function-call subsystems via ssCallSystemWithTID
 */
#define ssGetCallSystemOutputPtr(S) \
          (S)->callSys.outputs                            /* (int_T*)    */
#define _ssSetCallSystemOutputPtr(S,ptr) \
          (S)->callSys.outputs = (ptr)
#if !defined(S_FUNCTION_NAME)
#define ssSetCallSystemOutputPtr(S,ptr) _ssSetCallSystemOutputPtr(S,ptr)
#else
#define ssSetCallSystemOutputPtr(S,ptr) \
          ssSetCallSystemOutputPtr_cannot_be_used_in_SFunctions
#endif

#define ssGetCallSystemOutput(S,element) \
          (S)->callSys.outputs[element]                   /* (int_T)     */
#define ssSetCallSystemOutput(S,element) \
          (S)->callSys.outputs[element]=((int_T)1);


/*
 * ssCallSystemWithTID -
 *  This is used by S-function blocks to execute a function-call subsystem
 *  which are attached to the first output port of your S-function block.
 *  For blocks with multiple output ports, all "function-call's" must
 *  be performed on the first output port.
 */
# if SS_DO_FCN_CALL_ON_MAC
  static int_T ssCallSystemWithTid(SimStruct *S, int_T element, int_T tid)
  {
      int_T result = 0;
      if ((S)->callSys.fcns[element] != NULL) {
#         ifdef __MWERKS__
#         pragma mpwc on
#         endif
          result= (*(S)->callSys.fcns[element])((S)->callSys.args1[element],
                                                (S)->callSys.args2[element],
                                                tid);
#         ifdef __MWERKS__
#         pragma mpwc off
#         endif
      }
      return(result);
  }
# else
#   define ssCallSystemWithTid(S,element,tid) \
           (((S)->callSys.fcns[element] != NULL) ? \
             (*(S)->callSys.fcns[element])((S)->callSys.args1[element], \
                                         (S)->callSys.args2[element], tid): \
             (0))
# endif


/*
 * ssCallSystem -
 *  Provided for backwards compatibility. Here, tid is hardcoded is 0.
 */
#define ssCallSystem(S,element) ssCallSystemWithTid(S,element,0)

#define _ssSetCallSystemOutputArg1List(S,list) \
          (S)->callSys.args1 = (list)

#define _ssSetCallSystemOutputArg2List(S,list) \
          (S)->callSys.args2 = (list)

#define _ssSetCallSystemOutputFcnList(S,list) \
          (S)->callSys.fcns = (list)

#if !defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION)
 /*
  * The following cannot be used in S-functions
  */
# define ssGetCallSystemOutputArg1List(S) \
          (S)->callSys.args1                              /* (void**)        */
# define ssSetCallSystemOutputArg1List(S,list) \
         _ssSetCallSystemOutputArg1List(S,list)

# define ssGetCallSystemOutputArg2List(S) \
          (S)->callSys.args2                              /* (int_T*)        */
# define ssSetCallSystemOutputArg2List(S,list) \
          _ssSetCallSystemOutputArg2List(S,list)

# define ssGetCallSystemOutputFcnList(S) \
          (S)->callSys.fcns                               /* (SysOutputFcn*) */
# define ssSetCallSystemOutputFcnList(S,list) \
          _ssSetCallSystemOutputFcnList(S,list)
#else
#define ssSetCallSystemOutputArg1List(S,list) \
          ssSetCallSystemOutputArg1List_cannot_be_used_in_SFunctions
#define ssSetCallSystemOutputArg2List(S,list) \
          ssSetCallSystemOutputArg2List_cannot_be_used_in_SFunctions
#define ssSetCallSystemOutputFcnList(S,list) \
          ssSetCallSystemOutputFcnList_cannot_be_used_in_SFunctions
#endif



/*---------------------------- S->regDataType  ------------------------------*/

#if S_FUNCTION_LEVEL == 2

#if !defined(S_FUNCTION_NAME)
/*
 * The following cannot be used in S-functions
 */
# define ssGetDataTypeFcnsArg1(S) \
          (S)->regDataType.arg1                           /* (void*)        */
# define ssSetDataTypeFcnsArg1(S,ptr1) \
          (S)->regDataType.arg1 = ((void *)(ptr1))

# define ssGetRegisterDataTypeFcn(S) \
          (S)->regDataType.registerFcn                 /* (RegisterDataType) */
# define ssSetRegisterDataTypeFcn(S,val) \
          (S)->regDataType.registerFcn = (val)

# define ssGetDataTypeSizeFcn(S) \
          (S)->regDataType.getSizeFcn                  /* (GetDataTypeSize) */
# define ssSetGetDataTypeSizeFcn(S,val) \
          (S)->regDataType.getSizeFcn = (val)

# define ssGetSetDataTypeSizeFcn(S) \
          (S)->regDataType.setSizeFcn                  /* (SetDataTypeSize) */
# define ssSetDataTypeSizeFcn(S,val) \
          (S)->regDataType.setSizeFcn = (val)

# define ssGetDataTypeZeroFcn(S) \
          (S)->regDataType.getZeroFcn                  /* (GetDataTypeZero) */
# define ssSetGetDataTypeZeroFcn(S,val) \
          (S)->regDataType.getZeroFcn = (val)

# define ssGetSetDataTypeZeroFcn(S) \
          (S)->regDataType.setZeroFcn                  /* (SetDataTypeZero) */
# define ssSetDataTypeZeroFcn(S,val) \
          (S)->regDataType.setZeroFcn = (val)

# define ssGetDataTypeNameFcn(S) \
          (S)->regDataType.getNameFcn                  /* (GetDataTypeName) */
# define ssSetGetDataTypeNameFcn(S,val) \
          (S)->regDataType.getNameFcn = (val)

# define ssGetDataTypeIdFcn(S) \
          (S)->regDataType.getIdFcn                    /* (GetDataTypeId) */
# define ssSetGetDataTypeIdFcn(S,val) \
          (S)->regDataType.getIdFcn = (val)

# define ssGetSetNumDWorkFcn(S) \
          (S)->regDataType.setNumDWorkFcn              /* (SetNumDWork)     */
# define ssSetNumDWorkFcn(S,val) \
          (S)->regDataType.setNumDWorkFcn = (val)
#endif

#if SS_DO_FCN_CALL_ON_MAC
    static DTypeId ssRegisterDataType(SimStruct *S, char_T *name)
    {
        DTypeId id = INVALID_DTYPE_ID;
        if ((S)->regDataType.registerFcn != NULL) {
#          ifdef __MWERKS__
#            pragma mpwc on
#          endif
           id = (*(S)->regDataType.registerFcn)((S)->regDataType.arg1,name);
#          ifdef __MWERKS__
#            pragma mpwc off
#          endif
        }
        return(id);
    }
#else
#   define ssRegisterDataType(S,name) \
           (((S)->regDataType.registerFcn != NULL) ? \
           (*(S)->regDataType.registerFcn)((S)->regDataType.arg1,(name)): \
            (INVALID_DTYPE_ID))
#endif



#if SS_DO_FCN_CALL_ON_MAC
    static int_T ssSetDataTypeSize(SimStruct *S, DTypeId id, int_T size)
    {
        int_T result = 0;
        if ((S)->regDataType.setSizeFcn != NULL) {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
          result = (*(S)->regDataType.setSizeFcn)((S)->regDataType.arg1, id,
                                                  size);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
        }
        return(result);
    }
#else
#   define ssSetDataTypeSize(S,id,size) \
           (((S)->regDataType.setSizeFcn != NULL) ? \
           (*(S)->regDataType.setSizeFcn)((S)->regDataType.arg1,(id),(size)): \
            (0))
#endif


#if SS_DO_FCN_CALL_ON_MAC
    static int_T ssGetDataTypeSize(SimStruct *S, DTypeId id)
    {
        int_T size = INVALID_DTYPE_SIZE;
        if ((S)->regDataType.getSizeFcn != NULL) {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
          size = (*(S)->regDataType.getSizeFcn)((S)->regDataType.arg1, id);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
        }
        return(size);
    }
#else
#   define ssGetDataTypeSize(S,id) \
           (((S)->regDataType.getSizeFcn != NULL) ? \
           (*(S)->regDataType.getSizeFcn)((S)->regDataType.arg1,(id)): \
            (INVALID_DTYPE_SIZE))
#endif



#if SS_DO_FCN_CALL_ON_MAC
    static int_T ssSetDataTypeZero(SimStruct *S, DTypeId id, void *zero)
    {
        int_T result = 0;
        if ((S)->regDataType.setZeroFcn != NULL) {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
          result = (*(S)->regDataType.setZeroFcn)((S)->regDataType.arg1, id,
                                               zero);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
        }
        return(result);
    }
#else
#   define ssSetDataTypeZero(S,id, zero) \
           (((S)->regDataType.setZeroFcn != NULL) ? \
           (*(S)->regDataType.setZeroFcn)((S)->regDataType.arg1,(id),(zero)): \
            (0))
#endif


#if SS_DO_FCN_CALL_ON_MAC
    static const void * ssGetDataTypeZero(SimStruct *S,DTypeId id)
    {
        const void *zero = NULL;
        if ((S)->regDataType.getZeroFcn != NULL) {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
          zero = (*(S)->regDataType.getZeroFcn)((S)->regDataType.arg1, id);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
        }
        return(zero);
    }
#else
#   define ssGetDataTypeZero(S,id) \
           (((S)->regDataType.getZeroFcn != NULL) ? \
           (*(S)->regDataType.getZeroFcn)((S)->regDataType.arg1,(id)): \
            (NULL))
#endif

#if SS_DO_FCN_CALL_ON_MAC
    static const char_T *ssGetDataTypeName(SimStruct *S,DTypeId id)
    {
        const char_T *name = NULL;
        if ((S)->regDataType.getNameFcn != NULL) {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
          name = (*(S)->regDataType.getNameFcn)((S)->regDataType.arg1, id);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
        }
        return(name);
    }
#else
#   define ssGetDataTypeName(S,id) \
           (((S)->regDataType.getNameFcn != NULL) ? \
           (*(S)->regDataType.getNameFcn)((S)->regDataType.arg1,(id)): \
            (NULL))
#endif

#if SS_DO_FCN_CALL_ON_MAC
    static DTypeId ssGetDataTypeId(SimStruct *S,char_T *name)
    {
        DTypeId id = INVALID_DTYPE_ID;
        if ((S)->regDataType.getIdFcn != NULL) {
#         ifdef __MWERKS__
#           pragma mpwc on
#         endif
          id = (*(S)->regDataType.getIdFcn)((S)->regDataType.arg1, name);
#         ifdef __MWERKS__
#           pragma mpwc off
#         endif
        }
        return(id);
    }
#else
#   define ssGetDataTypeId(S,name) \
           (((S)->regDataType.getIdFcn != NULL) ? \
           (*(S)->regDataType.getIdFcn)((S)->regDataType.arg1,(name)): \
            (INVALID_DTYPE_ID))
#endif

#if defined(S_FUNCTION_NAME)
#  if SS_DO_FCN_CALL_ON_MAC
     static int_T ssSetNumDWork(SimStruct  *S, int_T num)
     {
         int_T result = 0;
         if ((S)->regDataType.setNumDWorkFcn != NULL) {
#           ifdef __MWERKS__
#             pragma mpwc on
#           endif
            result = (*(S)->regDataType.setNumDWorkFcn)((void*)S,num);
#           ifdef __MWERKS__
#             pragma mpwc off
#           endif
     }
     return(result);
}
#  elif defined(MATLAB_MEX_FILE)
#    define ssSetNumDWork(S,num) \
       (((S)->regDataType.setNumDWorkFcn != NULL) ? \
        (*(S)->regDataType.setNumDWorkFcn)(((void*)S),(num)): (0))
#  else /* RTW non-TLC S-function */
#    define ssSetNumDWork(S,num) ((_ssSetNumDWork(S,num)) >= -1)
#  endif
#else /* Simulink or RTW run-time interface code */
#  define ssSetNumDWork(S,num) ((_ssSetNumDWork(S,num)) >= -1)
#endif


#endif /* level 2 S-function */

/*-------------------------------- S->stInfo --------------------------------*/
#define ssGetSampleTimePtr(S) \
          (S)->stInfo.sampleTimes                         /*   (time_T *)    */
#define ssSetSampleTimePtr(S,ptr) \
          (S)->stInfo.sampleTimes = (ptr)

#define ssGetSampleTime(S,sti) \
          (S)->stInfo.sampleTimes[sti]                    /*   (time_T)      */
#define ssSetSampleTime(S,sti,t) \
          (S)->stInfo.sampleTimes[sti] = (t)

#define ssGetOffsetTimePtr(S) \
          (S)->stInfo.offsetTimes                         /*   (time_T *)    */
#define ssSetOffsetTimePtr(S,ptr) \
          (S)->stInfo.offsetTimes = (ptr)

#define ssGetOffsetTime(S,sti) \
          (S)->stInfo.offsetTimes[sti]                    /*   (time_T)      */
#define ssSetOffsetTime(S,sti,t) \
          (S)->stInfo.offsetTimes[sti] = (t)

#define ssGetTNext(S) \
          (S)->stInfo.tNext                               /*   (time_T)      */
#define ssSetTNext(S,tnext) \
          (S)->stInfo.tNext = (tnext)

#define _ssSetSampleTimeTaskIDPtr(S,tids) \
          (S)->stInfo.sampleTimeTaskIDs = (tids)

#if !defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION)
/*
 * The following are not for use in S-functions
 */
# define ssGetTNextTid(S) \
          (S)->stInfo.tNextTid                            /*   (int_T)   */
# define ssSetTNextTid(S,setting) \
          (S)->stInfo.tNextTid = (setting)

# define ssGetSampleTimeTaskIDPtr(S) \
          (S)->stInfo.sampleTimeTaskIDs                   /*   (int_T *)     */
# define ssSetSampleTimeTaskIDPtr(S,tids) \
          _ssSetSampleTimeTaskIDPtr(S,tids)
#else
# define ssSetSampleTimeTaskIDPtr(S,tids)\
          ssSetSampleTimeTaskIDPtr_cannot_be_used_in_SFunctions
#endif

#if TID_EQUALS_SAMPLE_TIME_INDEX
#  define ssGetSampleTimeTaskID(S,sti) (sti)              /*   (int_T)       */
#else
#  define ssGetSampleTimeTaskID(S,sti) \
            (S)->stInfo.sampleTimeTaskIDs[sti]            /*   (int_T)       */
#endif

#define _ssSetSampleTimeTaskID(S,sti,tid) \
          (S)->stInfo.sampleTimeTaskIDs[sti] = (tid)
#if !defined(S_FUNCTION_NAME)
#define ssSetSampleTimeTaskID(S,sti,tid) _ssSetSampleTimeTaskID(S,sti,tid)
#else
#define ssSetSampleTimeTaskID(S,sti,tid) \
          ssSetSampleTimeTaskID_cannot_be_used_in_SFunctions
#endif


/*--------------------------- S->modelMethods.sFcn --------------------------*/
/*
 * Macros are used to call an S-function block methods. These should not
 * be used by an S-function directly.
 */
#define ssSetmdlInitializeSizes(S,initSizes) \
         (S)->modelMethods.sFcn.mdlInitializeSizes = (initSizes)
#define sfcnInitializeSizes(S) \
         (*(S)->modelMethods.sFcn.mdlInitializeSizes)(S)
#if defined(MATLAB_MEX_FILE)
# define ssGetmdlGetInputPortWidthLevel1(S) \
         (S)->modelMethods.sFcn.mdlGetInputPortWidthLevel1
# define ssSetmdlGetInputPortWidthLevel1(S,getInputPortWidth) \
         (S)->modelMethods.sFcn.mdlGetInputPortWidthLevel1 =(getInputPortWidth)
# define sfcnGetInputPortWidthLevel1(S, outputPortWidth) \
         (*(S)->modelMethods.sFcn.mdlGetInputPortWidthLevel1)(S, \
            outputPortWidth)

# define ssGetmdlGetOutputPortWidthLevel1(S) \
         (S)->modelMethods.sFcn.mdlGetOutputPortWidthLevel1
# define ssSetmdlGetOutputPortWidthLevel1(S,getOutputPortWidth) \
         (S)->modelMethods.sFcn.mdlGetOutputPortWidthLevel1 = \
            (getOutputPortWidth)
# define sfcnGetOutputPortWidthLevel1(S, inputPortWidth) \
         (*(S)->modelMethods.sFcn.mdlGetOutputPortWidthLevel1)(S, \
            inputPortWidth)

# define ssGetmdlSetInputPortWidth(S) \
         (S)->modelMethods.sFcn.mdlSetInputPortWidth
# define ssSetmdlSetInputPortWidth(S,setInputPortWidth) \
         (S)->modelMethods.sFcn.mdlSetInputPortWidth = (setInputPortWidth)
# define sfcnSetInputPortWidth(S, portIdx, width) \
         (*(S)->modelMethods.sFcn.mdlSetInputPortWidth)(S, portIdx, width)

# define ssGetmdlSetOutputPortWidth(S) \
         (S)->modelMethods.sFcn.mdlSetOutputPortWidth
# define ssSetmdlSetOutputPortWidth(S,setOutputPortWidth) \
         (S)->modelMethods.sFcn.mdlSetOutputPortWidth = (setOutputPortWidth)
# define sfcnSetOutputPortWidth(S, portIdx, width) \
         (*(S)->modelMethods.sFcn.mdlSetOutputPortWidth)(S, portIdx, width)

# define ssGetmdlSetInputPortDataType(S) \
         (S)->modelMethods.sFcn.mdlSetInputPortDataType
# define ssSetmdlSetInputPortDataType(S,setInputPortDataType) \
         (S)->modelMethods.sFcn.mdlSetInputPortDataType = \
            (setInputPortDataType)
# define sfcnSetInputPortDataType(S, portIdx, inputPortDataType) \
         (*(S)->modelMethods.sFcn.mdlSetInputPortDataType)(S,portIdx, \
           inputPortDataType)

# define ssGetmdlSetOutputPortDataType(S) \
         (S)->modelMethods.sFcn.mdlSetOutputPortDataType
# define ssSetmdlSetOutputPortDataType(S,setOutputPortDataType) \
         (S)->modelMethods.sFcn.mdlSetOutputPortDataType = \
           (setOutputPortDataType)
# define sfcnSetOutputPortDataType(S, portIdx, outputPortDataType) \
         (*(S)->modelMethods.sFcn.mdlSetOutputPortDataType)(S, \
           portIdx, outputPortDataType)

# define ssGetmdlSetInputPortComplexSignal(S) \
         (S)->modelMethods.sFcn.fcnInEnable.mdlSetInputPortComplexSignal
# define ssSetmdlSetInputPortComplexSignal(S,setInputPortComplexSignal) \
         (S)->modelMethods.sFcn.fcnInEnable.mdlSetInputPortComplexSignal = \
            (setInputPortComplexSignal)
# define sfcnSetInputPortComplexSignal(S, portIdx, val) \
         (*(S)->modelMethods.sFcn.fcnInEnable.mdlSetInputPortComplexSignal)\
         (S, portIdx, val)

# define ssGetmdlSetOutputPortComplexSignal(S) \
         (S)->modelMethods.sFcn.fcnOutDisable.mdlSetOutputPortComplexSignal
# define ssSetmdlSetOutputPortComplexSignal(S,setOutputPortComplexSignal) \
         (S)->modelMethods.sFcn.fcnOutDisable.mdlSetOutputPortComplexSignal = \
            (setOutputPortComplexSignal)
# define sfcnSetOutputPortComplexSignal(S, portIdx, val) \
         (*(S)->modelMethods.sFcn.fcnOutDisable.mdlSetOutputPortComplexSignal)\
            (S, portIdx, val)
#endif

# define _ssGetRTWGeneratedEnable(S) \
         (S)->modelMethods.sFcn.fcnInEnable.mdlEnable
# define _ssSetRTWGeneratedEnable(S,setEnable) \
         (S)->modelMethods.sFcn.fcnInEnable.mdlEnable = (setEnable)
# define _sfcnRTWGeneratedEnable(S) \
         (*(S)->modelMethods.sFcn.fcnInEnable.mdlEnable)(S)

# define _ssGetRTWGeneratedDisable(S) \
         (S)->modelMethods.sFcn.fcnOutDisable.mdlDisable
# define _ssSetRTWGeneratedDisable(S,setDisable) \
         (S)->modelMethods.sFcn.fcnOutDisable.mdlDisable = (setDisable)
# define _sfcnRTWGeneratedDisable(S) \
         (*(S)->modelMethods.sFcn.fcnOutDisable.mdlDisable)(S)

#if !defined(S_FUNCTION_NAME) || defined(RTW_GENERATED_S_FUNCTION)
# define ssGetRTWGeneratedEnable(S) \
         _ssGetRTWGeneratedEnable(S)
# define ssSetRTWGeneratedEnable(S,setEnable) \
         _ssSetRTWGeneratedEnable(S,setEnable)
# define sfcnRTWGeneratedEnable(S) \
         _sfcnRTWGeneratedEnable(S)

# define ssGetRTWGeneratedDisable(S) \
         _ssGetRTWGeneratedDisable(S)
# define ssSetRTWGeneratedDisable(S,setDisable) \
         _ssSetRTWGeneratedDisable(S,setDisable)
# define sfcnRTWGeneratedDisable(S) \
         _sfcnRTWGeneratedDisable(S)

#else
  /* User S-Functions */
# define ssGetRTWGeneratedEnable(S) \
         ssGetRTWGeneratedEnable_cannot_be_used_in_SFunctions
# define ssSetRTWGeneratedEnable(S,setEnable) \
         ssGetRTWGeneratedEnable_cannot_be_used_in_SFunctions
# define sfcnRTWGeneratedEnable(S) \
         sfcnRTWGeneratedEnable_cannot_be_used_in_SFunctions

# define ssGetRTWGeneratedDisable(S) \
         ssGetRTWGeneratedDisable_cannot_be_used_in_SFunctions
# define ssSetRTWGeneratedDisable(S,setDisable) \
         ssSetRTWGeneratedDisable_cannot_be_used_in_SFunctions
# define sfcnRTWGeneratedDisable(S) \
         sfcnRTWGeneratedDisable_cannot_be_used_in_SFunctions
#endif

#define ssSetmdlInitializeSampleTimes(S,initSampleTimes) \
         (S)->modelMethods.sFcn.mdlInitializeSampleTimes = \
           (initSampleTimes)
#define sfcnInitializeSampleTimes(S) \
         (*(S)->modelMethods.sFcn.mdlInitializeSampleTimes)(S)

#if defined(MATLAB_MEX_FILE)

# define ssGetmdlSetInputPortSampleTime(S) \
         (S)->modelMethods.sFcn.mdlSetInputPortSampleTime
# define ssSetmdlSetInputPortSampleTime(S,fcn) \
         (S)->modelMethods.sFcn.mdlSetInputPortSampleTime = (fcn)
# define sfcnSetInputPortSampleTime(S, portIdx, sampleTime, offsetTime) \
         (*(S)->modelMethods.sFcn.mdlSetInputPortSampleTime)\
            (S, portIdx, sampleTime, offsetTime)

# define ssGetmdlSetOutputPortSampleTime(S) \
         (S)->modelMethods.sFcn.mdlSetOutputPortSampleTime
# define ssSetmdlSetOutputPortSampleTime(S,fcn) \
         (S)->modelMethods.sFcn.mdlSetOutputPortSampleTime = (fcn)
# define sfcnSetOutputPortSampleTime(S, portIdx, sampleTime, offsetTime) \
         (*(S)->modelMethods.sFcn.mdlSetOutputPortSampleTime)\
            (S, portIdx, sampleTime, offsetTime)

# define ssGetmdlSetWorkWidths(S) \
         (S)->modelMethods.sFcn.mdlSetWorkWidths
# define ssSetmdlSetWorkWidths(S,setWorkWidths) \
         (S)->modelMethods.sFcn.mdlSetWorkWidths = (setWorkWidths)
# define sfcnSetWorkWidths(S) \
         (*(S)->modelMethods.sFcn.mdlSetWorkWidths)(S)

# define ssGetmdlRTW(S) \
         (S)->modelMethods.sFcn.mdlRTW
# define ssSetmdlRTW(S,rtw) \
         (S)->modelMethods.sFcn.mdlRTW = (rtw)
# define sfcnRTW(S) \
         (*(S)->modelMethods.sFcn.mdlRTW)(S)
#endif

#define ssSetmdlInitializeConditions(S,initConds) \
         (S)->modelMethods.sFcn.mdlInitializeConditions.level2 = \
           (initConds)
#define ssGetmdlInitializeConditions(S) \
         (S)->modelMethods.sFcn.mdlInitializeConditions.level2

#define sfcnInitializeConditions(S) \
         (*(S)->modelMethods.sFcn.mdlInitializeConditions.level2)(S)

#define ssSetmdlInitializeConditionsLevel1(S,initConds) \
         (S)->modelMethods.sFcn.mdlInitializeConditions.level1 = \
           (initConds)
#define sfcnInitializeConditionsLevel1(x0, S) \
         (*(S)->modelMethods.sFcn.mdlInitializeConditions.level1)(x0,S)

#define ssGetmdlStart(S) \
         (S)->modelMethods.sFcn.mdlStart
#define ssSetmdlStart(S,start) \
         (S)->modelMethods.sFcn.mdlStart = (start)
#define sfcnStart(S) \
         (*(S)->modelMethods.sFcn.mdlStart)(S)

#if defined(MATLAB_MEX_FILE)
# define ssGetmdlCheckParameters(S) \
         (S)->modelMethods.sFcn.mdlCheckParameters
# define ssSetmdlCheckParameters(S,checkParameters) \
         (S)->modelMethods.sFcn.mdlCheckParameters = (checkParameters)
# define sfcnCheckParameters(S) \
         (*(S)->modelMethods.sFcn.mdlCheckParameters)(S)

# define ssGetmdlProcessParameters(S) \
         (S)->modelMethods.sFcn.mdlProcessParameters
# define ssSetmdlProcessParameters(S,fcnptr) \
         (S)->modelMethods.sFcn.mdlProcessParameters = (fcnptr)
# define sfcnProcessParameters(S) \
          (*(S)->modelMethods.sFcn.mdlProcessParameters)(S)
#endif

#if defined(MATLAB_MEX_FILE) || defined(NRT)
# define ssSetmdlGetTimeOfNextVarHit(S,getTimeOfNextVarHit) \
         (S)->modelMethods.sFcn.mdlGetTimeOfNextVarHit = (getTimeOfNextVarHit)
# define sfcnGetTimeOfNextVarHit(S) \
         (*(S)->modelMethods.sFcn.mdlGetTimeOfNextVarHit)(S)
#endif

#define ssSetmdlOutputs(S,outputs) \
         (S)->modelMethods.sFcn.mdlOutputs.level2 = (outputs)
#define sfcnOutputs(S, tid) \
         (*(S)->modelMethods.sFcn.mdlOutputs.level2)(S,tid)

#define ssSetmdlOutputsLevel1(S,outputs) \
         (S)->modelMethods.sFcn.mdlOutputs.level1 = (outputs)
#define sfcnOutputsLevel1(y, x, u, S, tid) \
         (*(S)->modelMethods.sFcn.mdlOutputs.level1)(y,x,u,S,tid)

#define ssSetmdlUpdate(S,update) \
         (S)->modelMethods.sFcn.mdlUpdate.level2 = (update)
#define ssGetmdlUpdate(S) \
         (S)->modelMethods.sFcn.mdlUpdate.level2
#define sfcnUpdate(S, tid) \
         (*(S)->modelMethods.sFcn.mdlUpdate.level2)(S,tid)

#define ssSetmdlUpdateLevel1(S,update) \
         (S)->modelMethods.sFcn.mdlUpdate.level1 = (update)
#define sfcnUpdateLevel1(x, u, S, tid) \
         (*(S)->modelMethods.sFcn.mdlUpdate.level1)(x,u,S,tid)

#define ssSetmdlDerivatives(S,derivs) \
         (S)->modelMethods.sFcn.mdlDerivatives.level2 = (derivs)
#define ssGetmdlDerivatives(S) \
         (S)->modelMethods.sFcn.mdlDerivatives.level2
#define sfcnDerivatives(S) \
         (*(S)->modelMethods.sFcn.mdlDerivatives.level2)(S)

#define ssSetmdlDerivativesLevel1(S,derivs) \
         (S)->modelMethods.sFcn.mdlDerivatives.level1 = (derivs)
#define sfcnDerivativesLevel1(dx, x, u, S, tid) \
         (*(S)->modelMethods.sFcn.mdlDerivatives.level1)(dx,x,u,S,tid)

#if defined(MATLAB_MEX_FILE) || defined(NRT)
# define ssSetmdlZeroCrossings(S,zeroCrossings) \
         (S)->modelMethods.sFcn.mdlZeroCrossings = (zeroCrossings)
# define sfcnZeroCrossings(S) \
         (*(S)->modelMethods.sFcn.mdlZeroCrossings)(S)
#endif

#define ssSetmdlTerminate(S,terminate) \
         (S)->modelMethods.sFcn.mdlTerminate = (terminate)
#define sfcnTerminate(S) \
         (*(S)->modelMethods.sFcn.mdlTerminate)(S)


/*-------------------------------- S->sFunctions ----------------------------*/

#define _ssGetSFunctions(S) \
          (S)->sFunctions                               /* (SimStruct **)    */
#define _ssSetSFunctions(S,SFunPtr) \
          (S)->sFunctions = (SFunPtr)
#if !defined(S_FUNCTION_NAME)
#define ssSetSFunctions(S,SFunPtr) _ssSetSFunctions(S,SFunPtr)
#else
#define ssSetSFunctions(S,SFunPtr) ssSetSFunctions_cannot_be_used_in_SFunctions
#endif

#define ssGetSFunction(S,sfun) \
          ((S)->sFunctions[sfun])                       /* (SimStruct *)     */
#define _ssSetSFunction(S,sfunid,simStruc) \
          (S)->sFunctions[sfunid] = (simStruc)
#if !defined(S_FUNCTION_NAME)
#define ssSetSFunction(S,sfunid,simStruc) _ssSetSFunction(S,sfunid,simStruc)
#else
#define ssSetSFunction(S,sfunid,simStruc) \
          ssSetSFunction_cannot_be_used_in_SFunctions
#endif



/*==============================*
 * Miscellaneous access methods *
 *==============================*/

/*------------------------- ssIsContinuousTask ------------------------------*/

#if defined(MATLAB_MEX_FILE) 
 /* 
  * During simulation, tid passed to S-functions is always 0 even in
  * multitasking mode 
  */
# define ssIsContinuousTask(S,tid) (S)->mdlInfo->sampleHits[0]
#elif defined(MULTITASKING) && TID01EQ == 1
# define ssIsContinuousTask(S,tid) \
           ((tid) <= 1)
#else
# define ssIsContinuousTask(S,tid) \
           ((tid) == 0)
#endif

/*-------------------------- ssIsSampleHit ----------------------------------*/

#if defined(MULTITASKING)

# define ssIsSampleHit(S,sti,tid) \
           (ssGetSampleTimeTaskID(S,sti) == (tid))

#else

# define ssIsSampleHit(S,sti,unused) \
           (ssIsMajorTimeStep(S) && \
            (S)->mdlInfo->sampleHits[ssGetSampleTimeTaskID(S,sti)])

#endif


/*------------------------- ssSetSampleHitInTask ----------------------------*/

#if defined(MULTITASKING) || defined(MATLAB_MEX_FILE)
# define _ssSetSampleHitInTask(S, task_j, task_i, hit) \
            (S)->mdlInfo->perTaskSampleHits[(task_j) + \
              ((task_i) * (ssGetNumSampleTimes(S)))] = (hit)
# if !defined(S_FUNCTION_NAME)
# define ssSetSampleHitInTask(S, task_j, task_i, hit) \
           _ssSetSampleHitInTask(S, task_j, task_i, hit)
# else
# define ssSetSampleHitInTask(S, task_j, task_i, hit) \
           ssSetSampleHitInTask_cannot_be_used_in_SFunctions
# endif
#endif


/*----------------------- ssIsSpecialSampleHit ------------------------------*/

#if defined(MULTITASKING) || defined(MATLAB_MEX_FILE)
/*
 * The ssIsSpecialSampleHit(S, my_sti, promoted_sti, tid) macro will be
 * "true" if the block is executing in a major time step in context of a
 * promoted sample time (promoted_sti) and we have a sample hit in the
 * original task (my_sti) which translates to:
 *    1) tid == tid_for(promoted_sti). It is required that this macro be
 *       invoked with in a ssIsSampleHit(S,promoted_sti,tid) to guarantee this
 *       case.
 *    2) Must be major time step.
 *    3) my_sti (the block's sti) has a sample hit at the current point in
 *       time.
 * Valid usage in an S-function would be:
 *	if (ssIsSampleHit(S, promoted_sti)) {
 *        if (ssIsSpecialSampleHit(S, my_sti, promoted_sti, tid)) {
 *        }
 *      }
 * providing prompted_sti is not the continuous task. If promoted_sti is
 * the continuous task, then the following must be used:
 *	if (ssIsContinuousTask(S, promoted_sti)) {
 *        if (ssIsSpecialSampleHit(S, my_sti, promoted_sti, tid)) {
 *        }
 *      }
 */
#  define ssIsSampleHitInTask(S, my_sti, tid) \
            (S)->mdlInfo->perTaskSampleHits[ \
              ssGetSampleTimeTaskID(S,my_sti) + \
                ((tid) * (ssGetNumSampleTimes(ssGetRootSS(S))))]

#  define ssIsSpecialSampleHit(S, my_sti, promoted_sti, tid) \
            (ssIsMajorTimeStep(S) && ssIsSampleHitInTask(S, my_sti, tid))
#else
#  define ssIsSpecialSampleHit(S, my_sti, promoted_sti, tid) \
            ssIsSampleHit(S, my_sti, tid)
#endif


/*----------------------- ssIsFirstInitCond ---------------------------------*/
#define ssIsFirstInitCond(S) \
          (ssGetT(S) == ssGetTStart(S))



/*===========================================================================*
 * The following are for backward compatibility for user written S-functions *
 *===========================================================================*/

#if defined(S_FUNCTION_NAME) && S_FUNCTION_LEVEL==1

#define SS_OPTION_NOT_USING_mexErrMsgTxt     SS_OPTION_EXCEPTION_FREE_CODE

#define ssGetChecksum(S)                     ssGetChecksum0(S)
#define ssSetChecksum(S,val)                 ssSetChecksum0(S,val)

#define ssGetParamChecksum(S)                ssGetChecksum3(S)
#define ssSetParamChecksum(S,val)            ssGetChecksum3(S,val)


/* Macros from Simulink 1.3, Simulink 2.0 */

# define ssGetStatus(S)                      ssGetErrorStatus(S)
# define ssSetStatus(S,msg)                  ssSetErrorStatus(S,msg)

# define ssGetSizes(S)                       ssGetSizesPtr(S)

# define ssGetMinStepSize(S)  (0.0)
# define ssSetMinStepSize(S,stepSize) /* do nothing */

# define ssGetNumScopes(S) (0.0/*noop*/)
# define ssSetNumScopes(S,nScopes) /*do nothing*/

# define ssGetIntgStopTime(S)               ssGetSolverStopTime(S)
# define ssSetIntgStopTime(S,stoptime)      ssSetSolverStopTime(S,stoptime)

# define ssSetMinorTimeStep(S,b)      \
     ssSetSimTimeStep(S,((b)? MINOR_TIME_STEP, MAJOR_TIME_STEP));

# define ssGetPresentTimeEvent(S,sti)       ssGetTaskTime(S,sti)
# define ssSetPresentTimeEvent(rootS,sti,t) ssSetTaskTime(rootS,sti,t)

# define ssGetSampleHitEventPtr(S)          ssGetSampleHitPtr(S)
# define ssSetSampleHitEventPtr(S,ptr)      ssSetSampleHitPtr(S,ptr)

# define ssSetSampleHitEvent(S,sti,hit)     ssSetSampleHit(S,sti,hit)

# define ssGetSampleTimeEventPtr(S)         ssGetSampleTimePtr(S)
# define ssSetSampleTimeEventPtr(S,ptr)     ssSetSampleTimePtr(S,ptr)

# define ssGetSampleTimeEvent(S,sti)        ssGetSampleTime(S,sti)
# define ssSetSampleTimeEvent(S,sti,t)      ssSetSampleTime(S,sti,t)

# define ssGetOffsetTimeEventPtr(S)         ssGetOffsetTimePtr(S)
# define ssSetOffsetTimeEventPtr(S,ptr)     ssSetOffsetTimePtr(S,ptr)

# define ssGetOffsetTimeEvent(S,sti)        ssGetOffsetTime(S,sti)
# define ssSetOffsetTimeEvent(S,sti,t)      ssSetOffsetTime(S,sti,t)

# define ssIsSampleHitEvent(S,sti,tid)      ssIsSampleHit(S,sti,tid)

# define ssSetSampleHitEventInTask(rootS, task_j, task_i, hit) \
           ssSetSampleHitInTask(rootS, task_j, task_i, hit)

# define ssIsSpecialSampleHitEvent(S, my_sti, promoted_sti, tid) \
           ssIsSpecialSampleHit(S, my_sti, promoted_sti, tid)


# define ssGetNumInputArgs(S)              ssGetNumSFcnParams(S)
# define ssSetNumInputArgs(S,numInputArgs) ssSetNumSFcnParams(S,numInputArgs)

# define ssGetNumArgs(S)                   ssGetSFcnParamsCount(S)
# define ssSetNumArgs(S,numArgs)           ssSetSFcnParamsCount(S,numArgs)

# define ssGetArgPtr(S)                    ssGetSFcnParamsPtr(S)
# define ssSetArgPtr(S,args)               ssSetSFcnParamsPtr(S,args)

# define ssGetArg(S,argNum)                ssGetSFcnParam(S,argNum)
# define ssSetArg(S,argIdx,argMat)         ssSetSFcnParam(S,argIdx,argMat)

#endif

#endif  /* __SIMSTRUC__ */
/* EOF: simstruc.h */
