Browse Source

(Very basic) working disassembler.

master
Ben Kurtovic 8 years ago
parent
commit
0e0c81589f
1 changed files with 42 additions and 12 deletions
  1. +42
    -12
      src/disassembler.c

+ 42
- 12
src/disassembler.c View File

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


Loading…
Cancel
Save