Debugger expression and memory access overhaul

- Memory references in expressions no longer default to the console's visible CPU if no device name was specified, except when entered through the console itself. Expressions in view windows now use the context of the currently selected device instead.
- The pcatmem debug command and similar qt mouseover function now produce an error message if the initial address translation fails.

Related internal changes (nw)
- The debugger_cpu class no longer interprets memory accesses. The existing routines have been moved into symbol_table (which used to invoke them as callbacks), and reimplemented in most other places. Thecode duplication is a bit messy, but could be potentially improved in the future with new utility classes.
- The cheat engine no longer needs to hook into the debugger_cpu class or instantiate a dummy instance of it.
- The inclusion of debug/express.h within emu.h has been undone. Some debugging structures now need unique_ptr to wrap the resulting incomplete classes; hopefully the performance impact of this is negligible. Another direct consequence is that the breakpoint, watchpoint and registerpoint classes are no longer inside device_debug and have their own source file.
- The breakpoint list is now a std::multimap, using the addresses as keys to hopefully expedite lookup.
- The visible CPU pointer has been removed from the debugger_cpu class, being now considered a property of the console instead.
- Many minor bits of code have been simplified.
This commit is contained in:
AJR 2020-05-25 11:15:39 -04:00
parent ad7a31ad57
commit 0fa6e7eb86
46 changed files with 1832 additions and 2025 deletions

View File

