Add memory write callback, optimize memory access with likely/unlikely
This commit is contained in:
parent
bdbe02b043
commit
06b744259b
@ -32,10 +32,11 @@ static uint16_t bank_for_addr(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
|
|
||||||
void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value)
|
void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value)
|
||||||
{
|
{
|
||||||
if (!gb->cheat_enabled) return;
|
if (likely(!gb->cheat_enabled)) return;
|
||||||
if (!gb->boot_rom_finished) return;
|
if (likely(gb->cheat_count == 0)) return; // Optimization
|
||||||
|
if (unlikely(!gb->boot_rom_finished)) return;
|
||||||
const GB_cheat_hash_t *hash = gb->cheat_hash[hash_addr(address)];
|
const GB_cheat_hash_t *hash = gb->cheat_hash[hash_addr(address)];
|
||||||
if (hash) {
|
if (unlikely(hash)) {
|
||||||
for (unsigned i = 0; i < hash->size; i++) {
|
for (unsigned i = 0; i < hash->size; i++) {
|
||||||
GB_cheat_t *cheat = hash->cheats[i];
|
GB_cheat_t *cheat = hash->cheats[i];
|
||||||
if (cheat->address == address && cheat->enabled && (!cheat->use_old_value || cheat->old_value == *value)) {
|
if (cheat->address == address && cheat->enabled && (!cheat->use_old_value || cheat->old_value == *value)) {
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#ifdef GB_INTERNAL
|
#ifdef GB_INTERNAL
|
||||||
|
|
||||||
// "Keyword" definitions
|
// "Keyword" definitions
|
||||||
#define likely(x) __builtin_expect((x), 1)
|
#define likely(x) __builtin_expect((bool)(x), 1)
|
||||||
#define unlikely(x) __builtin_expect((x), 0)
|
#define unlikely(x) __builtin_expect((bool)(x), 0)
|
||||||
|
|
||||||
#define internal __attribute__((visibility("internal")))
|
#define internal __attribute__((visibility("internal")))
|
||||||
|
|
||||||
|
@ -658,6 +658,7 @@ struct GB_gameboy_internal_s {
|
|||||||
GB_icd_vreset_callback_t icd_hreset_callback;
|
GB_icd_vreset_callback_t icd_hreset_callback;
|
||||||
GB_icd_vreset_callback_t icd_vreset_callback;
|
GB_icd_vreset_callback_t icd_vreset_callback;
|
||||||
GB_read_memory_callback_t read_memory_callback;
|
GB_read_memory_callback_t read_memory_callback;
|
||||||
|
GB_write_memory_callback_t write_memory_callback;
|
||||||
GB_boot_rom_load_callback_t boot_rom_load_callback;
|
GB_boot_rom_load_callback_t boot_rom_load_callback;
|
||||||
GB_print_image_callback_t printer_callback;
|
GB_print_image_callback_t printer_callback;
|
||||||
GB_workboy_set_time_callback workboy_set_time_callback;
|
GB_workboy_set_time_callback workboy_set_time_callback;
|
||||||
|
@ -688,15 +688,15 @@ void GB_set_read_memory_callback(GB_gameboy_t *gb, GB_read_memory_callback_t cal
|
|||||||
|
|
||||||
uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr)
|
uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr)
|
||||||
{
|
{
|
||||||
if (gb->n_watchpoints) {
|
if (unlikely(gb->n_watchpoints)) {
|
||||||
GB_debugger_test_read_watchpoint(gb, addr);
|
GB_debugger_test_read_watchpoint(gb, addr);
|
||||||
}
|
}
|
||||||
if (is_addr_in_dma_use(gb, addr)) {
|
if (unlikely(is_addr_in_dma_use(gb, addr))) {
|
||||||
addr = gb->dma_current_src;
|
addr = gb->dma_current_src;
|
||||||
}
|
}
|
||||||
uint8_t data = read_map[addr >> 12](gb, addr);
|
uint8_t data = read_map[addr >> 12](gb, addr);
|
||||||
GB_apply_cheat(gb, addr, &data);
|
GB_apply_cheat(gb, addr, &data);
|
||||||
if (gb->read_memory_callback) {
|
if (unlikely(gb->read_memory_callback)) {
|
||||||
data = gb->read_memory_callback(gb, addr, data);
|
data = gb->read_memory_callback(gb, addr, data);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
@ -708,7 +708,7 @@ uint8_t GB_safe_read_memory(GB_gameboy_t *gb, uint16_t addr)
|
|||||||
uint8_t data = read_map[addr >> 12](gb, addr);
|
uint8_t data = read_map[addr >> 12](gb, addr);
|
||||||
gb->disable_oam_corruption = false;
|
gb->disable_oam_corruption = false;
|
||||||
GB_apply_cheat(gb, addr, &data);
|
GB_apply_cheat(gb, addr, &data);
|
||||||
if (gb->read_memory_callback) {
|
if (unlikely(gb->read_memory_callback)) {
|
||||||
data = gb->read_memory_callback(gb, addr, data);
|
data = gb->read_memory_callback(gb, addr, data);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
@ -1563,12 +1563,22 @@ static write_function_t *const write_map[] =
|
|||||||
write_ram, write_high_memory, /* EXXX FXXX */
|
write_ram, write_high_memory, /* EXXX FXXX */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void GB_set_write_memory_callback(GB_gameboy_t *gb, GB_write_memory_callback_t callback)
|
||||||
|
{
|
||||||
|
gb->write_memory_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||||
{
|
{
|
||||||
if (gb->n_watchpoints) {
|
if (unlikely(gb->n_watchpoints)) {
|
||||||
GB_debugger_test_write_watchpoint(gb, addr, value);
|
GB_debugger_test_write_watchpoint(gb, addr, value);
|
||||||
}
|
}
|
||||||
if (is_addr_in_dma_use(gb, addr)) {
|
|
||||||
|
if (unlikely(gb->write_memory_callback)) {
|
||||||
|
if (!gb->write_memory_callback(gb, addr, value)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(is_addr_in_dma_use(gb, addr))) {
|
||||||
/* Todo: What should happen? Will this affect DMA? Will data be written? What and where? */
|
/* Todo: What should happen? Will this affect DMA? Will data be written? What and where? */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef uint8_t (*GB_read_memory_callback_t)(GB_gameboy_t *gb, uint16_t addr, uint8_t data);
|
typedef uint8_t (*GB_read_memory_callback_t)(GB_gameboy_t *gb, uint16_t addr, uint8_t data);
|
||||||
|
typedef bool (*GB_write_memory_callback_t)(GB_gameboy_t *gb, uint16_t addr, uint8_t data); // Return false to prevent the write
|
||||||
void GB_set_read_memory_callback(GB_gameboy_t *gb, GB_read_memory_callback_t callback);
|
void GB_set_read_memory_callback(GB_gameboy_t *gb, GB_read_memory_callback_t callback);
|
||||||
|
void GB_set_write_memory_callback(GB_gameboy_t *gb, GB_write_memory_callback_t callback);
|
||||||
|
|
||||||
uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr);
|
uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr);
|
||||||
uint8_t GB_safe_read_memory(GB_gameboy_t *gb, uint16_t addr); // Without side effects
|
uint8_t GB_safe_read_memory(GB_gameboy_t *gb, uint16_t addr); // Without side effects
|
||||||
|
Loading…
Reference in New Issue
Block a user