diff --git a/disas/main.c b/disas/main.c index 2c21a9a..c52e83c 100644 --- a/disas/main.c +++ b/disas/main.c @@ -11,9 +11,25 @@ #define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \ | OP_ADDR_IMM | OP_ADDR_ABS) +#define COLOR_RED 31 +#define COLOR_GREEN 32 +#define COLOR_YELLOW 33 +#define COLOR_BLUE 34 +#define COLOR_RESET 0 + char *prg_name; FILE *input; FILE *output; +int colorize = 1; + +void +term_color(FILE *stream, int color) +{ + if (!colorize) return; + + fprintf(stream, "\033[%dm", color); +} + uint8_t readu8(void) @@ -85,16 +101,40 @@ fatal(const char *str, ...) { va_list ap; + term_color(stderr, COLOR_RED); fprintf(stderr, "%s: ", prg_name); va_start(ap, str); vfprintf(stderr, str, ap); va_end(ap); fprintf(stderr, "\n"); + term_color(stderr, COLOR_RESET); exit(EXIT_FAILURE); } -void +static void +decode_value(int size, int is_addr) +{ + term_color(output, COLOR_GREEN); + if (!is_addr) fprintf(output, "#"); + switch (size) + { + case SIZE_BYTE: + fprintf(output, "$%X", readu8()); + break; + case SIZE_WORD: + fprintf(output, "$%hX", readu16()); + break; + case SIZE_LONG: + fprintf(output, "$%X", readu32()); + break; + default: + break; + } + term_color(output, COLOR_RESET); +} + +static void decode_target_suffix(uint8_t attr) { fprintf(output, "."); @@ -117,23 +157,41 @@ decode_target_suffix(uint8_t attr) } } -void -decode_address(uint8_t attr) +static void +decode_opcode(uint8_t opcode, uint8_t attr) { - switch (GET_ADDRESS_SIZE(attr)) + uint8_t addressing; + + addressing = opcode_addr[opcode]; + term_color(output, COLOR_BLUE); + fprintf(output, "%s", opcode_str[opcode]); + if ((addressing & OP_ADDR_IMPL) == 0 + && (addressing & OP_ADDR_REL) == 0 + && opcode != OP_JMP_abs + && opcode != OP_JMP_ind + && opcode != OP_JSR_abs) { - case SIZE_BYTE: - fprintf(output, " %%%X", readu8()); - break; - case SIZE_WORD: - fprintf(output, " %%%hX", readu16()); - break; - case SIZE_LONG: - fprintf(output, " %%%X", readu32()); - break; - default: - break; + decode_target_suffix(attr); } + term_color(output, COLOR_RESET); +} + +static void +decode_register(uint8_t opcode) +{ + uint8_t addr; + + addr = opcode_addr[opcode]; + term_color(output, COLOR_YELLOW); + if (addr & OP_ADDR_X) + { + fprintf(output, "X"); + } + else if (addr & OP_ADDR_Y) + { + fprintf(output, "Y"); + } + term_color(output, COLOR_RESET); } void @@ -143,22 +201,10 @@ decode_imm(uint8_t opcode) attr = readu8(); - fprintf(output, "%s", opcode_str[opcode]); - decode_target_suffix(attr); - switch (GET_TARGET_SIZE(attr)) - { - case SIZE_BYTE: - fprintf(output, " #$%X\n", readu8()); - break; - case SIZE_WORD: - fprintf(output, " #$%hX\n", readu16()); - break; - case SIZE_LONG: - fprintf(output, " #$%X\n", readu32()); - break; - default: - break; - } + decode_opcode(opcode, attr); + fprintf(output, " "); + decode_value(GET_TARGET_SIZE(attr), 0); + fprintf(output, "\n"); } void @@ -166,30 +212,26 @@ decode_ind(uint8_t opcode) { uint8_t attr; - fprintf(output, "%s", opcode_str[opcode]); attr = readu8(); - if (opcode != OP_JMP_ind) - { - decode_target_suffix(attr); - } + decode_opcode(opcode, attr); + fprintf(output, " "); if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y)) { - fprintf(output, " ("); - } - else - { - fprintf(output, " "); + fprintf(output, "("); } - decode_address(attr); + decode_value(GET_ADDRESS_SIZE(attr), 1); if (opcode_addr[opcode] & OP_ADDR_X) { - fprintf(output, ", X)"); + fprintf(output, ", "); + decode_register(opcode); + fprintf(output, ")"); } else if (opcode_addr[opcode] & OP_ADDR_Y) { - fprintf(output, "), Y"); + fprintf(output, "), "); + decode_register(opcode); } fprintf(output, "\n"); } @@ -199,22 +241,14 @@ decode_abs(uint8_t opcode) { uint8_t attr; - fprintf(output, "%s", opcode_str[opcode]); attr = readu8(); - if (opcode != OP_JSR_abs - || opcode != OP_JMP_abs) + decode_opcode(opcode, attr); + fprintf(output, " "); + decode_value(GET_ADDRESS_SIZE(attr), 1); + if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y)) { - decode_target_suffix(attr); - } - decode_address(attr); - - if (opcode_addr[opcode] & OP_ADDR_X) - { - fprintf(output, ", X"); - } - else if (opcode_addr[opcode] & OP_ADDR_Y) - { - fprintf(output, ", Y"); + fprintf(output, ", "); + decode_register(opcode); } fprintf(output, "\n"); } @@ -231,18 +265,20 @@ decode(void) switch (opcode_addr[opcode] & OP_ADDR_MODE) { case OP_ADDR_IMPL: + decode_opcode(opcode, 0); if (opcode_addr[opcode] & OP_ADDR_A) { - fprintf(output, "%s A\n", opcode_str[opcode]); - } - else - { - fprintf(output, "%s\n", opcode_str[opcode]); + term_color(output, COLOR_YELLOW); + fprintf(output, " A"); + term_color(output, COLOR_RESET); } + fprintf(output, "\n"); break; case OP_ADDR_REL: - relative = read16(); - fprintf(output, "%s $%hX\n", opcode_str[opcode], relative); + decode_opcode(opcode, 0); + fprintf(output, " "); + decode_value(SIZE_WORD, 1); + fprintf(output, "\n"); break; case OP_ADDR_IMM: decode_imm(opcode); @@ -292,6 +328,8 @@ version(void) int main(int argc, char **argv) { + char *no_color; + #ifdef HAVE_LIBGEN_H prg_name = basename(argv[0]); #else @@ -300,6 +338,12 @@ main(int argc, char **argv) input = stdin; output = stdout; + no_color = getenv("NO_COLOR"); + if (no_color != NULL && no_color[0] != '\0') + { + colorize = 0; + } + while ((argc > 1) && (argv[1][0] == '-')) { switch (argv[1][1]) @@ -321,6 +365,7 @@ main(int argc, char **argv) if (argc > 2) { + colorize = 0; output = fopen(argv[2], "w"); if (output == NULL) fatal("can't open %s.", argv[2]); } diff --git a/lib/op.h b/lib/op.h index d93c83c..76c392e 100644 --- a/lib/op.h +++ b/lib/op.h @@ -5,14 +5,14 @@ # define OP_MAX 256 -# define OP_ADDR_IMPL 0 -# define OP_ADDR_REL 1 << 0 -# define OP_ADDR_IMM 1 << 1 -# define OP_ADDR_IND 1 << 2 -# define OP_ADDR_ABS 1 << 3 -# define OP_ADDR_X 1 << 4 -# define OP_ADDR_Y 1 << 5 -# define OP_ADDR_A 1 << 6 +# define OP_ADDR_IMPL 1 << 0 +# define OP_ADDR_REL 1 << 1 +# define OP_ADDR_IMM 1 << 2 +# define OP_ADDR_IND 1 << 3 +# define OP_ADDR_ABS 1 << 4 +# define OP_ADDR_X 1 << 5 +# define OP_ADDR_Y 1 << 6 +# define OP_ADDR_A 1 << 7 # define OP_BRK_impl 0x00 # define OP_ORA_x_ind 0x01