From bdbe02b043d624dc3e0de9f8d0bb79b9b26a1c17 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 26 Nov 2021 13:54:28 +0200 Subject: [PATCH] Add a safe memory read API --- Cocoa/Document.m | 2 +- Core/debugger.c | 4 ++-- Core/gb.h | 1 + Core/memory.c | 14 +++++++++++++- Core/memory.h | 1 + Core/sm83_disassembler.c | 1 + 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Cocoa/Document.m b/Cocoa/Document.m index 39f0852..fafdefc 100644 --- a/Cocoa/Document.m +++ b/Cocoa/Document.m @@ -1335,7 +1335,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) - (uint8_t) readMemory:(uint16_t)addr { while (!GB_is_inited(&gb)); - return GB_read_memory(&gb, addr); + return GB_safe_read_memory(&gb, addr); } - (void) writeMemory:(uint16_t)addr value:(uint8_t)value diff --git a/Core/debugger.c b/Core/debugger.c index 5547721..b8d88d7 100644 --- a/Core/debugger.c +++ b/Core/debugger.c @@ -1451,7 +1451,7 @@ static bool examine(GB_gameboy_t *gb, char *arguments, char *modifiers, const de while (count) { GB_log(gb, "%02x:%04x: ", addr.bank, addr.value); for (unsigned i = 0; i < 16 && count; i++) { - GB_log(gb, "%02x ", GB_read_memory(gb, addr.value + i)); + GB_log(gb, "%02x ", GB_safe_read_memory(gb, addr.value + i)); count--; } addr.value += 16; @@ -1464,7 +1464,7 @@ static bool examine(GB_gameboy_t *gb, char *arguments, char *modifiers, const de while (count) { GB_log(gb, "%04x: ", addr.value); for (unsigned i = 0; i < 16 && count; i++) { - GB_log(gb, "%02x ", GB_read_memory(gb, addr.value + i)); + GB_log(gb, "%02x ", GB_safe_read_memory(gb, addr.value + i)); count--; } addr.value += 16; diff --git a/Core/gb.h b/Core/gb.h index 0d3846a..d7d988d 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -742,6 +742,7 @@ struct GB_gameboy_internal_s { /* Temporary state */ bool wx_just_changed; bool tile_sel_glitch; + bool disable_oam_corruption; // For safe memory reads GB_gbs_header_t gbs_header; ); diff --git a/Core/memory.c b/Core/memory.c index 4e6665e..f428f05 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -444,7 +444,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) } if (gb->oam_read_blocked) { - if (!GB_is_cgb(gb)) { + if (!GB_is_cgb(gb) && !gb->disable_oam_corruption) { if (addr < 0xFEA0) { uint16_t *oam = (uint16_t *)gb->oam; if (gb->accessed_oam_row == 0) { @@ -702,6 +702,18 @@ uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr) return data; } +uint8_t GB_safe_read_memory(GB_gameboy_t *gb, uint16_t addr) +{ + gb->disable_oam_corruption = true; + uint8_t data = read_map[addr >> 12](gb, addr); + gb->disable_oam_corruption = false; + GB_apply_cheat(gb, addr, &data); + if (gb->read_memory_callback) { + data = gb->read_memory_callback(gb, addr, data); + } + return data; +} + static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value) { switch (gb->cartridge_type->mbc_type) { diff --git a/Core/memory.h b/Core/memory.h index 0b7a43c..f351339 100644 --- a/Core/memory.h +++ b/Core/memory.h @@ -7,6 +7,7 @@ typedef uint8_t (*GB_read_memory_callback_t)(GB_gameboy_t *gb, uint16_t addr, ui void GB_set_read_memory_callback(GB_gameboy_t *gb, GB_read_memory_callback_t callback); 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 void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value); #ifdef GB_INTERNAL internal void GB_dma_run(GB_gameboy_t *gb); diff --git a/Core/sm83_disassembler.c b/Core/sm83_disassembler.c index 894c766..f85bfc2 100644 --- a/Core/sm83_disassembler.c +++ b/Core/sm83_disassembler.c @@ -2,6 +2,7 @@ #include #include "gb.h" +#define GB_read_memory GB_safe_read_memory typedef void opcode_t(GB_gameboy_t *gb, uint8_t opcode, uint16_t *pc);