home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / virt.lha / Virtual.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-14  |  3.8 KB  |  165 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1992 by Amit Fridman
  4.  *
  5.  *    Name .....: Virtual.c
  6.  *    Created ..: Friday 13-Nov-92 15:21:53
  7.  *    Revision .: 1
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    14-Nov-92   Amit Fridman           Version 1.0 finished
  12.  *    13-Nov-92   Amit Fridman           Created this file!
  13.  *
  14.  * $Revision Header ********************************************************/
  15. #define REVISION    1
  16.  
  17. #include <exec/memory.h>
  18. #include <libraries/dos.h>
  19. #include <string.h>
  20. #include "Virtual.h"
  21.  
  22. static char *VMFindBase(struct VirtMem *vm,struct SegEntry *seg,ULONG size,struct SegEntry **postseg,struct SegEntry **preseg);
  23.  
  24.  
  25. BOOL InitVirtualMem(struct VirtMem *vm,const char *FName,
  26.                                 ULONG VirtSize,ULONG PhysSize,USHORT SegNum)
  27. {
  28.     vm->File=Open(FName,MODE_NEWFILE);
  29.     if (vm->File) {
  30.         vm->PhysMem=AllocMem(PhysSize,0);
  31.         if (vm->PhysMem) {
  32.             vm->Segments=AllocMem(SegNum*sizeof(struct SegEntry),MEMF_CLEAR);
  33.             if (vm->Segments) {
  34.                 vm->PSegments=NULL;
  35.                 vm->VirtSize=VirtSize;
  36.                 vm->PhysSize=PhysSize;
  37.                 vm->SegNum=SegNum;
  38.                 strcpy(vm->FName,FName);
  39.                 vm->AccOffset=0;
  40.                 vm->Count=0;
  41.                 return(TRUE);
  42.             }
  43.         }
  44.         FreeMem(vm->PhysMem,PhysSize);
  45.     }
  46.     Close(vm->File);
  47.     return(FALSE);
  48. }
  49.  
  50. void FreeVirtMem(struct VirtMem *vm)
  51. {
  52.     FreeMem(vm->Segments,vm->SegNum*sizeof(struct SegEntry));
  53.     FreeMem(vm->PhysMem,vm->PhysSize);
  54.     Close(vm->File);
  55.     DeleteFile(vm->FName);
  56. }
  57.  
  58. struct SegEntry *CreateSegment(struct VirtMem *vm,ULONG size,SHORT pri)
  59. {
  60.     register int i;
  61.     struct SegEntry *seg;
  62.  
  63.     if (size>vm->PhysSize) return(NULL);
  64.     for (i=0; i<vm->SegNum; i++)
  65.         if (!(vm->Segments[i].Flags & SF_USED)) break;
  66.     if (i==vm->SegNum) return(NULL);
  67.     seg=&vm->Segments[i];
  68.     seg->NextP=NULL;
  69.     seg->Base=NULL;
  70.     seg->Size=size;
  71.     seg->FOffset=vm->AccOffset;
  72.     seg->Access=0;
  73.     seg->Pri=pri;
  74.     seg->Flags=SF_USED;
  75.     vm->AccOffset+=size;
  76.     Seek(vm->File,seg->FOffset,OFFSET_BEGINNING);
  77.     Write(vm->File,vm->PhysMem,size);
  78.     return(seg);
  79. }
  80.  
  81. BOOL Access(struct VirtMem *vm,struct SegEntry *seg)
  82. {
  83.     char *Base;
  84.     struct SegEntry *seg1,*seg2;
  85.     ULONG len;
  86.  
  87.     seg->Access=vm->Count;
  88.     vm->Count++;
  89.     if (seg->Flags & SF_PRESENT) return(TRUE);
  90.     Base=VMFindBase(vm,seg,seg->Size,&seg1,&seg2);
  91.     seg->Base=Base;
  92.     seg->Flags|=SF_PRESENT;
  93.     seg->NextP=seg1;
  94.     if (seg2)
  95.         seg2->NextP=seg;
  96.     else
  97.         vm->PSegments=seg;
  98.     if (!(seg->Flags & SF_INFILE)) return(TRUE);
  99.     Seek(vm->File,seg->FOffset,OFFSET_BEGINNING);
  100.     len=Read(vm->File,seg->Base,seg->Size);
  101.     return(len==seg->Size);
  102. }
  103.  
  104. static char *VMFindBase(struct VirtMem *vm,struct SegEntry *seg,ULONG size,
  105.                                     struct SegEntry **postseg,struct SegEntry **preseg)
  106. {
  107.     struct SegEntry *seg1,*seg2;
  108.     char *Base;
  109.     SHORT lowPri;
  110.     ULONG access;
  111.     struct SegEntry *ss1,*ss2;
  112.  
  113.     while (1) {
  114.         Base=vm->PhysMem;
  115.         seg1=vm->PSegments;
  116.         if (!seg1) {
  117.             *postseg=NULL;
  118.             *preseg=NULL;
  119.             return(Base);
  120.         }
  121.         seg2=NULL;
  122.         while (seg1) {
  123.             if (Base+size<=seg1->Base) { 
  124.                 *postseg=seg1;
  125.                 *preseg=seg2;
  126.                 return(Base);
  127.             }
  128.             Base=seg1->Base+seg1->Size;
  129.             seg2=seg1;
  130.             seg1=seg1->NextP;
  131.         }
  132.         if (Base+size<=vm->PhysMem+vm->PhysSize) {
  133.             *postseg=seg1;
  134.             *preseg=seg2;
  135.             return(Base);
  136.         }
  137.         lowPri=32767;
  138.         access=1<<31;
  139.         for (seg1=vm->PSegments,seg2=NULL; seg1; seg2=seg1,seg1=seg1->NextP)
  140.             if (seg1->Pri<lowPri) {
  141.                 lowPri=seg1->Pri;
  142.                 access=seg1->Access;
  143.                 ss1=seg1;
  144.                 ss2=seg2;
  145.             } else
  146.                 if ((seg1->Pri==lowPri) && (seg1->Access<access)) {
  147.                     access=seg1->Access;
  148.                     ss1=seg1;
  149.                     ss2=seg2;
  150.                 }
  151.         if (ss2)
  152.             ss2->NextP=ss1->NextP;
  153.         else
  154.             vm->PSegments=ss1->NextP;
  155.         if (ss1->Flags & SF_DIRTY) {
  156.             Seek(vm->File,ss1->FOffset,OFFSET_BEGINNING);
  157.             Write(vm->File,ss1->Base,ss1->Size);
  158.             ss1->Flags^=SF_DIRTY;
  159.         }
  160.         ss1->Flags^=SF_PRESENT;
  161.         ss1->Flags|=SF_INFILE;
  162.     }
  163.     return(NULL);
  164. }
  165.