home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / XMS.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  217 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. ** XMS.C
  5. **
  6. ** Routines to use Extended Memory from a DOS program.
  7. ** NOTE: Uses inline assembly language.
  8. **
  9. ** Released to the public domain by Cliff Rhodes with no guarantees
  10. ** of any kind.
  11. */
  12.  
  13. #include <dos.h>
  14.  
  15. #include "xms.h"
  16.  
  17. #define XMS_INT  0x002f     /* DOS Multiplex interrupt */
  18.  
  19. static int (_far * XMSDriver)(void);
  20.  
  21. static int initFlag = 0;
  22.  
  23. /*
  24. ** Verify that an Extended Memory Manager is installed.
  25. **
  26. ** Returns 1 if manager found, 0 if not.
  27. **
  28. ** NOTE: This function should be called before any other XMS function!
  29. */
  30.  
  31. int XMSinit(void)
  32. {
  33.       union REGS regs;
  34.       struct SREGS sregs;
  35.  
  36.       regs.x.ax = 0x4300;             /* Verify XMS manager present */
  37.       int86(XMS_INT, ®s, ®s);
  38.       if(regs.h.al == 0)
  39.             return 0;
  40.  
  41.       regs.x.ax = 0x4310;             /* Get XMS manager entry point */
  42.       int86x(XMS_INT, ®s, ®s, &sregs);
  43.  
  44.       /* Save entry point */
  45.  
  46.       XMSDriver = (int (_far *)(void)) MK_FP(sregs.es, regs.x.bx);
  47.  
  48.       return (initFlag = 1);
  49. }
  50.  
  51. /*
  52. ** Return version number of XMS driver, or 0 if not available.
  53. */
  54.  
  55. int XMSversion(void)
  56. {
  57.       if(!initFlag)
  58.             return 0;
  59.  
  60.       _asm mov ax, 0;
  61.  
  62.       return XMSDriver();
  63. }
  64.  
  65. /*
  66. ** Returns number of bytes available in largest free block.
  67. */
  68.  
  69. long  XMScoreleft(void)
  70. {
  71.       if(!initFlag)
  72.             return 0L;
  73.  
  74.       _asm mov ax, 0x0800;
  75.  
  76.       return 1024L * (long) XMSDriver();
  77. }
  78.  
  79. /*
  80. ** Attempts to allocate size bytes of extended memory.
  81. **
  82. ** Returns handle if successful, 0 if not.
  83. **
  84. ** NOTE: Actual size allocated will be the smallest multiple of 1024
  85. **       that is larger than size.
  86. */
  87.  
  88. unsigned int XMSalloc(long size)
  89. {
  90.       /* Get the number of 1024 byte units required by size. */
  91.  
  92.       int rval = (int) (size / 1024L);
  93.  
  94.       if(size % 1024L)
  95.             rval++;    /* Add a block for any excess */
  96.  
  97.       if(!initFlag)
  98.             return 0;
  99.  
  100.       _asm
  101.       {
  102.             mov dx, rval;
  103.             mov ax, 0x0900;
  104.       }
  105.  
  106.       if(XMSDriver())
  107.             _asm mov rval, dx;
  108.       else  rval = 0;
  109.  
  110.       return rval;
  111. }
  112.  
  113. /*
  114. ** Attempts to free extended memory referred to by handle. Returns 1
  115. ** if successful, 0 if not.
  116. */
  117.  
  118. int XMSfree(unsigned int handle)
  119. {
  120.       if(!initFlag)
  121.             return 0;
  122.  
  123.       _asm
  124.       {
  125.             mov dx, handle;
  126.             mov ax, 0x0a00;
  127.       }
  128.  
  129.       return XMSDriver();
  130. }
  131.  
  132. typedef struct {
  133.    long         nbytes;     /* Number of bytes to move */
  134.    unsigned int shandle;    /* Handle of source memory */
  135.    long         soffset;    /* Offset of source in handle's memory area */
  136.    unsigned int dhandle;    /* Handle of destination memory */
  137.    long         doffset;    /* Offset of destination in memory */
  138. } XMSRequestBlock;
  139.  
  140. static XMSRequestBlock bd;
  141.  
  142. static long XMSMove(long n)
  143. {
  144.       long rval;
  145.       unsigned int segm, offs;
  146.       XMSRequestBlock _far *fptr = (XMSRequestBlock _far *) &bd;
  147.  
  148.       if(!initFlag)
  149.             return 0L;
  150.  
  151.       bd.nbytes = n;
  152.  
  153.       offs = FP_OFF(fptr);
  154.       segm = FP_SEG(fptr);
  155.  
  156.       _asm
  157.       {
  158.             push ds;      /* Save DS */
  159.             mov ds, segm;
  160.             mov si, offs;
  161.             mov ax, 0x0b00;
  162.       }
  163.  
  164.       rval = (XMSDriver() == 0) ? 0L : n;
  165.  
  166.       _asm pop ds;    /* Restore DS since we changed it to make this call */
  167.  
  168.       return rval;
  169. }
  170.  
  171. /*
  172. ** Attempts to copy n bytes from srchandle to desthandle memory areas.
  173. ** Returns number of bytes copied, or 0 on error.
  174. */
  175.  
  176. long XMSmemcpy(unsigned int desthandle, long destoff,
  177.                unsigned int srchandle, long srcoff, long n)
  178. {
  179.       bd.shandle = srchandle;
  180.       bd.soffset = srcoff;
  181.       bd.dhandle = desthandle;
  182.       bd.doffset = destoff;
  183.  
  184.       return XMSMove(n);
  185. }
  186.  
  187. /*
  188. ** Attempts to copy n bytes from DOS src buffer to desthandle memory area.
  189. ** Returns number of bytes copied, or 0 on error.
  190. */
  191.  
  192. int DOStoXMSmove(unsigned int desthandle, long destoff,
  193.                  const char *src, int n)
  194. {
  195.       bd.shandle = 0;
  196.       bd.soffset = (long) ((char _far *) src);
  197.       bd.dhandle = desthandle;
  198.       bd.doffset = destoff;
  199.  
  200.       return (int) XMSMove((long) n);
  201. }
  202.  
  203. /*
  204. ** Attempts to copy n bytes to DOS dest buffer from srchandle memory area.
  205. ** Returns number of bytes copied, or 0 on error.
  206. */
  207.  
  208. int XMStoDOSmove(char *dest, unsigned int srchandle, long srcoff, int n)
  209. {
  210.       bd.shandle = srchandle;
  211.       bd.soffset = srcoff;
  212.       bd.dhandle = 0;
  213.       bd.doffset = (long) ((char _far *) dest);
  214.  
  215.       return (int) XMSMove((long) n);
  216. }
  217.