@ -244,6 +244,8 @@ files {
MAME_DIR .. "src/emu/debug/dvtext.h",
MAME_DIR .. "src/emu/debug/express.cpp",
MAME_DIR .. "src/emu/debug/express.h",
MAME_DIR .. "src/emu/debug/points.cpp",
MAME_DIR .. "src/emu/debug/points.h",
MAME_DIR .. "src/emu/debug/textbuf.cpp",
MAME_DIR .. "src/emu/debug/textbuf.h",
MAME_DIR .. "src/emu/drivers/empty.cpp",

View File

@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles
/*********************************************************************
debugcmd.c
debugcmd.cpp
Debugger command interface engine.
@ -18,6 +18,7 @@
#include "express.h"
#include "debughlp.h"
#include "debugvw.h"
#include "points.h"
#include "natkeyboard.h"
#include "render.h"
#include <cctype>
@ -58,9 +59,9 @@ u64 debugger_commands::cheat_sign_extend(const cheat_system *cheatsys, u64 value
{
switch (cheatsys->width)
{
case 1: value = s8(value); break;
case 2: value = s16(value); break;
case 4: value = s32(value); break;
case 1: value = s8(value); break;
case 2: value = s16(value); break;
case 4: value = s32(value); break;
}
}
return value;
@ -76,10 +77,9 @@ u64 debugger_commands::cheat_byte_swap(const cheat_system *cheatsys, u64 value)
{
switch (cheatsys->width)
{
case 2: value = ((value >> 8) & 0x00ff) | ((value << 8) & 0xff00); break;
case 4: value = ((value >> 24) & 0x000000ff) | ((value >> 8) & 0x0000ff00) | ((value << 8) & 0x00ff0000) | ((value << 24) & 0xff000000); break;
case 8: value = ((value >> 56) & 0x00000000000000ffU) | ((value >> 40) & 0x000000000000ff00U) | ((value >> 24) & 0x0000000000ff0000U) | ((value >> 8) & 0x00000000ff000000U) |
((value << 8) & 0x000000ff00000000U) | ((value << 24) & 0x0000ff0000000000U) | ((value << 40) & 0x00ff000000000000U) | ((value << 56) & 0xff00000000000000U); break;
case 2: value = swapendian_int16(value); break;
case 4: value = swapendian_int32(value); break;
case 8: value = swapendian_int64(value); break;
}
}
return value;
@ -93,7 +93,19 @@ u64 debugger_commands::cheat_byte_swap(const cheat_system *cheatsys, u64 value)
u64 debugger_commands::cheat_read_extended(const cheat_system *cheatsys, address_space &space, offs_t address)
{
return cheat_sign_extend(cheatsys, cheat_byte_swap(cheatsys, m_cpu.read_memory(space, address, cheatsys->width, true)));
address &= space.logaddrmask();
u64 value = space.unmap();
if (space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
{
switch (cheatsys->width)
{
case 1: value = space.read_byte(address); break;
case 2: value = space.read_word_unaligned(address); break;
case 4: value = space.read_dword_unaligned(address); break;
case 8: value = space.read_qword_unaligned(address); break;
}
}
return cheat_sign_extend(cheatsys, cheat_byte_swap(cheatsys, value));
}
debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu, debugger_console& console)
@ -110,6 +122,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
symtable.add("min", 2, 2, std::bind(&debugger_commands::execute_min, this, _1, _2));
symtable.add("max", 2, 2, std::bind(&debugger_commands::execute_max, this, _1, _2));
symtable.add("if", 3, 3, std::bind(&debugger_commands::execute_if, this, _1, _2));
symtable.add("cpunum", std::bind(&debugger_commands::get_cpunum, this));
/* add all single-entry save state globals */
for (int itemnum = 0; itemnum < MAX_GLOBALS; itemnum++)
@ -332,6 +345,17 @@ u64 debugger_commands::execute_if(int params, const u64 *param)
}
//-------------------------------------------------
// get_cpunum - getter callback for the
// 'cpunum' symbol
//-------------------------------------------------
u64 debugger_commands::get_cpunum()
{
execute_interface_iterator iter(m_machine.root_device());
return iter.indexof(m_console.get_visible_cpu()->execute());
}
/***************************************************************************
GLOBAL ACCESSORS
@ -385,7 +409,7 @@ bool debugger_commands::validate_number_parameter(const std::string &param, u64
/* evaluate the expression; success if no error */
try
{
result = parsed_expression(m_cpu.visible_symtable(), param.c_str()).execute();
result = parsed_expression(m_console.visible_symtable(), param.c_str()).execute();
return true;
}
catch (expression_error &error)
@ -436,7 +460,7 @@ bool debugger_commands::validate_cpu_parameter(const char *param, device_t *&res
/* if no parameter, use the visible CPU */
if (param == nullptr)
{
result = m_cpu.get_visible_cpu();
result = m_console.get_visible_cpu();
if (!result)
{
m_console.printf("No valid CPU is currently selected\n");
@ -454,7 +478,7 @@ bool debugger_commands::validate_cpu_parameter(const char *param, device_t *&res
u64 cpunum;
try
{
cpunum = parsed_expression(m_cpu.visible_symtable(), param).execute();
cpunum = parsed_expression(m_console.visible_symtable(), param).execute();
}
catch (expression_error &)
{
@ -743,7 +767,7 @@ void debugger_commands::execute_tracelog(int ref, const std::vector<std::string>
/* then do a printf */
char buffer[1024];
if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
m_cpu.get_visible_cpu()->debug()->trace_printf("%s", buffer);
m_console.get_visible_cpu()->debug()->trace_printf("%s", buffer);
}
@ -759,7 +783,7 @@ void debugger_commands::execute_tracesym(int ref, const std::vector<std::string>
for (int i = 0; i < params.size(); i++)
{
// find this symbol
symbol_entry *sym = m_cpu.visible_symtable().find(params[i].c_str());
symbol_entry *sym = m_console.visible_symtable().find(params[i].c_str());
if (!sym)
{
m_console.printf("Unknown symbol: %s\n", params[i].c_str());
@ -779,7 +803,7 @@ void debugger_commands::execute_tracesym(int ref, const std::vector<std::string>
// then do a printf
char buffer[1024];
if (mini_printf(buffer, format.str().c_str(), params.size(), values))
m_cpu.get_visible_cpu()->debug()->trace_printf("%s", buffer);
m_console.get_visible_cpu()->debug()->trace_printf("%s", buffer);
}
@ -816,7 +840,7 @@ void debugger_commands::execute_step(int ref, const std::vector<std::string> &pa
if (params.size() > 0 && !validate_number_parameter(params[0], steps))
return;
m_cpu.get_visible_cpu()->debug()->single_step(steps);
m_console.get_visible_cpu()->debug()->single_step(steps);
}
@ -831,7 +855,7 @@ void debugger_commands::execute_over(int ref, const std::vector<std::string> &pa
if (params.size() > 0 && !validate_number_parameter(params[0], steps))
return;
m_cpu.get_visible_cpu()->debug()->single_step_over(steps);
m_console.get_visible_cpu()->debug()->single_step_over(steps);
}
@ -841,7 +865,7 @@ void debugger_commands::execute_over(int ref, const std::vector<std::string> &pa
void debugger_commands::execute_out(int ref, const std::vector<std::string> &params)
{
m_cpu.get_visible_cpu()->debug()->single_step_out();
m_console.get_visible_cpu()->debug()->single_step_out();
}
@ -857,7 +881,7 @@ void debugger_commands::execute_go(int ref, const std::vector<std::string> &para
if (params.size() > 0 && !validate_number_parameter(params[0], addr))
return;
m_cpu.get_visible_cpu()->debug()->go(addr);
m_console.get_visible_cpu()->debug()->go(addr);
}
@ -868,7 +892,7 @@ void debugger_commands::execute_go(int ref, const std::vector<std::string> &para
void debugger_commands::execute_go_vblank(int ref, const std::vector<std::string> &params)
{
m_cpu.get_visible_cpu()->debug()->go_vblank();
m_console.get_visible_cpu()->debug()->go_vblank();
}
@ -884,7 +908,7 @@ void debugger_commands::execute_go_interrupt(int ref, const std::vector<std::str
if (params.size() > 0 && !validate_number_parameter(params[0], irqline))
return;
m_cpu.get_visible_cpu()->debug()->go_interrupt(irqline);
m_console.get_visible_cpu()->debug()->go_interrupt(irqline);
}
/*-------------------------------------------------
@ -899,11 +923,11 @@ void debugger_commands::execute_go_exception(int ref, const std::vector<std::str
if (params.size() > 0 && !validate_number_parameter(params[0], exception))
return;
parsed_expression condition(m_cpu.get_visible_cpu()->debug()->symtable());
parsed_expression condition(m_console.visible_symtable());
if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition))
return;
m_cpu.get_visible_cpu()->debug()->go_exception(exception, (condition.is_empty()) ? "1" : condition.original_string());
m_console.get_visible_cpu()->debug()->go_exception(exception, (condition.is_empty()) ? "1" : condition.original_string());
}
@ -919,7 +943,7 @@ void debugger_commands::execute_go_time(int ref, const std::vector<std::string>
if (params.size() > 0 && !validate_number_parameter(params[0], milliseconds))
return;
m_cpu.get_visible_cpu()->debug()->go_milliseconds(milliseconds);
m_console.get_visible_cpu()->debug()->go_milliseconds(milliseconds);
}
@ -929,11 +953,11 @@ void debugger_commands::execute_go_time(int ref, const std::vector<std::string>
-------------------------------------------------*/
void debugger_commands::execute_go_privilege(int ref, const std::vector<std::string> &params)
{
parsed_expression condition(m_cpu.get_visible_cpu()->debug()->symtable());
parsed_expression condition(m_console.visible_symtable());
if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition))
return;
m_cpu.get_visible_cpu()->debug()->go_privilege((condition.is_empty()) ? "1" : condition.original_string());
m_console.get_visible_cpu()->debug()->go_privilege((condition.is_empty()) ? "1" : condition.original_string());
}
/*-------------------------------------------------
@ -942,7 +966,7 @@ void debugger_commands::execute_go_privilege(int ref, const std::vector<std::str
void debugger_commands::execute_next(int ref, const std::vector<std::string> &params)
{
m_cpu.get_visible_cpu()->debug()->go_next_device();
m_console.get_visible_cpu()->debug()->go_next_device();
}
@ -1194,7 +1218,7 @@ void debugger_commands::execute_cpulist(int ref, const std::vector<std::string>
{
device_state_interface *state;
if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE) != nullptr)
m_console.printf("[%s%d] %s\n", &exec.device() == m_cpu.get_visible_cpu() ? "*" : "", index++, exec.device().tag());
m_console.printf("[%s%d] %s\n", &exec.device() == m_console.get_visible_cpu() ? "*" : "", index++, exec.device().tag());
}
}
@ -1425,8 +1449,9 @@ void debugger_commands::execute_bplist(int ref, const std::vector<std::string> &
m_console.printf("Device '%s' breakpoints:\n", device.tag());
/* loop over the breakpoints */
for (const device_debug::breakpoint &bp : device.debug()->breakpoint_list())
for (const auto &bpp : device.debug()->breakpoint_list())
{
debug_breakpoint &bp = *bpp.second;
buffer = string_format("%c%4X @ %0*X", bp.enabled() ? ' ' : 'D', bp.index(), device.debug()->logaddrchars(), bp.address());
if (std::string(bp.condition()).compare("1") != 0)
buffer.append(string_format(" if %s", bp.condition()));
@ -1725,7 +1750,7 @@ void debugger_commands::execute_rplist(int ref, const std::vector<std::string> &
m_console.printf("Device '%s' registerpoints:\n", device.tag());
/* loop over the breakpoints */
for (const device_debug::registerpoint &rp : device.debug()->registerpoint_list())
for (const debug_registerpoint &rp : device.debug()->registerpoint_list())
{
buffer = string_format("%c%4X if %s", rp.enabled() ? ' ' : 'D', rp.index(), rp.condition());
if (rp.action() != nullptr)
@ -2655,7 +2680,6 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa
int cur_data_size;
int data_count = 0;
int found = 0;
int j;
/* validate parameters */
if (!validate_number_parameter(params[0], offset))
@ -2681,7 +2705,7 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa
/* check for a string */
if (pdata[0] == '"' && pdata[pdatalen] == '"')
{
for (j = 1; j < pdatalen; j++)
for (int j = 1; j < pdatalen; j++)
{
data_to_find[data_count] = pdata[j];
data_size[data_count++] = 1;
@ -2709,21 +2733,54 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa
}
/* now search */
device_memory_interface &memory = space->device().memory();
auto dis = space->device().machine().disable_side_effects();
for (u64 i = offset; i <= endoffset; i += data_size[0])
{
int suboffset = 0;
bool match = true;
/* find the entire string */
for (j = 0; j < data_count && match; j++)
for (int j = 0; j < data_count && match; j++)
{
offs_t address = space->byte_to_address(i + suboffset);
switch (data_size[j])
{
case 1: match = (u8(m_cpu.read_byte(*space, space->byte_to_address(i + suboffset), true)) == u8(data_to_find[j])); break;
case 2: match = (u16(m_cpu.read_word(*space, space->byte_to_address(i + suboffset), true)) == u16(data_to_find[j])); break;
case 4: match = (u32(m_cpu.read_dword(*space, space->byte_to_address(i + suboffset), true)) == u32(data_to_find[j])); break;
case 8: match = (u64(m_cpu.read_qword(*space, space->byte_to_address(i + suboffset), true)) == u64(data_to_find[j])); break;
default: /* all other cases are wildcards */ break;
case 1:
address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address))
match = space->read_byte(address) == u8(data_to_find[j]);
else
match = false;
break;
case 2:
address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address))
match = space->read_word_unaligned(address) == u16(data_to_find[j]);
else
match = false;
break;
case 4:
address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address))
match = space->read_dword_unaligned(address) == u32(data_to_find[j]);
else
match = false;
break;
case 8:
address &= space->logaddrmask();
if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address))
match = space->read_qword_unaligned(address) == u64(data_to_find[j]);
else
match = false;
break;
default:
/* all other cases are wildcards */
break;
}
suboffset += data_size[j] & 0x0f;
}
@ -3010,7 +3067,7 @@ void debugger_commands::execute_trackpc(int ref, const std::vector<std::string>
if (turnOn)
{
// Insert current pc
if (m_cpu.get_visible_cpu() == cpu)
if (m_console.get_visible_cpu() == cpu)
{
const offs_t pc = cpu->state().pcbase();
cpu->debug()->set_track_pc_visited(pc);
@ -3083,9 +3140,35 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector<std::string>
if (!validate_cpu_space_parameter((params.size() > 1) ? params[1].c_str() : nullptr, ref, space))
return;
// Translate the address
offs_t a = address & space->logaddrmask();
if (!space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, a))
{
m_console.printf("Bad address\n");
return;
}
// Get the value of memory at the address
const int native_data_width = space->data_width() / 8;
const u64 data = m_cpu.read_memory(*space, space->address_to_byte(address), native_data_width, true);
u64 data = space->unmap();
auto dis = space->device().machine().disable_side_effects();
switch (space->data_width())
{
case 8:
data = space->read_byte(a);
break;
case 16:
data = space->read_word_unaligned(a);
break;
case 32:
data = space->read_dword_unaligned(a);
break;
case 64:
data = space->read_qword_unaligned(a);
break;
}
// Recover the pc & print
const int space_num = (int)ref;

View File

@ -84,6 +84,7 @@ private:
u64 execute_min(int params, const u64 *param);
u64 execute_max(int params, const u64 *param);
u64 execute_if(int params, const u64 *param);
u64 get_cpunum();
u64 global_get(global_entry *global);
void global_set(global_entry *global, u64 value);

View File

@ -35,6 +35,7 @@
debugger_console::debugger_console(running_machine &machine)
: m_machine(machine)
, m_visiblecpu(nullptr)
, m_console_textbuf(nullptr)
, m_errorlog_textbuf(nullptr)
{
@ -60,6 +61,17 @@ debugger_console::debugger_console(running_machine &machine)
/* register our own custom-command help */
register_command("helpcustom", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_console::execute_help_custom, this, _1, _2));
/* first CPU is visible by default */
for (device_t &device : device_iterator(m_machine.root_device()))
{
auto *cpu = dynamic_cast<cpu_device *>(&device);
if (cpu != nullptr)
{
m_visiblecpu = cpu;
break;
}
}
}
@ -121,6 +133,18 @@ void debugger_console::execute_help_custom(int ref, const std::vector<std::strin
}
//-------------------------------------------------
// visible_symtable - return the locally-visible
// symbol table
//-------------------------------------------------
symbol_table &debugger_console::visible_symtable()
{
return m_visiblecpu->debug()->symtable();
}
/*-------------------------------------------------
trim_parameter - executes a
command
@ -334,7 +358,7 @@ CMDERR debugger_console::internal_parse_command(const std::string &original_comm
{
try
{
parsed_expression(m_machine.debugger().cpu().visible_symtable(), command_start).execute();
parsed_expression(visible_symtable(), command_start).execute();
}
catch (expression_error &err)
{

View File

@ -107,6 +107,10 @@ public:
vprintf_wrap(wrapcol, util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...));
}
device_t *get_visible_cpu() { return m_visiblecpu; }
void set_visible_cpu(device_t *visiblecpu) { m_visiblecpu = visiblecpu; }
symbol_table &visible_symtable();
static std::string cmderr_to_string(CMDERR error);
private:
@ -134,6 +138,9 @@ private:
running_machine &m_machine;
// visible CPU device (the one that commands should apply to)
device_t *m_visiblecpu;
text_buffer *m_console_textbuf;
text_buffer *m_errorlog_textbuf;

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,6 @@
#pragma once
#include "express.h"
#include <set>
@ -39,134 +37,13 @@ typedef int (*debug_instruction_hook_func)(device_t &device, offs_t curpc);
class device_debug
{
public:
// breakpoint class
class breakpoint
{
friend class device_debug;
public:
// construction/destruction
breakpoint(
device_debug* debugInterface,
symbol_table &symbols,
int index,
offs_t address,
const char *condition = nullptr,
const char *action = nullptr);
// getters
const device_debug *debugInterface() const { return m_debugInterface; }
int index() const { return m_index; }
bool enabled() const { return m_enabled; }
offs_t address() const { return m_address; }
const char *condition() const { return m_condition.original_string(); }
const char *action() const { return m_action.c_str(); }
// setters
void setEnabled(bool value) { m_enabled = value; }
private:
// internals
bool hit(offs_t pc);
const device_debug * m_debugInterface; // the interface we were created from
int m_index; // user reported index
bool m_enabled; // enabled?
offs_t m_address; // execution address
parsed_expression m_condition; // condition
std::string m_action; // action
};
// watchpoint class
class watchpoint
{
friend class device_debug;
public:
// construction/destruction
watchpoint(
device_debug* debugInterface,
symbol_table &symbols,
int index,
address_space &space,
read_or_write type,
offs_t address,
offs_t length,
const char *condition = nullptr,
const char *action = nullptr);
~watchpoint();
// getters
const device_debug *debugInterface() const { return m_debugInterface; }
address_space &space() const { return m_space; }
int index() const { return m_index; }
read_or_write type() const { return m_type; }
bool enabled() const { return m_enabled; }
offs_t address() const { return m_address; }
offs_t length() const { return m_length; }
const char *condition() const { return m_condition.original_string(); }
const std::string &action() const { return m_action; }
// setters
void setEnabled(bool value);
// internals
bool hit(int type, offs_t address, int size);
private:
device_debug * m_debugInterface; // the interface we were created from
memory_passthrough_handler *m_phr; // passthrough handler reference, read access
memory_passthrough_handler *m_phw; // passthrough handler reference, write access
address_space & m_space; // address space
int m_index; // user reported index
bool m_enabled; // enabled?
read_or_write m_type; // type (read/write)
offs_t m_address; // start address
offs_t m_length; // length of watch area
parsed_expression m_condition; // condition
std::string m_action; // action
int m_notifier; // address map change notifier id
offs_t m_start_address[3]; // the start addresses of the checks to install
offs_t m_end_address[3]; // the end addresses
u64 m_masks[3]; // the access masks
bool m_installing; // prevent recursive multiple installs
void install(read_or_write mode);
void triggered(read_or_write type, offs_t address, u64 data, u64 mem_mask);
};
// registerpoint class
class registerpoint
{
friend class device_debug;
public:
// construction/destruction
registerpoint(symbol_table &symbols, int index, const char *condition, const char *action = nullptr);
// getters
int index() const { return m_index; }
bool enabled() const { return m_enabled; }
const char *condition() const { return m_condition.original_string(); }
const char *action() const { return m_action.c_str(); }
private:
// internals
bool hit();
int m_index; // user reported index
bool m_enabled; // enabled?
parsed_expression m_condition; // condition
std::string m_action; // action
};
public:
// construction/destruction
device_debug(device_t &device);
~device_debug();
// getters
symbol_table &symtable() { return m_symtable; }
symbol_table &symtable() { return *m_symtable; }
// commonly-used pass-throughs
int logaddrchars() const { return (m_memory != nullptr && m_memory->has_space(AS_PROGRAM)) ? m_memory->space(AS_PROGRAM).logaddrchars() : 8; }
@ -213,28 +90,28 @@ public:
}
// breakpoints
const std::forward_list<breakpoint> &breakpoint_list() const { return m_bplist; }
const breakpoint *breakpoint_find(offs_t address) const;
const auto &breakpoint_list() const { return m_bplist; }
const debug_breakpoint *breakpoint_find(offs_t address) const;
int breakpoint_set(offs_t address, const char *condition = nullptr, const char *action = nullptr);
bool breakpoint_clear(int index);
void breakpoint_clear_all();
bool breakpoint_enable(int index, bool enable = true);
void breakpoint_enable_all(bool enable = true);
breakpoint *triggered_breakpoint(void) { breakpoint *ret = m_triggered_breakpoint; m_triggered_breakpoint = nullptr; return ret; }
debug_breakpoint *triggered_breakpoint() { debug_breakpoint *ret = m_triggered_breakpoint; m_triggered_breakpoint = nullptr; return ret; }
// watchpoints
int watchpoint_space_count() const { return m_wplist.size(); }
const std::vector<std::unique_ptr<watchpoint>> &watchpoint_vector(int spacenum) const { return m_wplist[spacenum]; }
const std::vector<std::unique_ptr<debug_watchpoint>> &watchpoint_vector(int spacenum) const { return m_wplist[spacenum]; }
int watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, const char *action);
bool watchpoint_clear(int wpnum);
void watchpoint_clear_all();
bool watchpoint_enable(int index, bool enable = true);
void watchpoint_enable_all(bool enable = true);
void set_triggered_watchpoint(watchpoint *wp) { m_triggered_watchpoint = wp; }
watchpoint *triggered_watchpoint(void) { watchpoint *ret = m_triggered_watchpoint; m_triggered_watchpoint = nullptr; return ret; }
void set_triggered_watchpoint(debug_watchpoint *wp) { m_triggered_watchpoint = wp; }
debug_watchpoint *triggered_watchpoint() { debug_watchpoint *ret = m_triggered_watchpoint; m_triggered_watchpoint = nullptr; return ret; }
// registerpoints
const std::forward_list<registerpoint> &registerpoint_list() const { return m_rplist; }
const std::forward_list<debug_registerpoint> &registerpoint_list() const { return *m_rplist; }
int registerpoint_set(const char *condition, const char *action = nullptr);
bool registerpoint_clear(int index);
void registerpoint_clear_all();
@ -307,7 +184,7 @@ private:
// global state
u32 m_flags; // debugging flags for this CPU
symbol_table m_symtable; // symbol table for expression evaluation
std::unique_ptr<symbol_table> m_symtable; // symbol table for expression evaluation
debug_instruction_hook_func m_instrhook; // per-instruction callback hook
// stepping information
@ -330,12 +207,12 @@ private:
u32 m_pc_history_index; // current history index
// breakpoints and watchpoints
std::forward_list<breakpoint> m_bplist; // list of breakpoints
std::vector<std::vector<std::unique_ptr<watchpoint>>> m_wplist; // watchpoint lists for each address space
std::forward_list<registerpoint> m_rplist; // list of registerpoints
std::multimap<offs_t, std::unique_ptr<debug_breakpoint>> m_bplist; // list of breakpoints
std::vector<std::vector<std::unique_ptr<debug_watchpoint>>> m_wplist; // watchpoint lists for each address space
std::unique_ptr<std::forward_list<debug_registerpoint>> m_rplist; // list of registerpoints
breakpoint * m_triggered_breakpoint; // latest breakpoint that was triggered
watchpoint * m_triggered_watchpoint; // latest watchpoint that was triggered
debug_breakpoint * m_triggered_breakpoint; // latest breakpoint that was triggered
debug_watchpoint * m_triggered_watchpoint; // latest watchpoint that was triggered
// tracing
class tracer
@ -484,14 +361,9 @@ public:
/* flushes all traces; this is useful if a trace is going on when we fatalerror */
void flush_traces();
void configure_memory(symbol_table &table);
/* ----- debugging status & information ----- */
/* return the visible CPU device (the one that commands should apply to) */
device_t *get_visible_cpu() { return m_visiblecpu; }
/* return true if the current execution state is stopped */
bool is_stopped() const { return m_execution_state == exec_state::STOPPED; }
bool is_running() const { return m_execution_state == exec_state::RUNNING; }
@ -502,9 +374,6 @@ public:
/* return the global symbol table */
symbol_table &global_symtable() { return *m_symtable; }
/* return the locally-visible symbol table */
symbol_table &visible_symtable();
/* ----- debugger comment helpers ----- */
@ -515,41 +384,6 @@ public:
bool comment_load(bool is_inline);
/* ----- debugger memory accessors ----- */
/* return a byte from the specified memory space */
u8 read_byte(address_space &space, offs_t address, bool apply_translation);
/* return a word from the specified memory space */
u16 read_word(address_space &space, offs_t address, bool apply_translation);
/* return a dword from the specified memory space */
u32 read_dword(address_space &space, offs_t address, bool apply_translation);
/* return a qword from the specified memory space */
u64 read_qword(address_space &space, offs_t address, bool apply_translation);
/* return 1,2,4 or 8 bytes from the specified memory space */
u64 read_memory(address_space &space, offs_t address, int size, bool apply_translation);
/* write a byte to the specified memory space */
void write_byte(address_space &space, offs_t address, u8 data, bool apply_translation);
/* write a word to the specified memory space */
void write_word(address_space &space, offs_t address, u16 data, bool apply_translation);
/* write a dword to the specified memory space */
void write_dword(address_space &space, offs_t address, u32 data, bool apply_translation);
/* write a qword to the specified memory space */
void write_qword(address_space &space, offs_t address, u64 data, bool apply_translation);
/* write 1,2,4 or 8 bytes to the specified memory space */
void write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation);
/* read 1,2,4 or 8 bytes at the given offset from opcode space */
u64 read_opcode(address_space &space, offs_t offset, int size);
// getters
bool within_instruction_hook() const { return m_within_instruction_hook; }
bool memory_modified() const { return m_memory_modified; }
@ -560,7 +394,6 @@ public:
u32 get_registerpoint_index() { return m_rpindex++; }
// setters
void set_visible_cpu(device_t * visiblecpu) { m_visiblecpu = visiblecpu; }
void set_break_cpu(device_t * breakcpu) { m_breakcpu = breakcpu; }
void set_within_instruction(bool within_instruction) { m_within_instruction_hook = within_instruction; }
void set_memory_modified(bool memory_modified) { m_memory_modified = memory_modified; }
@ -581,26 +414,12 @@ public:
private:
static const size_t NUM_TEMP_VARIABLES;
/* expression handlers */
u64 expression_read_memory(const char *name, expression_space space, u32 address, int size, bool disable_se);
u64 expression_read_program_direct(address_space &space, int opcode, offs_t address, int size);
u64 expression_read_memory_region(const char *rgntag, offs_t address, int size);
void expression_write_memory(const char *name, expression_space space, u32 address, int size, u64 data, bool disable_se);
void expression_write_program_direct(address_space &space, int opcode, offs_t address, int size, u64 data);
void expression_write_memory_region(const char *rgntag, offs_t address, int size, u64 data);
expression_error::error_code expression_validate(const char *name, expression_space space);
device_t* expression_get_device(const char *tag);
// variable getters/setters
u64 get_cpunum();
// internal helpers
void on_vblank(screen_device &device, bool vblank_state);
running_machine& m_machine;
device_t * m_livecpu;
device_t * m_visiblecpu;
device_t * m_breakcpu;
std::unique_ptr<symbol_table> m_symtable; // global symbol table

View File

@ -11,6 +11,7 @@
#include "emu.h"
#include "debugger.h"
#include "dvbpoints.h"
#include "points.h"
#include <algorithm>
#include <iomanip>
@ -18,62 +19,62 @@
// Sorting functors for the qsort function
static bool cIndexAscending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cIndexAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return a->index() < b->index();
}
static bool cIndexDescending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cIndexDescending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return cIndexAscending(b, a);
}
static bool cEnabledAscending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cEnabledAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return !a->enabled() && b->enabled();
}
static bool cEnabledDescending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cEnabledDescending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return cEnabledAscending(b, a);
}
static bool cCpuAscending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cCpuAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return strcmp(a->debugInterface()->device().tag(), b->debugInterface()->device().tag()) < 0;
}
static bool cCpuDescending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cCpuDescending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return cCpuAscending(b, a);
}
static bool cAddressAscending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cAddressAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return a->address() < b->address();
}
static bool cAddressDescending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cAddressDescending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return cAddressAscending(b, a);
}
static bool cConditionAscending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cConditionAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return strcmp(a->condition(), b->condition()) < 0;
}
static bool cConditionDescending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cConditionDescending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return cConditionAscending(b, a);
}
static bool cActionAscending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cActionAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return strcmp(a->action(), b->action()) < 0;
}
static bool cActionDescending(const device_debug::breakpoint *a, const device_debug::breakpoint *b)
static bool cActionDescending(const debug_breakpoint *a, const debug_breakpoint *b)
{
return cActionAscending(b, a);
}
@ -169,7 +170,7 @@ void debug_view_breakpoints::view_click(const int button, const debug_view_xy& p
return;
// Enable / disable
const_cast<device_debug::breakpoint &>(*m_buffer[bpIndex]).setEnabled(!m_buffer[bpIndex]->enabled());
const_cast<debug_breakpoint &>(*m_buffer[bpIndex]).setEnabled(!m_buffer[bpIndex]->enabled());
machine().debug_view().update_all(DVT_DISASSEMBLY);
}
@ -195,8 +196,8 @@ void debug_view_breakpoints::gather_breakpoints()
{
// Collect
device_debug &debugInterface = *source->device()->debug();
for (const device_debug::breakpoint &bp : debugInterface.breakpoint_list())
m_buffer.push_back(&bp);
for (const auto &bpp : debugInterface.breakpoint_list())
m_buffer.push_back(bpp.second.get());
}
// And now for the sort
@ -270,7 +271,7 @@ void debug_view_breakpoints::view_update()
int bpi = row + m_topleft.y - 1;
if ((bpi < m_buffer.size()) && (bpi >= 0))
{
const device_debug::breakpoint *const bp = m_buffer[bpi];
const debug_breakpoint *const bp = m_buffer[bpi];
linebuf.clear();
linebuf.rdbuf()->clear();

View File

@ -48,8 +48,8 @@ private:
// internal state
bool (*m_sortType)(const device_debug::breakpoint *, const device_debug::breakpoint *);
std::vector<const device_debug::breakpoint *> m_buffer;
bool (*m_sortType)(const debug_breakpoint *, const debug_breakpoint *);
std::vector<const debug_breakpoint *> m_buffer;
};
#endif // MAME_EMU_DEBUG_DVBPOINTS_H

