/*static char *SCCSID = "@(#)osmac.h    6.2 91/10/18";*/
/*      SCCSID = @(#)osmac.h    6.2 91/10/18
 *
 *      This file contains useful macros for C programming.
 *
 */

/* WARNING: When updating the RAS flag, also update osmaca.inc */

/*
 *      The RAS flag causes all RAS related code to be compiled as
 *      part of the DOS. All RAS related code should be surrounded
 *      by:
 *              #IF (RAS)
 *                :
 *                ras code
 *                :
 *              #ENDIF  ; RAS
 */

/*  If PERFVIEW is not defined, do not include RAS code. 76699 */
/*  77052 Add check if MMIO build and include RAS if it is.    */
#ifdef PERFVIEW
#define RAS     1
#else
#ifdef MMIOPH
#define RAS     1
#else
#define RAS     0
#endif /* MMIOPH */
#endif /* PERFVIEW */

/* WARNING: When updating this list, also update .asm list in osmaca.inc */

#ifdef ALLSTRICT
#  ifndef DEMSTRICT
#    define DEMSTRICT
#  endif
#  ifndef EM86STRICT
#    define EM86STRICT
#  endif
#  ifndef VDHSTRICT
#    define VDHSTRICT
#  endif
#  ifndef VDDSTRICT
#    define VDDSTRICT
#  endif
#  ifndef VDMMSTRICT
#    define VDMMSTRICT
#  endif
#  ifndef DEVSTRICT
#    define DEVSTRICT
#  endif
#  ifndef FSSTRICT
#    define FSSTRICT
#  endif
#  ifndef INFOSTRICT
#    define INFOSTRICT
#  endif
#  ifndef INTERRPRT
#    define INTERRPRT
#  endif
#  ifndef KMSTRICT
#    define KMSTRICT
#  endif
#  ifndef LDRSTRICT
#    define LDRSTRICT
#  endif
#  ifndef MISCSTRICT
#    define MISCSTRICT
#  endif
#  ifndef MODECHECK
#    define MODECHECK
#  endif
#  ifndef PERFSTRICT
#    define PERFSTRICT
#  endif
#  ifndef PGSTRICT
#    define PGSTRICT
#  endif
#  ifndef SELSTRICT
#    define SELSTRICT 0x1
#  endif
#  ifndef SEMSTRICT
#    define SEMSTRICT
#  endif
#  ifndef SMSTRICT
#    define SMSTRICT
#  endif
#  ifndef VMSTRICT
#    define VMSTRICT
#  endif
#  ifndef VOLPRTCHK
#    define VOLPRTCHK
#  endif
#  ifndef DBGSTRICT
#    define DBGSTRICT
#  endif
#  ifndef PTSTRICT
#    define PTSTRICT
#  endif
#endif

/* returns the number of elements in a statically sized array */
#define NElements(array) ((sizeof array)/(sizeof array[0]))

#define SSToDS(p)       ((void *) (TKSSBase + (unsigned) (p)))

extern char *TKSSBase;

/* To get 0:32 address of a 16:16 pointer. return value -1 means
 * 16:16 address segment part is invalid.
 */
#define GET032OF1616(p,tmp)     (PVOID)((tmp = SELConvertToLaddr(SEGMENTOF16(p)))\
                                == -1 ? -1 : tmp + (ULONG)OFFSETOF16(p))


#ifndef FNO_NUM         /* if a .c file doesn't know it's filenumber */
#  define FNO_NUM       0       /* use unknown file number */
#  error                "../dosinc/osmac.h: FNO_NUM undefined"
                        -- cause syntax error
#endif

#ifndef FNO_INCL
#  error                "../dosinc/osmac.h: ../dosinc/fno*.h not included"
                        -- cause syntax error
#endif

#ifndef SCCSID
#  error                "../dosinc/osmac.h: SCCSID undefined"
                        -- cause syntax error
#endif

#define _LINEFILE_      ((__LINE__ << 16) | FNO_NUM)


/***EP  _assert - cause internal error if assertion fails
 *
 *      Given a boolean, this procedure causes an internal error if
 *      the boolean is false.  Typically, the value of this boolean is
 *      derived from some test expression.
 *
 *      _assert (f)
 *
 *      ENTRY   f               - boolean value (int)
 *      RETURN  NONE
 *
 *      CALLS   _panicfn/_panic
 *      WARNING This procedure is implemented as a macro.
 *      EFFECTS NONE
 */

#ifdef INTERRPRT
#  ifdef FNO_INCL               /* Has file number been specified? */
     static char _asrtCurFile[] = SCCSID;
#    define _assert(e)  if (!(e)) _panicfn(_LINEFILE_, _asrtCurFile); else
#    define panic(a)    _panicfnmsg(_LINEFILE_, _asrtCurFile, a)
#    define Panic(a)    _panicsprintf a, _panicfn(_LINEFILE_, _asrtCurFile)
#  else
#    define _assert(e)  if (!(e)) _panicfn(_LINEFILE_, __FILE__); else
#    define panic(a)    _panicfnmsg(_LINEFILE_, __FILE__, a)
#    define Panic(a)    _panicsprintf a, _panicfn(_LINEFILE_, __FILE__)
#  endif
#else
#  define _assert(e)    if (!(e)) _panic(_LINEFILE_); else
#  define panic(a)      _panic(_LINEFILE_)
#  define Panic(a)      _panic(_LINEFILE_)
#endif

extern int  _panicfnmsg(int linefile, char *pfn, char *pmsg);
extern void _cdecl _panicsprintf(char *pfmt,...);
extern void _panicfn(int linefile, char *pfn);
extern int  _panic(int linefile);
