#ifndef LIBRARIES_ARPBASE_H
#define LIBRARIES_ARPBASE_H
/**********************************************************************
 *
 *	AmigaDOS Replacement Project (ARP) -- Library Include File 'C'
 *
 **********************************************************************
 *
 *	History:
 *
 *	Version:	arpbase.h,v 34.00 02/27/88
 *
 *	Created by:	SDB
 *	Revised:	SDB -- Just bag earlier versions, since didn't have
 *			       time to maintain C header during 'the last days'.
 *			       Created this file mainly from arpbase.i.
 *
 *	Revised:	SDB -- Added stuff for version 32, ASyncRun()
 *			       returns and data structures.
 *			SDB -- Added ERROR_NO_CLI
 *			SDB -- Added final resident data structures,
 *			       final ASyncRun() data structures, and
 *			       date. Final edits for V33.4 release.
 **********************************************************************
 *
 *
 *	Copyright (c) 1987, by Scott Ballantyne
 *
 *	The arp.library, and related code and files may be freely used
 *	by supporters of ARP.  Modules in the arp.library may not be
 *	extracted for us in independent code, but you are welcome to provide
 *	the arp.library with your work and call on it freely.
 *
 *	You are equally welcome to contribute new functions, improve the
 *	ones within, or suggest additions.
 *
 *	BCPL programs are not welcome to call on the arp.library.
 *	The welcome mat is out to all others.
 *
 *********************************************************************/

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif  !EXEC_TYPES_H

#ifndef EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif  !EXEC_LIBRARIES_H

#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif  !EXEC_LISTS_H

#ifndef EXEC_SEMAPHORES_H
#include <exec/semaphores.h>
#endif  !EXEC_SEMAPHORES_H

#ifndef LIBRARIES_DOS_H
#include <libraries/dos.h>
#endif  !LIBRARIES_DOS_H

/* arp.library's node structure, not too hefty even now. */

struct ArpBase {
	struct Library	LibNode;	/* Standard library node	*/
	BPTR		SegList;	/* Pointer to loaded libcode	*/
	UBYTE		Flags;		/* Not used, yet!		*/
	UBYTE		ESCChar;	/* Character used for escaping	*/
	LONG		ArpReserved1;	/* ArpLib's use only!		*/
	struct Library	*EnvBase;	/* Dummy library for MANX compatibility */
	struct Library	*DosBase;	/* Dos library pointer		*/
	struct Library	*GfxBase;	/* Graphics lib pointer		*/
	struct Library	*IntuiBase;	/* Intuition lib pointer	*/
	struct MinList	ResLists;	/* Resource trackers		*/
	struct ResidentPrgNode *ResidentPrgList; /* Installed programs */
	struct SignalSemaphore ResPrgProtection; /* Protection for above */
};

/* Following is here *only* for information and for compatibility
 * with MANX, don't use in new code!
 */

struct EnvBase {
	struct Library	LibNode;	/* Standard library node for linkage */
	BYTE		*EnvSpace;	/* Access only when Forbidden! */
	ULONG		EnvSize;	/* Total allocated mem for EnvSpace */
	struct ArpBase	*ArpBase;	/* Added in V32 for Resource Tracking */
};

/* These are used in release 33.4, but not by the library code. Instead,
 * individual programs check for these flags. Not ideal, but such is life.
 *
 */

#define ARPB_WILD_WORLD 0L		; Mixed BCPL/Normal wildcards.
#define ARPB_WILD_BCPL  1L		; Pure BCPL wildcards.

#define ARPF_WILD_WORLD (1L << 0)
#define ARPF_WILD_BCPL  (1L << 1)

