diff --git a/README.md b/README.md index f46ced4..b1467a4 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ sORG $30000 $30000: $30053:mx $31066:e +$35440:d ``` The first line specifies the segment file that this map applies to. The filename in the quotes should be relative to the current directory. @@ -67,8 +68,15 @@ The next lines are a list of entry points to begin disassembly at. If, when ana The flags after the colon are optional, and specify whether emulation mode should be enabled, or 16-bit or 8-bit accumulator and index registers should be used. It defaults to native mode with 16-bit registers. +After the flags, you may optionally give the address a symbol name. Whenever +this memory location is referenced in the code, the symbol name will appear as a +comment. + You can also use bank-separators if you wish. `$3/1066` is the same as `$31066`. +The `d` flag is unique in that it identifies the address as a data location and +not an entry point. This is used to give variables symbol names. + ## Pascal folder @@ -200,7 +208,7 @@ registers. So we can use all of that information to disassemble this file. -`$ regs --org=2000 -m -x BASIC.SYSTEM > basic.s` +`$ regs --org=0x2000 -m -x BASIC.SYSTEM > basic.s` This tells regs to start with 8-bit accumulator and indices, and load the file starting at `$2000` before disassembling it. diff --git a/addresses.h b/addresses.h index 4b1691e..6824bb2 100644 --- a/addresses.h +++ b/addresses.h @@ -399,7 +399,7 @@ static MemAddress addresses[] = { #define numAddresses (sizeof(addresses) / sizeof(addresses[0])) -static const char *addressLookup(uint32_t addr) { +static const char *addressLookup(uint32_t addr, Map *map) { for (int i = 0; i < numAddresses; i++) { if (addresses[i].address >= addr) { if (addresses[i].address == addr) @@ -407,7 +407,12 @@ static const char *addressLookup(uint32_t addr) { break; } } + for (Rule *rule = map->rules; rule != NULL; rule = rule->next) { + if (rule->address == addr && rule->symbol != NULL) { + return rule->symbol; + } + } if (addr & ~0xffff) - return addressLookup(addr & 0xffff); // try pageless + return addressLookup(addr & 0xffff, map); // try pageless return NULL; } diff --git a/disasm.c b/disasm.c index a7badc1..9b49012 100644 --- a/disasm.c +++ b/disasm.c @@ -128,8 +128,10 @@ void disassemble(uint8_t *data, size_t len, Map *map) { printf("#$%02x", *ptr++); oprlen = 4; } else { - printf("#$%04x", r16(ptr)); ptr += 2; + val = r16(ptr); ptr += 2; + printf("#$%04x", val); oprlen = 6; + comments = addressLookup(val, map); } break; case IMMX: @@ -141,40 +143,50 @@ void disassemble(uint8_t *data, size_t len, Map *map) { x = r16(ptr); ptr += 2; printf("#$%04x", x); oprlen = 6; + comments = addressLookup(x, map); } break; case IMMS: - printf("#$%04x", r16(ptr)); ptr += 2; + val = r16(ptr); ptr += 2; + printf("#$%04x", val); oprlen = 6; + comments = addressLookup(x, map); break; case ABS: val = r16(ptr); ptr += 2; printf("$%04x", val); oprlen = 5; - comments = addressLookup(val); + comments = addressLookup(val, map); break; case ABL: val = r24(ptr); ptr += 3; printf("$%02x/%04x", val >> 16, val & 0xffff); oprlen = 8; - comments = addressLookup(val); + comments = addressLookup(val, map); break; case ABX: - printf("$%04x, x", r16(ptr)); ptr += 2; + val = r16(ptr); ptr += 2; + printf("$%04x, x", val); oprlen = 8; + comments = addressLookup(val, map); break; case ABY: - printf("$%04x, y", r16(ptr)); ptr += 2; + val = r16(ptr); ptr += 2; + printf("$%04x, y", val); oprlen = 8; + comments = addressLookup(val, map); break; case ABLX: val = r24(ptr); ptr += 3; printf("$%02x/%04x, x", val >> 16, val & 0xffff); oprlen = 11; + comments = addressLookup(val, map); break; case AIX: - printf("($%04x, x)", r16(ptr)); ptr += 2; + val = r16(ptr); ptr += 2; + printf("($%04x, x)", val); oprlen = 10; + comments = addressLookup(val, map); break; case ZP: printf("$%02x", *ptr++); @@ -193,8 +205,10 @@ void disassemble(uint8_t *data, size_t len, Map *map) { oprlen = 6; break; case IND: - printf("($%04x)", r16(ptr)); ptr += 2; + val = r16(ptr); ptr += 2; + printf("($%04x)", val); oprlen = 7; + comments = addressLookup(val, map); break; case INZ: printf("($%02x)", *ptr++); @@ -225,12 +239,14 @@ void disassemble(uint8_t *data, size_t len, Map *map) { d6 = delta + addr; printf("$%02x/%04x", d6 >> 16, d6 & 0xffff); oprlen = 8; + comments = addressLookup(d6, map); break; case RELL: delta16 = r16(ptr); ptr += 2; d6 = delta16 + addr; printf("$%02x/%04x", d6 >> 16, d6 & 0xffff); oprlen = 8; + comments = addressLookup(d6, map); break; case BANK: val = *ptr++; diff --git a/map.c b/map.c index d0289fd..d9999f1 100644 --- a/map.c +++ b/map.c @@ -48,7 +48,27 @@ static Rule *parseRule(ConfigFile *f) { rule->flags |= IsX8; foundFlag = true; } + if (token(f, 'd')) { + rule->flags &= ~IsOpcode; + rule->flags |= IsData; + foundFlag = true; + } } while (foundFlag); + rule->symbol = NULL; + if (token(f, '<')) { + uint8_t *fnp = f->p; + while (fnp < f->end && *fnp != '>') { + fnp++; + } + if (fnp == f->end) { + fail(f, "Symbol has no closing '>'."); + } + int flen = fnp - f->p; + rule->symbol = malloc(flen); + memcpy(rule->symbol, f->p, flen); + rule->symbol[flen] = 0; + f->p = fnp + 1; + } return rule; } diff --git a/map.h b/map.h index c8841df..9ed9d0d 100644 --- a/map.h +++ b/map.h @@ -19,6 +19,7 @@ typedef enum { typedef struct Rule { uint32_t address; uint16_t flags; + char *symbol; struct Rule *next; } Rule; diff --git a/omf.c b/omf.c index 8667211..d8216ec 100644 --- a/omf.c +++ b/omf.c @@ -17,7 +17,7 @@ static char doc[] = "Relocate and extract OMF segments" static char args_doc[] = "FILE"; static struct argp_option options[] = { {"org", 'o', "ADDRESS", OPTION_ARG_OPTIONAL, - "Start mapping the segments at this address, default 20000"}, + "Start mapping the segments at this address, default $20000"}, {"map", 'm', "FILE", OPTION_ARG_OPTIONAL, "Use this map to extract the segments"}, {"prefix", 'p', "PREFIX", OPTION_ARG_OPTIONAL, @@ -37,16 +37,32 @@ static inline uint32_t parseNum(const char *s) { while (isspace(*s)) { s++; } - while (isxdigit(*s)) { - res <<= 4; - if (*s >= '0' && *s <= '9') { - res |= *s - '0'; - } else if (*s >= 'a' && *s <= 'f') { - res |= *s - 'a' + 10; - } else if (*s >= 'A' && *s <= 'F') { - res |= *s - 'A' + 10; - } + bool ishex = false; + if (s[0] == '0' && s[1] == 'x') { + s += 2; + ishex = true; + } else if (s[0] == '$') { s++; + ishex = true; + } + if (ishex) { + while (isxdigit(*s)) { + res <<= 4; + if (*s >= '0' && *s <= '9') { + res |= *s - '0'; + } else if (*s >= 'a' && *s <= 'f') { + res |= *s - 'a' + 10; + } else if (*s >= 'A' && *s <= 'F') { + res |= *s - 'A' + 10; + } + s++; + } + } else { + while (isdigit(*s)) { + res *= 10; + res += *s - '0'; + s++; + } } return res; } diff --git a/regs.c b/regs.c index 48e8309..469076c 100644 --- a/regs.c +++ b/regs.c @@ -4,6 +4,7 @@ */ #include +#include #include "handle.h" #include "scan.h" #include "disasm.h" @@ -14,7 +15,7 @@ static char doc[] = "Disassemble Apple IIgs software"; static char args_doc[] = "FILE or MAP"; static struct argp_option options[] = { {"org", 'o', "ADDRESS", 0, - "Starting address of the binary file, in hex"}, + "Starting address of the binary file"}, {"m", 'm', 0, OPTION_ARG_OPTIONAL, "Start with 8-bit accumulator"}, {"x", 'x', 0, OPTION_ARG_OPTIONAL, @@ -35,16 +36,32 @@ static inline uint32_t parseNum(const char *s) { while (isspace(*s)) { s++; } - while (isxdigit(*s)) { - res <<= 4; - if (*s >= '0' && *s <= '9') { - res |= *s - '0'; - } else if (*s >= 'a' && *s <= 'f') { - res |= *s - 'a' + 10; - } else if (*s >= 'A' && *s <= 'F') { - res |= *s - 'A' + 10; - } + bool ishex = false; + if (s[0] == '0' && s[1] == 'x') { + s += 2; + ishex = true; + } else if (s[0] == '$') { s++; + ishex = true; + } + if (ishex) { + while (isxdigit(*s)) { + res <<= 4; + if (*s >= '0' && *s <= '9') { + res |= *s - '0'; + } else if (*s >= 'a' && *s <= 'f') { + res |= *s - 'a' + 10; + } else if (*s >= 'A' && *s <= 'F') { + res |= *s - 'A' + 10; + } + s++; + } + } else { + while (isdigit(*s)) { + res *= 10; + res += *s - '0'; + s++; + } } return res; } diff --git a/scan.c b/scan.c index 77c44eb..a039295 100644 --- a/scan.c +++ b/scan.c @@ -52,7 +52,9 @@ void scan(uint8_t *data, size_t len, Map *map) { map->mem = calloc(len, sizeof(MapFlags)); for (Rule *rule = map->rules; rule != NULL; rule = rule->next) { - appendList(&toScan, rule->address, rule->flags); + if (rule->flags & IsOpcode) { + appendList(&toScan, rule->address, rule->flags); + } } while (toScan.num > 0) {