home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / djsrc106.arj / VALLOC.C < prev    next >
C/C++ Source or Header  |  1992-04-13  |  7KB  |  296 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. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:126,1 */
  17.  
  18. #include <stdio.h>
  19. #include <dos.h>
  20.  
  21. #include "build.h"
  22. #include "types.h"
  23. #include "valloc.h"
  24. #include "xms.h"
  25. #include "mono.h"
  26. #include "vcpi.h"
  27.  
  28. #define VA_FREE    0
  29. #define VA_USED    1
  30.  
  31. #define    DOS_PAGE 256        /*  1MB / 4KB = 256 Pages  */
  32.  
  33. int valloc_initted = 0;
  34. static word8 map[4096];
  35. word16 mem_avail, mem_used;
  36. static word16 left_lo, left_hi;
  37.  
  38. static unsigned pn_lo_first, pn_lo_last, pn_hi_first, pn_hi_last;
  39. static unsigned vcpi_flush_ok = 0;
  40.  
  41. extern int debug_mode;
  42. extern word16 vcpi_installed;    /*  VCPI Installed set this not Zero  */
  43.  
  44. #if TOPLINEINFO
  45. valloc_update_status()
  46. {
  47.   char buf[20];
  48.   int i;
  49. #if 0
  50.   if (!debug_mode)
  51.     return;
  52. #endif
  53.   if (!valloc_initted)
  54.     return;
  55.   sprintf(buf, "%5dk", mem_avail);
  56.   for (i=0; i<6; i++)
  57.     poke(screen_seg, (i+70)*2, buf[i] | 0x0a00);
  58.   sprintf(buf, "%5dk", mem_used);
  59.   for (i=0; i<6; i++)
  60.     poke(screen_seg, (i+62)*2, buf[i] | 0x0a00);
  61. }
  62. #endif
  63.  
  64. static void vset(unsigned i, int b)
  65. {
  66.   unsigned o, m;
  67.   o = i>>3;
  68.   m = 1<<(i&7);
  69.   if (b)
  70.   {
  71.     if (!(map[o] & m))
  72.     {
  73. #if TOPLINEINFO
  74.       mem_avail -= 4;
  75.       mem_used += 4;
  76.       valloc_update_status();
  77. #endif
  78.       map[o] |= m;
  79.     }
  80.   }
  81.   else
  82.   {
  83.     if (map[o] & m)
  84.     {
  85. #if TOPLINEINFO
  86.       mem_avail += 4;
  87.       mem_used -= 4;
  88.       valloc_update_status();
  89. #endif
  90.       map[o] &= ~m;
  91.     }
  92.   }
  93. }
  94.  
  95. static int vtest(unsigned i)
  96. {
  97.   unsigned o, m;
  98.   o = i>>3;
  99.   m = 1<<(i&7);
  100.   return map[o] & m;
  101. }
  102.  
  103.  
  104. emb_handle_t emb_handle=-1;
  105.  
  106. void
  107. xms_free(void) {
  108.     if(use_xms && emb_handle != -1) {
  109.         xms_unlock_emb(emb_handle);
  110.         xms_emb_free(emb_handle);
  111. #if DEBUGGER
  112.     printf("XMS memory freed\n");
  113. #endif
  114.     }
  115. }
  116.  
  117. void
  118. xms_alloc_init(void) {
  119.     xms_extended_info *x = xms_query_extended_memory();
  120.     emb_off_t linear_base;
  121.     emb_size_K_t emb_size;
  122. #if DEBUGGER
  123.     printf("XMS driver detected\n");
  124. #endif
  125.     emb_size = x->max_free_block;
  126.     emb_handle = xms_emb_allocate(emb_size);
  127.     linear_base = xms_lock_emb(emb_handle);
  128.     pn_hi_first = (linear_base + 4095)/4096;
  129.     pn_hi_last = (linear_base + emb_size * 1024L)/4096 - 1;
  130. }
  131.  
  132.  
  133. static valloc_init()
  134. {
  135.   unsigned char far *vdisk;
  136.   int has_vdisk=1;
  137.   unsigned long vdisk_top;
  138.   unsigned los, i, lol;
  139.   struct REGPACK r;
  140.   
  141.   if (vcpi_installed)
  142.     {
  143.     pn_hi_first = 32767;
  144.     pn_hi_last  = DOS_PAGE;
  145.     }
  146.   else if(use_xms) {
  147.       xms_alloc_init();    /*  Try XMS allocation  */
  148.       }
  149.   else {
  150.     /*
  151.     ** int 15/vdisk memory allocation
  152.     */
  153.     r.r_ax = 0x8800;    /* get extended memory size */
  154.     intr(0x15, &r);
  155.     pn_hi_last = r.r_ax / 4 + 255;
  156.  
  157.     /* get ivec 19h, seg only */
  158.     vdisk = (unsigned char far *)(*(long far *)0x64L & 0xFFFF0000L);
  159.     for (i=0; i<5; i++)
  160.       if (vdisk[i+18] != "VDISK"[i])
  161.         has_vdisk = 0;
  162.     if (has_vdisk)
  163.     {
  164.           pn_hi_first = ( (vdisk[46]<<4) | (vdisk[45]>>4) );
  165.           if (vdisk[44] | (vdisk[45]&0xf))
  166.             pn_hi_first ++;
  167.     }
  168.     else
  169.       pn_hi_first = 256;
  170.   }
  171.  
  172.   r.r_ax= 0x4800;    /* get real memory size */
  173.   r.r_bx = 0xffff;
  174.   intr(0x21, &r);    /* lol == size of largest free memory block */
  175.   lol = r.r_bx;
  176.   r.r_ax = 0x4800;
  177.   intr(0x21, &r);    /* get the block */
  178.   pn_lo_first = (r.r_ax+0xFF) >> 8;    /* lowest real mem 4K block */
  179.   pn_lo_last = ((r.r_ax+lol-0x100)>>8);    /* highest real mem 4K block */
  180.  
  181.   r.r_es = r.r_ax;    /* free the block just allocated */
  182.   r.r_ax = 0x4900;    /* because Turbo Debugger won't if we don't */
  183.   intr(0x21, &r);
  184.  
  185.   mem_avail = 0;
  186.   for ( i=0; i<DOS_PAGE/8; i++)
  187.     map[i] = 0xff;    /* DOS Area  */
  188.   for (    ; i<4096; i++)
  189.     map[i] = (vcpi_installed)? 0x00:0xff;    /* Extened Memory Area  */
  190.  
  191.   for (i=pn_lo_first; i<=pn_lo_last; i++)
  192.     vset(i, VA_FREE);
  193.   for (i=pn_hi_first; i<=pn_hi_last; i++)
  194.     vset(i, VA_FREE);
  195.   vcpi_flush_ok = 1;
  196.  
  197.   mem_used = 0;
  198.   left_lo  = (pn_lo_last - pn_lo_first + 1)*4;
  199.   left_hi  = (vcpi_installed)? vcpi_capacity()*4:(pn_hi_last-pn_hi_first+1)*4;
  200.   if (vcpi_installed)
  201.     mem_avail = left_lo + left_hi;
  202.  
  203. /*  mem_avail = (pn_lo_last-pn_lo_first+1)*4 + (pn_hi_last-pn_hi_first+1)*4; */
  204. #if DEBUGGER
  205.   if (debug_mode)
  206.     printf("%d Kb conventional, %d Kb extended - %d Kb total RAM available\n",
  207.       left_lo,left_hi,mem_avail);
  208. #endif
  209.  
  210. #if TOPLINEINFO
  211.   valloc_update_status();
  212. #endif
  213.   valloc_initted = 1;
  214. }
  215.  
  216. unsigned valloc(where)
  217. {
  218.   unsigned pn;
  219.   if (!valloc_initted)
  220.     valloc_init();
  221.   switch (where)
  222.   {
  223.     case VA_640:
  224.       more_640:
  225.       for (pn=pn_lo_first; pn<=pn_lo_last; pn++)
  226.         if (vtest(pn) == VA_FREE)
  227.         {
  228.           left_lo -= 4;
  229.           vset(pn, VA_USED);
  230.           return pn;
  231.         }
  232.       pn = page_out(where);
  233.       if (pn != 0xffff) return pn;
  234.       goto more_640;
  235.     case VA_1M:
  236.       more_1m:
  237.       if (vcpi_installed)
  238.     {
  239.     if (pn = vcpi_alloc())
  240.       {
  241.       left_hi -= 4;
  242.       if (pn < pn_hi_first)
  243.         pn_hi_first = pn;
  244.       if (pn > pn_hi_last)
  245.         pn_hi_last  = pn;
  246.       vset(pn,VA_USED);
  247.       return pn;
  248.       }
  249.     }
  250.       else
  251.     {
  252.         for (pn=pn_hi_first; pn<=pn_hi_last; pn++)
  253.           if (vtest(pn) == VA_FREE)
  254.             {
  255.             left_hi -= 4;
  256.             vset(pn, VA_USED);
  257.             return pn;
  258.             }
  259.     }
  260.  
  261.       for (pn=pn_lo_first; pn<=pn_lo_last; pn++)
  262.         if (vtest(pn) == VA_FREE)
  263.         {
  264.           left_lo -= 4;
  265.           vset(pn, VA_USED);
  266.           return pn;
  267.         }
  268.       pn = page_out(where);
  269.       if (pn != 0xffff) return pn;
  270.       goto more_1m;
  271.   }
  272.   return 0;
  273. }
  274.  
  275. void vfree(unsigned pn)
  276. {
  277.   if ((vcpi_installed)&&(pn >= DOS_PAGE))
  278.     vcpi_free(pn);
  279.   vset(pn, VA_FREE);
  280. }
  281.  
  282. void vcpi_flush(void)
  283. {
  284.   word16 pn;
  285.  
  286.   if (!vcpi_flush_ok)
  287.     return;            /*  Not Initaialized Map[]  */
  288.   for(pn = pn_hi_first; pn <= pn_hi_last; pn++)
  289.     if (vtest(pn))
  290.       vcpi_free(pn);
  291.  
  292. #if DEBUGGER
  293.   printf("VCPI memory freed\n");
  294. #endif
  295. }
  296.