|
@@ -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; |
|
|