From 07459e64910757b600bca55715507b0264d19c2d Mon Sep 17 00:00:00 2001 From: smf- Date: Thu, 27 Mar 2008 20:23:36 +0000 Subject: [PATCH] Passes mem_mask to the read and write debug hooks. This allows the address & size of the memory access to be correctly calculated when using a memory call that takes a mem_mask. Unexpected results will occur if you pass in a mem_mask that has a gap in. For example 0x00ff00ff is treated as a 3 byte operation, a watchpoint for the gap will still trigger. To simplify the mem_mask decoding it is inverted before passing to the debugger. --- src/emu/debug/debugcpu.c | 55 +++++++++++++++++++++++++++++++--------- src/emu/debug/debugcpu.h | 4 +-- src/emu/memory.c | 44 ++++++++++++++++---------------- 3 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c index 23bbbd7267d..5640fe483a7 100644 --- a/src/emu/debug/debugcpu.c +++ b/src/emu/debug/debugcpu.c @@ -93,7 +93,7 @@ static void set_logunmap(UINT32 ref, UINT64 value); static UINT64 get_current_pc(UINT32 ref); static UINT64 get_cpu_reg(UINT32 ref); static void set_cpu_reg(UINT32 ref, UINT64 value); -static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address, offs_t size, UINT64 value_to_write); +static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask); static void check_hotspots(int cpunum, int spacenum, offs_t address); @@ -1079,13 +1079,13 @@ void debug_interrupt_hook(int cpunum, int irqline) standard_debug_hook_read - standard read hook -------------------------------------------------*/ -static void standard_debug_hook_read(int spacenum, int size, offs_t address) +static void standard_debug_hook_read(int spacenum, offs_t address, UINT64 mem_mask) { debug_cpu_info *info = &debug_cpuinfo[memory_hook_cpunum]; /* check watchpoints */ if (info->read_watchpoints) - check_watchpoints(memory_hook_cpunum, spacenum, WATCHPOINT_READ, address, size, 0); + check_watchpoints(memory_hook_cpunum, spacenum, WATCHPOINT_READ, address, 0, mem_mask); /* check hotspots */ if (info->hotspots) @@ -1097,13 +1097,13 @@ static void standard_debug_hook_read(int spacenum, int size, offs_t address) standard_debug_hook_write - standard write hook -------------------------------------------------*/ -static void standard_debug_hook_write(int spacenum, int size, offs_t address, UINT64 data) +static void standard_debug_hook_write(int spacenum, offs_t address, UINT64 data, UINT64 mem_mask) { debug_cpu_info *info = &debug_cpuinfo[memory_hook_cpunum]; /* check watchpoints */ if (info->write_watchpoints) - check_watchpoints(memory_hook_cpunum, spacenum, WATCHPOINT_WRITE, address, size, data); + check_watchpoints(memory_hook_cpunum, spacenum, WATCHPOINT_WRITE, address, data, mem_mask); } @@ -1307,10 +1307,11 @@ int debug_breakpoint_enable(int bpnum, int enable) breakpoints for a given CPU and address space -------------------------------------------------*/ -static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address, offs_t size, UINT64 value_to_write) +static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask) { debug_cpu_watchpoint *wp; UINT64 result; + offs_t size = 0; /* if we're within debugger code, don't stop */ if (within_debugger_code) @@ -1318,6 +1319,36 @@ static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address within_debugger_code = TRUE; + /* adjust address, size & value_to_write based on mem_mask. */ + if( mem_mask != 0 ) + { + const debug_cpu_info *info = &debug_cpuinfo[cpunum]; + int address_offset = 0; + int bus_size = info->space[spacenum].databytes; + + while (address_offset < bus_size && (mem_mask & 0xff) == 0) + { + address_offset++; + value_to_write >>= 8; + mem_mask >>= 8; + } + + while (mem_mask != 0) + { + size++; + mem_mask >>= 8; + } + + if (info->endianness == CPU_IS_LE) + { + address += address_offset; + } + else + { + address += bus_size - size - address_offset; + } + } + /* if we are a write watchpoint, stash the value that will be written */ wpaddr = address; if (type & WATCHPOINT_WRITE) @@ -1330,12 +1361,6 @@ static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address /* if we do, evaluate the condition */ if (wp->condition == NULL || (expression_execute(wp->condition, &result) == EXPRERR_NONE && result)) { - static const char *const sizes[] = - { - "0bytes", "byte", "word", "3bytes", "dword", "5bytes", "6bytes", "7bytes", "qword" - }; - char buffer[100]; - /* halt in the debugger by default */ execution_state = EXECUTION_STATE_STOPPED; @@ -1346,6 +1371,12 @@ static void check_watchpoints(int cpunum, int spacenum, int type, offs_t address /* print a notification, unless the action made us go again */ if (execution_state == EXECUTION_STATE_STOPPED) { + static const char *const sizes[] = + { + "0bytes", "byte", "word", "3bytes", "dword", "5bytes", "6bytes", "7bytes", "qword" + }; + char buffer[100]; + if (type & WATCHPOINT_WRITE) { sprintf(buffer, "Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->index, sizes[size], BYTE2ADDR(address, &debug_cpuinfo[cpunum], spacenum), activecpu_get_pc()); diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index 7eaeaf383e5..8f52c75b2fa 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -54,8 +54,8 @@ enum TYPE DEFINITIONS ***************************************************************************/ -typedef void (*debug_hook_read_func)(int spacenum, int size, offs_t address); -typedef void (*debug_hook_write_func)(int spacenum, int size, offs_t address, UINT64 data); +typedef void (*debug_hook_read_func)(int spacenum, offs_t address, UINT64 mem_mask); +typedef void (*debug_hook_write_func)(int spacenum, offs_t address, UINT64 data, UINT64 mem_mask); typedef struct _debug_trace_info debug_trace_info; diff --git a/src/emu/memory.c b/src/emu/memory.c index c0fa212448b..76250bd6b8c 100644 --- a/src/emu/memory.c +++ b/src/emu/memory.c @@ -196,11 +196,11 @@ typedef enum _read_or_write read_or_write; #define SUBTABLE_PTR(tabledata, entry) (&(tabledata)->table[(1 << LEVEL1_BITS) + (((entry) - SUBTABLE_BASE) << LEVEL2_BITS)]) #ifdef ENABLE_DEBUGGER -#define DEBUG_HOOK_READ(a,b,c) if (debug_hook_read) (*debug_hook_read)(a, b, c) -#define DEBUG_HOOK_WRITE(a,b,c,d) if (debug_hook_write) (*debug_hook_write)(a, b, c, d) +#define DEBUG_HOOK_READ(spacenum,address,mem_mask) if (debug_hook_read) (*debug_hook_read)(spacenum,address,mem_mask) +#define DEBUG_HOOK_WRITE(spacenum,address,data,mem_mask) if (debug_hook_write) (*debug_hook_write)(spacenum,address,data,mem_mask) #else -#define DEBUG_HOOK_READ(a,b,c) -#define DEBUG_HOOK_WRITE(a,b,c,d) +#define DEBUG_HOOK_READ(spacenum,address,mem_mask) +#define DEBUG_HOOK_WRITE(spacenum,address,data,mem_mask) #endif @@ -2514,7 +2514,7 @@ UINT8 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~0); \ - DEBUG_HOOK_READ(spacenum, 1, address); \ + DEBUG_HOOK_READ(spacenum, address, 0xff); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2534,7 +2534,7 @@ UINT8 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~0); \ - DEBUG_HOOK_READ(spacenum, 1, address); \ + DEBUG_HOOK_READ(spacenum, address - xormacro(shiftbytes), (masktype)0xff << (8 * (shiftbytes))); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2570,7 +2570,7 @@ UINT16 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~1); \ - DEBUG_HOOK_READ(spacenum, 2, address); \ + DEBUG_HOOK_READ(spacenum, address, 0xffff); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2590,7 +2590,7 @@ UINT16 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~1); \ - DEBUG_HOOK_READ(spacenum, 2, address); \ + DEBUG_HOOK_READ(spacenum, address - xormacro(shiftbytes), (masktype)0xffff << (8 * (shiftbytes))); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2624,7 +2624,7 @@ UINT32 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~3); \ - DEBUG_HOOK_READ(spacenum, 4, address); \ + DEBUG_HOOK_READ(spacenum, address, 0xffffffff); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2644,7 +2644,7 @@ UINT32 name(offs_t original_address, UINT32 mem_mask) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~3); \ - DEBUG_HOOK_READ(spacenum, 4, address); \ + DEBUG_HOOK_READ(spacenum, address, ~mem_mask); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2664,7 +2664,7 @@ UINT32 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~3); \ - DEBUG_HOOK_READ(spacenum, 4, address); \ + DEBUG_HOOK_READ(spacenum, address - xormacro(shiftbytes), (masktype)0xffffffff << (8 * (shiftbytes))); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2696,7 +2696,7 @@ UINT64 name(offs_t original_address) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~7); \ - DEBUG_HOOK_READ(spacenum, 8, address); \ + DEBUG_HOOK_READ(spacenum, address, ~(UINT64)0); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2716,7 +2716,7 @@ UINT64 name(offs_t original_address, UINT64 mem_mask) \ UINT32 entry; \ MEMREADSTART(); \ PERFORM_LOOKUP(readlookup,readhandlers,spacenum,~7); \ - DEBUG_HOOK_READ(spacenum, 8, address); \ + DEBUG_HOOK_READ(spacenum, address, ~mem_mask); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2741,7 +2741,7 @@ void name(offs_t original_address, UINT8 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~0); \ - DEBUG_HOOK_WRITE(spacenum, 1, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address, data, 0xff); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2761,7 +2761,7 @@ void name(offs_t original_address, UINT8 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~0); \ - DEBUG_HOOK_WRITE(spacenum, 1, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address - xormacro(shiftbytes), data, (masktype)0xff << (8 * (shiftbytes))); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2797,7 +2797,7 @@ void name(offs_t original_address, UINT16 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~1); \ - DEBUG_HOOK_WRITE(spacenum, 2, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address, data, 0xffff); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2817,7 +2817,7 @@ void name(offs_t original_address, UINT16 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~1); \ - DEBUG_HOOK_WRITE(spacenum, 2, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address - xormacro(shiftbytes), data, (masktype)0xffff << (8 * (shiftbytes))); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2851,7 +2851,7 @@ void name(offs_t original_address, UINT32 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~3); \ - DEBUG_HOOK_WRITE(spacenum, 4, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address, data, 0xffffffff); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2871,7 +2871,7 @@ void name(offs_t original_address, UINT32 data, UINT32 mem_mask) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~3); \ - DEBUG_HOOK_WRITE(spacenum, 4, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address, data, ~mem_mask); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2894,7 +2894,7 @@ void name(offs_t original_address, UINT32 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~3); \ - DEBUG_HOOK_WRITE(spacenum, 4, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address - xormacro(shiftbytes), data, (masktype)0xffffffff << (8 * (shiftbytes))); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2926,7 +2926,7 @@ void name(offs_t original_address, UINT64 data) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~7); \ - DEBUG_HOOK_WRITE(spacenum, 8, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address, data, ~(UINT64)0); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \ @@ -2946,7 +2946,7 @@ void name(offs_t original_address, UINT64 data, UINT64 mem_mask) \ UINT32 entry; \ MEMWRITESTART(); \ PERFORM_LOOKUP(writelookup,writehandlers,spacenum,~7); \ - DEBUG_HOOK_WRITE(spacenum, 8, address, data); \ + DEBUG_HOOK_WRITE(spacenum, address, data, ~mem_mask); \ \ /* handle banks inline */ \ address = (address - handler->bytestart) & handler->bytemask; \