Improved vm scriptability and broke out a minimal vm definition for people wishing to keep implementation trivial

This commit is contained in:
Jeremiah Orians 2017-04-08 15:08:12 -04:00
parent c1e55502d9
commit c369c9c492
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
3 changed files with 141 additions and 17 deletions

View File

@ -15,33 +15,41 @@
## along with stage0. If not, see <http://www.gnu.org/licenses/>. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
# Collections of tools
all: libvm vm all: libvm vm
libvm: wrapper.c vm_instructions.c vm_decode.c vm.h tty.c production: libvm-production vm-production asm dis
gcc -ggdb -Dtty_lib=true -shared -Wl,-soname,libvm.so -o libvm.so -fPIC wrapper.c vm_instructions.c vm_decode.c vm.h tty.c
development: vm libvm asm dis
# VM Builds
vm-minimal: vm.h vm_minimal.c vm_instructions.c vm_decode.c
gcc vm.h vm_minimal.c vm_instructions.c vm_decode.c -o bin/vm
vm: vm.h vm.c vm_instructions.c vm_decode.c tty.c vm: vm.h vm.c vm_instructions.c vm_decode.c tty.c
gcc -ggdb -Dtty_lib=true vm.h vm.c vm_instructions.c vm_decode.c tty.c -o bin/vm gcc -ggdb -Dtty_lib=true vm.h vm.c vm_instructions.c vm_decode.c tty.c -o bin/vm
vm-production: vm.h vm.c vm_instructions.c vm_decode.c
gcc vm.h vm.c vm_instructions.c vm_decode.c -o bin/vm
vm-trace: vm.h vm.c vm_instructions.c vm_decode.c tty.c dynamic_execution_trace.c vm-trace: vm.h vm.c vm_instructions.c vm_decode.c tty.c dynamic_execution_trace.c
gcc -ggdb -Dtty_lib=true -DTRACE=true vm.h vm.c vm_instructions.c vm_decode.c tty.c dynamic_execution_trace.c -o bin/vm gcc -ggdb -Dtty_lib=true -DTRACE=true vm.h vm.c vm_instructions.c vm_decode.c tty.c dynamic_execution_trace.c -o bin/vm
production: libvm-production vm-production asm dis # libVM Builds for Development tools
libvm: wrapper.c vm_instructions.c vm_decode.c vm.h tty.c
gcc -ggdb -Dtty_lib=true -shared -Wl,-soname,libvm.so -o libvm.so -fPIC wrapper.c vm_instructions.c vm_decode.c vm.h tty.c
libvm-production: wrapper.c vm_instructions.c vm_decode.c vm.h libvm-production: wrapper.c vm_instructions.c vm_decode.c vm.h
gcc -shared -Wl,-soname,libvm.so -o libvm.so -fPIC wrapper.c vm_instructions.c vm_decode.c vm.h gcc -shared -Wl,-soname,libvm.so -o libvm.so -fPIC wrapper.c vm_instructions.c vm_decode.c vm.h
vm-production: vm.h vm.c vm_instructions.c vm_decode.c # Primitive development tools, not required but it was handy
gcc vm.h vm.c vm_instructions.c vm_decode.c -o bin/vm
development: vm libvm asm dis
asm: High_level_prototypes/asm.c asm: High_level_prototypes/asm.c
gcc -ggdb High_level_prototypes/asm.c -o bin/asm gcc -ggdb High_level_prototypes/asm.c -o bin/asm
dis: High_level_prototypes/disasm.c dis: High_level_prototypes/disasm.c
gcc -ggdb High_level_prototypes/disasm.c -o bin/dis gcc -ggdb High_level_prototypes/disasm.c -o bin/dis
# Clean up after ourselves
clean: clean:
rm libvm.so bin/vm rm libvm.so bin/vm

62
vm.c
View File

@ -16,12 +16,13 @@
*/ */
#include "vm.h" #include "vm.h"
#include <getopt.h>
/* Load program tape into Memory */ /* Load program tape into Memory */
void load_program(struct lilith* vm, char **argv) void load_program(struct lilith* vm, char* rom_name)
{ {
FILE* program; FILE* program;
program = fopen(argv[1], "r"); program = fopen(rom_name, "r");
/* Figure out how much we need to load */ /* Figure out how much we need to load */
fseek(program, 0, SEEK_END); fseek(program, 0, SEEK_END);
@ -52,19 +53,62 @@ void execute_vm(struct lilith* vm)
/* Standard C main program */ /* Standard C main program */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* Make sure we have a program tape to run */ int c;
if (argc < 2)
tape_01_name = "tape_01";
tape_02_name = "tape_02";
char* rom_name = NULL;
static struct option long_options[] = {
{"rom", required_argument, 0, 'r'},
{"tape_01", required_argument, 0, '1'},
{"tape_02", required_argument, 0, '2'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
int option_index = 0;
while ((c = getopt_long(argc, argv, "r:h:1:2", long_options, &option_index)) != -1)
{ {
fprintf(stderr, "Usage: %s $FileName\nWhere $FileName is the name of the paper tape of the program being run\n", argv[0]); switch (c)
return EXIT_FAILURE; {
case 0: break;
case 'r':
{
rom_name = optarg;
break;
}
case 'h':
{
fprintf(stdout, "Usage: %s --rom $rom [--tape_01 $foo] [--tape_02 $bar]\n", argv[0]);
exit(EXIT_SUCCESS);
}
case '1':
{
tape_01_name = optarg;
break;
}
case '2':
{
tape_02_name = optarg;
break;
}
default:
{
exit(EXIT_FAILURE);
}
}
}
if(NULL == rom_name)
{
fprintf(stderr, "Usage: %s --rom $rom [--tape_01 $foo] [--tape_02 $bar]\n", argv[0]);
exit(EXIT_FAILURE);
} }
/* Perform all the essential stages in order */ /* Perform all the essential stages in order */
struct lilith* vm; struct lilith* vm;
tape_01_name = "tape_01";
tape_02_name = "tape_02";
vm = create_vm(1 << 21); vm = create_vm(1 << 21);
load_program(vm, argv); load_program(vm, rom_name);
execute_vm(vm); execute_vm(vm);
destroy_vm(vm); destroy_vm(vm);

72
vm_minimal.c Normal file
View File

@ -0,0 +1,72 @@
/* Copyright (C) 2016 Jeremiah Orians
* This file is part of stage0.
*
* stage0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* stage0 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with stage0. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vm.h"
/* Load program tape into Memory */
void load_program(struct lilith* vm, char **argv)
{
FILE* program;
program = fopen(argv[1], "r");
/* Figure out how much we need to load */
fseek(program, 0, SEEK_END);
size_t end = ftell(program);
rewind(program);
/* Load the entire tape into memory */
fread(vm->memory, 1, end, program);
fclose(program);
}
void execute_vm(struct lilith* vm)
{
struct Instruction* current;
current = calloc(1, sizeof(struct Instruction));
while(!vm->halted)
{
read_instruction(vm, current);
eval_instruction(vm, current);
}
free(current);
return;
}
/* Standard C main program */
int main(int argc, char **argv)
{
/* Make sure we have a program tape to run */
if (argc < 2)
{
fprintf(stderr, "Usage: %s $FileName\nWhere $FileName is the name of the paper tape of the program being run\n", argv[0]);
return EXIT_FAILURE;
}
/* Perform all the essential stages in order */
struct lilith* vm;
tape_01_name = "tape_01";
tape_02_name = "tape_02";
vm = create_vm(1 << 21);
load_program(vm, argv);
execute_vm(vm);
destroy_vm(vm);
return EXIT_SUCCESS;
}