mirror of
https://github.com/bradgrantham/apple2e.git
synced 2024-06-09 08:29:28 +00:00
Parse ld65 map file for symbolic debugging.
This commit is contained in:
parent
14a84bdb6a
commit
bfe64192a3
99
apple2e.cpp
99
apple2e.cpp
|
@ -45,6 +45,9 @@ APPLE2Einterface::ModeHistory mode_history;
|
||||||
|
|
||||||
const float paddle_max_pulse_seconds = .00282;
|
const float paddle_max_pulse_seconds = .00282;
|
||||||
|
|
||||||
|
// Map from memory address to name of function (from the ld65 map file).
|
||||||
|
static map<int,string> address_to_function_name;
|
||||||
|
|
||||||
typedef unsigned long long clk_t;
|
typedef unsigned long long clk_t;
|
||||||
struct system_clock
|
struct system_clock
|
||||||
{
|
{
|
||||||
|
@ -86,6 +89,73 @@ bool read_blob(char *name, unsigned char *b, size_t sz)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a map entry from an ld65 map file and add it to the address_to_function_name map.
|
||||||
|
*/
|
||||||
|
static void add_map_entry(char *line)
|
||||||
|
{
|
||||||
|
// Find end of function name and terminate it.
|
||||||
|
char *s = line;
|
||||||
|
while (*s != ' ') {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*s = '\0';
|
||||||
|
string function_name = string(line);
|
||||||
|
|
||||||
|
// Parse hex address.
|
||||||
|
int address = strtol(line + 26, NULL, 16);
|
||||||
|
|
||||||
|
// See if we have a duplicate. We define our own symbols (like _pushax) as aliases
|
||||||
|
// to cc65-defined ones (like pushax) so we can access them from C.
|
||||||
|
string old_function_name = address_to_function_name[address];
|
||||||
|
if (old_function_name.size() != 0 && old_function_name.size() < function_name.size()) {
|
||||||
|
// Skip this one, we already have one that's shorter (probably without
|
||||||
|
// leading underscore).
|
||||||
|
} else {
|
||||||
|
// Add to map.
|
||||||
|
address_to_function_name[address] = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a map file generated by ld65. Puts symbols into the address_to_function_name map.
|
||||||
|
*/
|
||||||
|
static bool read_map(char *name)
|
||||||
|
{
|
||||||
|
char line[100];
|
||||||
|
FILE *fp = fopen(name, "r");
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
while (state != 3 && fgets(line, sizeof(line), fp) != NULL) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (strncmp(line, "Exports list by name:", 21) == 0) {
|
||||||
|
// Found header.
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// Skip line with dashes.
|
||||||
|
state = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// Parse table.
|
||||||
|
if (strlen(line) <= 76) {
|
||||||
|
// End of table.
|
||||||
|
state = 3;
|
||||||
|
}
|
||||||
|
add_map_entry(line);
|
||||||
|
add_map_entry(line + 40);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct SoftSwitch
|
struct SoftSwitch
|
||||||
{
|
{
|
||||||
string name;
|
string name;
|
||||||
|
@ -1051,6 +1121,7 @@ struct MAINboard : board_base
|
||||||
disassemble_buffer = new unsigned char[data];
|
disassemble_buffer = new unsigned char[data];
|
||||||
disassemble_size = data;
|
disassemble_size = data;
|
||||||
disassemble_index = 0;
|
disassemble_index = 0;
|
||||||
|
printf("Size of buffer: %d bytes\n", disassemble_size);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (addr == 0xBFFF) {
|
} else if (addr == 0xBFFF) {
|
||||||
|
@ -1063,7 +1134,17 @@ struct MAINboard : board_base
|
||||||
string dis;
|
string dis;
|
||||||
for (int i = 0; i < disassemble_size; i += bytes) {
|
for (int i = 0; i < disassemble_size; i += bytes) {
|
||||||
tie(bytes, dis) = disassemble_6502(i, disassemble_buffer + i);
|
tie(bytes, dis) = disassemble_6502(i, disassemble_buffer + i);
|
||||||
printf("%s\n", dis.c_str());
|
printf("%-32s", dis.c_str());
|
||||||
|
if (bytes == 3) {
|
||||||
|
// Print function name if we have it.
|
||||||
|
int address = disassemble_buffer[i + 1] +
|
||||||
|
(disassemble_buffer[i + 2] << 8);
|
||||||
|
auto search = address_to_function_name.find(address);
|
||||||
|
if (search != address_to_function_name.end()) {
|
||||||
|
printf(" ; %s", search->second.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
delete[] disassemble_buffer;
|
delete[] disassemble_buffer;
|
||||||
|
@ -2695,7 +2776,7 @@ struct CPU6502
|
||||||
void usage(char *progname)
|
void usage(char *progname)
|
||||||
{
|
{
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("usage: %s [-debugger] [-fast] ROM.bin\n", progname);
|
printf("usage: %s [-debugger] [-fast] [-map ld65.map] ROM.bin\n", progname);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -2933,6 +3014,7 @@ int main(int argc, char **argv)
|
||||||
argc -= 1;
|
argc -= 1;
|
||||||
argv += 1;
|
argv += 1;
|
||||||
char *diskII_rom_name = NULL, *floppy1_name = NULL, *floppy2_name = NULL;
|
char *diskII_rom_name = NULL, *floppy1_name = NULL, *floppy2_name = NULL;
|
||||||
|
char *map_name = NULL;
|
||||||
|
|
||||||
while((argc > 0) && (argv[0][0] == '-')) {
|
while((argc > 0) && (argv[0][0] == '-')) {
|
||||||
if(strcmp(argv[0], "-debugger") == 0) {
|
if(strcmp(argv[0], "-debugger") == 0) {
|
||||||
|
@ -2965,6 +3047,14 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
argv += 2;
|
argv += 2;
|
||||||
argc -= 2;
|
argc -= 2;
|
||||||
|
} else if(strcmp(argv[0], "-map") == 0) {
|
||||||
|
if(argc < 2) {
|
||||||
|
fprintf(stderr, "-map option requires an ld65 map filename.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
map_name = argv[1];
|
||||||
|
argv += 2;
|
||||||
|
argc -= 2;
|
||||||
} else if(
|
} else if(
|
||||||
(strcmp(argv[0], "-help") == 0) ||
|
(strcmp(argv[0], "-help") == 0) ||
|
||||||
(strcmp(argv[0], "-h") == 0) ||
|
(strcmp(argv[0], "-h") == 0) ||
|
||||||
|
@ -2996,6 +3086,11 @@ int main(int argc, char **argv)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(map_name != NULL) {
|
||||||
|
if(!read_map(map_name))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
system_clock clk;
|
system_clock clk;
|
||||||
|
|
||||||
MAINboard* mainboard;
|
MAINboard* mainboard;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user