View File

@ -360,13 +360,7 @@ void debug_view_disasm::complete_information(const debug_view_disasm_source &sou
dasm.m_is_pc = adr == pc;
dasm.m_is_bp = false;
for(const device_debug::breakpoint &bp : source.device()->debug()->breakpoint_list())
if(adr == (bp.address() & source.m_space.logaddrmask())) {
dasm.m_is_bp = true;
break;
}
dasm.m_is_bp = source.device()->debug()->breakpoint_find(adr) != nullptr;
dasm.m_is_visited = source.device()->debug()->track_pc_visited(adr);
const char *comment = source.device()->debug()->comment_text(adr);

View File

@ -256,6 +256,118 @@ static inline float u64_to_double(u64 value)
return v.f;
}
//-------------------------------------------------
// generate_row - read one row of data and make a
// text representation of the chunks
//-------------------------------------------------
void debug_view_memory::generate_row(debug_view_char *destmin, debug_view_char *destmax, debug_view_char *destrow, offs_t address)
{
// get positional data
const memory_view_pos &posdata = s_memory_pos_table[m_data_format];
int spacing = posdata.m_spacing;
// generate the address
char addrtext[20];
sprintf(addrtext, m_addrformat.c_str(), address);
debug_view_char *dest = destrow + m_section[0].m_pos + 1;
for (int ch = 0; addrtext[ch] != 0 && ch < m_section[0].m_width - 1; ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = addrtext[ch];
// generate the data and the ascii string
std::string chunkascii;
if (m_data_format <= 8)
{
for (int chunknum = 0; chunknum < m_chunks_per_row; chunknum++)
{
u64 chunkdata;
bool ismapped = read_chunk(address, chunknum, chunkdata);
int chunkindex = m_reverse_view ? (m_chunks_per_row - 1 - chunknum) : chunknum;
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
for (int ch = 0; ch < spacing; ch++, dest++)
if (dest >= destmin && dest < destmax)
{
u8 shift = posdata.m_shift[ch];
if (shift < 64)
dest->byte = ismapped ? "0123456789ABCDEF"[(chunkdata >> shift) & 0x0f] : '*';
}
for (int i = 0; i < m_bytes_per_chunk; i++)
{
u8 chval = chunkdata >> (8 * (m_bytes_per_chunk - i - 1));
chunkascii += char((ismapped && isprint(chval)) ? chval : '.');
}
}
}
else
{
for (int chunknum = 0; chunknum < m_chunks_per_row; chunknum++)
{
char valuetext[64];
u64 chunkdata = 0;
extFloat80_t chunkdata80 = { 0, 0 };
bool ismapped;
if (m_data_format != 11)
ismapped = read(m_bytes_per_chunk, address + chunknum * m_steps_per_chunk, chunkdata);
else
ismapped = read(m_bytes_per_chunk, address + chunknum * m_steps_per_chunk, chunkdata80);
if (ismapped)
switch (m_data_format)
{
case 9:
sprintf(valuetext, "%.8g", u32_to_float(u32(chunkdata)));
break;
case 10:
sprintf(valuetext, "%.24g", u64_to_double(chunkdata));
break;
case 11:
float64_t f64 = extF80M_to_f64(&chunkdata80);
sprintf(valuetext, "%.24g", u64_to_double(f64.v));
break;
}
else
{
valuetext[0] = '*';
valuetext[1] = 0;
}
int ch;
int chunkindex = m_reverse_view ? (m_chunks_per_row - 1 - chunknum) : chunknum;
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
// first copy the text
for (ch = 0; (ch < spacing) && (valuetext[ch] != 0); ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = valuetext[ch];
// then fill with spaces
for (; ch < spacing; ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = ' ';
for (int i = 0; i < m_bytes_per_chunk; i++)
{
u8 chval = chunkdata >> (8 * (m_bytes_per_chunk - i - 1));
chunkascii += char((ismapped && isprint(chval)) ? chval : '.');
}
}
}
// generate the ASCII data, but follow the chunks
if (m_section[2].m_width > 0)
{
dest = destrow + m_section[2].m_pos + 1;
for (size_t i = 0; i != chunkascii.size(); i++)
{
if (dest >= destmin && dest < destmax)
dest->byte = chunkascii[i];
dest++;
}
}
}
//-------------------------------------------------
// view_update - update the contents of the
// memory view
@ -269,9 +381,6 @@ void debug_view_memory::view_update()
if (needs_recompute())
recompute();
// get positional data
const memory_view_pos &posdata = s_memory_pos_table[m_data_format];
// loop over visible rows
for (u32 row = 0; row < m_visible.y; row++)
{
@ -281,10 +390,9 @@ void debug_view_memory::view_update()
u32 effrow = m_topleft.y + row;
// reset the line of data; section 1 is normal, others are ancillary, cursor is selected
debug_view_char *dest = destmin;
for (int ch = 0; ch < m_visible.x; ch++, dest++)
u32 effcol = m_topleft.x;
for (debug_view_char *dest = destmin; dest != destmax; dest++, effcol++)
{
u32 effcol = m_topleft.x + ch;
dest->byte = ' ';
dest->attrib = DCA_ANCILLARY;
if (m_section[1].contains(effcol))
@ -300,96 +408,7 @@ void debug_view_memory::view_update()
{
offs_t addrbyte = m_byte_offset + effrow * m_bytes_per_row;
offs_t address = (source.m_space != nullptr) ? source.m_space->byte_to_address(addrbyte) : addrbyte;
char addrtext[20];
// generate the address
sprintf(addrtext, m_addrformat.c_str(), address);
dest = destrow + m_section[0].m_pos + 1;
for (int ch = 0; addrtext[ch] != 0 && ch < m_section[0].m_width - 1; ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = addrtext[ch];
// generate the data and the ascii string
std::string chunkascii;
for (int chunknum = 0; chunknum < m_chunks_per_row; chunknum++)
{
int chunkindex = m_reverse_view ? (m_chunks_per_row - 1 - chunknum) : chunknum;
int spacing = posdata.m_spacing;
if (m_data_format <= 8) {
u64 chunkdata;
bool ismapped = read_chunk(address, chunknum, chunkdata);
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
for (int ch = 0; ch < posdata.m_spacing; ch++, dest++)
if (dest >= destmin && dest < destmax)
{
u8 shift = posdata.m_shift[ch];
if (shift < 64)
dest->byte = ismapped ? "0123456789ABCDEF"[(chunkdata >> shift) & 0x0f] : '*';
}
for (int i=0; i < m_bytes_per_chunk; i++) {
u8 chval = chunkdata >> (8 * (m_bytes_per_chunk - i - 1));
chunkascii += char((ismapped && isprint(chval)) ? chval : '.');
}
}
else {
int ch;
char valuetext[64];
u64 chunkdata = 0;
extFloat80_t chunkdata80 = { 0, 0 };
bool ismapped;
if (m_data_format != 11)
ismapped = read(m_bytes_per_chunk, address + chunknum * m_steps_per_chunk, chunkdata);
else
ismapped = read(m_bytes_per_chunk, address + chunknum * m_steps_per_chunk, chunkdata80);
if (ismapped)
switch (m_data_format)
{
case 9:
sprintf(valuetext, "%.8g", u32_to_float(u32(chunkdata)));
break;
case 10:
sprintf(valuetext, "%.24g", u64_to_double(chunkdata));
break;
case 11:
float64_t f64 = extF80M_to_f64(&chunkdata80);
sprintf(valuetext, "%.24g", u64_to_double(f64.v));
break;
}
else {
valuetext[0] = '*';
valuetext[1] = 0;
}
dest = destrow + m_section[1].m_pos + 1 + chunkindex * spacing;
// first copy the text
for (ch = 0; (ch < spacing) && (valuetext[ch] != 0); ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = valuetext[ch];
// then fill with spaces
for (; ch < spacing; ch++, dest++)
if (dest >= destmin && dest < destmax)
dest->byte = ' ';
for (int i=0; i < m_bytes_per_chunk; i++) {
u8 chval = chunkdata >> (8 * (m_bytes_per_chunk - i - 1));
chunkascii += char((ismapped && isprint(chval)) ? chval : '.');
}
}
}
// generate the ASCII data, but follow the chunks
if (m_section[2].m_width > 0)
{
dest = destrow + m_section[2].m_pos + 1;
for (size_t i = 0; i != chunkascii.size(); i++) {
if (dest >= destmin && dest < destmax)
dest->byte = chunkascii[i];
dest++;
}
}
generate_row(destmin, destmax, destrow, address);
}
}
}
@ -784,15 +803,7 @@ bool debug_view_memory::read(u8 size, offs_t offs, u64 &data)
}
data = ~u64(0);
if (ismapped)
{
switch (size)
{
case 1: data = machine().debugger().cpu().read_byte(*source.m_space, offs, !m_no_translation); break;
case 2: data = machine().debugger().cpu().read_word(*source.m_space, offs, !m_no_translation); break;
case 4: data = machine().debugger().cpu().read_dword(*source.m_space, offs, !m_no_translation); break;
case 8: data = machine().debugger().cpu().read_qword(*source.m_space, offs, !m_no_translation); break;
}
}
data = m_expression.context().read_memory(*source.m_space, offs, size, !m_no_translation);
return ismapped;
}
@ -883,14 +894,7 @@ void debug_view_memory::write(u8 size, offs_t offs, u64 data)
if (source.m_space)
{
auto dis = machine().disable_side_effects();
switch (size)
{
case 1: machine().debugger().cpu().write_byte(*source.m_space, offs, data, !m_no_translation); break;
case 2: machine().debugger().cpu().write_word(*source.m_space, offs, data, !m_no_translation); break;
case 4: machine().debugger().cpu().write_dword(*source.m_space, offs, data, !m_no_translation); break;
case 8: machine().debugger().cpu().write_qword(*source.m_space, offs, data, !m_no_translation); break;
}
m_expression.context().write_memory(*source.m_space, offs, data, size, !m_no_translation);
return;
}

View File

@ -104,6 +104,7 @@ private:
void write(u8 size, offs_t offs, u64 data);
bool read(u8 size, offs_t offs, extFloat80_t &data);
bool read_chunk(offs_t address, int chunknum, u64 &chunkdata);
void generate_row(debug_view_char *destmin, debug_view_char *destmax, debug_view_char *destrow, offs_t address);
// internal state
debug_view_expression m_expression; // expression describing the start address

View File

@ -10,88 +10,89 @@
#include "emu.h"
#include "dvwpoints.h"
#include "points.h"
#include <algorithm>
#include <iomanip>
static bool cIndexAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cIndexAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return a->index() < b->index();
}
static bool cIndexDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cIndexDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cIndexAscending(b, a);
}
static bool cEnabledAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cEnabledAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return !a->enabled() && b->enabled();
}
static bool cEnabledDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cEnabledDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cEnabledAscending(b, a);
}
static bool cCpuAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cCpuAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return strcmp(a->debugInterface()->device().tag(), b->debugInterface()->device().tag()) < 0;
}
static bool cCpuDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cCpuDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cCpuAscending(b, a);
}
static bool cSpaceAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cSpaceAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return strcmp(a->space().name(), b->space().name()) < 0;
}
static bool cSpaceDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cSpaceDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cSpaceAscending(b, a);
}
static bool cAddressAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cAddressAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return a->address() < b->address();
}
static bool cAddressDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cAddressDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cAddressAscending(b, a);
}
static bool cTypeAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cTypeAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return int(a->type()) < int(b->type());
}
static bool cTypeDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cTypeDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cTypeAscending(b, a);
}
static bool cConditionAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cConditionAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return strcmp(a->condition(), b->condition()) < 0;
}
static bool cConditionDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cConditionDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cConditionAscending(b, a);
}
static bool cActionAscending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cActionAscending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return a->action() < b->action();
}
static bool cActionDescending(const device_debug::watchpoint *a, const device_debug::watchpoint *b)
static bool cActionDescending(const debug_watchpoint *a, const debug_watchpoint *b)
{
return cActionAscending(b, a);
}
@ -301,7 +302,7 @@ void debug_view_watchpoints::view_update()
if ((wpi < m_buffer.size()) && wpi >= 0)
{
static char const *const types[] = { "unkn ", "read ", "write", "r/w " };
device_debug::watchpoint *const wp = m_buffer[wpi];
debug_watchpoint *const wp = m_buffer[wpi];
linebuf.clear();
linebuf.rdbuf()->clear();

View File

@ -43,8 +43,8 @@ private:
// internal state
bool (*m_sortType)(const device_debug::watchpoint *, const device_debug::watchpoint *);
std::vector<device_debug::watchpoint *> m_buffer;
bool (*m_sortType)(const debug_watchpoint *, const debug_watchpoint *);
std::vector<debug_watchpoint *> m_buffer;
};
#endif // MAME_EMU_DEBUG_DVWPOINTS_H

View File

