From 0e0c81589f3c2f8603bd28584b15a60149ed48d1 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Mon, 18 Apr 2016 00:37:23 -0500 Subject: [PATCH] (Very basic) working disassembler. --- src/disassembler.c | 54 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/disassembler.c b/src/disassembler.c index b9906c9..3abe6c4 100644 --- a/src/disassembler.c +++ b/src/disassembler.c @@ -35,7 +35,7 @@ typedef enum { typedef struct { const uint8_t *data; - DataType *type; + DataType *types; size_t size; int8_t slot; } ROMBank; @@ -189,7 +189,8 @@ static void disassemble_header(Disassembly *dis, const ROM *rom) static ROMBank* init_banks(const ROM *rom) { size_t nbanks = NUM_BANKS(rom), i; - ROMBank *banks = cr_malloc(sizeof(ROMBank) * nbanks); + ROMBank *banks = cr_malloc(sizeof(ROMBank) * (nbanks + 1)); + DataType *types = cr_calloc(sizeof(DataType), rom->size); for (i = 0; i < nbanks; i++) { if (i == nbanks - 1 && rom->size % MMU_ROM_BANK_SIZE) @@ -197,24 +198,54 @@ static ROMBank* init_banks(const ROM *rom) else banks[i].size = MMU_ROM_BANK_SIZE; banks[i].data = rom->data + (i * MMU_ROM_BANK_SIZE); - banks[i].type = cr_calloc(sizeof(DataType), banks[i].size); + banks[i].types = types + (i * MMU_ROM_BANK_SIZE); banks[i].slot = -1; } + banks[nbanks].data = NULL; // Sentinel return banks; } /* Deallocate the given array of ROM banks. */ -static void free_banks(const ROM *rom, ROMBank *banks) +static void free_banks(ROMBank *banks) { - size_t nbanks = NUM_BANKS(rom), i; - for (i = 0; i < nbanks; i++) - free(banks[i].type); + free(banks[0].types); free(banks); } /* + Mark the ROM's header as non-binary/non-code inside of the relevant bank. +*/ +static void mark_header(const ROM *rom, ROMBank *banks) +{ + size_t i; + for (i = 0; i < HEADER_SIZE; i++) + banks[0].types[rom->header_location + i] = DT_HEADER; +} + +/* + Render fully analyzed banks into lines of disassembly. +*/ +static void render_banks(Disassembly *dis, ROMBank *banks) +{ + size_t bn = 0, i; + + while (banks[bn].data) { + WRITE_LINE(dis, "") + WRITE_LINE(dis, ";; " HRULE) + WRITE_LINE(dis, "") + WRITE_LINE(dis, ".block $%02zX", bn) + + for (i = 0; i < banks[bn].size; i++) { + if (banks[bn].types[i] == DT_BINARY) + WRITE_LINE(dis, ".byte $%02X", banks[bn].data[i]) + } + bn++; + } +} + +/* Disassemble a ROM into an array of strings, each storing one source line. Each line is newline-terminated. The array itself is terminated with a NULL @@ -229,11 +260,10 @@ char** disassemble(const ROM *rom) disassemble_header(&dis, rom); ROMBank *banks = init_banks(rom); - // TODO - // mark_header(): set DT_HEADER where appropriate - // analyze(): set DT_CODE (future: make labels, slots) where appropriate - // render(): WRITE_LINE a bunch of of times - free_banks(rom, banks); + mark_header(rom, banks); + // TODO: analyze(): set DT_CODE (future: make labels, slots) where appropriate + render_banks(&dis, banks); + free_banks(banks); write_line(&dis, NULL); return dis.lines;