home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK2 / SOURCE / MOVE / MOVEINIT.C$ / MOVEINIT
Encoding:
Text File  |  1992-01-23  |  13.1 KB  |  531 lines

  1. /***
  2. *moveinit.c - MOVE Initialization
  3. *
  4. *    Copyright (c) 1990-1992, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *    This file contains the routine _moveinit(); it determines an
  8. *    appropriate size for the overlay heap and cache and allocates them.
  9. *
  10. *******************************************************************************/
  11.  
  12. #include "moveapi.h"
  13.  
  14. #ifndef MOVE_ENV
  15.  
  16. /***
  17. *_moveinit - Allocate MOVE heap and cache
  18. *
  19. *Purpose:
  20. *    Allocate MOVE heap and cache at initialization time.
  21. *
  22. *    - Although $$MPOVLSIZE is a table of long counts of paragraphs,
  23. *      overlays generated with /DYNAMIC are never larger than 64 kb,
  24. *      so only 12 bits are meaningful in each entry.
  25. *
  26. *    - Minimum heap size is the size of the largest overlay.
  27. *    - If the program has four overlays or more
  28. *      requested heap size is the size of the three largest overlays
  29. *    - If the program has three overlays or less
  30. *      requested heap size is the size of the largest overlay
  31. *
  32. *    - Minimum cache ressource size is the size of the largest overlay.
  33. *    - Maximum cache ressource size is the total size of all overlays.
  34. *    - If maximum cache ressource size cannot be allocated in the same
  35. *      ressource, maximum combined cache size is the sum of maximum cache
  36. *      ressource size and minimum cache ressource
  37. *
  38. *Entry: <none>
  39. *
  40. *Exit:    <none>
  41. *
  42. *Exceptions:
  43. *
  44. *******************************************************************************/
  45.  
  46. void _far _moveinit (
  47. )
  48.     {
  49.     unsigned long _far * lpulOvlSizeCur; /* ptr to current of overlay size */
  50.     unsigned long _far * lpulOvlSizeEnd; /* ptr to end of overlay size table */
  51.  
  52.     unsigned short cparaOvl; /* size of current overlay */
  53.  
  54.     unsigned short cparaLarge; /* size of largest overlay */
  55.     unsigned short cparaMedium; /* size of second largest overlay */
  56.     unsigned short cparaSmall; /* size of third largest overlay */
  57.  
  58.     unsigned short cparaMax; /* size of heap as requested */
  59.     unsigned short cparaMin; /* minmum heap size */
  60.  
  61.     unsigned short ckbMax; /* sum of all overlays' sizes */
  62.     unsigned short ckbMin; /* minimum size of a cache ressource */
  63.  
  64.     unsigned short ckbXms; /* XMS avail size (kilobytes) */
  65.     unsigned short ckbEms; /* EMS avail size (kilobytes) */
  66.  
  67.     /* cparaLarge, cparaMedium, cparaSmall will be the sizes of
  68.      * the three largest overlays
  69.      */
  70.  
  71.     cparaLarge = 0;
  72.     cparaMedium = 0;
  73.     cparaSmall = 0;
  74.  
  75.     /* ckbMax is the sum of the image size of all the overlays. */
  76.  
  77.     ckbMax = 0;
  78.  
  79.     for (lpulOvlSizeCur = $$MPOVLSIZE + 1,
  80.      lpulOvlSizeEnd = $$MPOVLSIZE + $$COVL;
  81.      lpulOvlSizeCur < lpulOvlSizeEnd;
  82.      lpulOvlSizeCur ++)
  83.     {
  84.     cparaOvl = (unsigned short) (*lpulOvlSizeCur);
  85.     ckbMax += ((cparaOvl + 0x3f) >> 6);
  86.  
  87.     if (cparaOvl > cparaSmall)
  88.         {
  89.         if (cparaOvl > cparaMedium)
  90.         {
  91.         cparaSmall = cparaMedium;
  92.         if (cparaOvl > cparaLarge)
  93.             {
  94.             cparaMedium = cparaLarge;
  95.             cparaLarge = cparaOvl;
  96.             }
  97.         else
  98.             cparaMedium = cparaOvl;
  99.         }
  100.         else
  101.         cparaSmall = cparaOvl;
  102.         }
  103.     }
  104.  
  105.     /* cparaMax is the requested size of the overlay heap in paragraphs.
  106.      * If the program has less than 4 overlays, this will be the size of the
  107.      * largest overlay. If the program has more than 3 overlays, this will be
  108.      * the sum of the largest 3 overlays' sizes.
  109.      */
  110.  
  111.     if ($$COVL > 4)
  112.     cparaMax = cparaLarge + cparaMedium + cparaSmall;
  113.     else
  114.     cparaMax = cparaLarge;
  115.  
  116.     /* cparaMax is the minimum size of heap, it is the size
  117.      * of the largest overlay.
  118.      */
  119.  
  120.     cparaMin = cparaLarge;
  121.  
  122.     /* attempt to allocate the overlay heap. ignore return value (heap size).
  123.      * note that MOVE will abort if not enough memory to alloc minimum size.
  124.      */
  125.  
  126.     _movesetheap ($$COVL, cparaLarge, cparaMax);
  127.  
  128.     /* get available cache ressource amount */
  129.  
  130.     _movegetcache (&ckbXms, &ckbEms);
  131.  
  132.     /* ckbMin is the cache resource minimum size (largest overlay size) */
  133.  
  134.     ckbMin = ((cparaLarge + 0x3f) >> 6);
  135.  
  136.     /* allocate cache ressource:
  137.      *    1 try to allocate max in XMS
  138.      *    2 try to allocate max in EMS
  139.      *    3 allocate as much as possible in XMS
  140.      *    4 allocate as much as possible in EMS
  141.      */
  142.  
  143.     if (ckbXms >= ckbMax)
  144.     {
  145.     ckbXms = ckbMax;
  146.     ckbEms = 0;
  147.     }
  148.     else if (ckbEms >= ckbMax)
  149.     {
  150.     ckbXms = 0;
  151.     ckbEms = ckbMax;
  152.     }
  153.     else
  154.     {
  155.     if (ckbXms < ckbMin)
  156.         ckbXms = 0;
  157.  
  158.     if (ckbEms < ckbMin)
  159.         ckbEms = 0;
  160.  
  161.     if (ckbXms + ckbEms > ckbMax + ckbMin)
  162.         ckbEms = ckbMax + ckbMin - ckbXms;
  163.     }
  164.  
  165.     /* attempt to set the cache's size. we ignore errors */
  166.  
  167.     _movesetcache (ckbXms, ckbEms);
  168.  
  169. #ifdef MOVE_PROF
  170.     _movetraceon ();
  171. #endif
  172.     }
  173.  
  174.  
  175. #else /* MOVE_ENV */
  176.  
  177.  
  178. static char SzMOVE_COVL [] = "MOVE_COVL";
  179. static char SzMOVE_HEAP [] = "MOVE_HEAP";
  180. static char SzMOVE_XMS    [] = "MOVE_XMS";
  181. static char SzMOVE_EMS    [] = "MOVE_EMS";
  182.  
  183. /***
  184. * __movegetenv - Get value of MOVE environment variable
  185. *
  186. *Purpose:
  187. *    Get the value of the MOVE environment variable
  188. *
  189. *    Value should we stored with exactly four hexadecimal digits
  190. *
  191. *Entry:
  192. *    lpszName = name of variable to look for
  193. *
  194. *Exit:
  195. *    unsigned 16-bit integer = value in environment
  196. *                  zero if name not defined
  197. *
  198. *Exceptions:
  199. *
  200. *******************************************************************************/
  201.  
  202. unsigned short _far __movegetenv (
  203. char _far * lpszName
  204. )
  205.     {
  206.     _asm
  207.     {
  208.     les    di,[lpszName]    ; ES:DI = lpszName
  209.     xor    ax,ax        ; search value: null byte
  210.     mov    cx,-1        ; so won't stop scan
  211.     repne    scasb        ; scan for null, CX = -(1+strlen(lpszName))
  212.     not    cx
  213.     dec    cx        ; CX = strlen (lpszName)
  214.  
  215.     mov    dx,cx        ; DX = strlen (lpszName)
  216.  
  217.     mov    di,seg _movesegenv
  218.     mov    es,di
  219.     mov    di,offset _movesegenv
  220.     mov    es,es:[di]
  221.     xor    di,di        ; ES:DI = environment
  222.  
  223. __mge_next:
  224.  
  225.     mov    al,es:[di]    ; AL = next byte
  226.     or    al,al        ; if null, we've failed to find the string
  227.     je    __mge_fail
  228.  
  229.     lds    si,[lpszName]    ; DS:SI = lpszName
  230.     mov    cx,dx        ; CX = strlen (lpszName)
  231.     repz    cmpsb        ; compare strings
  232.  
  233.     jne    __mge_bad    ; did the compare succeed ?
  234.  
  235.     mov    al,es:[di]    ; AL = next byte
  236.     cmp    al,'='        ; if '=', we found the guy
  237.     je    __mge_found
  238.  
  239. __mge_bad:
  240.  
  241.     xor    ax,ax        ; search value: null byte
  242.     mov    cx,-1        ; so won't stop scan
  243.     repne    scasb        ; scan for null
  244.  
  245.     jmp    __mge_next    ; check next string
  246.  
  247. __mge_found:
  248.  
  249.     mov    cl,16        ; CL = 16 (shift factor)
  250.     xor    ax,ax        ; AX = 0 (result)
  251.  
  252. __mge_next_char:
  253.  
  254.     inc    di        ; advance to next char
  255.  
  256.     mov    dl,es:[di]    ; DL = next byte
  257.  
  258.     or    dl,dl        ; final byte ?
  259.     jz    __mge_done    ; if yes, we're done
  260.  
  261.     cmp    dl,'0'        ; char < '0' ?
  262.     jb    __mge_fail    ; if yes, invalid
  263.  
  264.     cmp    dl,'9'        ; '0' <= char <= '9' ?
  265.     jbe    __mge_digit    ; if yes, it's a digit
  266.  
  267.     cmp    dl,'A'        ; '9' < char < 'A' ?
  268.     jb    __mge_fail    ; if yes, invalid
  269.  
  270.     cmp    dl,'F'        ; 'A' <= char <= 'F' ?
  271.     jbe    __mge_letter    ; if yes, it's a letter
  272.  
  273.     cmp    dl,'a'        ; 'Z' < char < 'a' ?
  274.     jb    __mge_fail    ; if yes, invalid
  275.  
  276.     cmp    dl,'f'        ; 'a' <= char <= 'f' ?
  277.     jbe    __mge_letter    ; if yes, it's a letter
  278.  
  279.                 ; z < char : invalid
  280.  
  281. __mge_fail:
  282.  
  283.     xor    ax,ax        ; null result
  284.     jmp    __mge_end    ; finish
  285.  
  286. __mge_digit:
  287.  
  288.     and    dl,0fh
  289.  
  290.     jmp    __mge_store
  291.  
  292. __mge_letter:
  293.  
  294.     and    dl,0fh
  295.     add    dl,09h
  296.  
  297. __mge_store:
  298.  
  299.     xor    dh,dh        ; DH = 0 (so we can OR AX,DX)
  300.  
  301.     or    cl,cl        ; check shift count
  302.     jz    __mge_fail    ; if zero, it's the 5th digit, invalid
  303.  
  304.     sub    cl,4        ; update shift factor
  305.  
  306.     shl    dx,cl        ; shift digit
  307.  
  308.     or    ax,dx        ; put digit in result
  309.  
  310.     jmp    __mge_next_char
  311.  
  312. __mge_done:
  313.  
  314.     or    cl,cl        ; check shift count
  315.     jnz    __mge_fail    ; if not zero, we had less than 4 digits, invalid
  316.  
  317. __mge_end:
  318.     }
  319.     }
  320.  
  321.  
  322. /***
  323. *_moveinit - Allocate MOVE heap and cache
  324. *
  325. *Purpose:
  326. *    Allocate MOVE heap and cache at initialization time.
  327. *
  328. *    - Although $$MPOVLSIZE is a table of long counts of paragraphs,
  329. *      overlays generated with /DYNAMIC are never larger than 64 kb,
  330. *      so only 12 bits are meaningful in each entry.
  331. *
  332. *    - Minimum heap size is the size of the largest overlay.
  333. *    - If the program has four overlays or more
  334. *      requested heap size is the size of the three largest overlays
  335. *    - If the program has three overlays or less
  336. *      requested heap size is the size of the largest overlay
  337. *
  338. *    - Minimum cache ressource size is the size of the largest overlay.
  339. *    - Maximum cache ressource size is the total size of all overlays.
  340. *    - If maximum cache ressource size cannot be allocated in the same
  341. *      ressource, maximum combined cache size is the sum of maximum cache
  342. *      ressource size and minimum cache ressource
  343. *
  344. *Entry: <none>
  345. *
  346. *Exit:    <none>
  347. *
  348. *Exceptions:
  349. *
  350. *******************************************************************************/
  351.  
  352. void _far _moveinit (
  353. )
  354.     {
  355.     unsigned long _far * lpulOvlSizeCur; /* ptr to current of overlay size */
  356.     unsigned long _far * lpulOvlSizeEnd; /* ptr to end of overlay size table */
  357.  
  358.     unsigned short covlMax; /* maximum number of ovls supported */
  359.  
  360.     unsigned short cparaOvl; /* size of current overlay */
  361.  
  362.     unsigned short cparaLarge; /* size of largest overlay */
  363.     unsigned short cparaMedium; /* size of second largest overlay */
  364.     unsigned short cparaSmall; /* size of third largest overlay */
  365.  
  366.     unsigned short cparaMax; /* size of heap as requested */
  367.     unsigned short cparaMin; /* minmum heap size */
  368.  
  369.     unsigned short ckbMax; /* sum of all overlays' sizes */
  370.     unsigned short ckbMin; /* minimum size of a cache ressource */
  371.  
  372.     unsigned short ckbXms; /* XMS avail size (kilobytes) */
  373.     unsigned short ckbEms; /* EMS avail size (kilobytes) */
  374.  
  375.     unsigned short covlEnv; /* max number of ovls requested by env var */
  376.     unsigned short cparaEnv; /* heap size requested by env var */
  377.     unsigned short ckbXmsEnv; /* XMS cache size requested by env var */
  378.     unsigned short ckbEmsEnv; /* EMS cache size requested by env var */
  379.  
  380.     /* cparaLarge, cparaMedium, cparaSmall will be the sizes of
  381.      * the three largest overlays
  382.      */
  383.  
  384.     cparaLarge = 0;
  385.     cparaMedium = 0;
  386.     cparaSmall = 0;
  387.  
  388.     /* ckbMax is the sum of the image size of all the overlays. */
  389.  
  390.     ckbMax = 0;
  391.  
  392.     for (lpulOvlSizeCur = $$MPOVLSIZE + 1,
  393.      lpulOvlSizeEnd = $$MPOVLSIZE + $$COVL;
  394.      lpulOvlSizeCur < lpulOvlSizeEnd;
  395.      lpulOvlSizeCur ++)
  396.     {
  397.     cparaOvl = (unsigned short) (*lpulOvlSizeCur);
  398.     ckbMax += ((cparaOvl + 0x3f) >> 6);
  399.  
  400.     if (cparaOvl > cparaSmall)
  401.         {
  402.         if (cparaOvl > cparaMedium)
  403.         {
  404.         cparaSmall = cparaMedium;
  405.         if (cparaOvl > cparaLarge)
  406.             {
  407.             cparaMedium = cparaLarge;
  408.             cparaLarge = cparaOvl;
  409.             }
  410.         else
  411.             cparaMedium = cparaOvl;
  412.         }
  413.         else
  414.         cparaSmall = cparaOvl;
  415.         }
  416.     }
  417.  
  418.     /* covlMax is the requested size of the overlay table, it is the maximum
  419.      * number of overlays supported by MOVE for the application and its
  420.      * extensions
  421.      */
  422.  
  423.     covlEnv = __movegetenv (SzMOVE_COVL);
  424.  
  425.     if (covlEnv > $$COVL)
  426.     covlMax = covlEnv;
  427.     else
  428.     covlMax = $$COVL;
  429.  
  430.     /* cparaMin is the minimum size of heap, it is the size
  431.      * of the largest overlay.
  432.      */
  433.  
  434.     cparaMin = cparaLarge;
  435.  
  436.     /* cparaMax is the requested size of the overlay heap in paragraphs.
  437.      * If the program has less than 4 overlays, this will be the size of the
  438.      * largest overlay. If the program has more than 3 overlays, this will be
  439.      * the sum of the largest 3 overlays' sizes.
  440.      */
  441.  
  442.     cparaEnv = __movegetenv (SzMOVE_HEAP);
  443.  
  444.     if (cparaEnv != 0)
  445.     if (cparaEnv < cparaMin)
  446.         cparaMax = cparaMin;
  447.     else
  448.         cparaMax = cparaEnv;
  449.     else
  450.     if ($$COVL > 4)
  451.         cparaMax = cparaLarge + cparaMedium + cparaSmall;
  452.     else
  453.         cparaMax = cparaLarge;
  454.  
  455.     /* attempt to allocate the overlay heap. ignore return value (heap size).
  456.      * note that MOVE will abort if not enough memory to alloc minimum size.
  457.      */
  458.  
  459.     _movesetheap (covlMax, cparaMin, cparaMax);
  460.  
  461.     /* get available cache ressource amount */
  462.  
  463.     _movegetcache (&ckbXms, &ckbEms);
  464.  
  465.     /* ckbMin is the cache resource minimum size (largest overlay size) */
  466.  
  467.     ckbMin = ((cparaLarge + 0x3f) >> 6);
  468.  
  469.     /* allocate cache ressource: */
  470.  
  471.     ckbEmsEnv = __movegetenv (SzMOVE_EMS);
  472.     ckbXmsEnv = __movegetenv (SzMOVE_XMS);
  473.  
  474.     if (ckbEmsEnv != 0 || ckbXmsEnv != 0)
  475.     {
  476.     if (ckbEmsEnv < ckbMin || ckbEms < ckbMin)
  477.         ckbEms = 0;
  478.     else
  479.         if (ckbEmsEnv < ckbEms)
  480.         ckbEms = ckbEmsEnv;
  481.  
  482.     if (ckbXmsEnv < ckbMin || ckbXms < ckbMin)
  483.         ckbXms = 0;
  484.     else
  485.         if (ckbXmsEnv < ckbXms)
  486.         ckbXms = ckbXmsEnv;
  487.     }
  488.     else
  489.     {
  490.  
  491.     /* default algorithm:
  492.      *  1 try to allocate max in XMS
  493.      *  2 try to allocate max in EMS
  494.      *  3 allocate as much as possible in XMS
  495.      *  4 allocate as much as possible in EMS
  496.      */
  497.  
  498.     if (ckbXms >= ckbMax)
  499.         {
  500.         ckbXms = ckbMax;
  501.         ckbEms = 0;
  502.         }
  503.     else if (ckbEms >= ckbMax)
  504.         {
  505.         ckbXms = 0;
  506.         ckbEms = ckbMax;
  507.         }
  508.     else
  509.         {
  510.         if (ckbXms < ckbMin)
  511.         ckbXms = 0;
  512.  
  513.         if (ckbEms < ckbMin)
  514.         ckbEms = 0;
  515.  
  516.         if (ckbXms + ckbEms > ckbMax + ckbMin)
  517.         ckbEms = ckbMax + ckbMin - ckbXms;
  518.         }
  519.     }
  520.  
  521.     /* attempt to set the cache's size. we ignore errors */
  522.  
  523.     _movesetcache (ckbXms, ckbEms);
  524.  
  525. #ifdef MOVE_PROF
  526.     _movetraceon ();
  527. #endif
  528.     }
  529.  
  530. #endif // MOVE_ENV
  531.