00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00068
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);
00082
00083
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
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
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
00150 if(TMM_PagingEnabled(tm)<0)
00151 {
00152
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 {
00169 int curseg =-1;
00170 int i =-1;
00171 int numStrings=-1;
00172 int segpos =-1;
00173 int abspos =-1;
00174 SegList *list = NULL;
00175
00176 segpos=0;
00177 curseg=0;
00178 list=tm->processList[process]->segments;
00179 list=TMM_SeekSegListHead(list);
00180
00181
00182
00183 tarray=GetTokenLine(fileIn,&numStrings);
00184 while(tarray)
00185 {
00186 for(i=0; i<numStrings; i++)
00187 {
00188
00189
00190 if(segpos>=list->seg.len)
00191 {
00192 segpos=0;
00193 list=list->next;
00194 curseg++;
00195 }
00196
00197
00198 if(list==NULL)
00199 {
00200
00201 TMM_TerminateProcess(tm,process);
00202 FreeType(tarray);
00203 return(ERR_DATAOVERFLOW);
00204 }
00205
00206
00207 if(TMM_PagingEnabled(tm)>=0)
00208 {
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
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)
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
00316
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);
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 }