/* Global definitions used by every source file.
 * Some may be compiler dependent.
 */

/* Indexes into binmode in files.c; hook for compilers that have special
 * open modes for binary files
 */
#define READ_BINARY	0
#define WRITE_BINARY	1
#define APPEND_BINARY	2
extern char *binmode[];

/* These two lines assume that your compiler's longs are 32 bits and
 * shorts are 16 bits. It is already assumed that chars are 8 bits,
 * but it doesn't matter if they're signed or unsigned.
 */
typedef long int32;		/* 32-bit signed integer */
typedef unsigned short int16;	/* 16-bit unsigned integer */
#define uchar(x) ((unsigned char)(x))
#define MAXINT16 ((int16)65535) /* Largest 16-bit integer */

/* not all compilers support defined(SYM) in the preprocessor.... */
#ifdef NODEFINED
# define defined(x)	(x)
#endif

/* Since not all compilers support structure assignment, the ASSIGN()
 * macro is used. This controls how it's actually implemented.
 */
#ifdef NOSTRUCTASSIGN
			/* Version for old compilers that don't support it */
# define ASSIGN(a,b)	memcpy((char *)&(a),(char *)&(b),sizeof(b));
#else
			/* Version for compilers that do */
# define ASSIGN(a,b)	((a) = (b))
#endif

#if (defined(SYS5) || defined(MSC) || defined(__TURBOC__))
# define rindex		strrchr
# define index		strchr
#else
# define strrchr	rindex
# define strchr		index
#endif

#if (defined(MSC) || defined(__TURBOC__))
/* Turbo C needs prototypes for library functions. MSC would like them. */
# ifdef ATARI_ST
#  include <tos.h>
# endif
# ifdef MSDOS
#  ifdef MSC
#   include <dos.h>
#  endif
#  ifdef __TURBOC__
#   define interrupt
#   include <dos.h>
#   undef disable
#   define disable Disable
#  endif
# endif
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
extern long htol(char *);
# ifdef ATARI_ST
extern log_msg(char *,...);
# endif
#else
/* Heavily used functions from the standard library */
char *index(),*rindex(),*ctime(),*tmpnam(),*fgets();
long atol(),htol();
# if ((defined(ATARI_ST) && defined(MWC)) || defined(UNIX))
char *malloc(),*calloc();
# else
void *malloc(),*calloc();
# endif
#endif

/* Define null object pointer in case stdio.h isn't included */
#ifndef NULL
/* General purpose NULL pointer */
# if (defined(ATARI_ST) && defined(MWC))
#  define NULL (char *)0	/* MW does not like funny typecasts on void */
# else
#  define NULL (void *)0
# endif
#endif
#define NULLCHAR (char *)0	/* Null character pointer */
#define NULLFP	 (int (*)())0	/* Null pointer to function returning int */
#define NULLVFP	 (void (*)())0	/* Null pointer to function returning void */
#define NULLFILE (FILE *)0	/* Null file pointer */

#ifndef min
/* General purpose function macros */
# define min(x,y)	((x)<(y)?(x):(y))	/* Lesser of two args */
# define max(x,y)	((x)>(y)?(x):(y))	/* Greater of two args */
#endif

#if (defined(MPU8086) || defined(MPU8080) || defined(vax) || defined(MSDOS) || defined(M_I86) || defined(M_I286) || defined(M_I386))
# define LITTLE_ENDIAN		/* Low order bytes are first in memory */
#endif				/* Almost all other machines are big-endian */

#if (defined(AMIGA) || defined(ATARI_ST) || defined(MAC))
# define I_ALIGN	2	/* word-aligned integer storage */
#else
# define I_ALIGN	1	/* byte-aligned integer storage */
#endif

/* Define LARGECODE and LARGEDATA depending on the memory model ('86 only) */
#if (defined(M_I86MM) || defined(__MEDIUM__))
# define LARGECODE
#endif

#if (defined(M_I86LM) || defined(M_I86HM) || defined(__LARGE__) || defined(__HUGE__))
# define LARGECODE
# define LARGEDATA
#endif

