summaryrefslogtreecommitdiffstats
path: root/src/emu/debug/debugcpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/debugcpu.cpp')
-rw-r--r--src/emu/debug/debugcpu.cpp1219
1 files changed, 575 insertions, 644 deletions
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 01f15cb3e46..7c2806ba601 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -21,157 +21,93 @@
#include "coreutil.h"
#include <ctype.h>
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define NUM_TEMP_VARIABLES 10
-
enum
{
EXECUTION_STATE_STOPPED,
EXECUTION_STATE_RUNNING
};
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-struct debugcpu_private
-{
- device_t *livecpu;
- device_t *visiblecpu;
- device_t *breakcpu;
-
- FILE * source_file; /* script source file */
-
- symbol_table * symtable; /* global symbol table */
-
- bool within_instruction_hook;
- bool vblank_occurred;
- bool memory_modified;
- bool debugger_access;
-
- int execution_state;
- device_t * m_stop_when_not_device; // stop execution when the device ceases to be this
-
- UINT32 bpindex;
- UINT32 wpindex;
- UINT32 rpindex;
-
- UINT64 wpdata;
- UINT64 wpaddr;
- UINT64 tempvar[NUM_TEMP_VARIABLES];
-
- osd_ticks_t last_periodic_update_time;
-
- bool comments_loaded;
-};
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-/* internal helpers */
-static void debug_cpu_exit(running_machine &machine);
-static void on_vblank(running_machine &machine, screen_device &device, bool vblank_state);
-static void reset_transient_flags(running_machine &machine);
-static void process_source_file(running_machine &machine);
-
-/* expression handlers */
-static UINT64 expression_read_memory(void *param, const char *name, expression_space space, UINT32 address, int size);
-static UINT64 expression_read_program_direct(address_space &space, int opcode, offs_t address, int size);
-static UINT64 expression_read_memory_region(running_machine &machine, const char *rgntag, offs_t address, int size);
-static void expression_write_memory(void *param, const char *name, expression_space space, UINT32 address, int size, UINT64 data);
-static void expression_write_program_direct(address_space &space, int opcode, offs_t address, int size, UINT64 data);
-static void expression_write_memory_region(running_machine &machine, const char *rgntag, offs_t address, int size, UINT64 data);
-static expression_error::error_code expression_validate(void *param, const char *name, expression_space space);
-
-/* variable getters/setters */
-static UINT64 get_cpunum(symbol_table &table, void *ref);
-static UINT64 get_beamx(symbol_table &table, void *ref);
-static UINT64 get_beamy(symbol_table &table, void *ref);
-static UINT64 get_frame(symbol_table &table, void *ref);
-
-
-
-/***************************************************************************
- INITIALIZATION AND CLEANUP
-***************************************************************************/
+const size_t debugger_cpu::NUM_TEMP_VARIABLES = 10;
/*-------------------------------------------------
- debug_cpu_init - initialize the CPU
+ constructor - initialize the CPU
information for debugging
-------------------------------------------------*/
-void debug_cpu_init(running_machine &machine)
-{
- screen_device *first_screen = machine.first_screen();
- debugcpu_private *global;
- int regnum;
-
- /* allocate and reset globals */
- machine.debugcpu_data = global = auto_alloc_clear(machine, <debugcpu_private>());
- global->execution_state = EXECUTION_STATE_STOPPED;
- global->bpindex = 1;
- global->wpindex = 1;
- global->rpindex = 1;
+debugger_cpu::debugger_cpu(running_machine &machine)
+ : m_machine(machine)
+ , m_livecpu(nullptr)
+ , m_visiblecpu(nullptr)
+ , m_breakcpu(nullptr)
+ , m_source_file(nullptr)
+ , m_symtable(nullptr)
+ , m_execution_state(EXECUTION_STATE_STOPPED)
+ , m_bpindex(1)
+ , m_wpindex(1)
+ , m_rpindex(1)
+ , m_wpdata(0)
+ , m_wpaddr(0)
+ , m_comments_loaded(false)
+{
+ screen_device *first_screen = m_machine.first_screen();
+
+ m_tempvar = make_unique_clear<UINT64[]>(NUM_TEMP_VARIABLES);
/* create a global symbol table */
- global->symtable = global_alloc(symbol_table(&machine));
+ m_symtable = global_alloc(symbol_table(&m_machine));
// configure our base memory accessors
- debug_cpu_configure_memory(machine, *global->symtable);
+ configure_memory(*m_symtable);
/* add "wpaddr", "wpdata", "cycles", "cpunum", "logunmap" to the global symbol table */
- global->symtable->add("wpaddr", symbol_table::READ_ONLY, &global->wpaddr);
- global->symtable->add("wpdata", symbol_table::READ_ONLY, &global->wpdata);
- global->symtable->add("cpunum", nullptr, get_cpunum);
- global->symtable->add("beamx", (void *)first_screen, get_beamx);
- global->symtable->add("beamy", (void *)first_screen, get_beamy);
- global->symtable->add("frame", (void *)first_screen, get_frame);
+ m_symtable->add("wpaddr", symbol_table::READ_ONLY, &m_wpaddr);
+ m_symtable->add("wpdata", symbol_table::READ_ONLY, &m_wpdata);
+
+ using namespace std::placeholders;
+ m_symtable->add("cpunum", nullptr, std::bind(&debugger_cpu::get_cpunum, this, _1, _2));
+ m_symtable->add("beamx", (void *)first_screen, std::bind(&debugger_cpu::get_beamx, this, _1, _2));
+ m_symtable->add("beamy", (void *)first_screen, std::bind(&debugger_cpu::get_beamy, this, _1, _2));
+ m_symtable->add("frame", (void *)first_screen, std::bind(&debugger_cpu::get_frame, this, _1, _2));
/* add the temporary variables to the global symbol table */
- for (regnum = 0; regnum < NUM_TEMP_VARIABLES; regnum++)
+ for (int regnum = 0; regnum < NUM_TEMP_VARIABLES; regnum++)
{
char symname[10];
sprintf(symname, "temp%d", regnum);
- global->symtable->add(symname, symbol_table::READ_WRITE, &global->tempvar[regnum]);
+ m_symtable->add(symname, symbol_table::READ_WRITE, &m_tempvar[regnum]);
}
/* first CPU is visible by default */
- global->visiblecpu = machine.firstcpu;
+ m_visiblecpu = m_machine.firstcpu;
/* add callback for breaking on VBLANK */
- if (machine.first_screen() != nullptr)
- machine.first_screen()->register_vblank_callback(vblank_state_delegate(FUNC(on_vblank), &machine));
+ if (m_machine.first_screen() != nullptr)
+ m_machine.first_screen()->register_vblank_callback(vblank_state_delegate(FUNC(debugger_cpu::on_vblank), this));
- machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debug_cpu_exit), &machine));
+ machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debugger_cpu::exit), this));
}
-
-void debug_cpu_configure_memory(running_machine &machine, symbol_table &table)
+void debugger_cpu::configure_memory(symbol_table &table)
{
- table.configure_memory(&machine, expression_validate, expression_read_memory, expression_write_memory);
+ using namespace std::placeholders;
+ table.configure_memory(
+ &m_machine,
+ std::bind(&debugger_cpu::expression_validate, this, _1, _2, _3),
+ std::bind(&debugger_cpu::expression_read_memory, this, _1, _2, _3, _4, _5),
+ std::bind(&debugger_cpu::expression_write_memory, this, _1, _2, _3, _4, _5, _6));
}
-
/*-------------------------------------------------
- debug_cpu_flush_traces - flushes all traces;
- this is useful if a trace is going on when we
+ flush_traces - flushes all traces; this is
+ useful if a trace is going on when we
fatalerror
-------------------------------------------------*/
-void debug_cpu_flush_traces(running_machine &machine)
+void debugger_cpu::flush_traces()
{
/* this can be called on exit even when no debugging is enabled, so
make sure the devdebug is valid before proceeding */
- for (device_t &device : device_iterator(machine.root_device()))
+ for (device_t &device : device_iterator(m_machine.root_device()))
if (device.debug() != nullptr)
device.debug()->trace_flush();
}
@@ -183,90 +119,86 @@ void debug_cpu_flush_traces(running_machine &machine)
***************************************************************************/
/*-------------------------------------------------
- cpu_get_visible_cpu - return the visible CPU
+ get_visible_cpu - return the visible CPU
device (the one that commands should apply to)
-------------------------------------------------*/
-device_t *debug_cpu_get_visible_cpu(running_machine &machine)
+device_t* debugger_cpu::get_visible_cpu()
{
- return machine.debugcpu_data->visiblecpu;
+ return m_visiblecpu;
}
/*-------------------------------------------------
- debug_cpu_within_instruction_hook - true if
- the debugger is currently live
+ within_instruction_hook - true if the debugger
+ is currently live
-------------------------------------------------*/
-int debug_cpu_within_instruction_hook(running_machine &machine)
+bool debugger_cpu::within_instruction_hook()
{
- return machine.debugcpu_data->within_instruction_hook;
+ return m_within_instruction_hook;
}
/*-------------------------------------------------
- debug_cpu_is_stopped - return true if the
+ is_stopped - return true if the
current execution state is stopped
-------------------------------------------------*/
-int debug_cpu_is_stopped(running_machine &machine)
+bool debugger_cpu::is_stopped()
{
- debugcpu_private *global = machine.debugcpu_data;
- return (global != nullptr) ? (global->execution_state == EXECUTION_STATE_STOPPED) : false;
+ return m_execution_state == EXECUTION_STATE_STOPPED;
}
-
/***************************************************************************
SYMBOL TABLE INTERFACES
***************************************************************************/
/*-------------------------------------------------
- debug_cpu_get_global_symtable - return the
- global symbol table
+ get_global_symtable - return the global
+ symbol table
-------------------------------------------------*/
-symbol_table *debug_cpu_get_global_symtable(running_machine &machine)
+symbol_table* debugger_cpu::get_global_symtable()
{
- return machine.debugcpu_data->symtable;
+ return m_symtable;
}
/*-------------------------------------------------
- debug_cpu_get_visible_symtable - return the
+ get_visible_symtable - return the
locally-visible symbol table
-------------------------------------------------*/
-symbol_table *debug_cpu_get_visible_symtable(running_machine &machine)
+symbol_table* debugger_cpu::get_visible_symtable()
{
- return &machine.debugcpu_data->visiblecpu->debug()->symtable();
+ return &m_visiblecpu->debug()->symtable();
}
/*-------------------------------------------------
- debug_cpu_source_script - specifies a debug
- command script to execute
+ source_script - specifies a debug command
+ script to execute
-------------------------------------------------*/
-void debug_cpu_source_script(running_machine &machine, const char *file)
+void debugger_cpu::source_script(const char *file)
{
- debugcpu_private *global = machine.debugcpu_data;
-
/* close any existing source file */
- if (global->source_file != nullptr)
+ if (m_source_file != nullptr)
{
- fclose(global->source_file);
- global->source_file = nullptr;
+ fclose(m_source_file);
+ m_source_file = nullptr;
}
/* open a new one if requested */
if (file != nullptr)
{
- global->source_file = fopen(file, "r");
- if (!global->source_file)
+ m_source_file = fopen(file, "r");
+ if (!m_source_file)
{
- if (machine.phase() == MACHINE_PHASE_RUNNING)
- debug_console_printf(machine, "Cannot open command file '%s'\n", file);
+ if (m_machine.phase() == MACHINE_PHASE_RUNNING)
+ m_machine.debugger().console().printf("Cannot open command file '%s'\n", file);
else
fatalerror("Cannot open command file '%s'\n", file);
}
@@ -280,11 +212,11 @@ void debug_cpu_source_script(running_machine &machine, const char *file)
//**************************************************************************
//-------------------------------------------------
-// debug_comment_save - save all comments for
-// the given machine
+// omment_save - save all comments for the given
+// machine
//-------------------------------------------------
-bool debug_comment_save(running_machine &machine)
+bool debugger_cpu::comment_save()
{
bool comments_saved = false;
@@ -306,11 +238,11 @@ bool debug_comment_save(running_machine &machine)
xml_data_node *systemnode = xml_add_child(commentnode, "system", nullptr);
if (systemnode == nullptr)
throw emu_exception();
- xml_set_attribute(systemnode, "name", machine.system().name);
+ xml_set_attribute(systemnode, "name", m_machine.system().name);
// for each device
bool found_comments = false;
- for (device_t &device : device_iterator(machine.root_device()))
+ for (device_t &device : device_iterator(m_machine.root_device()))
if (device.debug() && device.debug()->comment_count() > 0)
{
// create a node for this device
@@ -328,8 +260,8 @@ bool debug_comment_save(running_machine &machine)
// flush the file
if (found_comments)
{
- emu_file file(machine.options().comment_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- osd_file::error filerr = file.open(machine.basename(), ".cmt");
+ emu_file file(m_machine.options().comment_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
+ osd_file::error filerr = file.open(m_machine.basename(), ".cmt");
if (filerr == osd_file::error::NONE)
{
xml_file_write(root, file);
@@ -349,15 +281,15 @@ bool debug_comment_save(running_machine &machine)
}
//-------------------------------------------------
-// debug_comment_load - load all comments for
-// the given machine
+// comment_load - load all comments for the given
+// machine
//-------------------------------------------------
-bool debug_comment_load(running_machine &machine,bool is_inline)
+bool debugger_cpu::comment_load(bool is_inline)
{
// open the file
- emu_file file(machine.options().comment_directory(), OPEN_FLAG_READ);
- osd_file::error filerr = file.open(machine.basename(), ".cmt");
+ emu_file file(m_machine.options().comment_directory(), OPEN_FLAG_READ);
+ osd_file::error filerr = file.open(m_machine.basename(), ".cmt");
// if an error, just return false
if (filerr != osd_file::error::NONE)
@@ -384,18 +316,18 @@ bool debug_comment_load(running_machine &machine,bool is_inline)
// check to make sure the file is applicable
xml_data_node *systemnode = xml_get_sibling(commentnode->child, "system");
const char *name = xml_get_attribute_string(systemnode, "name", "");
- if (strcmp(name, machine.system().name) != 0)
+ if (strcmp(name, m_machine.system().name) != 0)
throw emu_exception();
// iterate over devices
for (xml_data_node *cpunode = xml_get_sibling(systemnode->child, "cpu"); cpunode; cpunode = xml_get_sibling(cpunode->next, "cpu"))
{
const char *cputag_name = xml_get_attribute_string(cpunode, "tag", "");
- device_t *device = machine.device(cputag_name);
+ device_t *device = m_machine.device(cputag_name);
if (device != nullptr)
{
if(is_inline == false)
- debug_console_printf(machine,"@%s\n",cputag_name);
+ m_machine.debugger().console().printf("@%s\n", cputag_name);
if (!device->debug()->comment_import(*cpunode,is_inline))
throw emu_exception();
@@ -422,12 +354,11 @@ bool debug_comment_load(running_machine &machine,bool is_inline)
***************************************************************************/
/*-------------------------------------------------
- debug_cpu_translate - return the physical
- address corresponding to the given logical
- address
+ translate - return the physical address
+ corresponding to the given logical address
-------------------------------------------------*/
-int debug_cpu_translate(address_space &space, int intention, offs_t *address)
+bool debugger_cpu::translate(address_space &space, int intention, offs_t *address)
{
device_memory_interface *memory;
if (space.device().interface(memory))
@@ -441,58 +372,57 @@ int debug_cpu_translate(address_space &space, int intention, offs_t *address)
***************************************************************************/
/*-------------------------------------------------
- debug_read_byte - return a byte from the
- the specified memory space
+ read_byte - return a byte from the specified
+ memory space
-------------------------------------------------*/
-UINT8 debug_read_byte(address_space &space, offs_t address, int apply_translation)
+UINT8 debugger_cpu::read_byte(address_space &space, offs_t address, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
- UINT64 custom;
- UINT8 result;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
/* translate if necessary; if not mapped, return 0xff */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
+ UINT64 custom;
+ UINT8 result;
+ if (apply_translation && !translate(space, TRANSLATE_READ_DEBUG, &address))
+ {
result = 0xff;
-
- /* if there is a custom read handler, and it returns true, use that value */
+ }
else if (space.device().memory().read(space.spacenum(), address, 1, custom))
+ { /* if there is a custom read handler, and it returns true, use that value */
result = custom;
-
- /* otherwise, call the byte reading function for the translated address */
+ }
else
+ { /* otherwise, call the byte reading function for the translated address */
result = space.read_byte(address);
+ }
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
+ m_debugger_access = false;
+ space.set_debugger_access(false);
return result;
}
/*-------------------------------------------------
- debug_read_word - return a word from the
- specified memory space
+ read_word - return a word from the specified
+ memory space
-------------------------------------------------*/
-UINT16 debug_read_word(address_space &space, offs_t address, int apply_translation)
+UINT16 debugger_cpu::read_word(address_space &space, offs_t address, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
- UINT16 result;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
- /* if this is misaligned read, or if there are no word readers, just read two bytes */
+ UINT16 result;
if (!WORD_ALIGNED(address))
- {
- UINT8 byte0 = debug_read_byte(space, address + 0, apply_translation);
- UINT8 byte1 = debug_read_byte(space, address + 1, apply_translation);
+ { /* if this is misaligned read, or if there are no word readers, just read two bytes */
+ UINT8 byte0 = read_byte(space, address + 0, apply_translation);
+ UINT8 byte1 = read_byte(space, address + 1, apply_translation);
/* based on the endianness, the result is assembled differently */
if (space.endianness() == ENDIANNESS_LITTLE)
@@ -500,29 +430,31 @@ UINT16 debug_read_word(address_space &space, offs_t address, int apply_translati
else
result = byte1 | (byte0 << 8);
}
-
- /* otherwise, this proceeds like the byte case */
else
- {
- UINT64 custom;
+ { /* otherwise, this proceeds like the byte case */
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
/* translate if necessary; if not mapped, return 0xffff */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
+ UINT64 custom;
+ if (apply_translation && !translate(space, TRANSLATE_READ_DEBUG, &address))
+ {
result = 0xffff;
-
- /* if there is a custom read handler, and it returns true, use that value */
+ }
else if (space.device().memory().read(space.spacenum(), address, 2, custom))
+ { /* if there is a custom read handler, and it returns true, use that value */
result = custom;
-
- /* otherwise, call the byte reading function for the translated address */
+ }
else
+ { /* otherwise, call the byte reading function for the translated address */
result = space.read_word(address);
+ }
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
+ m_debugger_access = false;
+ space.set_debugger_access(false);
}
return result;
@@ -530,23 +462,20 @@ UINT16 debug_read_word(address_space &space, offs_t address, int apply_translati
/*-------------------------------------------------
- debug_read_dword - return a dword from the
- specified memory space
+ read_dword - return a dword from the specified
+ memory space
-------------------------------------------------*/
-UINT32 debug_read_dword(address_space &space, offs_t address, int apply_translation)
+UINT32 debugger_cpu::read_dword(address_space &space, offs_t address, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
- UINT32 result;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
- /* if this is misaligned read, or if there are no dword readers, just read two words */
+ UINT32 result;
if (!DWORD_ALIGNED(address))
- {
- UINT16 word0 = debug_read_word(space, address + 0, apply_translation);
- UINT16 word1 = debug_read_word(space, address + 2, apply_translation);
+ { /* if this is a misaligned read, or if there are no dword readers, just read two words */
+ UINT16 word0 = read_word(space, address + 0, apply_translation);
+ UINT16 word1 = read_word(space, address + 2, apply_translation);
/* based on the endianness, the result is assembled differently */
if (space.endianness() == ENDIANNESS_LITTLE)
@@ -554,29 +483,30 @@ UINT32 debug_read_dword(address_space &space, offs_t address, int apply_translat
else
result = word1 | (word0 << 16);
}
-
- /* otherwise, this proceeds like the byte case */
else
- {
- UINT64 custom;
+ { /* otherwise, this proceeds like the byte case */
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
- /* translate if necessary; if not mapped, return 0xffffffff */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
+ UINT64 custom;
+ if (apply_translation && !translate(space, TRANSLATE_READ_DEBUG, &address))
+ { /* translate if necessary; if not mapped, return 0xffffffff */
result = 0xffffffff;
-
- /* if there is a custom read handler, and it returns true, use that value */
+ }
else if (space.device().memory().read(space.spacenum(), address, 4, custom))
+ { /* if there is a custom read handler, and it returns true, use that value */
result = custom;
-
- /* otherwise, call the byte reading function for the translated address */
+ }
else
+ { /* otherwise, call the byte reading function for the translated address */
result = space.read_dword(address);
+ }
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
+ m_debugger_access = false;
+ space.set_debugger_access(false);
}
return result;
@@ -584,23 +514,20 @@ UINT32 debug_read_dword(address_space &space, offs_t address, int apply_translat
/*-------------------------------------------------
- debug_read_qword - return a qword from the
- specified memory space
+ read_qword - return a qword from the specified
+ memory space
-------------------------------------------------*/
-UINT64 debug_read_qword(address_space &space, offs_t address, int apply_translation)
+UINT64 debugger_cpu::read_qword(address_space &space, offs_t address, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
- UINT64 result;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
- /* if this is misaligned read, or if there are no qword readers, just read two dwords */
+ UINT64 result;
if (!QWORD_ALIGNED(address))
- {
- UINT32 dword0 = debug_read_dword(space, address + 0, apply_translation);
- UINT32 dword1 = debug_read_dword(space, address + 4, apply_translation);
+ { /* if this is a misaligned read, or if there are no qword readers, just read two dwords */
+ UINT32 dword0 = read_dword(space, address + 0, apply_translation);
+ UINT32 dword1 = read_dword(space, address + 4, apply_translation);
/* based on the endianness, the result is assembled differently */
if (space.endianness() == ENDIANNESS_LITTLE)
@@ -608,29 +535,31 @@ UINT64 debug_read_qword(address_space &space, offs_t address, int apply_translat
else
result = dword1 | ((UINT64)dword0 << 32);
}
-
- /* otherwise, this proceeds like the byte case */
else
- {
- UINT64 custom;
+ { /* otherwise, this proceeds like the byte case */
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
/* translate if necessary; if not mapped, return 0xffffffffffffffff */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_READ_DEBUG, &address))
+ UINT64 custom;
+ if (apply_translation && !translate(space, TRANSLATE_READ_DEBUG, &address))
+ {
result = ~(UINT64)0;
-
- /* if there is a custom read handler, and it returns true, use that value */
+ }
else if (space.device().memory().read(space.spacenum(), address, 8, custom))
+ { /* if there is a custom read handler, and it returns true, use that value */
result = custom;
-
- /* otherwise, call the byte reading function for the translated address */
+ }
else
+ { /* otherwise, call the byte reading function for the translated address */
result = space.read_qword(address);
+ }
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
+ m_debugger_access = false;
+ space.set_debugger_access(false);
}
return result;
@@ -638,41 +567,40 @@ UINT64 debug_read_qword(address_space &space, offs_t address, int apply_translat
/*-------------------------------------------------
- debug_read_memory - return 1,2,4 or 8 bytes
+ read_memory - return 1,2,4 or 8 bytes
from the specified memory space
-------------------------------------------------*/
-UINT64 debug_read_memory(address_space &space, offs_t address, int size, int apply_translation)
+UINT64 debugger_cpu::read_memory(address_space &space, offs_t address, int size, int apply_translation)
{
UINT64 result = ~(UINT64)0 >> (64 - 8*size);
switch (size)
{
- case 1: result = debug_read_byte(space, address, apply_translation); break;
- case 2: result = debug_read_word(space, address, apply_translation); break;
- case 4: result = debug_read_dword(space, address, apply_translation); break;
- case 8: result = debug_read_qword(space, address, apply_translation); break;
+ case 1: result = read_byte(space, address, apply_translation); break;
+ case 2: result = read_word(space, address, apply_translation); break;
+ case 4: result = read_dword(space, address, apply_translation); break;
+ case 8: result = read_qword(space, address, apply_translation); break;
}
return result;
}
/*-------------------------------------------------
- debug_write_byte - write a byte to the
- specified memory space
+ write_byte - write a byte to the specified
+ memory space
-------------------------------------------------*/
-void debug_write_byte(address_space &space, offs_t address, UINT8 data, int apply_translation)
+void debugger_cpu::write_byte(address_space &space, offs_t address, UINT8 data, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
/* translate if necessary; if not mapped, we're done */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
+ if (apply_translation && !translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
/* if there is a custom write handler, and it returns true, use that */
@@ -684,20 +612,20 @@ void debug_write_byte(address_space &space, offs_t address, UINT8 data, int appl
space.write_byte(address, data);
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
- global->memory_modified = true;
+ m_debugger_access = false;
+ space.set_debugger_access(false);
+
+ m_memory_modified = true;
}
/*-------------------------------------------------
- debug_write_word - write a word to the
- specified memory space
+ write_word - write a word to the specified
+ memory space
-------------------------------------------------*/
-void debug_write_word(address_space &space, offs_t address, UINT16 data, int apply_translation)
+void debugger_cpu::write_word(address_space &space, offs_t address, UINT16 data, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
@@ -706,13 +634,13 @@ void debug_write_word(address_space &space, offs_t address, UINT16 data, int app
{
if (space.endianness() == ENDIANNESS_LITTLE)
{
- debug_write_byte(space, address + 0, data >> 0, apply_translation);
- debug_write_byte(space, address + 1, data >> 8, apply_translation);
+ write_byte(space, address + 0, data >> 0, apply_translation);
+ write_byte(space, address + 1, data >> 8, apply_translation);
}
else
{
- debug_write_byte(space, address + 0, data >> 8, apply_translation);
- debug_write_byte(space, address + 1, data >> 0, apply_translation);
+ write_byte(space, address + 0, data >> 8, apply_translation);
+ write_byte(space, address + 1, data >> 0, apply_translation);
}
}
@@ -720,10 +648,11 @@ void debug_write_word(address_space &space, offs_t address, UINT16 data, int app
else
{
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
/* translate if necessary; if not mapped, we're done */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
+ if (apply_translation && !translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
/* if there is a custom write handler, and it returns true, use that */
@@ -735,21 +664,21 @@ void debug_write_word(address_space &space, offs_t address, UINT16 data, int app
space.write_word(address, data);
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
- global->memory_modified = true;
+ m_debugger_access = false;
+ space.set_debugger_access(false);
+
+ m_memory_modified = true;
}
}
/*-------------------------------------------------
- debug_write_dword - write a dword to the
- specified memory space
+ write_dword - write a dword to the specified
+ memory space
-------------------------------------------------*/
-void debug_write_dword(address_space &space, offs_t address, UINT32 data, int apply_translation)
+void debugger_cpu::write_dword(address_space &space, offs_t address, UINT32 data, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
@@ -758,13 +687,13 @@ void debug_write_dword(address_space &space, offs_t address, UINT32 data, int ap
{
if (space.endianness() == ENDIANNESS_LITTLE)
{
- debug_write_word(space, address + 0, data >> 0, apply_translation);
- debug_write_word(space, address + 2, data >> 16, apply_translation);
+ write_word(space, address + 0, data >> 0, apply_translation);
+ write_word(space, address + 2, data >> 16, apply_translation);
}
else
{
- debug_write_word(space, address + 0, data >> 16, apply_translation);
- debug_write_word(space, address + 2, data >> 0, apply_translation);
+ write_word(space, address + 0, data >> 16, apply_translation);
+ write_word(space, address + 2, data >> 0, apply_translation);
}
}
@@ -772,10 +701,10 @@ void debug_write_dword(address_space &space, offs_t address, UINT32 data, int ap
else
{
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ space.set_debugger_access(m_debugger_access = true);
/* translate if necessary; if not mapped, we're done */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
+ if (apply_translation && !translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
/* if there is a custom write handler, and it returns true, use that */
@@ -787,21 +716,21 @@ void debug_write_dword(address_space &space, offs_t address, UINT32 data, int ap
space.write_dword(address, data);
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
- global->memory_modified = true;
+ m_debugger_access = false;
+ space.set_debugger_access(false);
+
+ m_memory_modified = true;
}
}
/*-------------------------------------------------
- debug_write_qword - write a qword to the
- specified memory space
+ write_qword - write a qword to the specified
+ memory space
-------------------------------------------------*/
-void debug_write_qword(address_space &space, offs_t address, UINT64 data, int apply_translation)
+void debugger_cpu::write_qword(address_space &space, offs_t address, UINT64 data, int apply_translation)
{
- debugcpu_private *global = space.machine().debugcpu_data;
-
/* mask against the logical byte mask */
address &= space.logbytemask();
@@ -810,13 +739,13 @@ void debug_write_qword(address_space &space, offs_t address, UINT64 data, int ap
{
if (space.endianness() == ENDIANNESS_LITTLE)
{
- debug_write_dword(space, address + 0, data >> 0, apply_translation);
- debug_write_dword(space, address + 4, data >> 32, apply_translation);
+ write_dword(space, address + 0, data >> 0, apply_translation);
+ write_dword(space, address + 4, data >> 32, apply_translation);
}
else
{
- debug_write_dword(space, address + 0, data >> 32, apply_translation);
- debug_write_dword(space, address + 4, data >> 0, apply_translation);
+ write_dword(space, address + 0, data >> 32, apply_translation);
+ write_dword(space, address + 4, data >> 0, apply_translation);
}
}
@@ -824,10 +753,11 @@ void debug_write_qword(address_space &space, offs_t address, UINT64 data, int ap
else
{
/* all accesses from this point on are for the debugger */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
/* translate if necessary; if not mapped, we're done */
- if (apply_translation && !debug_cpu_translate(space, TRANSLATE_WRITE_DEBUG, &address))
+ if (apply_translation && !translate(space, TRANSLATE_WRITE_DEBUG, &address))
;
/* if there is a custom write handler, and it returns true, use that */
@@ -839,48 +769,51 @@ void debug_write_qword(address_space &space, offs_t address, UINT64 data, int ap
space.write_qword(address, data);
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
- global->memory_modified = true;
+ m_debugger_access = false;
+ space.set_debugger_access(false);
+
+ m_memory_modified = true;
}
}
/*-------------------------------------------------
- debug_write_memory - write 1,2,4 or 8 bytes
- to the specified memory space
+ write_memory - write 1,2,4 or 8 bytes to the
+ specified memory space
-------------------------------------------------*/
-void debug_write_memory(address_space &space, offs_t address, UINT64 data, int size, int apply_translation)
+void debugger_cpu::write_memory(address_space &space, offs_t address, UINT64 data, int size, int apply_translation)
{
switch (size)
{
- case 1: debug_write_byte(space, address, data, apply_translation); break;
- case 2: debug_write_word(space, address, data, apply_translation); break;
- case 4: debug_write_dword(space, address, data, apply_translation); break;
- case 8: debug_write_qword(space, address, data, apply_translation); break;
+ case 1: write_byte(space, address, data, apply_translation); break;
+ case 2: write_word(space, address, data, apply_translation); break;
+ case 4: write_dword(space, address, data, apply_translation); break;
+ case 8: write_qword(space, address, data, apply_translation); break;
}
}
/*-------------------------------------------------
- debug_read_opcode - read 1,2,4 or 8 bytes at
- the given offset from opcode space
+ read_opcode - read 1,2,4 or 8 bytes at the
+ given offset from opcode space
-------------------------------------------------*/
-UINT64 debug_read_opcode(address_space &space, offs_t address, int size)
+UINT64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size)
{
UINT64 result = ~(UINT64)0 & (~(UINT64)0 >> (64 - 8*size)), result2;
- debugcpu_private *global = space.machine().debugcpu_data;
/* keep in logical range */
address &= space.logbytemask();
/* return early if we got the result directly */
- space.set_debugger_access(global->debugger_access = true);
+ m_debugger_access = true;
+ space.set_debugger_access(true);
device_memory_interface *memory;
if (space.device().interface(memory) && memory->readop(address, size, result2))
{
- space.set_debugger_access(global->debugger_access = false);
+ m_debugger_access = false;
+ space.set_debugger_access(false);
return result2;
}
@@ -888,8 +821,8 @@ UINT64 debug_read_opcode(address_space &space, offs_t address, int size)
if (size > space.data_width() / 8)
{
int halfsize = size / 2;
- UINT64 r0 = debug_read_opcode(space, address + 0, halfsize);
- UINT64 r1 = debug_read_opcode(space, address + halfsize, halfsize);
+ UINT64 r0 = read_opcode(space, address + 0, halfsize);
+ UINT64 r1 = read_opcode(space, address + halfsize, halfsize);
if (space.endianness() == ENDIANNESS_LITTLE)
return r0 | (r1 << (8 * halfsize));
@@ -898,7 +831,7 @@ UINT64 debug_read_opcode(address_space &space, offs_t address, int size)
}
/* translate to physical first */
- if (!debug_cpu_translate(space, TRANSLATE_FETCH_DEBUG, &address))
+ if (!translate(space, TRANSLATE_FETCH_DEBUG, &address))
return result;
/* keep in physical range */
@@ -953,12 +886,15 @@ UINT64 debug_read_opcode(address_space &space, offs_t address, int size)
break;
default:
- fatalerror("debug_read_opcode: unknown type = %d\n", space.data_width() / 8 * 10 + size);
+ fatalerror("read_opcode: unknown type = %d\n", space.data_width() / 8 * 10 + size);
}
/* turn on debugger access */
- if (!global->debugger_access)
- space.set_debugger_access(global->debugger_access = true);
+ if (!m_debugger_access)
+ {
+ m_debugger_access = true;
+ space.set_debugger_access(true);
+ }
/* switch off the size and handle unaligned accesses */
switch (size)
@@ -1007,7 +943,9 @@ UINT64 debug_read_opcode(address_space &space, offs_t address, int size)
}
/* no longer accessing via the debugger */
- space.set_debugger_access(global->debugger_access = false);
+ m_debugger_access = false;
+ space.set_debugger_access(false);
+
return result;
}
@@ -1018,16 +956,12 @@ UINT64 debug_read_opcode(address_space &space, offs_t address, int size)
***************************************************************************/
/*-------------------------------------------------
- debug_cpu_exit - free all memory
+ exit - free all memory
-------------------------------------------------*/
-static void debug_cpu_exit(running_machine &machine)
+void debugger_cpu::exit()
{
- debugcpu_private *global = machine.debugcpu_data;
-
- /* free the global symbol table */
- if (global != nullptr)
- global_free(global->symtable);
+ global_free(m_symtable);
}
@@ -1035,11 +969,10 @@ static void debug_cpu_exit(running_machine &machine)
on_vblank - called when a VBLANK hits
-------------------------------------------------*/
-static void on_vblank(running_machine &machine, screen_device &device, bool vblank_state)
+void debugger_cpu::on_vblank(screen_device &device, bool vblank_state)
{
/* just set a global flag to be consumed later */
- if (vblank_state)
- device.machine().debugcpu_data->vblank_occurred = true;
+ m_vblank_occurred = true;
}
@@ -1048,12 +981,12 @@ static void on_vblank(running_machine &machine, screen_device &device, bool vbla
flags on all CPUs
-------------------------------------------------*/
-static void reset_transient_flags(running_machine &machine)
+void debugger_cpu::reset_transient_flags()
{
/* loop over CPUs and reset the transient flags */
- for (device_t &device : device_iterator(machine.root_device()))
+ for (device_t &device : device_iterator(m_machine.root_device()))
device.debug()->reset_transient_flag();
- machine.debugcpu_data->m_stop_when_not_device = nullptr;
+ m_stop_when_not_device = nullptr;
}
@@ -1062,42 +995,37 @@ static void reset_transient_flags(running_machine &machine)
a source file
-------------------------------------------------*/
-static void process_source_file(running_machine &machine)
+void debugger_cpu::process_source_file()
{
- debugcpu_private *global = machine.debugcpu_data;
-
/* loop until the file is exhausted or until we are executing again */
- while (global->source_file != nullptr && global->execution_state == EXECUTION_STATE_STOPPED)
+ while (m_source_file != nullptr && m_execution_state == EXECUTION_STATE_STOPPED)
{
- char buf[512];
- int i;
- char *s;
-
/* stop at the end of file */
- if (feof(global->source_file))
+ if (feof(m_source_file))
{
- fclose(global->source_file);
- global->source_file = nullptr;
+ fclose(m_source_file);
+ m_source_file = nullptr;
return;
}
/* fetch the next line */
+ char buf[512];
memset(buf, 0, sizeof(buf));
- fgets(buf, sizeof(buf), global->source_file);
+ fgets(buf, sizeof(buf), m_source_file);
/* strip out comments (text after '//') */
- s = strstr(buf, "//");
+ char *s = strstr(buf, "//");
if (s)
*s = '\0';
/* strip whitespace */
- i = (int)strlen(buf);
+ int i = (int)strlen(buf);
while((i > 0) && (isspace((UINT8)buf[i-1])))
buf[--i] = '\0';
/* execute the command */
if (buf[0])
- debug_console_execute_command(machine, buf, 1);
+ m_machine.debugger().console().execute_command(buf, true);
}
}
@@ -1112,12 +1040,12 @@ static void process_source_file(running_machine &machine)
based on a case insensitive tag search
-------------------------------------------------*/
-static device_t *expression_get_device(running_machine &machine, const char *tag)
+device_t* debugger_cpu::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 machine.device(fullname.c_str());
+ return m_machine.device(fullname.c_str());
}
@@ -1127,63 +1055,69 @@ static device_t *expression_get_device(running_machine &machine, const char *tag
space
-------------------------------------------------*/
-static UINT64 expression_read_memory(void *param, const char *name, expression_space spacenum, UINT32 address, int size)
+UINT64 debugger_cpu::expression_read_memory(void *param, const char *name, expression_space spacenum, UINT32 address, int size)
{
- running_machine &machine = *(running_machine *)param;
- UINT64 result = ~(UINT64)0 >> (64 - 8*size);
- device_t *device = nullptr;
-
switch (spacenum)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
case EXPSPACE_IO_LOGICAL:
case EXPSPACE_SPACE3_LOGICAL:
+ {
+ device_t *device = nullptr;
if (name != nullptr)
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (device == nullptr)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (device->memory().has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
{
address_space &space = device->memory().space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
- result = debug_read_memory(space, space.address_to_byte(address), size, true);
+ return read_memory(space, space.address_to_byte(address), size, true);
}
break;
+ }
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
case EXPSPACE_SPACE3_PHYSICAL:
+ {
+ device_t *device = nullptr;
if (name != nullptr)
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (device == nullptr)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (device->memory().has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
{
address_space &space = device->memory().space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
- result = debug_read_memory(space, space.address_to_byte(address), size, false);
+ return read_memory(space, space.address_to_byte(address), size, false);
}
break;
+ }
case EXPSPACE_OPCODE:
case EXPSPACE_RAMWRITE:
+ {
+ device_t *device = nullptr;
if (name != nullptr)
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (device == nullptr)
- device = debug_cpu_get_visible_cpu(machine);
- result = expression_read_program_direct(device->memory().space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size);
+ device = m_machine.debugger().cpu().get_visible_cpu();
+ return expression_read_program_direct(device->memory().space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size);
break;
+ }
case EXPSPACE_REGION:
if (name == nullptr)
break;
- result = expression_read_memory_region(machine, name, address, size);
+ return expression_read_memory_region(name, address, size);
break;
default:
break;
}
- return result;
+
+ return 0;
}
@@ -1192,9 +1126,8 @@ static UINT64 expression_read_memory(void *param, const char *name, expression_s
directly from an opcode or RAM pointer
-------------------------------------------------*/
-static UINT64 expression_read_program_direct(address_space &space, int opcode, offs_t address, int size)
+UINT64 debugger_cpu::expression_read_program_direct(address_space &space, int opcode, offs_t address, int size)
{
- UINT64 result = ~(UINT64)0 >> (64 - 8*size);
UINT8 *base;
/* adjust the address into a byte address, but not if being called recursively */
@@ -1205,17 +1138,16 @@ static UINT64 expression_read_program_direct(address_space &space, int opcode, o
if (size > 1)
{
int halfsize = size / 2;
- UINT64 r0, r1;
/* read each half, from lower address to upper address */
- r0 = expression_read_program_direct(space, opcode | 2, address + 0, halfsize);
- r1 = expression_read_program_direct(space, opcode | 2, address + halfsize, halfsize);
+ UINT64 r0 = expression_read_program_direct(space, opcode | 2, address + 0, halfsize);
+ UINT64 r1 = expression_read_program_direct(space, opcode | 2, address + halfsize, halfsize);
/* assemble based on the target endianness */
if (space.endianness() == ENDIANNESS_LITTLE)
- result = r0 | (r1 << (8 * halfsize));
+ return r0 | (r1 << (8 * halfsize));
else
- result = r1 | (r0 << (8 * halfsize));
+ return r1 | (r0 << (8 * halfsize));
}
/* handle the byte-sized final requests */
@@ -1231,12 +1163,13 @@ static UINT64 expression_read_program_direct(address_space &space, int opcode, o
if (base != nullptr)
{
if (space.endianness() == ENDIANNESS_LITTLE)
- result = base[BYTE8_XOR_LE(address) & lowmask];
+ return base[BYTE8_XOR_LE(address) & lowmask];
else
- result = base[BYTE8_XOR_BE(address) & lowmask];
+ return base[BYTE8_XOR_BE(address) & lowmask];
}
}
- return result;
+
+ return 0;
}
@@ -1245,9 +1178,9 @@ static UINT64 expression_read_program_direct(address_space &space, int opcode, o
from a memory region
-------------------------------------------------*/
-static UINT64 expression_read_memory_region(running_machine &machine, const char *rgntag, offs_t address, int size)
+UINT64 debugger_cpu::expression_read_memory_region(const char *rgntag, offs_t address, int size)
{
- memory_region *region = machine.root_device().memregion(rgntag);
+ memory_region *region = m_machine.root_device().memregion(rgntag);
UINT64 result = ~(UINT64)0 >> (64 - 8*size);
/* make sure we get a valid base before proceeding */
@@ -1260,8 +1193,8 @@ static UINT64 expression_read_memory_region(running_machine &machine, const char
UINT64 r0, r1;
/* read each half, from lower address to upper address */
- r0 = expression_read_memory_region(machine, rgntag, address + 0, halfsize);
- r1 = expression_read_memory_region(machine, rgntag, address + halfsize, halfsize);
+ r0 = expression_read_memory_region(rgntag, address + 0, halfsize);
+ r1 = expression_read_memory_region(rgntag, address + halfsize, halfsize);
/* assemble based on the target endianness */
if (region->endianness() == ENDIANNESS_LITTLE)
@@ -1294,9 +1227,8 @@ static UINT64 expression_read_memory_region(running_machine &machine, const char
space
-------------------------------------------------*/
-static void expression_write_memory(void *param, const char *name, expression_space spacenum, UINT32 address, int size, UINT64 data)
+void debugger_cpu::expression_write_memory(void *param, const char *name, expression_space spacenum, UINT32 address, int size, UINT64 data)
{
- running_machine &machine = *(running_machine *)param;
device_t *device = nullptr;
switch (spacenum)
@@ -1306,13 +1238,13 @@ static void expression_write_memory(void *param, const char *name, expression_sp
case EXPSPACE_IO_LOGICAL:
case EXPSPACE_SPACE3_LOGICAL:
if (name != nullptr)
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (device == nullptr)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (device->memory().has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
{
address_space &space = device->memory().space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
- debug_write_memory(space, space.address_to_byte(address), data, size, true);
+ write_memory(space, space.address_to_byte(address), data, size, true);
}
break;
@@ -1321,29 +1253,29 @@ static void expression_write_memory(void *param, const char *name, expression_sp
case EXPSPACE_IO_PHYSICAL:
case EXPSPACE_SPACE3_PHYSICAL:
if (name != nullptr)
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (device == nullptr)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (device->memory().has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
{
address_space &space = device->memory().space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
- debug_write_memory(space, space.address_to_byte(address), data, size, false);
+ write_memory(space, space.address_to_byte(address), data, size, false);
}
break;
case EXPSPACE_OPCODE:
case EXPSPACE_RAMWRITE:
if (name != nullptr)
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (device == nullptr)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
expression_write_program_direct(device->memory().space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size, data);
break;
case EXPSPACE_REGION:
if (name == nullptr)
break;
- expression_write_memory_region(machine, name, address, size, data);
+ expression_write_memory_region(name, address, size, data);
break;
default:
@@ -1357,11 +1289,8 @@ static void expression_write_memory(void *param, const char *name, expression_sp
directly to an opcode or RAM pointer
-------------------------------------------------*/
-static void expression_write_program_direct(address_space &space, int opcode, offs_t address, int size, UINT64 data)
+void debugger_cpu::expression_write_program_direct(address_space &space, int opcode, offs_t address, int size, UINT64 data)
{
- debugcpu_private *global = space.machine().debugcpu_data;
- UINT8 *base;
-
/* adjust the address into a byte address, but not if being called recursively */
if ((opcode & 2) == 0)
address = space.address_to_byte(address);
@@ -1370,10 +1299,10 @@ static void expression_write_program_direct(address_space &space, int opcode, of
if (size > 1)
{
int halfsize = size / 2;
- UINT64 r0, r1, halfmask;
/* break apart based on the target endianness */
- halfmask = ~(UINT64)0 >> (64 - 8 * halfsize);
+ UINT64 halfmask = ~(UINT64)0 >> (64 - 8 * halfsize);
+ UINT64 r0, r1;
if (space.endianness() == ENDIANNESS_LITTLE)
{
r0 = data & halfmask;
@@ -1397,7 +1326,7 @@ static void expression_write_program_direct(address_space &space, int opcode, of
offs_t lowmask = space.data_width() / 8 - 1;
/* get the base of memory, aligned to the address minus the lowbits */
- base = (UINT8 *)space.get_read_ptr(address & ~lowmask);
+ UINT8 *base = (UINT8 *)space.get_read_ptr(address & ~lowmask);
/* if we have a valid base, write the appropriate byte */
if (base != nullptr)
@@ -1406,7 +1335,7 @@ static void expression_write_program_direct(address_space &space, int opcode, of
base[BYTE8_XOR_LE(address) & lowmask] = data;
else
base[BYTE8_XOR_BE(address) & lowmask] = data;
- global->memory_modified = true;
+ m_memory_modified = true;
}
}
}
@@ -1417,10 +1346,9 @@ static void expression_write_program_direct(address_space &space, int opcode, of
from a memory region
-------------------------------------------------*/
-static void expression_write_memory_region(running_machine &machine, const char *rgntag, offs_t address, int size, UINT64 data)
+void debugger_cpu::expression_write_memory_region(const char *rgntag, offs_t address, int size, UINT64 data)
{
- debugcpu_private *global = machine.debugcpu_data;
- memory_region *region = machine.root_device().memregion(rgntag);
+ memory_region *region = m_machine.root_device().memregion(rgntag);
/* make sure we get a valid base before proceeding */
if (region != nullptr)
@@ -1429,10 +1357,10 @@ static void expression_write_memory_region(running_machine &machine, const char
if (size > 1)
{
int halfsize = size / 2;
- UINT64 r0, r1, halfmask;
/* break apart based on the target endianness */
- halfmask = ~(UINT64)0 >> (64 - 8 * halfsize);
+ UINT64 halfmask = ~(UINT64)0 >> (64 - 8 * halfsize);
+ UINT64 r0, r1;
if (region->endianness() == ENDIANNESS_LITTLE)
{
r0 = data & halfmask;
@@ -1445,8 +1373,8 @@ static void expression_write_memory_region(running_machine &machine, const char
}
/* write each half, from lower address to upper address */
- expression_write_memory_region(machine, rgntag, address + 0, halfsize, r0);
- expression_write_memory_region(machine, rgntag, address + halfsize, halfsize, r1);
+ expression_write_memory_region(rgntag, address + 0, halfsize, r0);
+ expression_write_memory_region(rgntag, address + halfsize, halfsize, r1);
}
/* only process if we're within range */
@@ -1458,10 +1386,14 @@ static void expression_write_memory_region(running_machine &machine, const char
/* 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;
- global->memory_modified = true;
+ }
+ m_memory_modified = true;
}
}
}
@@ -1473,9 +1405,8 @@ static void expression_write_memory_region(running_machine &machine, const char
appropriate name
-------------------------------------------------*/
-static expression_error::error_code expression_validate(void *param, const char *name, expression_space space)
+expression_error::error_code debugger_cpu::expression_validate(void *param, const char *name, expression_space space)
{
- running_machine &machine = *reinterpret_cast<running_machine *>(param);
device_t *device = nullptr;
switch (space)
@@ -1486,12 +1417,12 @@ static expression_error::error_code expression_validate(void *param, const char
case EXPSPACE_SPACE3_LOGICAL:
if (name)
{
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (!device)
return expression_error::INVALID_MEMORY_NAME;
}
if (!device)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (!device->memory().has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL)))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
@@ -1502,12 +1433,12 @@ static expression_error::error_code expression_validate(void *param, const char
case EXPSPACE_SPACE3_PHYSICAL:
if (name)
{
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (!device)
return expression_error::INVALID_MEMORY_NAME;
}
if (!device)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (!device->memory().has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL)))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
@@ -1516,12 +1447,12 @@ static expression_error::error_code expression_validate(void *param, const char
case EXPSPACE_RAMWRITE:
if (name)
{
- device = expression_get_device(machine, name);
+ device = expression_get_device(name);
if (!device)
return expression_error::INVALID_MEMORY_NAME;
}
if (!device)
- device = debug_cpu_get_visible_cpu(machine);
+ device = m_machine.debugger().cpu().get_visible_cpu();
if (!device->memory().has_space(AS_PROGRAM))
return expression_error::NO_SUCH_MEMORY_SPACE;
break;
@@ -1529,7 +1460,7 @@ static expression_error::error_code expression_validate(void *param, const char
case EXPSPACE_REGION:
if (!name)
return expression_error::MISSING_MEMORY_NAME;
- if (!machine.root_device().memregion(name) || !machine.root_device().memregion(name)->base())
+ if (!m_machine.root_device().memregion(name) || !m_machine.root_device().memregion(name)->base())
return expression_error::INVALID_MEMORY_NAME;
break;
@@ -1549,7 +1480,7 @@ static expression_error::error_code expression_validate(void *param, const char
get_beamx - get beam horizontal position
-------------------------------------------------*/
-static UINT64 get_beamx(symbol_table &table, void *ref)
+UINT64 debugger_cpu::get_beamx(symbol_table &table, void *ref)
{
screen_device *screen = reinterpret_cast<screen_device *>(ref);
return (screen != nullptr) ? screen->hpos() : 0;
@@ -1560,7 +1491,7 @@ static UINT64 get_beamx(symbol_table &table, void *ref)
get_beamy - get beam vertical position
-------------------------------------------------*/
-static UINT64 get_beamy(symbol_table &table, void *ref)
+UINT64 debugger_cpu::get_beamy(symbol_table &table, void *ref)
{
screen_device *screen = reinterpret_cast<screen_device *>(ref);
return (screen != nullptr) ? screen->vpos() : 0;
@@ -1571,7 +1502,7 @@ static UINT64 get_beamy(symbol_table &table, void *ref)
get_frame - get current frame number
-------------------------------------------------*/
-static UINT64 get_frame(symbol_table &table, void *ref)
+UINT64 debugger_cpu::get_frame(symbol_table &table, void *ref)
{
screen_device *screen = reinterpret_cast<screen_device *>(ref);
return (screen != nullptr) ? screen->frame_number() : 0;
@@ -1583,16 +1514,116 @@ static UINT64 get_frame(symbol_table &table, void *ref)
'cpunum' symbol
-------------------------------------------------*/
-static UINT64 get_cpunum(symbol_table &table, void *ref)
+UINT64 debugger_cpu::get_cpunum(symbol_table &table, void *ref)
{
- running_machine &machine = *reinterpret_cast<running_machine *>(table.globalref());
- device_t *target = machine.debugcpu_data->visiblecpu;
+ execute_interface_iterator iter(m_machine.root_device());
+ return iter.indexof(m_visiblecpu->execute());
+}
+
+
+void debugger_cpu::start_hook(device_t *device, bool stop_on_vblank)
+{
+ // stash a pointer to the current live CPU
+ assert(m_livecpu == nullptr);
+ m_livecpu = device;
+
+ // if we're a new device, stop now
+ if (m_stop_when_not_device != nullptr && m_stop_when_not_device != device)
+ {
+ m_stop_when_not_device = nullptr;
+ m_execution_state = EXECUTION_STATE_STOPPED;
+ reset_transient_flags();
+ }
- execute_interface_iterator iter(machine.root_device());
- return iter.indexof(target->execute());
+ // if we're running, do some periodic updating
+ if (m_execution_state != EXECUTION_STATE_STOPPED)
+ {
+ if (device == m_visiblecpu && osd_ticks() > m_last_periodic_update_time + osd_ticks_per_second() / 4)
+ { // check for periodic updates
+ m_machine.debug_view().update_all();
+ m_machine.debug_view().flush_osd_updates();
+ m_last_periodic_update_time = osd_ticks();
+ }
+ else if (device == m_breakcpu)
+ { // check for pending breaks
+ m_execution_state = EXECUTION_STATE_STOPPED;
+ m_breakcpu = nullptr;
+ }
+
+ // if a VBLANK occurred, check on things
+ if (m_vblank_occurred)
+ {
+ m_vblank_occurred = false;
+
+ // if we were waiting for a VBLANK, signal it now
+ if (stop_on_vblank)
+ {
+ m_execution_state = EXECUTION_STATE_STOPPED;
+ m_machine.debugger().console().printf("Stopped at VBLANK\n");
+ }
+ }
+ // check for debug keypresses
+ if (m_machine.ui_input().pressed(IPT_UI_DEBUG_BREAK))
+ m_visiblecpu->debug()->halt_on_next_instruction("User-initiated break\n");
+ }
}
+void debugger_cpu::stop_hook(device_t *device)
+{
+ assert(m_livecpu == device);
+ // clear the live CPU
+ m_livecpu = nullptr;
+}
+
+void debugger_cpu::ensure_comments_loaded()
+{
+ if (!m_comments_loaded)
+ {
+ comment_load(true);
+ m_comments_loaded = true;
+ }
+}
+
+
+//-------------------------------------------------
+// go_next_device - execute until we hit the next
+// device
+//-------------------------------------------------
+
+void debugger_cpu::go_next_device(device_t *device)
+{
+ m_stop_when_not_device = device;
+ m_execution_state = EXECUTION_STATE_RUNNING;
+}
+
+void debugger_cpu::go_vblank()
+{
+ m_vblank_occurred = false;
+ m_execution_state = EXECUTION_STATE_RUNNING;
+}
+
+void debugger_cpu::halt_on_next_instruction(device_t *device, util::format_argument_pack<std::ostream> &&args)
+{
+ // if something is pending on this CPU already, ignore this request
+ if (device == m_breakcpu)
+ return;
+
+ // output the message to the console
+ m_machine.debugger().console().vprintf(std::move(args));
+
+ // if we are live, stop now, otherwise note that we want to break there
+ if (device == m_livecpu)
+ {
+ m_execution_state = EXECUTION_STATE_STOPPED;
+ if (m_livecpu != nullptr)
+ m_livecpu->debug()->compute_debug_flags();
+ }
+ else
+ {
+ m_breakcpu = device;
+ }
+}
//**************************************************************************
// DEVICE DEBUG
@@ -1603,36 +1634,36 @@ static UINT64 get_cpunum(symbol_table &table, void *ref)
//-------------------------------------------------
device_debug::device_debug(device_t &device)
- : m_device(device),
- m_exec(nullptr),
- m_memory(nullptr),
- m_state(nullptr),
- m_disasm(nullptr),
- m_flags(0),
- m_symtable(&device, debug_cpu_get_global_symtable(device.machine())),
- m_instrhook(nullptr),
- m_dasm_override(nullptr),
- m_opwidth(0),
- m_stepaddr(0),
- m_stepsleft(0),
- m_stopaddr(0),
- m_stoptime(attotime::zero),
- m_stopirq(0),
- m_stopexception(0),
- m_endexectime(attotime::zero),
- m_total_cycles(0),
- m_last_total_cycles(0),
- m_pc_history_index(0),
- m_bplist(nullptr),
- m_rplist(nullptr),
- m_trace(nullptr),
- m_hotspot_threshhold(0),
- m_track_pc_set(),
- m_track_pc(false),
- m_comment_set(),
- m_comment_change(0),
- m_track_mem_set(),
- m_track_mem(false)
+ : m_device(device)
+ , m_exec(nullptr)
+ , m_memory(nullptr)
+ , m_state(nullptr)
+ , m_disasm(nullptr)
+ , m_flags(0)
+ , m_symtable(&device, device.machine().debugger().cpu().get_global_symtable())
+ , m_instrhook(nullptr)
+ , m_dasm_override(nullptr)
+ , m_opwidth(0)
+ , m_stepaddr(0)
+ , m_stepsleft(0)
+ , m_stopaddr(0)
+ , m_stoptime(attotime::zero)
+ , m_stopirq(0)
+ , m_stopexception(0)
+ , m_endexectime(attotime::zero)
+ , m_total_cycles(0)
+ , m_last_total_cycles(0)
+ , m_pc_history_index(0)
+ , m_bplist(nullptr)
+ , m_rplist(nullptr)
+ , m_trace(nullptr)
+ , m_hotspot_threshhold(0)
+ , m_track_pc_set()
+ , m_track_pc(false)
+ , m_comment_set()
+ , m_comment_change(0)
+ , m_track_mem_set()
+ , m_track_mem(false)
{
memset(m_pc_history, 0, sizeof(m_pc_history));
memset(m_wplist, 0, sizeof(m_wplist));
@@ -1699,7 +1730,6 @@ device_debug::~device_debug()
registerpoint_clear_all();
}
-
//-------------------------------------------------
// start_hook - the scheduler calls this hook
// before beginning execution for the given device
@@ -1707,60 +1737,13 @@ device_debug::~device_debug()
void device_debug::start_hook(const attotime &endtime)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert((m_device.machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
- // stash a pointer to the current live CPU
- assert(global->livecpu == nullptr);
- global->livecpu = &m_device;
-
- // if we're a new device, stop now
- if (global->m_stop_when_not_device != nullptr && global->m_stop_when_not_device != &m_device)
- {
- global->m_stop_when_not_device = nullptr;
- global->execution_state = EXECUTION_STATE_STOPPED;
- reset_transient_flags(m_device.machine());
- }
+ m_device.machine().debugger().cpu().start_hook(&m_device, (m_flags & DEBUG_FLAG_STOP_VBLANK) != 0);
// update the target execution end time
m_endexectime = endtime;
- // if we're running, do some periodic updating
- if (global->execution_state != EXECUTION_STATE_STOPPED)
- {
- // check for periodic updates
- if (&m_device == global->visiblecpu && osd_ticks() > global->last_periodic_update_time + osd_ticks_per_second()/4)
- {
- m_device.machine().debug_view().update_all();
- m_device.machine().debug_view().flush_osd_updates();
- global->last_periodic_update_time = osd_ticks();
- }
-
- // check for pending breaks
- else if (&m_device == global->breakcpu)
- {
- global->execution_state = EXECUTION_STATE_STOPPED;
- global->breakcpu = nullptr;
- }
-
- // if a VBLANK occurred, check on things
- if (global->vblank_occurred)
- {
- global->vblank_occurred = false;
-
- // if we were waiting for a VBLANK, signal it now
- if ((m_flags & DEBUG_FLAG_STOP_VBLANK) != 0)
- {
- global->execution_state = EXECUTION_STATE_STOPPED;
- debug_console_printf(m_device.machine(), "Stopped at VBLANK\n");
- }
- }
- // check for debug keypresses
- if (m_device.machine().ui_input().pressed(IPT_UI_DEBUG_BREAK))
- global->visiblecpu->debug()->halt_on_next_instruction("User-initiated break\n");
- }
-
// recompute the debugging mode
compute_debug_flags();
}
@@ -1773,12 +1756,7 @@ void device_debug::start_hook(const attotime &endtime)
void device_debug::stop_hook()
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
- assert(global->livecpu == &m_device);
-
- // clear the live CPU
- global->livecpu = nullptr;
+ m_device.machine().debugger().cpu().stop_hook(&m_device);
}
@@ -1789,13 +1767,11 @@ void device_debug::stop_hook()
void device_debug::interrupt_hook(int irqline)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
// see if this matches a pending interrupt request
if ((m_flags & DEBUG_FLAG_STOP_INTERRUPT) != 0 && (m_stopirq == -1 || m_stopirq == irqline))
{
- global->execution_state = EXECUTION_STATE_STOPPED;
- debug_console_printf(m_device.machine(), "Stopped on interrupt (CPU '%s', IRQ %d)\n", m_device.tag(), irqline);
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_STOPPED);
+ m_device.machine().debugger().console().printf("Stopped on interrupt (CPU '%s', IRQ %d)\n", m_device.tag(), irqline);
compute_debug_flags();
}
}
@@ -1808,13 +1784,11 @@ void device_debug::interrupt_hook(int irqline)
void device_debug::exception_hook(int exception)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
// see if this matches a pending interrupt request
if ((m_flags & DEBUG_FLAG_STOP_EXCEPTION) != 0 && (m_stopexception == -1 || m_stopexception == exception))
{
- global->execution_state = EXECUTION_STATE_STOPPED;
- debug_console_printf(m_device.machine(), "Stopped on exception (CPU '%s', exception %d)\n", m_device.tag(), exception);
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_STOPPED);
+ m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %d)\n", m_device.tag(), exception);
compute_debug_flags();
}
}
@@ -1828,10 +1802,10 @@ void device_debug::exception_hook(int exception)
void device_debug::instruction_hook(offs_t curpc)
{
running_machine &machine = m_device.machine();
- debugcpu_private *global = machine.debugcpu_data;
+ debugger_cpu& debugcpu = machine.debugger().cpu();
// note that we are in the debugger code
- global->within_instruction_hook = true;
+ debugcpu.set_within_instruction(true);
// update the history
m_pc_history[m_pc_history_index++ % HISTORY_SIZE] = curpc;
@@ -1852,11 +1826,11 @@ void device_debug::instruction_hook(offs_t curpc)
m_trace->update(curpc);
// per-instruction hook?
- if (global->execution_state != EXECUTION_STATE_STOPPED && (m_flags & DEBUG_FLAG_HOOKED) != 0 && (*m_instrhook)(m_device, curpc))
- global->execution_state = EXECUTION_STATE_STOPPED;
+ if (debugcpu.execution_state() != EXECUTION_STATE_STOPPED && (m_flags & DEBUG_FLAG_HOOKED) != 0 && (*m_instrhook)(m_device, curpc))
+ debugcpu.set_execution_state(EXECUTION_STATE_STOPPED);
// handle single stepping
- if (global->execution_state != EXECUTION_STATE_STOPPED && (m_flags & DEBUG_FLAG_STEPPING_ANY) != 0)
+ if (debugcpu.execution_state() != EXECUTION_STATE_STOPPED && (m_flags & DEBUG_FLAG_STEPPING_ANY) != 0)
{
// is this an actual step?
if (m_stepaddr == ~0 || curpc == m_stepaddr)
@@ -1867,7 +1841,7 @@ void device_debug::instruction_hook(offs_t curpc)
// if we hit 0, stop
if (m_stepsleft == 0)
- global->execution_state = EXECUTION_STATE_STOPPED;
+ debugcpu.set_execution_state(EXECUTION_STATE_STOPPED);
// update every 100 steps until we are within 200 of the end
else if ((m_flags & DEBUG_FLAG_STEPPING_OUT) == 0 && (m_stepsleft < 200 || m_stepsleft % 100 == 0))
@@ -1880,20 +1854,20 @@ void device_debug::instruction_hook(offs_t curpc)
}
// handle breakpoints
- if (global->execution_state != EXECUTION_STATE_STOPPED && (m_flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
+ if (debugcpu.execution_state() != EXECUTION_STATE_STOPPED && (m_flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
{
// see if we hit a target time
if ((m_flags & DEBUG_FLAG_STOP_TIME) != 0 && machine.time() >= m_stoptime)
{
- debug_console_printf(machine, "Stopped at time interval %.1g\n", machine.time().as_double());
- global->execution_state = EXECUTION_STATE_STOPPED;
+ machine.debugger().console().printf("Stopped at time interval %.1g\n", machine.time().as_double());
+ debugcpu.set_execution_state(EXECUTION_STATE_STOPPED);
}
// check the temp running breakpoint and break if we hit it
else if ((m_flags & DEBUG_FLAG_STOP_PC) != 0 && m_stopaddr == curpc)
{
- debug_console_printf(machine, "Stopped at temporary breakpoint %X on CPU '%s'\n", m_stopaddr, m_device.tag());
- global->execution_state = EXECUTION_STATE_STOPPED;
+ machine.debugger().console().printf("Stopped at temporary breakpoint %X on CPU '%s'\n", m_stopaddr, m_device.tag());
+ debugcpu.set_execution_state(EXECUTION_STATE_STOPPED);
}
// check for execution breakpoints
@@ -1902,23 +1876,19 @@ void device_debug::instruction_hook(offs_t curpc)
}
// if we are supposed to halt, do it now
- if (global->execution_state == EXECUTION_STATE_STOPPED)
+ if (debugcpu.execution_state() == EXECUTION_STATE_STOPPED)
{
bool firststop = true;
// load comments if we haven't yet
- if (!global->comments_loaded)
- {
- debug_comment_load(m_device.machine(),true);
- global->comments_loaded = true;
- }
+ debugcpu.ensure_comments_loaded();
// reset any transient state
- reset_transient_flags(m_device.machine());
- global->breakcpu = nullptr;
+ debugcpu.reset_transient_flags();
+ debugcpu.set_break_cpu(nullptr);
// remember the last visible CPU in the debugger
- global->visiblecpu = &m_device;
+ debugcpu.set_visible_cpu(&m_device);
// update all views
machine.debug_view().update_all();
@@ -1926,7 +1896,7 @@ void device_debug::instruction_hook(offs_t curpc)
// wait for the debugger; during this time, disable sound output
m_device.machine().sound().debugger_mute(true);
- while (global->execution_state == EXECUTION_STATE_STOPPED)
+ while (debugcpu.execution_state() == EXECUTION_STATE_STOPPED)
{
// flush any pending updates before waiting again
machine.debug_view().flush_osd_updates();
@@ -1934,29 +1904,29 @@ void device_debug::instruction_hook(offs_t curpc)
emulator_info::periodic_check();
// clear the memory modified flag and wait
- global->memory_modified = false;
+ debugcpu.set_memory_modified(false);
if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
machine.osd().wait_for_debugger(m_device, firststop);
firststop = false;
// if something modified memory, update the screen
- if (global->memory_modified)
+ if (debugcpu.memory_modified())
{
machine.debug_view().update_all(DVT_DISASSEMBLY);
machine.debugger().refresh_display();
}
// check for commands in the source file
- process_source_file(m_device.machine());
+ machine.debugger().cpu().process_source_file();
// if an event got scheduled, resume
if (machine.scheduled_event_pending())
- global->execution_state = EXECUTION_STATE_RUNNING;
+ debugcpu.set_execution_state(EXECUTION_STATE_RUNNING);
}
m_device.machine().sound().debugger_mute(false);
// remember the last visible CPU in the debugger
- global->visiblecpu = &m_device;
+ debugcpu.set_visible_cpu(&m_device);
}
// handle step out/over on the instruction we are about to execute
@@ -1964,7 +1934,7 @@ void device_debug::instruction_hook(offs_t curpc)
prepare_for_step_overout(pc());
// no longer in debugger code
- global->within_instruction_hook = false;
+ debugcpu.set_within_instruction(false);
}
@@ -2060,8 +2030,6 @@ offs_t device_debug::disassemble(char *buffer, offs_t pc, const UINT8 *oprom, co
void device_debug::ignore(bool ignore)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
if (ignore)
@@ -2069,8 +2037,11 @@ void device_debug::ignore(bool ignore)
else
m_flags |= DEBUG_FLAG_OBSERVING;
- if (&m_device == global->livecpu && ignore)
+ if (&m_device == m_device.machine().debugger().cpu().live_cpu() && ignore)
+ {
+ assert(m_exec != nullptr);
go_next_device();
+ }
}
@@ -2081,14 +2052,12 @@ void device_debug::ignore(bool ignore)
void device_debug::single_step(int numsteps)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stepsleft = numsteps;
m_stepaddr = ~0;
m_flags |= DEBUG_FLAG_STEPPING;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
@@ -2099,14 +2068,12 @@ void device_debug::single_step(int numsteps)
void device_debug::single_step_over(int numsteps)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stepsleft = numsteps;
m_stepaddr = ~0;
m_flags |= DEBUG_FLAG_STEPPING_OVER;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
@@ -2117,14 +2084,12 @@ void device_debug::single_step_over(int numsteps)
void device_debug::single_step_out()
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stepsleft = 100;
m_stepaddr = ~0;
m_flags |= DEBUG_FLAG_STEPPING_OUT;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
@@ -2135,13 +2100,11 @@ void device_debug::single_step_out()
void device_debug::go(offs_t targetpc)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stopaddr = targetpc;
m_flags |= DEBUG_FLAG_STOP_PC;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
@@ -2151,13 +2114,10 @@ void device_debug::go(offs_t targetpc)
void device_debug::go_vblank()
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
- global->vblank_occurred = false;
m_flags |= DEBUG_FLAG_STOP_VBLANK;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().go_vblank();
}
@@ -2168,15 +2128,17 @@ void device_debug::go_vblank()
void device_debug::go_interrupt(int irqline)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stopirq = irqline;
m_flags |= DEBUG_FLAG_STOP_INTERRUPT;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
+void device_debug::go_next_device()
+{
+ m_device.machine().debugger().cpu().go_next_device(&m_device);
+}
//-------------------------------------------------
// go_exception - execute until the specified
@@ -2185,13 +2147,11 @@ void device_debug::go_interrupt(int irqline)
void device_debug::go_exception(int exception)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stopexception = exception;
m_flags |= DEBUG_FLAG_STOP_EXCEPTION;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
@@ -2202,62 +2162,27 @@ void device_debug::go_exception(int exception)
void device_debug::go_milliseconds(UINT64 milliseconds)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
m_stoptime = m_device.machine().time() + attotime::from_msec(milliseconds);
m_flags |= DEBUG_FLAG_STOP_TIME;
- global->execution_state = EXECUTION_STATE_RUNNING;
-}
-
-
-//-------------------------------------------------
-// go_next_device - execute until we hit the next
-// device
-//-------------------------------------------------
-
-void device_debug::go_next_device()
-{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
- assert(m_exec != nullptr);
-
- global->m_stop_when_not_device = &m_device;
- global->execution_state = EXECUTION_STATE_RUNNING;
+ m_device.machine().debugger().cpu().set_execution_state(EXECUTION_STATE_RUNNING);
}
//-------------------------------------------------
-// halt_on_next_instruction - halt in the
-// debugger on the next instruction
+// halt_on_next_instruction_impl - halt in the
+// debugger on the next instruction, internal
+// implementation which is necessary solely due
+// to templates in C++ being janky as all get out
//-------------------------------------------------
void device_debug::halt_on_next_instruction_impl(util::format_argument_pack<std::ostream> &&args)
{
- debugcpu_private *global = m_device.machine().debugcpu_data;
-
assert(m_exec != nullptr);
-
- // if something is pending on this CPU already, ignore this request
- if (&m_device == global->breakcpu)
- return;
-
- // output the message to the console
- debug_console_vprintf(m_device.machine(), std::move(args));
-
- // if we are live, stop now, otherwise note that we want to break there
- if (&m_device == global->livecpu)
- {
- global->execution_state = EXECUTION_STATE_STOPPED;
- if (global->livecpu != nullptr)
- global->livecpu->debug()->compute_debug_flags();
- }
- else
- global->breakcpu = &m_device;
+ m_device.machine().debugger().cpu().halt_on_next_instruction(&m_device, std::move(args));
}
-
//-------------------------------------------------
// breakpoint_set - set a new breakpoint,
// returning its index
@@ -2266,7 +2191,8 @@ void device_debug::halt_on_next_instruction_impl(util::format_argument_pack<std:
int device_debug::breakpoint_set(offs_t address, const char *condition, const char *action)
{
// allocate a new one
- breakpoint *bp = auto_alloc(m_device.machine(), breakpoint(this, m_symtable, m_device.machine().debugcpu_data->bpindex++, address, condition, action));
+ UINT32 id = m_device.machine().debugger().cpu().get_breakpoint_index();
+ breakpoint *bp = auto_alloc(m_device.machine(), breakpoint(this, m_symtable, id, address, condition, action));
// hook it into our list
bp->m_next = m_bplist;
@@ -2357,7 +2283,8 @@ int device_debug::watchpoint_set(address_space &space, int type, offs_t address,
assert(space.spacenum() < ARRAY_LENGTH(m_wplist));
// allocate a new one
- watchpoint *wp = auto_alloc(m_device.machine(), watchpoint(this, m_symtable, m_device.machine().debugcpu_data->wpindex++, space, type, address, length, condition, action));
+ UINT32 id = m_device.machine().debugger().cpu().get_watchpoint_index();
+ watchpoint *wp = auto_alloc(m_device.machine(), watchpoint(this, m_symtable, id, space, type, address, length, condition, action));
// hook it into our list
wp->m_next = m_wplist[space.spacenum()];
@@ -2451,7 +2378,8 @@ void device_debug::watchpoint_enable_all(bool enable)
int device_debug::registerpoint_set(const char *condition, const char *action)
{
// allocate a new one
- registerpoint *rp = auto_alloc(m_device.machine(), registerpoint(m_symtable, m_device.machine().debugcpu_data->rpindex++, condition, action));
+ UINT32 id = m_device.machine().debugger().cpu().get_registerpoint_index();
+ registerpoint *rp = auto_alloc(m_device.machine(), registerpoint(m_symtable, id, condition, action));
// hook it into our list
rp->m_next = m_rplist;
@@ -2713,7 +2641,7 @@ bool device_debug::comment_import(xml_data_node &cpunode,bool is_inline)
if(is_inline == true)
m_comment_set.insert(dasm_comment(address, crc, datanode->value, color));
else
- debug_console_printf(m_device.machine()," %08X - %s\n",address,datanode->value);
+ m_device.machine().debugger().console().printf(" %08X - %s\n", address, datanode->value);
}
return true;
}
@@ -2739,8 +2667,8 @@ UINT32 device_debug::compute_opcode_crc32(offs_t pc) const
int maxbytes = max_opcode_bytes();
for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- opbuf[numbytes] = debug_read_opcode(decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1);
+ opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1);
+ argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1);
}
// disassemble to our buffer
@@ -2793,7 +2721,7 @@ void device_debug::trace_printf(const char *fmt, ...)
void device_debug::compute_debug_flags()
{
running_machine &machine = m_device.machine();
- debugcpu_private *global = machine.debugcpu_data;
+ debugger_cpu& debugcpu = machine.debugger().cpu();
// clear out global flags by default, keep DEBUG_FLAG_OSD_ENABLED
machine.debug_flags &= DEBUG_FLAG_OSD_ENABLED;
@@ -2804,7 +2732,7 @@ void device_debug::compute_debug_flags()
return;
// if we're stopped, keep calling the hook
- if (global->execution_state == EXECUTION_STATE_STOPPED)
+ if (debugcpu.execution_state() == EXECUTION_STATE_STOPPED)
machine.debug_flags |= DEBUG_FLAG_CALL_HOOK;
// if we're tracking history, or we're hooked, or stepping, or stopping at a breakpoint
@@ -2885,9 +2813,8 @@ void device_debug::breakpoint_update_flags()
}
// push the flags out globally
- debugcpu_private *global = m_device.machine().debugcpu_data;
- if (global->livecpu != nullptr)
- global->livecpu->debug()->compute_debug_flags();
+ if (m_device.machine().debugger().cpu().live_cpu() != nullptr)
+ m_device.machine().debugger().cpu().live_cpu()->debug()->compute_debug_flags();
}
@@ -2898,21 +2825,22 @@ void device_debug::breakpoint_update_flags()
void device_debug::breakpoint_check(offs_t pc)
{
+ debugger_cpu& debugcpu = m_device.machine().debugger().cpu();
+
// see if we match
for (breakpoint *bp = m_bplist; bp != nullptr; bp = bp->m_next)
if (bp->hit(pc))
{
// halt in the debugger by default
- debugcpu_private *global = m_device.machine().debugcpu_data;
- global->execution_state = EXECUTION_STATE_STOPPED;
+ debugcpu.set_execution_state(EXECUTION_STATE_STOPPED);
// if we hit, evaluate the action
if (!bp->m_action.empty())
- debug_console_execute_command(m_device.machine(), bp->m_action.c_str(), 0);
+ m_device.machine().debugger().console().execute_command(bp->m_action.c_str(), false);
// print a notification, unless the action made us go again
- if (global->execution_state == EXECUTION_STATE_STOPPED)
- debug_console_printf(m_device.machine(), "Stopped at breakpoint %X\n", bp->m_index);
+ if (debugcpu.execution_state() == EXECUTION_STATE_STOPPED)
+ m_device.machine().debugger().console().printf("Stopped at breakpoint %X\n", bp->m_index);
break;
}
@@ -2922,19 +2850,18 @@ void device_debug::breakpoint_check(offs_t pc)
if (rp->hit())
{
// halt in the debugger by default
- debugcpu_private *global = m_device.machine().debugcpu_data;
- global->execution_state = EXECUTION_STATE_STOPPED;
+ debugcpu.set_execution_state(EXECUTION_STATE_STOPPED);
// if we hit, evaluate the action
if (!rp->m_action.empty())
{
- debug_console_execute_command(m_device.machine(), rp->m_action.c_str(), 0);
+ m_device.machine().debugger().console().execute_command(rp->m_action.c_str(), false);
}
// print a notification, unless the action made us go again
- if (global->execution_state == EXECUTION_STATE_STOPPED)
+ if (debugcpu.execution_state() == EXECUTION_STATE_STOPPED)
{
- debug_console_printf(m_device.machine(), "Stopped at registerpoint %X\n", rp->m_index);
+ m_device.machine().debugger().console().printf("Stopped at registerpoint %X\n", rp->m_index);
}
break;
}
@@ -2976,14 +2903,18 @@ void device_debug::watchpoint_update_flags(address_space &space)
// for a given CPU and address space
//-------------------------------------------------
-void device_debug::watchpoint_check(address_space &space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask)
+void device_debug::watchpoint_check(address_space& space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask)
{
- debugcpu_private *global = space.machine().debugcpu_data;
+ space.machine().debugger().cpu().watchpoint_check(space, type, address, value_to_write, mem_mask, m_wplist);
+}
+void debugger_cpu::watchpoint_check(address_space& space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask, device_debug::watchpoint** wplist)
+{
// if we're within debugger code, don't stop
- if (global->within_instruction_hook || global->debugger_access)
+ if (m_within_instruction_hook || m_debugger_access)
return;
- global->within_instruction_hook = true;
+
+ m_within_instruction_hook = true;
// adjust address, size & value_to_write based on mem_mask.
offs_t size = 0;
@@ -3024,48 +2955,48 @@ void device_debug::watchpoint_check(address_space &space, int type, offs_t addre
}
// if we are a write watchpoint, stash the value that will be written
- global->wpaddr = address;
+ m_wpaddr = address;
if (type & WATCHPOINT_WRITE)
- global->wpdata = value_to_write;
+ m_wpdata = value_to_write;
// see if we match
- for (watchpoint *wp = m_wplist[space.spacenum()]; wp != nullptr; wp = wp->m_next)
+ for (device_debug::watchpoint *wp = wplist[space.spacenum()]; wp != nullptr; wp = wp->next())
if (wp->hit(type, address, size))
{
// halt in the debugger by default
- global->execution_state = EXECUTION_STATE_STOPPED;
+ m_execution_state = EXECUTION_STATE_STOPPED;
// if we hit, evaluate the action
- if (!wp->m_action.empty())
- debug_console_execute_command(space.machine(), wp->m_action.c_str(), 0);
+ if (strlen(wp->action()) > 0)
+ m_machine.debugger().console().execute_command(wp->action(), false);
// print a notification, unless the action made us go again
- if (global->execution_state == EXECUTION_STATE_STOPPED)
+ if (m_execution_state == EXECUTION_STATE_STOPPED)
{
static const char *const sizes[] =
{
"0bytes", "byte", "word", "3bytes", "dword", "5bytes", "6bytes", "7bytes", "qword"
};
- offs_t pc = (space.device().debug()->m_state != nullptr) ? space.device().debug()->m_state->pc() : 0;
+ offs_t pc = space.device().debug()->pc();
std::string buffer;
if (type & WATCHPOINT_WRITE)
{
- buffer = string_format("Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->m_index, sizes[size], space.byte_to_address(address), pc);
+ buffer = string_format("Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->index(), sizes[size], space.byte_to_address(address), pc);
if (value_to_write >> 32)
buffer.append(string_format(" (data=%X%08X)", (UINT32)(value_to_write >> 32), (UINT32)value_to_write));
else
buffer.append(string_format(" (data=%X)", (UINT32)value_to_write));
}
else
- buffer = string_format("Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->m_index, sizes[size], space.byte_to_address(address), pc);
- debug_console_printf(space.machine(), "%s\n", buffer.c_str());
+ buffer = string_format("Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->index(), sizes[size], space.byte_to_address(address), pc);
+ m_machine.debugger().console().printf("%s\n", buffer.c_str());
space.device().debug()->compute_debug_flags();
}
break;
}
- global->within_instruction_hook = false;
+ m_within_instruction_hook = false;
}
@@ -3090,7 +3021,7 @@ void device_debug::hotspot_check(address_space &space, offs_t address)
// if the bottom of the list is over the threshold, print it
hotspot_entry &spot = m_hotspots[m_hotspots.size() - 1];
if (spot.m_count > m_hotspot_threshhold)
- debug_console_printf(space.machine(), "Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space.name(), spot.m_access, spot.m_pc, spot.m_count);
+ space.machine().debugger().console().printf("Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space.name(), spot.m_access, spot.m_pc, spot.m_count);
// move everything else down and insert this one at the top
memmove(&m_hotspots[1], &m_hotspots[0], sizeof(m_hotspots[0]) * (m_hotspots.size() - 1));
@@ -3134,8 +3065,8 @@ UINT32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc)
int maxbytes = max_opcode_bytes();
for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- opbuf[numbytes] = debug_read_opcode(decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1);
+ opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1);
+ argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1);
}
// disassemble to our buffer
@@ -3481,7 +3412,7 @@ void device_debug::tracer::update(offs_t pc)
// execute any trace actions first
if (!m_action.empty())
- debug_console_execute_command(m_debug.m_device.machine(), m_action.c_str(), 0);
+ m_debug.m_device.machine().debugger().console().execute_command(m_action.c_str(), false);
// print the address
std::string buffer;