mirror of
https://github.com/tcarmelveilleux/dcc6502.git
synced 2025-05-08 22:41:47 +00:00
Major refactoring of arguments handling
This commit is contained in:
parent
57e20cdf26
commit
d8869a8d28
369
dcc6502.c
369
dcc6502.c
@ -56,18 +56,26 @@ typedef enum {
|
||||
#define EOK 0
|
||||
#endif
|
||||
|
||||
typedef struct OPcode {
|
||||
typedef struct opcode_s {
|
||||
uint8_t number; /* Number of the opcode */
|
||||
const char *mnemonic; /* Index in the name table */
|
||||
addressing_mode_e addressing; /* Addressing mode */
|
||||
unsigned int cycles; /* Number of cycles */
|
||||
unsigned int cross_page; /* 1 if cross-page boundaries affect cycles */
|
||||
} OPcode;
|
||||
} opcode_t;
|
||||
|
||||
typedef struct options_s {
|
||||
char *filename; /* Input filename */
|
||||
int nes_mode; /* 1 if NES commenting and warnings are enabled */
|
||||
int cycle_counting; /* 1 if we want cycle counting */
|
||||
int hex_output; /* 1 if hex dump output is desired at beginning of line */
|
||||
unsigned long max_num_bytes;
|
||||
uint16_t org; /* Origin of addresses */
|
||||
} options_t;
|
||||
|
||||
typedef uint16_t word;
|
||||
|
||||
/* Opcode table */
|
||||
OPcode opcode_table[NUMBER_OPCODES] = {
|
||||
opcode_t opcode_table[NUMBER_OPCODES] = {
|
||||
{0x69, "ADC", IMMED, 2, 1}, /* ADC */
|
||||
{0x65, "ADC", ZEROP, 3, 1},
|
||||
{0x75, "ADC", ZEPIX, 4, 1},
|
||||
@ -276,27 +284,15 @@ OPcode opcode_table[NUMBER_OPCODES] = {
|
||||
{0x98, "TYA", IMPLI, 2, 0} /* TYA */
|
||||
};
|
||||
|
||||
// FIXME: use g_ nomenclature for globals
|
||||
uint16_t org; /* Origin of addresses */
|
||||
int hex_output = 0; /* 1 if hex output is desired at beginning of line */
|
||||
int cycle_counting = 0; /* 1 if we want cycle counting */
|
||||
int nes_mode = 0; /* 1 if NES commenting and warnings are enabled */
|
||||
FILE *f; /* Input file */
|
||||
uint8_t buffer[0xffff]; /* Memory buffer */
|
||||
uint16_t PC = 0; /* Program counter */
|
||||
uint16_t max = 0xffff; /* Maximum number of bytes to disassemble */
|
||||
char line[512];
|
||||
|
||||
/* This function emits a comment header with information about the file
|
||||
being disassembled */
|
||||
|
||||
void emit_header(char *filename, int fsize, uint16_t org) {
|
||||
void emit_header(options_t *options, int fsize) {
|
||||
fprintf(stdout, "; Source generated by DCC6502 version %s\n", VERSION_INFO);
|
||||
fprintf(stdout, "; For more info about DCC6502, see https://github.com/tcarmelveilleux/dcc6502\n");
|
||||
fprintf(stdout, "; FILENAME: %s, File Size: %d, ORG: $%04X\n", filename, fsize, org);
|
||||
if (hex_output) fprintf(stdout, "; -> Hex output enabled\n");
|
||||
if (cycle_counting) fprintf(stdout, "; -> Cycle counting enabled\n");
|
||||
if (nes_mode) fprintf(stdout, "; -> NES mode enabled\n");
|
||||
fprintf(stdout, "; FILENAME: %s, File Size: %d, ORG: $%04X\n", options->filename, fsize, options->org);
|
||||
if (options->hex_output) fprintf(stdout, "; -> Hex output enabled\n");
|
||||
if (options->cycle_counting) fprintf(stdout, "; -> Cycle counting enabled\n");
|
||||
if (options->nes_mode) fprintf(stdout, "; -> NES mode enabled\n");
|
||||
fprintf(stdout, ";---------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
@ -358,33 +354,33 @@ void append_nes(char *input, uint16_t arg) {
|
||||
}
|
||||
}
|
||||
|
||||
#define DUMP_FORMAT (hex_output ? "%-16s%-16s;" : "%-8s%-16s;")
|
||||
#define DUMP_FORMAT (options->hex_output ? "%-16s%-16s;" : "%-8s%-16s;")
|
||||
#define HIGH_PART(val) (((val) >> 8) & 0xFFu)
|
||||
#define LOW_PART(val) ((val) & 0xFFu)
|
||||
#define LOAD_WORD(buffer, current_pc) ((uint16_t)buffer[(current_pc) + 1] | (((uint16_t)buffer[(current_pc) + 2]) << 8))
|
||||
|
||||
/* This function disassembles the opcode at the PC and outputs it in *output */
|
||||
void disassemble(char *output) {
|
||||
void disassemble(char *output, uint8_t *buffer, options_t *options, uint16_t *pc) {
|
||||
char opcode_repr[256], hex_dump[256];
|
||||
int i;
|
||||
int opcode_idx;
|
||||
int len = 0;
|
||||
int entry = 0;
|
||||
int found = 0;
|
||||
uint8_t byte_operand;
|
||||
word word_operand = 0;
|
||||
uint16_t current_addr = org + PC;
|
||||
uint8_t opcode = buffer[current_addr - org];
|
||||
uint16_t word_operand = 0;
|
||||
uint16_t current_addr = *pc;
|
||||
uint8_t opcode = buffer[current_addr];
|
||||
const char *mnemonic;
|
||||
|
||||
opcode_repr[0] = '\0';
|
||||
hex_dump[0] = '\0';
|
||||
|
||||
// Linear search for opcode
|
||||
for (i = 0; i < NUMBER_OPCODES; i++) {
|
||||
if (opcode == opcode_table[i].number) {
|
||||
for (opcode_idx = 0; opcode_idx < NUMBER_OPCODES; opcode_idx++) {
|
||||
if (opcode == opcode_table[opcode_idx].number) {
|
||||
/* Found the opcode, record its table index */
|
||||
found = 1;
|
||||
entry = i;
|
||||
entry = opcode_idx;
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +388,7 @@ void disassemble(char *output) {
|
||||
// For opcode not found, terminate early
|
||||
if (!found) {
|
||||
sprintf(opcode_repr, ".byte $%02x", opcode);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X:", current_addr, opcode);
|
||||
sprintf(output, "%-16s%-16s; INVALID OPCODE !!!\n", hex_dump, opcode_repr);
|
||||
} else {
|
||||
@ -412,125 +408,125 @@ void disassemble(char *output) {
|
||||
switch (opcode_table[entry].addressing) {
|
||||
case IMMED:
|
||||
/* Get immediate value operand */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
sprintf(opcode_repr, "%s #$%02x", mnemonic, byte_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case ABSOL:
|
||||
/* Get absolute address operand */
|
||||
word_operand = LOAD_WORD(buffer, PC);
|
||||
PC += 2;
|
||||
word_operand = LOAD_WORD(buffer, *pc);
|
||||
*pc += 2;
|
||||
|
||||
sprintf(opcode_repr, "%s $%02X%02X", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
|
||||
}
|
||||
|
||||
break;
|
||||
case ZEROP:
|
||||
/* Get zero page address */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
sprintf(opcode_repr, "%s $%02X", mnemonic, byte_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case IMPLI:
|
||||
sprintf(opcode_repr, "%s", mnemonic);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X:", current_addr, opcode);
|
||||
}
|
||||
|
||||
break;
|
||||
case INDIA:
|
||||
/* Get indirection address */
|
||||
word_operand = LOAD_WORD(buffer, PC);
|
||||
PC += 2;
|
||||
word_operand = LOAD_WORD(buffer, *pc);
|
||||
*pc += 2;
|
||||
|
||||
sprintf(opcode_repr, "%s ($%02X%02X)", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
|
||||
}
|
||||
|
||||
break;
|
||||
case ABSIX:
|
||||
/* Get base address */
|
||||
word_operand = LOAD_WORD(buffer, PC);
|
||||
PC += 2;
|
||||
word_operand = LOAD_WORD(buffer, *pc);
|
||||
*pc += 2;
|
||||
|
||||
sprintf(opcode_repr, "%s $%02X%02X,X", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
|
||||
}
|
||||
|
||||
break;
|
||||
case ABSIY:
|
||||
/* Get baser address */
|
||||
word_operand = LOAD_WORD(buffer, PC);
|
||||
PC += 2;
|
||||
word_operand = LOAD_WORD(buffer, *pc);
|
||||
*pc += 2;
|
||||
|
||||
sprintf(opcode_repr, "%s $%02X%02X,Y", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
|
||||
}
|
||||
|
||||
break;
|
||||
case ZEPIX:
|
||||
/* Get zero-page base address */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
sprintf(opcode_repr, "%s $%02X,X", mnemonic, byte_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case ZEPIY:
|
||||
/* Get zero-page base address */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
sprintf(opcode_repr, "%s $%02X,Y", mnemonic, byte_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case INDIN:
|
||||
/* Get zero-page base address */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
sprintf(opcode_repr, "%s ($%02X,X)", mnemonic, byte_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case ININD:
|
||||
/* Get zero-page base address */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
sprintf(opcode_repr, "%s ($%02X),Y", mnemonic, byte_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case RELAT:
|
||||
/* Get relative modifier */
|
||||
byte_operand = buffer[PC + 1];
|
||||
PC++;
|
||||
byte_operand = buffer[*pc + 1];
|
||||
*pc += 1;
|
||||
|
||||
// Compute displacement from first byte after full instruction.
|
||||
word_operand = current_addr + 2;
|
||||
@ -541,14 +537,14 @@ void disassemble(char *output) {
|
||||
}
|
||||
|
||||
sprintf(opcode_repr, "%s $%04X", mnemonic, word_operand);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
|
||||
}
|
||||
|
||||
break;
|
||||
case ACCUM:
|
||||
sprintf(opcode_repr, "%s A", mnemonic);
|
||||
if (hex_output) {
|
||||
if (options->hex_output) {
|
||||
sprintf(hex_dump, "$%04X> %02X:", current_addr, opcode);
|
||||
}
|
||||
|
||||
@ -562,7 +558,7 @@ void disassemble(char *output) {
|
||||
output += len;
|
||||
|
||||
/* Add cycle count if necessary */
|
||||
if (cycle_counting) {
|
||||
if (options->cycle_counting) {
|
||||
output = append_cycle(output, entry);
|
||||
}
|
||||
|
||||
@ -571,7 +567,7 @@ void disassemble(char *output) {
|
||||
case ABSOL:
|
||||
case ABSIX:
|
||||
case ABSIY:
|
||||
if (nes_mode) {
|
||||
if (options->nes_mode) {
|
||||
append_nes(output, word_operand);
|
||||
}
|
||||
break;
|
||||
@ -587,161 +583,152 @@ void version(void) {
|
||||
fprintf(stderr, "See source on github: https://github.com/tcarmelveilleux/dcc6502.\n");
|
||||
}
|
||||
|
||||
void usage_helper(char *str) {
|
||||
fprintf(stderr, "\t%s\n", str);
|
||||
}
|
||||
|
||||
// FIXME: add command line sample
|
||||
// FIXME: Make these more sane and add option for decimal
|
||||
void usage(void) {
|
||||
usage_helper("-?: Show this help message");
|
||||
usage_helper("-o ORG: Set the origin to ORG [default: 0x8000]");
|
||||
usage_helper("-h: Enable hex dump within disassembly");
|
||||
usage_helper("-m NUM_BYTES: Only disassemble the first NUM_BYTES bytes");
|
||||
usage_helper("-n: Enable NES register annotations");
|
||||
usage_helper("-v: Get only version information");
|
||||
usage_helper("-c: Enable cycle counting annotations");
|
||||
fprintf(stderr, "Usage: dcc6502 [options] FILENAME");
|
||||
fprintf(stderr, " -?/-h : Show this help message\n");
|
||||
fprintf(stderr, " -o ORIGIN : Set the origin (base address of disassembly) [default: 0x8000]\n");
|
||||
fprintf(stderr, " -m NUM_BYTES : Only disassemble the first NUM_BYTES bytes\n");
|
||||
fprintf(stderr, " -d : Enable hex dump within disassembly\n");
|
||||
fprintf(stderr, " -n : Enable NES register annotations\n");
|
||||
fprintf(stderr, " -v : Get only version information\n");
|
||||
fprintf(stderr, " -c : Enable cycle counting annotations\n");
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
uint16_t hex2int (char *str, uint16_t dfl) {
|
||||
unsigned long str_arg_to_ulong(char *str, unsigned long default_val) {
|
||||
uint32_t tmp = 0;
|
||||
|
||||
errno = EOK;
|
||||
tmp = strtoul(str, NULL, 16);
|
||||
tmp = strtoul(str, NULL, 0);
|
||||
/* In case of conversion error, take default value */
|
||||
if (EOK != errno) {
|
||||
fprintf(stderr, "WARNING -> error converting %s to a numerical value.", str);
|
||||
return dfl;
|
||||
return default_val;
|
||||
} else {
|
||||
return (uint16_t)(tmp & 0xFFFFu);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void set_org(char *str) {
|
||||
if (strlen(str) < 3) {
|
||||
fprintf(stderr, "WARNING -> %s is not a valid ORG switch, defaulting to $8000\n", str);
|
||||
org = 0x8000;
|
||||
return;
|
||||
void usage_and_exit(int exit_code, const char *message) {
|
||||
version();
|
||||
usage();
|
||||
if (NULL != message) {
|
||||
fprintf(stderr, "%s\n", message);
|
||||
}
|
||||
|
||||
org = hex2int(&str[2], 0x8000u);
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
void set_max(char *str) {
|
||||
if (strlen(str) < 3) {
|
||||
max = 0xFFFF-org;
|
||||
fprintf(stderr, "WARNING -> %s is not a valid MAX switch, defaulting to $%04X\n", str, max);
|
||||
return;
|
||||
void parse_args(int argc, char *argv[], options_t *options) {
|
||||
int arg_idx = 1;
|
||||
|
||||
options->cycle_counting = 0;
|
||||
options->hex_output = 0;
|
||||
options->nes_mode = 0;
|
||||
options->org = 0x8000;
|
||||
options->max_num_bytes = 65536;
|
||||
|
||||
while (arg_idx < argc) {
|
||||
/* First non-dash-starting argument is assumed to be filename */
|
||||
if (argv[arg_idx][0] != '-') {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Got a switch, process it */
|
||||
switch (argv[arg_idx][1]) {
|
||||
case 'h':
|
||||
case '?':
|
||||
usage_and_exit(0, NULL);
|
||||
break;
|
||||
case 'n':
|
||||
options->nes_mode = 1;
|
||||
break;
|
||||
case 'c':
|
||||
options->cycle_counting = 1;
|
||||
break;
|
||||
case 'd':
|
||||
options->hex_output = 1;
|
||||
break;
|
||||
case 'v':
|
||||
version();
|
||||
exit(0);
|
||||
break;
|
||||
case 'o':
|
||||
if ((arg_idx == (argc - 1)) || (argv[arg_idx + 1][0] == '-')) {
|
||||
usage_and_exit(1, "Missing argument to -o switch");
|
||||
}
|
||||
|
||||
/* Get argument and parse it */
|
||||
arg_idx++;
|
||||
options->org = (uint16_t)(str_arg_to_ulong(argv[arg_idx], 0x8000u) & 0xFFFFu);
|
||||
break;
|
||||
case 'm':
|
||||
if ((arg_idx == (argc - 1)) || (argv[arg_idx + 1][0] == '-')) {
|
||||
usage_and_exit(1, "Missing argument to -m switch");
|
||||
}
|
||||
|
||||
/* Get argument and parse it */
|
||||
arg_idx++;
|
||||
options->max_num_bytes = str_arg_to_ulong(argv[arg_idx], 65536u);
|
||||
break;
|
||||
default:
|
||||
version();
|
||||
usage();
|
||||
fprintf(stderr, "Unrecognized switch: %s\n", argv[arg_idx]);
|
||||
exit(1);
|
||||
}
|
||||
arg_idx++;
|
||||
}
|
||||
|
||||
max = hex2int(&str[2], 0xFFFFu);
|
||||
/* Make sure we have a filename left to take after we stopped parsing switches */
|
||||
if (arg_idx >= argc) {
|
||||
usage_and_exit(1, "Missing filename from command line");
|
||||
}
|
||||
|
||||
options->filename = argv[arg_idx];
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int idx = 0;
|
||||
char tmpstring[512];
|
||||
char filename[512];
|
||||
int byte_count = 0;
|
||||
char tmpstr[512];
|
||||
uint8_t *buffer; /* Memory buffer */
|
||||
FILE *input_file; /* Input file */
|
||||
uint16_t pc; /* Program counter */
|
||||
options_t options; /* Command-line options parsing results */
|
||||
|
||||
cycle_counting = 0;
|
||||
hex_output = 0;
|
||||
org = 0x8000;
|
||||
parse_args(argc, argv, &options);
|
||||
|
||||
if (argc < 2) {
|
||||
buffer = calloc(1, 65536);
|
||||
if (NULL == buffer) {
|
||||
usage_and_exit(3, "Could not allocate disassembly memory buffer.");
|
||||
}
|
||||
|
||||
/* Read file into memory buffer */
|
||||
input_file = fopen(options.filename, "rb");
|
||||
|
||||
if (NULL == input_file) {
|
||||
version();
|
||||
usage();
|
||||
exit(1);
|
||||
fprintf(stderr, "File not found or invalid filename : %s\n", options.filename);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
for (idx = 1; idx < argc - 1; idx++) {
|
||||
if (argv[idx][0] != '-') {
|
||||
version();
|
||||
usage();
|
||||
fprintf(stderr, "Unrecognized switch: %s\n", argv[idx]);
|
||||
exit(1);
|
||||
}
|
||||
switch (argv[idx][1]) {
|
||||
case '?':
|
||||
version();
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
case 'n':
|
||||
nes_mode = 1;
|
||||
break;
|
||||
case 'c':
|
||||
cycle_counting = 1;
|
||||
break;
|
||||
case 'h':
|
||||
hex_output = 1;
|
||||
break;
|
||||
case 'v':
|
||||
version();
|
||||
exit(0);
|
||||
break;
|
||||
case 'o':
|
||||
set_org(argv[idx]);
|
||||
break;
|
||||
case 'm':
|
||||
set_max(argv[idx]);
|
||||
break;
|
||||
default:
|
||||
version();
|
||||
usage();
|
||||
fprintf(stderr, "Unrecognized switch: %s\n", argv[idx]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (argv[1][0] != '-') {
|
||||
strncpy(filename, argv[1], 511);
|
||||
} else {
|
||||
switch (argv[1][1]) {
|
||||
case '?':
|
||||
version();
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
case 'v':
|
||||
version();
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
version();
|
||||
usage();
|
||||
fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
|
||||
exit(1);
|
||||
|
||||
}
|
||||
}
|
||||
byte_count = 0;
|
||||
while(!feof(input_file) && ((options.org + byte_count) <= 0xFFFFu) && (byte_count < options.max_num_bytes)) {
|
||||
fread(&buffer[options.org + byte_count], 1, 1, input_file);
|
||||
byte_count++;
|
||||
}
|
||||
|
||||
strncpy(filename, argv[argc - 1], 511);
|
||||
fclose(input_file);
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
|
||||
if (NULL == f) {
|
||||
version();
|
||||
fprintf(stderr, "File not found or invalid filename : %s\n", filename);
|
||||
exit(1);
|
||||
/* Disassemble contents of buffer */
|
||||
emit_header(&options, byte_count);
|
||||
pc = options.org;
|
||||
while((pc <= 0xFFFFu) && ((pc - options.org) < byte_count)) {
|
||||
disassemble(tmpstr, buffer, &options, &pc);
|
||||
fprintf(stdout, "%s\n", tmpstr);
|
||||
pc++;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
while(!feof(f) && ((idx + org) < 65535)) {
|
||||
fread(&buffer[idx], 1, 1, f);
|
||||
idx++;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
emit_header(filename, idx, org);
|
||||
PC = 0;
|
||||
while(((PC + org) < 65535) && (PC <= max) && (PC < idx)) {
|
||||
disassemble(tmpstring);
|
||||
fprintf(stdout, "%s\n", tmpstring);
|
||||
PC++;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user