/***************************************************************************/
/* preprocessor macros for crystal                                         */
/***************************************************************************/

/* for better reading...                                                   */

#define not !

/* ST compilers                                                            */

#define ST (ANAM2 || LPRM2 || SPCM2 || HM2 || MM2   || TDIM2 || FTLM2 || \
            MAMM2 || JM2   || MSM2  || RM2 || GNUM2)

/* memory models                                                           */

#define linear (ANAM2 || LPRM2 || SPCM2 || HM2  || MM2   || TDIM2 || \
                FTLM2 || MAMM2 || JM2   || MSM2 || RM2   || GNUM2 || \
                XAM2  || XGM2  || XHM2  || XRM2 || MCSM2 || XGPM2 || \
                CBM2  || MWM2  || XTM2  || MOCM2)

#define intel (FSTM2 || TSM2_1 || TSM2_2 || SDSM2 || LM2 || TM2 || HSM2 || \
               SBM2  || GPM2)

/* operating Systems                                                       */

#define GEMDOS ST
#define PCDOS intel
#define UNIX (XAM2 || XGM2 || XHM2 || XRM2 || MCSM2 || XGPM2 || CBM2 || \
              MWM2 || XTM2 || MOCM2)
#define FLEXOS

#if not((GEMDOS) || (PCDOS) || (UNIX))
#error compiler not supported
#endif

/* define long if a compiler does not support 16 bit types                 */

#define long (ANAM2 || XAM2)

/* if you want to take care of ABC-GEM then set to 1 else 0                */

#define ABC 1

/*
#if ABC
#warning ...taking care of ABC-GEM
#endif
*/

/* if you want to emulate scrap functions by means of POSIX calls          */

#define use_POSIX 1

/*
#if use_POSIX
#warning ...using POSIX calls
#endif
*/

/* handle REF parameters (system-dependent)                                */

#ifndef MM2
#define REF
#endif

/* ISO SYSTEM.CAST()                                                       */

#if (defined ANAM2) || (defined XAM2)   || (defined TDIM2)  || \
    (defined FSTM2) || (defined LM2)    || (defined SDSM2)  || \
    (defined MSM2)  || (defined TSM2_1) || (defined TSM2_2) || \
    (defined FTLM2)
#define CAST(T,x) T(x)
#elif (defined LPRM2) || (defined SPCM2)
#define CAST(T,x) VAL(T,x)
#endif

/* ISO constant constructors                                               */

#define constructor (HM2 || MM2 || ISOM2)

/* ISO procedure constants                                                 */

#define proc_const (TSM2_1 || TSM2_2 || FTLM2 || ISOM2)

/* ISO PACKEDSET                                                           */

#ifndef ISOM2
#define PACKEDSET SET
#endif

/* set a MC68K register like SPCM2, TDIM2, LPRM2, ANAM2 ...                */

#if (defined HM2) || (defined MM2)
#define SETREG(Reg,F) LOAD(F,Reg)
#elif (defined MSM2)
#define SETREG(Reg,F) (*$A+*) MOVE.L \#F,Reg (*$A-*)
#endif

/* ISO INT(), assuming VAL IMPORT                                          */

#if (defined FTLM2) || (defined TSM2_1)|| (defined ANAM2) || \
    (defined FSTM2) || (defined LPRM2) || (defined SPCM2) || \
    (defined TDIM2)
#define INT(a) VAL(INTEGER,a)
#endif

/* compiler directives                                                     */

#if (defined MM2)
#define DEF_SWITCHES $C+,H+,I+,Z+
#define IMP_SWITCHES $A+,B-,C+,D-,E-,H+,I+,J+,K+,L+,M+,R-,S-,T+,U+,Y+,Z+
#define DRIVER $B+

#elif (defined HM2) || (defined XHM2)
#define DEF_SWITCHES $i-,$w-,$E+,$F-,$K-
#define IMP_SWITCHES $i-,$w-,$D-,$E+,$G+,$H-,$I-,$K-,$L-,$P-,$Q+,$S-,$T-,$V-,$W-,$X+,$Y-
#define DRIVER $M+

#elif (defined TDIM2)
#define DEF_SWITCHES
#define IMP_SWITCHES $C-,$N-,$Q+,$R-,$S-,$T-,$V-

#elif (defined FSTM2)
#define DEF_SWITCHES
#define IMP_SWITCHES $A+,$L-,$R-,$S-,$T-

#elif (defined TSM2_1)
#define DEF_SWITCHES
#define IMP_SWITCHES

