Simplified hex value conversions for args

This commit is contained in:
Tennessee Carmel-Veilleux 2014-07-24 18:56:51 -04:00
parent 0ffacd9e5d
commit 34ccb70eae
1 changed files with 40 additions and 45 deletions

View File

@ -29,6 +29,7 @@
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h>
#define VERSION_INFO "v1.6" #define VERSION_INFO "v1.6"
#define NUMBER_OPCODES 151 #define NUMBER_OPCODES 151
@ -48,6 +49,11 @@
#define RELAT 11 /* Relative */ #define RELAT 11 /* Relative */
#define ACCUM 12 /* Accumulator */ #define ACCUM 12 /* Accumulator */
/** Some compilers don't have EOK in errno.h */
#ifndef EOK
#define EOK 0
#endif
typedef struct OPcode { typedef struct OPcode {
uint8_t number; /* Number of the opcode */ uint8_t number; /* Number of the opcode */
unsigned int name; /* Index in the name table */ unsigned int name; /* Index in the name table */
@ -278,7 +284,6 @@ OPcode opcode_table[NUMBER_OPCODES] = {
{0x98, 55, IMPLI, 2, 0} /* TYA */ {0x98, 55, IMPLI, 2, 0} /* TYA */
}; };
// FIXME: use stdint types
// FIXME: use g_ nomenclature for globals // FIXME: use g_ nomenclature for globals
uint16_t org; /* Origin of addresses */ uint16_t org; /* Origin of addresses */
int hex_output = 0; /* 1 if hex output is desired at beginning of line */ int hex_output = 0; /* 1 if hex output is desired at beginning of line */
@ -366,7 +371,6 @@ void append_nes(char *input, uint16_t arg) {
#define LOW_PART(val) ((val) & 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)) #define LOAD_WORD(buffer, current_pc) ((uint16_t)buffer[(current_pc) + 1] | (((uint16_t)buffer[(current_pc) + 2]) << 8))
// FIXME: Refactor code to reduce line duplication and make more readable
/* This function disassembles the opcode at the PC and outputs it in *output */ /* This function disassembles the opcode at the PC and outputs it in *output */
void disassemble(char *output) { void disassemble(char *output) {
char opcode_repr[256], hex_dump[256]; char opcode_repr[256], hex_dump[256];
@ -594,65 +598,56 @@ void usage_helper(char *str) {
} }
// FIXME: add command line sample // FIXME: add command line sample
// FIXME: Make these more sane and add option for decimal
void usage(void) { void usage(void) {
usage_helper("-? -> Show this help message"); usage_helper("-? -> Show this help message");
usage_helper("-oXXXX -> Set the origin (ORG) [dfl: $8000]"); usage_helper("-oXXXX -> Set the origin (ORG), where XXXX is hexadecimal [default: 8000]");
usage_helper("-h -> Get hex info about disassembly"); usage_helper("-h -> Enable hex dump within disassembly");
usage_helper("-mXXXX -> Only disassemble the first XXXX bytes"); usage_helper("-mXXXX -> Only disassemble the first XXXX bytes, where XXXX is hexadecimal");
usage_helper("-n -> Enable NES mode"); usage_helper("-mXXXX -> Only disassemble the first XXXX bytes, where XXXX is hexadecimal");
usage_helper("-n -> Enable NES register annotations");
usage_helper("-v -> Get only version information"); usage_helper("-v -> Get only version information");
usage_helper("-c -> Get cycle counting info"); usage_helper("-c -> Enable cycle counting annotations");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
// FIXME: DE-KLUDGIFY THIS :D // FIXME: DE-KLUDGIFY THIS :D
uint16_t hex2int (char *str, uint16_t dfl) { uint16_t hex2int (char *str, uint16_t dfl) {
char HEX_digits[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; uint32_t tmp = 0;
int i, j;
char k = 0;
char c, shift;
uint16_t tmp = 0;
shift = 0; errno = EOK;
for (i = 5; i >= 2; i--) { tmp = strtoul(str, NULL, 16);
if (!isxdigit(str[i])) { /* In case of conversion error, take default value */
tmp = dfl; if (EOK != errno) {
break; fprintf(stderr, "WARNING -> error converting %s to a numerical value.", str);
} return dfl;
c = toupper(str[i]); } else {
for (j = 0; j < 16; j++) { return (uint16_t)(tmp & 0xFFFFu);
if (c == HEX_digits[j]) {
k = j;
}
}
tmp |= ((k & 0xf) << shift);
shift += 4;
} }
return tmp;
} }
void set_org(char *str) { void set_org(char *str) {
if (strlen(str) < 6) { if (strlen(str) < 3) {
fprintf(stderr, "WARNING -> %s is not a valid ORG switch, defaulting to $8000\n", str); fprintf(stderr, "WARNING -> %s is not a valid ORG switch, defaulting to $8000\n", str);
org = 0x8000; org = 0x8000;
return; return;
} }
org = hex2int(str, 0x8000); org = hex2int(&str[2], 0x8000u);
} }
void set_max(char *str) { void set_max(char *str) {
if (strlen(str) != 6) { if (strlen(str) < 3) {
max = 0xFFFF-org; max = 0xFFFF-org;
fprintf(stderr, "WARNING -> %s is not a valid MAX switch, defaulting to $%04X\n", str, max); fprintf(stderr, "WARNING -> %s is not a valid MAX switch, defaulting to $%04X\n", str, max);
return; return;
} }
max = hex2int(str, 0xFFFF); max = hex2int(&str[2], 0xFFFFu);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int i = 0; int idx = 0;
char tmpstring[512]; char tmpstring[512];
char filename[512]; char filename[512];
@ -667,14 +662,14 @@ int main(int argc, char *argv[]) {
} }
if (argc > 2) { if (argc > 2) {
for (i = 1; i < argc - 1; i++) { for (idx = 1; idx < argc - 1; idx++) {
if (argv[i][0] != '-') { if (argv[idx][0] != '-') {
version(); version();
usage(); usage();
fprintf(stderr, "Unrecognized switch: %s\n", argv[i]); fprintf(stderr, "Unrecognized switch: %s\n", argv[idx]);
exit(1); exit(1);
} }
switch (argv[i][1]) { switch (argv[idx][1]) {
case '?': case '?':
version(); version();
usage(); usage();
@ -694,15 +689,15 @@ int main(int argc, char *argv[]) {
exit(0); exit(0);
break; break;
case 'o': case 'o':
set_org(argv[i]); set_org(argv[idx]);
break; break;
case 'm': case 'm':
set_max(argv[i]); set_max(argv[idx]);
break; break;
default: default:
version(); version();
usage(); usage();
fprintf(stderr, "Unrecognized switch: %s\n", argv[i]); fprintf(stderr, "Unrecognized switch: %s\n", argv[idx]);
exit(1); exit(1);
} }
} }
@ -740,17 +735,17 @@ int main(int argc, char *argv[]) {
exit(1); exit(1);
} }
i = 0; idx = 0;
while(!feof(f) && ((i + org) < 65535)) { while(!feof(f) && ((idx + org) < 65535)) {
fread(&buffer[i], 1, 1, f); fread(&buffer[idx], 1, 1, f);
i++; idx++;
} }
fclose(f); fclose(f);
emit_header(filename, i, org); emit_header(filename, idx, org);
PC = 0; PC = 0;
while(((PC + org) < 65535) && (PC <= max) && (PC < i)) { while(((PC + org) < 65535) && (PC <= max) && (PC < idx)) {
disassemble(tmpstring); disassemble(tmpstring);
fprintf(stdout, "%s\n", tmpstring); fprintf(stdout, "%s\n", tmpstring);
PC++; PC++;