summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/emu.lua2
-rw-r--r--src/emu/debug/debugcmd.cpp165
-rw-r--r--src/emu/debug/debugcmd.h1
-rw-r--r--src/emu/debug/debugcon.cpp26
-rw-r--r--src/emu/debug/debugcon.h7
-rw-r--r--src/emu/debug/debugcpu.cpp1395
-rw-r--r--src/emu/debug/debugcpu.h209
-rw-r--r--src/emu/debug/dvbpoints.cpp33
-rw-r--r--src/emu/debug/dvbpoints.h4
-rw-r--r--src/emu/debug/dvdisasm.cpp8
-rw-r--r--src/emu/debug/dvmemory.cpp230
-rw-r--r--src/emu/debug/dvmemory.h1
-rw-r--r--src/emu/debug/dvwpoints.cpp35
-rw-r--r--src/emu/debug/dvwpoints.h4
-rw-r--r--src/emu/debug/express.cpp594
-rw-r--r--src/emu/debug/express.h26
-rw-r--r--src/emu/debug/points.cpp441
-rw-r--r--src/emu/debug/points.h149
-rw-r--r--src/emu/debugger.cpp2
-rw-r--r--src/emu/emufwd.h5
-rw-r--r--src/frontend/mame/cheat.cpp19
-rw-r--r--src/frontend/mame/cheat.h2
-rw-r--r--src/frontend/mame/luaengine.cpp10
-rw-r--r--src/mame/drivers/chihiro.cpp7
-rw-r--r--src/mame/drivers/konamim2.cpp63
-rw-r--r--src/mame/machine/fddebug.cpp12
-rw-r--r--src/mame/machine/xbox.cpp121
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp21
-rw-r--r--src/osd/modules/debugger/debugimgui.cpp36
-rw-r--r--src/osd/modules/debugger/debugwin.cpp2
-rw-r--r--src/osd/modules/debugger/none.cpp3
-rw-r--r--src/osd/modules/debugger/osx/debugconsole.mm21
-rw-r--r--src/osd/modules/debugger/osx/debugview.mm3
-rw-r--r--src/osd/modules/debugger/osx/debugwindowhandler.mm21
-rw-r--r--src/osd/modules/debugger/osx/disassemblyviewer.mm9
-rw-r--r--src/osd/modules/debugger/osx/memoryview.mm1
-rw-r--r--src/osd/modules/debugger/osx/memoryviewer.mm4
-rw-r--r--src/osd/modules/debugger/osx/registersview.mm4
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.cpp9
-rw-r--r--src/osd/modules/debugger/qt/mainwindow.cpp17
-rw-r--r--src/osd/modules/debugger/qt/memorywindow.cpp60
-rw-r--r--src/osd/modules/debugger/qt/windowqt.cpp18
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.cpp4
-rw-r--r--src/osd/modules/debugger/win/debugviewinfo.cpp5
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.cpp19
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.cpp7
46 files changed, 1821 insertions, 2014 deletions
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua
index 0a5207d5365..89c7d3ccd20 100644
--- a/scripts/src/emu.lua
+++ b/scripts/src/emu.lua
@@ -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",
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index 01d2f462d50..d8e1c985d27 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -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;
diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h
index 62e8008c322..a47378765ff 100644
--- a/src/emu/debug/debugcmd.h
+++ b/src/emu/debug/debugcmd.h
@@ -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);
diff --git a/src/emu/debug/debugcon.cpp b/src/emu/debug/debugcon.cpp
index 2c5989a8faa..e9c08268338 100644
--- a/src/emu/debug/debugcon.cpp
+++ b/src/emu/debug/debugcon.cpp
@@ -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)
{
diff --git a/src/emu/debug/debugcon.h b/src/emu/debug/debugcon.h
index e57b06a7378..cabff196d9f 100644
--- a/src/emu/debug/debugcon.h
+++ b/src/emu/debug/debugcon.h
@@ -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;
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index fb5db3ffb89..afdef1362d1 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -13,6 +13,7 @@
#include "debugbuf.h"
#include "express.h"
+#include "points.h"
#include "debugcon.h"
#include "debugvw.h"
@@ -36,7 +37,6 @@ const size_t debugger_cpu::NUM_TEMP_VARIABLES = 10;
debugger_cpu::debugger_cpu(running_machine &machine)
: m_machine(machine)
, m_livecpu(nullptr)
- , m_visiblecpu(nullptr)
, m_breakcpu(nullptr)
, m_symtable(nullptr)
, m_vblank_occurred(false)
@@ -53,17 +53,13 @@ debugger_cpu::debugger_cpu(running_machine &machine)
m_tempvar = make_unique_clear<u64[]>(NUM_TEMP_VARIABLES);
/* create a global symbol table */
- m_symtable = std::make_unique<symbol_table>();
+ m_symtable = std::make_unique<symbol_table>(machine);
+ m_symtable->set_memory_modified_func([this]() { set_memory_modified(true); });
- // configure our base memory accessors
- configure_memory(*m_symtable);
-
- /* add "wpaddr", "wpdata", "cycles", "cpunum", "logunmap" to the global symbol table */
+ /* add "wpaddr", "wpdata" to the global symbol table */
m_symtable->add("wpaddr", symbol_table::READ_ONLY, &m_wpaddr);
m_symtable->add("wpdata", symbol_table::READ_ONLY, &m_wpdata);
- m_symtable->add("cpunum", std::bind(&debugger_cpu::get_cpunum, this));
-
screen_device_iterator screen_iterator = screen_device_iterator(m_machine.root_device());
screen_device_iterator::auto_iterator iter = screen_iterator.begin();
const uint32_t count = (uint32_t)screen_iterator.count();
@@ -74,7 +70,7 @@ debugger_cpu::debugger_cpu(running_machine &machine)
m_symtable->add("beamx", [&screen]() { return screen.hpos(); });
m_symtable->add("beamy", [&screen]() { return screen.vpos(); });
m_symtable->add("frame", [&screen]() { return screen.frame_number(); });
- iter.current()->register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
+ screen.register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
}
else if (count > 1)
{
@@ -84,7 +80,7 @@ debugger_cpu::debugger_cpu(running_machine &machine)
m_symtable->add(string_format("beamx%d", i).c_str(), [&screen]() { return screen.hpos(); });
m_symtable->add(string_format("beamy%d", i).c_str(), [&screen]() { return screen.vpos(); });
m_symtable->add(string_format("frame%d", i).c_str(), [&screen]() { return screen.frame_number(); });
- iter.current()->register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
+ screen.register_vblank_callback(vblank_state_delegate(&debugger_cpu::on_vblank, this));
}
}
@@ -95,27 +91,8 @@ debugger_cpu::debugger_cpu(running_machine &machine)
sprintf(symname, "temp%d", regnum);
m_symtable->add(symname, symbol_table::READ_WRITE, &m_tempvar[regnum]);
}
-
- /* 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;
- }
- }
}
-void debugger_cpu::configure_memory(symbol_table &table)
-{
- using namespace std::placeholders;
- table.configure_memory(
- std::bind(&debugger_cpu::expression_validate, this, _1, _2),
- 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));
-}
/*-------------------------------------------------
flush_traces - flushes all traces; this is
@@ -135,22 +112,6 @@ void debugger_cpu::flush_traces()
//**************************************************************************
-// SYMBOL TABLE INTERFACES
-//**************************************************************************
-
-//-------------------------------------------------
-// visible_symtable - return the locally-visible
-// symbol table
-//-------------------------------------------------
-
-symbol_table &debugger_cpu::visible_symtable()
-{
- return m_visiblecpu->debug()->symtable();
-}
-
-
-
-//**************************************************************************
// MEMORY AND DISASSEMBLY HELPERS
//**************************************************************************
@@ -288,294 +249,6 @@ bool debugger_cpu::comment_load(bool is_inline)
/***************************************************************************
- DEBUGGER MEMORY ACCESSORS
-***************************************************************************/
-
-/*-------------------------------------------------
- read_byte - return a byte from the specified
- memory space
--------------------------------------------------*/
-
-u8 debugger_cpu::read_byte(address_space &space, offs_t address, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, return 0xff */
- if (!memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- return 0xff;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- return space.read_byte(address);
-}
-
-
-/*-------------------------------------------------
- read_word - return a word from the specified
- memory space
--------------------------------------------------*/
-
-u16 debugger_cpu::read_word(address_space &space, offs_t address, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, return 0xffff */
- if (!memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- return 0xffff;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- return space.read_word_unaligned(address);
-}
-
-
-/*-------------------------------------------------
- read_dword - return a dword from the specified
- memory space
--------------------------------------------------*/
-
-u32 debugger_cpu::read_dword(address_space &space, offs_t address, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, return 0xffffffff */
- if (!memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- return 0xffffffff;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- return space.read_dword_unaligned(address);
-}
-
-
-/*-------------------------------------------------
- read_qword - return a qword from the specified
- memory space
--------------------------------------------------*/
-
-u64 debugger_cpu::read_qword(address_space &space, offs_t address, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- /* translate if necessary; if not mapped, return 0xffffffffffffffff */
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, return 0xffffffff */
- if (!memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- return ~u64(0);
- }
-
- /* otherwise, call the byte reading function for the translated address */
- return space.read_qword_unaligned(address);
-}
-
-
-/*-------------------------------------------------
- read_memory - return 1,2,4 or 8 bytes
- from the specified memory space
--------------------------------------------------*/
-
-u64 debugger_cpu::read_memory(address_space &space, offs_t address, int size, bool apply_translation)
-{
- u64 result = ~u64(0) >> (64 - 8*size);
- switch (size)
- {
- 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;
-}
-
-
-/*-------------------------------------------------
- write_byte - write a byte to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_byte(address_space &space, offs_t address, u8 data, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, we're done */
- if (!memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- return;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- space.write_byte(address, data);
-
- m_memory_modified = true;
-}
-
-
-/*-------------------------------------------------
- write_word - write a word to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_word(address_space &space, offs_t address, u16 data, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, we're done */
- if (!memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- return;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- space.write_word_unaligned(address, data);
-
- m_memory_modified = true;
-}
-
-
-/*-------------------------------------------------
- write_dword - write a dword to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_dword(address_space &space, offs_t address, u32 data, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, we're done */
- if (!memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- return;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- space.write_dword_unaligned(address, data);
-
- m_memory_modified = true;
-}
-
-
-/*-------------------------------------------------
- write_qword - write a qword to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_qword(address_space &space, offs_t address, u64 data, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation)
- {
- /* mask against the logical byte mask */
- address &= space.logaddrmask();
-
- /* translate if necessary; if not mapped, we're done */
- if (!memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- return;
- }
-
- /* otherwise, call the byte reading function for the translated address */
- space.write_qword_unaligned(address, data);
-
- m_memory_modified = true;
-}
-
-
-/*-------------------------------------------------
- write_memory - write 1,2,4 or 8 bytes to the
- specified memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation)
-{
- switch (size)
- {
- 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;
- }
-}
-
-
-/*-------------------------------------------------
- read_opcode - read 1,2,4 or 8 bytes at the
- given offset from opcode space
--------------------------------------------------*/
-
-u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size)
-{
- device_memory_interface &memory = space.device().memory();
-
- u64 result = ~u64(0) & (~u64(0) >> (64 - 8*size));
-
- /* keep in logical range */
- address &= space.logaddrmask();
-
- /* translate to physical first */
- if (!memory.translate(space.spacenum(), TRANSLATE_FETCH_DEBUG, address))
- return result;
-
- /* keep in physical range */
- address &= space.addrmask();
-
- /* switch off the size and handle unaligned accesses */
- 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 6:
- case 8:
- result = space.read_qword_unaligned(address);
- break;
- }
-
- return result;
-}
-
-
-
-/***************************************************************************
INTERNAL HELPERS
***************************************************************************/
@@ -605,537 +278,6 @@ void debugger_cpu::reset_transient_flags()
}
-
-/***************************************************************************
- EXPRESSION HANDLERS
-***************************************************************************/
-
-/*-------------------------------------------------
- expression_get_device - return a device
- based on a case insensitive tag search
--------------------------------------------------*/
-
-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 m_machine.root_device().subdevice(fullname.c_str());
-}
-
-
-/*-------------------------------------------------
- expression_read_memory - read 1,2,4 or 8 bytes
- at the given offset in the given address
- space
--------------------------------------------------*/
-
-u64 debugger_cpu::expression_read_memory(const char *name, expression_space spacenum, u32 address, int size, bool disable_se)
-{
- switch (spacenum)
- {
- case EXPSPACE_PROGRAM_LOGICAL:
- case EXPSPACE_DATA_LOGICAL:
- case EXPSPACE_IO_LOGICAL:
- case EXPSPACE_SPACE3_LOGICAL:
- {
- device_t *device = nullptr;
- device_memory_interface *memory;
-
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->memory();
- }
- if (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:
- {
- device_t *device = nullptr;
- device_memory_interface *memory;
-
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->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:
- {
- device_t *device = nullptr;
- device_memory_interface *memory;
-
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->memory();
- }
- auto dis = m_machine.disable_side_effects(disable_se);
- return expression_read_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size);
- break;
- }
-
- case EXPSPACE_OPCODE:
- {
- device_t *device = nullptr;
- device_memory_interface *memory;
-
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->memory();
- }
- auto dis = m_machine.disable_side_effects(disable_se);
- return expression_read_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size);
- break;
- }
-
- case EXPSPACE_REGION:
- if (name == nullptr)
- break;
- return expression_read_memory_region(name, address, size);
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-
-/*-------------------------------------------------
- expression_read_program_direct - read memory
- directly from an opcode or RAM pointer
--------------------------------------------------*/
-
-u64 debugger_cpu::expression_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 = expression_read_program_direct(space, opcode | 2, address + 0, halfsize);
- u64 r1 = expression_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;
-}
-
-
-/*-------------------------------------------------
- expression_read_memory_region - read memory
- from a memory region
--------------------------------------------------*/
-
-u64 debugger_cpu::expression_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 = 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)
- 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;
-}
-
-
-/*-------------------------------------------------
- expression_write_memory - write 1,2,4 or 8
- bytes at the given offset in the given address
- space
--------------------------------------------------*/
-
-void debugger_cpu::expression_write_memory(const char *name, expression_space spacenum, u32 address, int size, u64 data, bool disable_se)
-{
- device_t *device = nullptr;
- device_memory_interface *memory;
-
- switch (spacenum)
- {
- case EXPSPACE_PROGRAM_LOGICAL:
- case EXPSPACE_DATA_LOGICAL:
- case EXPSPACE_IO_LOGICAL:
- case EXPSPACE_SPACE3_LOGICAL:
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->memory();
- }
- if (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 = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->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);
- write_memory(space, address, data, size, false);
- }
- break;
-
- case EXPSPACE_RAMWRITE: {
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->memory();
- }
- auto dis = m_machine.disable_side_effects(disable_se);
- expression_write_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size, data);
- break;
- }
-
- case EXPSPACE_OPCODE: {
- if (name != nullptr)
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- {
- device = get_visible_cpu();
- memory = &device->memory();
- }
- auto dis = m_machine.disable_side_effects(disable_se);
- expression_write_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size, data);
- break;
- }
-
- case EXPSPACE_REGION:
- if (name == nullptr)
- break;
- expression_write_memory_region(name, address, size, data);
- break;
-
- default:
- break;
- }
-}
-
-
-/*-------------------------------------------------
- expression_write_program_direct - write memory
- directly to an opcode or RAM pointer
--------------------------------------------------*/
-
-void debugger_cpu::expression_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 */
- expression_write_program_direct(space, opcode | 2, address + 0, halfsize, r0);
- expression_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;
- m_memory_modified = true;
- }
- }
-}
-
-
-/*-------------------------------------------------
- expression_write_memory_region - write memory
- from a memory region
--------------------------------------------------*/
-
-void debugger_cpu::expression_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 */
- 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 */
- 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;
- }
- m_memory_modified = true;
- }
- }
-}
-
-
-/*-------------------------------------------------
- expression_validate - validate that the
- provided expression references an
- appropriate name
--------------------------------------------------*/
-
-expression_error::error_code debugger_cpu::expression_validate(const char *name, expression_space space)
-{
- device_t *device = nullptr;
- device_memory_interface *memory;
-
- switch (space)
- {
- case EXPSPACE_PROGRAM_LOGICAL:
- case EXPSPACE_DATA_LOGICAL:
- case EXPSPACE_IO_LOGICAL:
- case EXPSPACE_SPACE3_LOGICAL:
- if (name)
- {
- device = expression_get_device(name);
- if (device == nullptr)
- return expression_error::INVALID_MEMORY_NAME;
- }
- if (!device)
- device = get_visible_cpu();
- if (!device->interface(memory) || !memory->has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL)))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
-
- case EXPSPACE_PROGRAM_PHYSICAL:
- case EXPSPACE_DATA_PHYSICAL:
- case EXPSPACE_IO_PHYSICAL:
- case EXPSPACE_SPACE3_PHYSICAL:
- if (name)
- {
- device = expression_get_device(name);
- if (device == nullptr)
- return expression_error::INVALID_MEMORY_NAME;
- }
- if (!device)
- device = get_visible_cpu();
- if (!device->interface(memory) || !memory->has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL)))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
-
- case EXPSPACE_RAMWRITE:
- if (name)
- {
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- return expression_error::INVALID_MEMORY_NAME;
- }
- if (!device)
- device = get_visible_cpu();
- if (!device->interface(memory) || !memory->has_space(AS_PROGRAM))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
-
- case EXPSPACE_OPCODE:
- if (name)
- {
- device = expression_get_device(name);
- if (device == nullptr || !device->interface(memory))
- return expression_error::INVALID_MEMORY_NAME;
- }
- if (!device)
- device = get_visible_cpu();
- if (!device->interface(memory) || !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;
-}
-
-
-
-//**************************************************************************
-// VARIABLE GETTERS/SETTERS
-//**************************************************************************
-
-//-------------------------------------------------
-// get_cpunum - getter callback for the
-// 'cpunum' symbol
-//-------------------------------------------------
-
-u64 debugger_cpu::get_cpunum()
-{
- execute_interface_iterator iter(m_machine.root_device());
- return iter.indexof(m_visiblecpu->execute());
-}
-
-
//**************************************************************************
// EXECUTION HOOKS
//**************************************************************************
@@ -1164,7 +306,8 @@ void debugger_cpu::start_hook(device_t *device, bool stop_on_vblank)
// if we're running, do some periodic updating
if (m_execution_state != exec_state::STOPPED)
{
- if (device == m_visiblecpu && osd_ticks() > m_last_periodic_update_time + osd_ticks_per_second() / 4)
+ device_t *visiblecpu = m_machine.debugger().console().get_visible_cpu();
+ if (device == 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();
@@ -1191,8 +334,8 @@ void debugger_cpu::start_hook(device_t *device, bool stop_on_vblank)
// check for debug keypresses
if (m_machine.ui_input().pressed(IPT_UI_DEBUG_BREAK))
{
- m_visiblecpu->debug()->ignore(false);
- m_visiblecpu->debug()->halt_on_next_instruction("User-initiated break\n");
+ visiblecpu->debug()->ignore(false);
+ visiblecpu->debug()->halt_on_next_instruction("User-initiated break\n");
}
}
}
@@ -1276,7 +419,7 @@ device_debug::device_debug(device_t &device)
, m_state(nullptr)
, m_disasm(nullptr)
, m_flags(0)
- , m_symtable(&device.machine().debugger().cpu().global_symtable())
+ , m_symtable(std::make_unique<symbol_table>(device.machine(), &device.machine().debugger().cpu().global_symtable(), &device))
, m_instrhook(nullptr)
, m_stepaddr(0)
, m_stepsleft(0)
@@ -1289,7 +432,7 @@ device_debug::device_debug(device_t &device)
, m_last_total_cycles(0)
, m_pc_history_index(0)
, m_bplist()
- , m_rplist()
+ , m_rplist(std::make_unique<std::forward_list<debug_registerpoint>>())
, m_triggered_breakpoint(nullptr)
, m_triggered_watchpoint(nullptr)
, m_trace(nullptr)
@@ -1329,31 +472,31 @@ device_debug::device_debug(device_t &device)
// add global symbol for cycles and totalcycles
if (m_exec != nullptr)
{
- m_symtable.add("cycles", [this]() { return m_exec->cycles_remaining(); });
- m_symtable.add("totalcycles", symbol_table::READ_ONLY, &m_total_cycles);
- m_symtable.add("lastinstructioncycles", [this]() { return m_total_cycles - m_last_total_cycles; });
+ m_symtable->add("cycles", [this]() { return m_exec->cycles_remaining(); });
+ m_symtable->add("totalcycles", symbol_table::READ_ONLY, &m_total_cycles);
+ m_symtable->add("lastinstructioncycles", [this]() { return m_total_cycles - m_last_total_cycles; });
}
// add entries to enable/disable unmap reporting for each space
if (m_memory != nullptr)
{
if (m_memory->has_space(AS_PROGRAM))
- m_symtable.add(
+ m_symtable->add(
"logunmap",
[&space = m_memory->space(AS_PROGRAM)] () { return space.log_unmap(); },
[&space = m_memory->space(AS_PROGRAM)] (u64 value) { return space.set_log_unmap(bool(value)); });
if (m_memory->has_space(AS_DATA))
- m_symtable.add(
+ m_symtable->add(
"logunmap",
[&space = m_memory->space(AS_DATA)] () { return space.log_unmap(); },
[&space = m_memory->space(AS_DATA)] (u64 value) { return space.set_log_unmap(bool(value)); });
if (m_memory->has_space(AS_IO))
- m_symtable.add(
+ m_symtable->add(
"logunmap",
[&space = m_memory->space(AS_IO)] () { return space.log_unmap(); },
[&space = m_memory->space(AS_IO)] (u64 value) { return space.set_log_unmap(bool(value)); });
if (m_memory->has_space(AS_OPCODES))
- m_symtable.add(
+ m_symtable->add(
"logunmap",
[&space = m_memory->space(AS_OPCODES)] () { return space.log_unmap(); },
[&space = m_memory->space(AS_OPCODES)] (u64 value) { return space.set_log_unmap(bool(value)); });
@@ -1368,7 +511,7 @@ device_debug::device_debug(device_t &device)
{
using namespace std::placeholders;
strmakelower(tempstr.assign(entry->symbol()));
- m_symtable.add(
+ m_symtable->add(
tempstr.c_str(),
std::bind(&device_state_interface::state_int, m_state, entry->index()),
entry->writeable() ? std::bind(&device_state_interface::set_state_int, m_state, entry->index(), _1) : symbol_table::setter_func(nullptr),
@@ -1383,8 +526,8 @@ device_debug::device_debug(device_t &device)
m_flags = DEBUG_FLAG_OBSERVING | DEBUG_FLAG_HISTORY;
// if no curpc, add one
- if (m_state && !m_symtable.find("curpc"))
- m_symtable.add("curpc", std::bind(&device_state_interface::pcbase, m_state));
+ if (m_state && !m_symtable->find("curpc"))
+ m_symtable->add("curpc", std::bind(&device_state_interface::pcbase, m_state));
}
// set up trace
@@ -1657,7 +800,7 @@ void device_debug::instruction_hook(offs_t curpc)
debugcpu.set_break_cpu(nullptr);
// remember the last visible CPU in the debugger
- debugcpu.set_visible_cpu(&m_device);
+ machine.debugger().console().set_visible_cpu(&m_device);
// update all views
machine.debug_view().update_all();
@@ -1692,10 +835,10 @@ void device_debug::instruction_hook(offs_t curpc)
if (machine.scheduled_event_pending())
debugcpu.set_execution_running();
}
- m_device.machine().sound().debugger_mute(false);
+ machine.sound().debugger_mute(false);
// remember the last visible CPU in the debugger
- debugcpu.set_visible_cpu(&m_device);
+ machine.debugger().console().set_visible_cpu(&m_device);
}
// handle step out/over on the instruction we are about to execute
@@ -1879,7 +1022,7 @@ void device_debug::go_exception(int exception, const char *condition)
m_device.machine().rewind_invalidate();
m_stopexception = exception;
- m_exception_condition = std::make_unique<parsed_expression>(m_symtable, condition);
+ m_exception_condition = std::make_unique<parsed_expression>(*m_symtable, condition);
m_flags |= DEBUG_FLAG_STOP_EXCEPTION;
m_device.machine().debugger().cpu().set_execution_running();
}
@@ -1910,7 +1053,7 @@ void device_debug::go_privilege(const char *condition)
{
assert(m_exec != nullptr);
m_device.machine().rewind_invalidate();
- m_privilege_condition = std::make_unique<parsed_expression>(m_symtable, condition);
+ m_privilege_condition = std::make_unique<parsed_expression>(*m_symtable, condition);
m_flags |= DEBUG_FLAG_STOP_PRIVILEGE;
m_device.machine().debugger().cpu().set_execution_running();
}
@@ -1934,11 +1077,11 @@ void device_debug::halt_on_next_instruction_impl(util::format_argument_pack<std:
// given address, or nullptr if none exists there
//-------------------------------------------------
-const device_debug::breakpoint *device_debug::breakpoint_find(offs_t address) const
+const debug_breakpoint *device_debug::breakpoint_find(offs_t address) const
{
- for (const breakpoint &bp : m_bplist)
- if (bp.address() == address)
- return &bp;
+ auto bpitp = m_bplist.equal_range(address);
+ if (bpitp.first != bpitp.second)
+ return bpitp.first->second.get();
return nullptr;
}
@@ -1952,11 +1095,11 @@ int device_debug::breakpoint_set(offs_t address, const char *condition, const ch
{
// allocate a new one and hook it into our list
u32 id = m_device.machine().debugger().cpu().get_breakpoint_index();
- m_bplist.emplace_front(this, m_symtable, id, address, condition, action);
+ m_bplist.emplace(address, std::make_unique<debug_breakpoint>(this, *m_symtable, id, address, condition, action));
// update the flags and return the index
breakpoint_update_flags();
- return m_bplist.front().m_index;
+ return id;
}
@@ -1968,10 +1111,10 @@ int device_debug::breakpoint_set(offs_t address, const char *condition, const ch
bool device_debug::breakpoint_clear(int index)
{
// scan the list to see if we own this breakpoint
- for (auto bbp = m_bplist.before_begin(); std::next(bbp) != m_bplist.end(); ++bbp)
- if (std::next(bbp)->m_index == index)
+ for (auto bpit = m_bplist.begin(); bpit != m_bplist.end(); ++bpit)
+ if (bpit->second->m_index == index)
{
- m_bplist.erase_after(bbp);
+ m_bplist.erase(bpit);
breakpoint_update_flags();
return true;
}
@@ -2001,13 +1144,16 @@ void device_debug::breakpoint_clear_all()
bool device_debug::breakpoint_enable(int index, bool enable)
{
// scan the list to see if we own this breakpoint
- for (breakpoint &bp : m_bplist)
+ for (auto &bpp : m_bplist)
+ {
+ debug_breakpoint &bp = *bpp.second;
if (bp.m_index == index)
{
bp.m_enabled = enable;
breakpoint_update_flags();
return true;
}
+ }
// we don't own it, return false
return false;
@@ -2022,8 +1168,8 @@ bool device_debug::breakpoint_enable(int index, bool enable)
void device_debug::breakpoint_enable_all(bool enable)
{
// apply the enable to all breakpoints we own
- for (breakpoint &bp : m_bplist)
- breakpoint_enable(bp.index(), enable);
+ for (auto &bpp : m_bplist)
+ breakpoint_enable(bpp.second->index(), enable);
}
@@ -2039,7 +1185,7 @@ int device_debug::watchpoint_set(address_space &space, read_or_write type, offs_
// allocate a new one
u32 id = m_device.machine().debugger().cpu().get_watchpoint_index();
- m_wplist[space.spacenum()].emplace_back(std::make_unique<watchpoint>(this, m_symtable, id, space, type, address, length, condition, action));
+ m_wplist[space.spacenum()].emplace_back(std::make_unique<debug_watchpoint>(this, *m_symtable, id, space, type, address, length, condition, action));
return id;
}
@@ -2123,11 +1269,11 @@ int device_debug::registerpoint_set(const char *condition, const char *action)
{
// allocate a new one
u32 id = m_device.machine().debugger().cpu().get_registerpoint_index();
- m_rplist.emplace_front(m_symtable, id, condition, action);
+ m_rplist->emplace_front(*m_symtable, id, condition, action);
// update the flags and return the index
breakpoint_update_flags();
- return m_rplist.front().m_index;
+ return m_rplist->front().m_index;
}
@@ -2139,10 +1285,10 @@ int device_debug::registerpoint_set(const char *condition, const char *action)
bool device_debug::registerpoint_clear(int index)
{
// scan the list to see if we own this registerpoint
- for (auto brp = m_rplist.before_begin(); std::next(brp) != m_rplist.end(); ++brp)
+ for (auto brp = m_rplist->before_begin(); std::next(brp) != m_rplist->end(); ++brp)
if (std::next(brp)->m_index == index)
{
- m_rplist.erase_after(brp);
+ m_rplist->erase_after(brp);
breakpoint_update_flags();
return true;
}
@@ -2159,7 +1305,7 @@ bool device_debug::registerpoint_clear(int index)
void device_debug::registerpoint_clear_all()
{
// clear the list
- m_rplist.clear();
+ m_rplist->clear();
breakpoint_update_flags();
}
@@ -2172,7 +1318,7 @@ void device_debug::registerpoint_clear_all()
bool device_debug::registerpoint_enable(int index, bool enable)
{
// scan the list to see if we own this conditionpoint
- for (registerpoint &rp : m_rplist)
+ for (debug_registerpoint &rp : *m_rplist)
if (rp.m_index == index)
{
rp.m_enabled = enable;
@@ -2193,7 +1339,7 @@ bool device_debug::registerpoint_enable(int index, bool enable)
void device_debug::registerpoint_enable_all(bool enable)
{
// apply the enable to all registerpoints we own
- for (registerpoint &rp : m_rplist)
+ for (debug_registerpoint &rp : *m_rplist)
registerpoint_enable(rp.index(), enable);
}
@@ -2516,8 +1662,8 @@ void device_debug::breakpoint_update_flags()
{
// see if there are any enabled breakpoints
m_flags &= ~DEBUG_FLAG_LIVE_BP;
- for (breakpoint &bp : m_bplist)
- if (bp.m_enabled)
+ for (auto &bpp : m_bplist)
+ if (bpp.second->m_enabled)
{
m_flags |= DEBUG_FLAG_LIVE_BP;
break;
@@ -2526,7 +1672,7 @@ void device_debug::breakpoint_update_flags()
if ( ! ( m_flags & DEBUG_FLAG_LIVE_BP ) )
{
// see if there are any enabled registerpoints
- for (registerpoint &rp : m_rplist)
+ for (debug_registerpoint &rp : *m_rplist)
{
if (rp.m_enabled)
{
@@ -2551,7 +1697,10 @@ 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)
+ auto bpitp = m_bplist.equal_range(pc);
+ for (auto bpit = bpitp.first; bpit != bpitp.second; ++bpit)
+ {
+ debug_breakpoint &bp = *bpit->second;
if (bp.hit(pc))
{
// halt in the debugger by default
@@ -2569,9 +1718,10 @@ void device_debug::breakpoint_check(offs_t pc)
}
break;
}
+ }
// see if we have any matching registerpoints
- for (registerpoint &rp : m_rplist)
+ for (debug_registerpoint &rp : *m_rplist)
{
if (rp.hit())
{
@@ -2645,433 +1795,6 @@ void device_debug::hotspot_check(address_space &space, offs_t address)
}
-//**************************************************************************
-// DEBUG BREAKPOINT
-//**************************************************************************
-
-//-------------------------------------------------
-// breakpoint - constructor
-//-------------------------------------------------
-
-device_debug::breakpoint::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 device_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
-//**************************************************************************
-
-//-------------------------------------------------
-// watchpoint - constructor
-//-------------------------------------------------
-
-device_debug::watchpoint::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);
- }
- });
-}
-
-device_debug::watchpoint::~watchpoint()
-{
- m_space.remove_change_notifier(m_notifier);
- if (m_phr)
- m_phr->remove();
- if (m_phw)
- m_phw->remove();
-}
-
-void device_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 device_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 device_debug::watchpoint::triggered(read_or_write type, offs_t address, u64 data, u64 mem_mask)
-{
- auto &machine = m_debugInterface->m_device.machine();
- auto &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
-//**************************************************************************
-
-//-------------------------------------------------
-// registerpoint - constructor
-//-------------------------------------------------
-
-device_debug::registerpoint::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 device_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;
-}
-
-
//**************************************************************************
// TRACER
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index 36b718c6a16..b21bd72b122 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -13,8 +13,6 @@
#pragma once
-#include "express.h"
-
#include <set>
@@ -40,133 +38,12 @@ 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
diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp
index 2ab47b906f2..b4b03f75681 100644
--- a/src/emu/debug/dvbpoints.cpp
+++ b/src/emu/debug/dvbpoints.cpp
@@ -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();
diff --git a/src/emu/debug/dvbpoints.h b/src/emu/debug/dvbpoints.h
index 2cba6cd3081..18419434c03 100644
--- a/src/emu/debug/dvbpoints.h
+++ b/src/emu/debug/dvbpoints.h
@@ -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
diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp
index 95d72e5cda8..385a0c98a65 100644
--- a/src/emu/debug/dvdisasm.cpp
+++ b/src/emu/debug/dvdisasm.cpp
@@ -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);
diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp
index e4daaff1a80..eaffcac33b8 100644
--- a/src/emu/debug/dvmemory.cpp
+++ b/src/emu/debug/dvmemory.cpp
@@ -257,6 +257,118 @@ static inline float u64_to_double(u64 value)
}
//-------------------------------------------------
+// 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;
}
diff --git a/src/emu/debug/dvmemory.h b/src/emu/debug/dvmemory.h
index 05138c2ba0c..8aa5df7cbeb 100644
--- a/src/emu/debug/dvmemory.h
+++ b/src/emu/debug/dvmemory.h
@@ -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
diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp
index fb713ac58e7..28f2740a2f5 100644
--- a/src/emu/debug/dvwpoints.cpp
+++ b/src/emu/debug/dvwpoints.cpp
@@ -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();
diff --git a/src/emu/debug/dvwpoints.h b/src/emu/debug/dvwpoints.h
index 26b7c676e0e..753cbe62356 100644
--- a/src/emu/debug/dvwpoints.h
+++ b/src/emu/debug/dvwpoints.h
@@ -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
diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp
index bb1f17e05f3..2f5da8d0dea 100644
--- a/src/emu/debug/express.cpp
+++ b/src/emu/debug/express.cpp
@@ -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,59 +463,580 @@ void symbol_table::set_value(const char *symbol, u64 value)
}
+
+//**************************************************************************
+// EXPRESSION MEMORY HANDLERS
+//**************************************************************************
+
//-------------------------------------------------
-// memory_valid - return true if the given
-// memory name/space/offset combination is valid
+// read_memory - return 1,2,4 or 8 bytes
+// from the specified memory space
//-------------------------------------------------
-expression_error::error_code symbol_table::memory_valid(const char *name, expression_space 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_valid != nullptr)
+ 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)
{
- 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)
+ device->interface(memory);
}
- return expression_error::NO_SUCH_MEMORY_SPACE;
+ 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;
}
//-------------------------------------------------
-// memory_value - return a value read from memory
+// read_program_direct - read memory directly
+// from an opcode or RAM pointer
//-------------------------------------------------
-u64 symbol_table::memory_value(const char *name, expression_space space, u32 offset, int size, bool disable_se)
+u64 symbol_table::read_program_direct(address_space &space, int opcode, offs_t address, int size)
{
- // 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)
+ 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)
{
- 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;
+ if (space.endianness() == ENDIANNESS_LITTLE)
+ return base[BYTE8_XOR_LE(address) & lowmask];
+ else
+ return base[BYTE8_XOR_BE(address) & lowmask];
}
+ }
+
return 0;
}
//-------------------------------------------------
-// set_memory_value - write a value to memory
+// read_memory_region - read memory from a
+// memory region
//-------------------------------------------------
-void symbol_table::set_memory_value(const char *name, expression_space space, u32 offset, int size, u64 value, bool disable_se)
+u64 symbol_table::read_memory_region(const char *rgntag, offs_t address, int size)
{
- // 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)
+ 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)
{
- 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;
+ 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
+//-------------------------------------------------
+
+expression_error::error_code symbol_table::memory_valid(const char *name, expression_space space)
+{
+ 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)
+ {
+ 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 + (space - EXPSPACE_PROGRAM_LOGICAL)))
+ return expression_error::NO_SUCH_MEMORY_SPACE;
+ break;
+
+ case EXPSPACE_PROGRAM_PHYSICAL:
+ case EXPSPACE_DATA_PHYSICAL:
+ case EXPSPACE_IO_PHYSICAL:
+ case EXPSPACE_SPACE3_PHYSICAL:
+ 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_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL)))
+ return expression_error::NO_SUCH_MEMORY_SPACE;
+ break;
+
+ case EXPSPACE_RAMWRITE:
+ 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_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;
}
diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h
index 6b3ac6afa84..1caee590d5a 100644
--- a/src/emu/debug/express.h
+++ b/src/emu/debug/express.h
@@ -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
};
diff --git a/src/emu/debug/points.cpp b/src/emu/debug/points.cpp
new file mode 100644
index 00000000000..1cde2bbf486
--- /dev/null
+++ b/src/emu/debug/points.cpp
@@ -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;
+}
diff --git a/src/emu/debug/points.h b/src/emu/debug/points.h
new file mode 100644
index 00000000000..220b75728ce
--- /dev/null
+++ b/src/emu/debug/points.h
@@ -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
diff --git a/src/emu/debugger.cpp b/src/emu/debugger.cpp
index f3a35a2a0bb..5e866057d61 100644
--- a/src/emu/debugger.cpp
+++ b/src/emu/debugger.cpp
@@ -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");
}
diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h
index 275d1fecedd..bd7d2235a15 100644
--- a/src/emu/emufwd.h
+++ b/src/emu/emufwd.h
@@ -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;
diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp
index 00f8c9d67fd..daf6461b0f4 100644
--- a/src/frontend/mame/cheat.cpp
+++ b/src/frontend/mame/cheat.cpp
@@ -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();
}
diff --git a/src/frontend/mame/cheat.h b/src/frontend/mame/cheat.h
index b81225faf15..b8f3e89a4e5 100644
--- a/src/frontend/mame/cheat.h
+++ b/src/frontend/mame/cheat.h
@@ -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;
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 8d3bd043ce0..993a3eeb428 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -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();
diff --git a/src/mame/drivers/chihiro.cpp b/src/mame/drivers/chihiro.cpp
index 8bbdd7f4ed0..a30570a2de3 100644
--- a/src/mame/drivers/chihiro.cpp
+++ b/src/mame/drivers/chihiro.cpp
@@ -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];
diff --git a/src/mame/drivers/konamim2.cpp b/src/mame/drivers/konamim2.cpp
index 13728e0ea0d..28f2ac63b19 100644
--- a/src/mame/drivers/konamim2.cpp
+++ b/src/mame/drivers/konamim2.cpp
@@ -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.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.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 = 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 */
diff --git a/src/mame/machine/fddebug.cpp b/src/mame/machine/fddebug.cpp
index a62cb823d9a..1e186468e12 100644
--- a/src/mame/machine/fddebug.cpp
+++ b/src/mame/machine/fddebug.cpp
@@ -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;
diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp
index 95d14f42167..2e84803167e 100644
--- a/src/mame/machine/xbox.cpp
+++ b/src/mame/machine/xbox.cpp
@@ -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;
}
}
}
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp
index 63dbd420184..b8c0bbe7b80 100644
--- a/src/osd/modules/debugger/debuggdbstub.cpp
+++ b/src/osd/modules/debugger/debuggdbstub.cpp
@@ -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
diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp
index c1e3a4de21d..296b148c5db 100644
--- a/src/osd/modules/debugger/debugimgui.cpp
+++ b/src/osd/modules/debugger/debugimgui.cpp
@@ -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();
}
diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp
index 975e7ba6bc6..18bbc07dd70 100644
--- a/src/osd/modules/debugger/debugwin.cpp
+++ b/src/osd/modules/debugger/debugwin.cpp
@@ -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)
diff --git a/src/osd/modules/debugger/none.cpp b/src/osd/modules/debugger/none.cpp
index 3ce8d6572bc..ef23fe04089 100644
--- a/src/osd/modules/debugger/none.cpp
+++ b/src/osd/modules/debugger/none.cpp
@@ -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()
diff --git a/src/osd/modules/debugger/osx/debugconsole.mm b/src/osd/modules/debugger/osx/debugconsole.mm
index 1bd285e8c3b..c1689a8b855 100644
--- a/src/osd/modules/debugger/osx/debugconsole.mm
+++ b/src/osd/modules/debugger/osx/debugconsole.mm
@@ -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]);
diff --git a/src/osd/modules/debugger/osx/debugview.mm b/src/osd/modules/debugger/osx/debugview.mm
index a414e4ad8a4..df7c4dbcc01 100644
--- a/src/osd/modules/debugger/osx/debugview.mm
+++ b/src/osd/modules/debugger/osx/debugview.mm
@@ -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();
}
diff --git a/src/osd/modules/debugger/osx/debugwindowhandler.mm b/src/osd/modules/debugger/osx/debugwindowhandler.mm
index c1aa8e383a2..fd1eb44f6d3 100644
--- a/src/osd/modules/debugger/osx/debugwindowhandler.mm
+++ b/src/osd/modules/debugger/osx/debugwindowhandler.mm
@@ -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();
}
diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm
index eb039f4ca17..1f286a6bfc4 100644
--- a/src/osd/modules/debugger/osx/disassemblyviewer.mm
+++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm
@@ -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]);
diff --git a/src/osd/modules/debugger/osx/memoryview.mm b/src/osd/modules/debugger/osx/memoryview.mm
index 78af307e993..0db48236b79 100644
--- a/src/osd/modules/debugger/osx/memoryview.mm
+++ b/src/osd/modules/debugger/osx/memoryview.mm
@@ -9,7 +9,6 @@
#include "emu.h"
#import "memoryview.h"
-#include "debug/debugcpu.h"
#include "debug/debugvw.h"
#include "util/xmlfile.h"
diff --git a/src/osd/modules/debugger/osx/memoryviewer.mm b/src/osd/modules/debugger/osx/memoryviewer.mm
index 80d5434a826..b1064aee69f 100644
--- a/src/osd/modules/debugger/osx/memoryviewer.mm
+++ b/src/osd/modules/debugger/osx/memoryviewer.mm
@@ -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];
diff --git a/src/osd/modules/debugger/osx/registersview.mm b/src/osd/modules/debugger/osx/registersview.mm
index ae202fa488e..c710179c5bd 100644
--- a/src/osd/modules/debugger/osx/registersview.mm
+++ b/src/osd/modules/debugger/osx/registersview.mm
@@ -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;
diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp
index 04cbd523cdd..52b33b50da8 100644
--- a/src/osd/modules/debugger/qt/dasmwindow.cpp
+++ b/src/osd/modules/debugger/qt/dasmwindow.cpp
@@ -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);
diff --git a/src/osd/modules/debugger/qt/mainwindow.cpp b/src/osd/modules/debugger/qt/mainwindow.cpp
index 6a79ebf955d..f2026db67e9 100644
--- a/src/osd/modules/debugger/qt/mainwindow.cpp
+++ b/src/osd/modules/debugger/qt/mainwindow.cpp
@@ -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)
{
diff --git a/src/osd/modules/debugger/qt/memorywindow.cpp b/src/osd/modules/debugger/qt/memorywindow.cpp
index 2124effcbbd..bead6af0cef 100644
--- a/src/osd/modules/debugger/qt/memorywindow.cpp
+++ b/src/osd/modules/debugger/qt/memorywindow.cpp
@@ -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);
+ }
}
}
diff --git a/src/osd/modules/debugger/qt/windowqt.cpp b/src/osd/modules/debugger/qt/windowqt.cpp
index dda9ee64dc7..aa32ffb5220 100644
--- a/src/osd/modules/debugger/qt/windowqt.cpp
+++ b/src/osd/modules/debugger/qt/windowqt.cpp
@@ -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()
diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp
index 27a6228d2f5..e6ad4c0986f 100644
--- a/src/osd/modules/debugger/win/consolewininfo.cpp
+++ b/src/osd/modules/debugger/win/consolewininfo.cpp
@@ -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);
diff --git a/src/osd/modules/debugger/win/debugviewinfo.cpp b/src/osd/modules/debugger/win/debugviewinfo.cpp
index ff46d13c7fe..1b824a04b8c 100644
--- a/src/osd/modules/debugger/win/debugviewinfo.cpp
+++ b/src/osd/modules/debugger/win/debugviewinfo.cpp
@@ -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
diff --git a/src/osd/modules/debugger/win/debugwininfo.cpp b/src/osd/modules/debugger/win/debugwininfo.cpp
index 1645582038c..e684e1f32fa 100644
--- a/src/osd/modules/debugger/win/debugwininfo.cpp
+++ b/src/osd/modules/debugger/win/debugwininfo.cpp
@@ -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
{
diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.cpp b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
index 0d22b7b8d39..800443b47c1 100644
--- a/src/osd/modules/debugger/win/disasmbasewininfo.cpp
+++ b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
@@ -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)