@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles
/***************************************************************************
express.c
express.cpp
Generic expressions engine.
@ -358,24 +358,23 @@ u64 function_symbol_entry::execute(int numparams, const u64 *paramlist)
// symbol_table - constructor
//-------------------------------------------------
symbol_table::symbol_table(symbol_table *parent)
: m_parent(parent),
m_memory_valid(nullptr),
m_memory_read(nullptr),
m_memory_write(nullptr)
symbol_table::symbol_table(running_machine &machine, symbol_table *parent, device_t *device)
: m_machine(machine)
, m_parent(parent)
, m_memintf(dynamic_cast<device_memory_interface *>(device))
, m_memory_modified(nullptr)
{
}
//-------------------------------------------------
// add - add a new u64 pointer symbol
// set_memory_modified_func - install notifier
// for when memory is modified in debugger
//-------------------------------------------------
void symbol_table::configure_memory(valid_func valid, read_func read, write_func write)
void symbol_table::set_memory_modified_func(memory_modified_func modified)
{
m_memory_valid = std::move(valid);
m_memory_read = std::move(read);
m_memory_write = std::move(write);
m_memory_modified = std::move(modified);
}
@ -464,6 +463,492 @@ void symbol_table::set_value(const char *symbol, u64 value)
}
//**************************************************************************
// EXPRESSION MEMORY HANDLERS
//**************************************************************************
//-------------------------------------------------
// read_memory - return 1,2,4 or 8 bytes
// from the specified memory space
//-------------------------------------------------
u64 symbol_table::read_memory(address_space &space, offs_t address, int size, bool apply_translation)
{
u64 result = ~u64(0) >> (64 - 8*size);
if (apply_translation)
{
// mask against the logical byte mask
address &= space.logaddrmask();
// translate if necessary; if not mapped, return 0xffffffffffffffff
if (!space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
return result;
}
// otherwise, call the reading function for the translated address
switch (size)
{
case 1: result = space.read_byte(address); break;
case 2: result = space.read_word_unaligned(address); break;
case 4: result = space.read_dword_unaligned(address); break;
case 8: result = space.read_qword_unaligned(address); break;
}
return result;
}
//-------------------------------------------------
// write_memory - write 1,2,4 or 8 bytes to the
// specified memory space
//-------------------------------------------------
void symbol_table::write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation)
{
if (apply_translation)
{
// mask against the logical byte mask
address &= space.logaddrmask();
// translate if necessary; if not mapped, we're done
if (!space.device().memory().translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
return;
}
// otherwise, call the writing function for the translated address
switch (size)
{
case 1: space.write_byte(address, data); break;
case 2: space.write_word_unaligned(address, data); break;
case 4: space.write_dword_unaligned(address, data); break;
case 8: space.write_qword_unaligned(address, data); break;
}
notify_memory_modified();
}
//-------------------------------------------------
// expression_get_device - return a device
// based on a case insensitive tag search
//-------------------------------------------------
device_t *symbol_table::expression_get_device(const char *tag)
{
// convert to lowercase then lookup the name (tags are enforced to be all lower case)
std::string fullname(tag);
strmakelower(fullname);
return m_machine.root_device().subdevice(fullname.c_str());
}
//-------------------------------------------------
// notify_memory_modified - notify that memory
// has been changed
//-------------------------------------------------
void symbol_table::notify_memory_modified()
{
// walk up the table hierarchy to find the owner
for (symbol_table *symtable = this; symtable != nullptr; symtable = symtable->m_parent)
if (symtable->m_memory_modified != nullptr)
m_memory_modified();
}
//-------------------------------------------------
// memory_value - read 1,2,4 or 8 bytes at the
// given offset in the given address space
//-------------------------------------------------
u64 symbol_table::memory_value(const char *name, expression_space spacenum, u32 address, int size, bool disable_se)
{
device_memory_interface *memory = m_memintf;
switch (spacenum)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
case EXPSPACE_IO_LOGICAL:
case EXPSPACE_SPACE3_LOGICAL:
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
{
address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
auto dis = m_machine.disable_side_effects(disable_se);
return read_memory(space, address, size, true);
}
break;
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
case EXPSPACE_SPACE3_PHYSICAL:
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
{
address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
auto dis = m_machine.disable_side_effects(disable_se);
return read_memory(space, address, size, false);
}
break;
case EXPSPACE_RAMWRITE:
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_PROGRAM))
{
auto dis = m_machine.disable_side_effects(disable_se);
return read_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size);
}
break;
case EXPSPACE_OPCODE:
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_OPCODES))
{
auto dis = m_machine.disable_side_effects(disable_se);
return read_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size);
}
break;
case EXPSPACE_REGION:
if (name == nullptr)
break;
return read_memory_region(name, address, size);
default:
break;
}
return 0;
}
//-------------------------------------------------
// read_program_direct - read memory directly
// from an opcode or RAM pointer
//-------------------------------------------------
u64 symbol_table::read_program_direct(address_space &space, int opcode, offs_t address, int size)
{
u8 *base;
// adjust the address into a byte address, but not if being called recursively
if ((opcode & 2) == 0)
address = space.address_to_byte(address);
// call ourself recursively until we are byte-sized
if (size > 1)
{
int halfsize = size / 2;
// read each half, from lower address to upper address
u64 r0 = read_program_direct(space, opcode | 2, address + 0, halfsize);
u64 r1 = read_program_direct(space, opcode | 2, address + halfsize, halfsize);
// assemble based on the target endianness
if (space.endianness() == ENDIANNESS_LITTLE)
return r0 | (r1 << (8 * halfsize));
else
return r1 | (r0 << (8 * halfsize));
}
// handle the byte-sized final requests
else
{
// lowmask specified which address bits are within the databus width
offs_t lowmask = space.data_width() / 8 - 1;
// get the base of memory, aligned to the address minus the lowbits
base = (u8 *)space.get_read_ptr(address & ~lowmask);
// if we have a valid base, return the appropriate byte
if (base != nullptr)
{
if (space.endianness() == ENDIANNESS_LITTLE)
return base[BYTE8_XOR_LE(address) & lowmask];
else
return base[BYTE8_XOR_BE(address) & lowmask];
}
}
return 0;
}
//-------------------------------------------------
// read_memory_region - read memory from a
// memory region
//-------------------------------------------------
u64 symbol_table::read_memory_region(const char *rgntag, offs_t address, int size)
{
memory_region *region = m_machine.root_device().memregion(rgntag);
u64 result = ~u64(0) >> (64 - 8*size);
// make sure we get a valid base before proceeding
if (region != nullptr)
{
// call ourself recursively until we are byte-sized
if (size > 1)
{
int halfsize = size / 2;
u64 r0, r1;
// read each half, from lower address to upper address
r0 = read_memory_region(rgntag, address + 0, halfsize);
r1 = read_memory_region(rgntag, address + halfsize, halfsize);
// assemble based on the target endianness
if (region->endianness() == ENDIANNESS_LITTLE)
result = r0 | (r1 << (8 * halfsize));
else
result = r1 | (r0 << (8 * halfsize));
}
// only process if we're within range
else if (address < region->bytes())
{
// lowmask specified which address bits are within the databus width
u32 lowmask = region->bytewidth() - 1;
u8 *base = region->base() + (address & ~lowmask);
// if we have a valid base, return the appropriate byte
if (region->endianness() == ENDIANNESS_LITTLE)
result = base[BYTE8_XOR_LE(address) & lowmask];
else
result = base[BYTE8_XOR_BE(address) & lowmask];
}
}
return result;
}
//-------------------------------------------------
// set_memory_value - write 1,2,4 or 8 bytes at
// the given offset in the given address space
//-------------------------------------------------
void symbol_table::set_memory_value(const char *name, expression_space spacenum, u32 address, int size, u64 data, bool disable_se)
{
device_memory_interface *memory = m_memintf;
switch (spacenum)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
case EXPSPACE_IO_LOGICAL:
case EXPSPACE_SPACE3_LOGICAL:
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
{
address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
auto dis = m_machine.disable_side_effects(disable_se);
write_memory(space, address, data, size, true);
}
break;
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
case EXPSPACE_SPACE3_PHYSICAL:
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
{
address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
auto dis = m_machine.disable_side_effects(disable_se);
write_memory(space, address, data, size, false);
}
break;
case EXPSPACE_RAMWRITE: {
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_PROGRAM))
{
auto dis = m_machine.disable_side_effects(disable_se);
write_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size, data);
}
break;
}
case EXPSPACE_OPCODE: {
if (name != nullptr)
{
device_t *device = expression_get_device(name);
if (device != nullptr)
device->interface(memory);
}
if (memory != nullptr && memory->has_space(AS_OPCODES))
{
auto dis = m_machine.disable_side_effects(disable_se);
write_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size, data);
}
break;
}
case EXPSPACE_REGION:
if (name == nullptr)
break;
write_memory_region(name, address, size, data);
break;
default:
break;
}
}
//-------------------------------------------------
// write_program_direct - write memory directly
// to an opcode or RAM pointer
//-------------------------------------------------
void symbol_table::write_program_direct(address_space &space, int opcode, offs_t address, int size, u64 data)
{
// adjust the address into a byte address, but not if being called recursively
if ((opcode & 2) == 0)
address = space.address_to_byte(address);
// call ourself recursively until we are byte-sized
if (size > 1)
{
int halfsize = size / 2;
// break apart based on the target endianness
u64 halfmask = ~u64(0) >> (64 - 8 * halfsize);
u64 r0, r1;
if (space.endianness() == ENDIANNESS_LITTLE)
{
r0 = data & halfmask;
r1 = (data >> (8 * halfsize)) & halfmask;
}
else
{
r0 = (data >> (8 * halfsize)) & halfmask;
r1 = data & halfmask;
}
// write each half, from lower address to upper address
write_program_direct(space, opcode | 2, address + 0, halfsize, r0);
write_program_direct(space, opcode | 2, address + halfsize, halfsize, r1);
}
// handle the byte-sized final case
else
{
// lowmask specified which address bits are within the databus width
offs_t lowmask = space.data_width() / 8 - 1;
// get the base of memory, aligned to the address minus the lowbits
u8 *base = (u8 *)space.get_read_ptr(address & ~lowmask);
// if we have a valid base, write the appropriate byte
if (base != nullptr)
{
if (space.endianness() == ENDIANNESS_LITTLE)
base[BYTE8_XOR_LE(address) & lowmask] = data;
else
base[BYTE8_XOR_BE(address) & lowmask] = data;
notify_memory_modified();
}
}
}
//-------------------------------------------------
// write_memory_region - write memory to a
// memory region
//-------------------------------------------------
void symbol_table::write_memory_region(const char *rgntag, offs_t address, int size, u64 data)
{
memory_region *region = m_machine.root_device().memregion(rgntag);
// make sure we get a valid base before proceeding
if (region != nullptr)
{
// call ourself recursively until we are byte-sized
if (size > 1)
{
int halfsize = size / 2;
// break apart based on the target endianness
u64 halfmask = ~u64(0) >> (64 - 8 * halfsize);
u64 r0, r1;
if (region->endianness() == ENDIANNESS_LITTLE)
{
r0 = data & halfmask;
r1 = (data >> (8 * halfsize)) & halfmask;
}
else
{
r0 = (data >> (8 * halfsize)) & halfmask;
r1 = data & halfmask;
}
// write each half, from lower address to upper address
write_memory_region(rgntag, address + 0, halfsize, r0);
write_memory_region(rgntag, address + halfsize, halfsize, r1);
}
// only process if we're within range
else if (address < region->bytes())
{
// lowmask specified which address bits are within the databus width
u32 lowmask = region->bytewidth() - 1;
u8 *base = region->base() + (address & ~lowmask);
// if we have a valid base, set the appropriate byte
if (region->endianness() == ENDIANNESS_LITTLE)
{
base[BYTE8_XOR_LE(address) & lowmask] = data;
}
else
{
base[BYTE8_XOR_BE(address) & lowmask] = data;
}
notify_memory_modified();
}
}
}
//-------------------------------------------------
// memory_valid - return true if the given
// memory name/space/offset combination is valid
@ -471,52 +956,87 @@ void symbol_table::set_value(const char *symbol, u64 value)
expression_error::error_code symbol_table::memory_valid(const char *name, expression_space space)
{
// walk up the table hierarchy to find the owner
for (symbol_table *symtable = this; symtable != nullptr; symtable = symtable->m_parent)
if (symtable->m_memory_valid != nullptr)
device_memory_interface *memory = m_memintf;
switch (space)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
case EXPSPACE_IO_LOGICAL:
case EXPSPACE_SPACE3_LOGICAL:
if (name != nullptr)
{
expression_error::error_code err = symtable->m_memory_valid(name, space);
if (err != expression_error::NO_SUCH_MEMORY_SPACE)
return err;
device_t *device = expression_get_device(name);
if (device == nullptr)
return expression_error::INVALID_MEMORY_NAME;
if (!device->interface(memory))
return expression_error::NO_SUCH_MEMORY_SPACE;
}
return expression_error::NO_SUCH_MEMORY_SPACE;
}
else if (memory == nullptr)
return expression_error::MISSING_MEMORY_NAME;
if (!memory->has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL)))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
//-------------------------------------------------
// memory_value - return a value read from memory
//-------------------------------------------------
u64 symbol_table::memory_value(const char *name, expression_space space, u32 offset, int size, bool disable_se)
{
// walk up the table hierarchy to find the owner
for (symbol_table *symtable = this; symtable != nullptr; symtable = symtable->m_parent)
if (symtable->m_memory_valid != nullptr)
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
case EXPSPACE_SPACE3_PHYSICAL:
if (name)
{
expression_error::error_code err = symtable->m_memory_valid(name, space);
if (err != expression_error::NO_SUCH_MEMORY_SPACE && symtable->m_memory_read != nullptr)
return symtable->m_memory_read(name, space, offset, size, disable_se);
return 0;
device_t *device = expression_get_device(name);
if (device == nullptr)
return expression_error::INVALID_MEMORY_NAME;
if (!device->interface(memory))
return expression_error::NO_SUCH_MEMORY_SPACE;
}
return 0;
}
else if (memory == nullptr)
return expression_error::MISSING_MEMORY_NAME;
if (!memory->has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL)))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
//-------------------------------------------------
// set_memory_value - write a value to memory
//-------------------------------------------------
void symbol_table::set_memory_value(const char *name, expression_space space, u32 offset, int size, u64 value, bool disable_se)
{
// walk up the table hierarchy to find the owner
for (symbol_table *symtable = this; symtable != nullptr; symtable = symtable->m_parent)
if (symtable->m_memory_valid != nullptr)
case EXPSPACE_RAMWRITE:
if (name)
{
expression_error::error_code err = symtable->m_memory_valid(name, space);
if (err != expression_error::NO_SUCH_MEMORY_SPACE && symtable->m_memory_write != nullptr)
symtable->m_memory_write(name, space, offset, size, value, disable_se);
return;
device_t *device = expression_get_device(name);
if (device == nullptr)
return expression_error::INVALID_MEMORY_NAME;
if (!device->interface(memory))
return expression_error::NO_SUCH_MEMORY_SPACE;
}
else if (memory == nullptr)
return expression_error::MISSING_MEMORY_NAME;
if (!memory->has_space(AS_PROGRAM))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
case EXPSPACE_OPCODE:
if (name)
{
device_t *device = expression_get_device(name);
if (device == nullptr)
return expression_error::INVALID_MEMORY_NAME;
if (!device->interface(memory))
return expression_error::NO_SUCH_MEMORY_SPACE;
}
else if (memory == nullptr)
return expression_error::MISSING_MEMORY_NAME;
if (!memory->has_space(AS_OPCODES))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
case EXPSPACE_REGION:
if (!name)
return expression_error::MISSING_MEMORY_NAME;
if (!m_machine.root_device().memregion(name) || !m_machine.root_device().memregion(name)->base())
return expression_error::INVALID_MEMORY_NAME;
break;
default:
return expression_error::NO_SUCH_MEMORY_SPACE;
}
return expression_error::NONE;
}

View File

@ -49,6 +49,8 @@ enum expression_space
// TYPE DEFINITIONS
//**************************************************************************
using offs_t = u32;
// ======================> expression_error
// an expression_error holds an error code and a string offset
@ -154,9 +156,7 @@ public:
typedef std::function<u64(int numparams, const u64 *paramlist)> execute_func;
// callback functions for memory reads/writes
typedef std::function<expression_error::error_code(const char *name, expression_space space)> valid_func;
typedef std::function<u64(const char *name, expression_space space, u32 offset, int size, bool disable_se)> read_func;
typedef std::function<void(const char *name, expression_space space, u32 offset, int size, u64 value, bool disable_se)> write_func;
typedef std::function<void()> memory_modified_func;
enum read_write
{
@ -165,14 +165,14 @@ public:
};
// construction/destruction
symbol_table(symbol_table *parent = nullptr);
symbol_table(running_machine &machine, symbol_table *parent = nullptr, device_t *device = nullptr);
// getters
const std::unordered_map<std::string, std::unique_ptr<symbol_entry>> &entries() const { return m_symlist; }
symbol_table *parent() const { return m_parent; }
// setters
void configure_memory(valid_func valid, read_func read, write_func write);
void set_memory_modified_func(memory_modified_func modified);
// symbol access
void add(const char *name, read_write rw, u64 *ptr = nullptr);
@ -190,14 +190,24 @@ public:
expression_error::error_code memory_valid(const char *name, expression_space space);
u64 memory_value(const char *name, expression_space space, u32 offset, int size, bool disable_se);
void set_memory_value(const char *name, expression_space space, u32 offset, int size, u64 value, bool disable_se);
u64 read_memory(address_space &space, offs_t address, int size, bool apply_translation);
void write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation);
private:
// memory helpers
u64 read_program_direct(address_space &space, int opcode, offs_t address, int size);
u64 read_memory_region(const char *rgntag, offs_t address, int size);
void write_program_direct(address_space &space, int opcode, offs_t address, int size, u64 data);
void write_memory_region(const char *rgntag, offs_t address, int size, u64 data);
device_t *expression_get_device(const char *tag);
void notify_memory_modified();
// internal state
running_machine & m_machine; // reference to the machine
symbol_table * m_parent; // pointer to the parent symbol table
std::unordered_map<std::string,std::unique_ptr<symbol_entry>> m_symlist; // list of symbols
valid_func m_memory_valid; // validation callback
read_func m_memory_read; // read callback
write_func m_memory_write; // write callback
device_memory_interface *const m_memintf; // pointer to the local memory interface (if any)
memory_modified_func m_memory_modified; // memory modified callback
};

441
src/emu/debug/points.cpp Normal file
View File

@ -0,0 +1,441 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
points.cpp
Debugger breakpoints, watchpoints, etc.
***************************************************************************/
#include "emu.h"
#include "points.h"
#include "debugger.h"
#include "debugcon.h"
//**************************************************************************
// DEBUG BREAKPOINT
//**************************************************************************
//-------------------------------------------------
// debug_breakpoint - constructor
//-------------------------------------------------
debug_breakpoint::debug_breakpoint(device_debug* debugInterface,
symbol_table &symbols,
int index,
offs_t address,
const char *condition,
const char *action)
: m_debugInterface(debugInterface),
m_index(index),
m_enabled(true),
m_address(address),
m_condition(symbols, (condition != nullptr) ? condition : "1"),
m_action((action != nullptr) ? action : "")
{
}
//-------------------------------------------------
// hit - detect a hit
//-------------------------------------------------
bool debug_breakpoint::hit(offs_t pc)
{
// don't hit if disabled
if (!m_enabled)
return false;
// must match our address
if (m_address != pc)
return false;
// must satisfy the condition
if (!m_condition.is_empty())
{
try
{
return (m_condition.execute() != 0);
}
catch (expression_error &)
{
return false;
}
}
return true;
}
//**************************************************************************
// DEBUG WATCHPOINT
//**************************************************************************
//-------------------------------------------------
// debug_watchpoint - constructor
//-------------------------------------------------
debug_watchpoint::debug_watchpoint(device_debug* debugInterface,
symbol_table &symbols,
int index,
address_space &space,
read_or_write type,
offs_t address,
offs_t length,
const char *condition,
const char *action)
: m_debugInterface(debugInterface),
m_phr(nullptr),
m_phw(nullptr),
m_space(space),
m_index(index),
m_enabled(true),
m_type(type),
m_address(address & space.addrmask()),
m_length(length),
m_condition(symbols, (condition != nullptr) ? condition : "1"),
m_action((action != nullptr) ? action : ""),
m_installing(false)
{
std::fill(std::begin(m_start_address), std::end(m_start_address), 0);
std::fill(std::begin(m_end_address), std::end(m_end_address), 0);
std::fill(std::begin(m_masks), std::end(m_masks), 0);
int ashift = m_space.addr_shift();
endianness_t endian = m_space.endianness();
offs_t subamask = m_space.alignment() - 1;
offs_t unit_size = ashift <= 0 ? 8 << -ashift : 8 >> ashift;
offs_t start = m_address;
offs_t end = (m_address + m_length - 1) & space.addrmask();
if (end < start)
end = space.addrmask();
offs_t rstart = start & ~subamask;
offs_t rend = end | subamask;
u64 smask, mmask, emask;
smask = mmask = emask = make_bitmask<u64>(m_space.data_width());
if (start != rstart)
{
if (endian == ENDIANNESS_LITTLE)
smask &= ~make_bitmask<u64>((start - rstart) * unit_size);
else
smask &= make_bitmask<u64>((rstart + subamask + 1 - start) * unit_size);
}
if (end != rend)
{
if (endian == ENDIANNESS_LITTLE)
emask &= make_bitmask<u64>((subamask + 1 + end - rend) * unit_size);
else
emask &= ~make_bitmask<u64>((rend - end) * unit_size);
}
if (rend == (rstart | subamask) || smask == emask)
{
m_start_address[0] = rstart;
m_end_address[0] = rend;
m_masks[0] = smask & emask;
}
else
{
int idx = 0;
if (smask != mmask)
{
m_start_address[idx] = rstart;
m_end_address[idx] = rstart | subamask;
m_masks[idx] = smask;
idx++;
rstart += subamask + 1;
}
if (mmask == emask)
{
m_start_address[idx] = rstart;
m_end_address[idx] = rend;
m_masks[idx] = emask;
}
else
{
if (rstart < rend - subamask)
{
m_start_address[idx] = rstart;
m_end_address[idx] = rend - subamask - 1;
m_masks[idx] = mmask;
idx++;
}
m_start_address[idx] = rend - subamask;
m_end_address[idx] = rend;
m_masks[idx] = emask;
}
}
install(read_or_write::READWRITE);
m_notifier = m_space.add_change_notifier([this](read_or_write mode) {
if (m_enabled)
{
install(mode);
}
});
}
debug_watchpoint::~debug_watchpoint()
{
m_space.remove_change_notifier(m_notifier);
if (m_phr)
m_phr->remove();
if (m_phw)
m_phw->remove();
}
void debug_watchpoint::setEnabled(bool value)
{
if (m_enabled != value)
{
m_enabled = value;
if (m_enabled)
install(read_or_write::READWRITE);
else
{
m_installing = true;
if(m_phr)
m_phr->remove();
if(m_phw)
m_phw->remove();
m_installing = false;
}
}
}
void debug_watchpoint::install(read_or_write mode)
{
if (m_installing)
return;
m_installing = true;
if ((u32(mode) & u32(read_or_write::READ)) && m_phr)
m_phr->remove();
if ((u32(mode) & u32(read_or_write::WRITE)) && m_phw)
m_phw->remove();
std::string name = util::string_format("wp@%x", m_address);
switch (m_space.data_width())
{
case 8:
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
m_phr = m_space.install_read_tap(m_start_address[0], m_end_address[0], name,
[this](offs_t offset, u8 &data, u8 mem_mask) {
triggered(read_or_write::READ, offset, data, mem_mask);
}, m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
m_phw = m_space.install_write_tap(m_start_address[0], m_end_address[0], name,
[this](offs_t offset, u8 &data, u8 mem_mask) {
triggered(read_or_write::WRITE, offset, data, mem_mask);
}, m_phw);
break;
case 16:
for (int i=0; i != 3; i++)
if (m_masks[i])
{
u16 mask = m_masks[i];
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
[this, mask](offs_t offset, u16 &data, u16 mem_mask) {
if (mem_mask & mask)
triggered(read_or_write::READ, offset, data, mem_mask);
}, m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
[this, mask](offs_t offset, u16 &data, u16 mem_mask) {
if (mem_mask & mask)
triggered(read_or_write::WRITE, offset, data, mem_mask);
}, m_phw);
}
break;
case 32:
for (int i=0; i != 3; i++)
if (m_masks[i])
{
u32 mask = m_masks[i];
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
[this, mask](offs_t offset, u32 &data, u32 mem_mask) {
if (mem_mask & mask)
triggered(read_or_write::READ, offset, data, mem_mask);
}, m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
[this, mask](offs_t offset, u32 &data, u32 mem_mask) {
if (mem_mask & mask)
triggered(read_or_write::WRITE, offset, data, mem_mask);
}, m_phw);
}
break;
case 64:
for (int i=0; i != 3; i++)
if (m_masks[i])
{
u64 mask = m_masks[i];
if (u32(m_type) & u32(mode) & u32(read_or_write::READ))
m_phr = m_space.install_read_tap(m_start_address[i], m_end_address[i], name,
[this, mask](offs_t offset, u64 &data, u64 mem_mask) {
if (mem_mask & mask)
triggered(read_or_write::READ, offset, data, mem_mask);
}, m_phr);
if (u32(m_type) & u32(mode) & u32(read_or_write::WRITE))
m_phw = m_space.install_write_tap(m_start_address[i], m_end_address[i], name,
[this, mask](offs_t offset, u64 &data, u64 mem_mask) {
if (mem_mask & mask)
triggered(read_or_write::WRITE, offset, data, mem_mask);
}, m_phw);
}
break;
}
m_installing = false;
}
void debug_watchpoint::triggered(read_or_write type, offs_t address, u64 data, u64 mem_mask)
{
running_machine &machine = m_debugInterface->device().machine();
debugger_manager &debug = machine.debugger();
// if we're within debugger code, don't trigger
if (debug.cpu().within_instruction_hook() || machine.side_effects_disabled())
return;
// adjust address, size & value_to_write based on mem_mask.
offs_t size = 0;
int ashift = m_space.addr_shift();
offs_t unit_size = ashift <= 0 ? 8 << -ashift : 8 >> ashift;
u64 unit_mask = make_bitmask<u64>(unit_size);
offs_t address_offset = 0;
if(!mem_mask)
mem_mask = 0xff;
while (!(mem_mask & unit_mask))
{
address_offset++;
data >>= unit_size;
mem_mask >>= unit_size;
}
while (mem_mask)
{
size++;
mem_mask >>= unit_size;
}
data &= make_bitmask<u64>(size * unit_size);
if (m_space.endianness() == ENDIANNESS_LITTLE)
address += address_offset;
else
address += m_space.alignment() - size - address_offset;
// stash the value that will be written or has just been read
debug.cpu().set_wpinfo(address, data);
// protect against recursion
debug.cpu().set_within_instruction(true);
// must satisfy the condition
if (!m_condition.is_empty())
{
try
{
if (!m_condition.execute())
{
debug.cpu().set_within_instruction(false);
return;
}
}
catch (expression_error &)
{
debug.cpu().set_within_instruction(false);
return;
}
}
// halt in the debugger by default
bool was_stopped = debug.cpu().is_stopped();
debug.cpu().set_execution_stopped();
// evaluate the action
if (!m_action.empty())
debug.console().execute_command(m_action, false);
// print a notification, unless the action made us go again
if (debug.cpu().is_stopped())
{
std::string buffer;
buffer = string_format(type == read_or_write::READ ?
"Stopped at watchpoint %X reading %0*X from %08X" :
"Stopped at watchpoint %X writing %0*X to %08X",
m_index,
size * unit_size / 4,
data,
address);
if (debug.cpu().live_cpu() == &m_space.device())
{
offs_t pc = m_space.device().state().pcbase();
debug.console().printf("%s (PC=%X)\n", buffer, pc);
m_debugInterface->compute_debug_flags();
}
else if (!was_stopped)
{
debug.console().printf("%s\n", buffer);
debug.cpu().set_execution_running();
debug.cpu().set_break_cpu(&m_space.device());
}
m_debugInterface->set_triggered_watchpoint(this);
}
debug.cpu().set_within_instruction(false);
}
//**************************************************************************
// DEBUG REGISTERPOINT
//**************************************************************************
//-------------------------------------------------
// debug_registerpoint - constructor
//-------------------------------------------------
debug_registerpoint::debug_registerpoint(symbol_table &symbols, int index, const char *condition, const char *action)
: m_index(index),
m_enabled(true),
m_condition(symbols, (condition != nullptr) ? condition : "1"),
m_action((action != nullptr) ? action : "")
{
}
//-------------------------------------------------
// hit - detect a hit
//-------------------------------------------------
bool debug_registerpoint::hit()
{
// don't hit if disabled
if (!m_enabled)
return false;
// must satisfy the condition
if (!m_condition.is_empty())
{
try
{
return (m_condition.execute() != 0);
}
catch (expression_error &)
{
return false;
}
}
return true;
}

