home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / djgpp / go32 / valloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-30  |  5.2 KB  |  245 lines

  1. /* This is file VALLOC.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* History:126,1 */
  16.  
  17. #include <stdio.h>
  18. #include <dos.h>
  19.  
  20. #include "build.h"
  21. #include "types.h"
  22. #include "valloc.h"
  23. #include "xms.h"
  24. #include "mono.h"
  25.  
  26. #define VA_FREE    0
  27. #define VA_USED    1
  28.  
  29. int valloc_initted = 0;
  30. static word8 map[4096];
  31. word16 mem_avail, mem_used;
  32. static word16 left_lo, left_hi;
  33.  
  34. static unsigned pn_lo_first, pn_lo_last, pn_hi_first, pn_hi_last;
  35.  
  36. extern int debug_mode;
  37.  
  38. #if TOPLINEINFO
  39. valloc_update_status()
  40. {
  41.   char buf[20];
  42.   int i;
  43. #if 0
  44.   if (!debug_mode)
  45.     return;
  46. #endif
  47.   if (!valloc_initted)
  48.     return;
  49.   sprintf(buf, "%5dk", mem_avail);
  50.   for (i=0; i<6; i++)
  51.     poke(screen_seg, (i+70)*2, buf[i] | 0x0a00);
  52.   sprintf(buf, "%5dk", mem_used);
  53.   for (i=0; i<6; i++)
  54.     poke(screen_seg, (i+62)*2, buf[i] | 0x0a00);
  55. }
  56. #endif
  57.  
  58. static void vset(unsigned i, int b)
  59. {
  60.   unsigned o, m;
  61.   o = i>>3;
  62.   m = 1<<(i&7);
  63.   if (b)
  64.   {
  65.     if (!(map[o] & m))
  66.     {
  67. #if TOPLINEINFO
  68.       mem_avail -= 4;
  69.       mem_used += 4;
  70.       valloc_update_status();
  71. #endif
  72.       map[o] |= m;
  73.     }
  74.   }
  75.   else
  76.   {
  77.     if (map[o] & m)
  78.     {
  79. #if TOPLINEINFO
  80.       mem_avail += 4;
  81.       mem_used -= 4;
  82.       valloc_update_status();
  83. #endif
  84.       map[o] &= ~m;
  85.     }
  86.   }
  87. }
  88.  
  89. static int vtest(unsigned i)
  90. {
  91.   unsigned o, m;
  92.   o = i>>3;
  93.   m = 1<<(i&7);
  94.   return map[o] & m;
  95. }
  96.  
  97.  
  98. emb_handle_t emb_handle;
  99.  
  100. void
  101. xms_free(void) {
  102.     if(xms_installed()) {
  103.         xms_unlock_emb(emb_handle);
  104.         xms_emb_free(emb_handle);
  105. #if DEBUGGER
  106.     printf("XMS memory freed\n");
  107. #endif
  108.     }
  109. }
  110.  
  111. void
  112. xms_alloc_init(void) {
  113.     xms_extended_info *x = xms_query_extended_memory();
  114.     emb_off_t linear_base;
  115.     emb_size_K_t emb_size;
  116. #if DEBUGGER
  117.     printf("XMS driver detected\n");
  118. #endif
  119.     emb_size = x->max_free_block;
  120.     emb_handle = xms_emb_allocate(emb_size);
  121.     linear_base = xms_lock_emb(emb_handle);
  122.     pn_hi_first = (linear_base + 4095)/4096;
  123.     pn_hi_last = pn_hi_first + emb_size / 4 - 1;
  124. }
  125.  
  126.  
  127. static valloc_init()
  128. {
  129.   unsigned char far *vdisk;
  130.   int has_vdisk=1;
  131.   unsigned long vdisk_top;
  132.   unsigned los, i, lol;
  133.   struct REGPACK r;
  134.   
  135.   /*
  136.   ** try xms allocation
  137.   */
  138.   if(xms_installed()) {
  139.       xms_alloc_init();
  140.   } else {
  141.     /*
  142.     ** int 15/vdisk memory allocation
  143.     */
  144.     r.r_ax = 0x8800;    /* get extended memory size */
  145.     intr(0x15, &r);
  146.     pn_hi_last = r.r_ax / 4 + 255;
  147.  
  148.     /* get ivec 19h, seg only */
  149.     vdisk = (char far *)(*(long far *)0x64L & 0xFFFF0000L);
  150.     for (i=0; i<5; i++)
  151.       if (vdisk[i+18] != "VDISK"[i])
  152.         has_vdisk = 0;
  153.     if (has_vdisk)
  154.     {
  155.       vdisk_top = vdisk[46] * 65536L + vdisk[45] * 256 + vdisk[44];
  156.       pn_hi_first = (vdisk_top + 4095) / 4096;
  157.     }
  158.     else
  159.       pn_hi_first = 256;
  160.   }
  161.  
  162.   r.r_ax= 0x4800;    /* get real memory size */
  163.   r.r_bx = 0xffff;
  164.   intr(0x21, &r);    /* lol == size of largest free memory block */
  165.   lol = r.r_bx;
  166.   r.r_ax = 0x4800;
  167.   intr(0x21, &r);    /* get the block */
  168.   pn_lo_first = (r.r_ax+0xFF) >> 8;    /* lowest real mem 4K block */
  169.   pn_lo_last = (r.r_ax+lol-1) >> 8; /* highest real mem 4K block */
  170.  
  171.   r.r_es = r.r_ax;    /* free the block just allocated */
  172.   r.r_ax = 0x4900;
  173.   intr(0x21, &r);
  174.  
  175.   mem_avail = 0;
  176.   for (i=0; i<4096; i++)
  177.     map[i] = 0xff;
  178.   for (i=pn_lo_first; i<=pn_lo_last; i++)
  179.     vset(i, VA_FREE);
  180.   for (i=pn_hi_first; i<=pn_hi_last; i++)
  181.     vset(i, VA_FREE);
  182.  
  183. /*  mem_avail = (pn_lo_last-pn_lo_first+1)*4 + (pn_hi_last-pn_hi_first+1)*4; */
  184. #if DEBUGGER
  185.   if (debug_mode)
  186.     printf("%d Kb conventional, %d Kb extended - %d Kb total RAM available\n",
  187.       (pn_lo_last-pn_lo_first+1)*4,
  188.       (pn_hi_last-pn_hi_first+1)*4,
  189.       mem_avail);
  190. #endif
  191.  
  192.   mem_used = 0;
  193.   left_lo = (pn_lo_last-pn_lo_first+1)*4;
  194.   left_hi = (pn_hi_last-pn_hi_first+1)*4;
  195. #if TOPLINEINFO
  196.   valloc_update_status();
  197. #endif
  198.   valloc_initted = 1;
  199. }
  200.  
  201. unsigned valloc(where)
  202. {
  203.   unsigned pn;
  204.   if (!valloc_initted)
  205.     valloc_init();
  206.   switch (where)
  207.   {
  208.     case VA_640:
  209.       more_640:
  210.       for (pn=pn_lo_first; pn<=pn_lo_last; pn++)
  211.         if (vtest(pn) == VA_FREE)
  212.         {
  213.           left_lo -= 4;
  214.           vset(pn, VA_USED);
  215.           return pn;
  216.         }
  217.       page_out(where);
  218.       goto more_640;
  219.     case VA_1M:
  220.       more_1m:
  221.       for (pn=pn_hi_first; pn<=pn_hi_last; pn++)
  222.         if (vtest(pn) == VA_FREE)
  223.         {
  224.           left_hi -= 4;
  225.           vset(pn, VA_USED);
  226.           return pn;
  227.         }
  228.       for (pn=pn_lo_first; pn<=pn_lo_last; pn++)
  229.         if (vtest(pn) == VA_FREE)
  230.         {
  231.           left_lo -= 4;
  232.           vset(pn, VA_USED);
  233.           return pn;
  234.         }
  235.       page_out(where);
  236.       goto more_1m;
  237.   }
  238.   return 0;
  239. }
  240.  
  241. void vfree(unsigned pn)
  242. {
  243.   vset(pn, VA_FREE);
  244. }
  245.