Colorize disassembler output
This commit is contained in:
parent
262a211da9
commit
3b0e785644
175
disas/main.c
175
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]);
|
||||
}
|
||||
|
|
16
lib/op.h
16
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
|
||||
|
|
Loading…
Reference in a new issue