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));
|
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;
|
*error = true;
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@ -1361,7 +1370,10 @@ void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path)
|
|||||||
if (!gb->bank_symbols[bank]) {
|
if (!gb->bank_symbols[bank]) {
|
||||||
gb->bank_symbols[bank] = GB_map_alloc();
|
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);
|
free(line);
|
||||||
|
@ -142,6 +142,13 @@ void GB_free(GB_gameboy_t *gb)
|
|||||||
GB_map_free(gb->bank_symbols[i]);
|
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)
|
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;
|
uint16_t n_watchpoints;
|
||||||
struct GB_watchpoint_s *watchpoints;
|
struct GB_watchpoint_s *watchpoints;
|
||||||
|
|
||||||
/* Symbol table */
|
/* Symbol tables */
|
||||||
GB_symbol_map_t *bank_symbols[0x200];
|
GB_symbol_map_t *bank_symbols[0x200];
|
||||||
|
GB_reversed_symbol_map_t reversed_symbol_map;
|
||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
bool turbo;
|
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;
|
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);
|
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]));
|
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]));
|
memmove(&map->symbols[index + 1], &map->symbols[index], (map->n_symbols - index) * sizeof(map->symbols[0]));
|
||||||
map->symbols[index].addr = addr;
|
map->symbols[index].addr = addr;
|
||||||
map->symbols[index].name = strdup(name);
|
map->symbols[index].name = strdup(name);
|
||||||
map->n_symbols++;
|
map->n_symbols++;
|
||||||
|
return &map->symbols[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr)
|
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);
|
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>
|
#include <string.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t addr;
|
|
||||||
char *name;
|
char *name;
|
||||||
|
uint16_t addr;
|
||||||
} GB_bank_symbol_t;
|
} 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 {
|
typedef struct {
|
||||||
GB_bank_symbol_t *symbols;
|
GB_bank_symbol_t *symbols;
|
||||||
size_t n_symbols;
|
size_t n_symbols;
|
||||||
} GB_symbol_map_t;
|
} 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);
|
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);
|
GB_symbol_map_t *GB_map_alloc(void);
|
||||||
void GB_map_free(GB_symbol_map_t *map);
|
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 */
|
#endif /* symbol_hash_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user