/*************** C SPECIFIC STUFF *************************************/
/* There are a few things in arp.library that are only directly acessable
 * from assembler.  The glue routines provided by us for all 'C' compilers
 * use the following conventions to make these available to C programs.
 * The glue for other language's should use as similar a mechanism as
 * possible, so that no matter what language or compiler we speak, when
 * talk about arp, we will know what the other guy is saying.
 *
 * Here are the cases:
 *	Atol() - if a bad digit is encountered, will store a ERRBADINT in
 *		 Errno, the return from Atol() will be the bad character
 *		 encountered.  Note: Atol() will not clear Errno if return
 *		 is successful.
 *	Trackers: All tracking calls return the Tracker pointer in A1 as a
 *		  secondary result, you can obtain this from the global
 *		  variable LastTracker immediately after the call.
 * Finally, GetTracker() syntax is differnt for C and assembler, for 'C'
 * the Syntax is GetTraker( ID ), the binding routine will store the ID
 * into the tracker on return.
 *
 * In cases where you have allocated a tracker before you have obtained a
 * resource (usually the most efficient method), and the resource has not
 * been obtained, you will need to clear the tracker id.  The macro CLEAR_ID()
 * has been provided for that purpose.  It expects a pointer to a DefaultTracker
 * sort of struct.
 *
 */

extern LONG Errno;	/* Error returns not reportable by functions */
extern struct DefaultTracker *LastTracker;	/* Look here after a tracking call */
#define ERRBADINT	1L	/* Atol() could not convert string to number */

#define CLEAR_ID( t )	((SHORT *) t)[-1] = NULL

/*
 * Non controversial, normal library style stuff
 */

#define ArpName		"arp.library"		/* Name to use when opening */
#define ArpVersion	34L			/* Current version of arplib */


/*
 * The alert object is what you use if you really must return an 
 * alert to the user. You would normally OR this with another alert number
 * from the alerts.h file, generally, these should be NON deadend alerts.
 *
 * For example, if you can't open ArpLibrary:
 *	Alert( (AG_OpenLib|AO_ArpLib), 0L);
 *
 */
#define AO_ArpLib	0x00008036L		/* Alert object */

/*
 * Alerts that arp.library can return.
 */

#define AN_ArpLib	0x03600000L	/* Alert number			*/
#define AN_ArpNoMem	0x03610000L	/* No more memory		*/
#define AN_ArpInputMem	0x03610002L	/* No memory for input buffer	*/
#define AN_ArpNoMakeEnv	0x83610003L	/* No memory to make EnvLib	*/

#define AN_ArpNoDOS	0x83630001L	/* Can't open DOS		*/
#define AN_ArpNoGfx	0x83630002L	/* Can't open graphics.library	*/
#define AN_ArpNoIntuit	0x83630003L	/* Can't open intuition		*/
#define AN_BadPackBlues	0x83640000L	/* Bad packet returned to SendPacket()	*/
#define AN_Zombie	0x83600003L	/* Zombie roaming around system */

#define AN_ArpScattered	0x83600002L	/* Scatter loading not allowed for arp */

/* Return codes you can get from calling arp.library's Assign() function */

#define ASSIGN_OK	0L	/* Everything is cool and groovey */
#define ASSIGN_NODEV	1L	/* "Physical" is not valid for assignment */
#define ASSIGN_FATAL	2L	/* Something really icky happened */
#define ASSIGN_CANCEL	3L	/* Tried to cancel something but it won't cancel */

/* Size of buffer you need if you are going to call ReadLine() */

#define MaxInputBuf	256L

/************************** File Requester ****************************/
/***************** Submit the following to FileRequest() **************/
/**********************************************************************/

struct FileRequester {
	BYTE	*fr_Hail;		/* Hailing text			*/
	BYTE	*fr_File;		/* Filename array (FCHARS * N)	*/
	BYTE	*fr_Dir;		/* Directory array (DSIZE + 1)	*/
	struct Window *fr_Window;	/* Window requesting files or NULL*/
	UBYTE	fr_FuncFlags;		/* Set bitdef's below		*/
	UBYTE	fr_reserved1;		/* Set to NULL			*/
	VOID	(*fr_Function)();	/* Your function, see bitdef's	*/
	LONG	fr_reserved2;		/* RESERVED			*/
};

/* The following are the defines for fr_FuncFlags.  These bits tell
 * FileRequest() what your fr_UserFunc is expecting, and what FileRequest()
 * should call it for.
 *
 * You are called like so:
 * fr_Function(Mask, Object)
 * ULONG	Mask;
 * CPTR		*Object;
 *
 * The Mask is a copy of the flag value that caused FileRequest() to call
 * your function. You can use this to determine what action you need to
 * perform, and exactly what Object is, so you know what to do and
 * what to return.
 */

