Commits

Palmer, 2E0EOL  committed 621ed68

No history available. We will track changes to dpcrtlmm manually,
due to filename changes etc.

  • Participants

Comments (0)

Files changed (52)

+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.

File DPCRTLMM.DSK

+Turbo C Context File 

File DPCRTLMM.PRJ

+Turbo C Project File 

File EXAMPLE1.DSK

+Turbo C Context File 

File EXAMPLE1.PRJ

+Turbo C Project File 

File EXAMPLE2.DSK

+Turbo C Context File 

File EXAMPLE2.PRJ

+Turbo C Project File 

File EXAMPLE3.DSK

+Turbo C Context File 

File EXAMPLE3.PRJ

+Turbo C Project File 
+Please read the documentation in the docs/ sub-directory.
+You will find a complete manual there.
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+#define DPCRTLMM_SOURCE
+
+/*
+  Main allocation function and block array grower
+*/
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef DPCRTLMM_WANTFARDATA
+# ifdef HAVE_ALLOC_H
+#  include <alloc.h>
+# endif /*HAVE_ALLOC_H*/
+#endif /*DPCRTLMM_WANTFARDATA*/
+
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h" /* General build parameters */
+#include "dpcrtlmm.h" /* Main library header */
+#include "intdata.h" /* Internal library data */
+#include "log.h" /* Main logging support */
+#include "vptrap.h" /* _VerifyPtrs() */
+#include "dbghooks.h" /* Debug hook executive and support functions */
+#include "biglock.h" /* Mutual exclusion */
+#include "alloc.h"
+/*-------------------------------------------------------------------------*/
+/* Internal functions (local) */
+
+static void OurLog(
+  const char * File,
+  const unsigned int Line,
+  const unsigned short Severity,
+  const char *Message
+);
+
+/*
+  Grow the array by 'GrowByElems' elements, returns FALSE if
+  it fails but then the original array is still valid and no
+  bigger.  Always make sure the array pointer is resolved, NULL
+  pointers are not acceptable and will be caught with assert()
+*/
+
+static unsigned int GrowBlockArray(
+  PS_DPCRTLMM_BLOCKDESCARRAY PCurrentBlockArray,
+  const unsigned int GrowByElems
+);
+
+#ifdef OURLOG /* Somebody else using OURLOG? */
+#  undef OURLOG /* Don't want their version */
+#endif /*OURLOG*/
+
+/* Do the same paranoid check for OURLOG_POS */
+#ifdef OURLOG_POS
+#  undef OURLOG_POS
+#endif /*OURLOG_POS*/
+
+/* Shortcut for typecast */
+#define OURLOG(f, l, sev, msg) \
+  OurLog((f), (l), ((const unsigned short)(sev)), (msg))
+
+#define OURLOG_POS(sev, msg) \
+  OURLOG(__FILE__, __LINE__, (sev), (msg))
+/*-------------------------------------------------------------------------*/
+void DPCRTLMM_FARDATA* dpcrtlmm_AllocEx(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const size_t NewBlockSize,
+  const char *File,
+  const unsigned int Line
+)
+{
+  /* Thread safe wrapper for AllocEx() */
+  void DPCRTLMM_FARDATA* ret;
+
+  LOCK
+  ret = dpcrtlmm_int_AllocEx(PBlockArray, NewBlockSize, File, Line);
+  UNLOCK
+
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+void DPCRTLMM_FARDATA* dpcrtlmm_int_AllocEx(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const size_t NewBlockSize,
+  const char *File,
+  const unsigned int Line
+)
+{
+  /* locals */
+  void DPCRTLMM_FARDATA* genBlockPtr; /* Generated block pointer */
+  char logMsg[MAX_TRAP_STRING_LENGTH + 1];
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  S_DPCRTLMM_DEBUGHOOKINFO debugHookInfo;
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+  PS_DPCRTLMM_BLOCKDESCARRAY PRArr = _ResolveArrayPtr(PBlockArray); /* Resolving is done because of a possible NULL */
+
+  _VerifyPtrs("Alloc()", PBlockArray, NULL); /* Haults program if array not valid, third arg is not applicable here */
+
+  sprintf(
+    logMsg,
+    "Program Requested to allocate %u byte block for array 0x%p",
+    (unsigned int)NewBlockSize,
+    (void*)PBlockArray
+  );
+  OURLOG(File, Line, DPCRTLMM_LOG_MESSAGE, logMsg);
+
+  genBlockPtr = DPCRTLMM_MALLOC(NewBlockSize); /* Allocate block */
+  if (!genBlockPtr) /* Out of memory? */
+  {
+    /* Use buffer for log messages, it's the same size as for traps */
+    sprintf(
+      logMsg,
+      "Attempt to allocate block of %u bytes for array at base 0x%p has failed",
+      (unsigned int)NewBlockSize,
+      (void*)PBlockArray
+    );
+    OURLOG(File, Line, DPCRTLMM_LOG_MESSAGE, logMsg); /* I haven't made this a warning because it can happen in a very legitimate situation where the caller may be prepared for a large allocation to handle */
+    return NULL; /* No pointer generated */
+  }
+
+  /* Now add the block to the array, first grow array */
+  if (!GrowBlockArray(PRArr, 1))
+  {
+    /* Attempt to enlarge the array failed? */
+    DPCRTLMM_FREE(genBlockPtr); /* Release the new block of memory */
+
+    sprintf(
+      logMsg,
+      "Attempt to enlarge array at base 0x%p by one element failed",
+      (void*)PBlockArray
+    );
+    /* This could be quite critical, if the memory manager is running our of space */
+    OURLOG_POS(DPCRTLMM_LOG_WARNING, logMsg);
+    return NULL; /* Give up */
+  }
+
+  /* Now the block's address can be added to the array */
+  PRArr->Descriptors[PRArr->Count-1].PBase = genBlockPtr; /* Put pointer to base of block in block descriptor in the array */
+  PRArr->Descriptors[PRArr->Count-1].Size = NewBlockSize; /* Save size so caller can find it out leter */
+
+  /* Version 1.1.4 changes, source file/line records */
+  PRArr->Descriptors[PRArr->Count-1].SourceLine = Line;
+  if ( File ) {
+    PRArr->Descriptors[PRArr->Count-1].SourceFile = (char*)malloc((strlen(File)+1)*sizeof(char));
+    if ( PRArr->Descriptors[PRArr->Count-1].SourceFile )
+      strcpy(PRArr->Descriptors[PRArr->Count-1].SourceFile, File);
+  }
+
+  /* Update library statistics */
+  dpcrtlmm_int__blockCount++;
+  dpcrtlmm_int__allocCharge += NewBlockSize;
+  /* Update peaks */
+  if ( dpcrtlmm_int__blockCount > dpcrtlmm_int__blockCountPeak )
+    dpcrtlmm_int__blockCountPeak = dpcrtlmm_int__blockCount;
+  if ( dpcrtlmm_int__allocCharge > dpcrtlmm_int__allocPeak )
+    dpcrtlmm_int__allocPeak = dpcrtlmm_int__allocCharge;
+
+  /* Call the debug hook executive */
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  memset(&debugHookInfo, 0, sizeof(S_DPCRTLMM_DEBUGHOOKINFO)); /* Init structure */
+  debugHookInfo.PRelArr = PRArr; /* Use resolved value, NULL means N/A, this is the only point at which the array pointer address is exposed to the caller directly (expect other debug hook calls of course) */
+  debugHookInfo.PRelDesc = genBlockPtr;
+  debugHookInfo.HookType = DPCRTLMM_HOOK_ALLOC;
+  debugHookInfo.AllocReq = (unsigned int)NewBlockSize;
+  debugHookInfo.Success = 1U; /* TRUE */
+  dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_ALLOC, &debugHookInfo);
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  return genBlockPtr; /* Give pointer to the caller */
+}
+/*-------------------------------------------------------------------------*/
+static unsigned int GrowBlockArray(
+  PS_DPCRTLMM_BLOCKDESCARRAY PCurrentBlockArray,
+  const unsigned int GrowByElems
+)
+{
+  PS_DPCRTLMM_BLOCKDESCRIPTOR ptr; /* Pointer to block descriptors during enlargement */
+  unsigned int oldCount; /* Count before enlargement */
+  unsigned int initi; /* Initialization interator */
+
+  #ifdef NDEBUG /* Not in debug mode? */
+    if (!PCurrentBlockArray) return 0U; /* Just get out indicating error before disaster */
+  #else /* Debug mode */
+    assert(PCurrentBlockArray);
+  #endif /*NDEBUG*/
+
+  if (!GrowByElems) /* Want to grow by nothing? */
+  {
+    OURLOG_POS(DPCRTLMM_LOG_WARNING, "Attempt to GrowBlockArray() by no items, ignored");
+    return 1U; /* Success, already this size, it's great when there's nothing to do isn't it, programmer's are lazy */
+  }
+
+  oldCount = PCurrentBlockArray->Count; /* Take count before we grow array */
+  ptr = DPCRTLMM_REALLOC( PCurrentBlockArray->Descriptors, (oldCount + GrowByElems) * sizeof(S_DPCRTLMM_BLOCKDESCRIPTOR) ); /* Grow array */
+  if (!ptr) /* Couldn't grow? */
+    return 0U; /* Fail */
+
+  /* Update array information */
+  PCurrentBlockArray->Count += GrowByElems;
+  PCurrentBlockArray->Descriptors = ptr; /* Possible relocation might mean the pointer to the descriptors may need updating, make it so */
+
+  for ( initi = oldCount; initi < PCurrentBlockArray->Count; initi++ ) /* All new descriptors in the array that we just created */
+  {
+    PCurrentBlockArray->Descriptors[initi].PBase = NULL; /* No block assigned to this new descriptor yet */
+    PCurrentBlockArray->Descriptors[initi].Size = (size_t)0U; /* Therefore no size either */
+    PCurrentBlockArray->Descriptors[initi].Flags = 0U; /* No flags set */
+    PCurrentBlockArray->Descriptors[initi].SourceLine = 0U; /* No source line allocation */
+    PCurrentBlockArray->Descriptors[initi].SourceFile = NULL; /* No known source file */
+  }
+  return 1U; /* Success */
+}
+/*-------------------------------------------------------------------------*/
+static void OurLog(
+  const char *File,
+  const unsigned int Line,
+  const unsigned short Severity,
+  const char *Str
+)
+{
+   /* Our job is to add "Alloc() to the start of the string, saves data space
+  if everybody in this module calls this instead of _Log() directly.
+  We can't use LOG() twice because the information will be put on different
+  lines so a copy is needed. */
+
+  if (Str && Str[0]) /* Valid string of at least on character sent to us? */
+  {
+    char* PcopyStr;
+    const char FuncName[] = "Alloc(): "; /* Prefix */
+
+    PcopyStr = (char*)malloc( sizeof(FuncName) + strlen(Str) ); /* Allocate space for copy, note that NULL termination is automatic because using sizeof() */
+    if (PcopyStr)
+    {
+      strcpy(PcopyStr, FuncName); /* Prepend prefix */
+      strcat(PcopyStr, Str); /* Add log string after the prefix */
+
+      dpcrtlmm_int_Log(File, Line, Severity, PcopyStr); /* Pass on to the normal logger */
+
+      free(PcopyStr); /* Copy can now be released */
+    }
+  }
+  return;
+}
+/*-------------------------------------------------------------------------*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef INC_DPCRTLMM_ALLOC_H
+#define INC_DPCRTLMM_ALLOC_H
+/*-------------------------------------------------------------------------*/
+#ifndef DPCRTLMM_SOURCE
+#  error ("This header is for internal library use only, include dpcrtlmm.h")
+#endif /*DPCRTLMM_SOURCE*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif /*__cplusplus*/
+
+void DPCRTLMM_FARDATA *dpcrtlmm_int_AllocEx(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const size_t NewBlockSize,
+  const char *File,
+  const unsigned int Line
+);
+
+#ifdef __cplusplus
+  }
+#endif /*__cplusplus*/
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_ALLOC_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+  Raw block descriptor flag modifiers : David Duncan Ross Palmer
+  Copyright 2000-2006 Daybo Logic, all rights reserved.
+  Now supports NULL arrays
+*/
+#define DPCRTLMM_SOURCE
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <stddef.h>
+#include <string.h> /* memset() */
+#include <stdio.h>
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h" /* General build parameters */
+#include "dpcrtlmm.h" /* Main library header */
+#include "intdata.h" /* Internal library data */
+#include "vptrap.h" /* _VerifyPtrs() (replaces BBA/BBP traps) */
+#include "iblkptr.h" /* For getting array descriptor index for a particular block */
+#include "dbghooks.h" /* The debug hook executive */
+#include "biglock.h" /* Library's mutual exclusion */
+#include "bdflags.h"
+/*-------------------------------------------------------------------------*/
+/*
+  NOTE: Adding of the hook caller in here has caused two variables
+  both holding the index of the block, this should be optimised away when
+  I can be bothered
+*/
+/*-------------------------------------------------------------------------*/
+unsigned char dpcrtlmm_ModifyDescriptorFlags(
+  const PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr,
+  const unsigned char *PNewFlags
+)
+{
+  unsigned char ret;
+
+  LOCK
+  ret = dpcrtlmm_int_ModifyDescriptorFlags(
+    PBlockArray,
+    Ptr,
+    PNewFlags
+  );
+  UNLOCK
+
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+unsigned char dpcrtlmm_int_ModifyDescriptorFlags(
+  const PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr,
+  const unsigned char *PNewFlags
+)
+{
+  /* locals */
+  const char funcName[] = "ModifyDescriptorFlags()"; /* Name of this function */
+  unsigned int blockIndex; /* Index of block descriptor into the array */
+  unsigned char oldFlags; /* Old flags, returned to caller */
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  S_DPCRTLMM_DEBUGHOOKINFO debugHookInfo;
+  unsigned int indexOfBlock;
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+  PS_DPCRTLMM_BLOCKDESCARRAY PRArr; /* Holds resolved pointer array */
+
+  /* Bah, this is a pain supporting this particular hook */
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  memset(&debugHookInfo, 0, sizeof(S_DPCRTLMM_DEBUGHOOKINFO));
+
+  debugHookInfo.PRelArr = _ResolveArrayPtr(PBlockArray);
+  indexOfBlock = dpcrtlmm_int_IndexFromBlockPtr(PBlockArray, Ptr);
+  /* Looked up the right descriptor to suit hook requirements */
+  debugHookInfo.PRelDesc = &_ResolveArrayPtr(PBlockArray)->Descriptors[indexOfBlock];
+  debugHookInfo.HookType = DPCRTLMM_HOOK_MODIFYDESCFLAGS;
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  _VerifyPtrs(funcName, PBlockArray, Ptr); /* Make sure invalid pointers don't get past here */
+
+  PRArr = _ResolveArrayPtr(PBlockArray); /* Makes NULL goto &_defaultArray */
+  blockIndex = _IndexFromBlockPtr(PRArr, Ptr); /* Get the index */
+  oldFlags = PRArr->Descriptors[blockIndex].Flags; /* Save current flags */
+  if (PNewFlags) /* Caller passed new flags */
+    PRArr->Descriptors[blockIndex].Flags = *PNewFlags; /* Modify the flags */
+
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  debugHookInfo.Success = 1U;
+  debugHookInfo.Misc0 = (unsigned long)oldFlags;
+  debugHookInfo.Misc1 = (unsigned long)( (PNewFlags) ? (*PNewFlags) : (oldFlags) );
+  dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_MODIFYDESCFLAGS, &debugHookInfo);
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  return oldFlags; /* Give the old flags back to the caller */
+}
+/*-------------------------------------------------------------------------*/
+
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef INC_DPCRTLMM_BDFLAGS_H
+#define INC_DPCRTLMM_BDFLAGS_H
+/*-------------------------------------------------------------------------*/
+#ifndef DPCRTLMM_SOURCE
+#  error ("bdflags.h is for internal DPCRTLMM use")
+#endif
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+unsigned char dpcrtlmm_int_ModifyDescriptorFlags(
+  const PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr,
+  const unsigned char *PNewFlags
+);
+
+#ifdef __cplusplus
+  }
+#endif
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_BDFLAGS_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DPCRTLMM_SOURCE
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+
+#ifndef _RECURSIVE
+# define _RECURSIVE
+#endif /*!_RECURSIVE*/
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif /*!_GNU_SOURCE*/
+
+#include <stdio.h>
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h"
+#include "dpcrtlmm.h"
+#include "biglock.h"
+
+#ifdef DPCRTLMM_THREADS
+
+#ifdef DPCRTLMM_THREADS_PTHREAD
+#  ifndef DPCRTLMM_THREADS_PTHREAD_NP
+#    pragma message "Threads on POSIX configured as max portabillty doesn't support recursion, required for DPCRTLMM access from user callbacks.  Callbacks have the power to deadlock a thread"
+#  endif /*!DPCRTLMM_THREADS_PTHREAD_NP*/
+#endif /*DPCRTLMM_THREADS_PTHREAD*/
+
+#if defined(DPCRTLMM_THREADS_NT)
+#  include <windows.h>
+#elif defined(DPCRTLMM_THREADS_PTH)
+#  include <pth.h>
+#elif defined(DPCRTLMM_THREADS_PTHREAD)
+#  include <errno.h>
+#  include <pthread.h>
+#endif
+
+/*
+  Sometimes configure tells us we have non-portable functions available
+  but the macro PTHREAD_MUTEX_RECURSIVE_NP is not really available at
+  all.  If that is the case, revoke what configure set up for us
+*/
+#ifdef DPCRTLMM_THREADS_PTHREAD
+#  ifdef DPCRTLMM_THREADS_PTHREAD_NP
+#    ifndef PTHREAD_MUTEX_RECURSIVE_NP
+#      undef DPCRTLMM_THREADS_PTHREAD_NP
+#    endif /*!PTHREAD_MUTEX_RECURSIVE_NP*/
+#  endif /*DPCRTLMM_THREADS_PTHREAD_NP*/
+#endif /*DPCRTLMM_THREADS_PTHREAD*/
+/*--------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_THREADS_NT
+
+#  define Mutant CRITICAL_SECTION
+#  define InitialiseMutant(x) InitializeCriticalSection((x))
+#  define LockMutant(x) EnterCriticalSection((x))
+#  define UnlockMutant(x) LeaveCriticalSection((x))
+#  define DestroyMutant(x) DeleteCriticalSection((x))
+
+#elif defined(DPCRTLMM_THREADS_PTH)
+
+#  define Mutant pth_mutex_t
+#  define InitialiseMutant(x) pth_mutex_init((x))
+#  define LockMutant(x) pth_mutex_acquire((x), (0), (NULL))
+#  define UnlockMutant(x) pth_mutex_release((x))
+#  define DestroyMutant(x) pth_mutex_init((x))
+
+#elif defined(DPCRTLMM_THREADS_PTHREAD)
+
+#  define Mutant pthread_mutex_t
+#  ifdef DPCRTLMM_THREADS_PTHREAD_NP /* Supporting non-portable extension? */
+#    define InitialiseMutant(x) InitNPMutant((x))
+#  else
+#    define InitialiseMutant(x) pthread_mutex_init((x), NULL)
+#  endif /*DPCRTLMM_MAXPORT*/
+#  define LockMutant(x) pthread_mutex_lock((x))
+#  define UnlockMutant(x) pthread_mutex_unlock((x))
+#  define DestroyMutant(x) pthread_mutex_destroy((x))
+
+#endif /*DPCRTLMM_THREADS_NT*/
+/*--------------------------------------------------------------------------*/
+static Mutant bigLock;
+
+#ifdef DPCRTLMM_THREADS_PTHREAD
+#  ifdef DPCRTLMM_THREADS_PTHREAD_NP
+    void InitNPMutant(pthread_mutex_t* PMutant);
+#  endif /*DPCRTLMM_THREADS_PTHREAD_NP*/
+#endif /*DPCRTLMM_THREADS_PTHREAD*/
+/*--------------------------------------------------------------------------*/
+void dpcrtlmm_int_BigLockInit()
+{
+  InitialiseMutant(&bigLock);
+}
+/*--------------------------------------------------------------------------*/
+void dpcrtlmm_int_BigLockUninit()
+{
+  DestroyMutant(&bigLock);
+}
+/*--------------------------------------------------------------------------*/
+void dpcrtlmm_int_BigLock(int LockState)
+{
+  if ( LockState )
+    LockMutant(&bigLock);
+  else
+    UnlockMutant(&bigLock);
+}
+/*--------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_THREADS_PTHREAD
+#ifdef DPCRTLMM_THREADS_PTHREAD_NP
+void InitNPMutant(pthread_mutex_t* PMutant)
+{
+  pthread_mutexattr_t attributes;
+
+  pthread_mutexattr_init(&attributes);
+  pthread_mutexattr_setkind_np(&attributes, PTHREAD_MUTEX_RECURSIVE_NP);
+  pthread_mutex_init(PMutant, &attributes);
+  pthread_mutexattr_destroy(&attributes);
+}
+#endif /*DPCRTLMM_THREADS_PTHREAD_NP*/
+#endif /*DPCRTLMM_THREADS_PTHREAD*/
+/*--------------------------------------------------------------------------*/
+#else /* !DPCRTLMM_THREADS -- Threads not required */
+  char dpcrtlmm_int_BigLockDummyVar; /* Need at least one external to comply with ANSI */
+#endif /*DPCRTLMM_THREADS*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef INC_DPCRTLMM_BIGLOCK_H
+#define INC_DPCRTLMM_BIGLOCK_H
+/*-------------------------------------------------------------------------*/
+#ifndef DPCRTLMM_SOURCE
+#  error ("biglock is for internal library use")
+#endif
+
+#ifdef DPCRTLMM_THREADS
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+void dpcrtlmm_int_BigLockInit(void);
+void dpcrtlmm_int_BigLockUninit(void);
+void dpcrtlmm_int_BigLock(int LockState);
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /*DPCRTLMM_THREADS*/
+
+#ifdef DPCRTLMM_THREADS
+#  define LOCK dpcrtlmm_int_BigLock(1);
+#  define UNLOCK dpcrtlmm_int_BigLock(0);
+#else
+#  define LOCK
+#  define UNLOCK
+#endif /*DPCRTLMM_THREADS*/
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_BIGLOCK_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+#############################################################################
+# Block array creation and destruction functions                            #
+# Normally each module or section of a program will make it's own array     #
+# using the functions herin, if it is too much hastle (because of cleaning  #
+# up each module) or the program wants to hide behind a normal allocation   #
+# function re-routed to us via a hack then only one block array exists per  #
+# per program.                                                              #
+# 24/11/2001 (DDRP): Attention, block arrays need to start supporting file/ #
+# line info soon.
+#############################################################################
+*/
+
+#define DPCRTLMM_SOURCE
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h> /* memset() */
+
+#ifdef DPCRTLMM_WANTFARDATA
+# ifdef HAVE_ALLOC_H
+#  include <alloc.h>
+# endif /*HAVE_ALLOC_H*/
+#endif /*DPCRTLMM_WANTFARDATA*/
+
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h" /* General build parameters */
+#include "dpcrtlmm.h" /* Main library header */
+#include "intdata.h" /* Access to internal data */
+#include "log.h" /* LOG macro */
+#include "trap.h" /* Trap() */
+#include "safelist.h" /* Safety list support functions */
+#include "dbghooks.h" /* For the debug hook executive */
+#include "biglock.h" /* For total library mutual exclusion */
+#include "blkarray.h"
+/*-------------------------------------------------------------------------*/
+static PS_DPCRTLMM_BLOCKDESCARRAY dpcrtlmm_int_CreateBlockArray(void);
+static unsigned int dpcrtlmm_int_IsDefaultBlockArray(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray
+);
+/*-------------------------------------------------------------------------*/
+PS_DPCRTLMM_BLOCKDESCARRAY dpcrtlmm_CreateBlockArray()
+{
+  /* Thread safe wrapper for CreateBlockArray() */
+  PS_DPCRTLMM_BLOCKDESCARRAY ret;
+
+  LOCK
+  ret = dpcrtlmm_int_CreateBlockArray();
+  UNLOCK
+
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+void dpcrtlmm_DestroyBlockArray(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray
+)
+{
+  /* Thread safe wrapper for DestroyBlockArray() */
+
+  LOCK
+  dpcrtlmm_int_DestroyBlockArray(PBlockArray);
+  UNLOCK
+}
+/*-------------------------------------------------------------------------*/
+unsigned int dpcrtlmm_IsDefaultBlockArray(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray
+)
+{
+  /* Thread safe wrapper for IsDefaultBlockArray() */
+
+  unsigned int ret;
+
+  LOCK
+  ret = dpcrtlmm_int_IsDefaultBlockArray(PBlockArray);
+  UNLOCK
+
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+static PS_DPCRTLMM_BLOCKDESCARRAY dpcrtlmm_int_CreateBlockArray()
+{
+  PS_DPCRTLMM_BLOCKDESCARRAY Parray; /* Pointer for caller */
+  #ifdef DPCRTLMM_LOG
+  char logMsg[MAX_TRAP_STRING_LENGTH+1];
+  #endif /*DPCRTLMM_LOG*/
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  S_DPCRTLMM_DEBUGHOOKINFO debugHookInfo;
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  /* Init debug hook info */
+  memset(&debugHookInfo, 0, sizeof(S_DPCRTLMM_DEBUGHOOKINFO));
+  debugHookInfo.HookType = DPCRTLMM_HOOK_CREATEBLOCKARRAY;
+  /* Ha, this is only vaugely relevant, this will do */
+  debugHookInfo.AllocReq = (unsigned int)sizeof(S_DPCRTLMM_BLOCKDESCARRAY);
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  /*
+    Alloc the array for the caller
+  */
+  Parray = (S_DPCRTLMM_BLOCKDESCARRAY*)malloc( sizeof(S_DPCRTLMM_BLOCKDESCARRAY) );
+  if (!Parray) /* Failed to alloc */
+  {
+    /* Memory outages while in memory manager mode must be warned about! */
+    WARNING("CreateBlockArray(): Couldn\'t allocate the new block array!");
+    #ifdef DPCRTLMM_DEBUGHOOKS
+    /* PRelArr is nothing, we couldn't allocate one :( */
+    /* PRelDesc is nothing, there is no related descriptor */
+    debugHookInfo.Success = 0U; /* Ahh, no failure! */
+    /* The rest are reserved or not used */
+    dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_CREATEBLOCKARRAY, &debugHookInfo);   /* Call the debug hook executive */
+    #endif /*DPCRTLMM_DEBUGHOOKS*/
+    return Parray; /* Give the NULL pointer back to the caller */
+  }
+  Parray->Count = 0U; /* No descriptors in list */
+  Parray->Descriptors = NULL; /* Nothing in block list */
+
+  /* The array base must be added to the list of acceptable arrays,
+     (the so called safety list)
+  */
+  if ( !SafetyList_AddBase(Parray) ) /* Add to safety list */
+  {
+    /* Failed to add to the list?!  Memory outages while in memory manager must be warned about */
+    WARNING("CreateBlockArray(): The array base address could not be added to the safety list");
+    DPCRTLMM_FREE(Parray); /* Free the array again */
+    Parray = NULL; /* So caller sees there's nothing allocated */
+  }
+
+  #ifdef DPCRTLMM_LOG
+  /* Safe, log progress */
+  sprintf(logMsg, "CreateBlockArray() returns base 0x%p", (void*)Parray);
+  MESSAGE(__FILE__, __LINE__, logMsg);
+  #endif /*DPCRTLMM_LOG*/
+
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  /* Set up more hook information to indicate success */
+  debugHookInfo.PRelArr = Parray; /* The relavant array in this case is the one allocated */
+  debugHookInfo.Success = 1U; /* Yay, success! */
+  dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_CREATEBLOCKARRAY, &debugHookInfo);   /* Call the debug hook executive */
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+  return Parray; /* Give new pointer to the caller */
+}
+/*-------------------------------------------------------------------------*/
+void dpcrtlmm_int_DestroyBlockArray( PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray )
+{
+  /* locals */
+  unsigned int sli; /* Safety list loop processing */
+  char trapStr[MAX_TRAP_STRING_LENGTH+1]; /* Sometimes used for creating trap strings */
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  S_DPCRTLMM_DEBUGHOOKINFO debugHookInfo; /* Used for calling the debug hook executive */
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  /* Set up common stuff for the debug hook info */
+  debugHookInfo.PRelArr = _ResolveArrayPtr(PBlockArray);
+  /* There is no relavent descriptor */
+  debugHookInfo.HookType = DPCRTLMM_HOOK_DESTROYBLOCKARRAY;
+  /* There is no allocation request */
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  for ( sli = 0U; sli < DPCRTLMM_SAFETYLIST_MAXSIZE; sli++ ) /* For all the possible items in the safety list */
+  {
+    if (_safetyList[sli]) /* Is this entry used? */
+    {
+      if (_safetyList[sli] == PBlockArray) /* Pointer match! */
+      {
+        if (_safetyList[sli]->Count) /* Any descriptors remaining? */
+        {
+          unsigned long totBytes = 0UL;
+          unsigned int li;
+
+          for ( li = 0; li < _safetyList[sli]->Count; li++ ) /* All blocks */
+          {
+            totBytes += _safetyList[sli]->Descriptors[li].Size; /* Add size of block to total */
+          }
+
+          sprintf(
+            trapStr,
+            "DestroyBlockArray(): %u blocks of memory not freed from array based at 0x%p\n                      Total bytes leakage for this array: %lu",
+            _safetyList[sli]->Count,
+            (void*)_safetyList[sli],
+            totBytes
+          );
+          Trap(DPCRTLMM_TRAP_UNFREED_BLOCKS, trapStr);
+        }
+        if (_safetyList[sli]->Descriptors) /* Descriptors not zero? */
+        {
+          sprintf(
+            trapStr,
+            "DestroyBlockArray(): Base of raw descriptor array not freed!\n0x%p->0x%p (PBlockArray->Descriptors must be NULL)",
+            (void*)_safetyList[sli],
+            (void*)_safetyList[sli]->Descriptors
+          );
+          Trap(DPCRTLMM_TRAP_BASENONZERO, trapStr);
+        }
+        DPCRTLMM_FREE(_safetyList[sli]); /* BUG FIX: Forgot to release the memory for the array block pointer */
+        _safetyList[sli] = NULL; /* Remove this array from the safety list */
+        #ifdef DPCRTLMM_LOG
+        sprintf(
+          trapStr,
+          "DestroyBlockArray(): The array at base 0x%p was destroyed",
+          (void*)PBlockArray
+        ); /* Prepare log message */
+        MESSAGE(__FILE__, __LINE__, trapStr);
+        #endif /*DPCRTLMM_LOG*/
+
+        #ifdef DPCRTLMM_DEBUGHOOKS
+        /* Success, call hooks */
+        debugHookInfo.Success = 1U; /* Wicked! */
+        dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_DESTROYBLOCKARRAY, &debugHookInfo);
+        #endif /*DPCRTLMM_DEBUGHOOKS*/
+        return; /* Exit to caller */
+      }
+    }
+  }
+  /* Entire list processed, array base specified not found */
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  /* Call hooks */
+  debugHookInfo.Success = 0U; /* Failed */
+  dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_DESTROYBLOCKARRAY, &debugHookInfo);
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+  /* Fire trap */
+  sprintf(
+    trapStr,
+    "DestroyBlockArray(): Attempt to destroy unknown array (0x%p)!\n",
+    (void*)PBlockArray
+  );
+  Trap(DPCRTLMM_TRAP_BAD_BLOCK_ARRAY, trapStr);
+  return;
+}
+/*-------------------------------------------------------------------------*/
+static unsigned int dpcrtlmm_int_IsDefaultBlockArray( PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray )
+{
+  #ifdef DPCRTLMM_NONULL_BLOCKDESCARRAY
+  return 0; /* Default (NULL) array does not exist */
+  #else
+  if (!PBlockArray || PBlockArray == &_defaultArray)
+    return 1U; /* TRUE */
+  return 0U; /* FALSE */
+  #endif
+}
+/*-------------------------------------------------------------------------*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef INC_DPCRTLMM_BLKARRAY_H
+#define INC_DPCRTLMM_BLKARRAY_H
+/*-------------------------------------------------------------------------*/
+#ifndef DPCRTLMM_SOURCE
+# error ("Use DPCRTLMM.H not seperate, internal headers")
+#endif /*DPCRTLMM_SOURCE*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+void dpcrtlmm_int_DestroyBlockArray(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray
+);
+
+#ifdef __cplusplus
+  }
+#endif
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_BLKARRAY_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+  Module for handling memory block lock flags,
+  written by Overlord David Duncan Ross Palmer
+  Copyright (C)2000-2006 Daybo Logic, all rights reserved.
+  Creation: 22nd Feb 2000
+  Last modified: 23rd Feb 2006
+*/
+
+#define DPCRTLMM_SOURCE
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <stddef.h>
+#include <stdio.h>
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h" /* General build parameters */
+#include "dpcrtlmm.h" /* The main library header */
+#include "biglock.h" /* Mutual exclusion */
+#include "bdflags.h" /* Need this to get around the lock */
+#include "bloclock.h"
+/*-------------------------------------------------------------------------*/
+void dpcrtlmm_SetBlockLockingFlag(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr,
+  const unsigned int NewStatus
+)
+{
+  LOCK
+  dpcrtlmm_int_SetBlockLockingFlag(PBlockArray, Ptr, NewStatus);
+  UNLOCK
+}
+/*-------------------------------------------------------------------------*/
+unsigned int dpcrtlmm_IsBlockLocked(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr
+)
+{
+  unsigned int ret;
+
+  LOCK
+  ret = dpcrtlmm_int_IsBlockLocked(PBlockArray, Ptr);
+  UNLOCK
+
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+void dpcrtlmm_ToggleBlockLockingStatus(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr
+)
+{
+  LOCK
+  dpcrtlmm_int_ToggleBlockLockingStatus(PBlockArray, Ptr);
+  UNLOCK
+}
+/*-------------------------------------------------------------------------*/
+void dpcrtlmm_int_SetBlockLockingFlag(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr,
+  const unsigned int NewStatus
+)
+{
+  unsigned char flags;
+
+  /* Get current flags */
+  flags = dpcrtlmm_int_ModifyDescriptorFlags(PBlockArray, Ptr, NULL);
+  if (NewStatus) /* Locking? */
+    flags |= 1; /* Set lock bit */
+  else /* Unlocking? */
+    flags |= ~1; /* Clear lock bit */
+
+  /* Set the new flags */
+  dpcrtlmm_int_ModifyDescriptorFlags(PBlockArray, Ptr, &flags);
+  return; /* That was simple enough, I can drink some water now */
+}
+/*-------------------------------------------------------------------------*/
+unsigned int dpcrtlmm_int_IsBlockLocked(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr
+)
+{
+  unsigned char flags;
+
+  /* Get the flags for the descriptor */
+  flags = dpcrtlmm_int_ModifyDescriptorFlags(PBlockArray, Ptr, NULL);
+  if ( ((flags & 1) == 1) ) /* The lock bit is set? */
+    return 1U; /* Yes, the block is locked */
+  return 0U; /* No, the block is not locked */
+}
+/*-------------------------------------------------------------------------*/
+void dpcrtlmm_int_ToggleBlockLockingStatus(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr
+)
+{
+  /* Get current status */
+  unsigned int oldLockStat = dpcrtlmm_int_IsBlockLocked(PBlockArray, Ptr);
+  /* Set locking state as NOT current locking state */
+  dpcrtlmm_int_SetBlockLockingFlag(PBlockArray, Ptr, !oldLockStat);
+}
+/*-------------------------------------------------------------------------*/
+
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef INC_DPCRTLMM_BLOCLOCK_H
+#define INC_DPCRTLMM_BLOCLOCK_H
+/*-------------------------------------------------------------------------*/
+#ifdef __cplusplus
+  extern "C" {
+#endif /*__cplusplus*/
+
+#ifndef DPCRTLMM_SOURCE
+#  error ("This header is not for you")
+#endif /*DPCRTLMM_SOURCE*/
+
+void dpcrtlmm_int_SetBlockLockingFlag(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr,
+  const unsigned int NewStatus
+);
+
+unsigned int dpcrtlmm_int_IsBlockLocked(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr
+);
+
+void dpcrtlmm_int_ToggleBlockLockingStatus(
+  PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray,
+  const void DPCRTLMM_FARDATA *Ptr
+);
+
+#ifdef __cplusplus
+  }
+#endif /*__cplusplus*/
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_BLOCLOCK_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+The build header is used to add some more sense to the user options in
+config.h.  Note: Don't directly edit build.h or config.h, build.h is
+readonly and is included by the library, config.h is dynamically written
+by the config program and included in this file.
+
+
+3rd Mar 2000 - Overlord Added DPCRTLMM_SAFETYLIST_MAXSIZE
+13th May 2000 - Overlord removed hack SDYNMEN_WANT_IGNORANCE, doesn't apply
+                since removal of dependancies to other libs (most notibly
+                synmem of course). Sorry this doesn't mean anything to
+                programmers outside of Daybo Logic. ignore.
+14th June 2000 - Overlord Added DPCRTLMM_FARDATA to allow explicit far data
+19th July 2000 - Overlord added a macro to disallow NULL as a special built-in
+                 BLOCKDESCARRAY, the macro is called
+                 DPCRTLMM_NONULL_BLOCKDESCARRAY, find the define in this file &
+                 uncomment it to restore old behaviour.
+21st July 2000 - Overlord added check for DPCRTLMM_SOURCE to try to stop users
+                 making the mistake of including this in their programs.
+25th July 2000 - Overlord added DPCRTLMM_STDBLOCKLIMIT for free versions
+17th Nov 2000 - Overlord stripped all stuff to do with limiting and pricing
+                and the like in preparation for GPL release.
+24th May 2001 - Overlord refined versioning system, 1.2 goes down to 1.1.4 due
+                to DPCRTLMM_VERSION_PATCH.
+9th June 2001 - Overlord took most options out and made them the responsibillty
+                of the config program and config.h
+*/
+
+#ifndef INC_DPCRTLMM_BUILD_H
+#define INC_DPCRTLMM_BUILD_H
+/*
+  Below follows a non-user configuration ...
+*/
+/*-------------------------------------------------------------------------*/
+/* Try to prevent users including this header */
+#ifndef DPCRTLMM_SOURCE
+#error this header is not intended for use outside of the library
+#endif /*!DPCRTLMM_SOURCE*/
+
+/* Definition of MAX_TRAP_STRING_LENGTH (change if trap/log strings are
+        getting too long*/
+
+#ifdef MAX_TRAP_STRING_LENGTH /* Somebody else is using the macro we want? */
+#  undef MAX_TRAP_STRING_LENGTH
+#endif /*MAX_TRAP_STRING_LENGTH*/
+
+#define MAX_TRAP_STRING_LENGTH (191) /* Maximum length of a trap string (excluding space for NULL terminator) - NOT USER CONFIGURABLE*/
+
+/* To allow explicit far data pointers which are
+non-ANSI, configure with configure --enable-fardata */
+
+#ifndef __FLAT__ /* Segmented */
+#  ifdef DPCRTLMM_WANTFARDATA
+#    define DPCRTLMM_FARDATA far /* Non-ANSI, avoid if possible */
+#    define DPCRTLMM_MALLOC farmalloc
+#    define DPCRTLMM_REALLOC farrealloc
+#    define DPCRTLMM_CALLOC farcalloc
+#    define DPCRTLMM_FREE farfree
+#  else
+#    define DPCRTLMM_FARDATA
+#    define DPCRTLMM_MALLOC malloc
+#    define DPCRTLMM_REALLOC realloc
+#    define DPCRTLMM_CALLOC calloc
+#    define DPCRTLMM_FREE free
+#  endif /*DPCRTLMM_WANTFARDATA*/
+#else /* Flat */
+#  define DPCRTLMM_FARDATA
+#  define DPCRTLMM_MALLOC malloc
+#  define DPCRTLMM_REALLOC realloc
+#  define DPCRTLMM_CALLOC calloc
+#  define DPCRTLMM_FREE free
+#endif /*!__FLAT__*/
+
+/* Library version information can be set here */
+#define DPCRTLMM_VERSION_MAJOR (1)
+#define DPCRTLMM_VERSION_MINOR (2)
+#define DPCRTLMM_VERSION_PATCH (0)
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_BUILD_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DPCRTLMM_SOURCE
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h" /* General build parameters */
+#include "dpcrtlmm.h" /* Main library header */
+#include "intdata.h" /* Internal library data */
+#include "log.h" /* Main logging support */
+#include "iblkptr.h" /* dpcrtlmm_int_IndexFromBlockPtr() */
+#include "dbghooks.h" /* Debug hook executive */
+#include "biglock.h" /* For entire library mutual exclusion */
+#include "alloc.h" /* Allows us to call AllocEx(), bipassing the big lock */
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_LOG
+static void OurLog(
+  const char *File,
+  const unsigned int Line,
+  const unsigned short Severity,
+  const char *Str
+);
+#endif /*DPCRTLMM_LOG*/
+
+#ifdef OURLOG /* Somebody else using OURLOG? */
+#  undef OURLOG /* Don't want their version */
+#endif /*OURLOG*/
+
+#define OURLOG(f, l, sev, msg) OurLog((f), (l), ((const unsigned short)(sev)), (msg))
+static void DPCRTLMM_FARDATA* dpcrtlmm_int_CallocEx(PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray, const unsigned int N, const size_t NewBlockSize, const char* File, const unsigned int Line);
+/*-------------------------------------------------------------------------*/
+void DPCRTLMM_FARDATA* dpcrtlmm_CallocEx(PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray, const unsigned int N, const size_t NewBlockSize, const char* File, const unsigned int Line)
+{
+  void DPCRTLMM_FARDATA* ret;
+
+  LOCK
+  ret = dpcrtlmm_int_CallocEx(PBlockArray, N, NewBlockSize, File, Line);
+  UNLOCK
+
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+static void DPCRTLMM_FARDATA* dpcrtlmm_int_CallocEx(PS_DPCRTLMM_BLOCKDESCARRAY PBlockArray, const unsigned int N, const size_t NewBlockSize, const char* File, const unsigned int Line)
+{
+  void DPCRTLMM_FARDATA* resultantPtr;
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  S_DPCRTLMM_DEBUGHOOKINFO debugHookInfo;
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+  #ifdef DPCRTLMM_LOG
+  char logMsg[MAX_TRAP_STRING_LENGTH+1];
+  #endif /*DPCRTLMM_LOG*/
+
+  #ifdef DPCRTLMM_LOG
+  sprintf(
+    logMsg,
+    "Calloc() called, %u blocks of %u bytes requested, "
+    "passing on to Alloc()",
+    N,
+    (unsigned int)NewBlockSize
+  );
+  OURLOG(File, Line, DPCRTLMM_LOG_MESSAGE, logMsg);
+  #endif /*DPCRTLMM_LOG*/
+
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  debugHookInfo.PRelArr = _ResolveArrayPtr(PBlockArray);
+  debugHookInfo.HookType = DPCRTLMM_HOOK_CALLOC;
+  debugHookInfo.AllocReq = (N*NewBlockSize);
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+  resultantPtr = dpcrtlmm_int_AllocEx( PBlockArray, (N*NewBlockSize), File, Line); /* Call Alloc() */
+  if (resultantPtr)
+  {
+    #ifdef DPCRTLMM_DEBUGHOOKS
+    /* Ahh damn it, I'll have to look up the descriptor for this block */
+    unsigned int blkIndex = dpcrtlmm_int_IndexFromBlockPtr(PBlockArray, resultantPtr);
+    debugHookInfo.PRelDesc = &_ResolveArrayPtr(PBlockArray)->Descriptors[blkIndex];
+    debugHookInfo.Success = 1U;
+    #endif /*DPCRTLMM_DEBUGHOOKS*/
+
+    #ifdef DPCRTLMM_LOG
+    OURLOG(File, Line, DPCRTLMM_LOG_MESSAGE, "Allocation successful");
+    #endif /*DPCRTLMM_LOG*/
+
+    /* Bug fix: I didn't realize this but the specification for for calloc()
+       requires that the new memory is zeroed. Fix DPCRTLMM Version 1.1.2 or 1.1.3 */
+    memset(resultantPtr, 0, N*NewBlockSize);
+  }
+  else
+  {
+    #ifdef DPCRTLMM_DEBUGHOOKS
+    /*blockDescArray.Success = 0U;   - optimized away */
+    #endif /*DPCRTLMM_DEBUGHOOKS*/
+    #ifdef DPCRTLMM_LOG
+    OURLOG(File, Line, DPCRTLMM_LOG_MESSAGE, "Allocation failed");
+    #endif /*DPCRTLMM_LOG*/
+  }
+
+  #ifdef DPCRTLMM_DEBUGHOOKS
+  dpcrtlmm_int_CallDebugHook(DPCRTLMM_HOOK_CALLOC, &debugHookInfo);
+  #endif /*DPCRTLMM_DEBUGHOOKS*/
+  return resultantPtr;
+}
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_LOG
+static void OurLog(const char* File, const unsigned int Line, const unsigned short Severity, const char* Str)
+{
+  /* Our job is to add "Calloc() to the start of the string, saves data space
+  if everybody in this module calls this instead of _Log() directly.
+  We can't call _Log() twice because the information will be put on different
+  lines so a copy is needed. */
+
+  if (Str && Str[0]) /* Valid string of at least on character sent to us? */
+  {
+    char* PcopyStr;
+    const char FuncName[] = "Calloc(): "; /* Prefix */
+
+    PcopyStr = (char*)malloc( sizeof(FuncName) + strlen(Str) ); /* Allocate space for copy.  Note that NULL termination is automatic because using sizeof() */
+    if (PcopyStr)
+    {
+      strcpy(PcopyStr, FuncName); /* Prepend prefix */
+      strcat(PcopyStr, Str); /* Add log string after the prefix */
+
+      dpcrtlmm_int_Log(File, Line, Severity, PcopyStr); /* Pass on to the normal logger */
+
+      free(PcopyStr); /* Copy can now be released */
+    }
+  }
+  return;
+}
+#endif /*DPCRTLMM_LOG*/
+/*-------------------------------------------------------------------------*/
+/* config.h specifically crafted for Turbo C++ */
+
+#define DPCRTLMM_SAFETYLIST_MAXSIZE (64)
+#define DPCRTLMM_DEV_ERROR stderr
+#define DPCRTLMM_HOOKCHAIN_SIZE (32)
+#define DPCRTLMM_DEBUGHOOKS
+#define __NO_NAMESPACES__
+#define DPCRTLMM_WANTFARDATA /* Get rid of this if your code won't compile */
+#define HAVE_ALLOC_H
+
+typedef unsigned int bool;
+#define false (0)
+#define true (!(false))
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+  The debug hook executive and supporting code
+  written (and perfomed by David Duncan Ross Palmer.
+
+  File DBGHOOKS.C
+  Library: DPCRTLMM Memory Manager
+  Date of creation: 24th February 2000
+  Last modified: 21st February 2006 by David Duncan Ross Palmer
+*/
+
+#define DPCRTLMM_SOURCE
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#ifdef DPCRTLMM_HDRSTOP
+#  pragma hdrstop
+#endif /*DPCRTLMM_HDRSTOP*/
+
+#include "build.h" /* General build parameters */
+#include "dpcrtlmm.h" /* Main library header */
+#include "intdata.h" /* Internal library data */
+#include "log.h" /* LOG macro */
+#include "biglock.h" /* Mutual exclusion */
+#include "dbghooks.h"
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+
+static unsigned int BadHookType(
+  const unsigned int HookType
+);
+
+static unsigned int dpcrtlmm_int_InstallDebugHook(
+  const unsigned short HookType,
+  unsigned int(*NewHookProc)(PS_DPCRTLMM_DEBUGHOOKINFO)
+);
+
+static unsigned int dpcrtlmm_int_GetDebugHookChainCount(
+  const unsigned int HookType
+);
+
+static unsigned int dpcrtlmm_int_GetDebugHookMatrixCount(
+  void
+);
+
+static unsigned int dpcrtlmm_int_UninstallDebugHook(
+  const unsigned short HookType,
+  unsigned int(*HookProc2Remove)(PS_DPCRTLMM_DEBUGHOOKINFO)
+);
+
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+unsigned int dpcrtlmm_InstallDebugHook(
+  const unsigned short HookType,
+  unsigned int(*NewHookProc)(PS_DPCRTLMM_DEBUGHOOKINFO)
+)
+{
+  unsigned int ret;
+
+  LOCK
+  ret = dpcrtlmm_int_InstallDebugHook(HookType, NewHookProc);
+  UNLOCK
+
+  return ret;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+unsigned int dpcrtlmm_GetDebugHookChainCount(
+  const unsigned int HookType
+)
+{
+  unsigned int ret;
+
+  LOCK
+  ret = dpcrtlmm_int_GetDebugHookChainCount(HookType);
+  UNLOCK
+
+  return ret;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+unsigned int dpcrtlmm_GetDebugHookMatrixCount()
+{
+  unsigned int ret;
+
+  LOCK
+  ret = dpcrtlmm_int_GetDebugHookMatrixCount();
+  UNLOCK
+
+  return ret;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+unsigned int dpcrtlmm_UninstallDebugHook(
+  const unsigned short HookType,
+  unsigned int(*HookProc2Remove)(PS_DPCRTLMM_DEBUGHOOKINFO)
+)
+{
+  unsigned int ret;
+
+  LOCK
+  ret = dpcrtlmm_int_UninstallDebugHook(HookType, HookProc2Remove);
+  UNLOCK
+
+  return ret;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+void dpcrtlmm_int_InitDebugHookMatrix()
+{
+  /* Initialize or clear the debug hook matrix */
+  unsigned int chainI; /* Used during initialization of chains loop */
+
+  for ( chainI = 0U; chainI < DPCRTLMM_HOOKCHAIN_SIZE; chainI++ )
+  {
+    unsigned int hookTypeI; /* Nested loop to process chains for other hook types */
+
+    for ( hookTypeI = 0U; hookTypeI < DPCRTLMM_DEBUGHOOK_LASTHOOK+1; hookTypeI++ )
+    {
+      unsigned int (*NULLHookPtr)(PS_DPCRTLMM_DEBUGHOOKINFO) = NULL; /* Make NULL pointer */
+
+      dpcrtlmm_int__debugHookMatrix[(size_t)chainI][(size_t)hookTypeI] = NULLHookPtr; /* Init element */
+    }
+  }
+  return;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+void dpcrtlmm_int_CallDebugHook(
+  const unsigned short HookType,
+  const PS_DPCRTLMM_DEBUGHOOKINFO PDebugHookInfo
+)
+{
+  /* locals */
+  S_DPCRTLMM_DEBUGHOOKINFO debugHookInfo; /* Local copy of caller's stuff */
+  unsigned int allHooksLoop; /* Used to control processing of all the hooks loop */
+
+  /* We must copy the debug hook information from the caller so that hook
+  functions may change information before it is passed on to the next hook
+  function, if they so desire, without damanging the person who called the
+  trap executive (incase they use the original pointers somehow), though I
+  can't think how they can offhand, still... */
+
+  if (BadHookType(HookType)) /* Bad hook type (out of range in matrix) */
+  {
+    ERROR("CallDebugHook: Internal library error, HookType out of range!");
+    return;
+  }
+
+  debugHookInfo = *PDebugHookInfo; /* Copy details by auto C deref */
+
+  for ( allHooksLoop = 0U; allHooksLoop < DPCRTLMM_HOOKCHAIN_SIZE; allHooksLoop++ ) { /* All viable hook locations in the chain */
+    unsigned int (*HookProc)(PS_DPCRTLMM_DEBUGHOOKINFO) = _debugHookMatrix[allHooksLoop][HookType]; /* Get hook function pointer from chain */
+
+    if ( !HookProc ) /* No hook info */
+      continue; /* Move onto next hook pointer */
+
+    if ( !HookProc(&debugHookInfo) ) /* Call hook procedure */
+      break; /* Hook requested not to pass information onto following hooks */
+  }
+  return; /* All hook calls are done */
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+static unsigned int dpcrtlmm_int_InstallDebugHook(
+  const unsigned short HookType,
+  unsigned int(*NewHookProc)(PS_DPCRTLMM_DEBUGHOOKINFO)
+)
+{
+  /* This function has added support for DPCRTLMM_HOOK_ALL */
+  unsigned int i; /* looping */
+  unsigned int set = 0U; /* set = FALSE */
+
+  if (HookType != DPCRTLMM_HOOK_ALL) /* Specific hook, not general hook */
+  {
+    if (BadHookType(HookType)) return 0U; /* Ensure hook type is valid */
+    /* Find the first free entry in the chain */
+    for ( i = 0U; i < DPCRTLMM_HOOKCHAIN_SIZE; i++ )
+    {
+      if ( !_debugHookMatrix[i][HookType] ) /* Found free entry? */
+      {
+        _debugHookMatrix[i][HookType] = NewHookProc; /* Install hook proc */
+        set = 1U; /* Remember at least one hook was installed: set 'set' TRUE */
+        break; /* Don't keep looping */
+      }
+    }
+  }
+  else /* General hook that wants everything! */
+  {
+    unsigned short nextHook;
+
+    for ( nextHook = (unsigned short)0x0000U; nextHook < DPCRTLMM_DEBUGHOOK_LASTHOOK; nextHook++ ) { /* Go through all valid hook types */
+      if ( !dpcrtlmm_InstallDebugHook(nextHook, NewHookProc) ) { /* Call ourselves back to sort it out */
+        /* Failed to install a hook? */
+        dpcrtlmm_UninstallDebugHook(DPCRTLMM_HOOK_ALL, NewHookProc); /* Remove all of the hooks which are for this address */
+        return 0U; /* Report failure for the whole lot, FALSE return */
+      }
+      set = 1U; /* Report success, in a while */
+    }
+  }
+
+  return set; /* No space for handler */
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+static unsigned int dpcrtlmm_int_GetDebugHookChainCount(
+  const unsigned int HookType
+)
+{
+  unsigned int i;
+  unsigned total = 0U;
+
+  if (!BadHookType(HookType))
+  {
+    for ( i = 0U; i < DPCRTLMM_HOOKCHAIN_SIZE; i++ ) /* All hook positions */
+    {
+      if ( _debugHookMatrix[i][HookType] ) /* Hook installed at this point in the chain? */
+        total++; /* Increment count */
+    }
+  }
+  return total;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+static unsigned int dpcrtlmm_int_GetDebugHookMatrixCount(void)
+{
+  unsigned int i;
+  unsigned total = 0U;
+
+  for ( i = 0U; i <= DPCRTLMM_DEBUGHOOK_LASTHOOK; i++ ) /* All types of hooks */
+    total += dpcrtlmm_int_GetDebugHookChainCount(i); /* Add chain contents to total for all chains */
+
+  return total; /* Give total to caller */
+}
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+static unsigned int dpcrtlmm_int_UninstallDebugHook(
+  const unsigned short HookType,
+  unsigned int(*HookProc2Remove)(PS_DPCRTLMM_DEBUGHOOKINFO)
+)
+{
+  /* This function has added support for DPCRTLMM_HOOK_ALL */
+
+  unsigned int i;
+  unsigned int retStatus = 0U; /* Return status FALSE by default */
+
+  if (HookType != DPCRTLMM_HOOK_ALL) /* Specific hook type request */
+  {
+    if (BadHookType(HookType)) return 0U;
+
+    for ( i = 0U; i < DPCRTLMM_DEBUGHOOK_LASTHOOK; i++ ) { /* Process all entries in the chain */
+      if ( _debugHookMatrix[i][HookType] == HookProc2Remove ) { /* Found entry */
+        retStatus = 1U; /* We found it! Return TRUE */
+        _debugHookMatrix[i][HookType] = NULL; /* Delete address of hook proc */
+        /* Not breaking the loop so we can remove duplicates too, say for
+        example the user installed the same hook proc twice for the same type */
+      }
+    }
+  }
+  else { /* HookType is general */
+    unsigned short si; /* Used for loop */
+    retStatus = 1U; /* We always say success */
+
+    for (si = (unsigned short)(0x0000U); si <= DPCRTLMM_DEBUGHOOK_LASTHOOK; si++) /* All possible debug hook types */
+      dpcrtlmm_UninstallDebugHook(si, HookProc2Remove); /* Uninstall this hook from this type */
+  }
+
+  return retStatus; /* Give status to caller */
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+#ifdef DPCRTLMM_DEBUGHOOKS
+static unsigned int BadHookType(const unsigned int HookType)
+{
+  unsigned int bad = 0U; /* Not a bad hook type yet... */
+
+#ifndef NDEBUG_ /* Debugging lib */
+    assert( HookType <= DPCRTLMM_DEBUGHOOK_LASTHOOK ); /* Check hook type is valid */
+  #else /* Not in debug mode, must handle this same trap differenty */
+    if ( !(HookType <= DPCRTLMM_DEBUGHOOK_LASTHOOK) ) /* Check hook type is valid */
+      bad = 1U; /* bad = TRUE */
+  #endif /*!NDEBUG*/
+
+  return bad;
+}
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+/*-------------------------------------------------------------------------*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+  Header for the debug hook executive and support code
+*/
+
+#ifndef INC_DPCRTLMM_DBGHOOKS_H
+#define INC_DPCRTLMM_DBGHOOKS_H
+/*-------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif /*__cplusplus*/
+
+#ifndef DPCRTLMM_SOURCE
+#  error ("Internal library users only!")  // <-- See Overlord DDRP
+#endif /*!DPCRTLMM_SOURCE*/
+
+#ifdef DPCRTLMM_DEBUGHOOKS
+
+void dpcrtlmm_int_InitDebugHookMatrix(void); /* Call to clear all pointers in the matrix */
+
+/* Debug hook executive, caller must prepare information according to the
+rules first. */
+void dpcrtlmm_int_CallDebugHook(
+  const unsigned short HookType,
+  const PS_DPCRTLMM_DEBUGHOOKINFO PDebugHookInfo
+);
+
+/*
+  For user mode functions declrs:
+  dpcrtlmm_InstallDebugHook(),
+  dpcrtlmm_GetDebugHookChainCount(),
+  dpcrtlmm_GetDebugHookMatrixCount() &
+  dpcrtlmm_UninstallDebugHook()
+                                   
+  look in the public header dpcrtlmm.h.
+*/
+
+#endif /*DPCRTLMM_DEBUGHOOKS*/
+
+#ifdef INC_DPCRTLMM_INTDATA_H
+#  define _InitDebugHookMatrix dpcrtlmm_int_InitDebugHookMatrix
+#  define _CallHook dpcrtlmm_int_CallHook
+#endif /*INC_DPCRTLMM_INTDATA_H*/
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif /*__cplusplus*/
+/*-------------------------------------------------------------------------*/
+#endif /*!INC_DPCRTLMM_DBGHOOKS_H*/
+/*
+Daybo Logic C RTL Memory Manager
+Copyright (c) 2000-2006, David Duncan Ross Palmer, Daybo Logic
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+      
+    * Neither the name of the Daybo Logic nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// DPCRTLMM 1.2 compatible encapsulation object for C++
+// Add this file to your C++ project
+// You can have this particular module it's free
+// Last modification: Dec 2000
+// I'm not going to use new style C++ casts, I want this module to port
+// to compilers pre-ANSI/ISO C++
+// If you have any warnings mail them to me at Overlord@DayboLogic.co.uk
+// but please make sure it's the full compiler output with compiler name
+// and version.
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /*HAVE_CONFIG_H*/
+#include <stddef.h> /* For NULL */
+#include <stdio.h>
+#ifdef DPCRTLMM_HDRSTOP // Same as in library source
+#  pragma hdrstop
+#endif //DPCRTLMM_HDRSTOP
+
+#include "dpcrtlmm.h" // Library header
+#include "dpccap.h" // Class definitions
+
+#ifndef __NO_NAMESPACES__
+Overlord::
+#endif
+TDPCRTLMM_MemManager MemManager;
+//----------------------------------------------------------------------------
+// Overlord::TDPCRTLMM_MemManager
+
+// Constructor, starts DPCRTLMM
+#ifndef __NO_NAMESPACES__
+Overlord::
+#endif
+TDPCRTLMM_MemManager::TDPCRTLMM_MemManager()
+  : firstAccess(1)
+{
+}
+//----------------------------------------------------------------------------
+// Destructor, shuts down DPCRTLMM
+#ifndef __NO_NAMESPACES__
+Overlord::
+#endif
+TDPCRTLMM_MemManager::~TDPCRTLMM_MemManager()
+{
+  if ( this->firstAccess == 0 ) { /* Has been accessed/started? */
+    dpcrtlmm_Shutdown();
+    this->firstAccess = 1;
+  }
+}
+//----------------------------------------------------------------------------
+// Explicit startup function
+void
+#ifndef __NO_NAMESPACES__