/*
The following declarations are used in most every program written by Paul
Kienitz.  Generally, I use a symbol table file which includes exec/exec.h,
libraries/dosextens.h, stdio.h, and this, which pulls in functions.h.  I have
a separate symbol file for intuition/intuitionbase.h with INTUITIONPRIVATE
defined.  Intuitionbase.h pulls in all the other intuition/ files.
*/

#ifndef PAUL_DOT_AITCH
#define PAUL_DOT_AITCH

#ifdef _STDIO_H
#define put(S) fputs(S, stdout)
#endif


#define null   0L
#define maxint 0x7fffffffL
#define minint 0x80000000L
/* uppercase is a pain in the wazoo */

#define bip(T, B) ((T *) (B << 2))
#define gbip(B)   bip(void, B)
/* B is expected to be of type BPTR or BSTR. */

typedef short bool;
#define false 0
#define true  1

typedef unsigned short ushort;
typedef unsigned long  ulong;
typedef unsigned char  ubyte;

typedef void *adr;
typedef char *str;
typedef str  *stray;

#define bit(B) (1L << (B))

#define import  extern
#define PUBLIC

#ifndef private
#define private static
#else
#undef  private
#define private PUBLIC
#endif


#ifdef AZTEC_C

/******
HERE'S THE PART where we monkey with functions.h.  The problem is that many
of the functions in there are incorrectly declared, according to me.  First,
CreateProc and DeviceProc are declared as returning struct Process pointers
when they in fact return struct MsgPort pointers.  Secondly, all of the DOS
functions that return BPTRs are declared as returning pointers.  And they
define OpenWorkBench as returning a short!  Some of these functions can be
fixed by #defining Blah as _Blah, when the glue routine provides both names,
and declaring _Blah properly.  For the others, we use a #define before
functions.h to prevent it from defining them at all.
*/

#define CreateProc    ___n_O_ne_XI__st_EN_t____1
#define DeviceProc    ___n_O_ne_XI__st_EN_t____2
#define CreateDir     ___n_O_ne_XI__st_EN_t____3
#define ParentDir     ___n_O_ne_XI__st_EN_t____4
#define DupLock       ___n_O_ne_XI__st_EN_t____5
#define LoadSeg       ___n_O_ne_XI__st_EN_t____6
#define OpenWorkBench ___n_O_ne_XI__st_EN_t____7

#include <functions.h>

#undef CreateProc
#undef DeviceProc
#undef CreateDir
#undef ParentDir
#undef DupLock
#undef LoadSeg
#undef OpenWorkBench


#ifndef LIBRARIES_DOS_H
#define BPTR long
#endif

import BPTR CreateDir(), ParentDir(), DupLock(), LoadSeg();

import struct MsgPort *CreateProc(), *DeviceProc();

import struct Screen *OpenWorkBench();

/* the autodocs say don't use the return of OpenWorkBench as a screen pointer
because it might change as soon as you get it.  BUT if you use LockIBase, the
screen pointer will be valid until you UnlockIBase. */

import BPTR _Lock(), _Open(), _Input(), _Output(), _CurrentDir();

#define Lock       _Lock
#define Open       _Open
#define Input      _Input
#define Output     _Output
#define CurrentDir _CurrentDir

/*
What we really need is different BPTR types that are incompatible for
assignment without casts, yet refuse to be dereferenced as pointers.  Like
FileLockBPTR, SegListBPTR, etc.  But what would these be defined as?
*/


/* AND NOW, convenience stuff:::::::::::::::::::: */

#ifdef SAVE_ONE_MEASLY_INSTRUCTION_PER_CALL

import struct Message *_GetMsg();
import void            _ReplyMsg();
import struct Message *_WaitPort();
import struct Task    *_FindTask();

#define GetMsg   _GetMsg
#define ReplyMsg _ReplyMsg
#define WaitPort _WaitPort
#define FindTask _FindTask

#endif
/*
There are probably a few other glue routines with two names and wasted
instructions.  (It's like, GetMsg is a jump to _GetMsg.  Why didn't they just
put the two symbols at the same address??  Bozos...)
*/

import adr  _AllocMem();
import void _FreeMem();

#else  /* lattice */
#define _AllocMem AllocMem
#define _FreeMem  FreeMem
#define _Lock     Lock
#define _Open     Open
#endif AZTEC_C


#ifdef EXEC_MEMORY_H

#define Alloc(S)    _AllocMem((long) (S), 0L)
#define AllocC(S)   _AllocMem((long) (S), MEMF_CHIP)
#define AllocP(S)   _AllocMem((long) (S), MEMF_PUBLIC)
#define AllocZ(S)   _AllocMem((long) (S), MEMF_CLEAR)
#define AllocCP(S)  _AllocMem((long) (S), MEMF_CHIP | MEMF_PUBLIC)
#define AllocCZ(S)  _AllocMem((long) (S), MEMF_CHIP | MEMF_CLEAR)
#define AllocPZ(S)  _AllocMem((long) (S), MEMF_PUBLIC | MEMF_CLEAR)
#define AllocCPZ(S) _AllocMem((long) (S), MEMF_CHIP | MEMF_PUBLIC | MEMF_CLEAR)
#define NewR(T, R)  ((T *) _AllocMem((long) sizeof(T), R))
#define New(T)      NewR(T, 0L)
#define MewC(T)     NewR(T, MEMF_CHIP)
#define NewP(T)     NewR(T, MEMF_PUBLIC)
#define NewZ(T)     NewR(T, MEMF_CLEAR)
#define NewCP(T)    NewR(T, MEMF_CHIP | MEMF_PUBLIC)
#define NewCZ(T)    NewR(T, MEMF_CHIP | MEMF_CLEAR)
#define NewPZ(T)    NewR(T, MEMF_PUBLIC | MEMF_CLEAR)
#define NewCPZ(T)   NewR(T, MEMF_CHIP | MEMF_PUBLIC | MEMF_CLEAR)

#endif

#define Free(T, A)    _FreeMem(A, (long) sizeof(T))
#define FreeMem(A, S) _FreeMem(A, (long) (S))


#ifdef LIBRARIES_DOS_H

#define RLock(F) _Lock(F, ACCESS_READ)
#define WLock(F) _Lock(F, ACCESS_WRITE)
#define OOpen(F) _Open(F, MODE_OLDFILE)
#define NOpen(F) _Open(F, MODE_NEWFILE)

#endif


#define Forbid() ((*((ubyte **) 4))[295]++)
/* as efficient as assembly; Aztec turns that into two instructions. */

#define ThisProcess() ((*((struct Process ***) 4))[69])
/* equivalent to (struct Process *) SysBase->ThisTask, two instructions. */

/** the cowardly safe alternative:
#define ThisProcess() ((struct Process *) _FindTask(0L))
import struct Task *_FindTask();
*/

#ifdef AZTEC_C	 /* remove this for old v3.4 aztec */
#define strcpy _BUILTIN_strcpy
#define strcmp _BUILTIN_strcmp
#define strlen _BUILTIN_strlen
#endif

#endif PAUL_DOT_AITCH
