Colorize disassembler output

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-02-29 16:25:59 +01:00
parent 262a211da9
commit 3b0e785644
2 changed files with 118 additions and 73 deletions

View file

@ -11,9 +11,25 @@
#define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \ #define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \
| OP_ADDR_IMM | OP_ADDR_ABS) | 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; char *prg_name;
FILE *input; FILE *input;
FILE *output; FILE *output;
int colorize = 1;
void
term_color(FILE *stream, int color)
{
if (!colorize) return;
fprintf(stream, "\033[%dm", color);
}
uint8_t uint8_t
readu8(void) readu8(void)
@ -85,16 +101,40 @@ fatal(const char *str, ...)
{ {
va_list ap; va_list ap;
term_color(stderr, COLOR_RED);
fprintf(stderr, "%s: ", prg_name); fprintf(stderr, "%s: ", prg_name);
va_start(ap, str); va_start(ap, str);
vfprintf(stderr, str, ap); vfprintf(stderr, str, ap);
va_end(ap); va_end(ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
term_color(stderr, COLOR_RESET);
exit(EXIT_FAILURE); 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) decode_target_suffix(uint8_t attr)
{ {
fprintf(output, "."); fprintf(output, ".");
@ -117,23 +157,41 @@ decode_target_suffix(uint8_t attr)
} }
} }
void static void
decode_address(uint8_t attr) 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: decode_target_suffix(attr);
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_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 void
@ -143,22 +201,10 @@ decode_imm(uint8_t opcode)
attr = readu8(); attr = readu8();
fprintf(output, "%s", opcode_str[opcode]); decode_opcode(opcode, attr);
decode_target_suffix(attr); fprintf(output, " ");
switch (GET_TARGET_SIZE(attr)) decode_value(GET_TARGET_SIZE(attr), 0);
{ fprintf(output, "\n");
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;
}
} }
void void
@ -166,30 +212,26 @@ decode_ind(uint8_t opcode)
{ {
uint8_t attr; uint8_t attr;
fprintf(output, "%s", opcode_str[opcode]);
attr = readu8(); attr = readu8();
if (opcode != OP_JMP_ind) decode_opcode(opcode, attr);
{ fprintf(output, " ");
decode_target_suffix(attr);
}
if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y)) if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y))
{ {
fprintf(output, "("); fprintf(output, "(");
} }
else
{
fprintf(output, " ");
}
decode_address(attr); decode_value(GET_ADDRESS_SIZE(attr), 1);
if (opcode_addr[opcode] & OP_ADDR_X) 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) else if (opcode_addr[opcode] & OP_ADDR_Y)
{ {
fprintf(output, "), Y"); fprintf(output, "), ");
decode_register(opcode);
} }
fprintf(output, "\n"); fprintf(output, "\n");
} }
@ -199,22 +241,14 @@ decode_abs(uint8_t opcode)
{ {
uint8_t attr; uint8_t attr;
fprintf(output, "%s", opcode_str[opcode]);
attr = readu8(); attr = readu8();
if (opcode != OP_JSR_abs decode_opcode(opcode, attr);
|| opcode != OP_JMP_abs) fprintf(output, " ");
decode_value(GET_ADDRESS_SIZE(attr), 1);
if (opcode_addr[opcode] & (OP_ADDR_X | OP_ADDR_Y))
{ {
decode_target_suffix(attr); fprintf(output, ", ");
} decode_register(opcode);
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, "\n"); fprintf(output, "\n");
} }
@ -231,18 +265,20 @@ decode(void)
switch (opcode_addr[opcode] & OP_ADDR_MODE) switch (opcode_addr[opcode] & OP_ADDR_MODE)
{ {
case OP_ADDR_IMPL: case OP_ADDR_IMPL:
decode_opcode(opcode, 0);
if (opcode_addr[opcode] & OP_ADDR_A) if (opcode_addr[opcode] & OP_ADDR_A)
{ {
fprintf(output, "%s A\n", opcode_str[opcode]); term_color(output, COLOR_YELLOW);
} fprintf(output, " A");
else term_color(output, COLOR_RESET);
{
fprintf(output, "%s\n", opcode_str[opcode]);
} }
fprintf(output, "\n");
break; break;
case OP_ADDR_REL: case OP_ADDR_REL:
relative = read16(); decode_opcode(opcode, 0);
fprintf(output, "%s $%hX\n", opcode_str[opcode], relative); fprintf(output, " ");
decode_value(SIZE_WORD, 1);
fprintf(output, "\n");
break; break;
case OP_ADDR_IMM: case OP_ADDR_IMM:
decode_imm(opcode); decode_imm(opcode);
@ -292,6 +328,8 @@ version(void)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char *no_color;
#ifdef HAVE_LIBGEN_H #ifdef HAVE_LIBGEN_H
prg_name = basename(argv[0]); prg_name = basename(argv[0]);
#else #else
@ -300,6 +338,12 @@ main(int argc, char **argv)
input = stdin; input = stdin;
output = stdout; output = stdout;
no_color = getenv("NO_COLOR");
if (no_color != NULL && no_color[0] != '\0')
{
colorize = 0;
}
while ((argc > 1) && (argv[1][0] == '-')) while ((argc > 1) && (argv[1][0] == '-'))
{ {
switch (argv[1][1]) switch (argv[1][1])
@ -321,6 +365,7 @@ main(int argc, char **argv)
if (argc > 2) if (argc > 2)
{ {
colorize = 0;
output = fopen(argv[2], "w"); output = fopen(argv[2], "w");
if (output == NULL) fatal("can't open %s.", argv[2]); if (output == NULL) fatal("can't open %s.", argv[2]);
} }

View file

@ -5,14 +5,14 @@
# define OP_MAX 256 # define OP_MAX 256
# define OP_ADDR_IMPL 0 # define OP_ADDR_IMPL 1 << 0
# define OP_ADDR_REL 1 << 0 # define OP_ADDR_REL 1 << 1
# define OP_ADDR_IMM 1 << 1 # define OP_ADDR_IMM 1 << 2
# define OP_ADDR_IND 1 << 2 # define OP_ADDR_IND 1 << 3
# define OP_ADDR_ABS 1 << 3 # define OP_ADDR_ABS 1 << 4
# define OP_ADDR_X 1 << 4 # define OP_ADDR_X 1 << 5
# define OP_ADDR_Y 1 << 5 # define OP_ADDR_Y 1 << 6
# define OP_ADDR_A 1 << 6 # define OP_ADDR_A 1 << 7
# define OP_BRK_impl 0x00 # define OP_BRK_impl 0x00
# define OP_ORA_x_ind 0x01 # define OP_ORA_x_ind 0x01