/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_o_o|\\ Copyright (c) 1989 The Software Distillery.                    *
* |. o.| ||          All Rights Reserved                                  *
* | .  | ||          Written by Doug Walker                               *
* | o  | ||          The Software Distillery                              *
* |  . |//           235 Trillingham Lane                                 *
* ======             Cary, NC 27513                                       *
*                    BBS:(919)-471-6436                                   *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>

#define MWDEBUG
#include "memwatch.h"

#ifdef AllocMem
#undef AllocMem
#endif

#ifdef FreeMem
#undef FreeMem
#endif

#if 0
/* Change this to #if 1 if you want debug msgs from the memlib */
/* routines themselves for some reason - djw                   */
#define BUG(a) printf a ;
#endif

#define MSG(fh, msg) Write(fh, msg, strlen(msg))

#define MWT_CHIP 0
#define MWT_FAST 1

struct MWGlobal
{
   LONG flags;          /* Various MWF_ flags, see below                */
   LONG num[2];         /* Current number of allocations, chip and fast */
   LONG sum[2];         /* Current amount allocated, chip and fast      */
   LONG max[2];         /* Max amount allocated, chip and fast          */
   LONG lim[2];         /* Limit on allocations, chip and fast          */
   BPTR dbfh;           /* File to send debug output to                 */
   struct MWAlc *first; /* List of active memory allocations            */
   struct MWAlc *freed; /* List of free memory extents                  */
   struct MWAlc *lfree; /* Last allocation freed with free()            */
   struct Task *task;   /* Pointer to owning task's Task structure      */
};

struct MWMsg
{
   struct Message msgpart;    /* Linkage                  */
   int type;                  /* MWM_ types - see defines */
   int interval;              /* Interval to check        */
   struct MWGlobal *mwg;      /* Our global mem struct    */
};

struct MWAlc
{
   struct MWAlc *next;  /* Next memory block in chain           */
   LONG size;           /* Size of allocation in bytes          */
   LONG flags;          /* MEMF_ Flags memory was allocated with*/
   LONG myflags;        /* my flags, see defines below          */
   char *file;          /* Filename containing allocation point */
   LONG line;           /* Line number of allocation            */
   char *ffile;         /* Filename of free point               */
   char *fline;         /* Line number of free point            */
   char header[4];      /* Header sentinal                      */
   char memory[4];      /* Actual allocation comes here         */
                        /* 4 extra bytes covers trailer sentinal*/
};

/* Defines for use with MWAlc.myflags */
/* if myflags&MWF_REPMASK == MWF_REPORTED,   */
/* This alloc already reported as trashed    */
/* Use multiple bits in case the 'myflags'   */
/* are trashed, odds are better of detecting */
/* If we ever need more myflag bits, just    */
/* define MWF_REPMASK not to include them    */

#define MWF_REPORTED 0xaa55aa55
#define MWF_REPMASK  0xffffffff

#define MWHEADER     "MWHD"  /* Beginning sentinal                       */
#define MWTRAILER    "MWTR"  /* Trailing sentinal                        */

#define MWATRASH     0xaa  /* Trash allocated memory with this           */
#define MWFTRASH     0x55  /* Trash freed memory with this               */

/* Message types to external memory debugger                             */
#define MWM_CONTROL  0x00000000 /* MWII-type message                     */
#define MWM_INIT     0x00000001 /* Install new global struct             */
#define MWM_TERM     0x00000002 /* Remove old global struct              */
#define MWM_KILLME   0x00000003 /* An error has occurred; hold my task   */
#define MWM_BURY     0x00000004 /* Return the killed task                */
#define MWM_RESET    0x00000005 /* Restart everything, forget current    */
#define MWM_CONTINUE 0x00000006 /* Revive the killed task                */

#define MWM_REPLY    0x00001000 /* Reply to msg if set (except KILLME)   */

/* Message type return codes, returned in msg->type                      */
#define MWM_OK       0x00010000 /* OK                                    */
#define MWM_FULL     0x00020000 /* Table full, couldn't add              */
#define MWM_INVALID  0x00030000 /* Unspecified error                     */
#define MWM_NONE     0x00040000 /* MWM_BURY sent, no process killed      */
#define MWM_BADCMD   0x00050000 /* Unrecognized msg type                 */

#define MWPORTNAME   "MWIII_Port"

int MWSend   MWARGS((int));
void MWHold  MWARGS((void));
void MWPurge MWARGS((void));
void MWPanic MWARGS((char *));
void MWPrint MWARGS((struct MWAlc *, int, LONG, LONG));