#elif (defined TSM2_2)
#define DEF_SWITCHES
#define IMP_SWITCHES \#check(nil_ptr=>off,index=>off,stack=>off,overflow=>off,range=>off)

#elif (defined LM2)
#define DEF_SWITCHES
#define IMP_SWITCHES $S-,R-,F-,T-

#elif (defined FTLM2)
#define DEF_SWITCHES
#define IMP_SWITCHES $L-*)(*$P-*)(*$R-*)(*$T-*)(*$U-

#else
#define DEF_SWITCHES
#define IMP_SWITCHES
#endif

#if (defined HM2) || (defined XHM2)
#define begin_word (*$W+*)
#define end_word (*$W-*)
#else
#define begin_word
#define end_word
#endif

/* macros supporting Seimet's method                                       */

#if (defined LPRM2) || (defined SPCM2)
#define AES_SYSTEM_IMPORT FROM SYSTEM IMPORT SETREG,VAL; \
                          FROM Register IMPORT D1;
#define CAST_IMPORT FROM SYSTEM IMPORT VAL;
#elif (defined MM2) || (defined HM2)
#define AES_SYSTEM_IMPORT FROM SYSTEM IMPORT LOAD,CAST; \
                          FROM Register IMPORT D1;
#define CAST_IMPORT FROM SYSTEM IMPORT CAST;
#elif (defined ANAM2) || (defined TDIM2) || (defined FTLM2)
#define AES_SYSTEM_IMPORT FROM SYSTEM IMPORT SETREG; \
                          FROM Register IMPORT D1;
#define CAST_IMPORT
#elif (defined GPM2) || (defined XGPM2)
#define AES_SYSTEM_IMPORT FROM SYSTEM IMPORT CAST;
#define CAST_IMPORT FROM SYSTEM IMPORT CAST;
#else
#define AES_SYSTEM_IMPORT
#define CAST_IMPORT
#endif

/* use Seimet's method                                                     */

#define Seimet (LPRM2 || SPCM2 || HM2 || MM2 || TDIM2 || ANAM2 || MSM2 || \
                FTLM2)

#if Seimet
#define crystal(a,b,c,d) SETREG(D1,F ## a); crystal
#endif

/* a fill byte will be necessary if a type within a record occupies        */
/* 8 bits (e.g. an enumeration type) instead of 16 bits                    */

#define fill_byte (LPRM2  || SPCM2  || HM2   || ANAM2 || FSTM2 || SDSM2 || \
                   TSM2_1 || TSM2_2 || LM2   || FTLM2 || TDIM2 || GPM2)

/* if a compiler supports 'packed' records (two bytes are packed to one    */
/* word)                                                                   */

#define packing (LPRM2 || SPCM2 || HM2   || ANAM2 || MM2    || MSM2   || \
                 XAM2  || XHM2  || FSTM2 || SDSM2 || TSM2_1 || TSM2_2 || \
                 LM2   || FTLM2 || TDIM2 || GPM2)

/* if a compiler has trouble with forward pointers                         */

#define no_forward_pointers FSTM2 || MSM2

/* if a export list is still necessary                                     */

#define export (ANAM2 || XAM2 || CBM2)

/* we do not use variant records with tag fields, so define for PIM2:      */

#if (defined ANAM2) || (defined XAM2)
#define CASE: CASE
#endif

/* if a compiler does not allow local modules within implementation modules*/

#define no_local_modules (LPRM2 || SPCM2 || SDSM2 || FTLM2 || TSM2_1)

/* NEW() and DISPOSE() for LPRM2 etc.                                      */

#if (defined LPRM2)
#define NEW(P) ALLOCATE(P,SIZE(P^))
#define DISPOSE(P) DEALLOCATE(P,SIZE(P^))
#elif (defined SPCM2)
#define NEW(P) ALLOCATE(P,SIZE(P^))
#define DISPOSE(P) DEALLOCATE(P)
#endif

/* there are compilers with a revers or swapped order of bits within sets  */

#define revers FTLM2

#define swapped /* NONE */

/* FTLM2 special                                                           */

#ifdef FTLM2
#define HIGH(x) CARDINAL(HIGH(x))
#endif

/* TSM2_1 special                                                          */

#ifdef TSM2_1
#define EXPORT IMPORT
#endif

/* FSTM2 3.1 special                                                       */

#define no_set_return FSTM2

/* language macros                                                         */

#define ENDIF END
#define ENDFOR END
#define ENDCASE END
#define ENDWHILE END
#define CONTINUE
#define BREAK
