#ifndef LIBRARIES_PATCH_H
#define LIBRARIES_PATCH_H
/*****************************************************************************/
/*
**	Filename:	libraries/patch.h
**	Release:	6.0
**	Date:		13.12.97
**
**	definition of patch.library public structures and returncodes
**
**	(C) Copyright 1993-97 Stefan Fuchs
**	All Rights Reserved
*/
/*****************************************************************************/

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

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

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

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


/*----------------------------------------------------------------------------*/
/* ErrorCodes */
#define PATERR_Ok		0	/* Everything Ok				*/
#define PATERR_PatchInUse	1	/* Patch Usecount <> 0				*/
#define PATERR_InvalidHandle	2	/* Pointer to patch is not (no longer) valid	*/
#define PATERR_OutOfMem		3	/* Out of memory				*/
#define PATERR_OpenLib		4	/* Failed to open requested library		*/
#define PATERR_FuncNotStd	5	/* Function to patch is not in the standard format */
#define PATERR_PatchInstalled	6	/* Can't remove patch because another program has  */
					/* installed a non-patch.library patch later       */
#define PATERR_InvalidTags	7	/* There was an error in the combination of the specified Tags */
#define PATERR_OpenDev		8	/* Failed to open requested device */
#define PATERR_NoTaskList	9	/* PATT_AddTask... or PATT_RemTask... was specified for a patch, */
					/* which had no PATT_CreateTaskList set */
#define PATERR_TaskListExists	10	/* PATT_CreateTaskList was specified, but there already exists a TaskList */
#define PATERR_InvalidTaskList	11	/* PATT_CreateTaskList was specified with a wrong parameter */
#define PATERR_PatchUnnamed	12	/* PATT_PatchName with GetPatch was specified, for a patch without an IDString */
#define PATERR_NoSemaphore	13	/* Could not allocate semaphore */

#define PATERR_KickTooOld	14	/* Kickstart version is too old for this function */
#define PATERR_InvalidPattern	15	/* Pattern passed via PATT_AddTaskPattern is not valid */
#define PATERR_Restricted	16	/* Certain tags/features may not be used when patching certain functions */

/*----------------------------------------------------------------------------*/
struct PatchNotifyMessage {
    struct Message pnm_ExecMessage;
    ULONG  pnm_Class;
    UWORD  pnm_Code;
    APTR   pnm_Object;
};

/*----------------------------------------------------------------------------*/
#define PATCHNOTIFY_CLASS	0x50000000
/*----------------------------------------------------------------------------*/
/*Notification codes (pnm_Code) (ignore messages with other codes): */
#define PATCOD_PatchInstalled	1	/* new patch has been added */
#define PATCOD_PatchRemoved	2	/* a patch has been removed */
#define PATCOD_PatchChanged	3	/* attributes of a patch have been changed */

/*----------------------------------------------------------------------------*/
struct PatchXResult {		/* Use PatchAlloc(PS_TYPE_XRESULT) to allocate this */
    struct Node pxr_Node;	/* Reserved */
    ULONG  pxr_RegPattern;	/* Which of the following register fields are used */
    ULONG  pxr_RegD0;
    ULONG  pxr_RegD1;
    ULONG  pxr_RegD2;
    ULONG  pxr_RegD3;
    ULONG  pxr_RegD4;
    ULONG  pxr_RegD5;
    ULONG  pxr_RegD6;
    ULONG  pxr_RegD7;
    ULONG  pxr_RegA0;
    ULONG  pxr_RegA1;
    ULONG  pxr_RegA2;
    ULONG  pxr_RegA3;
    ULONG  pxr_RegA4;
    ULONG  pxr_RegA5;
    ULONG  pxr_RegA6;
    UWORD  pxr_FlowControl;	/* What patches follow this one (see below) */
};
/*----------------------------------------------------------------------------*/
/* Valid values for pxr_FlowControl: */
#define PATFC_Normal	0	/* No change in the sequence of patchcodes */
#define PATFC_FallBack	1	/* Use original function (only valid, if PATT_Priority is NULL) */

/*----------------------------------------------------------------------------*/
/* Register definitions for the obsolete PATT_SaveRegisters and pxr_RegPattern */