149
src/emu/debug/points.h Normal file
View File

@ -0,0 +1,149 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
points.h
Debugger breakpoints, watchpoints, etc.
***************************************************************************/
#ifndef MAME_EMU_DEBUG_POINTS_H
#define MAME_EMU_DEBUG_POINTS_H
#pragma once
#include "debugcpu.h"
#include "express.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> debug_breakpoint
class debug_breakpoint
{
friend class device_debug;
public:
// construction/destruction
debug_breakpoint(
device_debug* debugInterface,
symbol_table &symbols,
int index,
offs_t address,
const char *condition = nullptr,
const char *action = nullptr);
// getters
const device_debug *debugInterface() const { return m_debugInterface; }
int index() const { return m_index; }
bool enabled() const { return m_enabled; }
offs_t address() const { return m_address; }
const char *condition() const { return m_condition.original_string(); }
const char *action() const { return m_action.c_str(); }
// setters
void setEnabled(bool value) { m_enabled = value; }
private:
// internals
bool hit(offs_t pc);
const device_debug * m_debugInterface; // the interface we were created from
int m_index; // user reported index
bool m_enabled; // enabled?
offs_t m_address; // execution address
parsed_expression m_condition; // condition
std::string m_action; // action
};
// ======================> debug_watchpoint
class debug_watchpoint
{
friend class device_debug;
public:
// construction/destruction
debug_watchpoint(
device_debug* debugInterface,
symbol_table &symbols,
int index,
address_space &space,
read_or_write type,
offs_t address,
offs_t length,
const char *condition = nullptr,
const char *action = nullptr);
~debug_watchpoint();
// getters
const device_debug *debugInterface() const { return m_debugInterface; }
address_space &space() const { return m_space; }
int index() const { return m_index; }
read_or_write type() const { return m_type; }
bool enabled() const { return m_enabled; }
offs_t address() const { return m_address; }
offs_t length() const { return m_length; }
const char *condition() const { return m_condition.original_string(); }
const std::string &action() const { return m_action; }
// setters
void setEnabled(bool value);
// internals
bool hit(int type, offs_t address, int size);
private:
void install(read_or_write mode);
void triggered(read_or_write type, offs_t address, u64 data, u64 mem_mask);
device_debug * m_debugInterface; // the interface we were created from
memory_passthrough_handler *m_phr; // passthrough handler reference, read access
memory_passthrough_handler *m_phw; // passthrough handler reference, write access
address_space & m_space; // address space
int m_index; // user reported index
bool m_enabled; // enabled?
read_or_write m_type; // type (read/write)
offs_t m_address; // start address
offs_t m_length; // length of watch area
parsed_expression m_condition; // condition
std::string m_action; // action
int m_notifier; // address map change notifier id
offs_t m_start_address[3]; // the start addresses of the checks to install
offs_t m_end_address[3]; // the end addresses
u64 m_masks[3]; // the access masks
bool m_installing; // prevent recursive multiple installs
};
// ======================> debug_registerpoint
class debug_registerpoint
{
friend class device_debug;
public:
// construction/destruction
debug_registerpoint(symbol_table &symbols, int index, const char *condition, const char *action = nullptr);
// getters
int index() const { return m_index; }
bool enabled() const { return m_enabled; }
const char *condition() const { return m_condition.original_string(); }
const char *action() const { return m_action.c_str(); }
private:
// internals
bool hit();
int m_index; // user reported index
bool m_enabled; // enabled?
parsed_expression m_condition; // condition
std::string m_action; // action
};
#endif // MAME_EMU_DEBUG_POINTS_H

View File

@ -31,7 +31,7 @@ static bool g_atexit_registered = false;
void debugger_manager::debug_break()
{
m_cpu->get_visible_cpu()->debug()->halt_on_next_instruction("Internal breakpoint\n");
m_console->get_visible_cpu()->debug()->halt_on_next_instruction("Internal breakpoint\n");
}

View File

@ -96,6 +96,11 @@ class debug_view_manager;
class parsed_expression;
class symbol_table;
// declared in debug/points.h
class debug_breakpoint;
class debug_watchpoint;
class debug_registerpoint;
// declared in debugger.h
class debugger_manager;

View File

@ -79,9 +79,7 @@
#include "ui/ui.h"
#include "ui/menu.h"
#include "debugger.h"
#include "emuopts.h"
#include "debug/debugcpu.h"
#include <cstring>
#include <iterator>
@ -679,7 +677,7 @@ void cheat_script::script_entry::output_argument::save(emu_file &cheatfile) cons
cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, std::string const &filename, util::xml::data_node const &cheatnode)
: m_manager(manager)
, m_symbols(&globaltable)
, m_symbols(manager.machine(), &globaltable)
, m_state(SCRIPT_STATE_OFF)
, m_numtemp(DEFAULT_TEMP_VARIABLES)
, m_argindex(0)
@ -1058,7 +1056,7 @@ constexpr int cheat_manager::CHEAT_VERSION;
cheat_manager::cheat_manager(running_machine &machine)
: m_machine(machine)
, m_disabled(true)
, m_symtable()
, m_symtable(machine)
{
// if the cheat engine is disabled, we're done
if (!machine.options().cheat())
@ -1081,19 +1079,6 @@ cheat_manager::cheat_manager(running_machine &machine)
m_symtable.add("frombcd", 1, 1, execute_frombcd);
m_symtable.add("tobcd", 1, 1, execute_tobcd);
// we rely on the debugger expression callbacks; if the debugger isn't
// enabled, we must jumpstart them manually
if ((machine.debug_flags & DEBUG_FLAG_ENABLED) == 0)
{
m_cpu = std::make_unique<debugger_cpu>(machine);
m_cpu->configure_memory(m_symtable);
}
else
{
// configure for memory access (shared with debugger)
machine.debugger().cpu().configure_memory(m_symtable);
}
// load the cheats
reload();
}

