| @@ -35,7 +35,7 @@ typedef enum { | |||||
| typedef struct { | typedef struct { | ||||
| const uint8_t *data; | const uint8_t *data; | ||||
| DataType *type; | |||||
| DataType *types; | |||||
| size_t size; | size_t size; | ||||
| int8_t slot; | int8_t slot; | ||||
| } ROMBank; | } ROMBank; | ||||
| @@ -189,7 +189,8 @@ static void disassemble_header(Disassembly *dis, const ROM *rom) | |||||
| static ROMBank* init_banks(const ROM *rom) | static ROMBank* init_banks(const ROM *rom) | ||||
| { | { | ||||
| size_t nbanks = NUM_BANKS(rom), i; | 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++) { | for (i = 0; i < nbanks; i++) { | ||||
| if (i == nbanks - 1 && rom->size % MMU_ROM_BANK_SIZE) | if (i == nbanks - 1 && rom->size % MMU_ROM_BANK_SIZE) | ||||
| @@ -197,24 +198,54 @@ static ROMBank* init_banks(const ROM *rom) | |||||
| else | else | ||||
| banks[i].size = MMU_ROM_BANK_SIZE; | banks[i].size = MMU_ROM_BANK_SIZE; | ||||
| banks[i].data = rom->data + (i * 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[i].slot = -1; | ||||
| } | } | ||||
| banks[nbanks].data = NULL; // Sentinel | |||||
| return banks; | return banks; | ||||
| } | } | ||||
| /* | /* | ||||
| Deallocate the given array of ROM 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); | 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. | 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 | 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); | disassemble_header(&dis, rom); | ||||
| ROMBank *banks = init_banks(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); | write_line(&dis, NULL); | ||||
| return dis.lines; | return dis.lines; | ||||