mirror of
https://github.com/mrkite/regs.git
synced 2025-02-21 22:29:05 +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:
|
$30000:
|
||||||
$30053:mx
|
$30053:mx
|
||||||
$31066:e
|
$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.
|
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.
|
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`.
|
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
|
## Pascal folder
|
||||||
@ -200,7 +208,7 @@ registers.
|
|||||||
|
|
||||||
So we can use all of that information to disassemble this file.
|
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
|
This tells regs to start with 8-bit accumulator and indices, and load the
|
||||||
file starting at `$2000` before disassembling it.
|
file starting at `$2000` before disassembling it.
|
||||||
|
@ -399,7 +399,7 @@ static MemAddress addresses[] = {
|
|||||||
|
|
||||||
#define numAddresses (sizeof(addresses) / sizeof(addresses[0]))
|
#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++) {
|
for (int i = 0; i < numAddresses; i++) {
|
||||||
if (addresses[i].address >= addr) {
|
if (addresses[i].address >= addr) {
|
||||||
if (addresses[i].address == addr)
|
if (addresses[i].address == addr)
|
||||||
@ -407,7 +407,12 @@ static const char *addressLookup(uint32_t addr) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Rule *rule = map->rules; rule != NULL; rule = rule->next) {
|
||||||
|
if (rule->address == addr && rule->symbol != NULL) {
|
||||||
|
return rule->symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (addr & ~0xffff)
|
if (addr & ~0xffff)
|
||||||
return addressLookup(addr & 0xffff); // try pageless
|
return addressLookup(addr & 0xffff, map); // try pageless
|
||||||
return NULL;
|
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++);
|
printf("#$%02x", *ptr++);
|
||||||
oprlen = 4;
|
oprlen = 4;
|
||||||
} else {
|
} else {
|
||||||
printf("#$%04x", r16(ptr)); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
|
printf("#$%04x", val);
|
||||||
oprlen = 6;
|
oprlen = 6;
|
||||||
|
comments = addressLookup(val, map);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IMMX:
|
case IMMX:
|
||||||
@ -141,40 +143,50 @@ void disassemble(uint8_t *data, size_t len, Map *map) {
|
|||||||
x = r16(ptr); ptr += 2;
|
x = r16(ptr); ptr += 2;
|
||||||
printf("#$%04x", x);
|
printf("#$%04x", x);
|
||||||
oprlen = 6;
|
oprlen = 6;
|
||||||
|
comments = addressLookup(x, map);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IMMS:
|
case IMMS:
|
||||||
printf("#$%04x", r16(ptr)); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
|
printf("#$%04x", val);
|
||||||
oprlen = 6;
|
oprlen = 6;
|
||||||
|
comments = addressLookup(x, map);
|
||||||
break;
|
break;
|
||||||
case ABS:
|
case ABS:
|
||||||
val = r16(ptr); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
printf("$%04x", val);
|
printf("$%04x", val);
|
||||||
oprlen = 5;
|
oprlen = 5;
|
||||||
comments = addressLookup(val);
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case ABL:
|
case ABL:
|
||||||
val = r24(ptr); ptr += 3;
|
val = r24(ptr); ptr += 3;
|
||||||
printf("$%02x/%04x", val >> 16, val & 0xffff);
|
printf("$%02x/%04x", val >> 16, val & 0xffff);
|
||||||
oprlen = 8;
|
oprlen = 8;
|
||||||
comments = addressLookup(val);
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case ABX:
|
case ABX:
|
||||||
printf("$%04x, x", r16(ptr)); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
|
printf("$%04x, x", val);
|
||||||
oprlen = 8;
|
oprlen = 8;
|
||||||
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case ABY:
|
case ABY:
|
||||||
printf("$%04x, y", r16(ptr)); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
|
printf("$%04x, y", val);
|
||||||
oprlen = 8;
|
oprlen = 8;
|
||||||
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case ABLX:
|
case ABLX:
|
||||||
val = r24(ptr); ptr += 3;
|
val = r24(ptr); ptr += 3;
|
||||||
printf("$%02x/%04x, x", val >> 16, val & 0xffff);
|
printf("$%02x/%04x, x", val >> 16, val & 0xffff);
|
||||||
oprlen = 11;
|
oprlen = 11;
|
||||||
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case AIX:
|
case AIX:
|
||||||
printf("($%04x, x)", r16(ptr)); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
|
printf("($%04x, x)", val);
|
||||||
oprlen = 10;
|
oprlen = 10;
|
||||||
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case ZP:
|
case ZP:
|
||||||
printf("$%02x", *ptr++);
|
printf("$%02x", *ptr++);
|
||||||
@ -193,8 +205,10 @@ void disassemble(uint8_t *data, size_t len, Map *map) {
|
|||||||
oprlen = 6;
|
oprlen = 6;
|
||||||
break;
|
break;
|
||||||
case IND:
|
case IND:
|
||||||
printf("($%04x)", r16(ptr)); ptr += 2;
|
val = r16(ptr); ptr += 2;
|
||||||
|
printf("($%04x)", val);
|
||||||
oprlen = 7;
|
oprlen = 7;
|
||||||
|
comments = addressLookup(val, map);
|
||||||
break;
|
break;
|
||||||
case INZ:
|
case INZ:
|
||||||
printf("($%02x)", *ptr++);
|
printf("($%02x)", *ptr++);
|
||||||
@ -225,12 +239,14 @@ void disassemble(uint8_t *data, size_t len, Map *map) {
|
|||||||
d6 = delta + addr;
|
d6 = delta + addr;
|
||||||
printf("$%02x/%04x", d6 >> 16, d6 & 0xffff);
|
printf("$%02x/%04x", d6 >> 16, d6 & 0xffff);
|
||||||
oprlen = 8;
|
oprlen = 8;
|
||||||
|
comments = addressLookup(d6, map);
|
||||||
break;
|
break;
|
||||||
case RELL:
|
case RELL:
|
||||||
delta16 = r16(ptr); ptr += 2;
|
delta16 = r16(ptr); ptr += 2;
|
||||||
d6 = delta16 + addr;
|
d6 = delta16 + addr;
|
||||||
printf("$%02x/%04x", d6 >> 16, d6 & 0xffff);
|
printf("$%02x/%04x", d6 >> 16, d6 & 0xffff);
|
||||||
oprlen = 8;
|
oprlen = 8;
|
||||||
|
comments = addressLookup(d6, map);
|
||||||
break;
|
break;
|
||||||
case BANK:
|
case BANK:
|
||||||
val = *ptr++;
|
val = *ptr++;
|
||||||
|
20
map.c
20
map.c
@ -48,7 +48,27 @@ static Rule *parseRule(ConfigFile *f) {
|
|||||||
rule->flags |= IsX8;
|
rule->flags |= IsX8;
|
||||||
foundFlag = true;
|
foundFlag = true;
|
||||||
}
|
}
|
||||||
|
if (token(f, 'd')) {
|
||||||
|
rule->flags &= ~IsOpcode;
|
||||||
|
rule->flags |= IsData;
|
||||||
|
foundFlag = true;
|
||||||
|
}
|
||||||
} while (foundFlag);
|
} 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;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
map.h
1
map.h
@ -19,6 +19,7 @@ typedef enum {
|
|||||||
typedef struct Rule {
|
typedef struct Rule {
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
char *symbol;
|
||||||
struct Rule *next;
|
struct Rule *next;
|
||||||
} Rule;
|
} 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 char args_doc[] = "FILE";
|
||||||
static struct argp_option options[] = {
|
static struct argp_option options[] = {
|
||||||
{"org", 'o', "ADDRESS", OPTION_ARG_OPTIONAL,
|
{"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,
|
{"map", 'm', "FILE", OPTION_ARG_OPTIONAL,
|
||||||
"Use this map to extract the segments"},
|
"Use this map to extract the segments"},
|
||||||
{"prefix", 'p', "PREFIX", OPTION_ARG_OPTIONAL,
|
{"prefix", 'p', "PREFIX", OPTION_ARG_OPTIONAL,
|
||||||
@ -37,16 +37,32 @@ static inline uint32_t parseNum(const char *s) {
|
|||||||
while (isspace(*s)) {
|
while (isspace(*s)) {
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
while (isxdigit(*s)) {
|
bool ishex = false;
|
||||||
res <<= 4;
|
if (s[0] == '0' && s[1] == 'x') {
|
||||||
if (*s >= '0' && *s <= '9') {
|
s += 2;
|
||||||
res |= *s - '0';
|
ishex = true;
|
||||||
} else if (*s >= 'a' && *s <= 'f') {
|
} else if (s[0] == '$') {
|
||||||
res |= *s - 'a' + 10;
|
|
||||||
} else if (*s >= 'A' && *s <= 'F') {
|
|
||||||
res |= *s - 'A' + 10;
|
|
||||||
}
|
|
||||||
s++;
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
37
regs.c
37
regs.c
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "scan.h"
|
#include "scan.h"
|
||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
@ -14,7 +15,7 @@ static char doc[] = "Disassemble Apple IIgs software";
|
|||||||
static char args_doc[] = "FILE or MAP";
|
static char args_doc[] = "FILE or MAP";
|
||||||
static struct argp_option options[] = {
|
static struct argp_option options[] = {
|
||||||
{"org", 'o', "ADDRESS", 0,
|
{"org", 'o', "ADDRESS", 0,
|
||||||
"Starting address of the binary file, in hex"},
|
"Starting address of the binary file"},
|
||||||
{"m", 'm', 0, OPTION_ARG_OPTIONAL,
|
{"m", 'm', 0, OPTION_ARG_OPTIONAL,
|
||||||
"Start with 8-bit accumulator"},
|
"Start with 8-bit accumulator"},
|
||||||
{"x", 'x', 0, OPTION_ARG_OPTIONAL,
|
{"x", 'x', 0, OPTION_ARG_OPTIONAL,
|
||||||
@ -35,16 +36,32 @@ static inline uint32_t parseNum(const char *s) {
|
|||||||
while (isspace(*s)) {
|
while (isspace(*s)) {
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
while (isxdigit(*s)) {
|
bool ishex = false;
|
||||||
res <<= 4;
|
if (s[0] == '0' && s[1] == 'x') {
|
||||||
if (*s >= '0' && *s <= '9') {
|
s += 2;
|
||||||
res |= *s - '0';
|
ishex = true;
|
||||||
} else if (*s >= 'a' && *s <= 'f') {
|
} else if (s[0] == '$') {
|
||||||
res |= *s - 'a' + 10;
|
|
||||||
} else if (*s >= 'A' && *s <= 'F') {
|
|
||||||
res |= *s - 'A' + 10;
|
|
||||||
}
|
|
||||||
s++;
|
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;
|
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));
|
map->mem = calloc(len, sizeof(MapFlags));
|
||||||
|
|
||||||
for (Rule *rule = map->rules; rule != NULL; rule = rule->next) {
|
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) {
|
while (toScan.num > 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user