#include #include #include #include #include #include #include #include #include #include "dcpu16.h" /* * cli driver for dcpu16 core * * Justin Wind * 2012 04 10 - implementation started * */ static const char * const src_id_ = "$Id$"; /* global invocation options */ struct options { unsigned int verbose; } opt_ = { .verbose = 0, }; #define VERBOSE_PRINTF(...) do { if (opt_.verbose) printf(__VA_ARGS__); } while (0) static void usage_(char *prog, unsigned int full) { FILE *f = full ? stdout : stderr; char *x = strrchr(prog, '/'); if (x && *(x + 1)) prog = x + 1; if (full) fprintf(f, "%s -- \n\n", prog); fprintf(f, "Usage: %s [file]\n", prog); if (full) { fprintf(f, "\nOptions:\n" "\t [file] -- ram image to load initially\n" "\t -h -- this screen\n" "\t -v -- verbose execution tracing\n"); fprintf(f, "\n%78s\n", src_id_); } } static int file_load_(struct dcpu16 *vm, char *filename) { FILE *f; size_t r; f = fopen(filename, "rb"); if (f == NULL) { fprintf(stderr, "%s('%s'):%s\n", "fopen", filename, strerror(errno)); return -1; } r = fread(vm->ram, sizeof(DCPU16_WORD), DCPU16_RAM, f); VERBOSE_PRINTF("read %zu words", r); if (ferror(f)) fprintf(stderr, "%s('%s'):%s\n", "fread", filename, strerror(errno)); fclose(f); return 0; } int main(int argc, char **argv) { int c; char *command; char *prompt = "dcpu16> "; struct dcpu16 *vm; while ( (c = getopt(argc, argv, "hv")) != EOF) { switch (c) { case 'v': opt_.verbose++; break; case 'h': usage_(argv[0], 1); exit(EX_OK); default: usage_(argv[0], 0); exit(EX_USAGE); } } if (opt_.verbose < 1) { dcpu16_warn_cb_set(NULL); dcpu16_trace_cb_set(NULL); } else if (opt_.verbose < 2) { dcpu16_trace_cb_set(NULL); } argc -= optind; argv += optind; if ((vm = dcpu16_new()) == NULL) { fprintf(stderr, "could not allocate new dcpu instance\n"); exit(EX_UNAVAILABLE); } if (argc) { file_load_(vm, *argv); } dcpu16_state_print(vm); dcpu16_disassemble_print(vm, vm->pc); while ( (command = readline(prompt)) ) { if (strcasecmp(command, "quit") == 0) break; dcpu16_step(vm); dcpu16_state_print(vm); dcpu16_disassemble_print(vm, vm->pc); } printf("finished\n"); dcpu16_delete(&vm); exit(EX_OK); }