#define FRB_DoWildFunc	7L /* Call me with a FIB and a name, ZERO return accepts. */
#define FRB_DoMsgFunc	6L /* You get all IDCMP messages not for FileRequest() */
#define FRB_DoColor	5L /* Set this bit for that new and different look */
#define FRB_NewIDCMP	4L /* Force a new IDCMP (only if fr_Window != NULL) */
#define FRB_NewWindFunc	3L /* You get to modify the newwindow structure. */
#define FRB_AddGadFunc	2L /* You get to add gadgets. */
#define FRB_GEventFunc	1L /* Function to call if one of your gadgets is selected. */
#define	FRB_ListFunc	0L /* Not implemented yet. */

#define FRF_DoWildFunc	(1L << 7)
#define FRF_DoMsgFunc	(1L << 6)
#define	FRF_DoColor	(1L << 5)
#define FRF_NewIDCMP	(1L << 4)
#define FRF_NewWindFunc	(1L << 3)
#define FRF_AddGadFunc	(1L << 2)
#define FRF_GEventFunc	(1L << 1)
#define FRF_ListFunc	(1L << 0)

#define FCHARS	32L			/* Filename size */
#define DSIZE	33L			/* Directory name size */

#define FR_FIRST_GADGET	0x7680L	/* User gadgetID's must be less than this value */

/*************************************************************************/
/********************** PATTERN MATCHING *********************************/
/*************************************************************************/

/* Structure expected by FindFirst(), FindNext() */
/*
 * You need to allocate this structure and initialize it as follows:
 *
 * Set ap_BreakBits to the signal bits (CDEF) that you want to take a
 * break on, or NULL, if you don't want to convenience the user.
 *
 * if you want to have the FULL PATH NAME of the files you found, allocate
 * a buffer at the END of this structure, and put the size of it into
 * ap_Length.  If you don't want the full path name, make sure you set
 * ap_Length to zero.  In this case, the name of the file, and stats are
 * available in the ap_Info, as per usual.
 *
 * Then call FindFirst() and then afterwards, FindNext() with this structure.
 * You should check the return value each time (see below) and take the
 * appropriate action, ultimately calling FreeAnchorChain() when there
 * are no more files and you are done.  You can tell when you are done by
 * checking for the normal AmigaDOS return code ERROR_NO_MORE_ENTRIES.
 *
 * You will also have to check the DirEntryType variable in the ap_Info
 * structure to determine what exactly you have received.
 */

struct AnchorPath {
	struct Anchor	*ap_Base;	/* Pointer to first anchor */
	struct Anchor	*ap_Last;	/* Pointer to last anchor */
	LONG	ap_BreakBits;	/* Bits to break on */
	LONG	ap_FoundBreak;	/* Bits we broke on. Also returns ERROR_BREAK */
	ULONG	ap_Length;	/* Actual size of ap_Buf, set to 0 if no ap_Buf */
	struct	FileInfoBlock	ap_Info;
	BYTE	ap_Buf[1];	/* Allocate a buffer here, if desired */
};
/*
 * structure used by the pattern matching functions, no need to obtain, diddle
 * or allocate this yourself.
 */

struct Anchor {
	struct Anchor		*an_Next;
	struct Anchor		*an_Pred;
	struct FileLock		*an_Lock;
	struct FileInfoBlock	*an_Info;
	LONG	an_Status;		/* Type of this anchor node */
	union {
		WORD	an_Text;	/* Actual instance of a BSTRing */
		BYTE	an_Actual[2];	/* more memory allocated as required */
	} an_BSTR;
};
/* This structure takes a pointer, and returns FALSE if wildcard was not
 * found by FindFirst()
 */
#define IsWild( ptr )		( *((LONG *)(ptr)) )

/* Constants used by wildcard routines */
/* These are the pre-parsed tokens referred to by pattern match.  It is not
 * necessary for you to do anything about these, FindFirst() FindNext()
 * handle all these for you.
 */

#define P_ANY		0x80L	/* Token for '*' or '#?' */
#define P_SINGLE	0x81L	/* Token for '?' */
#define P_ORSTART	0x82L	/* Token for '(' */
#define P_ORNEXT	0x83L	/* Token for '|' */
#define P_OREND		0x84L	/* Token for ')' */
#define P_TAG		0x85L	/* Token for '{' */
#define P_TAGEND	0x86L	/* Token for '}' */
#define P_NOTCLASS	0x87L	/* Token for '^' */
#define P_CLASS		0x88L	/* Token for '[]' */
#define P_REPBEG	0x89L	/* Token for '[' */
#define P_REPEND	0x8AL	/* Token for ']' */

/* Values for an_Status, NOTE: these are the actual bit numbers. */
#define COMPLEX_BIT	1L	/* Parsing complex pattern */
#define EXAMINE_BIT	2L	/* Searching directory */

/* Returns from FindFirst() FindNext() */
/* Note that you can also get return codes as defined in dos.h,
 * particularly you can get ERROR_NO_MORE_ENTRIES.
 */

#define ERROR_BUFFER_OVERFLOW	303L	/* User or internal buffer overflow */
#define ERROR_BREAK		304L	/* A break character was received */

/* Structure used by AddDANode(), AddDADevs(), FreeDAList().
 *
 * This structure is used to create lists of names, which normally
 * are devices, assigns, volumes, files, or directories.
 */

struct DirectoryEntry {
	struct DirectoryEntry	*de_Next;	/* Next in list */
	BYTE	de_Type;			/* DLX_mumble */
	BYTE	de_Flags;		/* For future expansion, DO NOT USE! */
	BYTE	de_Name[1];		/* The name of the thing found */
};

/* Defines you use to get a list of the devices you want to look at.
 * For example, to get a list of all directories and volumes, do:
 *
 *	AddDADevs( mydalist, (DLF_DIRS | DLF_VOLUMES) )
 *
 * After this, you can examine the de_type field of the elements added to
 * your list (if any) to discover specifics about the objects added.
 *
 * Note that if you want only devices which are also disks, you must request
 * (DLF_DEVICES | DLF_DISKONLY).
 */

#define DLB_DEVICES	0L	/* Return devices */
#define DLB_DISKONLY	1L	/* Modifier for above: Return disk devices only */
#define DLB_VOLUMES	2L	/* Return volumes only */
#define DLB_DIRS	3L	/* Return assigned devices only */

#define DLF_DEVICES	(1L << 0)
#define DLF_DISKONLY	(1L << 1)
#define DLF_VOLUMES	(1L << 2)
#define DLF_DIRS	(1L << 3)

/* Legal de_Type values, check for these after a call to AddDADevs(), or use
 * on your own as the ID values in AddDANode().
 */

#define DLX_FILE	0L	/* AddDADevs() can't determine this */
#define DLX_DIR		8L	/* AddDADevs() can't determine this */
#define DLX_DEVICE	16L	/* It's a resident device */

#define DLX_VOLUME	24L	/* Device is a volume */
#define DLX_UNMOUNTED	32L	/* Device is not resident */

#define DLX_ASSIGN	40L	/* Device is a logical assignment */

/*********************************************************************/
/********************** RESOURCE TRACKING ****************************/
/*********************************************************************/

/* Note: ResList MUST be a DosAllocMem'ed list!, this is done for
 * you when you call CreateTaskResList(), typically, you won't need
 * to access/allocate this structure.
 */

struct ResList {
	struct MinNode	rl_Node;	/* Used by arplib to link reslist's */
	struct Task	*rl_TaskID;	/* Owner of this list */
	struct MinList	rl_FirstItem;	/* List of TrackedResource's */
	struct ArpResList *rl_Link;	/* SyncRun's use - hide list here */
};
/*
 * The rl_FirstItem list (above) is a list of TrackedResource (below).
 * It is very important that nothing in this list depend on the task
 * existing at resource freeing time (i.e., RemTask(0L) type stuff,
 * DeletePort() and the rest).
 *
 * The tracking functions return a struct Tracker *Tracker to you, this
 * is a pointer to whatever follows the tr_ID variable.
 * The default case is reflected below, and you get it if you call
 * GetTracker() ( see DefaultTracker below).
 *
 * NOTE: The two user variables mentioned in an earlier version don't
 * exist, and never did. Sorry about that (SDB).
 *
 * However, you can still use ArpAlloc() to allocate your own tracking nodes
 * and they can be any size or shape you like, as long as the base structure
 * is preserved. They will be freed automagically just like the default trackers.
 */

