Improved vm scriptability and broke out a minimal vm definition for people wishing to keep implementation trivial
This commit is contained in:
parent
c1e55502d9
commit
c369c9c492
24
makefile
24
makefile
|
@ -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
62
vm.c
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue