home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / tt / vmem11 / vmem_prg / vsubrout.c < prev   
C/C++ Source or Header  |  1990-10-02  |  14KB  |  638 lines

  1. #include "vmem.h"
  2.  
  3. /**************************************/
  4. /* Einlesen einer Seite in den Cache: */
  5. /**************************************/
  6.  
  7. BYTE *load_page (vmempage, flag)
  8.     VPAGE    vmempage;
  9.     int        flag;
  10. {
  11.     CPAGE    cachepage;
  12.     BYTE    *cacheaddr;
  13.  
  14. #ifdef STAT
  15.     stat_access++;
  16. #endif
  17.  
  18.     if (WHERE_FLAG (vmempage) == CACHE)
  19.     {
  20.         cachepage = search_cache (vmempage);    /* Seite im Cache suchen */
  21.  
  22. #ifdef DEBUG
  23.     printf ("LOAD_PAGE (Flag: %x): %x from CACHE %x (Flag: %x)\n",
  24.     flag, vmempage, cachepage, cache_flags [cachepage]);
  25. #endif
  26.  
  27.         ACCESSED (cachepage);
  28.         UPDATE_FLAG (cachepage, flag);
  29.         return (CACHE_ADDRESS (cachepage));
  30.     }
  31.  
  32.  
  33.     cachepage = find_cache ();        /* älteste Seite im Cache suchen */
  34.  
  35.     FILE_TO_CACHE (vmempage);
  36.     ALLOC_CACHE (cachepage, flag, vmempage);    /* Cache-Seite belegen */
  37.     cacheaddr = CACHE_ADDRESS (cachepage);
  38.  
  39. #ifdef DEBUG    
  40.     if (NEW_FLAG (vmempage) == NEW)
  41.     {
  42.         printf ("LOAD_PAGE (Flag: %x): NEW PAGE %x\n",
  43.         flag, vmempage);
  44.     }
  45.     else
  46.     {
  47.         printf ("LOAD_PAGE (Flag: %x): %x from CACHE %x (Flag: %x)\n",
  48.         flag, vmempage, cachepage, cache_flags [cachepage]);
  49.     }
  50. #endif
  51.  
  52.     read_page (cacheaddr, vmempage);
  53.     if (flag == CACHE_WRITE)
  54.         MAKE_OLD (vmempage);
  55.  
  56.     return (cacheaddr);
  57. }
  58.  
  59.  
  60. /******************************************/
  61. /* Schreiben eines Puffers in eine Seite: */
  62. /******************************************/
  63.  
  64. void save_page (block, vmempage)
  65.     BYTE    *block;
  66.     VPAGE    vmempage;
  67. {
  68.     CPAGE    cachepage;
  69.  
  70. #ifdef STAT
  71.     stat_access++;
  72. #endif
  73.  
  74.     if (WHERE_FLAG (vmempage) == CACHE)
  75.     {
  76.         cachepage = search_cache (vmempage);    /* Seite im Cache suchen */
  77.  
  78. #ifdef DEBUG
  79.     printf ("SAVE_PAGE: %x into CACHE %x\n",
  80.     vmempage, cachepage);
  81. #endif
  82.  
  83.         ACCESSED (cachepage);                    /* Zugriff auf <cachepage> */
  84.         SET_FLAG (cachepage, CACHE_WRITE);        /* Cache-Flag aktualisieren */
  85.         MAKE_OLD (vmempage);
  86.         COPY_CACHE (CACHE_ADDRESS (cachepage), block);
  87.         return;
  88.     }
  89.  
  90.     if (NEW_FLAG (vmempage) == NEW)
  91.     {
  92.         cachepage = find_cache ();
  93.  
  94. #ifdef DEBUG
  95.     printf ("SAVE_PAGE: NEW PAGE %x into CACHE %x\n",
  96.     vmempage, cachepage);
  97. #endif    
  98.  
  99.         ALLOC_CACHE (cachepage, CACHE_WRITE, vmempage);
  100.         FILE_TO_CACHE (vmempage);
  101.         MAKE_OLD (vmempage);
  102.         COPY_CACHE (CACHE_ADDRESS (cachepage), block);
  103.     }
  104.     else
  105.     {
  106. #ifdef DEBUG
  107.     printf ("SAVE_PAGE: WRITE %x\n", vmempage);
  108. #endif    
  109.         write_page (block, vmempage);
  110.     }
  111. }
  112.  
  113.  
  114. /************************************************************/
  115. /* Suchen einer freien Seite im Cache; falls kein Treffer:  */
  116. /* Auslagern der Seite, die den geringsten Aufwand benötigt */
  117. /************************************************************/
  118.  
  119. CPAGE find_cache ()
  120. {
  121.     CPAGE    cachepage;
  122.     VPAGE    vmempage;
  123.  
  124.     for (cachepage = 0; cachepage < info.cache_count; cachepage++)
  125.     {
  126.         if (cache_flags [cachepage] == CACHE_FREE)
  127.         {
  128.             ACCESSED (cachepage);
  129.             return (cachepage);
  130.         }
  131.     }
  132.  
  133. /* Auswahl einer zu verdrängenden Seite: */
  134.  
  135. #ifdef DEBUG
  136.     printf ("  AGE: ");
  137.     {
  138.         int j;
  139.         
  140.         for (j=0; j < age_count; j++)
  141.             printf ("%02x ", cache_age [j]);
  142.         printf ("\n");
  143.     }
  144. #endif
  145.  
  146.     cachepage = get_oldest ();
  147.     vmempage = cache_page [cachepage];
  148.  
  149. /* Auslagern dieser Seite, falls nötig */
  150.  
  151.     if (cache_flags [cachepage] == CACHE_WRITE)
  152.     {
  153.         write_page (CACHE_ADDRESS (cachepage), vmempage);
  154.  
  155. #ifdef DEBUG
  156.     printf ("FIND_CACHE: WRITE CACHE %x (%x) ==>  ",
  157.     cachepage, vmempage);
  158. #endif
  159.  
  160.     }
  161.     else
  162.     {
  163.  
  164. #ifdef DEBUG
  165.     printf ("FIND_CACHE: DELETE CACHE %x (%x) ==>  ",
  166.     cachepage, vmempage);
  167. #endif
  168.  
  169.         CACHE_TO_FILE (vmempage);
  170.     }
  171.  
  172.     ACCESSED (cachepage);
  173.     FREE_CACHE (cachepage);
  174.     return (cachepage);
  175. }
  176.  
  177.  
  178. /*********************************************************************/
  179. /* Einlesen einer Seite aus dem virtuellen Speicher in einen Puffer: */
  180. /*********************************************************************/
  181.  
  182. void read_page (block, vmempage)
  183.     BYTE    *block;
  184.     VPAGE    vmempage;
  185. {
  186.     long    rsize;
  187.     
  188. #ifdef STAT
  189.     stat_read++;
  190. #endif
  191.  
  192.     if (NEW_FLAG (vmempage) == NEW)
  193.     {
  194.         INIT_CACHE (block);
  195.     }
  196.     else
  197.     {
  198.         if (sector_flag)
  199.         {
  200.             READ_SECTOR (block, cluster_size, sector_no [vmempage]);
  201.         }
  202.         else
  203.         {
  204.             FSEEK (vmempage);
  205.             if ((rsize = FREAD (info.page_size, block)) != info.page_size)
  206.             {
  207.                 printf ("Fread-Error #%ld!!\nPage: %x  Offset: %ld\n",
  208.                     rsize, vmempage, PAGE_TO_ADDR (vmempage));
  209.                 vm_close ();
  210.                 exit (3);
  211.             }
  212.         }
  213.     }
  214. }
  215.  
  216.  
  217. /*******************************************************************/
  218. /* Schreiben eines Puffers in eine Seite des virtuellen Speichers: */
  219. /*******************************************************************/
  220.  
  221. void write_page (block, vmempage)
  222.     BYTE    *block;
  223.     VPAGE    vmempage;
  224. {
  225.     long    wsize;
  226.  
  227. #ifdef STAT
  228.     stat_write++;
  229. #endif
  230.  
  231.     CACHE_TO_FILE (vmempage);
  232.     MAKE_OLD (vmempage);
  233.  
  234.     if (sector_flag)
  235.     {
  236.         WRITE_SECTOR (block, cluster_size, sector_no [vmempage]);
  237.     }
  238.     else
  239.     {
  240.         FSEEK (vmempage);
  241.         if ((wsize = FWRITE (info.page_size, block)) != info.page_size)
  242.         {
  243.             printf ("Fwrite-Error #%ld!!\nPage: %x  Offset: %ld\n",
  244.                 wsize, vmempage, PAGE_TO_ADDR (vmempage));
  245.             vm_close ();
  246.             exit (4);
  247.         }
  248.     }
  249. }
  250.  
  251.  
  252. /*************************************/
  253. /* Initialisierung der Datei-Seiten: */
  254. /*************************************/
  255.  
  256. int init_pages (vmempage, count)
  257.     VPAGE    vmempage;
  258.     WORD    count;
  259. {
  260.     long    size, size2;
  261.  
  262.     if (sector_flag)
  263.     {
  264.         if (alloc_sector (vmempage, count) == OK)
  265.             return (OK);
  266.         else
  267.         {
  268.             free_sector (vmempage, count);
  269.             return (NOT_OK);
  270.         }
  271.     }
  272.  
  273.     if ((vmempage + count) <= max_page)
  274.         return (OK);
  275.  
  276.     FSEEK (max_page);
  277.     size = PAGE_TO_ADDR ((vmempage + count) - max_page);
  278.     max_page = vmempage + count - 1;
  279.  
  280.     while (size > 0)
  281.     {
  282.         size2 = MIN (size, info.cache_size);
  283.         if (FWRITE (size2, cache) != size2)
  284.             return (FILE_ERROR);
  285.  
  286.         size -= size2;
  287.     }
  288.     return (OK);
  289. }
  290.  
  291.  
  292. /********************************************************************/
  293. /* <count> CACHE-Seiten ab <cachepage> rausschreiben und freigeben: */
  294. /********************************************************************/
  295.  
  296. void cache_clr (cachepage, count)
  297.     CPAGE    cachepage;
  298.     WORD    count;
  299. {
  300.     VPAGE    vmempage;
  301.  
  302.     while (count-- > 0)
  303.     {
  304.         vmempage = cache_page [cachepage];
  305.         switch (cache_flags [cachepage])
  306.         {
  307.             case CACHE_WRITE:
  308.                 write_page (CACHE_ADDRESS (cachepage), vmempage);
  309.  
  310. #ifdef DEBUG
  311.     printf ("CACHE_CLR: WRITE CACHE %x (%x)\n",
  312.     cachepage, vmempage);
  313. #endif
  314.  
  315.                 FREE_CACHE (cachepage);
  316.                 break;
  317.  
  318.             case CACHE_READ:
  319.  
  320. #ifdef DEBUG
  321.     printf ("CACHE_CLR: DELETE CACHE %x (%x)\n", cachepage, vmempage);
  322. #endif
  323.  
  324.                 CACHE_TO_FILE (vmempage);
  325.                 FREE_CACHE (cachepage);
  326.                 break;
  327.         }
  328.         cache_age [cachepage++] = 0;
  329.     }
  330. }
  331.  
  332.  
  333. /***********************************************************************/
  334. /* Schreiben einer Sequenz im Cache in die Datei-Seiten ab <vmempage>: */
  335. /***********************************************************************/
  336.  
  337. void write_sequence (cachepage, count, vmempage)
  338.     CPAGE    cachepage;
  339.     WORD    count;
  340.     VPAGE    vmempage;
  341. {
  342.     CPAGE    i;
  343.     VPAGE    vpage;
  344.     char    *block;
  345.     
  346.     vpage = vmempage;
  347.     block = CACHE_ADDRESS (cachepage);
  348.  
  349.     if (write_test (vmempage, count) == count)
  350.     {
  351.         CPAGE    select;
  352.  
  353.         for (i = cachepage; i < (cachepage + count); i++)
  354.         {
  355.             select = search_cache (vmempage);    /* Seite im Cache suchen */
  356.             ACCESSED (select);                    /* Zugriff auf <select> */
  357.             SET_FLAG (select, CACHE_WRITE);        /* Cache-Flag aktualisieren */
  358.             MAKE_OLD (vmempage);
  359.             COPY_CACHE (CACHE_ADDRESS (select), block);
  360.             block += info.page_size;
  361.         }
  362.         return;
  363.     }
  364.  
  365.     for (i = cachepage; i < (cachepage + count); i++)
  366.     {
  367.         if (WHERE_FLAG (vpage) == CACHE)
  368.         {
  369.             CACHE_TO_FILE (vpage);
  370.             FREE_CACHE (search_cache (vpage));
  371.         }
  372.         MAKE_OLD (vpage++);
  373.     }
  374.  
  375.     if (sector_flag)
  376.     {
  377.         for (i = cachepage; i < (cachepage + count); i++)
  378.         {
  379.             WRITE_SECTOR (block, cluster_size, sector_no [vmempage++]);
  380.             block += info.page_size;
  381.         }
  382.     }
  383.     else
  384.     {
  385.         long    size, wsize;
  386.  
  387.         size = PAGE_TO_ADDR (count);
  388.         FSEEK (vmempage);
  389.         if ((wsize = FWRITE (size, block)) != size)
  390.         {
  391.             printf ("Fwrite-Error #%ld!!\nPage: %x  Offset: %ld\n",
  392.                 wsize, vmempage, PAGE_TO_ADDR (vmempage));
  393.             vm_close ();
  394.             exit (4);
  395.         }
  396.     }
  397. }
  398.  
  399.  
  400. /**************************************************************/
  401. /* Lesen einer Sequenz von Seiten ab <vmempage> in den Cache: */
  402. /**************************************************************/
  403.  
  404. void read_sequence (cachepage, count, vmempage)
  405.     CPAGE    cachepage;
  406.     WORD    count;
  407.     VPAGE    vmempage;
  408. {
  409.     CPAGE    i, select;
  410.     VPAGE    vpage;
  411.     char    *block;
  412.  
  413.     vpage = vmempage;
  414.     block = CACHE_ADDRESS (cachepage);
  415.  
  416.     if (read_test (vmempage, count) == count)
  417.     {
  418.         for (i = cachepage; i < (cachepage + count); i++)
  419.         {
  420.             if (WHERE_FLAG (vmempage) == CACHE)
  421.             {
  422.                 select = search_cache (vmempage);    /* Seite im Cache suchen */
  423.                 ACCESSED (select);                    /* Zugriff auf <select> */
  424.                 COPY_CACHE (block, CACHE_ADDRESS (select));
  425.             }
  426.             else
  427.             {
  428.                 INIT_CACHE (block);
  429.             }
  430.             block += info.page_size;
  431.         }
  432.         return;
  433.     }
  434.  
  435.     if (sector_flag)
  436.     {
  437.         for (i = cachepage; i < (cachepage + count); i++)
  438.         {
  439.             READ_SECTOR (block, cluster_size, sector_no [vpage++]);
  440.             block += info.page_size;
  441.         }
  442.     }
  443.     else
  444.     {
  445.         long    size, rsize;
  446.  
  447.         size = PAGE_TO_ADDR (count);
  448.         FSEEK (vmempage);
  449.         if ((rsize = FREAD (size, block)) != size)
  450.         {
  451.             printf ("Fread-Error #%ld!!\nPage: %x  Offset: %ld\n",
  452.                 rsize, vmempage, PAGE_TO_ADDR (vmempage));
  453.             vm_close ();
  454.             exit (3);
  455.         }
  456.     }
  457.  
  458.     for (i = cachepage; i < (cachepage + count); i++)
  459.     {
  460.         if (WHERE_FLAG (vmempage) == CACHE)
  461.         {
  462.             select = search_cache (vmempage);    /* Seite im Cache suchen */
  463.             ACCESSED (select);
  464.             COPY_CACHE (CACHE_ADDRESS (i), CACHE_ADDRESS (select));
  465.         }
  466.         else
  467.         {
  468.             if (NEW_FLAG (vmempage) == NEW)
  469.             {
  470.                 INIT_CACHE (CACHE_ADDRESS (i));
  471.             }
  472.         }
  473.         vmempage++;
  474.     }
  475. }
  476.  
  477.  
  478. /************************************/
  479. /* freien Memory Deskriptor suchen: */
  480. /************************************/
  481.  
  482. MD get_free_md (void)
  483. {
  484.     MD mem;
  485.  
  486.     mem = 0;
  487.     while (MD_START (mem) != FREE_MD)
  488.         mem++;
  489.  
  490.     return (mem);
  491. }
  492.  
  493.  
  494. /*****************************/
  495. /* Sektoren in FAT2 belegen: */
  496. /*****************************/
  497.  
  498. int alloc_sector (vmempage, count)
  499.     VPAGE    vmempage;
  500.     WORD    count;
  501. {
  502.     WORD    fat1, fat2, sector, offset, cluster;
  503.  
  504.     fat2 = bpb_block->fatrec;
  505.     fat1 = fat2 - bpb_block->fsiz;
  506.     sector = 0;
  507.     offset = 4;
  508.     READ_SECTOR (buffer, 1, fat2);
  509.  
  510.     while (count > 0)
  511.     {
  512.         if (offset >= bpb_block->recsiz)
  513.         {
  514.             WRITE_SECTOR (buffer, 1, fat1+sector);
  515.             WRITE_SECTOR (buffer, 1, fat2+sector);
  516.             if (++sector > bpb_block->fsiz)
  517.                 return (NOT_OK);
  518.             offset = 0;
  519.             READ_SECTOR (buffer, 1, fat2+sector);
  520.         }
  521.  
  522.         switch (size_bits)
  523.         {
  524.             case 0:
  525.                 if (*((WORD *) (buffer + offset)) == 0)
  526.                 {
  527.                     *((WORD *) (buffer + offset)) = 0xFFFF;
  528.                     cluster = sector << (record_bits - cluster_bits);
  529.                     cluster += (offset >> 1) - 2;
  530.                     cluster <<= cluster_bits;
  531.                     cluster += bpb_block->datrec;
  532.                     sector_no [vmempage++] = cluster;
  533.                     --count;
  534.                 }
  535.                 offset += 2;
  536.                 break;
  537.             case 1:
  538.                 if ((offset + 4) < bpb_block->recsiz)
  539.                 {
  540.                     if (*((ULONG *) (buffer + offset)) == 0)
  541.                     {
  542.                         *((ULONG *) (buffer + offset)) = 0xFFFFFFFFL;
  543.                         cluster = sector << (record_bits - cluster_bits);
  544.                         cluster += (offset >> 1) - 2;
  545.                         cluster <<= cluster_bits;
  546.                         cluster += bpb_block->datrec;
  547.                         sector_no [vmempage++] = cluster;
  548.                         offset += 4;
  549.                         --count;
  550.                         break;
  551.                     }
  552.                 }
  553.                 offset += 2;
  554.                 break;
  555.             case 2:
  556.                 if ((offset + 8) < bpb_block->recsiz)
  557.                 {
  558.                     if ((*((ULONG *) (buffer + offset)) == 0)
  559.                         && (*((ULONG *) (buffer + offset + 4)) == 0))
  560.                     {
  561.                         *((ULONG *) (buffer + offset)) = 0xFFFFFFFFL;
  562.                         *((ULONG *) (buffer + offset + 4)) = 0xFFFFFFFFL;
  563.                         cluster = sector << (record_bits - cluster_bits);
  564.                         cluster += (offset >> 1) - 2;
  565.                         cluster <<= cluster_bits;
  566.                         cluster += bpb_block->datrec;
  567.                         sector_no [vmempage++] = cluster;
  568.                         offset += 8;
  569.                         --count;
  570.                         break;
  571.                     }
  572.                 }
  573.                 offset += 2;
  574.                 break;
  575.         }
  576.     }
  577.     WRITE_SECTOR (buffer, 1, fat1+sector);
  578.     WRITE_SECTOR (buffer, 1, fat2+sector);
  579.  
  580.     if (cluster > sectors)
  581.         return (NOT_OK);
  582.     else
  583.         return (OK);
  584. }
  585.  
  586.  
  587. /*******************************/
  588. /* Sektoren in FAT2 freigeben: */
  589. /*******************************/
  590.  
  591. void free_sector (vmempage, count)
  592.     VPAGE    vmempage;
  593.     WORD    count;
  594. {
  595.     WORD    fat1, fat2, sector, sector_alt, offset;
  596.     
  597.     fat2 = bpb_block->fatrec;
  598.     fat1 = fat2 - bpb_block->fsiz;
  599.     sector_alt = EMPTY_ENTRY;
  600.  
  601.     while (count-- > 0)
  602.     {
  603.         sector = sector_no [vmempage++] - bpb_block->datrec;
  604.         sector >>= cluster_bits;
  605.         offset = sector = sector + 2;
  606.         sector >>= (record_bits - cluster_bits);
  607.         offset &= sector_mask;
  608.         offset += offset;
  609.  
  610.         if (sector != sector_alt)
  611.         {
  612.             if (sector_alt != EMPTY_ENTRY)
  613.             {
  614.                 WRITE_SECTOR (buffer, 1, fat1+sector_alt);
  615.                 WRITE_SECTOR (buffer, 1, fat2+sector_alt);
  616.             }
  617.             READ_SECTOR (buffer, 1, fat2+sector);
  618.             sector_alt = sector;
  619.         }
  620.  
  621.         switch (size_bits)
  622.         {
  623.             case 0:
  624.                 *((WORD *) (buffer + offset)) = 0;
  625.                 break;
  626.             case 1:
  627.                 *((ULONG *) (buffer + offset)) = 0;
  628.                 break;
  629.             case 2:
  630.                 *((ULONG *) (buffer + offset)) = 0;
  631.                 *((ULONG *) (buffer + offset + 4)) = 0;
  632.                 break;
  633.         }
  634.     }
  635.     WRITE_SECTOR (buffer, 1, fat1+sector);
  636.     WRITE_SECTOR (buffer, 1, fat2+sector);
  637. }
  638.