struct TrackedResource {
	struct MinNode	tr_Node;	/* Double linked pointer */
	BYTE		tr_Flags;	/* Don't touch */
	BYTE		tr_Lock;	/* Don't touch, for Get/FreeAccess() */
	SHORT		tr_ID;		/* Item's ID */
	/*
	 * The struct DefaultTracker *Tracker portion of the structure.
	 * The stuff below this point can conceivably vary, depending
	 * on user needs, etc.  This reflects the default.
	 */
	union {
		CPTR	tr_Resource;	/* Whatever */
                LONG	tg_Verify;	/* For use during TRAK_GENERIC */
	} tr_Object;			/* The thing being tracked */
	union {
		VOID	(*tg_Function)(); /* Function to call for TRAK_GENERIC */
		struct	Window	*tr_Window2;	/* For TRAK_WINDOW */
	} tr_Extra;				/* Only needed sometimes */
};

#define tg_Value tg_Verify	/* Ancient compatibility */

/* You get a pointer to a struct of the following type when you call
 * GetTracker().  You can change this, and use ArpAlloc() instead of
 * GetTracker() to do tracking. Of course, you have to take a wee bit
 * more responsibility if you do, as well as if you use TRAK_GENERIC
 * stuff.
 *
 * TRAK_GENERIC folks need to set up a task function to be called when an
 * item is freed.  Some care is required to set this up properly.
 *
 * Some special cases are indicated by the unions below, for TRAK_WINDOW,
 * if you have more than one window opened, and don't want the IDCMP closed
 * particularly, you need to set a ptr to the other window in dt_Window2.
 * See CloseWindowSafely() for more info.  If only one window, set this to NULL.
 *
 */

struct DefaultTracker {
	union {
		CPTR	dt_Resource;	/* Whatever */
		LONG	tg_Verify;	/* For use during TRAK_GENERIC */
	} dt_Object;			/* The object being tracked */
	union {
		VOID	(*tg_Function)();  /* Function to call for TRAK_GENERIC */
		struct Window *dt_Window2;	/* For TRAK_WINDOW */
	} dt_Extra;
};

/* Items the tracker knows what to do about */

#define TRAK_AAMEM	0L	/* Default (ArpAlloc) element */
#define TRAK_LOCK	1L	/* File lock */
#define TRAK_FILE	2L	/* Opened file */
#define TRAK_WINDOW	3L	/* Window -- see docs */
#define TRAK_SCREEN	4L	/* Screen */
#define TRAK_LIBRARY	5L	/* Opened library */
#define TRAK_DAMEM	6L	/* Pointer to DosAllocMem block */
#define TRAK_MEMNODE	7L	/* AllocEntry() node */
#define TRAK_SEGLIST	8L	/* Program segment */
#define TRAK_RESLIST	9L	/* ARP (nested) ResList */
#define TRAK_MEM	10L	/* Memory ptr/length */
#define TRAK_GENERIC	11L	/* Generic Element, your choice */
#define TRAK_DALIST	12L	/* DAlist ( aka file request ) */
#define TRAK_ANCHOR	13L	/* Anchor chain (pattern matching) */
#define TRAK_MAX	13L	/* Poof, anything higher is tossed */   

#define TRB_UNLINK	7L	/* Free node bit */
#define TRB_RELOC	6L	/* This may be relocated (not used yet) */
#define TRB_MOVED	5L	/* Item moved */

#define TRF_UNLINK	(1L << 7)
#define TRF_RELOC	(1L << 6)
#define TRF_MOVED	(1L << 5)

/* Returns from CompareLock() */
#define LCK_EQUAL	0L	/* The two locks refer to the same object */
#define LCK_VOLUME	1L	/* Locks are on the same volume */
#define LCK_DIFVOL1	2L	/* Locks are on different volumes */
#define LCK_DIFVOL2	3L	/* Locks are on different volumes */

