src/disass.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
#include <assert.h> #include <getopt.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "vm.h" char *usage = "Usage: %s [-z] [-s [start_addr]] -i [vmcodefile]\n" "-z (optional): don't display addresses next to disassembly\n" "-s (optional): start disassembly at 'start_addr' in file\n" "-i (required): path to file to disassemble\n"; /* TODO: eventually reimplement assembler in C (going to be annoying) */ /* disassemble_file: */ void disassemble_file(FILE *fp, bool show_addr, uint16_t start_addr) { uint8_t instr[3]; uint16_t start = start_addr; if (start_addr) fseek(fp, (long)start, SEEK_SET); while(!feof(fp)) { if(!fread(instr, 1, 3, fp)) break; if(show_addr) { printf("0x%04x: ", start); start += 3; } print_op_decoded(instr, true); } /*// keep in case I ever want to read instructions from a static buffer for (uint16_t i = 0; i < code_length / 3; i += 3) { instr[0] = rom[i]; instr[1] = rom[i+1]; instr[2] = rom[i+2]; print_decoded(instr); }*/ } int main(int argc, char *argv[]) { int opt; bool show_addr = true; // show address of instructions int start_addr = 0x00; // by default, assume code starts here char infile[4096]; // if file path > 4096, I mean... if (argc < 2) { // expect at least one argument fprintf(stderr, usage, argv[0]); return EXIT_FAILURE; } while ((opt = getopt(argc, argv, "zs:i:")) != -1) { switch (opt) { case 'z': show_addr = false; break; case 's': if (sscanf(optarg, "%i", &start_addr) == EOF) { fprintf(stderr, usage, argv[0]); return EXIT_FAILURE; } break; case 'i': strncpy(infile, optarg, 4096-1); break; case '?': default: fprintf(stderr, usage, argv[0]); return EXIT_FAILURE; } } if (optind > argc) { fprintf(stderr, "Expected arguments after option -i\n"); return EXIT_FAILURE; } FILE *fp = fopen(infile, "rb"); if (fp == NULL) { perror("fopen() failed..."); return EXIT_FAILURE; } // TODO: maybe write assembler in C also, but I'll probably write it in // another lang for now printf("start_addr: %d\n", start_addr); disassemble_file(fp, show_addr, (uint16_t)start_addr); fclose(fp); return EXIT_SUCCESS; } |