View File

@ -14,7 +14,6 @@
#pragma once
#include "debug/express.h"
#include "debug/debugcpu.h"
#include "ui/text.h"
#include "xmlfile.h"
@ -345,7 +344,6 @@ private:
int8_t m_lastline; // last line used for output
bool m_disabled; // true if the cheat engine is disabled
symbol_table m_symtable; // global symbol table
std::unique_ptr<debugger_cpu> m_cpu; // debugger interface for cpus/memory
// constants
static constexpr int CHEAT_VERSION = 1;

View File

@ -14,6 +14,7 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/points.h"
#include "debug/textbuf.h"
#include "drivenum.h"
#include "emuopts.h"
@ -1577,8 +1578,8 @@ void lua_engine::initialize()
debugger_type.set("consolelog", sol::property([](debugger_manager &debug) { return wrap_textbuf(debug.console().get_console_textbuf()); }));
debugger_type.set("errorlog", sol::property([](debugger_manager &debug) { return wrap_textbuf(debug.console().get_errorlog_textbuf()); }));
debugger_type.set("visible_cpu", sol::property(
[](debugger_manager &debug) { debug.cpu().get_visible_cpu(); },
[](debugger_manager &debug, device_t &dev) { debug.cpu().set_visible_cpu(&dev); }));
[](debugger_manager &debug) { debug.console().get_visible_cpu(); },
[](debugger_manager &debug, device_t &dev) { debug.console().set_visible_cpu(&dev); }));
debugger_type.set("execution_state", sol::property(
[](debugger_manager &debug) {
return debug.cpu().is_stopped() ? "stop" : "run";
@ -1616,7 +1617,7 @@ void lua_engine::initialize()
* debug:bpset(addr, [opt] cond, [opt] act) - set breakpoint on addr, cond and act are debugger
* expressions. returns breakpoint index
* debug:bpclr(idx) - clear break
* debug:bplist()[] - table of breakpoints (k=index, v=device_debug::breakpoint)
* debug:bplist()[] - table of breakpoints (k=index, v=debug_breakpoint)
* debug:wpset(space, type, addr, len, [opt] cond, [opt] act) - set watchpoint, cond and act
* are debugger expressions.
* returns watchpoint index
@ -1636,8 +1637,9 @@ void lua_engine::initialize()
device_debug_type.set("bpclr", &device_debug::breakpoint_clear);
device_debug_type.set("bplist", [this](device_debug &dev) {
sol::table table = sol().create_table();
for(const device_debug::breakpoint &bpt : dev.breakpoint_list())
for(const auto &bpp : dev.breakpoint_list())
{
const debug_breakpoint &bpt = *bpp.second;
sol::table bp = sol().create_table();
bp["enabled"] = bpt.enabled();
bp["address"] = bpt.address();

View File

@ -682,7 +682,6 @@ St. Instr. Comment
/* jamtable disassembler */
void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint32_t size) // 0xff000080 == fff00080
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
offs_t addr = (offs_t)address;
if (!space.device().memory().translate(space.spacenum(), TRANSLATE_READ_DEBUG, addr))
@ -694,11 +693,11 @@ void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint
{
offs_t base = addr;
uint32_t opcode = cpu.read_byte(space, addr, true);
uint32_t opcode = space.read_byte(addr);
addr++;
uint32_t op1 = cpu.read_dword(space, addr, true);
uint32_t op1 = space.read_dword_unaligned(addr);
addr += 4;
uint32_t op2 = cpu.read_dword(space, addr, true);
uint32_t op2 = space.read_dword_unaligned(addr);
addr += 4;
char sop1[16];

View File

@ -1581,7 +1581,6 @@ void konamim2_state::dump_task_command(int ref, const std::vector<std::string> &
m2ptr pt_UserData; /* user-private data */
};
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_ppc1->space();
uint64_t addr;
@ -1603,14 +1602,14 @@ void konamim2_state::dump_task_command(int ref, const std::vector<std::string> &
Task task;
task.t.pn_Next = cpu.read_dword(space, address + offsetof(ItemNode, pn_Next), true);
task.t.pn_Prev = cpu.read_dword(space, address + offsetof(ItemNode, pn_Prev), true);
task.t.n_SubsysType = cpu.read_byte(space, address + offsetof(ItemNode, n_SubsysType), true);
task.t.n_Type = cpu.read_byte(space, address + offsetof(ItemNode, n_Type), true);
task.t.n_Priority = cpu.read_byte(space, address + offsetof(ItemNode, n_Priority), true);
task.t.n_Flags = cpu.read_byte(space, address + offsetof(ItemNode, n_Flags), true);
task.t.n_Size = cpu.read_dword(space, address + offsetof(ItemNode, n_Size), true);
task.t.pn_Name = cpu.read_dword(space, address + offsetof(ItemNode, pn_Name), true);
task.t.pn_Next = space.read_dword(address + offsetof(ItemNode, pn_Next));
task.t.pn_Prev = space.read_dword(address + offsetof(ItemNode, pn_Prev));
task.t.n_SubsysType = space.read_byte(address + offsetof(ItemNode, n_SubsysType));
task.t.n_Type = space.read_byte(address + offsetof(ItemNode, n_Type));
task.t.n_Priority = space.read_byte(address + offsetof(ItemNode, n_Priority));
task.t.n_Flags = space.read_byte(address + offsetof(ItemNode, n_Flags));
task.t.n_Size = space.read_dword(address + offsetof(ItemNode, n_Size));
task.t.pn_Name = space.read_dword(address + offsetof(ItemNode, pn_Name));
char name[128];
char *ptr = name;
@ -1618,31 +1617,31 @@ void konamim2_state::dump_task_command(int ref, const std::vector<std::string> &
do
{
*ptr = cpu.read_byte(space, nameptr++, true);
*ptr = space.read_byte(nameptr++);
} while (*ptr++ != 0);
task.t.n_Version = cpu.read_byte(space, address + offsetof(ItemNode, n_Version), true);
task.t.n_Revision = cpu.read_byte(space, address + offsetof(ItemNode, n_Revision), true);
task.t.n_Reserved0 = cpu.read_byte(space, address + offsetof(ItemNode, n_Reserved0), true);
task.t.n_ItemFlags = cpu.read_byte(space, address + offsetof(ItemNode, n_ItemFlags), true);
task.t.n_Item = cpu.read_dword(space, address + offsetof(ItemNode, n_Item), true);
task.t.n_Owner = cpu.read_dword(space, address + offsetof(ItemNode, n_Owner), true);
task.t.pn_Reserved1 = cpu.read_dword(space, address + offsetof(ItemNode, pn_Reserved1), true);
task.t.n_Version = space.read_byte(address + offsetof(ItemNode, n_Version));
task.t.n_Revision = space.read_byte(address + offsetof(ItemNode, n_Revision));
task.t.n_Reserved0 = space.read_byte(address + offsetof(ItemNode, n_Reserved0));
task.t.n_ItemFlags = space.read_byte(address + offsetof(ItemNode, n_ItemFlags));
task.t.n_Item = space.read_dword(address + offsetof(ItemNode, n_Item));
task.t.n_Owner = space.read_dword(address + offsetof(ItemNode, n_Owner));
task.t.pn_Reserved1 = space.read_dword(address + offsetof(ItemNode, pn_Reserved1));
task.pt_ThreadTask = cpu.read_dword(space, address + offsetof(Task, pt_ThreadTask), true);
task.t_WaitBits = cpu.read_dword(space, address + offsetof(Task, t_WaitBits), true);
task.t_SigBits = cpu.read_dword(space, address + offsetof(Task, t_SigBits), true);
task.t_AllocatedSigs = cpu.read_dword(space, address + offsetof(Task, t_AllocatedSigs), true);
task.pt_StackBase = cpu.read_dword(space, address + offsetof(Task, pt_StackBase), true);
task.t_StackSize = cpu.read_dword(space, address + offsetof(Task, t_StackSize), true);
task.t_MaxUSecs = cpu.read_dword(space, address + offsetof(Task, t_MaxUSecs), true);
task.t_ElapsedTime.tt_Hi = cpu.read_dword(space, address + offsetof(Task, t_ElapsedTime)+0, true);
task.t_ElapsedTime.tt_Lo = cpu.read_dword(space, address + offsetof(Task, t_ElapsedTime)+4, true);
task.t_NumTaskLaunch = cpu.read_dword(space, address + offsetof(Task, t_NumTaskLaunch), true);
task.t_Flags = cpu.read_dword(space, address + offsetof(Task, t_Flags), true);
task.t_Module = cpu.read_dword(space, address + offsetof(Task, t_Module), true);
task.t_DefaultMsgPort = cpu.read_dword(space, address + offsetof(Task, t_DefaultMsgPort), true);
task.pt_UserData = cpu.read_dword(space, address + offsetof(Task, pt_UserData), true);
task.pt_ThreadTask = space.read_dword(address + offsetof(Task, pt_ThreadTask));
task.t_WaitBits = space.read_dword(address + offsetof(Task, t_WaitBits));
task.t_SigBits = space.read_dword(address + offsetof(Task, t_SigBits));
task.t_AllocatedSigs = space.read_dword(address + offsetof(Task, t_AllocatedSigs));
task.pt_StackBase = space.read_dword(address + offsetof(Task, pt_StackBase));
task.t_StackSize = space.read_dword(address + offsetof(Task, t_StackSize));
task.t_MaxUSecs = space.read_dword(address + offsetof(Task, t_MaxUSecs));
task.t_ElapsedTime.tt_Hi = space.read_dword(address + offsetof(Task, t_ElapsedTime)+0);
task.t_ElapsedTime.tt_Lo = space.read_dword(address + offsetof(Task, t_ElapsedTime)+4);
task.t_NumTaskLaunch = space.read_dword(address + offsetof(Task, t_NumTaskLaunch));
task.t_Flags = space.read_dword(address + offsetof(Task, t_Flags));
task.t_Module = space.read_dword(address + offsetof(Task, t_Module));
task.t_DefaultMsgPort = space.read_dword(address + offsetof(Task, t_DefaultMsgPort));
task.pt_UserData = space.read_dword(address + offsetof(Task, pt_UserData));
// m2ptr pt_ThreadTask; /* I am a thread of what task? */
// uint32_t t_WaitBits; /* signals being waited for */

View File

@ -883,7 +883,7 @@ static void execute_fdeliminate(running_machine &machine, int ref, int params, c
static void execute_fdunlock(running_machine &machine, int ref, int params, const char **param)
{
device_t *cpu = machine.debugger().cpu().get_visible_cpu();
device_t *cpu = machine.debugger().console().get_visible_cpu();
/* support 0 or 1 parameters */
uint64_t offset;
@ -920,7 +920,7 @@ static void execute_fdunlock(running_machine &machine, int ref, int params, cons
static void execute_fdignore(running_machine &machine, int ref, int params, const char **param)
{
device_t *cpu = machine.debugger().cpu().get_visible_cpu();
device_t *cpu = machine.debugger().console().get_visible_cpu();
/* support 0 or 1 parameters */
if (params == 1 && strcmp(param[0], "all") == 0)
@ -944,7 +944,7 @@ static void execute_fdignore(running_machine &machine, int ref, int params, cons
/* if no parameter given, implicitly run as well */
if (params == 0)
machine.debugger().cpu().get_visible_cpu()->debug()->go();
machine.debugger().console().get_visible_cpu()->debug()->go();
}
@ -1026,7 +1026,7 @@ static void execute_fdstate(running_machine &machine, int ref, int params, const
static void execute_fdpc(running_machine &machine, int ref, int params, const char **param)
{
device_t *cpu = machine.debugger().cpu().get_visible_cpu();
device_t *cpu = machine.debugger().console().get_visible_cpu();
/* support 0 or 1 parameters */
uint64_t newpc = 0;
@ -1048,7 +1048,7 @@ static void execute_fdpc(running_machine &machine, int ref, int params, const ch
static void execute_fdsearch(running_machine &machine, int ref, int params, const char **param)
{
address_space &space = machine->debugger().cpu().get_visible_cpu()->memory().space(AS_PROGRAM);
address_space &space = machine->debugger().console().get_visible_cpu()->memory().space(AS_PROGRAM);
int pc = space.device().state().pc();
int length, first = true;
uint8_t instrdata[2];
@ -1174,7 +1174,7 @@ static void execute_fdsearch(running_machine &machine, int ref, int params, cons
static void execute_fddasm(running_machine &machine, int ref, int params, const char **param)
{
address_space &space = machine->debugger().cpu().get_visible_cpu()->memory().space(AS_PROGRAM);
address_space &space = machine->debugger().console().get_visible_cpu()->memory().space(AS_PROGRAM);
int origstate = fd1094_set_state(keyregion, -1);
const char *filename;
int skipped = false;

View File

@ -83,7 +83,6 @@ void xbox_base_state::find_debug_params()
void xbox_base_state::dump_string_command(int ref, const std::vector<std::string> &params)
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr;
@ -101,11 +100,10 @@ void xbox_base_state::dump_string_command(int ref, const std::vector<std::string
con.printf("Address is unmapped.\n");
return;
}
address = (offs_t)addr;
uint32_t length = cpu.read_word(space, address, true);
uint32_t maximumlength = cpu.read_word(space, address + 2, true);
offs_t buffer = cpu.read_dword(space, address + 4, true);
uint32_t length = space.read_word_unaligned(address);
uint32_t maximumlength = space.read_word_unaligned(address + 2);
offs_t buffer = space.read_dword_unaligned(address + 4);
con.printf("Length %d word\n", length);
con.printf("MaximumLength %d word\n", maximumlength);
con.printf("Buffer %08X byte* ", buffer);
@ -114,17 +112,19 @@ void xbox_base_state::dump_string_command(int ref, const std::vector<std::string
if (length > 256)
length = 256;
for (int a = 0; a < length; a++)
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, buffer))
{
uint8_t c = cpu.read_byte(space, buffer + a, true);
con.printf("%c", c);
for (int a = 0; a < length; a++)
{
uint8_t c = space.read_byte(buffer + a);
con.printf("%c", c);
}
}
con.printf("\n");
}
void xbox_base_state::dump_process_command(int ref, const std::vector<std::string> &params)
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr;
@ -142,21 +142,19 @@ void xbox_base_state::dump_process_command(int ref, const std::vector<std::strin
con.printf("Address is unmapped.\n");
return;
}
address = (offs_t)addr;
con.printf("ReadyListHead {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address, true), cpu.read_dword(space, address + 4, true));
con.printf("ThreadListHead {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 8, true), cpu.read_dword(space, address + 12, true));
con.printf("StackCount %d dword\n", cpu.read_dword(space, address + 16, true));
con.printf("ThreadQuantum %d dword\n", cpu.read_dword(space, address + 20, true));
con.printf("BasePriority %d byte\n", cpu.read_byte(space, address + 24, true));
con.printf("DisableBoost %d byte\n", cpu.read_byte(space, address + 25, true));
con.printf("DisableQuantum %d byte\n", cpu.read_byte(space, address + 26, true));
con.printf("_padding %d byte\n", cpu.read_byte(space, address + 27, true));
con.printf("ReadyListHead {%08X,%08X} _LIST_ENTRY\n", space.read_dword(address), space.read_dword_unaligned(address + 4));
con.printf("ThreadListHead {%08X,%08X} _LIST_ENTRY\n", space.read_dword(address + 8), space.read_dword_unaligned(address + 12));
con.printf("StackCount %d dword\n", space.read_dword_unaligned(address + 16));
con.printf("ThreadQuantum %d dword\n", space.read_dword_unaligned(address + 20));
con.printf("BasePriority %d byte\n", space.read_byte(address + 24));
con.printf("DisableBoost %d byte\n", space.read_byte(address + 25));
con.printf("DisableQuantum %d byte\n", space.read_byte(address + 26));
con.printf("_padding %d byte\n", space.read_byte(address + 27));
}
void xbox_base_state::dump_list_command(int ref, const std::vector<std::string> &params)
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr;
@ -184,7 +182,6 @@ void xbox_base_state::dump_list_command(int ref, const std::vector<std::string>
con.printf("Address is unmapped.\n");
return;
}
address = (offs_t)addr;
if (params.size() >= 3)
con.printf("Entry Object\n");
else
@ -198,7 +195,7 @@ void xbox_base_state::dump_list_command(int ref, const std::vector<std::string>
else
con.printf("%08X\n", (uint32_t)addr);
old = addr;
addr = cpu.read_dword(space, address, true);
addr = space.read_dword_unaligned(address);
if (addr == start)
break;
if (addr == old)
@ -206,13 +203,11 @@ void xbox_base_state::dump_list_command(int ref, const std::vector<std::string>
address = (offs_t)addr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address))
break;
address = (offs_t)addr;
}
}
void xbox_base_state::dump_dpc_command(int ref, const std::vector<std::string> &params)
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr;
@ -230,20 +225,18 @@ void xbox_base_state::dump_dpc_command(int ref, const std::vector<std::string> &
con.printf("Address is unmapped.\n");
return;
}
address = (offs_t)addr;
con.printf("Type %d word\n", cpu.read_word(space, address, true));
con.printf("Inserted %d byte\n", cpu.read_byte(space, address + 2, true));
con.printf("Padding %d byte\n", cpu.read_byte(space, address + 3, true));
con.printf("DpcListEntry {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 4, true), cpu.read_dword(space, address + 8, true));
con.printf("DeferredRoutine %08X dword\n", cpu.read_dword(space, address + 12, true));
con.printf("DeferredContext %08X dword\n", cpu.read_dword(space, address + 16, true));
con.printf("SystemArgument1 %08X dword\n", cpu.read_dword(space, address + 20, true));
con.printf("SystemArgument2 %08X dword\n", cpu.read_dword(space, address + 24, true));
con.printf("Type %d word\n", space.read_word_unaligned(address));
con.printf("Inserted %d byte\n", space.read_byte(address + 2));
con.printf("Padding %d byte\n", space.read_byte(address + 3));
con.printf("DpcListEntry {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 4), space.read_dword_unaligned(address + 8, true));
con.printf("DeferredRoutine %08X dword\n", space.read_dword_unaligned(address + 12));
con.printf("DeferredContext %08X dword\n", space.read_dword_unaligned(address + 16));
con.printf("SystemArgument1 %08X dword\n", space.read_dword_unaligned(address + 20));
con.printf("SystemArgument2 %08X dword\n", space.read_dword_unaligned(address + 24));
}
void xbox_base_state::dump_timer_command(int ref, const std::vector<std::string> &params)
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
uint64_t addr;
@ -261,22 +254,20 @@ void xbox_base_state::dump_timer_command(int ref, const std::vector<std::string>
con.printf("Address is unmapped.\n");
return;
}
address = (offs_t)addr;
con.printf("Header.Type %d byte\n", cpu.read_byte(space, address, true));
con.printf("Header.Absolute %d byte\n", cpu.read_byte(space, address + 1, true));
con.printf("Header.Size %d byte\n", cpu.read_byte(space, address + 2, true));
con.printf("Header.Inserted %d byte\n", cpu.read_byte(space, address + 3, true));
con.printf("Header.SignalState %08X dword\n", cpu.read_dword(space, address + 4, true));
con.printf("Header.WaitListEntry {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 8, true), cpu.read_dword(space, address + 12, true));
con.printf("%s", string_format("DueTime %x qword\n", (int64_t)cpu.read_qword(space, address + 16, true)).c_str());
con.printf("TimerListEntry {%08X,%08X} _LIST_ENTRY\n", cpu.read_dword(space, address + 24, true), cpu.read_dword(space, address + 28, true));
con.printf("Dpc %08X dword\n", cpu.read_dword(space, address + 32, true));
con.printf("Period %d dword\n", cpu.read_dword(space, address + 36, true));
con.printf("Header.Type %d byte\n", space.read_byte(address));
con.printf("Header.Absolute %d byte\n", space.read_byte(address + 1));
con.printf("Header.Size %d byte\n", space.read_byte(address + 2));
con.printf("Header.Inserted %d byte\n", space.read_byte(address + 3));
con.printf("Header.SignalState %08X dword\n", space.read_dword_unaligned(address + 4));
con.printf("Header.WaitListEntry {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 8), space.read_dword_unaligned(address + 12));
con.printf("%s", string_format("DueTime %x qword\n", (int64_t)space.read_qword_unaligned(address + 16)).c_str());
con.printf("TimerListEntry {%08X,%08X} _LIST_ENTRY\n", space.read_dword_unaligned(address + 24), space.read_dword_unaligned(address + 28));
con.printf("Dpc %08X dword\n", space.read_dword_unaligned(address + 32));
con.printf("Period %d dword\n", space.read_dword_unaligned(address + 36));
}
void xbox_base_state::curthread_command(int ref, const std::vector<std::string> &params)
{
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
address_space &space = m_maincpu->space();
offs_t address;
@ -288,26 +279,29 @@ void xbox_base_state::curthread_command(int ref, const std::vector<std::string>
con.printf("Address is unmapped.\n");
return;
}
address = (offs_t)fsbase + (offs_t)debugc_bios->parameter[7-1];
uint32_t kthrd = cpu.read_dword(space, address, true);
uint32_t kthrd = space.read_dword_unaligned(address);
con.printf("Current thread is %08X\n", kthrd);
address = (offs_t)(kthrd + debugc_bios->parameter[8-1]);
uint32_t topstack = cpu.read_dword(space, address, true);
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address))
return;
uint32_t topstack = space.read_dword_unaligned(address);
con.printf("Current thread stack top is %08X\n", topstack);
address = (offs_t)(kthrd + debugc_bios->parameter[4-1]);
uint32_t tlsdata = cpu.read_dword(space, address, true);
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address))
return;
uint32_t tlsdata = space.read_dword_unaligned(address);
if (tlsdata == 0)
address = (offs_t)(topstack - debugc_bios->parameter[5-1] - debugc_bios->parameter[6-1]);
else
address = (offs_t)(tlsdata - debugc_bios->parameter[6-1]);
con.printf("Current thread function is %08X\n", cpu.read_dword(space, address, true));
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, address))
con.printf("Current thread function is %08X\n", space.read_dword_unaligned(address));
}
void xbox_base_state::threadlist_command(int ref, const std::vector<std::string> &params)
{
address_space &space = m_maincpu->space();
debugger_cpu &cpu = machine().debugger().cpu();
debugger_console &con = machine().debugger().console();
con.printf("Pri. _KTHREAD Stack Function\n");
@ -315,20 +309,31 @@ void xbox_base_state::threadlist_command(int ref, const std::vector<std::string>
for (int pri = 0; pri < 16; pri++)
{
uint32_t curr = debugc_bios->parameter[1 - 1] + pri * 8;
uint32_t next = cpu.read_dword(space, curr, true);
uint32_t addr = curr;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr))
continue;
uint32_t next = space.read_dword_unaligned(addr);
while ((next != curr) && (next != 0))
{
uint32_t kthrd = next - debugc_bios->parameter[2 - 1];
uint32_t topstack = cpu.read_dword(space, kthrd + debugc_bios->parameter[3 - 1], true);
uint32_t tlsdata = cpu.read_dword(space, kthrd + debugc_bios->parameter[4 - 1], true);
uint32_t function;
if (!m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, kthrd))
break;
uint32_t topstack = space.read_dword_unaligned(kthrd + debugc_bios->parameter[3 - 1]);
uint32_t tlsdata = space.read_dword_unaligned(kthrd + debugc_bios->parameter[4 - 1]);
uint32_t function = 0;
if (tlsdata == 0)
function = cpu.read_dword(space, topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1], true);
addr = topstack - debugc_bios->parameter[5 - 1] - debugc_bios->parameter[6 - 1];
else
function = cpu.read_dword(space, tlsdata - debugc_bios->parameter[6 - 1], true);
addr = tlsdata - debugc_bios->parameter[6 - 1];
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr))
function = space.read_dword_unaligned(addr);
con.printf(" %02d %08x %08x %08x\n", pri, kthrd, topstack, function);
next = cpu.read_dword(space, next, true);
addr = next;
if (m_maincpu->translate(AS_PROGRAM, TRANSLATE_READ_DEBUG, addr))
next = space.read_dword_unaligned(addr);
else
break;
}
}
}

View File

@ -9,6 +9,7 @@
#include "emu.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/points.h"
#include "debug/textbuf.h"
#include "debug_module.h"
#include "debugger.h"
@ -426,8 +427,8 @@ private:
std::map<offs_t, uint64_t> m_address_map;
device_debug::breakpoint *m_triggered_breakpoint;
device_debug::watchpoint *m_triggered_watchpoint;
debug_breakpoint *m_triggered_breakpoint;
debug_watchpoint *m_triggered_watchpoint;
std::string m_target_xml;
@ -596,7 +597,7 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop)
}
else
{
device_debug *debug = m_debugger_cpu->get_visible_cpu()->debug();
device_debug *debug = m_debugger_console->get_visible_cpu()->debug();
m_triggered_watchpoint = debug->triggered_watchpoint();
m_triggered_breakpoint = debug->triggered_breakpoint();
if ( m_send_stop_packet )
@ -683,7 +684,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_c(const char *buf)
if ( *buf != '\0' )
return REPLY_UNSUPPORTED;
m_debugger_cpu->get_visible_cpu()->debug()->go();
m_debugger_console->get_visible_cpu()->debug()->go();
m_send_stop_packet = true;
return REPLY_NONE;
}
@ -696,7 +697,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_D(const char *buf)
if ( *buf != '\0' )
return REPLY_UNSUPPORTED;
m_debugger_cpu->get_visible_cpu()->debug()->go();
m_debugger_console->get_visible_cpu()->debug()->go();
m_dettached = true;
return REPLY_OK;
@ -752,7 +753,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_H(const char *buf)
debug_gdbstub::cmd_reply debug_gdbstub::handle_k(const char *buf)
{
m_machine->schedule_exit();
m_debugger_cpu->get_visible_cpu()->debug()->go();
m_debugger_console->get_visible_cpu()->debug()->go();
m_dettached = true;
m_socket.close();
return REPLY_NONE;
@ -969,7 +970,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_s(const char *buf)
if ( *buf != '\0' )
return REPLY_UNSUPPORTED;
m_debugger_cpu->get_visible_cpu()->debug()->single_step();
m_debugger_console->get_visible_cpu()->debug()->single_step();
m_send_stop_packet = true;
return REPLY_NONE;
}
@ -977,7 +978,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_s(const char *buf)
//-------------------------------------------------------------------------
static bool remove_breakpoint(device_debug *debug, uint64_t address, int /*kind*/)
{
const device_debug::breakpoint *bp = debug->breakpoint_find(address);
const debug_breakpoint *bp = debug->breakpoint_find(address);
if (bp != nullptr)
return debug->breakpoint_clear(bp->index());
return false;
@ -1021,7 +1022,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_z(const char *buf)
m_address_map.erase(offset);
}
device_debug *debug = m_debugger_cpu->get_visible_cpu()->debug();
device_debug *debug = m_debugger_console->get_visible_cpu()->debug();
switch ( type )
{
// Note: software and hardware breakpoints are treated both the
@ -1062,7 +1063,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
m_address_map[offset] = address;
}
device_debug *debug = m_debugger_cpu->get_visible_cpu()->debug();
device_debug *debug = m_debugger_console->get_visible_cpu()->debug();
switch ( type )
{
// Note: software and hardware breakpoints are treated both the

View File

@ -375,36 +375,36 @@ void debug_imgui::handle_keys()
else
{
m_machine->schedule_soft_reset();
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
}
}
if(ImGui::IsKeyPressed(ITEM_ID_F5,false))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_running = true;
}
if(ImGui::IsKeyPressed(ITEM_ID_F6,false))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
m_machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
m_running = true;
}
if(ImGui::IsKeyPressed(ITEM_ID_F7,false))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
m_machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
m_running = true;
}
if(ImGui::IsKeyPressed(ITEM_ID_F8,false))
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
m_machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
if(ImGui::IsKeyPressed(ITEM_ID_F9,false))
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
if(ImGui::IsKeyPressed(ITEM_ID_F10,false))
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
if(ImGui::IsKeyPressed(ITEM_ID_F11,false))
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
if(ImGui::IsKeyPressed(ITEM_ID_F12,false))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_hide = true;
}
@ -484,7 +484,7 @@ void debug_imgui::handle_console(running_machine* machine)
// if console input is empty, then do a single step
if(strlen(view_main_console->console_input) == 0)
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
view_main_console->exec_cmd = false;
history_pos = view_main_console->console_history.size();
return;
@ -1248,33 +1248,33 @@ void debug_imgui::draw_console()
ImGui::Separator();
if(ImGui::MenuItem("Run", "F5"))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_running = true;
}
if(ImGui::MenuItem("Go to next CPU", "F6"))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
m_machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
m_running = true;
}
if(ImGui::MenuItem("Run until next interrupt", "F7"))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
m_machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
m_running = true;
}
if(ImGui::MenuItem("Run until VBLANK", "F8"))
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
m_machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
if(ImGui::MenuItem("Run and hide debugger", "F12"))
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_hide = true;
}
ImGui::Separator();
if(ImGui::MenuItem("Single step", "F11"))
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
if(ImGui::MenuItem("Step over", "F10"))
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
if(ImGui::MenuItem("Step out", "F9"))
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
ImGui::EndMenu();
}