/****************************** ASyncRun() ***************************/
/*
 * Message sent back on your request by an exiting process.
 * You request this by putting the address of your message in pcb_LastGasp,
 * and initializing the ReplyPort variable of your ZombieMsg to the
 * port you wish the message posted to.
 */

struct ZombieMsg {
	struct Message	zm_ExecMessage;
	ULONG	zm_TaskNum;		/* Task ID */
	ULONG	zm_ReturnCode;		/* Process's return code */
	ULONG	zm_Result2;		/* System return code */
	struct	DateStamp zm_ExitTime;	/* Date stamp at time of exit */
	ULONG	zm_UserInfo;		/* For whatever you wish. */
};

/* Structure required by ASyncRun() -- see docs for more info. */

struct ProcessControlBlock {
	ULONG	pcb_StackSize;		/* Stacksize for new process */
	BYTE	pcb_Pri;		/* Priority of new task */
	BYTE	pcb_Control;		/* Control bits, see defines below */
	APTR	pcb_TrapCode;		/* Optional Trap Code */
	ULONG	pcb_Input,p_Output;	/* Optional stdin, stdout */
	union {
		ULONG	pcb_SplatFile;	/* File to use for Open("*") */
		BYTE	*pcb_ConName;	/* CON: filename */
	} pcb_Console;
	ULONG	pcb_SplatFile;		/* File to use for Open("*") */
	CPTR	pcb_LoadedCode; 	/* If not null, will not load/unload code */
	struct ZombieMsg *pcb_LastGasp;	 /* ReplyMsg() to be filled in by exit */
	struct MsgPort	*pcb_WBProcess;	/* Valid only when PRB_NOCLI */
};

/* Some programs appear to have bugs in the startup code that does not handle
 * well a zero length command line (lattice startup has this, but is probably
 * not unique).  Use this macro to pass a null cmd line to a process using
 * either ASyncRun() or SyncRun()
 */

#define NOCMD	"\n"

/* The following control bits determine what ASyncRun() does on Abnormal Exits
 * and on background process termination. 
 */

#define	PRB_SAVEIO	0L	/* Don't free/check file handles on exit */
#define PRB_CLOSESPLAT	1L	/* Close Splat file, must request explicitly */
#define PRB_NOCLI	2L	/* Don't create a CLI process */
#define PRB_INTERACTIVE	3L	/* This should be interactive */
#define PRB_CODE	4L	/* Dangerous yet enticing */
#define PRB_STDIO	5L	/* Do the stdio thing, splat = CON:Filename */

#define PRF_SAVEIO	(1L << 0)
#define PRF_CLOSESPLAT	(1L << 1)
#define PRF_NOCLI	(1L << 2)
#define PRF_INTERACTIVE	(1L << 3)
#define PRF_CODE	(1L << 4)
#define PRF_STDIO	(1L << 5)

/* Error returns from SyncRun() and ASyncRun() */
#define PR_NOFILE	-1L	/* Could not LoadSeg() the file */
#define	PR_NOMEM	-2L	/* No memory for something */
#define PR_NOCLI	-3L	/* Only SyncRun() will fail if call not cli */
#define PR_NOSLOT	-4L	/* No room in TaskArray */
#define PR_NOINPUT	-5L	/* Could not open input file */
#define PR_NOOUTPUT	-6L	/* Could not get output file */
#define PR_NOLOCK	-7L	/* Could not get a lock */
#define PR_ARGERR	-8L	/* Bad argument to ASyncRun() */
#define PR_NOBCPL	-9L	/* Bad program passed to ASyncRun() */
#define PR_BADLIB	-10	/* Bad library version */
#define PR_NOSTDIO	-11	/* Couldn't get stdio handles */

/* Programs should return this as result2 if need a cli and don't have one. */

#define ERROR_NOT_CLI	400L		/* Program/function neeeds to be cli */

/******************** Resident Program Support *****************************/
/*
 * This is the kind of node allocated for you when yhou AddResidentPrg() a code
 * segment.  They are stored as a single linked list with the root in
 * ArpBase.  If you absolutely *must* wander through this list instead of
 * using the supplied functions, then you must first obtain the semaphore
 * which protects this list, and then release it afterwards.
 * Do not use Forbid() and Permit() to gain exclusive access!
 * Note that the supplied functions handle this locking protocol for you.
 */