/* In LARGE model, a pointer can't be register so leave them to the compiler */
#ifdef LARGEDATA
# define register
#endif

/* Convert an address to a LONG value and vice-versa for printing and input */
/* Of course, the Intel 80x86 line of processors causes a lot of headaches */
#if (defined(MSDOS) || defined(M_I86MM))
# if (defined(LARGEDATA) && defined(__TURBOC__))
#  define ptr2long(x)	(((unsigned long) (x) >> 12) + (unsigned) (x))
#  define long2ptr(x)	((((x) << 12) & 0xffff0000L) + ((x) & 0x0f))
# endif
# if (!defined(LARGEDATA))
   long	ptr2long();			/* for fuzzy segment addresses */
#  define long2ptr(x)	((char *) (x))
# endif
#endif

#ifndef long2ptr
# define ptr2long(x)	((long) (x))	/* typecast suffices for others */
# define long2ptr(x)	((char *) (x))
#endif

#ifdef MPU8080 /* Assembler routines are available */
int16 hinibble(),lonibble(),hibyte(),lobyte(),hiword(),loword();
#else
/* Extract a short from a long */
# if (defined(ATARI_ST) && defined(MWC) && (MWC < 306))
extern int Sixteen;			/* MW C before 3.0.6 cannot << 16 */
#  define hiword(x)	((int16)((x) >> Sixteen)) /* hide compiler bug.. */
# else
#  define hiword(x)	((int16)((x) >> 16))
# endif
# define loword(x)	((int16)(x))

/* Extract a byte from a short */
# define hibyte(x)	(uchar((x) >> 8))
# define lobyte(x)	(uchar(x))

/* Extract nibbles from a byte */
# define hinibble(x)	(((x) >> 4) & 0xf)
# define lonibble(x)	((x) & 0xf)
#endif

#ifdef LITTLE_ENDIAN
int16 get16();
int32 get32();
#else
#define get16(cp)	(*((int16 *)(cp)))
#define get32(cp)	(*((int32 *)(cp)))
#endif

#if (defined(LITTLE_ENDIAN) || I_ALIGN > 1)
char *put16(),*put32();
#else
#define put16(cp,x)	(*((int16 *)(cp)) = (x), (cp) + sizeof(int16))
#define put32(cp,x)	(*((int32 *)(cp)) = (x), (cp) + sizeof(int32))
#endif

#if defined(ATARI_ST)
/* the 68000 processor won't let you disable interrupts in user mode
 * therefore, a trap handler has been defined to do this, and it's
 * installed as trap #5. The Mark Williams compiler generates a trap #5
 * when you call the magic function "micro_rtx" (their multi-tasking
 * executive).	From version 3, it can generate any trap number using
 * the magic function _VtrapX_().  We'll use trap #7 in that case.
 * Turbo-C will have to call a function calling the trap.
 * the trap handler returns the previous processor level as a char.
 */

# ifdef __TURBOC__
extern char spl(char);			/* function doing the TRAP #5 */
#  define disable()	spl(6)
#  define restore(state) spl(state)
# endif

# ifdef MWC
#  if MWC < 300
#   define disable()	micro_rtx(6)
#   define restore(st)	micro_rtx(st)
#  else
#   define disable()	_Vtrap7_(6)
#   define restore(st)	_Vtrap7_(st)
#  endif

/* a quick, non-checking free() function as a macro (for MW C only) */
#  ifdef QFREE
#   define free(p)	((char *) (p))[-1] |= 1;
#  endif
#  define NOTMPFILE			/* MW C lacks tmpfile() */
# endif
#endif

#ifdef NOTMPFILE
# define fclose(fp)	notmpfclose(fp) /* our own fclose() to delete tmpfiles */
#endif

/* Hardware I/O functions that can be replaced with macros in some compilers */
#ifdef MSC
# define inportb	inp
# define outportb	outp
#else
# ifndef __TURBOC__
unsigned char inportb();
unsigned int inportw();
# endif
#endif
