vm.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* Copyright (C) 2016 Jeremiah Orians
  2. * This file is part of stage0.
  3. *
  4. * stage0 is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * stage0 is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with stage0. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "vm.h"
  18. int Memory_Size;
  19. /* Load program tape into Memory */
  20. size_t load_program(struct lilith* vm, char* rom_name)
  21. {
  22. FILE* program;
  23. program = fopen(rom_name, "r");
  24. if(NULL == program)
  25. {
  26. fprintf(stderr, "The rom file: %s could not be found\nif you are running the make; you forgot the git submodules\nPlease review the section: \"Need to know information\" in the README\n", rom_name);
  27. exit(EXIT_FAILURE);
  28. }
  29. /* Figure out how much we need to load */
  30. fseek(program, 0, SEEK_END);
  31. size_t end = ftell(program);
  32. rewind(program);
  33. /* Deal with the special case of the ROM is bigger than available memory */
  34. if(end > vm->amount_of_Ram)
  35. {
  36. fprintf(stderr, "Program %s is %d bytes large but only %d bytes of memory have been allocated!\n", rom_name, (int)end, (int)vm->amount_of_Ram);
  37. exit(EXIT_FAILURE);
  38. }
  39. /* Load the entire tape into memory */
  40. fread(vm->memory, 1, end, program);
  41. fclose(program);
  42. return end;
  43. }
  44. void execute_vm(struct lilith* vm)
  45. {
  46. struct Instruction* current;
  47. current = calloc(1, sizeof(struct Instruction));
  48. while(!vm->halted)
  49. {
  50. read_instruction(vm, current);
  51. eval_instruction(vm, current);
  52. }
  53. free(current);
  54. return;
  55. }
  56. /* Standard C main program */
  57. int main(int argc, char **argv)
  58. {
  59. POSIX_MODE = false;
  60. FUZZING = false;
  61. char* c;
  62. int length;
  63. Memory_Size = (16 * 1024);
  64. int Stack_Size = (64 * 1024);
  65. tape_01_name = "tape_01";
  66. tape_02_name = "tape_02";
  67. TTY_out = stdout;
  68. TTY_in = stdin;
  69. char* rom_name = NULL;
  70. char class;
  71. int i = 1;
  72. while(i <= argc)
  73. {
  74. if(NULL == argv[i])
  75. {
  76. i = i + 1;
  77. }
  78. else if(match(argv[i], "-r") || match(argv[i], "--rom") || match(argv[i], "--tape-00") || match(argv[i], "-0"))
  79. {
  80. rom_name = argv[i + 1];
  81. i = i + 2;
  82. }
  83. else if(match(argv[i], "-h") || match(argv[i], "--help"))
  84. {
  85. fprintf(stdout, "Usage: %s --rom $rom [--tape_01 $foo] [--tape_02 $bar]\n", argv[0]);
  86. exit(EXIT_SUCCESS);
  87. }
  88. else if(match(argv[i], "-1") || match(argv[i], "--tape_01") || match(argv[i], "--tape-01"))
  89. {
  90. tape_01_name = argv[i + 1];
  91. i = i + 2;
  92. }
  93. else if(match(argv[i], "-2") || match(argv[i], "--tape_02") || match(argv[i], "--tape-02"))
  94. {
  95. tape_02_name = argv[i + 1];
  96. i = i + 2;
  97. }
  98. else if(match(argv[i], "--tty-in"))
  99. {
  100. TTY_in = fopen(argv[i+1], "r");
  101. require(NULL != TTY_in, "unable to open file for --tty-in\n");
  102. i = i + 2;
  103. }
  104. else if(match(argv[i], "--tty-out"))
  105. {
  106. TTY_out = fopen(argv[i+1], "w");
  107. require(NULL != TTY_out, "unable to open file for --tty-out\n");
  108. i = i + 2;
  109. }
  110. else if(match(argv[i], "-m") || match(argv[i], "--memory"))
  111. {
  112. length = strlen(argv[i + 1]) - 1;
  113. c = argv[i+1];
  114. class = c[length];
  115. if('K' == class)
  116. {
  117. c[length] = 0;
  118. Memory_Size = atoi(c);
  119. Memory_Size = Memory_Size * 1024;
  120. }
  121. else if('M' == class)
  122. {
  123. c[length] = 0;
  124. Memory_Size = atoi(c);
  125. Memory_Size = Memory_Size * 1024 * 1024;
  126. }
  127. else if('G' == class)
  128. {
  129. c[length] = 0;
  130. Memory_Size = atoi(c);
  131. Memory_Size = Memory_Size * 1024 * 1024 * 1024;
  132. }
  133. else
  134. {
  135. Memory_Size = atoi(c);
  136. }
  137. i = i + 2;
  138. }
  139. else if(match(argv[i], "-s") || match(argv[i], "--stack"))
  140. {
  141. length = strlen(argv[i + 1]) - 1;
  142. c = argv[i+1];
  143. class = c[length];
  144. if('K' == class)
  145. {
  146. c[length] = 0;
  147. Stack_Size = atoi(c);
  148. Stack_Size = Stack_Size * 1024;
  149. }
  150. else if('M' == class)
  151. {
  152. c[length] = 0;
  153. Stack_Size = atoi(c);
  154. Stack_Size = Stack_Size * 1024 * 1024;
  155. }
  156. else if('G' == class)
  157. {
  158. c[length] = 0;
  159. Stack_Size = atoi(c);
  160. Stack_Size = Stack_Size * 1024 * 1024 * 1024;
  161. }
  162. else
  163. {
  164. Stack_Size = atoi(c);
  165. }
  166. i = i + 2;
  167. }
  168. else if(match(argv[i], "-P") || match(argv[i], "--POSIX-MODE") || match(argv[i], "--posix-mode"))
  169. {
  170. POSIX_MODE = true;
  171. i = i + 1;
  172. }
  173. else if(match(argv[i], "-F") || match(argv[i], "--fuzzing"))
  174. {
  175. FUZZING = true;
  176. i = i + 1;
  177. }
  178. else
  179. {
  180. fprintf(stderr, "unknown option %s\n", argv[i]);
  181. exit(EXIT_FAILURE);
  182. }
  183. }
  184. if(NULL == rom_name)
  185. {
  186. fprintf(stderr, "Usage: %s --rom $rom [--tape_01 $foo] [--tape_02 $bar]\n", argv[0]);
  187. exit(EXIT_FAILURE);
  188. }
  189. /* Perform all the essential stages in order */
  190. struct lilith* vm;
  191. size_t image;
  192. vm = create_vm(Memory_Size);
  193. image = load_program(vm, rom_name);
  194. if(POSIX_MODE)
  195. {
  196. /* Set HEAP pointer */
  197. vm->reg[12] = image + Stack_Size;
  198. /* HEAP starts right after stack ends */
  199. /* Set STACK pointer */
  200. vm->reg[15] = image;
  201. /* STACK starts right after core image ends */
  202. }
  203. execute_vm(vm);
  204. destroy_vm(vm);
  205. return EXIT_SUCCESS;
  206. }