struct ResidentPrgNode {
	struct ResidentPrgNode	 	*rpn_Next;	/* next or NULL */
	LONG				rpn_Usage;	/* Number of current users */
	ULONG				rpn_CheckSum;	/* Checksum of code */
	BPTR				rpn_Segment;	/* Actual segment */
	BYTE				rpn_Name[1];	/* Allocated as needed */
};


/* If your program starts with this structure, ASyncRun() and SyncRun() will
 * override a users stack request with the value in rpt_StackSize.
 * Furthermore, if you are actually attached to the resident list, a memory
 * block of size rpt_DataSize will be allocated for you, and
 * a pointer to this data passed to you in register A4.  You may use this
 * block to clone the data segment of programs, thus resulting in one
 * copy of text, but multiple copies of data/bss for each process
 * invocation.  If you are resident, your program will start at
 * rpt_Instruction, otherwise, it will be launched from the initial branch.
 */

struct ResidentProgramTag {
	BPTR	rpt_NextSeg;	/* Provided by DOS at LoadSeg time. */
	UWORD	rpt_BRA;	/* Short branch to executable */
	UWORD	rpt_Magic;	/* Resident majik value */
	ULONG	rpt_StackSize;	/* min stack for this process */
	ULONG	rpt_DataSize;	/* Data size to allocate if resident */
	/* 	rpt_Instruction; /* Start here if resident */
};
/*
 * The form of the ARP allocated node in your tasks memlist when launched
 * as a resident program. Note that the data portion of the node will only
 * exist if you have specified a nonzero value for rpt_DataSize. Note also
 * that this structure is READ ONLY, modify values in this at your own
 * risk.  The stack stuff is for tracking, if you need actual addresses
 * or stack size, check the normal places for it in your process/task struct.
 */
struct ProcessMemory {
	struct Node	pm_Node;
	UWORD		pm_Num;		/* This is 1 if no data, two if data */
	CPTR		pm_Stack;
	ULONG		pm_StackSize;
	CPTR		pm_Data;	/* Only here if pm_Num == 2 */
	ULONG		pm_DataSize;
};

/* To find the above on your memlist, search for the following name.
 * We guarantee this will be the only arp.library allocated node on
 * your memlist with this name, i.e. FindName(task->tcb_MemEntry, PMEM_NAME);
 */
#define PMEM_NAME	"ARP_MEM"

#define RESIDENT_MAGIC		0x4AFC		/* same as RTC_MATCHWORD (trapf) */

/* The initial branch destination and rpt_Instruction do not have to be the same.
 * This allows different actions to be taken if you are diskloaded or
 * resident. DataSize memory will be allocated only if you are resident,
 * but StackSize will override all user stack requests.
 */

/*********************** String/Data structures *************************/

struct DateTime {
	struct	DateStamp dat_Stamp;	/* DOS Datestamp */
	UBYTE		dat_Format;	/* controls appearance ot dat_StrDate */
	UBYTE		dat_Flags;	/* See BITDEF's below */
	BYTE		*dat_StrDay;	/* day of the week string */
	BYTE		*dat_StrDate;	/* date string */
	BYTE		*dat_StrTime;	/* time string */
};

/* Size of buffer you need for each DateTime strings: */
#define LEN_DATSTRING	10L

/* For dat_Flags */

#define DTB_SUBST	0L	/* Substitute "Today" "Tomorrow" where appropriate */
#define DTB_FUTURE	1L	/* Day of the week is in future */

#define DTF_SUBST	(1L << 0)
#define DTF_FUTURE	(1L << 1)

/* For dat_Format */
#define FORMAT_DOS	0L		/* dd-mmm-yy AmigaDOS's own, unique style */
#define FORMAT_INT	1L		/* yy-mm-dd International format */
#define FORMAT_USA	2L		/* mm-dd-yy The good'ol'USA.	*/
#define FORMAT_CDN	3L		/* dd-mm-yy Our brothers and sisters to the north */
#define FORMAT_MAX	FORMAT_CDN	/* Larger than this? Defaults to AmigaDOS */

#endif !LIBRARIES_ARPBASE_H
