mirror of
https://github.com/holub/mame
synced 2025-05-28 16:43:04 +03:00
Big debugger cleanup.
Important note for OSD ports: the get/set property functions have been retired for debug_views. Instead, there are specific functions to perform each get/set operation. In addition, the format of the update callback has changed to pass the osd private data in, and the update callback/osd private data must be passed in at view allocation time. And osd_wait_for_debugger() now gets a CPU object instead of the machine. Removed extra debugger tracking for address spaces and added some of the useful data to the address_space structure. Updated all debugger commands and views to use CPU and address space objects where appropriate. Added new memory functions for converting between bytes and addresses, and for performing translations for a given address space. Removed debugger macros that did similar things in favor of calling these functions. Rewrote most of the memory view handling. Disasm and register views still need some additional tweaking.
This commit is contained in:
parent
e16734f2f3
commit
d924407859
@ -1308,11 +1308,12 @@ void cpu_reset(const device_config *device)
|
||||
|
||||
offs_t cpu_get_physical_pc_byte(const device_config *device)
|
||||
{
|
||||
const address_space *space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM);
|
||||
offs_t pc;
|
||||
|
||||
cpu_push_context(device);
|
||||
pc = cpu_address_to_byte(device, ADDRESS_SPACE_PROGRAM, cpu_get_info_int(device, CPUINFO_INT_PC));
|
||||
pc = cpu_address_physical(device, ADDRESS_SPACE_PROGRAM, TRANSLATE_FETCH, pc);
|
||||
pc = memory_address_to_byte(space, cpu_get_info_int(device, CPUINFO_INT_PC));
|
||||
memory_address_physical(space, TRANSLATE_FETCH, &pc);
|
||||
cpu_pop_context();
|
||||
return pc;
|
||||
}
|
||||
@ -1367,7 +1368,8 @@ offs_t cpu_dasm(const device_config *device, char *buffer, offs_t pc, const UINT
|
||||
assert((result & DASMFLAG_LENGTHMASK) != 0);
|
||||
#ifdef MAME_DEBUG
|
||||
{
|
||||
int bytes = cpu_address_to_byte(device, ADDRESS_SPACE_PROGRAM, result & DASMFLAG_LENGTHMASK);
|
||||
const address_space *space = classheader->space[ADDRESS_SPACE_PROGRAM];
|
||||
int bytes = memory_address_to_byte(space, result & DASMFLAG_LENGTHMASK);
|
||||
assert(bytes >= cpu_get_min_opcode_bytes(device));
|
||||
assert(bytes <= cpu_get_max_opcode_bytes(device));
|
||||
(void) bytes; /* appease compiler */
|
||||
|
@ -554,6 +554,7 @@ typedef enum _cpu_type cpu_type;
|
||||
#define cputype_get_databus_width(cputype, space) cputype_get_info_int(cputype, CPUINFO_INT_DATABUS_WIDTH + (space))
|
||||
#define cputype_get_addrbus_width(cputype, space) cputype_get_info_int(cputype, CPUINFO_INT_ADDRBUS_WIDTH + (space))
|
||||
#define cputype_get_addrbus_shift(cputype, space) cputype_get_info_int(cputype, CPUINFO_INT_ADDRBUS_SHIFT + (space))
|
||||
#define cputype_get_logaddr_width(cputype, space) cputype_get_info_int(cputype, CPUINFO_INT_LOGADDR_WIDTH + (space))
|
||||
#define cputype_get_page_shift(cputype, space) cputype_get_info_int(cputype, CPUINFO_INT_PAGE_SHIFT + (space))
|
||||
#define cputype_get_debug_register_list(cputype) cputype_get_info_ptr(cputype, CPUINFO_PTR_DEBUG_REGISTER_LIST)
|
||||
#define cputype_get_name(cputype) cputype_get_info_string(cputype, CPUINFO_STR_NAME)
|
||||
@ -798,74 +799,4 @@ INLINE const address_space *cpu_get_address_space(const device_config *cpu, int
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
cpu_address_to_byte - convert an address in
|
||||
the specified address space to a byte offset
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t cpu_address_to_byte(const device_config *cpu, int space, offs_t address)
|
||||
{
|
||||
cpu_class_header *classheader = cpu->classtoken;
|
||||
int shift = classheader->address_shift[space];
|
||||
return (shift < 0) ? (address << -shift) : (address >> shift);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
cpu_address_to_byte_end - convert an address
|
||||
in the specified address space to a byte
|
||||
offset specifying the last byte covered by
|
||||
the address
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t cpu_address_to_byte_end(const device_config *cpu, int space, offs_t address)
|
||||
{
|
||||
cpu_class_header *classheader = cpu->classtoken;
|
||||
int shift = classheader->address_shift[space];
|
||||
return (shift < 0) ? ((address << -shift) | ((1 << -shift) - 1)) : (address >> shift);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
cpu_byte_to_address - convert a byte offset
|
||||
to an address in the specified address space
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t cpu_byte_to_address(const device_config *cpu, int space, offs_t address)
|
||||
{
|
||||
cpu_class_header *classheader = cpu->classtoken;
|
||||
int shift = classheader->address_shift[space];
|
||||
return (shift < 0) ? (address >> -shift) : (address << shift);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
cpu_byte_to_address_end - convert a byte offset
|
||||
to an address in the specified address space
|
||||
specifying the last address covered by the
|
||||
byte
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t cpu_byte_to_address_end(const device_config *cpu, int space, offs_t address)
|
||||
{
|
||||
cpu_class_header *classheader = cpu->classtoken;
|
||||
int shift = classheader->address_shift[space];
|
||||
return (shift < 0) ? (address >> -shift) : ((address << shift) | ((1 << shift) - 1));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
cpu_address_physical - return the physical
|
||||
address corresponding to the given logical
|
||||
address
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t cpu_address_physical(const device_config *cpu, int space, int intention, offs_t address)
|
||||
{
|
||||
cpu_class_header *classheader = cpu->classtoken;
|
||||
if (classheader->translate != NULL)
|
||||
(*classheader->translate)(cpu, space, intention, &address);
|
||||
return address;
|
||||
}
|
||||
|
||||
#endif /* __CPUINTRF_H__ */
|
||||
|
@ -114,9 +114,7 @@ static void execute_hardreset(running_machine *machine, int ref, int params, con
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Initialization
|
||||
|
||||
INITIALIZATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -282,9 +280,7 @@ static void debug_command_exit(running_machine *machine)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Simple Global Functions
|
||||
|
||||
GLOBAL FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -319,9 +315,7 @@ static UINT64 execute_if(void *globalref, void *ref, UINT32 params, const UINT64
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Global accessors
|
||||
|
||||
GLOBAL ACCESSORS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -361,9 +355,7 @@ static void global_set(void *globalref, void *ref, UINT64 value)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Parameter Validation Helpers
|
||||
|
||||
PARAMETER VALIDATION HELPERS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -373,25 +365,46 @@ static void global_set(void *globalref, void *ref, UINT64 value)
|
||||
|
||||
int debug_command_parameter_number(running_machine *machine, const char *param, UINT64 *result)
|
||||
{
|
||||
EXPRERR err = expression_evaluate(param, debug_cpu_get_visible_symtable(machine), &debug_expression_callbacks, machine, result);
|
||||
EXPRERR err;
|
||||
|
||||
/* NULL parameter does nothing and returns no error */
|
||||
if (param == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* evaluate the expression; success if no error */
|
||||
err = expression_evaluate(param, debug_cpu_get_visible_symtable(machine), &debug_expression_callbacks, machine, result);
|
||||
if (err == EXPRERR_NONE)
|
||||
return 1;
|
||||
return TRUE;
|
||||
|
||||
/* print an error pointing to the character that caused it */
|
||||
debug_console_printf("Error in expression: %s\n", param);
|
||||
debug_console_printf(" %*s^", EXPRERR_ERROR_OFFSET(err), "");
|
||||
debug_console_printf("%s\n", exprerr_to_string(err));
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
debug_command_parameter_cpu - validates a
|
||||
number parameter as a cpu
|
||||
parameter as a cpu
|
||||
-------------------------------------------------*/
|
||||
|
||||
int debug_command_parameter_cpu(running_machine *machine, const char *param, const device_config **result)
|
||||
{
|
||||
UINT64 cpunum;
|
||||
EXPRERR err;
|
||||
|
||||
/* if no parameter, use the visible CPU */
|
||||
if (param == NULL)
|
||||
{
|
||||
*result = debug_cpu_get_visible_cpu(machine);
|
||||
if (*result == NULL)
|
||||
{
|
||||
debug_console_printf("No valid CPU is currently selected\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* first look for a tag match */
|
||||
*result = cputag_get_cpu(machine, param);
|
||||
@ -409,15 +422,39 @@ int debug_command_parameter_cpu(running_machine *machine, const char *param, con
|
||||
/* if out of range, complain */
|
||||
if (cpunum >= ARRAY_LENGTH(machine->cpu) || machine->cpu[cpunum] == NULL)
|
||||
{
|
||||
debug_console_printf("Invalid CPU index %d\n", (UINT32) ((FPTR)*result));
|
||||
debug_console_printf("Invalid CPU index %d\n", (UINT32)cpunum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*result = machine->cpu[cpunum];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
debug_command_parameter_cpu_space - validates
|
||||
a parameter as a cpu and retrieves the given
|
||||
address space
|
||||
-------------------------------------------------*/
|
||||
|
||||
int debug_command_parameter_cpu_space(running_machine *machine, const char *param, int spacenum, const address_space **result)
|
||||
{
|
||||
const device_config *cpu;
|
||||
|
||||
/* first do the standard CPU thing */
|
||||
if (!debug_command_parameter_cpu(machine, param, &cpu))
|
||||
return FALSE;
|
||||
|
||||
/* fetch the space pointer */
|
||||
*result = cpu_get_address_space(cpu, spacenum);
|
||||
if (*result == NULL)
|
||||
{
|
||||
debug_console_printf("No %s memory space found for CPU '%s'\n", address_space_names[spacenum], cpu->tag);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
debug_command_parameter_expression - validates
|
||||
an expression parameter
|
||||
@ -425,13 +462,25 @@ int debug_command_parameter_cpu(running_machine *machine, const char *param, con
|
||||
|
||||
static int debug_command_parameter_expression(running_machine *machine, const char *param, parsed_expression **result)
|
||||
{
|
||||
EXPRERR err = expression_parse(param, debug_cpu_get_visible_symtable(machine), &debug_expression_callbacks, machine, result);
|
||||
EXPRERR err;
|
||||
|
||||
/* NULL parameter does nothing and returns no error */
|
||||
if (param == NULL)
|
||||
{
|
||||
*result = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* parse the expression; success if no error */
|
||||
err = expression_parse(param, debug_cpu_get_visible_symtable(machine), &debug_expression_callbacks, machine, result);
|
||||
if (err == EXPRERR_NONE)
|
||||
return 1;
|
||||
return TRUE;
|
||||
|
||||
/* output an error */
|
||||
debug_console_printf("Error in expression: %s\n", param);
|
||||
debug_console_printf(" %*s^", EXPRERR_ERROR_OFFSET(err), "");
|
||||
debug_console_printf("%s\n", exprerr_to_string(err));
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@ -442,9 +491,18 @@ static int debug_command_parameter_expression(running_machine *machine, const ch
|
||||
|
||||
static int debug_command_parameter_command(running_machine *machine, const char *param)
|
||||
{
|
||||
CMDERR err = debug_console_validate_command(machine, param);
|
||||
CMDERR err;
|
||||
|
||||
/* NULL parameter does nothing and returns no error */
|
||||
if (param == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* validate the comment; success if no error */
|
||||
err = debug_console_validate_command(machine, param);
|
||||
if (err == CMDERR_NONE)
|
||||
return 1;
|
||||
return TRUE;
|
||||
|
||||
/* output an error */
|
||||
debug_console_printf("Error in command: %s\n", param);
|
||||
debug_console_printf(" %*s^", CMDERR_ERROR_OFFSET(err), "");
|
||||
debug_console_printf("%s\n", debug_cmderr_to_string(err));
|
||||
@ -454,9 +512,7 @@ static int debug_command_parameter_command(running_machine *machine, const char
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Command Helpers
|
||||
|
||||
COMMAND HELPERS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -691,7 +747,7 @@ static void execute_step(running_machine *machine, int ref, int params, const ch
|
||||
UINT64 steps = 1;
|
||||
|
||||
/* if we have a parameter, use it instead */
|
||||
if (params > 0 && !debug_command_parameter_number(machine, param[0], &steps))
|
||||
if (!debug_command_parameter_number(machine, param[0], &steps))
|
||||
return;
|
||||
|
||||
debug_cpu_single_step(machine, steps);
|
||||
@ -707,7 +763,7 @@ static void execute_over(running_machine *machine, int ref, int params, const ch
|
||||
UINT64 steps = 1;
|
||||
|
||||
/* if we have a parameter, use it instead */
|
||||
if (params > 0 && !debug_command_parameter_number(machine, param[0], &steps))
|
||||
if (!debug_command_parameter_number(machine, param[0], &steps))
|
||||
return;
|
||||
|
||||
debug_cpu_single_step_over(machine, steps);
|
||||
@ -733,7 +789,7 @@ static void execute_go(running_machine *machine, int ref, int params, const char
|
||||
UINT64 addr = ~0;
|
||||
|
||||
/* if we have a parameter, use it instead */
|
||||
if (params > 0 && !debug_command_parameter_number(machine, param[0], &addr))
|
||||
if (!debug_command_parameter_number(machine, param[0], &addr))
|
||||
return;
|
||||
|
||||
debug_cpu_go(machine, addr);
|
||||
@ -760,7 +816,7 @@ static void execute_go_interrupt(running_machine *machine, int ref, int params,
|
||||
UINT64 irqline = -1;
|
||||
|
||||
/* if we have a parameter, use it instead */
|
||||
if (params > 0 && !debug_command_parameter_number(machine, param[0], &irqline))
|
||||
if (!debug_command_parameter_number(machine, param[0], &irqline))
|
||||
return;
|
||||
|
||||
debug_cpu_go_interrupt(machine, irqline);
|
||||
@ -776,7 +832,7 @@ static void execute_go_time(running_machine *machine, int ref, int params, const
|
||||
UINT64 milliseconds = -1;
|
||||
|
||||
/* if we have a parameter, use it instead */
|
||||
if (params > 0 && !debug_command_parameter_number(machine, param[0], &milliseconds))
|
||||
if (!debug_command_parameter_number(machine, param[0], &milliseconds))
|
||||
return;
|
||||
|
||||
debug_cpu_go_milliseconds(machine, milliseconds);
|
||||
@ -835,15 +891,15 @@ static void execute_ignore(running_machine *machine, int ref, int params, const
|
||||
for (cpunum = 0; cpunum < ARRAY_LENGTH(machine->cpu); cpunum++)
|
||||
if (machine->cpu[cpunum] != NULL)
|
||||
{
|
||||
const cpu_debug_data *info = cpu_get_debug_data(machine->cpu[cpunum]);
|
||||
const cpu_debug_data *cpuinfo = cpu_get_debug_data(machine->cpu[cpunum]);
|
||||
|
||||
/* build up a comma-separated list */
|
||||
if ((info->flags & DEBUG_FLAG_OBSERVING) == 0)
|
||||
if ((cpuinfo->flags & DEBUG_FLAG_OBSERVING) == 0)
|
||||
{
|
||||
if (buflen == 0)
|
||||
buflen += sprintf(&buffer[buflen], "Currently ignoring CPU %d", cpunum);
|
||||
buflen += sprintf(&buffer[buflen], "Currently ignoring CPU '%s'", machine->cpu[cpunum]->tag);
|
||||
else
|
||||
buflen += sprintf(&buffer[buflen], ",%d", cpunum);
|
||||
buflen += sprintf(&buffer[buflen], ", '%s'", machine->cpu[cpunum]->tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -900,15 +956,15 @@ static void execute_observe(running_machine *machine, int ref, int params, const
|
||||
for (cpunum = 0; cpunum < ARRAY_LENGTH(machine->cpu); cpunum++)
|
||||
if (machine->cpu[cpunum] != NULL)
|
||||
{
|
||||
const cpu_debug_data *info = cpu_get_debug_data(machine->cpu[cpunum]);
|
||||
const cpu_debug_data *cpuinfo = cpu_get_debug_data(machine->cpu[cpunum]);
|
||||
|
||||
/* build up a comma-separated list */
|
||||
if ((info->flags & DEBUG_FLAG_OBSERVING) != 0)
|
||||
if ((cpuinfo->flags & DEBUG_FLAG_OBSERVING) != 0)
|
||||
{
|
||||
if (buflen == 0)
|
||||
buflen += sprintf(&buffer[buflen], "Currently observing CPU %d", cpunum);
|
||||
buflen += sprintf(&buffer[buflen], "Currently observing CPU '%s'", machine->cpu[cpunum]->tag);
|
||||
else
|
||||
buflen += sprintf(&buffer[buflen], ",%d", cpunum);
|
||||
buflen += sprintf(&buffer[buflen], ", '%s'", machine->cpu[cpunum]->tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -942,13 +998,17 @@ static void execute_observe(running_machine *machine, int ref, int params, const
|
||||
|
||||
static void execute_comment(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const device_config *cpu;
|
||||
UINT64 address;
|
||||
|
||||
/* param 1 is the address for the comment */
|
||||
if (!debug_command_parameter_number(machine, param[0], &address))
|
||||
return;
|
||||
|
||||
/* CPU parameter is implicit */
|
||||
if (!debug_command_parameter_cpu(machine, NULL, &cpu))
|
||||
return;
|
||||
|
||||
/* make sure param 2 exists */
|
||||
if (strlen(param[1]) == 0)
|
||||
{
|
||||
@ -968,12 +1028,16 @@ static void execute_comment(running_machine *machine, int ref, int params, const
|
||||
|
||||
static void execute_comment_del(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const device_config *cpu;
|
||||
UINT64 address;
|
||||
|
||||
/* param 1 can either be a command or the address for the comment */
|
||||
if (!debug_command_parameter_number(machine, param[0], &address))
|
||||
return;
|
||||
|
||||
/* CPU parameter is implicit */
|
||||
if (!debug_command_parameter_cpu(machine, NULL, &cpu))
|
||||
return;
|
||||
|
||||
/* If it's a number, it must be an address */
|
||||
/* The bankoff and cbn will be pulled from what's currently active */
|
||||
@ -1001,6 +1065,7 @@ static void execute_comment_save(running_machine *machine, int ref, int params,
|
||||
static void execute_bpset(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
parsed_expression *condition = NULL;
|
||||
const device_config *cpu;
|
||||
const char *action = NULL;
|
||||
UINT64 address;
|
||||
int bpnum;
|
||||
@ -1010,15 +1075,19 @@ static void execute_bpset(running_machine *machine, int ref, int params, const c
|
||||
return;
|
||||
|
||||
/* param 2 is the condition */
|
||||
if (params > 1 && !debug_command_parameter_expression(machine, param[1], &condition))
|
||||
if (!debug_command_parameter_expression(machine, param[1], &condition))
|
||||
return;
|
||||
|
||||
/* param 3 is the action */
|
||||
if (params > 2 && !debug_command_parameter_command(machine, action = param[2]))
|
||||
if (!debug_command_parameter_command(machine, action = param[2]))
|
||||
return;
|
||||
|
||||
/* CPU is implicit */
|
||||
if (!debug_command_parameter_cpu(machine, NULL, &cpu))
|
||||
return;
|
||||
|
||||
/* set the breakpoint */
|
||||
bpnum = debug_cpu_breakpoint_set(debug_cpu_get_visible_cpu(machine), address, condition, action);
|
||||
bpnum = debug_cpu_breakpoint_set(cpu, address, condition, action);
|
||||
debug_console_printf("Breakpoint %X set\n", bpnum);
|
||||
}
|
||||
|
||||
@ -1154,6 +1223,7 @@ static void execute_bplist(running_machine *machine, int ref, int params, const
|
||||
static void execute_wpset(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
parsed_expression *condition = NULL;
|
||||
const address_space *space;
|
||||
const char *action = NULL;
|
||||
UINT64 address, length;
|
||||
int type = 0;
|
||||
@ -1181,15 +1251,19 @@ static void execute_wpset(running_machine *machine, int ref, int params, const c
|
||||
}
|
||||
|
||||
/* param 4 is the condition */
|
||||
if (params > 3 && !debug_command_parameter_expression(machine, param[3], &condition))
|
||||
if (!debug_command_parameter_expression(machine, param[3], &condition))
|
||||
return;
|
||||
|
||||
/* param 5 is the action */
|
||||
if (params > 4 && !debug_command_parameter_command(machine, action = param[4]))
|
||||
if (!debug_command_parameter_command(machine, action = param[4]))
|
||||
return;
|
||||
|
||||
/* CPU is implicit */
|
||||
if (!debug_command_parameter_cpu_space(machine, NULL, ref, &space))
|
||||
return;
|
||||
|
||||
/* set the watchpoint */
|
||||
wpnum = debug_cpu_watchpoint_set(cpu_get_address_space(debug_cpu_get_visible_cpu(machine), ref), type, address, length, condition, action);
|
||||
wpnum = debug_cpu_watchpoint_set(space, type, address, length, condition, action);
|
||||
debug_console_printf("Watchpoint %X set\n", wpnum);
|
||||
}
|
||||
|
||||
@ -1217,7 +1291,7 @@ static void execute_wpclear(running_machine *machine, int ref, int params, const
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
{
|
||||
debug_cpu_watchpoint *wp;
|
||||
while ((wp = cpuinfo->space[spacenum].wplist) != NULL)
|
||||
while ((wp = cpuinfo->wplist[spacenum]) != NULL)
|
||||
debug_cpu_watchpoint_clear(machine, wp->index);
|
||||
}
|
||||
}
|
||||
@ -1261,7 +1335,7 @@ static void execute_wpdisenable(running_machine *machine, int ref, int params, c
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
{
|
||||
debug_cpu_watchpoint *wp;
|
||||
for (wp = cpuinfo->space[spacenum].wplist; wp != NULL; wp = wp->next)
|
||||
for (wp = cpuinfo->wplist[spacenum]; wp != NULL; wp = wp->next)
|
||||
debug_cpu_watchpoint_enable(machine, wp->index, ref);
|
||||
}
|
||||
}
|
||||
@ -1303,20 +1377,20 @@ static void execute_wplist(running_machine *machine, int ref, int params, const
|
||||
int spacenum;
|
||||
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
{
|
||||
if (cpuinfo->space[spacenum].wplist != NULL)
|
||||
if (cpuinfo->wplist[spacenum] != NULL)
|
||||
{
|
||||
static const char *const types[] = { "unkn ", "read ", "write", "r/w " };
|
||||
const address_space *space = cpu_get_address_space(machine->cpu[cpunum], spacenum);
|
||||
debug_cpu_watchpoint *wp;
|
||||
|
||||
debug_console_printf("CPU %d %s space watchpoints:\n", cpunum, address_space_names[spacenum]);
|
||||
debug_console_printf("CPU '%s' %s space watchpoints:\n", space->cpu->tag, address_space_names[spacenum]);
|
||||
|
||||
/* loop over the watchpoints */
|
||||
for (wp = cpuinfo->space[spacenum].wplist; wp != NULL; wp = wp->next)
|
||||
for (wp = cpuinfo->wplist[spacenum]; wp != NULL; wp = wp->next)
|
||||
{
|
||||
int buflen;
|
||||
buflen = sprintf(buffer, "%c%4X @ %08X-%08X %s", wp->enabled ? ' ' : 'D',
|
||||
wp->index, BYTE2ADDR(wp->address, cpuinfo, spacenum), BYTE2ADDR(wp->address + wp->length, cpuinfo, spacenum) - 1, types[wp->type & 3]);
|
||||
wp->index, memory_byte_to_address(space, wp->address), memory_byte_to_address_end(space, wp->address + wp->length) - 1, types[wp->type & 3]);
|
||||
if (wp->condition)
|
||||
buflen += sprintf(&buffer[buflen], " if %s", expression_original_string(wp->condition));
|
||||
if (wp->action)
|
||||
@ -1325,7 +1399,6 @@ static void execute_wplist(running_machine *machine, int ref, int params, const
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!printed)
|
||||
@ -1340,7 +1413,7 @@ static void execute_wplist(running_machine *machine, int ref, int params, const
|
||||
|
||||
static void execute_hotspot(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const device_config *cpu;
|
||||
UINT64 threshhold;
|
||||
UINT64 count;
|
||||
|
||||
@ -1359,7 +1432,7 @@ static void execute_hotspot(running_machine *machine, int ref, int params, const
|
||||
if (cpuinfo->hotspots != NULL)
|
||||
{
|
||||
debug_cpu_hotspot_track(cpuinfo->device, 0, 0);
|
||||
debug_console_printf("Cleared hotspot tracking on CPU %d\n", (int)cpunum);
|
||||
debug_console_printf("Cleared hotspot tracking on CPU '%s'\n", machine->cpu[cpunum]->tag);
|
||||
cleared = TRUE;
|
||||
}
|
||||
}
|
||||
@ -1372,11 +1445,11 @@ static void execute_hotspot(running_machine *machine, int ref, int params, const
|
||||
/* extract parameters */
|
||||
count = 64;
|
||||
threshhold = 250;
|
||||
if (params > 0 && !debug_command_parameter_cpu(machine, param[0], &cpu))
|
||||
if (!debug_command_parameter_cpu(machine, (params > 0) ? param[0] : NULL, &cpu))
|
||||
return;
|
||||
if (params > 1 && !debug_command_parameter_number(machine, param[1], &count))
|
||||
if (!debug_command_parameter_number(machine, param[1], &count))
|
||||
return;
|
||||
if (params > 2 && !debug_command_parameter_number(machine, param[2], &threshhold))
|
||||
if (!debug_command_parameter_number(machine, param[2], &threshhold))
|
||||
return;
|
||||
|
||||
/* attempt to install */
|
||||
@ -1393,31 +1466,22 @@ static void execute_hotspot(running_machine *machine, int ref, int params, const
|
||||
|
||||
static void execute_save(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const address_space *space = cpu_get_address_space(cpu, ref);
|
||||
UINT64 offset, endoffset, length;
|
||||
const cpu_debug_data *info;
|
||||
int spacenum = ref;
|
||||
const address_space *space;
|
||||
FILE *f;
|
||||
UINT64 i;
|
||||
|
||||
/* validate parameters */
|
||||
if (space == NULL)
|
||||
{
|
||||
debug_console_printf("Invalid or non-existant address space %s on CPU '%s'\n", address_space_names[ref], cpu->tag);
|
||||
return;
|
||||
}
|
||||
if (!debug_command_parameter_number(machine, param[1], &offset))
|
||||
return;
|
||||
if (!debug_command_parameter_number(machine, param[2], &length))
|
||||
return;
|
||||
if (params > 3 && !debug_command_parameter_cpu(machine, param[3], &cpu))
|
||||
if (!debug_command_parameter_cpu_space(machine, (params > 3) ? param[3] : NULL, ref, &space))
|
||||
return;
|
||||
|
||||
/* determine the addresses to write */
|
||||
info = cpu_get_debug_data(cpu);
|
||||
endoffset = ADDR2BYTE_MASKED(offset + length - 1, info, spacenum);
|
||||
offset = ADDR2BYTE_MASKED(offset, info, spacenum);
|
||||
endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;
|
||||
offset = memory_address_to_byte(space, offset) & space->bytemask;
|
||||
|
||||
/* open the file */
|
||||
f = fopen(param[0], "wb");
|
||||
@ -1428,7 +1492,7 @@ static void execute_save(running_machine *machine, int ref, int params, const ch
|
||||
}
|
||||
|
||||
/* now write the data out */
|
||||
cpu_push_context(cpu);
|
||||
cpu_push_context(space->cpu);
|
||||
for (i = offset; i <= endoffset; i++)
|
||||
{
|
||||
UINT8 byte = debug_read_byte(space, i, TRUE);
|
||||
@ -1448,44 +1512,35 @@ static void execute_save(running_machine *machine, int ref, int params, const ch
|
||||
|
||||
static void execute_dump(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const address_space *space = cpu_get_address_space(cpu, ref);
|
||||
UINT64 offset, endoffset, length, width = 0, ascii = 1;
|
||||
const cpu_debug_data *info;
|
||||
int spacenum = ref;
|
||||
const address_space *space;
|
||||
FILE *f = NULL;
|
||||
UINT64 i, j;
|
||||
|
||||
/* validate parameters */
|
||||
if (space == NULL)
|
||||
{
|
||||
debug_console_printf("Invalid or non-existant address space %s on CPU '%s'\n", address_space_names[ref], cpu->tag);
|
||||
return;
|
||||
}
|
||||
if (!debug_command_parameter_number(machine, param[1], &offset))
|
||||
return;
|
||||
if (!debug_command_parameter_number(machine, param[2], &length))
|
||||
return;
|
||||
if (params > 3 && !debug_command_parameter_number(machine, param[3], &width))
|
||||
if (!debug_command_parameter_number(machine, param[3], &width))
|
||||
return;
|
||||
if (params > 4 && !debug_command_parameter_number(machine, param[4], &ascii))
|
||||
if (!debug_command_parameter_number(machine, param[4], &ascii))
|
||||
return;
|
||||
if (params > 5 && !debug_command_parameter_cpu(machine, param[5], &cpu))
|
||||
if (!debug_command_parameter_cpu_space(machine, (params > 5) ? param[5] : NULL, ref, &space))
|
||||
return;
|
||||
|
||||
/* further validation */
|
||||
info = cpu_get_debug_data(cpu);
|
||||
if (width == 0)
|
||||
width = info->space[spacenum].databytes;
|
||||
if (width < ADDR2BYTE(1, info, spacenum))
|
||||
width = ADDR2BYTE(1, info, spacenum);
|
||||
width = space->dbits / 8;
|
||||
if (width < memory_address_to_byte(space, 1))
|
||||
width = memory_address_to_byte(space, 1);
|
||||
if (width != 1 && width != 2 && width != 4 && width != 8)
|
||||
{
|
||||
debug_console_printf("Invalid width! (must be 1,2,4 or 8)\n");
|
||||
return;
|
||||
}
|
||||
endoffset = ADDR2BYTE_MASKED(offset + length - 1, info, spacenum);
|
||||
offset = ADDR2BYTE_MASKED(offset, info, spacenum);
|
||||
endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;
|
||||
offset = memory_address_to_byte(space, offset) & space->bytemask;
|
||||
|
||||
/* open the file */
|
||||
f = fopen(param[0], "w");
|
||||
@ -1496,14 +1551,14 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
}
|
||||
|
||||
/* now write the data out */
|
||||
cpu_push_context(cpu);
|
||||
cpu_push_context(space->cpu);
|
||||
for (i = offset; i <= endoffset; i += 16)
|
||||
{
|
||||
char output[200];
|
||||
int outdex = 0;
|
||||
|
||||
/* print the address */
|
||||
outdex += sprintf(&output[outdex], "%0*X: ", info->space[spacenum].logchars, (UINT32)BYTE2ADDR(i, info, spacenum));
|
||||
outdex += sprintf(&output[outdex], "%0*X: ", space->logaddrchars, (UINT32)memory_byte_to_address(space, i));
|
||||
|
||||
/* print the bytes */
|
||||
switch (width)
|
||||
@ -1514,7 +1569,7 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
if (i + j <= endoffset)
|
||||
{
|
||||
offs_t curaddr = i + j;
|
||||
if (info->translate == NULL || (*info->translate)(cpu, spacenum, TRANSLATE_READ, &curaddr))
|
||||
if (memory_address_physical(space, TRANSLATE_READ, &curaddr))
|
||||
{
|
||||
UINT8 byte = debug_read_byte(space, i + j, TRUE);
|
||||
outdex += sprintf(&output[outdex], " %02X", byte);
|
||||
@ -1533,7 +1588,7 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
if (i + j <= endoffset)
|
||||
{
|
||||
offs_t curaddr = i + j;
|
||||
if (info->translate == NULL || (*info->translate)(cpu, spacenum, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
if (memory_address_physical(space, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
{
|
||||
UINT16 word = debug_read_word(space, i + j, TRUE);
|
||||
outdex += sprintf(&output[outdex], " %04X", word);
|
||||
@ -1552,7 +1607,7 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
if (i + j <= endoffset)
|
||||
{
|
||||
offs_t curaddr = i + j;
|
||||
if (info->translate == NULL || (*info->translate)(cpu, spacenum, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
if (memory_address_physical(space, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
{
|
||||
UINT32 dword = debug_read_dword(space, i + j, TRUE);
|
||||
outdex += sprintf(&output[outdex], " %08X", dword);
|
||||
@ -1571,7 +1626,7 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
if (i + j <= endoffset)
|
||||
{
|
||||
offs_t curaddr = i + j;
|
||||
if (info->translate == NULL || (*info->translate)(cpu, spacenum, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
if (memory_address_physical(space, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
{
|
||||
UINT64 qword = debug_read_qword(space, i + j, TRUE);
|
||||
outdex += sprintf(&output[outdex], " %08X%08X", (UINT32)(qword >> 32), (UINT32)qword);
|
||||
@ -1592,7 +1647,7 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
for (j = 0; j < 16 && (i + j) <= endoffset; j++)
|
||||
{
|
||||
offs_t curaddr = i + j;
|
||||
if (info->translate == NULL || (*info->translate)(cpu, spacenum, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
if (memory_address_physical(space, TRANSLATE_READ_DEBUG, &curaddr))
|
||||
{
|
||||
UINT8 byte = debug_read_byte(space, i + j, TRUE);
|
||||
outdex += sprintf(&output[outdex], "%c", (byte >= 32 && byte < 128) ? byte : '.');
|
||||
@ -1619,34 +1674,27 @@ static void execute_dump(running_machine *machine, int ref, int params, const ch
|
||||
|
||||
static void execute_find(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const address_space *space = cpu_get_address_space(cpu, ref);
|
||||
UINT64 offset, endoffset, length;
|
||||
const cpu_debug_data *info;
|
||||
const address_space *space;
|
||||
UINT64 data_to_find[256];
|
||||
UINT8 data_size[256];
|
||||
int cur_data_size;
|
||||
int data_count = 0;
|
||||
int spacenum = ref;
|
||||
int found = 0;
|
||||
UINT64 i, j;
|
||||
|
||||
/* validate parameters */
|
||||
if (space == NULL)
|
||||
{
|
||||
debug_console_printf("Invalid or non-existant address space %s on CPU '%s'\n", address_space_names[ref], cpu->tag);
|
||||
return;
|
||||
}
|
||||
if (!debug_command_parameter_number(machine, param[0], &offset))
|
||||
return;
|
||||
if (!debug_command_parameter_number(machine, param[1], &length))
|
||||
return;
|
||||
if (!debug_command_parameter_cpu_space(machine, NULL, ref, &space))
|
||||
return;
|
||||
|
||||
/* further validation */
|
||||
info = cpu_get_debug_data(cpu);
|
||||
endoffset = ADDR2BYTE_MASKED(offset + length - 1, info, spacenum);
|
||||
offset = ADDR2BYTE_MASKED(offset, info, spacenum);
|
||||
cur_data_size = ADDR2BYTE(1, info, spacenum);
|
||||
endoffset = memory_address_to_byte(space, offset + length - 1) & space->bytemask;
|
||||
offset = memory_address_to_byte(space, offset) & space->bytemask;
|
||||
cur_data_size = memory_address_to_byte(space, 1);
|
||||
if (cur_data_size == 0)
|
||||
cur_data_size = 1;
|
||||
|
||||
@ -1686,7 +1734,7 @@ static void execute_find(running_machine *machine, int ref, int params, const ch
|
||||
}
|
||||
|
||||
/* now search */
|
||||
cpu_push_context(cpu);
|
||||
cpu_push_context(space->cpu);
|
||||
for (i = offset; i <= endoffset; i += data_size[0])
|
||||
{
|
||||
int suboffset = 0;
|
||||
@ -1710,7 +1758,7 @@ static void execute_find(running_machine *machine, int ref, int params, const ch
|
||||
if (match)
|
||||
{
|
||||
found++;
|
||||
debug_console_printf("Found at %*X\n", info->space[spacenum].logchars, (UINT32)BYTE2ADDR(i, info, spacenum));
|
||||
debug_console_printf("Found at %*X\n", space->logaddrchars, (UINT32)memory_byte_to_address(space, i));
|
||||
}
|
||||
}
|
||||
cpu_pop_context();
|
||||
@ -1727,11 +1775,9 @@ static void execute_find(running_machine *machine, int ref, int params, const ch
|
||||
|
||||
static void execute_dasm(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const address_space *space = cpu_get_address_space(cpu, ADDRESS_SPACE_PROGRAM);
|
||||
UINT64 offset, length, bytes = 1;
|
||||
const cpu_debug_data *info;
|
||||
int minbytes, maxbytes, byteswidth;
|
||||
const address_space *space;
|
||||
FILE *f = NULL;
|
||||
int i, j;
|
||||
|
||||
@ -1740,17 +1786,14 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
|
||||
return;
|
||||
if (!debug_command_parameter_number(machine, param[2], &length))
|
||||
return;
|
||||
if (params > 3 && !debug_command_parameter_number(machine, param[3], &bytes))
|
||||
if (!debug_command_parameter_number(machine, param[3], &bytes))
|
||||
return;
|
||||
if (params > 4 && !debug_command_parameter_cpu(machine, param[4], &cpu))
|
||||
if (!debug_command_parameter_cpu_space(machine, (params > 4) ? param[4] : NULL, ADDRESS_SPACE_PROGRAM, &space))
|
||||
return;
|
||||
|
||||
/* further validation */
|
||||
info = cpu_get_debug_data(cpu);
|
||||
|
||||
/* determine the width of the bytes */
|
||||
minbytes = cpu_get_min_opcode_bytes(cpu);
|
||||
maxbytes = cpu_get_max_opcode_bytes(cpu);
|
||||
minbytes = cpu_get_min_opcode_bytes(space->cpu);
|
||||
maxbytes = cpu_get_max_opcode_bytes(space->cpu);
|
||||
byteswidth = 0;
|
||||
if (bytes)
|
||||
{
|
||||
@ -1767,10 +1810,10 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
|
||||
}
|
||||
|
||||
/* now write the data out */
|
||||
cpu_push_context(cpu);
|
||||
cpu_push_context(space->cpu);
|
||||
for (i = 0; i < length; )
|
||||
{
|
||||
int pcbyte = ADDR2BYTE_MASKED(offset + i, info, ADDRESS_SPACE_PROGRAM);
|
||||
int pcbyte = memory_address_to_byte(space, offset + i) & space->bytemask;
|
||||
char output[200+DEBUG_COMMENT_MAX_LINE_LENGTH], disasm[200];
|
||||
const char *comment;
|
||||
offs_t tempaddr;
|
||||
@ -1778,11 +1821,11 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
|
||||
int numbytes = 0;
|
||||
|
||||
/* print the address */
|
||||
outdex += sprintf(&output[outdex], "%0*X: ", info->space[ADDRESS_SPACE_PROGRAM].logchars, (UINT32)BYTE2ADDR(pcbyte, info, ADDRESS_SPACE_PROGRAM));
|
||||
outdex += sprintf(&output[outdex], "%0*X: ", space->logaddrchars, (UINT32)memory_byte_to_address(space, pcbyte));
|
||||
|
||||
/* make sure we can translate the address */
|
||||
tempaddr = pcbyte;
|
||||
if (info->translate == NULL || (*info->translate)(info->device, ADDRESS_SPACE_PROGRAM, TRANSLATE_FETCH_DEBUG, &tempaddr))
|
||||
if (memory_address_physical(space, TRANSLATE_FETCH_DEBUG, &tempaddr))
|
||||
{
|
||||
UINT8 opbuf[64], argbuf[64];
|
||||
|
||||
@ -1794,14 +1837,14 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
|
||||
}
|
||||
|
||||
/* disassemble the result */
|
||||
i += numbytes = cpu_dasm(cpu, disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
|
||||
i += numbytes = cpu_dasm(space->cpu, disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
|
||||
}
|
||||
|
||||
/* print the bytes */
|
||||
if (bytes)
|
||||
{
|
||||
int startdex = outdex;
|
||||
numbytes = ADDR2BYTE(numbytes, info, ADDRESS_SPACE_PROGRAM);
|
||||
numbytes = memory_address_to_byte(space, numbytes);
|
||||
switch (minbytes)
|
||||
{
|
||||
case 1:
|
||||
@ -1836,7 +1879,7 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
|
||||
sprintf(&output[outdex], "%s", disasm);
|
||||
|
||||
/* attempt to add the comment */
|
||||
comment = debug_comment_get_text(cpu, tempaddr, debug_comment_get_opcode_crc32(cpu, tempaddr));
|
||||
comment = debug_comment_get_text(space->cpu, tempaddr, debug_comment_get_opcode_crc32(space->cpu, tempaddr));
|
||||
if (comment != NULL)
|
||||
{
|
||||
/* somewhat arbitrary guess as to how long most disassembly lines will be [column 60] */
|
||||
@ -1871,15 +1914,15 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
|
||||
|
||||
static void execute_trace_internal(running_machine *machine, int ref, int params, const char *param[], int trace_over)
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const char *action = NULL, *filename = param[0];
|
||||
const device_config *cpu;
|
||||
FILE *f = NULL;
|
||||
const char *mode;
|
||||
|
||||
/* validate parameters */
|
||||
if (params > 1 && !debug_command_parameter_cpu(machine, param[1], &cpu))
|
||||
if (!debug_command_parameter_cpu(machine, (params > 1) ? param[1] : NULL, &cpu))
|
||||
return;
|
||||
if (params > 2 && !debug_command_parameter_command(machine, action = param[2]))
|
||||
if (!debug_command_parameter_command(machine, action = param[2]))
|
||||
return;
|
||||
|
||||
/* further validation */
|
||||
@ -1951,53 +1994,52 @@ static void execute_traceflush(running_machine *machine, int ref, int params, co
|
||||
|
||||
static void execute_history(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const address_space *space = cpu_get_address_space(cpu, ADDRESS_SPACE_PROGRAM);
|
||||
UINT64 count = DEBUG_HISTORY_SIZE;
|
||||
const cpu_debug_data *info;
|
||||
const cpu_debug_data *cpuinfo;
|
||||
const address_space *space;
|
||||
int i;
|
||||
|
||||
/* validate parameters */
|
||||
if (params > 0 && !debug_command_parameter_cpu(machine, param[0], &cpu))
|
||||
if (!debug_command_parameter_cpu_space(machine, (params > 0) ? param[0] : NULL, ADDRESS_SPACE_PROGRAM, &space))
|
||||
return;
|
||||
if (params > 1 && !debug_command_parameter_number(machine, param[1], &count))
|
||||
if (!debug_command_parameter_number(machine, param[1], &count))
|
||||
return;
|
||||
|
||||
/* further validation */
|
||||
if (count > DEBUG_HISTORY_SIZE)
|
||||
count = DEBUG_HISTORY_SIZE;
|
||||
|
||||
info = cpu_get_debug_data(cpu);
|
||||
cpuinfo = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* loop over lines */
|
||||
cpu_push_context(cpu);
|
||||
cpu_push_context(space->cpu);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
offs_t pc = info->pc_history[(info->pc_history_index + DEBUG_HISTORY_SIZE - count + i) % DEBUG_HISTORY_SIZE];
|
||||
int maxbytes = cpu_get_max_opcode_bytes(cpu);
|
||||
offs_t pc = cpuinfo->pc_history[(cpuinfo->pc_history_index + DEBUG_HISTORY_SIZE - count + i) % DEBUG_HISTORY_SIZE];
|
||||
int maxbytes = cpu_get_max_opcode_bytes(space->cpu);
|
||||
UINT8 opbuf[64], argbuf[64];
|
||||
char buffer[200];
|
||||
offs_t pcbyte;
|
||||
int numbytes;
|
||||
|
||||
/* fetch the bytes up to the maximum */
|
||||
pcbyte = ADDR2BYTE_MASKED(pc, info, ADDRESS_SPACE_PROGRAM);
|
||||
pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
|
||||
for (numbytes = 0; numbytes < maxbytes; numbytes++)
|
||||
{
|
||||
opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, FALSE);
|
||||
argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, TRUE);
|
||||
}
|
||||
|
||||
cpu_dasm(cpu, buffer, pc, opbuf, argbuf);
|
||||
cpu_dasm(space->cpu, buffer, pc, opbuf, argbuf);
|
||||
|
||||
debug_console_printf("%0*X: %s\n", info->space[ADDRESS_SPACE_PROGRAM].logchars, pc, buffer);
|
||||
debug_console_printf("%0*X: %s\n", space->logaddrchars, pc, buffer);
|
||||
}
|
||||
cpu_pop_context();
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
execute_snap - execute the trace over command
|
||||
execute_snap - execute the snapshot command
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void execute_snap(running_machine *machine, int ref, int params, const char *param[])
|
||||
@ -2061,9 +2103,7 @@ static void execute_source(running_machine *machine, int ref, int params, const
|
||||
|
||||
static void execute_map(running_machine *machine, int ref, int params, const char *param[])
|
||||
{
|
||||
const device_config *cpu = debug_cpu_get_visible_cpu(machine);
|
||||
const cpu_debug_data *info;
|
||||
int spacenum = ref;
|
||||
const address_space *space;
|
||||
offs_t taddress;
|
||||
UINT64 address;
|
||||
int intention;
|
||||
@ -2071,28 +2111,23 @@ static void execute_map(running_machine *machine, int ref, int params, const cha
|
||||
/* validate parameters */
|
||||
if (!debug_command_parameter_number(machine, param[0], &address))
|
||||
return;
|
||||
info = cpu_get_debug_data(cpu);
|
||||
|
||||
/* CPU is implicit */
|
||||
if (!debug_command_parameter_cpu_space(machine, NULL, ref, &space))
|
||||
return;
|
||||
|
||||
/* do the translation first */
|
||||
for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++)
|
||||
{
|
||||
static const char *const intnames[] = { "Read", "Write", "Fetch" };
|
||||
taddress = ADDR2BYTE_MASKED(address, info, spacenum);
|
||||
if (info->translate != NULL)
|
||||
taddress = memory_address_to_byte(space, address) & space->bytemask;
|
||||
if (memory_address_physical(space, intention, &taddress))
|
||||
{
|
||||
if ((*info->translate)(info->device, spacenum, intention, &taddress))
|
||||
{
|
||||
const char *mapname = memory_get_handler_string(cpu_get_address_space(cpu, spacenum), intention == TRANSLATE_WRITE_DEBUG, taddress);
|
||||
debug_console_printf("%7s: %08X logical == %08X physical -> %s\n", intnames[intention & 3], (UINT32)address, BYTE2ADDR(taddress, info, spacenum), mapname);
|
||||
}
|
||||
else
|
||||
debug_console_printf("%7s: %08X logical is unmapped\n", intnames[intention & 3], (UINT32)address);
|
||||
const char *mapname = memory_get_handler_string(space, intention == TRANSLATE_WRITE_DEBUG, taddress);
|
||||
debug_console_printf("%7s: %08X logical == %08X physical -> %s\n", intnames[intention & 3], (UINT32)address, memory_byte_to_address(space, taddress), mapname);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *mapname = memory_get_handler_string(cpu_get_address_space(cpu, spacenum), intention == TRANSLATE_WRITE_DEBUG, taddress);
|
||||
debug_console_printf("%7s: %08X -> %s\n", intnames[intention & 3], BYTE2ADDR(taddress, info, spacenum), mapname);
|
||||
}
|
||||
debug_console_printf("%7s: %08X logical is unmapped\n", intnames[intention & 3], (UINT32)address);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2138,7 +2173,7 @@ static void execute_symlist(running_machine *machine, int ref, int params, const
|
||||
int symnum, count = 0;
|
||||
|
||||
/* validate parameters */
|
||||
if (params > 0 && !debug_command_parameter_cpu(machine, param[0], &cpu))
|
||||
if (!debug_command_parameter_cpu(machine, param[0], &cpu))
|
||||
return;
|
||||
|
||||
if (cpu != NULL)
|
||||
|
@ -17,11 +17,22 @@
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* initialization */
|
||||
/* ----- initialization ----- */
|
||||
|
||||
/* initializes the command system */
|
||||
void debug_command_init(running_machine *machine);
|
||||
|
||||
/* parameter validation */
|
||||
|
||||
|
||||
/* ----- parameter validation ----- */
|
||||
|
||||
/* validates a number parameter */
|
||||
int debug_command_parameter_number(running_machine *machine, const char *param, UINT64 *result);
|
||||
|
||||
/* validates a parameter as a cpu */
|
||||
int debug_command_parameter_cpu(running_machine *machine, const char *param, const device_config **result);
|
||||
|
||||
/* validates a parameter as a cpu and retrieves the given address space */
|
||||
int debug_command_parameter_cpu_space(running_machine *machine, const char *param, int spacenum, const address_space **result);
|
||||
|
||||
#endif
|
||||
|
@ -310,7 +310,6 @@ UINT32 debug_comment_all_change_count(running_machine *machine)
|
||||
|
||||
UINT32 debug_comment_get_opcode_crc32(const device_config *device, offs_t address)
|
||||
{
|
||||
const cpu_debug_data *info = cpu_get_debug_data(device);
|
||||
const address_space *space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM);
|
||||
int i;
|
||||
UINT32 crc;
|
||||
@ -318,7 +317,7 @@ UINT32 debug_comment_get_opcode_crc32(const device_config *device, offs_t addres
|
||||
char buff[256];
|
||||
offs_t numbytes;
|
||||
int maxbytes = cpu_get_max_opcode_bytes(device);
|
||||
UINT32 addrmask = (cpu_get_debug_data(device))->space[ADDRESS_SPACE_PROGRAM].logaddrmask;
|
||||
UINT32 addrmask = space->logaddrmask;
|
||||
|
||||
memset(opbuf, 0x00, sizeof(opbuf));
|
||||
memset(argbuf, 0x00, sizeof(argbuf));
|
||||
@ -331,7 +330,7 @@ UINT32 debug_comment_get_opcode_crc32(const device_config *device, offs_t addres
|
||||
}
|
||||
|
||||
numbytes = cpu_dasm(device, buff, address & addrmask, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
|
||||
numbytes = ADDR2BYTE(numbytes, info, ADDRESS_SPACE_PROGRAM);
|
||||
numbytes = memory_address_to_byte(space, numbytes);
|
||||
|
||||
crc = crc32(0, argbuf, numbytes);
|
||||
|
||||
|
@ -209,7 +209,10 @@ static CMDERR internal_execute_command(running_machine *machine, int execute, in
|
||||
params = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
params = 0;
|
||||
param[0] = NULL;
|
||||
}
|
||||
|
||||
/* search the command list */
|
||||
len = strlen(command);
|
||||
@ -260,7 +263,7 @@ static CMDERR internal_execute_command(running_machine *machine, int execute, in
|
||||
static CMDERR internal_parse_command(running_machine *machine, const char *original_command, int execute)
|
||||
{
|
||||
char command[MAX_COMMAND_LENGTH], parens[MAX_COMMAND_LENGTH];
|
||||
char *params[MAX_COMMAND_PARAMS];
|
||||
char *params[MAX_COMMAND_PARAMS] = { 0 };
|
||||
CMDERR result = CMDERR_NONE;
|
||||
char *command_start;
|
||||
char *p, c = 0;
|
||||
@ -328,7 +331,7 @@ static CMDERR internal_parse_command(running_machine *machine, const char *origi
|
||||
if (isexpr && paramcount == 1)
|
||||
{
|
||||
UINT64 expresult;
|
||||
EXPRERR exprerr = expression_evaluate(command_start, cpu_get_debug_data(machine->activecpu)->symtable, &debug_expression_callbacks, machine, &expresult);
|
||||
EXPRERR exprerr = expression_evaluate(command_start, debug_cpu_get_visible_symtable(machine), &debug_expression_callbacks, machine, &expresult);
|
||||
if (exprerr != EXPRERR_NONE)
|
||||
return MAKE_CMDERR_EXPRESSION_ERROR(EXPRERR_ERROR_OFFSET(exprerr));
|
||||
}
|
||||
|
@ -159,8 +159,8 @@ const express_callbacks debug_expression_callbacks =
|
||||
void debug_cpu_init(running_machine *machine)
|
||||
{
|
||||
const device_config *first_screen = video_screen_first(machine->config);
|
||||
int cpunum, spacenum, regnum;
|
||||
debugcpu_private *global;
|
||||
int cpunum, regnum;
|
||||
|
||||
/* allocate and reset globals */
|
||||
machine->debugcpu_data = global = auto_malloc(sizeof(*global));
|
||||
@ -204,11 +204,9 @@ void debug_cpu_init(running_machine *machine)
|
||||
/* reset the PC data */
|
||||
info->flags = DEBUG_FLAG_OBSERVING | DEBUG_FLAG_HISTORY;
|
||||
info->device = machine->cpu[cpunum];
|
||||
info->endianness = cpu_get_endianness(info->device);
|
||||
info->opwidth = cpu_get_min_opcode_bytes(info->device);
|
||||
|
||||
/* fetch the memory accessors */
|
||||
info->translate = (cpu_translate_func)cpu_get_info_fct(info->device, CPUINFO_PTR_TRANSLATE);
|
||||
info->read = (cpu_read_func)cpu_get_info_fct(info->device, CPUINFO_PTR_READ);
|
||||
info->write = (cpu_write_func)cpu_get_info_fct(info->device, CPUINFO_PTR_WRITE);
|
||||
info->readop = (cpu_readop_func)cpu_get_info_fct(info->device, CPUINFO_PTR_READOP);
|
||||
@ -252,40 +250,6 @@ void debug_cpu_init(running_machine *machine)
|
||||
/* add the symbol to the table */
|
||||
symtable_add_register(info->symtable, symname, (void *)(FPTR)regnum, get_cpu_reg, set_cpu_reg);
|
||||
}
|
||||
|
||||
/* loop over address spaces and get info */
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
{
|
||||
debug_space_info *spaceinfo = &info->space[spacenum];
|
||||
int datawidth = cpu_get_databus_width(info->device, spacenum);
|
||||
int logwidth = cpu_get_logaddr_width(info->device, spacenum);
|
||||
int physwidth = cpu_get_addrbus_width(info->device, spacenum);
|
||||
int addrshift = cpu_get_addrbus_shift(info->device, spacenum);
|
||||
int pageshift = cpu_get_page_shift(info->device, spacenum);
|
||||
|
||||
if (logwidth == 0)
|
||||
logwidth = physwidth;
|
||||
|
||||
spaceinfo->space = cpu_get_address_space(cpu, spacenum);
|
||||
spaceinfo->databytes = datawidth / 8;
|
||||
spaceinfo->pageshift = pageshift;
|
||||
|
||||
/* left/right shifts to convert addresses to bytes */
|
||||
spaceinfo->addr2byte_lshift = (addrshift < 0) ? -addrshift : 0;
|
||||
spaceinfo->addr2byte_rshift = (addrshift > 0) ? addrshift : 0;
|
||||
|
||||
/* number of character used to display addresses */
|
||||
spaceinfo->physchars = (physwidth + 3) / 4;
|
||||
spaceinfo->logchars = (logwidth + 3) / 4;
|
||||
|
||||
/* masks to apply to addresses */
|
||||
spaceinfo->physaddrmask = (0xfffffffful >> (32 - physwidth));
|
||||
spaceinfo->logaddrmask = (0xfffffffful >> (32 - logwidth));
|
||||
|
||||
/* masks to apply to byte addresses */
|
||||
spaceinfo->physbytemask = ((spaceinfo->physaddrmask << spaceinfo->addr2byte_lshift) | ((1 << spaceinfo->addr2byte_lshift) - 1)) >> spaceinfo->addr2byte_rshift;
|
||||
spaceinfo->logbytemask = ((spaceinfo->logaddrmask << spaceinfo->addr2byte_lshift) | ((1 << spaceinfo->addr2byte_lshift) - 1)) >> spaceinfo->addr2byte_rshift;
|
||||
}
|
||||
}
|
||||
|
||||
/* first CPU is visible by default */
|
||||
@ -614,7 +578,7 @@ void debug_cpu_instruction_hook(const device_config *device, offs_t curpc)
|
||||
{
|
||||
/* clear the memory modified flag and wait */
|
||||
global->memory_modified = FALSE;
|
||||
osd_wait_for_debugger(device->machine, firststop);
|
||||
osd_wait_for_debugger(device, firststop);
|
||||
firststop = FALSE;
|
||||
|
||||
/* if something modified memory, update the screen */
|
||||
@ -1051,8 +1015,8 @@ int debug_cpu_watchpoint_set(const address_space *space, int type, offs_t addres
|
||||
wp->index = global->wpindex++;
|
||||
wp->enabled = TRUE;
|
||||
wp->type = type;
|
||||
wp->address = ADDR2BYTE_MASKED(address, info, space->spacenum);
|
||||
wp->length = ADDR2BYTE(length, info, space->spacenum);
|
||||
wp->address = memory_address_to_byte(space, address) & space->bytemask;
|
||||
wp->length = memory_address_to_byte(space, length);
|
||||
wp->condition = condition;
|
||||
wp->action = NULL;
|
||||
if (action != NULL)
|
||||
@ -1062,8 +1026,8 @@ int debug_cpu_watchpoint_set(const address_space *space, int type, offs_t addres
|
||||
}
|
||||
|
||||
/* hook us in */
|
||||
wp->next = info->space[space->spacenum].wplist;
|
||||
info->space[space->spacenum].wplist = wp;
|
||||
wp->next = info->wplist[space->spacenum];
|
||||
info->wplist[space->spacenum] = wp;
|
||||
|
||||
watchpoint_update_flags(space);
|
||||
|
||||
@ -1088,12 +1052,12 @@ int debug_cpu_watchpoint_clear(running_machine *machine, int wpnum)
|
||||
cpu_debug_data *info = cpu_get_debug_data(machine->cpu[cpunum]);
|
||||
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
for (pwp = NULL, wp = info->space[spacenum].wplist; wp != NULL; pwp = wp, wp = wp->next)
|
||||
for (pwp = NULL, wp = info->wplist[spacenum]; wp != NULL; pwp = wp, wp = wp->next)
|
||||
if (wp->index == wpnum)
|
||||
{
|
||||
/* unlink us from the list */
|
||||
if (pwp == NULL)
|
||||
info->space[spacenum].wplist = wp->next;
|
||||
info->wplist[spacenum] = wp->next;
|
||||
else
|
||||
pwp->next = wp->next;
|
||||
|
||||
@ -1131,7 +1095,7 @@ int debug_cpu_watchpoint_enable(running_machine *machine, int wpnum, int enable)
|
||||
cpu_debug_data *info = cpu_get_debug_data(machine->cpu[cpunum]);
|
||||
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
for (wp = info->space[spacenum].wplist; wp; wp = wp->next)
|
||||
for (wp = info->wplist[spacenum]; wp != NULL; wp = wp->next)
|
||||
if (wp->index == wpnum)
|
||||
{
|
||||
wp->enabled = (enable != 0);
|
||||
@ -1302,13 +1266,13 @@ UINT8 debug_read_byte(const address_space *space, offs_t address, int apply_tran
|
||||
UINT8 result;
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_READ_DEBUG, &address))
|
||||
result = 0xff;
|
||||
|
||||
/* if there is a custom read handler, and it returns TRUE, use that value */
|
||||
@ -1333,12 +1297,10 @@ UINT8 debug_read_byte(const address_space *space, offs_t address, int apply_tran
|
||||
UINT16 debug_read_word(const address_space *space, offs_t address, int apply_translation)
|
||||
{
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT64 custom;
|
||||
UINT16 result;
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* if this is misaligned read, or if there are no word readers, just read two bytes */
|
||||
if ((address & 1) != 0)
|
||||
@ -1347,7 +1309,7 @@ UINT16 debug_read_word(const address_space *space, offs_t address, int apply_tra
|
||||
UINT8 byte1 = debug_read_byte(space, address + 1, apply_translation);
|
||||
|
||||
/* based on the endianness, the result is assembled differently */
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
result = byte0 | (byte1 << 8);
|
||||
else
|
||||
result = byte1 | (byte0 << 8);
|
||||
@ -1356,15 +1318,18 @@ UINT16 debug_read_word(const address_space *space, offs_t address, int apply_tra
|
||||
/* otherwise, this proceeds like the byte case */
|
||||
else
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT64 custom;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xffff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_READ_DEBUG, &address))
|
||||
result = 0xffff;
|
||||
|
||||
/* if there is a custom read handler, and it returns TRUE, use that value */
|
||||
else if (info->read && (*info->read)(space->cpu, space->spacenum, address, 2, &custom))
|
||||
else if (info->read != NULL && (*info->read)(space->cpu, space->spacenum, address, 2, &custom))
|
||||
result = custom;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1387,12 +1352,10 @@ UINT16 debug_read_word(const address_space *space, offs_t address, int apply_tra
|
||||
UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_translation)
|
||||
{
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT64 custom;
|
||||
UINT32 result;
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* if this is misaligned read, or if there are no dword readers, just read two words */
|
||||
if ((address & 3) != 0)
|
||||
@ -1401,7 +1364,7 @@ UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_tr
|
||||
UINT16 word1 = debug_read_word(space, address + 2, apply_translation);
|
||||
|
||||
/* based on the endianness, the result is assembled differently */
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
result = word0 | (word1 << 16);
|
||||
else
|
||||
result = word1 | (word0 << 16);
|
||||
@ -1410,15 +1373,18 @@ UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_tr
|
||||
/* otherwise, this proceeds like the byte case */
|
||||
else
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT64 custom;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xffffffff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_READ_DEBUG, &address))
|
||||
result = 0xffffffff;
|
||||
|
||||
/* if there is a custom read handler, and it returns TRUE, use that value */
|
||||
else if (info->read && (*info->read)(space->cpu, space->spacenum, address, 4, &custom))
|
||||
else if (info->read != NULL && (*info->read)(space->cpu, space->spacenum, address, 4, &custom))
|
||||
result = custom;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1441,12 +1407,10 @@ UINT32 debug_read_dword(const address_space *space, offs_t address, int apply_tr
|
||||
UINT64 debug_read_qword(const address_space *space, offs_t address, int apply_translation)
|
||||
{
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT64 custom;
|
||||
UINT64 result;
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* if this is misaligned read, or if there are no qword readers, just read two dwords */
|
||||
if ((address & 7) != 0)
|
||||
@ -1455,7 +1419,7 @@ UINT64 debug_read_qword(const address_space *space, offs_t address, int apply_tr
|
||||
UINT32 dword1 = debug_read_dword(space, address + 4, apply_translation);
|
||||
|
||||
/* based on the endianness, the result is assembled differently */
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
result = dword0 | ((UINT64)dword1 << 32);
|
||||
else
|
||||
result = dword1 | ((UINT64)dword0 << 32);
|
||||
@ -1464,15 +1428,18 @@ UINT64 debug_read_qword(const address_space *space, offs_t address, int apply_tr
|
||||
/* otherwise, this proceeds like the byte case */
|
||||
else
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT64 custom;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, return 0xffffffffffffffff */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_READ_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_READ_DEBUG, &address))
|
||||
result = ~(UINT64)0;
|
||||
|
||||
/* if there is a custom read handler, and it returns TRUE, use that value */
|
||||
else if (info->read && (*info->read)(space->cpu, space->spacenum, address, 8, &custom))
|
||||
else if (info->read != NULL && (*info->read)(space->cpu, space->spacenum, address, 8, &custom))
|
||||
result = custom;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1498,17 +1465,17 @@ void debug_write_byte(const address_space *space, offs_t address, UINT8 data, in
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate != NULL && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_WRITE_DEBUG, &address))
|
||||
;
|
||||
|
||||
/* if there is a custom write handler, and it returns TRUE, use that */
|
||||
else if (info->write && (*info->write)(space->cpu, space->spacenum, address, 1, data))
|
||||
else if (info->write != NULL && (*info->write)(space->cpu, space->spacenum, address, 1, data))
|
||||
;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1529,15 +1496,14 @@ void debug_write_byte(const address_space *space, offs_t address, UINT8 data, in
|
||||
void debug_write_word(const address_space *space, offs_t address, UINT16 data, int apply_translation)
|
||||
{
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* if this is a misaligned write, or if there are no word writers, just read two bytes */
|
||||
if ((address & 1) != 0)
|
||||
{
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
{
|
||||
debug_write_byte(space, address + 0, data >> 0, apply_translation);
|
||||
debug_write_byte(space, address + 1, data >> 8, apply_translation);
|
||||
@ -1552,15 +1518,17 @@ void debug_write_word(const address_space *space, offs_t address, UINT16 data, i
|
||||
/* otherwise, this proceeds like the byte case */
|
||||
else
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_WRITE_DEBUG, &address))
|
||||
;
|
||||
|
||||
/* if there is a custom write handler, and it returns TRUE, use that */
|
||||
else if (info->write && (*info->write)(space->cpu, space->spacenum, address, 2, data))
|
||||
else if (info->write != NULL && (*info->write)(space->cpu, space->spacenum, address, 2, data))
|
||||
;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1582,15 +1550,14 @@ void debug_write_word(const address_space *space, offs_t address, UINT16 data, i
|
||||
void debug_write_dword(const address_space *space, offs_t address, UINT32 data, int apply_translation)
|
||||
{
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* if this is a misaligned write, or if there are no dword writers, just read two words */
|
||||
if ((address & 3) != 0)
|
||||
{
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
{
|
||||
debug_write_word(space, address + 0, data >> 0, apply_translation);
|
||||
debug_write_word(space, address + 2, data >> 16, apply_translation);
|
||||
@ -1605,15 +1572,17 @@ void debug_write_dword(const address_space *space, offs_t address, UINT32 data,
|
||||
/* otherwise, this proceeds like the byte case */
|
||||
else
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_WRITE_DEBUG, &address))
|
||||
;
|
||||
|
||||
/* if there is a custom write handler, and it returns TRUE, use that */
|
||||
else if (info->write && (*info->write)(space->cpu, space->spacenum, address, 4, data))
|
||||
else if (info->write != NULL && (*info->write)(space->cpu, space->spacenum, address, 4, data))
|
||||
;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1635,15 +1604,14 @@ void debug_write_dword(const address_space *space, offs_t address, UINT32 data,
|
||||
void debug_write_qword(const address_space *space, offs_t address, UINT64 data, int apply_translation)
|
||||
{
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* mask against the logical byte mask */
|
||||
address &= info->space[space->spacenum].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* if this is a misaligned write, or if there are no qword writers, just read two dwords */
|
||||
if ((address & 7) != 0)
|
||||
{
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
{
|
||||
debug_write_dword(space, address + 0, data >> 0, apply_translation);
|
||||
debug_write_dword(space, address + 4, data >> 32, apply_translation);
|
||||
@ -1654,18 +1622,21 @@ void debug_write_qword(const address_space *space, offs_t address, UINT64 data,
|
||||
debug_write_dword(space, address + 4, data >> 0, apply_translation);
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, this proceeds like the byte case */
|
||||
else
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* all accesses from this point on are for the debugger */
|
||||
memory_set_debugger_access(space, global->debugger_access = TRUE);
|
||||
|
||||
/* translate if necessary; if not mapped, we're done */
|
||||
if (apply_translation && info->translate && !(*info->translate)(space->cpu, space->spacenum, TRANSLATE_WRITE_DEBUG, &address))
|
||||
if (apply_translation && !memory_address_physical(space, TRANSLATE_WRITE_DEBUG, &address))
|
||||
;
|
||||
|
||||
/* if there is a custom write handler, and it returns TRUE, use that */
|
||||
else if (info->write && (*info->write)(space->cpu, space->spacenum, address, 8, data))
|
||||
else if (info->write != NULL && (*info->write)(space->cpu, space->spacenum, address, 8, data))
|
||||
;
|
||||
|
||||
/* otherwise, call the byte reading function for the translated address */
|
||||
@ -1691,10 +1662,10 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
|
||||
const void *ptr;
|
||||
|
||||
/* keep in logical range */
|
||||
address &= info->space[ADDRESS_SPACE_PROGRAM].logbytemask;
|
||||
address &= space->logbytemask;
|
||||
|
||||
/* shortcut if we have a custom routine */
|
||||
if (info->readop)
|
||||
if (info->readop != NULL)
|
||||
{
|
||||
UINT64 result;
|
||||
if ((*info->readop)(space->cpu, address, size, &result))
|
||||
@ -1702,25 +1673,25 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
|
||||
}
|
||||
|
||||
/* if we're bigger than the address bus, break into smaller pieces */
|
||||
if (size > info->space[ADDRESS_SPACE_PROGRAM].databytes)
|
||||
if (size > space->dbits / 8)
|
||||
{
|
||||
int halfsize = size / 2;
|
||||
UINT64 r0 = debug_read_opcode(space, address + 0, halfsize, arg);
|
||||
UINT64 r1 = debug_read_opcode(space, address + halfsize, halfsize, arg);
|
||||
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
return r0 | (r1 << (8 * halfsize));
|
||||
else
|
||||
return r1 | (r0 << (8 * halfsize));
|
||||
}
|
||||
|
||||
/* translate to physical first */
|
||||
if (info->translate && !(*info->translate)(space->cpu, ADDRESS_SPACE_PROGRAM, TRANSLATE_FETCH_DEBUG, &address))
|
||||
if (!memory_address_physical(space, TRANSLATE_FETCH_DEBUG, &address))
|
||||
return ~(UINT64)0 & (~(UINT64)0 >> (64 - 8*size));
|
||||
|
||||
/* keep in physical range */
|
||||
address &= info->space[ADDRESS_SPACE_PROGRAM].physbytemask;
|
||||
switch (info->space[ADDRESS_SPACE_PROGRAM].databytes * 10 + size)
|
||||
address &= space->bytemask;
|
||||
switch (space->dbits / 8 * 10 + size)
|
||||
{
|
||||
/* dump opcodes in bytes from a byte-sized bus */
|
||||
case 11:
|
||||
@ -1728,7 +1699,7 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
|
||||
|
||||
/* dump opcodes in bytes from a word-sized bus */
|
||||
case 21:
|
||||
address ^= (info->endianness == CPU_IS_LE) ? BYTE_XOR_LE(0) : BYTE_XOR_BE(0);
|
||||
address ^= (space->endianness == CPU_IS_LE) ? BYTE_XOR_LE(0) : BYTE_XOR_BE(0);
|
||||
break;
|
||||
|
||||
/* dump opcodes in words from a word-sized bus */
|
||||
@ -1737,12 +1708,12 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
|
||||
|
||||
/* dump opcodes in bytes from a dword-sized bus */
|
||||
case 41:
|
||||
address ^= (info->endianness == CPU_IS_LE) ? BYTE4_XOR_LE(0) : BYTE4_XOR_BE(0);
|
||||
address ^= (space->endianness == CPU_IS_LE) ? BYTE4_XOR_LE(0) : BYTE4_XOR_BE(0);
|
||||
break;
|
||||
|
||||
/* dump opcodes in words from a dword-sized bus */
|
||||
case 42:
|
||||
address ^= (info->endianness == CPU_IS_LE) ? WORD_XOR_LE(0) : WORD_XOR_BE(0);
|
||||
address ^= (space->endianness == CPU_IS_LE) ? WORD_XOR_LE(0) : WORD_XOR_BE(0);
|
||||
break;
|
||||
|
||||
/* dump opcodes in dwords from a dword-sized bus */
|
||||
@ -1751,17 +1722,17 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
|
||||
|
||||
/* dump opcodes in bytes from a qword-sized bus */
|
||||
case 81:
|
||||
address ^= (info->endianness == CPU_IS_LE) ? BYTE8_XOR_LE(0) : BYTE8_XOR_BE(0);
|
||||
address ^= (space->endianness == CPU_IS_LE) ? BYTE8_XOR_LE(0) : BYTE8_XOR_BE(0);
|
||||
break;
|
||||
|
||||
/* dump opcodes in words from a qword-sized bus */
|
||||
case 82:
|
||||
address ^= (info->endianness == CPU_IS_LE) ? WORD2_XOR_LE(0) : WORD2_XOR_BE(0);
|
||||
address ^= (space->endianness == CPU_IS_LE) ? WORD2_XOR_LE(0) : WORD2_XOR_BE(0);
|
||||
break;
|
||||
|
||||
/* dump opcodes in dwords from a qword-sized bus */
|
||||
case 84:
|
||||
address ^= (info->endianness == CPU_IS_LE) ? DWORD_XOR_LE(0) : DWORD_XOR_BE(0);
|
||||
address ^= (space->endianness == CPU_IS_LE) ? DWORD_XOR_LE(0) : DWORD_XOR_BE(0);
|
||||
break;
|
||||
|
||||
/* dump opcodes in qwords from a qword-sized bus */
|
||||
@ -1769,13 +1740,13 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("debug_read_opcode: unknown type = %d", info->space[ADDRESS_SPACE_PROGRAM].databytes * 10 + size);
|
||||
fatalerror("debug_read_opcode: unknown type = %d", space->dbits / 8 * 10 + size);
|
||||
break;
|
||||
}
|
||||
|
||||
/* get pointer to data */
|
||||
/* note that we query aligned to the bus width, and then add back the low bits */
|
||||
lowbits_mask = info->space[ADDRESS_SPACE_PROGRAM].databytes - 1;
|
||||
lowbits_mask = space->dbits / 8 - 1;
|
||||
if (!arg)
|
||||
ptr = memory_decrypted_read_ptr(space, address & ~lowbits_mask);
|
||||
else
|
||||
@ -1832,11 +1803,11 @@ static void debug_cpu_exit(running_machine *machine)
|
||||
debug_cpu_breakpoint_clear(machine, info->bplist->index);
|
||||
|
||||
/* loop over all address spaces */
|
||||
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
|
||||
for (spacenum = 0; spacenum < ARRAY_LENGTH(info->wplist); spacenum++)
|
||||
{
|
||||
/* free all watchpoints */
|
||||
while (info->space[spacenum].wplist != NULL)
|
||||
debug_cpu_watchpoint_clear(machine, info->space[spacenum].wplist->index);
|
||||
while (info->wplist[spacenum] != NULL)
|
||||
debug_cpu_watchpoint_clear(machine, info->wplist[spacenum]->index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1933,6 +1904,8 @@ static void perform_trace(cpu_debug_data *info)
|
||||
/* if no more than 1 hit, process normally */
|
||||
if (count <= 1)
|
||||
{
|
||||
const address_space *space = cpu_get_address_space(info->device, ADDRESS_SPACE_PROGRAM);
|
||||
|
||||
/* if we just finished looping, indicate as much */
|
||||
if (info->trace.loops != 0)
|
||||
fprintf(info->trace.file, "\n (loops for %d instructions)\n\n", info->trace.loops);
|
||||
@ -1943,7 +1916,7 @@ static void perform_trace(cpu_debug_data *info)
|
||||
debug_console_execute_command(info->device->machine, info->trace.action, 0);
|
||||
|
||||
/* print the address */
|
||||
offset = sprintf(buffer, "%0*X: ", info->space[ADDRESS_SPACE_PROGRAM].logchars, pc);
|
||||
offset = sprintf(buffer, "%0*X: ", space->logaddrchars, pc);
|
||||
|
||||
/* print the disassembly */
|
||||
dasmresult = dasm_wrapped(info->device, &buffer[offset], pc);
|
||||
@ -2132,7 +2105,7 @@ static void watchpoint_update_flags(const address_space *space)
|
||||
enableread = TRUE;
|
||||
|
||||
/* see if there are any enabled breakpoints */
|
||||
for (wp = info->space[space->spacenum].wplist; wp != NULL; wp = wp->next)
|
||||
for (wp = info->wplist[space->spacenum]; wp != NULL; wp = wp->next)
|
||||
if (wp->enabled)
|
||||
{
|
||||
if (wp->type & WATCHPOINT_READ)
|
||||
@ -2169,7 +2142,7 @@ static void watchpoint_check(const address_space *space, int type, offs_t addres
|
||||
/* adjust address, size & value_to_write based on mem_mask. */
|
||||
if (mem_mask != 0)
|
||||
{
|
||||
int bus_size = info->space[space->spacenum].databytes;
|
||||
int bus_size = space->dbits / 8;
|
||||
int address_offset = 0;
|
||||
|
||||
while (address_offset < bus_size && (mem_mask & 0xff) == 0)
|
||||
@ -2185,7 +2158,7 @@ static void watchpoint_check(const address_space *space, int type, offs_t addres
|
||||
mem_mask >>= 8;
|
||||
}
|
||||
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
address += address_offset;
|
||||
else
|
||||
address += bus_size - size - address_offset;
|
||||
@ -2197,7 +2170,7 @@ static void watchpoint_check(const address_space *space, int type, offs_t addres
|
||||
global->wpdata = value_to_write;
|
||||
|
||||
/* see if we match */
|
||||
for (wp = info->space[space->spacenum].wplist; wp != NULL; wp = wp->next)
|
||||
for (wp = info->wplist[space->spacenum]; wp != NULL; wp = wp->next)
|
||||
if (wp->enabled && (wp->type & type) != 0 && address + size > wp->address && address < wp->address + wp->length)
|
||||
|
||||
/* if we do, evaluate the condition */
|
||||
@ -2221,14 +2194,14 @@ static void watchpoint_check(const address_space *space, int type, offs_t addres
|
||||
|
||||
if (type & WATCHPOINT_WRITE)
|
||||
{
|
||||
sprintf(buffer, "Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->index, sizes[size], cpu_byte_to_address(space->cpu, space->spacenum, address), cpu_get_pc(space->cpu));
|
||||
sprintf(buffer, "Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->index, sizes[size], memory_byte_to_address(space, address), cpu_get_pc(space->cpu));
|
||||
if (value_to_write >> 32)
|
||||
sprintf(&buffer[strlen(buffer)], " (data=%X%08X)", (UINT32)(value_to_write >> 32), (UINT32)value_to_write);
|
||||
else
|
||||
sprintf(&buffer[strlen(buffer)], " (data=%X)", (UINT32)value_to_write);
|
||||
}
|
||||
else
|
||||
sprintf(buffer, "Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->index, sizes[size], cpu_byte_to_address(space->cpu, space->spacenum, address), cpu_get_pc(space->cpu));
|
||||
sprintf(buffer, "Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->index, sizes[size], memory_byte_to_address(space, address), cpu_get_pc(space->cpu));
|
||||
debug_console_printf("%s\n", buffer);
|
||||
compute_debug_flags(space->cpu);
|
||||
}
|
||||
@ -2252,7 +2225,7 @@ static void check_hotspots(const address_space *space, offs_t address)
|
||||
|
||||
/* see if we have a match in our list */
|
||||
for (hotindex = 0; hotindex < info->hotspot_count; hotindex++)
|
||||
if (info->hotspots[hotindex].access == address && info->hotspots[hotindex].pc == pc && info->hotspots[hotindex].spacenum == space->spacenum)
|
||||
if (info->hotspots[hotindex].access == address && info->hotspots[hotindex].pc == pc && info->hotspots[hotindex].space == space)
|
||||
break;
|
||||
|
||||
/* if we didn't find any, make a new entry */
|
||||
@ -2261,13 +2234,13 @@ static void check_hotspots(const address_space *space, offs_t address)
|
||||
/* if the bottom of the list is over the threshhold, print it */
|
||||
debug_hotspot_entry *spot = &info->hotspots[info->hotspot_count - 1];
|
||||
if (spot->count > info->hotspot_threshhold)
|
||||
debug_console_printf("Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", address_space_names[spot->spacenum], spot->access, spot->pc, spot->count);
|
||||
debug_console_printf("Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space->name, spot->access, spot->pc, spot->count);
|
||||
|
||||
/* move everything else down and insert this one at the top */
|
||||
memmove(&info->hotspots[1], &info->hotspots[0], sizeof(info->hotspots[0]) * (info->hotspot_count - 1));
|
||||
info->hotspots[0].access = address;
|
||||
info->hotspots[0].pc = pc;
|
||||
info->hotspots[0].spacenum = space->spacenum;
|
||||
info->hotspots[0].space = space;
|
||||
info->hotspots[0].count = 1;
|
||||
}
|
||||
|
||||
@ -2293,7 +2266,6 @@ static void check_hotspots(const address_space *space, offs_t address)
|
||||
|
||||
static UINT32 dasm_wrapped(const device_config *device, char *buffer, offs_t pc)
|
||||
{
|
||||
const cpu_debug_data *cpuinfo = cpu_get_debug_data(device);
|
||||
const address_space *space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM);
|
||||
int maxbytes = cpu_get_max_opcode_bytes(device);
|
||||
UINT8 opbuf[64], argbuf[64];
|
||||
@ -2301,7 +2273,7 @@ static UINT32 dasm_wrapped(const device_config *device, char *buffer, offs_t pc)
|
||||
int numbytes;
|
||||
|
||||
/* fetch the bytes up to the maximum */
|
||||
pcbyte = ADDR2BYTE_MASKED(pc, cpuinfo, ADDRESS_SPACE_PROGRAM);
|
||||
pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
|
||||
for (numbytes = 0; numbytes < maxbytes; numbytes++)
|
||||
{
|
||||
opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, FALSE);
|
||||
@ -2387,10 +2359,8 @@ static UINT64 expression_read_address_space(const address_space *space, offs_t a
|
||||
|
||||
if (space != NULL)
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* adjust the address into a byte address */
|
||||
address = ADDR2BYTE(address, info, space->spacenum);
|
||||
address = memory_address_to_byte(space, address);
|
||||
|
||||
/* switch contexts and do the read */
|
||||
cpu_push_context(space->cpu);
|
||||
@ -2418,12 +2388,11 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
|
||||
|
||||
if (space != NULL)
|
||||
{
|
||||
cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
UINT8 *base;
|
||||
|
||||
/* adjust the address into a byte address, but not if being called recursively */
|
||||
if ((opcode & 2) == 0)
|
||||
address = ADDR2BYTE(address, info, ADDRESS_SPACE_PROGRAM);
|
||||
address = memory_address_to_byte(space, address);
|
||||
|
||||
/* call ourself recursively until we are byte-sized */
|
||||
if (size > 1)
|
||||
@ -2436,7 +2405,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
|
||||
r1 = expression_read_program_direct(space, opcode | 2, address + halfsize, halfsize);
|
||||
|
||||
/* assemble based on the target endianness */
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
result = r0 | (r1 << (8 * halfsize));
|
||||
else
|
||||
result = r1 | (r0 << (8 * halfsize));
|
||||
@ -2446,7 +2415,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
|
||||
else
|
||||
{
|
||||
/* lowmask specified which address bits are within the databus width */
|
||||
offs_t lowmask = info->space[ADDRESS_SPACE_PROGRAM].databytes - 1;
|
||||
offs_t lowmask = space->dbits / 8 - 1;
|
||||
|
||||
/* get the base of memory, aligned to the address minus the lowbits */
|
||||
if (opcode & 1)
|
||||
@ -2457,7 +2426,7 @@ static UINT64 expression_read_program_direct(const address_space *space, int opc
|
||||
/* if we have a valid base, return the appropriate byte */
|
||||
if (base != NULL)
|
||||
{
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
result = base[BYTE8_XOR_LE(address) & lowmask];
|
||||
else
|
||||
result = base[BYTE8_XOR_BE(address) & lowmask];
|
||||
@ -2598,10 +2567,8 @@ static void expression_write_address_space(const address_space *space, offs_t ad
|
||||
{
|
||||
if (space != NULL)
|
||||
{
|
||||
const cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
|
||||
/* adjust the address into a byte address */
|
||||
address = ADDR2BYTE(address, info, space->spacenum);
|
||||
address = memory_address_to_byte(space, address);
|
||||
|
||||
/* switch contexts and do the write */
|
||||
cpu_push_context(space->cpu);
|
||||
@ -2626,13 +2593,12 @@ static void expression_write_program_direct(const address_space *space, int opco
|
||||
{
|
||||
if (space != NULL)
|
||||
{
|
||||
const cpu_debug_data *info = cpu_get_debug_data(space->cpu);
|
||||
debugcpu_private *global = space->machine->debugcpu_data;
|
||||
UINT8 *base;
|
||||
|
||||
/* adjust the address into a byte address, but not if being called recursively */
|
||||
if ((opcode & 2) == 0)
|
||||
address = ADDR2BYTE(address, info, ADDRESS_SPACE_PROGRAM);
|
||||
address = memory_address_to_byte(space, address);
|
||||
|
||||
/* call ourself recursively until we are byte-sized */
|
||||
if (size > 1)
|
||||
@ -2642,7 +2608,7 @@ static void expression_write_program_direct(const address_space *space, int opco
|
||||
|
||||
/* break apart based on the target endianness */
|
||||
halfmask = ~(UINT64)0 >> (64 - 8 * halfsize);
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
{
|
||||
r0 = data & halfmask;
|
||||
r1 = (data >> (8 * halfsize)) & halfmask;
|
||||
@ -2662,7 +2628,7 @@ static void expression_write_program_direct(const address_space *space, int opco
|
||||
else
|
||||
{
|
||||
/* lowmask specified which address bits are within the databus width */
|
||||
offs_t lowmask = info->space[ADDRESS_SPACE_PROGRAM].databytes - 1;
|
||||
offs_t lowmask = space->dbits / 8 - 1;
|
||||
|
||||
/* get the base of memory, aligned to the address minus the lowbits */
|
||||
if (opcode & 1)
|
||||
@ -2673,7 +2639,7 @@ static void expression_write_program_direct(const address_space *space, int opco
|
||||
/* if we have a valid base, write the appropriate byte */
|
||||
if (base != NULL)
|
||||
{
|
||||
if (info->endianness == CPU_IS_LE)
|
||||
if (space->endianness == CPU_IS_LE)
|
||||
base[BYTE8_XOR_LE(address) & lowmask] = data;
|
||||
else
|
||||
base[BYTE8_XOR_BE(address) & lowmask] = data;
|
||||
|
@ -62,16 +62,6 @@
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define ADDR2BYTE(val,info,spc) (((val) << (info)->space[spc].addr2byte_lshift) >> (info)->space[spc].addr2byte_rshift)
|
||||
#define ADDR2BYTE_MASKED(val,info,spc) (ADDR2BYTE(val,info,spc) & (info)->space[spc].logbytemask)
|
||||
#define BYTE2ADDR(val,info,spc) (((val) << (info)->space[spc].addr2byte_rshift) >> (info)->space[spc].addr2byte_lshift)
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
@ -97,30 +87,12 @@ struct _debug_trace_info
|
||||
};
|
||||
|
||||
|
||||
typedef struct _debug_space_info debug_space_info;
|
||||
struct _debug_space_info
|
||||
{
|
||||
const address_space *space; /* pointer to the CPU's address space */
|
||||
debug_cpu_watchpoint *wplist; /* list of watchpoints */
|
||||
UINT8 databytes; /* width of the data bus, in bytes */
|
||||
UINT8 pageshift; /* page shift */
|
||||
UINT8 addr2byte_lshift; /* left shift to convert CPU address to a byte value */
|
||||
UINT8 addr2byte_rshift; /* right shift to convert CPU address to a byte value */
|
||||
UINT8 physchars; /* number of characters to use for physical addresses */
|
||||
UINT8 logchars; /* number of characters to use for logical addresses */
|
||||
offs_t physaddrmask; /* physical address mask */
|
||||
offs_t logaddrmask; /* logical address mask */
|
||||
offs_t physbytemask; /* physical byte mask */
|
||||
offs_t logbytemask; /* logical byte mask */
|
||||
};
|
||||
|
||||
|
||||
typedef struct _debug_hotspot_entry debug_hotspot_entry;
|
||||
struct _debug_hotspot_entry
|
||||
{
|
||||
offs_t access; /* access address */
|
||||
offs_t pc; /* PC of the access */
|
||||
int spacenum; /* space where the access occurred */
|
||||
const address_space *space; /* space where the access occurred */
|
||||
UINT32 count; /* number of hits */
|
||||
};
|
||||
|
||||
@ -131,7 +103,6 @@ struct _cpu_debug_data
|
||||
const device_config *device; /* CPU device object */
|
||||
symbol_table * symtable; /* symbol table for expression evaluation */
|
||||
UINT32 flags; /* debugging flags for this CPU */
|
||||
UINT8 endianness; /* little or bigendian */
|
||||
UINT8 opwidth; /* width of an opcode */
|
||||
offs_t stepaddr; /* step target address for DEBUG_FLAG_STEPPING_OVER */
|
||||
int stepsleft; /* number of steps left until done */
|
||||
@ -147,12 +118,11 @@ struct _cpu_debug_data
|
||||
UINT32 pc_history_index; /* current history index */
|
||||
int hotspot_count; /* number of hotspots */
|
||||
int hotspot_threshhold; /* threshhold for the number of hits to print */
|
||||
cpu_translate_func translate; /* address translation routine */
|
||||
cpu_read_func read; /* memory read routine */
|
||||
cpu_write_func write; /* memory write routine */
|
||||
cpu_readop_func readop; /* opcode read routine */
|
||||
debug_instruction_hook_func instrhook; /* per-instruction callback hook */
|
||||
debug_space_info space[ADDRESS_SPACES]; /* per-address space info */
|
||||
debug_cpu_watchpoint *wplist[ADDRESS_SPACES]; /* watchpoint lists for each address space */
|
||||
};
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,40 +26,25 @@
|
||||
#define DVT_TIMERS (6)
|
||||
#define DVT_ALLOCS (7)
|
||||
|
||||
/* properties available for all views */
|
||||
#define DVP_VISIBLE_ROWS (1) /* r/w - UINT32 */
|
||||
#define DVP_VISIBLE_COLS (2) /* r/w - UINT32 */
|
||||
#define DVP_TOTAL_ROWS (3) /* r/w - UINT32 */
|
||||
#define DVP_TOTAL_COLS (4) /* r/w - UINT32 */
|
||||
#define DVP_TOP_ROW (5) /* r/w - UINT32 */
|
||||
#define DVP_LEFT_COL (6) /* r/w - UINT32 */
|
||||
#define DVP_UPDATE_CALLBACK (7) /* r/w - void (*update)(debug_view *) */
|
||||
#define DVP_VIEW_DATA (8) /* r/o - debug_view_char * */
|
||||
#define DVP_SUPPORTS_CURSOR (9) /* r/o - UINT32 */
|
||||
#define DVP_CURSOR_VISIBLE (10) /* r/w - UINT32 */
|
||||
#define DVP_CURSOR_ROW (11) /* r/w - UINT32 */
|
||||
#define DVP_CURSOR_COL (12) /* r/w - UINT32 */
|
||||
#define DVP_CHARACTER (13) /* w/o - UINT32 */
|
||||
#define DVP_OSD_PRIVATE (14) /* r/w - void * */
|
||||
|
||||
/* properties available for register views */
|
||||
#define DVP_REGS_CPUNUM (100) /* r/w - UINT32 */
|
||||
enum _disasm_right_column
|
||||
{
|
||||
DASM_RIGHTCOL_NONE,
|
||||
DASM_RIGHTCOL_RAW,
|
||||
DASM_RIGHTCOL_ENCRYPTED,
|
||||
DASM_RIGHTCOL_COMMENTS
|
||||
};
|
||||
typedef enum _disasm_right_column disasm_right_column;
|
||||
|
||||
/* properties available for disassembly views */
|
||||
#define DVP_DASM_CPUNUM (100) /* r/w - UINT32 */
|
||||
#define DVP_DASM_EXPRESSION (101) /* r/w - const char * */
|
||||
#define DVP_DASM_TRACK_LIVE (102) /* r/w - UINT32 */
|
||||
#define DVP_DASM_RIGHT_COLUMN (103) /* r/w - UINT32 */
|
||||
#define DVP_DASM_RIGHTCOL_NONE (0)
|
||||
#define DVP_DASM_RIGHTCOL_RAW (1)
|
||||
#define DVP_DASM_RIGHTCOL_ENCRYPTED (2)
|
||||
#define DVP_DASM_RIGHTCOL_COMMENTS (3)
|
||||
#define DVP_DASM_BACKWARD_STEPS (104) /* r/w - UINT32 */
|
||||
#define DVP_DASM_WIDTH (105) /* r/w - UINT32 */
|
||||
#define DVP_DASM_ACTIVE_ADDRESS (112) /* r/w - UINT32 */
|
||||
|
||||
/* properties available for memory views */
|
||||
#define DVP_MEM_CPUNUM (100) /* r/w - UINT32 */
|
||||
#define DVP_MEM_SPACE (100) /* r/w - address space * */
|
||||
#define DVP_MEM_EXPRESSION (101) /* r/w - const char * */
|
||||
#define DVP_MEM_TRACK_LIVE (102) /* r/w - UINT32 */
|
||||
#define DVP_MEM_SPACENUM (103) /* r/w - UINT32 */
|
||||
@ -73,9 +58,6 @@
|
||||
#define DVP_MEM_WIDTH (111) /* r/w - UINT32 */
|
||||
#define DVP_MEM_NO_TRANSLATION (113) /* r/w - UINT32 */
|
||||
|
||||
/* properties available for textbuffer views */
|
||||
#define DVP_TEXTBUF_LINE_LOCK (100) /* r/w - UINT32 */
|
||||
|
||||
/* attribute bits for debug_view_char.attrib */
|
||||
#define DCA_NORMAL (0x00) /* in Windows: black on white */
|
||||
#define DCA_CHANGED (0x01) /* in Windows: red foreground */
|
||||
@ -101,11 +83,6 @@
|
||||
#define DCH_CTRLLEFT (12) /* ctrl+left */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MACROS
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
@ -115,23 +92,37 @@
|
||||
typedef struct _debug_view debug_view;
|
||||
|
||||
|
||||
/* OSD callback function for a view */
|
||||
typedef void (*debug_view_osd_update_func)(debug_view *view, void *osdprivate);
|
||||
|
||||
|
||||
/* pair of X,Y coordinates for sizing */
|
||||
typedef struct _debug_view_xy debug_view_xy;
|
||||
struct _debug_view_xy
|
||||
{
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
};
|
||||
|
||||
|
||||
/* a single "character" in the debug view has an ASCII value and an attribute byte */
|
||||
typedef struct _debug_view_char debug_view_char;
|
||||
struct _debug_view_char
|
||||
{
|
||||
UINT8 byte;
|
||||
UINT8 attrib;
|
||||
};
|
||||
typedef struct _debug_view_char debug_view_char;
|
||||
|
||||
|
||||
union _debug_property_info
|
||||
/* description of a raw memory space */
|
||||
typedef struct _memory_view_raw memory_view_raw;
|
||||
struct _memory_view_raw
|
||||
{
|
||||
UINT32 i;
|
||||
const char *s;
|
||||
void *p;
|
||||
genf *f;
|
||||
void * base;
|
||||
offs_t length;
|
||||
offs_t offsetxor;
|
||||
UINT8 endianness;
|
||||
};
|
||||
typedef union _debug_property_info debug_property_info;
|
||||
|
||||
|
||||
|
||||
@ -139,90 +130,190 @@ typedef union _debug_property_info debug_property_info;
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* initialization */
|
||||
void debug_view_init(running_machine *machine);
|
||||
void debug_view_exit(running_machine *machine);
|
||||
|
||||
/* view creation/deletion */
|
||||
debug_view * debug_view_alloc(running_machine *machine, int type);
|
||||
void debug_view_free(debug_view *view);
|
||||
/* ----- initialization and cleanup ----- */
|
||||
|
||||
/* property management */
|
||||
void debug_view_get_property(debug_view *view, int property, debug_property_info *value);
|
||||
void debug_view_set_property(debug_view *view, int property, debug_property_info value);
|
||||
|
||||
/* update management */
|
||||
void debug_view_begin_update(debug_view *view);
|
||||
void debug_view_end_update(debug_view *view);
|
||||
void debug_view_update_all(void);
|
||||
void debug_view_update_type(int type);
|
||||
|
||||
/* misc stuff */
|
||||
void debug_disasm_update_all(void);
|
||||
/* initializes the view system */
|
||||
void debug_view_init(running_machine *machine);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE HELPERS
|
||||
***************************************************************************/
|
||||
/* ----- view creation/deletion ----- */
|
||||
|
||||
INLINE UINT32 debug_view_get_property_UINT32(debug_view *view, int property)
|
||||
{
|
||||
debug_property_info value;
|
||||
debug_view_get_property(view, property, &value);
|
||||
return value.i;
|
||||
}
|
||||
/* allocate a new debug view */
|
||||
debug_view *debug_view_alloc(running_machine *machine, int type, debug_view_osd_update_func osdupdate, void *osdprivate);
|
||||
|
||||
INLINE void debug_view_set_property_UINT32(debug_view *view, int property, UINT32 value)
|
||||
{
|
||||
debug_property_info info;
|
||||
info.i = value;
|
||||
debug_view_set_property(view, property, info);
|
||||
}
|
||||
/* free a debug view */
|
||||
void debug_view_free(debug_view *view);
|
||||
|
||||
|
||||
INLINE const char *debug_view_get_property_string(debug_view *view, int property)
|
||||
{
|
||||
debug_property_info value;
|
||||
debug_view_get_property(view, property, &value);
|
||||
return value.s;
|
||||
}
|
||||
|
||||
INLINE void debug_view_set_property_string(debug_view *view, int property, const char *value)
|
||||
{
|
||||
debug_property_info info;
|
||||
info.s = value;
|
||||
debug_view_set_property(view, property, info);
|
||||
}
|
||||
/* ----- update management ----- */
|
||||
|
||||
/* begin a sequence of changes so that only one update occurs */
|
||||
void debug_view_begin_update(debug_view *view);
|
||||
|
||||
/* complete a sequence of changes so that only one update occurs */
|
||||
void debug_view_end_update(debug_view *view);
|
||||
|
||||
/* force all views to refresh */
|
||||
void debug_view_update_all(void);
|
||||
|
||||
/* force all views of a given type to refresh */
|
||||
void debug_view_update_type(int type);
|
||||
|
||||
/* force all disassembly views to refresh */
|
||||
void debug_disasm_update_all(void);
|
||||
|
||||
|
||||
INLINE void *debug_view_get_property_ptr(debug_view *view, int property)
|
||||
{
|
||||
debug_property_info value;
|
||||
debug_view_get_property(view, property, &value);
|
||||
return value.p;
|
||||
}
|
||||
|
||||
INLINE void debug_view_set_property_ptr(debug_view *view, int property, void *value)
|
||||
{
|
||||
debug_property_info info;
|
||||
info.s = value;
|
||||
debug_view_set_property(view, property, info);
|
||||
}
|
||||
/* ----- standard view properties ----- */
|
||||
|
||||
/* return a pointer to a 2-dimentional array of characters that represent the visible area of the view */
|
||||
const debug_view_char *debug_view_get_chars(debug_view *view);
|
||||
|
||||
/* type a character into a view */
|
||||
void debug_view_type_character(debug_view *view, int character);
|
||||
|
||||
|
||||
INLINE genf *debug_view_get_property_fct(debug_view *view, int property)
|
||||
{
|
||||
debug_property_info value;
|
||||
debug_view_get_property(view, property, &value);
|
||||
return value.f;
|
||||
}
|
||||
|
||||
INLINE void debug_view_set_property_fct(debug_view *view, int property, genf *value)
|
||||
{
|
||||
debug_property_info info;
|
||||
info.f = value;
|
||||
debug_view_set_property(view, property, info);
|
||||
}
|
||||
/* ----- standard view sizing ----- */
|
||||
|
||||
/* return the total view size in rows and columns */
|
||||
debug_view_xy debug_view_get_total_size(debug_view *view);
|
||||
|
||||
/* return the visible size in rows and columns */
|
||||
debug_view_xy debug_view_get_visible_size(debug_view *view);
|
||||
|
||||
/* return the top left position of the visible area in rows and columns */
|
||||
debug_view_xy debug_view_get_visible_position(debug_view *view);
|
||||
|
||||
/* set the visible size in rows and columns */
|
||||
void debug_view_set_visible_size(debug_view *view, debug_view_xy size);
|
||||
|
||||
/* set the top left position of the visible area in rows and columns */
|
||||
void debug_view_set_visible_position(debug_view *view, debug_view_xy pos);
|
||||
|
||||
|
||||
|
||||
/* ----- standard view cursor management ----- */
|
||||
|
||||
/* return the current cursor position as a row and column */
|
||||
debug_view_xy debug_view_get_cursor_position(debug_view *view);
|
||||
|
||||
/* return TRUE if a cursor is supported for this view type */
|
||||
int debug_view_get_cursor_supported(debug_view *view);
|
||||
|
||||
/* return TRUE if a cursor is currently visible */
|
||||
int debug_view_get_cursor_visible(debug_view *view);
|
||||
|
||||
/* set the current cursor position as a row and column */
|
||||
void debug_view_set_cursor_position(debug_view *view, debug_view_xy pos);
|
||||
|
||||
/* set the visible state of the cursor */
|
||||
void debug_view_set_cursor_visible(debug_view *view, int visible);
|
||||
|
||||
|
||||
|
||||
/* ----- registers view-specific properties ----- */
|
||||
|
||||
/* return the CPU whose registers are currently displayed */
|
||||
const device_config *registers_view_get_cpu(debug_view *view);
|
||||
|
||||
/* specify the CPU whose registers are to be displayed */
|
||||
void registers_view_set_cpu(debug_view *view, const device_config *device);
|
||||
|
||||
|
||||
|
||||
/* ----- disassembly view-specific properties ----- */
|
||||
|
||||
/* return the address space whose disassembly is being displayed */
|
||||
const address_space *disasm_view_get_address_space(debug_view *view);
|
||||
|
||||
/* return the expression string describing the home address */
|
||||
const char *disasm_view_get_expression(debug_view *view);
|
||||
|
||||
/* return the contents of the right column */
|
||||
disasm_right_column disasm_view_get_right_column(debug_view *view);
|
||||
|
||||
/* return the number of instructions displayed before the home address */
|
||||
UINT32 disasm_view_get_backward_steps(debug_view *view);
|
||||
|
||||
/* return the width in characters of the main disassembly section */
|
||||
UINT32 disasm_view_get_disasm_width(debug_view *view);
|
||||
|
||||
/* return the PC of the currently selected address in the view */
|
||||
offs_t disasm_view_get_selected_address(debug_view *view);
|
||||
|
||||
/* set the address space whose disassembly is being displayed */
|
||||
void disasm_view_set_address_space(debug_view *view, const address_space *space);
|
||||
|
||||
/* set the expression string describing the home address */
|
||||
void disasm_view_set_expression(debug_view *view, const char *expression);
|
||||
|
||||
/* set the contents of the right column */
|
||||
void disasm_view_set_right_column(debug_view *view, disasm_right_column contents);
|
||||
|
||||
/* set the number of instructions displayed before the home address */
|
||||
void disasm_view_set_backward_steps(debug_view *view, UINT32 steps);
|
||||
|
||||
/* set the width in characters of the main disassembly section */
|
||||
void disasm_view_set_disasm_width(debug_view *view, UINT32 width);
|
||||
|
||||
/* set the PC of the currently selected address in the view */
|
||||
void disasm_view_set_selected_address(debug_view *view, offs_t address);
|
||||
|
||||
|
||||
|
||||
/* ----- memory view-specific properties ----- */
|
||||
|
||||
/* return the address space whose memory is being displayed */
|
||||
const address_space *memory_view_get_address_space(debug_view *view);
|
||||
|
||||
/* return a raw description of the memory being displayed */
|
||||
const memory_view_raw *memory_view_get_raw(debug_view *view);
|
||||
|
||||
/* return the expression string describing the home address */
|
||||
const char *memory_view_get_expression(debug_view *view);
|
||||
|
||||
/* return the currently displayed bytes per chunk */
|
||||
UINT8 memory_view_get_bytes_per_chunk(debug_view *view);
|
||||
|
||||
/* return the number of chunks displayed across a row */
|
||||
UINT32 memory_view_get_chunks_per_row(debug_view *view);
|
||||
|
||||
/* return TRUE if the memory view is displayed reverse */
|
||||
UINT8 memory_view_get_reverse(debug_view *view);
|
||||
|
||||
/* return TRUE if the memory view is displaying an ASCII representation */
|
||||
UINT8 memory_view_get_ascii(debug_view *view);
|
||||
|
||||
/* return TRUE if the memory view is displaying physical addresses versus logical addresses */
|
||||
UINT8 memory_view_get_physical(debug_view *view);
|
||||
|
||||
/* set the address space whose memory is being displayed */
|
||||
void memory_view_set_address_space(debug_view *view, const address_space *space);
|
||||
|
||||
/* provide a raw description of the memory to be displayed */
|
||||
void memory_view_set_raw(debug_view *view, const memory_view_raw *raw);
|
||||
|
||||
/* set the expression string describing the home address */
|
||||
void memory_view_set_expression(debug_view *view, const char *expression);
|
||||
|
||||
/* specify the number of bytes displayed per chunk */
|
||||
void memory_view_set_bytes_per_chunk(debug_view *view, UINT8 chunkbytes);
|
||||
|
||||
/* specify the number of chunks displayed across a row */
|
||||
void memory_view_set_chunks_per_row(debug_view *view, UINT32 rowchunks);
|
||||
|
||||
/* specify TRUE if the memory view is displayed reverse */
|
||||
void memory_view_set_reverse(debug_view *view, UINT8 reverse);
|
||||
|
||||
/* specify TRUE if the memory view should display an ASCII representation */
|
||||
void memory_view_set_ascii(debug_view *view, UINT8 ascii);
|
||||
|
||||
/* specify TRUE if the memory view should display physical addresses versus logical addresses */
|
||||
void memory_view_set_physical(debug_view *view, UINT8 physical);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1316,6 +1316,27 @@ UINT64 *_memory_install_device_handler64(const address_space *space, const devic
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MISCELLANEOUS UTILITIES
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
memory_address_physical - return the physical
|
||||
address corresponding to the given logical
|
||||
address
|
||||
-------------------------------------------------*/
|
||||
|
||||
int memory_address_physical(const address_space *space, int intention, offs_t *address)
|
||||
{
|
||||
cpu_class_header *classheader = space->cpu->classtoken;
|
||||
if (classheader->translate != NULL)
|
||||
return (*classheader->translate)(space->cpu, space->spacenum, intention, address);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEBUGGER HELPERS
|
||||
***************************************************************************/
|
||||
@ -1473,24 +1494,36 @@ static void memory_init_spaces(running_machine *machine)
|
||||
if (cputype_get_addrbus_width(cputype, spacenum) > 0)
|
||||
{
|
||||
address_space *space = malloc_or_die(sizeof(*space));
|
||||
int accessorindex;
|
||||
int logbits = cputype_get_logaddr_width(cputype, spacenum);
|
||||
int ashift = cputype_get_addrbus_shift(cputype, spacenum);
|
||||
int abits = cputype_get_addrbus_width(cputype, spacenum);
|
||||
int dbits = cputype_get_databus_width(cputype, spacenum);
|
||||
int endianness = cputype_get_endianness(cputype);
|
||||
int accessorindex = (dbits == 8) ? 0 : (dbits == 16) ? 1 : (dbits == 32) ? 2 : 3;
|
||||
int entrynum;
|
||||
|
||||
/* if logbits is 0, revert to abits */
|
||||
if (logbits == 0)
|
||||
logbits = abits;
|
||||
|
||||
/* determine the address and data bits */
|
||||
memset(space, 0, sizeof(*space));
|
||||
space->machine = machine;
|
||||
space->cpu = machine->cpu[cpunum];
|
||||
space->spacenum = spacenum;
|
||||
space->name = address_space_names[spacenum];
|
||||
space->endianness = cputype_get_endianness(cputype);
|
||||
space->ashift = cputype_get_addrbus_shift(cputype, spacenum);
|
||||
space->abits = cputype_get_addrbus_width(cputype, spacenum);
|
||||
space->dbits = cputype_get_databus_width(cputype, spacenum);
|
||||
space->addrmask = 0xffffffffUL >> (32 - space->abits);
|
||||
space->bytemask = ADDR2BYTE_END(space, space->addrmask);
|
||||
accessorindex = (space->dbits == 8) ? 0 : (space->dbits == 16) ? 1 : (space->dbits == 32) ? 2 : 3;
|
||||
space->accessors = memory_accessors[accessorindex][(space->endianness == CPU_IS_LE) ? 0 : 1];
|
||||
space->map = NULL;
|
||||
space->accessors = memory_accessors[accessorindex][(endianness == CPU_IS_LE) ? 0 : 1];
|
||||
space->addrmask = 0xffffffffUL >> (32 - abits);
|
||||
space->bytemask = (ashift < 0) ? ((space->addrmask << -ashift) | ((1 << -ashift) - 1)) : (space->addrmask >> ashift);
|
||||
space->logaddrmask = 0xffffffffUL >> (32 - logbits);
|
||||
space->logbytemask = (ashift < 0) ? ((space->logaddrmask << -ashift) | ((1 << -ashift) - 1)) : (space->logaddrmask >> ashift);
|
||||
space->spacenum = spacenum;
|
||||
space->endianness = endianness;
|
||||
space->ashift = ashift;
|
||||
space->pageshift = cputype_get_page_shift(cputype, spacenum);
|
||||
space->abits = abits;
|
||||
space->dbits = dbits;
|
||||
space->addrchars = (abits + 3) / 4;
|
||||
space->logaddrchars = (logbits + 3) / 4;
|
||||
space->log_unmap = TRUE;
|
||||
|
||||
/* allocate subtable information; we malloc this manually because it will be realloc'ed */
|
||||
@ -2931,40 +2964,40 @@ static address_map_entry *block_assign_intersecting(address_space *space, offs_t
|
||||
|
||||
static READ8_HANDLER( unmap_read8 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory byte read from %08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset));
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory byte read from %08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset));
|
||||
return space->unmap;
|
||||
}
|
||||
static READ16_HANDLER( unmap_read16 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory word read from %08X & %04X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset*2), mem_mask);
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory word read from %08X & %04X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset*2), mem_mask);
|
||||
return space->unmap;
|
||||
}
|
||||
static READ32_HANDLER( unmap_read32 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory dword read from %08X & %08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset*4), mem_mask);
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory dword read from %08X & %08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset*4), mem_mask);
|
||||
return space->unmap;
|
||||
}
|
||||
static READ64_HANDLER( unmap_read64 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory qword read from %08X & %08X%08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset*8), (int)(mem_mask >> 32), (int)(mem_mask & 0xffffffff));
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory qword read from %08X & %08X%08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset*8), (int)(mem_mask >> 32), (int)(mem_mask & 0xffffffff));
|
||||
return space->unmap;
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( unmap_write8 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory byte write to %08X = %02X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset), data);
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory byte write to %08X = %02X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset), data);
|
||||
}
|
||||
static WRITE16_HANDLER( unmap_write16 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory word write to %08X = %04X & %04X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset*2), data, mem_mask);
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory word write to %08X = %04X & %04X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset*2), data, mem_mask);
|
||||
}
|
||||
static WRITE32_HANDLER( unmap_write32 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory dword write to %08X = %08X & %08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset*4), data, mem_mask);
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory dword write to %08X = %08X & %08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset*4), data, mem_mask);
|
||||
}
|
||||
static WRITE64_HANDLER( unmap_write64 )
|
||||
{
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory qword write to %08X = %08X%08X & %08X%08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, cpu_byte_to_address(space->cpu, space->spacenum, offset*8), (int)(data >> 32), (int)(data & 0xffffffff), (int)(mem_mask >> 32), (int)(mem_mask & 0xffffffff));
|
||||
if (space->log_unmap && !space->debugger_access) logerror("CPU '%s' (PC=%08X): unmapped %s memory qword write to %08X = %08X%08X & %08X%08X\n", space->cpu->tag, cpu_get_pc(space->cpu), space->name, memory_byte_to_address(space, offset*8), (int)(data >> 32), (int)(data & 0xffffffff), (int)(mem_mask >> 32), (int)(mem_mask & 0xffffffff));
|
||||
}
|
||||
|
||||
|
||||
|
@ -280,13 +280,18 @@ struct _address_space
|
||||
direct_read_data direct; /* fast direct-access read info */
|
||||
direct_update_func directupdate; /* fast direct-access update callback */
|
||||
UINT64 unmap; /* unmapped value */
|
||||
offs_t addrmask; /* global address mask */
|
||||
offs_t bytemask; /* byte-converted global address mask */
|
||||
offs_t addrmask; /* physical address mask */
|
||||
offs_t bytemask; /* byte-converted physical address mask */
|
||||
offs_t logaddrmask; /* logical address mask */
|
||||
offs_t logbytemask; /* byte-converted logical address mask */
|
||||
UINT8 spacenum; /* address space index */
|
||||
UINT8 endianness; /* endianness of this space */
|
||||
INT8 ashift; /* address shift */
|
||||
UINT8 pageshift; /* page shift */
|
||||
UINT8 abits; /* address bits */
|
||||
UINT8 dbits; /* data bits */
|
||||
UINT8 addrchars; /* number of characters to use for physical addresses */
|
||||
UINT8 logaddrchars; /* number of characters to use for logical addresses */
|
||||
UINT8 debugger_access; /* treat accesses as coming from the debugger */
|
||||
UINT8 log_unmap; /* log unmapped accesses in this space? */
|
||||
address_table read; /* memory read lookup table */
|
||||
@ -935,6 +940,13 @@ UINT64 *_memory_install_device_handler64(const address_space *space, const devic
|
||||
|
||||
|
||||
|
||||
/* ----- miscellaneous utilities ----- */
|
||||
|
||||
/* return the physical address corresponding to the given logical address */
|
||||
int memory_address_physical(const address_space *space, int intention, offs_t *address);
|
||||
|
||||
|
||||
|
||||
/* ----- debugger helpers ----- */
|
||||
|
||||
/* return a string describing the handler at a particular offset */
|
||||
@ -964,6 +976,54 @@ void memory_dump(running_machine *machine, FILE *file);
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
memory_address_to_byte - convert an address in
|
||||
the specified address space to a byte offset
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t memory_address_to_byte(const address_space *space, offs_t address)
|
||||
{
|
||||
return (space->ashift < 0) ? (address << -space->ashift) : (address >> space->ashift);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
memory_address_to_byte_end - convert an address
|
||||
in the specified address space to a byte
|
||||
offset specifying the last byte covered by
|
||||
the address
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t memory_address_to_byte_end(const address_space *space, offs_t address)
|
||||
{
|
||||
return (space->ashift < 0) ? ((address << -space->ashift) | ((1 << -space->ashift) - 1)) : (address >> space->ashift);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
memory_byte_to_address - convert a byte offset
|
||||
to an address in the specified address space
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t memory_byte_to_address(const address_space *space, offs_t address)
|
||||
{
|
||||
return (space->ashift < 0) ? (address >> -space->ashift) : (address << space->ashift);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
memory_byte_to_address_end - convert a byte
|
||||
offset to an address in the specified address
|
||||
space specifying the last address covered by
|
||||
the byte
|
||||
-------------------------------------------------*/
|
||||
|
||||
INLINE offs_t memory_byte_to_address_end(const address_space *space, offs_t address)
|
||||
{
|
||||
return (space->ashift < 0) ? (address >> -space->ashift) : ((address << space->ashift) | ((1 << space->ashift) - 1));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
memory_read_byte/word/dword/qword - read a
|
||||
value from the specified address space
|
||||
|
@ -97,7 +97,7 @@
|
||||
void osd_init(running_machine *machine);
|
||||
|
||||
|
||||
void osd_wait_for_debugger(running_machine *machine, int firststop);
|
||||
void osd_wait_for_debugger(const device_config *device, int firststop);
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user