home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / utils / amd-udi / udi / realcopy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  4.6 KB  |  144 lines

  1. /************************************************************************/
  2. /*    Copyright (C) 1986-1991 Phar Lap Software, Inc.            */
  3. /*    Unpublished - rights reserved under the Copyright Laws of the    */
  4. /*    United States.  Use, duplication, or disclosure by the         */
  5. /*    Government is subject to restrictions as set forth in         */
  6. /*    subparagraph (c)(1)(ii) of the Rights in Technical Data and     */
  7. /*    Computer Software clause at 252.227-7013.            */
  8. /*    Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138    */
  9. /************************************************************************/
  10. /* REALCOPY.C:  copy real mode code to conventional memory */
  11.  
  12. /*
  13.  * The routine in this file allocates conventional memory and copies
  14.  * real mode code to it.
  15.  */
  16. #include <stdio.h>
  17. #include <pltypes.h>
  18. #include <pharlap.h>
  19.  
  20. realcopy(start_offs, end_offs, real_basep, prot_basep, rmem_adrp)
  21. ULONG    start_offs;
  22. ULONG    end_offs;
  23. REALPTR    *real_basep;
  24. FARPTR    *prot_basep;
  25. USHORT    *rmem_adrp;
  26.  
  27. /*
  28. Description:
  29.     This routine allocates conventional memory for the specified block
  30.     of code (which must be within the first 64K of the protected mode
  31.     program segment) and copies the code to it.
  32.  
  33.     The caller should free up the conventional memory block when it
  34.     is done with the conventional memory.
  35.  
  36.     NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER.
  37.  
  38. Calling arguments:
  39.     start_offs    start of real mode code in program segment
  40.     end_offs    1 byte past end of real mode code in program segment
  41.     real_basep    returned;  real mode ptr to use as a base for the
  42.                 real mode code (eg, to get the real mode FAR
  43.                 addr of a function foo(), take
  44.                 real_basep + (ULONG) foo).
  45.                 This pointer is constructed such that
  46.                 offsets within the real mode segment are
  47.                 the same as the link-time offsets in the
  48.                 protected mode program segment
  49.     prot_basep    returned;  prot mode ptr to use as a base for getting
  50.                 to the conventional memory, also constructed
  51.                 so that adding the prot mode offset of a
  52.                 function or variable to the base gets you a 
  53.                 ptr to the function or variable in the 
  54.                 conventional memory block.
  55.     rmem_adrp    returned;  real mode para addr of allocated 
  56.                 conventional memory block, to be used to free
  57.                 up the conventional memory when done.  DO NOT
  58.                 USE THIS TO CONSTRUCT A REAL MODE PTR, USE
  59.                 REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT
  60.                 CORRECTLY. 
  61.  
  62. Returned values:
  63.     TRUE        if error
  64.     FALSE        if success
  65. */
  66. {
  67.     ULONG    rm_base;    /* base real mode para addr for accessing */
  68.                     /* allocated conventional memory */
  69.     UCHAR    *sp;        /* source pointer for copy */
  70.     FARPTR    dp;        /* destination pointer for copy */
  71.     ULONG    len;        /* number of bytes to copy */
  72.     ULONG    temp;
  73.     USHORT    stemp;
  74.  
  75. /*
  76.  * First check for valid inputs
  77.  */
  78.      if (start_offs >= end_offs || end_offs > 0x10000)
  79.     {
  80.         return TRUE;
  81.     }
  82.  
  83. /*
  84.  * Round start_offs down to a paragraph (16-byte) boundary so we can set up
  85.  * the real mode pointer easily.
  86.  */
  87.      start_offs &= ~15;
  88.  
  89. /*
  90.  * Allocate the conventional memory for our real mode code.  Remember to
  91.  * round byte count UP to 16-byte paragraph size.  We alloc it
  92.  * above the DOS data buffer so both the DOS data buffer and the appl
  93.  * conventional mem block can still be resized.
  94.  *
  95.  * First just try to alloc it;  if we can't get it, shrink the appl mem
  96.  * block down to the minimum, try to alloc the memory again, then grow the
  97.  * appl mem block back to the maximum.  (Don't try to shrink the DOS data 
  98.  * buffer to free conventional memory;  it wouldn't be good for this routine 
  99.  * to have the possible side effect of making file I/O run slower.)
  100.  */
  101.     len = ((end_offs - start_offs) + 15) >> 4; 
  102.     if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
  103.     {
  104.         if (_dx_cmem_usage(0, FALSE, &temp, &temp) != _DOSE_NONE)
  105.         {
  106.             return TRUE;
  107.         }
  108.         if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
  109.             *rmem_adrp = 0;
  110.         if (_dx_cmem_usage(0, TRUE, &temp, &temp) != _DOSE_NONE)
  111.         {
  112.             if (*rmem_adrp != 0)
  113.                 _dx_real_free(*rmem_adrp);
  114.             return TRUE;
  115.         }
  116.         if (*rmem_adrp == 0)
  117.         {
  118.             return TRUE;
  119.         }
  120.     }
  121.  
  122. /*
  123.  * Construct real mode & protected mode pointers to access the allocated 
  124.  * memory.  Note we know start_offs is aligned on a paragraph (16-byte) 
  125.  * boundary, because we rounded it down.
  126.  *
  127.  * We make the offsets come out rights by backing off the real mode selector
  128.  * by start_offs.
  129.  */
  130.     rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4);
  131.      RP_SET(*real_basep, 0, rm_base);
  132.     FP_SET(*prot_basep, rm_base << 4, SS_DOSMEM);
  133.  
  134. /*
  135.  * Copy the real mode code to the allocated memory
  136.  */
  137.      sp = (UCHAR *) start_offs;
  138.     dp = *prot_basep + start_offs; 
  139.     len = end_offs - start_offs; 
  140.     while (len-- > 0)
  141.         *dp++ = *sp++;
  142.      return FALSE;
  143. }
  144.