View File

@ -161,7 +161,7 @@ void debugger_windows::debugger_update()
{
HWND const focuswnd = GetFocus();
m_machine->debugger().cpu().get_visible_cpu()->debug()->halt_on_next_instruction("User-initiated break\n");
m_machine->debugger().debug_break();
// if we were focused on some window's edit box, reset it to default
for (auto &info : m_window_list)

View File

@ -10,6 +10,7 @@
#include "debug_module.h"
#include "modules/osdmodule.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debugger.h"
@ -42,7 +43,7 @@ void debug_none::init_debugger(running_machine &machine)
void debug_none::wait_for_debugger(device_t &device, bool firststop)
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
}
void debug_none::debugger_update()

View File

@ -24,6 +24,7 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/points.h"
#include "util/xmlfile.h"
@ -181,7 +182,7 @@
[dasmSplit setFrame:rhsFrame];
// select the current processor
[self setCPU:machine->debugger().cpu().get_visible_cpu()];
[self setCPU:machine->debugger().console().get_visible_cpu()];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(auxiliaryWindowWillClose:)
@ -219,7 +220,7 @@
NSString *command = [sender stringValue];
if ([command length] == 0)
{
machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
machine->debugger().console().get_visible_cpu()->debug()->single_step();
[history reset];
}
else
@ -234,10 +235,10 @@
- (IBAction)debugToggleBreakpoint:(id)sender {
device_t &device = *[dasmView source]->device();
if ([dasmView cursorVisible] && (machine->debugger().cpu().get_visible_cpu() == &device))
if ([dasmView cursorVisible] && (machine->debugger().console().get_visible_cpu() == &device))
{
offs_t const address = [dasmView selectedAddress];
const device_debug::breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find(address);
const debug_breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find(address);
// if it doesn't exist, add a new one
NSString *command;
@ -252,9 +253,9 @@
- (IBAction)debugToggleBreakpointEnable:(id)sender {
device_t &device = *[dasmView source]->device();
if ([dasmView cursorVisible] && (machine->debugger().cpu().get_visible_cpu() == &device))
if ([dasmView cursorVisible] && (machine->debugger().console().get_visible_cpu() == &device))
{
const device_debug::breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);
const debug_breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);
if (bp != nullptr)
{
NSString *command;
@ -270,7 +271,7 @@
- (IBAction)debugRunToCursor:(id)sender {
device_t &device = *[dasmView source]->device();
if ([dasmView cursorVisible] && (machine->debugger().cpu().get_visible_cpu() == &device))
if ([dasmView cursorVisible] && (machine->debugger().console().get_visible_cpu() == &device))
{
NSString *command = [NSString stringWithFormat:@"go 0x%lX", (unsigned long)[dasmView selectedAddress]];
machine->debugger().console().execute_command([command UTF8String], 1);
@ -499,7 +500,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification
object:self
userInfo:info];
machine->debugger().cpu().get_visible_cpu()->debug()->go();
machine->debugger().console().get_visible_cpu()->debug()->go();
}
}
@ -562,9 +563,9 @@
SEL const action = [item action];
BOOL const inContextMenu = ([item menu] == [dasmView menu]);
BOOL const haveCursor = [dasmView cursorVisible];
BOOL const isCurrent = (machine->debugger().cpu().get_visible_cpu() == [dasmView source]->device());
BOOL const isCurrent = (machine->debugger().console().get_visible_cpu() == [dasmView source]->device());
const device_debug::breakpoint *breakpoint = nullptr;
const debug_breakpoint *breakpoint = nullptr;
if (haveCursor)
{
breakpoint = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);

View File

@ -10,6 +10,7 @@
#include "emu.h"
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "modules/lib/osdobj_common.h"
@ -871,7 +872,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
- (void)insertNewline:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
machine->debugger().console().get_visible_cpu()->debug()->single_step();
}

View File

@ -14,6 +14,7 @@
#import "debugview.h"
#include "debugger.h"
#include "debug/debugcon.h"
#include "util/xmlfile.h"
@ -189,12 +190,12 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
- (IBAction)debugBreak:(id)sender {
if (machine->debug_flags & DEBUG_FLAG_ENABLED)
machine->debugger().cpu().get_visible_cpu()->debug()->halt_on_next_instruction("User-initiated break\n");
machine->debugger().console().get_visible_cpu()->debug()->halt_on_next_instruction("User-initiated break\n");
}
- (IBAction)debugRun:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->go();
machine->debugger().console().get_visible_cpu()->debug()->go();
}
@ -203,43 +204,43 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
object:self
userInfo:[NSDictionary dictionaryWithObject:[NSValue valueWithPointer:machine]
forKey:@"MAMEDebugMachine"]];
machine->debugger().cpu().get_visible_cpu()->debug()->go();
machine->debugger().console().get_visible_cpu()->debug()->go();
}
- (IBAction)debugRunToNextCPU:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
}
- (IBAction)debugRunToNextInterrupt:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
}
- (IBAction)debugRunToNextVBLANK:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
}
- (IBAction)debugStepInto:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
machine->debugger().console().get_visible_cpu()->debug()->single_step();
}
- (IBAction)debugStepOver:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
}
- (IBAction)debugStepOut:(id)sender {
machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
}
- (IBAction)debugSoftReset:(id)sender {
machine->schedule_soft_reset();
machine->debugger().cpu().get_visible_cpu()->debug()->go();
machine->debugger().console().get_visible_cpu()->debug()->go();
}

