main.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Giovanni Agosta, Andrea Di Biagio
  3. * Politecnico di Milano, 2007
  4. *
  5. * main.c
  6. * Formal Languages & Compilers Machine, 2007/2008
  7. *
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "fetch.h"
  13. #include "machine.h"
  14. #include "decode.h"
  15. int main(int argc, char **argv)
  16. {
  17. FILE *fp; /* pointer to the object file */
  18. int len=0; /* length of the object file */
  19. unsigned int *code=NULL; /* pointer to the code block */
  20. int lcode = 0; /* length of the code block */
  21. int mmgmt=BASIC; /* memory management */
  22. int i;
  23. int breakat=-1; /* break execution at instruction # */
  24. int count=0; /* iterations counter */
  25. pc=0; /* PC register is set ot zero in the beginning */
  26. #ifdef DEBUG
  27. decoded_instr *current_instr;
  28. #endif
  29. /* Apertura del file oggetto */
  30. if (argc<2)
  31. {
  32. /* L'esecuzione termina poichè non è stato specificato il file
  33. * oggetto come argomento */
  34. fprintf(stdout, "Formal Languages & Compilers Machine, 2007/2008.\n"
  35. "\n\nSyntax:\n\tmace [options] objectfile\n");
  36. return NOARGS;
  37. }
  38. /* apre il file oggetto specificato come argomento */
  39. fp = fopen(argv[argc-1],"r");
  40. if (fp == NULL)
  41. {
  42. fprintf(stderr,"Object file %s doesn't exist.\n", argv[argc-1]);
  43. /* termina l'esecuzione in quanto è stato specificato un file
  44. * oggetto inesistente */
  45. return NOFILE;
  46. }
  47. for(i=1; i<argc-1; i++)
  48. {
  49. if (strcmp(argv[i],"segmented")==0)
  50. mmgmt = SEGMENTED;
  51. else if (strcmp(argv[i],"break")==0)
  52. {
  53. char *error;
  54. /* legge il prossimo argomento come numero in base 10 */
  55. breakat = strtol(argv[i+1],&error,10);
  56. if (*error != '\0')
  57. {
  58. /* errore nella lettura dell'argomento */
  59. #ifdef DEBUG
  60. fprintf(stderr,"Error while reading option "
  61. "break: %d=%c, string=%s "
  62. "=> %d.\n",*error,*error,argv[i+1],breakat);
  63. #endif
  64. return WRONG_ARGS;
  65. }
  66. i++; /* salta l'argomento gia' letto */
  67. }
  68. }
  69. #ifdef DEBUG
  70. fprintf(stderr,"Running with %s memory \n", (mmgmt == BASIC)? "BASIC" : "SEGMENTED");
  71. #endif
  72. /* Resetta i registri e la memoria */
  73. for (i=0; i<NREGS; i++) reg[i] = 0;
  74. for (i=0; i<MEMSIZE; i++) mem[i] = 0;
  75. /* Calcola lunghezza del file */
  76. fseek(fp,0,SEEK_END);
  77. len = ftell(fp);
  78. fseek(fp,0,SEEK_SET);
  79. #ifdef DEBUG
  80. fprintf(stderr,"Available memory: %d. "
  81. "Requested memory: %d \n", MEMSIZE, len);
  82. #endif
  83. if (mmgmt==BASIC)
  84. {
  85. /* Usa una sola area di memoria per codice e dati */
  86. if (len>MEMSIZE)
  87. {
  88. fprintf(stderr,"Out of memory.\n");
  89. return MEM_FAULT;
  90. }
  91. code = (unsigned int*)mem;
  92. } else
  93. {
  94. /* Alloca spazio in memoria per il codice */
  95. code = (unsigned int*) malloc(sizeof(unsigned int)*len);
  96. }
  97. /* Carica il codice macchina in memoria */
  98. for (i=0; i<len; i=i+2)
  99. {
  100. if (i==0)
  101. {
  102. unsigned int c1,c2,c3,c4;
  103. c1 = fgetc(fp);
  104. c2 = fgetc(fp);
  105. c3 = fgetc(fp);
  106. c4 = fgetc(fp);
  107. if (c1!='L' && c2 != 'F' && c3!='C' && c4!='M')
  108. {
  109. #ifdef DEBUG
  110. fprintf(stderr,"Wrong object file format.\n");
  111. #endif
  112. return WRONG_FORMAT;
  113. }
  114. else
  115. {
  116. int value[4];
  117. int found;
  118. int count;
  119. /* initialize the local variables */
  120. count = 0;
  121. found = 0;
  122. memset(value, 0, 4);
  123. while (count < 4)
  124. {
  125. found += fread(value + count, 4, 1, fp);
  126. /* verify the header format */
  127. if (value[count] != 0)
  128. {
  129. #ifdef DEBUG
  130. fprintf(stderr,"Wrong object file format.\n");
  131. #endif
  132. return WRONG_FORMAT;
  133. }
  134. count ++;
  135. }
  136. }
  137. }
  138. if (!fread(code + lcode, 4, 1, fp))
  139. break;
  140. lcode++;
  141. }
  142. #ifdef DEBUG
  143. fprintf(stderr,"Starting execution.\n");
  144. print_regs(stderr);
  145. print_psw(stderr);
  146. print_Memory_Dump(stderr, lcode);
  147. if (pc < lcode) {
  148. current_instr = decode(code[0]);
  149. print(stderr, current_instr);
  150. free(current_instr);
  151. }
  152. #endif
  153. /* decodifica ed esegue il codice */
  154. for (pc=0; pc<lcode && pc>=0; )
  155. {
  156. pc = fetch_execute(code,pc);
  157. #ifdef DEBUG
  158. print_regs(stderr);
  159. print_psw(stderr);
  160. print_Memory_Dump(stderr, lcode);
  161. #endif
  162. reg[0]=0; /* reset R0 to 0; R0 is wired to 0, so we ignore all writes */
  163. count++; /* conta le istruzioni eseguite */
  164. if ((breakat>0) && (breakat<=count))
  165. {
  166. #ifdef DEBUG
  167. fprintf(stderr,"Break after %d instructions.\n",count);
  168. #endif
  169. return BREAK;
  170. }
  171. /* Check the HALT condition */
  172. if (pc == _HALT)
  173. return OK;
  174. #ifdef DEBUG
  175. current_instr = decode(code[pc]);
  176. fprintf(stderr,"\n\n");
  177. print(stderr, current_instr);
  178. free(current_instr);
  179. #endif
  180. }
  181. #ifdef DEBUG
  182. fprintf(stderr,"Memory access error.\n");
  183. #endif
  184. return pc;
  185. }