diff --git a/Core/debugger.c b/Core/debugger.c index 94eaa08..3e8223f 100644 --- a/Core/debugger.c +++ b/Core/debugger.c @@ -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); diff --git a/Core/gb.c b/Core/gb.c index 13f29ba..82847e4 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -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) diff --git a/Core/gb.h b/Core/gb.h index 04ebb95..f5221ea 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -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; diff --git a/Core/symbol_hash.c b/Core/symbol_hash.c index 86d5029..7f5cbe2 100644 --- a/Core/symbol_hash.c +++ b/Core/symbol_hash.c @@ -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) @@ -64,4 +65,42 @@ 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; } \ No newline at end of file diff --git a/Core/symbol_hash.h b/Core/symbol_hash.h index 8044e3f..0544f94 100644 --- a/Core/symbol_hash.h +++ b/Core/symbol_hash.h @@ -5,19 +5,32 @@ #include 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 */