View File

@ -16,6 +16,7 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/points.h"
#include "util/xmlfile.h"
@ -109,7 +110,7 @@
[actionButton release];
// set default state
[dasmView selectSubviewForDevice:machine->debugger().cpu().get_visible_cpu()];
[dasmView selectSubviewForDevice:machine->debugger().console().get_visible_cpu()];
[dasmView setExpression:@"curpc"];
[expressionField setStringValue:@"curpc"];
[expressionField selectText:self];
@ -176,7 +177,7 @@
{
device_t &device = *[dasmView source]->device();
offs_t const address = [dasmView selectedAddress];
const device_debug::breakpoint *bp = device.debug()->breakpoint_find(address);
const debug_breakpoint *bp = device.debug()->breakpoint_find(address);
// if it doesn't exist, add a new one
if (bp == nullptr)
@ -203,7 +204,7 @@
{
device_t &device = *[dasmView source]->device();
offs_t const address = [dasmView selectedAddress];
const device_debug::breakpoint *bp = device.debug()->breakpoint_find(address);
const debug_breakpoint *bp = device.debug()->breakpoint_find(address);
if (bp != nullptr)
{
device.debug()->breakpoint_enable(bp->index(), !bp->enabled());
@ -252,7 +253,7 @@
BOOL const inContextMenu = ([item menu] == [dasmView menu]);
BOOL const haveCursor = [dasmView cursorVisible];
const device_debug::breakpoint *breakpoint = nullptr;
const debug_breakpoint *breakpoint = nullptr;
if (haveCursor)
{
breakpoint = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);

View File

@ -9,7 +9,6 @@
#include "emu.h"
#import "memoryview.h"
#include "debug/debugcpu.h"
#include "debug/debugvw.h"
#include "util/xmlfile.h"

View File

@ -14,7 +14,7 @@
#import "memoryview.h"
#include "debugger.h"
#include "debug/debugcpu.h"
#include "debug/debugcon.h"
#include "debug/dvmemory.h"
#include "util/xmlfile.h"
@ -108,7 +108,7 @@
[actionButton release];
// set default state
[memoryView selectSubviewForDevice:machine->debugger().cpu().get_visible_cpu()];
[memoryView selectSubviewForDevice:machine->debugger().console().get_visible_cpu()];
[memoryView setExpression:@"0"];
[expressionField setStringValue:@"0"];
[expressionField selectText:self];

View File

@ -10,7 +10,7 @@
#include "emu.h"
#include "debugger.h"
#include "debug/debugcpu.h"
#include "debug/debugcon.h"
#include "debug/debugvw.h"
@ -30,7 +30,7 @@
- (NSSize)maximumFrameSize {
debug_view_xy max;
device_t *curcpu = machine->debugger().cpu().get_visible_cpu();
device_t *curcpu = machine->debugger().console().get_visible_cpu();
const debug_view_source *source = view->source_for_device(curcpu);
max.x = max.y = 0;

View File

@ -12,6 +12,7 @@
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/dvdisasm.h"
#include "debug/points.h"
DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
@ -141,7 +142,7 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
// If none exists, add a new one
if (bp == nullptr)
@ -172,7 +173,7 @@ void DasmWindow::enableBreakpointAtCursor(bool changedTo)
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
{
@ -228,7 +229,7 @@ void DasmWindow::dasmViewUpdated()
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
{
@ -260,7 +261,7 @@ void DasmWindow::populateComboBox()
void DasmWindow::setToCurrentCpu()
{
device_t* curCpu = m_machine->debugger().cpu().get_visible_cpu();
device_t* curCpu = m_machine->debugger().console().get_visible_cpu();
if (curCpu)
{
const debug_view_source *source = m_dasmView->view()->source_for_device(curCpu);

View File

@ -14,6 +14,7 @@
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/dvdisasm.h"
#include "debug/points.h"
MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
@ -214,13 +215,13 @@ bool MainWindow::eventFilter(QObject* obj, QEvent* event)
void MainWindow::toggleBreakpointAtCursor(bool changedTo)
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device()))
if (dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t const address = downcast<debug_view_disasm *>(dasmView)->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
// Find an existing breakpoint at this address
const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
// If none exists, add a new one
std::string command;
@ -242,13 +243,13 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
void MainWindow::enableBreakpointAtCursor(bool changedTo)
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device()))
if (dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t const address = dasmView->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
// Find an existing breakpoint at this address
const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
{
@ -265,7 +266,7 @@ void MainWindow::enableBreakpointAtCursor(bool changedTo)
void MainWindow::runToCursor(bool changedTo)
{
debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
if (dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device()))
if (dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address();
std::string command = string_format("go 0x%X", address);
@ -304,7 +305,7 @@ void MainWindow::executeCommand(bool withClear)
// A blank command is a "silent step"
if (command == "")
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
return;
}
@ -396,7 +397,7 @@ void MainWindow::unmountImage(bool changedTo)
void MainWindow::dasmViewUpdated()
{
debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
bool const haveCursor = dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device());
bool const haveCursor = dasmView->cursor_visible() && (m_machine->debugger().console().get_visible_cpu() == dasmView->source()->device());
bool haveBreakpoint = false;
bool breakpointEnabled = false;
if (haveCursor)
@ -406,7 +407,7 @@ void MainWindow::dasmViewUpdated()
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
if (bp != nullptr)
{

View File

@ -295,7 +295,7 @@ void MemoryWindow::populateComboBox()
void MemoryWindow::setToCurrentCpu()
{
device_t* curCpu = m_machine->debugger().cpu().get_visible_cpu();
device_t* curCpu = m_machine->debugger().console().get_visible_cpu();
if (curCpu)
{
const debug_view_source *source = m_memTable->view()->source_for_device(curCpu);
@ -355,27 +355,51 @@ void DebuggerMemView::mousePressEvent(QMouseEvent* event)
const offs_t address = memView->addressAtCursorPosition(clickViewPosition);
const debug_view_memory_source* source = downcast<const debug_view_memory_source*>(memView->source());
address_space* addressSpace = source->space();
const int nativeDataWidth = addressSpace->data_width() / 8;
const uint64_t memValue = source->device()->machine().debugger().cpu().read_memory(*addressSpace,
addressSpace->address_to_byte(address),
nativeDataWidth,
true);
const offs_t pc = source->device()->debug()->track_mem_pc_from_space_address_data(addressSpace->spacenum(),
address,
memValue);
if (pc != (offs_t)(-1))
offs_t a = address & space->logaddrmask();
if (!addressSpace->device().memory().translate(addressSpace->spacenum(), TRANSLATE_READ_DEBUG, a))
{
// TODO: You can specify a box that the tooltip stays alive within - might be good?
const QString addressAndPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);
QToolTip::showText(QCursor::pos(), addressAndPc, nullptr);
// Copy the PC into the clipboard as well
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString("%1").arg(pc, 2, 16));
QToolTip::showText(QCursor::pos(), "Bad address", nullptr);
}
else
{
QToolTip::showText(QCursor::pos(), "UNKNOWN PC", nullptr);
uint64_t memValue = addressSpace->unmap();
auto dis = addressSpace->device().machine().disable_side_effects();
switch (addressSpace->data_width())
{
case 8:
memValue = space->read_byte(a);
break;
case 16:
memValue = space->read_word_unaligned(a);
break;
case 32:
memValue = space->read_dword_unaligned(a);
break;
case 64:
memValue = space->read_qword_unaligned(a);
break;
}
const offs_t pc = source->device()->debug()->track_mem_pc_from_space_address_data(addressSpace->spacenum(),
address,
memValue);
if (pc != (offs_t)(-1))
{
// TODO: You can specify a box that the tooltip stays alive within - might be good?
const QString addressAndPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);
QToolTip::showText(QCursor::pos(), addressAndPc, nullptr);
// Copy the PC into the clipboard as well
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(QString("%1").arg(pc, 2, 16));
}
else
{
QToolTip::showText(QCursor::pos(), "UNKNOWN PC", nullptr);
}
}
}

View File

@ -179,49 +179,49 @@ void WindowQt::debugActOpenDevices()
void WindowQt::debugActRun()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
}
void WindowQt::debugActRunAndHide()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
m_machine->debugger().console().get_visible_cpu()->debug()->go();
hideAll();
}
void WindowQt::debugActRunToNextCpu()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
m_machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
}
void WindowQt::debugActRunNextInt()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
m_machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
}
void WindowQt::debugActRunNextVBlank()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
m_machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
}
void WindowQt::debugActStepInto()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActStepOver()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
}
void WindowQt::debugActStepOut()
{
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
}
void WindowQt::debugActSoftReset()
{
m_machine->schedule_soft_reset();
m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActHardReset()

View File

@ -78,7 +78,7 @@ consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
}
// recompute the children
set_cpu(*machine().debugger().cpu().get_visible_cpu());
set_cpu(*machine().debugger().console().get_visible_cpu());
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@ -481,7 +481,7 @@ bool consolewin_info::handle_command(WPARAM wparam, LPARAM lparam)
void consolewin_info::process_string(std::string const &string)
{
if (string.empty()) // an empty string is a single step
machine().debugger().cpu().get_visible_cpu()->debug()->single_step();
machine().debugger().console().get_visible_cpu()->debug()->single_step();
else // otherwise, just process the command
machine().debugger().console().execute_command(string, true);

View File

@ -12,6 +12,7 @@
#include "debugwininfo.h"
#include "uimetrics.h"
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "strconv.h"
@ -207,7 +208,7 @@ bool debugview_info::source_is_visible_cpu() const
if (m_view != nullptr)
{
const debug_view_source *const source = m_view->source();
return (source != nullptr) && (machine().debugger().cpu().get_visible_cpu() == source->device());
return (source != nullptr) && (machine().debugger().console().get_visible_cpu() == source->device());
}
return false;
}
@ -245,7 +246,7 @@ bool debugview_info::set_source_for_device(device_t &device)
bool debugview_info::set_source_for_visible_cpu()
{
device_t *const curcpu = machine().debugger().cpu().get_visible_cpu();
device_t *const curcpu = machine().debugger().console().get_visible_cpu();
if (curcpu != nullptr)
return set_source_for_device(*curcpu);
else

View File

@ -12,6 +12,7 @@
#include "debugviewinfo.h"
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "window.h"
#include "winutf8.h"
@ -300,31 +301,31 @@ bool debugwin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_RUN_AND_HIDE:
debugger().hide_all();
case ID_RUN:
machine().debugger().cpu().get_visible_cpu()->debug()->go();
machine().debugger().console().get_visible_cpu()->debug()->go();
return true;
case ID_NEXT_CPU:
machine().debugger().cpu().get_visible_cpu()->debug()->go_next_device();
machine().debugger().console().get_visible_cpu()->debug()->go_next_device();
return true;
case ID_RUN_VBLANK:
machine().debugger().cpu().get_visible_cpu()->debug()->go_vblank();
machine().debugger().console().get_visible_cpu()->debug()->go_vblank();
return true;
case ID_RUN_IRQ:
machine().debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
machine().debugger().console().get_visible_cpu()->debug()->go_interrupt();
return true;
case ID_STEP:
machine().debugger().cpu().get_visible_cpu()->debug()->single_step();
machine().debugger().console().get_visible_cpu()->debug()->single_step();
return true;
case ID_STEP_OVER:
machine().debugger().cpu().get_visible_cpu()->debug()->single_step_over();
machine().debugger().console().get_visible_cpu()->debug()->single_step_over();
return true;
case ID_STEP_OUT:
machine().debugger().cpu().get_visible_cpu()->debug()->single_step_out();
machine().debugger().console().get_visible_cpu()->debug()->single_step_out();
return true;
case ID_REWIND_STEP:
@ -348,7 +349,7 @@ bool debugwin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_SOFT_RESET:
machine().schedule_soft_reset();
machine().debugger().cpu().get_visible_cpu()->debug()->go();
machine().debugger().console().get_visible_cpu()->debug()->go();
return true;
case ID_EXIT:
@ -507,7 +508,7 @@ LRESULT debugwin_info::window_proc(UINT message, WPARAM wparam, LPARAM lparam)
if (m_is_main_console)
{
debugger().hide_all();
machine().debugger().cpu().get_visible_cpu()->debug()->go();
machine().debugger().console().get_visible_cpu()->debug()->go();
}
else
{

View File

@ -15,6 +15,7 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/points.h"
//#include "winutf8.h"
@ -115,7 +116,7 @@ void disasmbasewin_info::update_menu()
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
const device_debug::breakpoint *bp = debug->breakpoint_find(address);
const debug_breakpoint *bp = debug->breakpoint_find(address);
if (bp == nullptr)
{
@ -166,7 +167,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
const device_debug::breakpoint *bp = debug->breakpoint_find(address);
const debug_breakpoint *bp = debug->breakpoint_find(address);
// if it doesn't exist, add a new one
if (!is_main_console())
@ -204,7 +205,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
const device_debug::breakpoint *bp = debug->breakpoint_find(address);
const debug_breakpoint *bp = debug->breakpoint_find(address);
// if it doesn't exist, add a new one
if (bp != nullptr)