Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields  

ToyLoad.c

00001 /***************************************************************************
00002                           ToyLoad.c
00003 
00004     Contains the code for processing .lod files.
00005                              -------------------
00006     begin                : Sat Jan 25 2003
00007     copyright            : (C) 2003 by Tyler Montbriand
00008     student #            : 200200370
00009     class                : CS330
00010     email                : monttyle@heavyspace.ca
00011 
00012    TODO - convert from from Explodee calls to LineToType calls
00013     
00014  ***************************************************************************/
00015 
00016 #include<stdlib.h>
00017 #include<stdio.h>
00018 #include<string.h>
00019 #include<ctype.h>
00020 
00021 #include "ToySegment.h"
00022 #include "ToySegmentList.h"
00023 #include "ToyProcess.h"
00024 #include "ToyMemType.h"
00025 #include "ToyMem.h"
00026 #include "ToyMemPage.h"
00027 #include "ToyVirtualMem.h"
00028 #include "ToyMem_Internal.h"
00029 #include "toyparse.h"
00030 #include "ToyLoad.h"
00031 #include "ToySwap.h"
00032 
00034 const char  *DataType_Magic[]       = {  "8585",NULL           };
00036 const char  *DataType_Integer[]     = {  "%u","#%u",NULL       };
00038 const char  *DataType_String[]      = {  "\"%s",NULL           };
00040 const char  *DataType_Instruction[] = {  "RUN","HALT",NULL     };
00042 const char **DataType_List[]        = { DataType_Magic,
00043                                         DataType_Integer,
00044                                         DataType_String,
00045                                         DataType_Instruction,
00046                                         NULL                  };
00047 
00048  
00053 TokenType *GetTokenLine(FILE *fp, int *n);
00054 
00059 ErrMessage_t TMM_Load(ToyMM *tm, int process, const char *filename, int addr)
00060 {
00061   int n           =-1;
00062   int numSegments =-1;
00063   int segSizes[4] ={-1,-1,-1,-1};
00064   FILE *fileIn    =NULL;
00065   TokenType *tarray=NULL;
00066   
00067   /*  Can't open nonexistent files,
00068       nor use nonexistent toy-mm's  */
00069   if((tm==NULL)||(filename==NULL))          return(ERR_UNKNOWN);
00070   else if((process<0)||(process>=MAX_PROCESSES))
00071   {
00072     return(ERR_UNKNOWN);
00073   }
00074   else if(tm->processList[process]!=NULL)
00075   {
00076     return(ERR_PROCESSEXISTS);
00077   }
00078 
00079   fileIn=fopen(filename,"r");
00080 
00081   if(fileIn==NULL)  return(ERR_NOFILE); /*  Couldn't open file*/
00082 
00083   /*  Get 1st line.  Should be magic #. */
00084   tarray=GetTokenLine(fileIn,&n);
00085   if(CheckLineSyntax(tarray,DATA_MAGIC,0,TYPE_ENDCLOSE)<0)
00086   {
00087     fclose(fileIn);    
00088     FreeType(tarray);
00089     return(ERR_INVALIDFILE);
00090   }
00091   FreeType(tarray);
00092 
00093   /*  Get 2nd line.  Should be # segments.  */
00094   tarray=GetTokenLine(fileIn,&n);
00095   if(CheckLineSyntax(tarray,DATA_INTEGER,0,TYPE_ENDCLOSE)<0)
00096   {
00097     fclose(fileIn);    
00098     FreeType(tarray);
00099     return(ERR_INVALIDFILE);
00100   }
00101   else if(sscanf(tarray[0].token,"%d",&numSegments)!=1)
00102   {
00103     fclose(fileIn);    
00104     FreeType(tarray);
00105     return(ERR_INVALIDFILE);
00106   }
00107   else if((numSegments<=0)||(numSegments>4))
00108   {
00109     fclose(fileIn);    
00110     FreeType(tarray);
00111     return(ERR_INVALIDFILE);
00112   }
00113 
00114   FreeType(tarray);
00115 
00116   /*  Get the segment sizes.  Should be like "1 3 8 4"  */
00117   tarray=GetTokenLine(fileIn,&n);
00118   if(tarray==NULL)  return(ERR_INVALIDFILE);
00119   else if(n!=numSegments)
00120   {
00121     fclose(fileIn);    
00122     FreeType(tarray);
00123     return(ERR_INVALIDINSTRUCTION);
00124   }
00125   
00126   for(n=0; n<numSegments; n++)
00127   {
00128     if(tarray[n].type!=DATA_INTEGER)
00129     {
00130       fclose(fileIn);      
00131       FreeType(tarray);
00132       return(ERR_INVALIDFILE);
00133     }
00134     else if(sscanf(tarray[n].token,"%d",&segSizes[n])!=1)
00135     {
00136       fclose(fileIn);      
00137       FreeType(tarray);
00138       return(ERR_INVALIDFILE);      
00139     }
00140     else if(segSizes[n]<=0)
00141     {
00142       fclose(fileIn);      
00143       FreeType(tarray);
00144       return(ERR_INVALIDFILE);      
00145     }
00146   }
00147   FreeType(tarray);
00148 
00149   /*  Allocate the process. */
00150   if(TMM_PagingEnabled(tm)<0)
00151   {
00152     /*  Different allocation functions for paged and non-paged. */
00153     if(TMM_AllocateProcessAt(tm,process,addr,numSegments,segSizes)!=ERR_NONE)
00154     {
00155       fclose(fileIn);
00156       return(ERR_INSUFFICIENTMEM);
00157     }
00158   }
00159   else
00160   {
00161     if(TMM_PagedAllocateProcess(tm,process,numSegments,segSizes)!=ERR_NONE)
00162     {
00163       fclose(fileIn);
00164       return(ERR_INSUFFICIENTMEM);
00165     }
00166   }
00167 
00168   { /*  OK, now we're cookin'.  Load stuff into memory! */
00169     int curseg    =-1;
00170     int i         =-1;
00171     int numStrings=-1;      /*  # of strings in list  */
00172     int segpos    =-1;      /*  Position in segment   */
00173     int abspos    =-1;      /*  absolute memory position  */
00174     SegList *list = NULL;   /*  Current segment       */
00175     
00176     segpos=0;
00177     curseg=0;
00178     list=tm->processList[process]->segments;  /*Get the list of segments*/
00179     list=TMM_SeekSegListHead(list);
00180 
00181 
00182     /*  Get the next line of input  */
00183     tarray=GetTokenLine(fileIn,&numStrings);    
00184     while(tarray)
00185     {
00186       for(i=0; i<numStrings; i++)
00187       {
00188         /*  If we've reached the end of this segment,
00189             advance to the next one.                */
00190         if(segpos>=list->seg.len)
00191         {
00192           segpos=0;
00193           list=list->next;
00194           curseg++;
00195         }
00196 
00197         /*  If there is no next segment, we're out of memory. */
00198         if(list==NULL)
00199         {
00200           /*  Out of segment space! */
00201           TMM_TerminateProcess(tm,process);
00202           FreeType(tarray);
00203           return(ERR_DATAOVERFLOW);
00204         }
00205 
00206         /* In paged mode, we have to allocate the frames as we go */
00207         if(TMM_PagingEnabled(tm)>=0)
00208         { /* Figure out what page we're on */
00209           int page=(segpos+list->seg.pos)/tm->pageSize;
00210 
00211           if(TMM_PageFree(tm,process,page)>=0)
00212           {
00213             int frame=TMM_FindFreeFrame(tm);
00214             if(frame<0)
00215             {
00216               printf("Error - Could not find a free page\n");
00217               printf("Email me at monttyle@heavyspace.ca - tell me what you did\n");
00218               abort();
00219             }
00220             else
00221             {
00222               TMM_AssignFrame(tm,process,frame,page);
00223             }
00224           }
00225         }
00226 
00227 
00228         /* Calculate our position in memory */
00229         abspos=TMM_GetRealAddress(tm,process,segpos+list->seg.pos);
00230         if(abspos<0)
00231         {
00232           printf("Virtual address fault!\n");
00233           TMM_TerminateProcess(tm,process);
00234           return(ERR_UNKNOWN);
00235         }
00236 
00237         switch(curseg)
00238         {
00239         case SEG_CODE:
00240           if(tarray[i].type!=DATA_INSTRUCTION)
00241           {
00242             FreeType(tarray);
00243             fclose(fileIn);
00244             TMM_TerminateProcess(tm,process);
00245             return(ERR_INVALIDINSTRUCTION);
00246           }
00247           break;
00248 
00249         case SEG_DATA:
00250           if((tarray[i].type!=DATA_INTEGER)&&(tarray[i].type!=DATA_STRING))
00251           {
00252             FreeType(tarray);
00253             fclose(fileIn);
00254             TMM_TerminateProcess(tm,process);
00255             return(ERR_INVALIDDATA);
00256           }
00257           break;
00258 
00259         default:
00260           FreeType(tarray);
00261           fclose(fileIn);
00262           TMM_TerminateProcess(tm,process);
00263           return(ERR_DATAOVERFLOW);
00264         }        
00265 
00266         if(tarray[i].type==DATA_ERROR)  /*  If the parser doesn't recognize it  */
00267         {
00268           FreeType(tarray);
00269           fclose(fileIn);
00270           return(ERR_INVALIDDATA);
00271         }
00272 
00273         tm->mem[abspos].type=(DataType_e)tarray[i].type;
00274 
00275         switch(tarray[i].type)
00276         {
00277         default:
00278           printf("Unknown type %d\n",tarray[i].type);
00279           printf("Email me at monttyle@heavyspace.ca and tell me how you did this.\n");
00280           abort();
00281           break;
00282           
00283         case DATA_INTEGER:
00284           {
00285             int val;
00286             sscanf(tarray[i].token+1,"%d",&val);
00287             tm->mem[abspos].integer.value=val;
00288           }
00289           break;
00290         case DATA_INSTRUCTION:
00291           tm->mem[abspos].integer.value=tarray[i].subtype;
00292           break;
00293 
00294         case DATA_STRING:
00295           tm->mem[abspos].string.value[0]='\0';
00296           if(strlen(tarray[i].token)>MAX_STRLEN)
00297           {
00298             FreeType(tarray);
00299             fclose(fileIn);
00300             return(ERR_INVALIDDATA);
00301             break;
00302           }
00303 
00304           strcpy(tm->mem[abspos].string.value,tarray[i].token+1);
00305           break;
00306         }
00307 
00308         segpos++;
00309       }
00310       FreeType(tarray);  
00311       tarray=GetTokenLine(fileIn,&numStrings);
00312     }
00313 
00314 
00315     /* Cleanup - if we're in paged mode, we might have to add in the
00316        last frames that didn't get allocated before.                 */
00317     if(TMM_PagingEnabled(tm)>=0)
00318     while(list)
00319     {
00320       for(segpos=list->seg.pos; segpos<list->seg.pos+list->seg.len; segpos+=tm->pageSize)
00321       {
00322         int page=segpos/tm->pageSize;
00323         if(TMM_PageFree(tm,process,page)>=0)
00324         {
00325           int frame=TMM_FindFreeFrame(tm);
00326           if(frame<0)
00327           {
00328             printf("Couldn't find a free page!\n");
00329             printf("Tell me how you did this at monttyle@heavyspace.ca\n");
00330             abort();
00331           }
00332           else
00333           {
00334             TMM_AssignFrame(tm,process,frame,page);
00335           }
00336         }
00337       }
00338       list=list->next;
00339     }
00340 
00341   }
00342   
00343   
00344   fclose(fileIn);
00345   return(ERR_NONE);
00346 }
00347 
00348 
00353 TokenType *GetTokenLine(FILE *fp, int *n)
00354 {
00355   char buf[300];
00356   TokenType *tarray=NULL;
00357   buf[0]='\0';
00358 
00359   if(feof(fp))
00360   {
00361     if(n!=NULL) (*n)=0;
00362     return(NULL);
00363   }
00364   fgets(buf,300,fp);    /*  Get text                  */
00365   tarray=LineToTypes(buf,DataType_List);
00366 
00367   if((tarray!=NULL)&&(n!=NULL))
00368   {
00369     for((*n)=0; tarray[(*n)].token!=NULL; (*n)++);
00370 
00371     return(tarray);
00372   }
00373   else
00374   {
00375     (*n)=0;
00376     return(NULL);
00377   }
00378 }

Generated on Fri Apr 4 14:29:07 2003 for ToyMem by doxygen1.3-rc3