mirror of
https://github.com/mrkite/regs.git
synced 2024-09-07 11:54:25 +00:00
added symbols
This commit is contained in:
parent
d73ecd7868
commit
9461dc4cb5
10
README.md
10
README.md
@ -57,6 +57,7 @@ sORG $30000
|
||||
$30000:
|
||||
$30053:mx
|
||||
$31066:e
|
||||
$35440:d <myTable>
|
||||
```
|
||||
|
||||
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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
32
disasm.c
32
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++;
|
||||
|
20
map.c
20
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;
|
||||
}
|
||||
|
||||
|
1
map.h
1
map.h
@ -19,6 +19,7 @@ typedef enum {
|
||||
typedef struct Rule {
|
||||
uint32_t address;
|
||||
uint16_t flags;
|
||||
char *symbol;
|
||||
struct Rule *next;
|
||||
} Rule;
|
||||
|
||||
|
36
omf.c
36
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;
|
||||
}
|
||||
|
37
regs.c
37
regs.c
@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <argp.h>
|
||||
#include <stdbool.h>
|
||||
#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;
|
||||
}
|
||||
|
4
scan.c
4
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user