Symbol support in the expression evaluator
This commit is contained in:
parent
c3a831db7d
commit
e20e81befd
@ -498,7 +498,16 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
|
||||
return VALUE_16(GB_read_memory(gb, *watchpoint_address));
|
||||
}
|
||||
}
|
||||
GB_log(gb, "Unknown register: %.*s\n", length, string);
|
||||
|
||||
char symbol_name[length + 1];
|
||||
memcpy(symbol_name, string, length);
|
||||
symbol_name[length] = 0;
|
||||
const GB_symbol_t *symbol = GB_reversed_map_find_symbol(&gb->reversed_symbol_map, symbol_name);
|
||||
if (symbol) {
|
||||
return (value_t){true, symbol->bank, symbol->addr};
|
||||
}
|
||||
|
||||
GB_log(gb, "Unknown register or symbol: %.*s\n", length, string);
|
||||
*error = true;
|
||||
return ERROR;
|
||||
}
|
||||
@ -1361,7 +1370,10 @@ void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path)
|
||||
if (!gb->bank_symbols[bank]) {
|
||||
gb->bank_symbols[bank] = GB_map_alloc();
|
||||
}
|
||||
GB_map_add_symbol(gb->bank_symbols[bank], address, symbol);
|
||||
GB_bank_symbol_t *allocated_symbol = GB_map_add_symbol(gb->bank_symbols[bank], address, symbol);
|
||||
if (allocated_symbol) {
|
||||
GB_reversed_map_add_symbol(&gb->reversed_symbol_map, bank, allocated_symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
|
@ -142,6 +142,13 @@ void GB_free(GB_gameboy_t *gb)
|
||||
GB_map_free(gb->bank_symbols[i]);
|
||||
}
|
||||
}
|
||||
for (int i = 0x400; i--;) {
|
||||
if (gb->reversed_symbol_map.buckets[i]) {
|
||||
GB_symbol_t *next = gb->reversed_symbol_map.buckets[i]->next;
|
||||
free(gb->reversed_symbol_map.buckets[i]);
|
||||
gb->reversed_symbol_map.buckets[i] = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GB_load_boot_rom(GB_gameboy_t *gb, const char *path)
|
||||
|
@ -360,8 +360,9 @@ typedef struct GB_gameboy_s {
|
||||
uint16_t n_watchpoints;
|
||||
struct GB_watchpoint_s *watchpoints;
|
||||
|
||||
/* Symbol table */
|
||||
/* Symbol tables */
|
||||
GB_symbol_map_t *bank_symbols[0x200];
|
||||
GB_reversed_symbol_map_t reversed_symbol_map;
|
||||
|
||||
/* Misc */
|
||||
bool turbo;
|
||||
|
@ -20,17 +20,18 @@ static size_t GB_map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr)
|
||||
return (size_t) min;
|
||||
}
|
||||
|
||||
void GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name)
|
||||
GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name)
|
||||
{
|
||||
size_t index = GB_map_find_symbol_index(map, addr);
|
||||
|
||||
if (index < map->n_symbols && map->symbols[index].addr == addr) return;
|
||||
if (index < map->n_symbols && map->symbols[index].addr == addr) return NULL;
|
||||
|
||||
map->symbols = realloc(map->symbols, (map->n_symbols + 1) * sizeof(map->symbols[0]));
|
||||
memmove(&map->symbols[index + 1], &map->symbols[index], (map->n_symbols - index) * sizeof(map->symbols[0]));
|
||||
map->symbols[index].addr = addr;
|
||||
map->symbols[index].name = strdup(name);
|
||||
map->n_symbols++;
|
||||
return &map->symbols[index];
|
||||
}
|
||||
|
||||
const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr)
|
||||
@ -65,3 +66,41 @@ void GB_map_free(GB_symbol_map_t *map)
|
||||
|
||||
free(map);
|
||||
}
|
||||
|
||||
static int hash_name(const char *name)
|
||||
{
|
||||
int r = 0;
|
||||
while (*name) {
|
||||
r <<= 1;
|
||||
if (r & 0x400) {
|
||||
r ^= 0x401;
|
||||
}
|
||||
r += (unsigned char)*(name++);
|
||||
}
|
||||
|
||||
return r & 0x3FF;
|
||||
}
|
||||
|
||||
void GB_reversed_map_add_symbol(GB_reversed_symbol_map_t *map, uint16_t bank, GB_bank_symbol_t *bank_symbol)
|
||||
{
|
||||
int hash = hash_name(bank_symbol->name);
|
||||
GB_symbol_t *symbol = malloc(sizeof(*symbol));
|
||||
symbol->name = bank_symbol->name;
|
||||
symbol->addr = bank_symbol->addr;
|
||||
symbol->bank = bank;
|
||||
symbol->next = map->buckets[hash];
|
||||
map->buckets[hash] = symbol;
|
||||
}
|
||||
|
||||
const GB_symbol_t *GB_reversed_map_find_symbol(GB_reversed_symbol_map_t *map, const char *name)
|
||||
{
|
||||
int hash = hash_name(name);
|
||||
GB_symbol_t *symbol = map->buckets[hash];
|
||||
|
||||
while (symbol) {
|
||||
if (strcmp(symbol->name, name) == 0) return symbol;
|
||||
symbol = symbol->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -5,19 +5,32 @@
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t addr;
|
||||
char *name;
|
||||
uint16_t addr;
|
||||
} GB_bank_symbol_t;
|
||||
|
||||
typedef struct GB_symbol_s {
|
||||
struct GB_symbol_s *next;
|
||||
const char *name;
|
||||
uint16_t bank;
|
||||
uint16_t addr;
|
||||
} GB_symbol_t;
|
||||
|
||||
typedef struct {
|
||||
GB_bank_symbol_t *symbols;
|
||||
size_t n_symbols;
|
||||
} GB_symbol_map_t;
|
||||
|
||||
void GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name);
|
||||
GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name);
|
||||
const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr);
|
||||
GB_symbol_map_t *GB_map_alloc(void);
|
||||
void GB_map_free(GB_symbol_map_t *map);
|
||||
|
||||
typedef struct {
|
||||
GB_symbol_t *buckets[0x400];
|
||||
} GB_reversed_symbol_map_t;
|
||||
|
||||
void GB_reversed_map_add_symbol(GB_reversed_symbol_map_t *map, uint16_t bank, GB_bank_symbol_t *symbol);
|
||||
const GB_symbol_t *GB_reversed_map_find_symbol(GB_reversed_symbol_map_t *map, const char *name);
|
||||
|
||||
#endif /* symbol_hash_h */
|
||||
|
Loading…
Reference in New Issue
Block a user