vm.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. #include <getopt.h>
  19. /* Load program tape into Memory */
  20. void load_program(struct lilith* vm, char* rom_name)
  21. {
  22. FILE* program;
  23. program = fopen(rom_name, "r");
  24. /* Figure out how much we need to load */
  25. fseek(program, 0, SEEK_END);
  26. size_t end = ftell(program);
  27. rewind(program);
  28. /* Deal with the special case of the ROM is bigger than available memory */
  29. if(end > vm->amount_of_Ram)
  30. {
  31. 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);
  32. exit(EXIT_FAILURE);
  33. }
  34. /* Load the entire tape into memory */
  35. fread(vm->memory, 1, end, program);
  36. fclose(program);
  37. }
  38. void execute_vm(struct lilith* vm)
  39. {
  40. struct Instruction* current;
  41. current = calloc(1, sizeof(struct Instruction));
  42. while(!vm->halted)
  43. {
  44. read_instruction(vm, current);
  45. eval_instruction(vm, current);
  46. }
  47. free(current);
  48. return;
  49. }
  50. /* Standard C main program */
  51. int main(int argc, char **argv)
  52. {
  53. int c;
  54. int Memory_Size = (16 * 1024);
  55. tape_01_name = "tape_01";
  56. tape_02_name = "tape_02";
  57. char* rom_name = NULL;
  58. char class;
  59. static struct option long_options[] = {
  60. {"rom", required_argument, 0, 'r'},
  61. {"tape_01", required_argument, 0, '1'},
  62. {"tape_02", required_argument, 0, '2'},
  63. {"memory", required_argument, 0, 'm'},
  64. {"help", no_argument, 0, 'h'},
  65. {0, 0, 0, 0}
  66. };
  67. int option_index = 0;
  68. while ((c = getopt_long(argc, argv, "r:h:1:2:m", long_options, &option_index)) != -1)
  69. {
  70. switch (c)
  71. {
  72. case 0: break;
  73. case 'r':
  74. {
  75. rom_name = optarg;
  76. break;
  77. }
  78. case 'h':
  79. {
  80. fprintf(stdout, "Usage: %s --rom $rom [--tape_01 $foo] [--tape_02 $bar]\n", argv[0]);
  81. exit(EXIT_SUCCESS);
  82. }
  83. case '1':
  84. {
  85. tape_01_name = optarg;
  86. break;
  87. }
  88. case '2':
  89. {
  90. tape_02_name = optarg;
  91. break;
  92. }
  93. case 'm':
  94. {
  95. int length = strlen(optarg) - 1;
  96. class = optarg[length];
  97. optarg[length] = 0;
  98. Memory_Size = atoi(optarg);
  99. if('K' == class)
  100. {
  101. Memory_Size = Memory_Size * 1024;
  102. }
  103. else if('M' == class)
  104. {
  105. Memory_Size = Memory_Size * 1024 * 1024;
  106. }
  107. else if('G' == class)
  108. {
  109. Memory_Size = Memory_Size * 1024 * 1024 * 1024;
  110. }
  111. break;
  112. }
  113. default:
  114. {
  115. exit(EXIT_FAILURE);
  116. }
  117. }
  118. }
  119. if(NULL == rom_name)
  120. {
  121. fprintf(stderr, "Usage: %s --rom $rom [--tape_01 $foo] [--tape_02 $bar]\n", argv[0]);
  122. exit(EXIT_FAILURE);
  123. }
  124. /* Perform all the essential stages in order */
  125. struct lilith* vm;
  126. vm = create_vm(Memory_Size);
  127. load_program(vm, rom_name);
  128. execute_vm(vm);
  129. destroy_vm(vm);
  130. return EXIT_SUCCESS;
  131. }