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

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. ** EMS.C
  5. **
  6. ** Expanded Memory Functions
  7. **
  8. ** Released to the public domain by Cliff Rhodes with no guarantees
  9. ** of any kind.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <dos.h>
  14.  
  15. #include "ems.h"       
  16.  
  17. /* EMS driver values */
  18. #define EMS_ID      "EMMXXXX0" /* EMS identifier string */
  19. #define EMS_INT     0x67       /* EMS interrupt number */
  20. #define EMS_VERSION 0x32       /* Version 3.2 of EMS */
  21.  
  22. /* EMS service codes */
  23. #define EMSservice1  0x40    /* Get EMS status */
  24. #define EMSservice2  0x41    /* Get segment address of page 0 */
  25. #define EMSservice3  0x42    /* Get total number of expanded pages */
  26. #define EMSservice4  0x43    /* Get handle and assign pages to it */
  27. #define EMSservice5  0x44    /* Map a page into one of the page frames */
  28. #define EMSservice6  0x45    /* Close EMS handle */
  29. #define EMSservice7  0x46    /* Get the EMS version number */
  30.  
  31.  
  32. /*
  33. ** Determines if EMS present. If so returns base segment of EMS.
  34. ** Returns 0 if EMS not available. The base segment is necessary
  35. ** for mapping EMS memory pages into the user address space (see
  36. ** EMSmap() below).
  37. */
  38.  
  39. unsigned int EMSbaseaddress(void)
  40. {
  41.       static const char tag[] = EMS_ID;
  42.  
  43.       char far      *p;
  44.       int           i;
  45.       union REGS    regs;
  46.       struct SREGS  segs;
  47.  
  48.       regs.h.ah = 0x35;
  49.       regs.h.al = EMS_INT;
  50.       int86x(0x21, ®s, ®s, &segs);
  51.  
  52.       p = (char far *) (MK_FP(segs.es, 10)); /* EMS_ID must be at offset 10 */
  53.  
  54.       for(i = 0; i < 8; i++)
  55.       {
  56.             if(tag[i] != p[i])
  57.                   return 0;                  /* If EMS_ID not found, return */
  58.       }
  59.  
  60.       regs.h.ah = EMSservice2;               /* Get page frame segment */
  61.       int86(EMS_INT, ®s, ®s);
  62.  
  63.       return regs.h.ah ? 0 : (unsigned int) regs.x.bx;
  64. }
  65.  
  66. /*
  67. ** Returns current EMS version, -1 if not found or obsolete
  68. */
  69.  
  70. int EMSversion(void)
  71. {
  72.       union REGS regs;
  73.  
  74.       regs.h.ah = EMSservice7;
  75.       int86(EMS_INT, ®s, ®s);
  76.  
  77.       if(!regs.h.ah && regs.h.al >= EMS_VERSION)  /* Make sure at least 3.2 */
  78.             return regs.x.ax;
  79.  
  80.       return -1;
  81. }
  82.  
  83. /*
  84. ** Returns 0 if EMS system OK, -1 if not
  85. */
  86.  
  87. int  EMSstatus(void)
  88. {
  89.       union REGS regs;
  90.  
  91.       regs.h.ah = EMSservice1;
  92.       int86(EMS_INT, ®s, ®s);
  93.  
  94.       return regs.h.ah ? -1 : 0;
  95. }
  96.  
  97. /*
  98. ** Returns number of free EMS pages (each page is 16k), -1 if error
  99. */
  100.  
  101. int EMSpages(void)
  102. {
  103.       union REGS  regs;
  104.  
  105.       regs.h.ah = EMSservice3;
  106.       int86(EMS_INT, ®s, ®s);
  107.  
  108.       return regs.h.ah ? -1 : (int) regs.x.bx;
  109. }
  110.  
  111. /*
  112. ** Returns handle to block of size pages or -1 if error.
  113. ** NOTE: always free any handles when you are done!.
  114. */
  115.  
  116. int EMSalloc(int pages)
  117. {
  118.       union REGS regs;
  119.  
  120.       regs.h.ah = EMSservice4;
  121.       regs.x.bx = pages;
  122.       int86(EMS_INT, ®s, ®s);
  123.  
  124.       return regs.h.ah ? -1 : (int) regs.x.dx;
  125. }
  126.  
  127. /*
  128. ** Frees handle block, returns 0 if successful, -1 if error
  129. */
  130.  
  131. int EMSfree(int handle)
  132. {
  133.       union REGS regs;
  134.  
  135.       regs.h.ah = EMSservice6;
  136.       regs.x.dx = handle;
  137.       int86(EMS_INT, ®s, ®s);
  138.  
  139.       return regs.h.ah ? -1 : 0;
  140. }
  141.  
  142. /*
  143. ** Maps page of handle into bank. Returns 0 if successful, -1 if error.
  144. ** Each handle controls 1 or more 16k pages of EMS memory.
  145. ** There are four banks 0-3. bank 0 starts at the segment returned by
  146. ** EMSbaseaddress(), bank 1 starts at that segment with offset 16k, etc.
  147. */
  148.  
  149. int  EMSmap(int bank, int handle, int page)
  150. {
  151.       union REGS regs;
  152.  
  153.       regs.h.ah = EMSservice5;
  154.       regs.h.al = bank;
  155.       regs.x.bx = page;
  156.       regs.x.dx = handle;
  157.       int86(EMS_INT, ®s, ®s);
  158.  
  159.       return regs.h.ah ? -1 : 0;
  160. }
  161.