#define PATREG_D0	0x8000
#define PATREG_D1	0x4000
#define PATREG_D2	0x2000
#define PATREG_D3	0x1000
#define PATREG_D4	0x0800
#define PATREG_D5	0x0400
#define PATREG_D6	0x0200
#define PATREG_D7	0x0100
#define PATREG_A0	0x0080
#define PATREG_A1	0x0040
#define PATREG_A2	0x0020
#define PATREG_A3	0x0010
#define PATREG_A4	0x0008
#define PATREG_A5	0x0004
#define PATREG_A6	0x0002

/*----------------------------------------------------------------------------*/
#define	PatchName "patch.library"
/*----------------------------------------------------------------------------*/




/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* The following structures are not needed by normal patch.library applications */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
struct PatchBase
{
	struct Library PB_LibNode;
	UBYTE PB_Flags;					/* see below */
	UBYTE PB_reserved1;
	ULONG PB_private1;
	struct SignalSemaphore	PB_Semaphore;		/* Semaphore to protect MasterPatchList */
	struct List		PB_MasterPatchHeader;	/* Listheader Structure for MasterPatch */

	/* ... */

};
/* PB_Flags: */

#define PBF_CheckPC	(1L<<0)	    	/* If TRUE: Enable safe removal of patches! */
					/* Patch.library will use a hack, which */
					/* is highly dependent on OS versions and installed */
					/* processors and may therefore not work with */
					/* certain configurations */
					/* It's unlikely to crash the machine though */
					/* New with V5, default: FALSE */
#define	PBF_PatchSetFuncActive (1L<<1)	/* If TRUE: A program redirects SetFunction() to patch.library */
					/* (older versions of PatchSetFunc do not set this bit) */
					/* New with V4, default: FALSE */
#define PBF_BreakForbid (1L<<2)		/* If TRUE: Break forbid and disable, when */
					/* trying to get the global semaphore */
					/* New with V6, default: FALSE */
#define PBF_NoStackAllocmem (1L<<3)	/* If TRUE: Do not call Allocmem for stack extension */
					/* New with V6, default: FALSE */

/*----------------------------------------------------------------------------*/
/* Before accessing this structure, make sure MPS_Node.ln_Type is PS_TYPE_MASTER */

struct MasterPatch			/* This structure is READONLY */
{
struct	Node	MPS_Node;		/* ln_Name may contain a pointer to the name of the patched library */
					/* To compensate the loss of a valid librarybase */
					/* ln_Name is now (V4) guaranteed to contain a valid name */
					/* This may however be a library, device or resource name */
	UWORD	MPS_Flags;		/* no public flags defined */
struct	MinList	MPS_PatchHeader;	/* Listheader Structure for Patch structures */
	APTR	MPS_Private01;		/* This pointer, up to V3 known as MPS_PatchedLibraryBase */
					/* has been renamed, because with the introduction of the */
					/* PatchSupervisor it may or may not contain a valid */
					/* librarybase, it may even contain 0. */
	WORD	MPS_PatchedLVO;		/* Library Vector Offset in patched library */

	/* ... */

};

/*----------------------------------------------------------------------------*/
/* Before accessing this structure, make sure PS_Node.ln_Type is either PS_TYPE_USER or PS_TYPE_SYSTEM */
/* Make sure your program can handle lists, that do not contain any nodes of */
/* PS_TYPE_USER or PS_TYPE_SYSTEM */

struct	Patch			/* This structure is READONLY */
{
struct	Node	PS_Node;	/* ln_Name may contain a pointer to the name of the patch */
	UWORD	PS_Flags;	/* no public flags defined */

	/* ... */

};

/*----------------------------------------------------------------------------*/
/* public types for patch and masterpatch structures: */
#define PS_TYPE_MASTER	1	/* node is MasterPatch structure */
#define PS_TYPE_USER	2	/* node was installed by an Application using the library interface */
#define PS_TYPE_SYSTEM	3	/* node was installed by the support program PatchSetFunc */
#define PS_TYPE_XRESULT	 30	/* this struct is an PatchXResult structure */



#endif	/* LIBRARIES_PATCH_H */
