summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/debugcmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/debugcmd.cpp')
-rw-r--r--src/emu/debug/debugcmd.cpp1650
1 files changed, 733 insertions, 917 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index 20431072cff..ad463ace500 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -21,8 +21,10 @@
#include "debugger.h"
#include "emuopts.h"
+#include "fileio.h"
#include "natkeyboard.h"
#include "render.h"
+#include "screen.h"
#include "softlist.h"
#include "corestr.h"
@@ -30,35 +32,7 @@
#include <algorithm>
#include <cctype>
#include <fstream>
-
-
-
-namespace {
-
-template <typename T>
-inline std::string_view::size_type find_delimiter(std::string_view str, T &&is_delim)
-{
- unsigned parens = 0;
- for (std::string_view::size_type i = 0; str.length() > i; ++i)
- {
- if (str[i] == '(')
- {
- ++parens;
- }
- else if (parens)
- {
- if (str[i] == ')')
- --parens;
- }
- else if (is_delim(str[i]))
- {
- return i;
- }
- }
- return std::string_view::npos;
-}
-
-} // anonymous namespace
+#include <sstream>
@@ -79,7 +53,8 @@ const size_t debugger_commands::MAX_GLOBALS = 1000;
bool debugger_commands::cheat_address_is_valid(address_space &space, offs_t address)
{
- return space.device().memory().translate(space.spacenum(), TRANSLATE_READ, address) && (space.get_write_ptr(address) != nullptr);
+ address_space *tspace;
+ return space.device().memory().translate(space.spacenum(), device_memory_interface::TR_READ, address, tspace) && (tspace->get_write_ptr(address) != nullptr);
}
@@ -130,14 +105,15 @@ u64 debugger_commands::cheat_system::read_extended(offs_t address) const
{
address &= space->logaddrmask();
u64 value = space->unmap();
- if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, address))
+ address_space *tspace;
+ if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
{
switch (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;
+ case 1: value = tspace->read_byte(address); break;
+ case 2: value = tspace->read_word_unaligned(address); break;
+ case 4: value = tspace->read_dword_unaligned(address); break;
+ case 8: value = tspace->read_qword_unaligned(address); break;
}
}
return sign_extend(byte_swap(value));
@@ -194,7 +170,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
if ((valcount == 1) && (blockcount == 1) && strstr(name, "/globals/"))
{
char symname[100];
- sprintf(symname, ".%s", strrchr(name, '/') + 1);
+ snprintf(symname, 100, ".%s", strrchr(name, '/') + 1);
m_global_array[itemnum].base = base;
m_global_array[itemnum].size = valsize;
symtable.add(
@@ -231,6 +207,9 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("gtime", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1));
m_console.register_command("gt", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1));
m_console.register_command("gp", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1));
+ m_console.register_command("gbt", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_branch, this, true, _1));
+ m_console.register_command("gbf", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_branch, this, false, _1));
+ m_console.register_command("gni", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_next_instruction, this, _1));
m_console.register_command("next", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1));
m_console.register_command("n", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1));
m_console.register_command("focus", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1));
@@ -239,6 +218,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("suspend", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1));
m_console.register_command("resume", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1));
m_console.register_command("cpulist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cpulist, this, _1));
+ m_console.register_command("time", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_time, this, _1));
m_console.register_command("comadd", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1));
m_console.register_command("//", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1));
@@ -275,6 +255,13 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("rpenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_rpdisenable, this, true, _1));
m_console.register_command("rplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rplist, this, _1));
+ m_console.register_command("epset", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_epset, this, _1));
+ m_console.register_command("ep", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_epset, this, _1));
+ m_console.register_command("epclear", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epclear, this, _1));
+ m_console.register_command("epdisable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epdisenable, this, false, _1));
+ m_console.register_command("epenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epdisenable, this, true, _1));
+ m_console.register_command("eplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_eplist, this, _1));
+
m_console.register_command("statesave", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1));
m_console.register_command("ss", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1));
m_console.register_command("stateload", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1));
@@ -442,475 +429,15 @@ void debugger_commands::global_set(global_entry *global, u64 value)
-/***************************************************************************
- PARAMETER VALIDATION HELPERS
-***************************************************************************/
-
-/// \brief Validate parameter as a Boolean value
-///
-/// Validates a parameter as a Boolean value. Fixed strings and
-/// expressions evaluating to numeric values are recognised. The result
-/// is unchanged for an empty string.
-/// \param [in] param The parameter string.
-/// \param [in,out] result The default value on entry, and the value of
-/// the parameter interpreted as a Boolean on success. Unchanged if
-/// the parameter is an empty string.
-/// \return true if the parameter is a valid Boolean value or an empty
-/// string, or false otherwise.
-bool debugger_commands::validate_boolean_parameter(const std::string &param, bool &result)
-{
- // nullptr parameter does nothing and returns no error
- if (param.empty())
- return true;
-
- // evaluate the expression; success if no error
- bool const is_true = !core_stricmp(param.c_str(), "true");
- bool const is_false = !core_stricmp(param.c_str(), "false");
-
- if (is_true || is_false)
- {
- result = is_true;
- return true;
- }
-
- // try to evaluate as a number
- u64 val;
- if (!validate_number_parameter(param, val))
- return false;
-
- result = val != 0;
- return true;
-}
-
-
-/// \brief Validate parameter as a numeric value
-///
-/// Parses the parameter as an expression and evaluates it as a number.
-/// \param [in] param The parameter string.
-/// \param [out] result The numeric value of the expression on success.
-/// Unchanged on failure.
-/// \return true if the parameter is a valid expression that evaluates
-/// to a numeric value, or false otherwise.
-bool debugger_commands::validate_number_parameter(std::string_view param, u64 &result)
-{
- // evaluate the expression; success if no error
- try
- {
- result = parsed_expression(m_console.visible_symtable(), param).execute();
- return true;
- }
- catch (expression_error const &error)
- {
- // print an error pointing to the character that caused it
- m_console.printf("Error in expression: %s\n", param);
- m_console.printf(" %*s^", error.offset(), "");
- m_console.printf("%s\n", error.code_string());
- return false;
- }
-}
-
-
-/// \brief Validate parameter as a device
-///
-/// Validates a parameter as a device identifier and retrieves the
-/// device on success. A string corresponding to the tag of a device
-/// refers to that device; an empty string refers to the current CPU
-/// with debugger focus; any other string is parsed as an expression
-/// and treated as an index of a device implementing
-/// #device_execute_interface and #device_state_interface, and exposing
-/// a generic PC base value.
-/// \param [in] param The parameter string.
-/// \param [out] result A pointer to the device on success, or unchanged
-/// on failure.
-/// \return true if the parameter refers to a device in the current
-/// system, or false otherwise.
-bool debugger_commands::validate_device_parameter(std::string_view param, device_t *&result)
-{
- // if no parameter, use the visible CPU
- if (param.empty())
- {
- device_t *const current = m_console.get_visible_cpu();
- if (current)
- {
- result = current;
- return true;
- }
- else
- {
- m_console.printf("No valid CPU is currently selected\n");
- return false;
- }
- }
-
- // next look for a tag match
- std::string_view relative = param;
- device_t &base = get_device_search_base(relative);
- device_t *device = base.subdevice(strmakelower(relative));
- if (device)
- {
- result = device;
- return true;
- }
-
- // then evaluate as an expression; on an error assume it was a tag
- u64 cpunum;
- try
- {
- cpunum = parsed_expression(m_console.visible_symtable(), param).execute();
- }
- catch (expression_error &)
- {
- m_console.printf("Unable to find device '%s'\n", param);
- return false;
- }
-
- // attempt to find by numerical index
- device = get_cpu_by_index(cpunum);
- if (device)
- {
- result = device;
- return true;
- }
- else
- {
- // if out of range, complain
- m_console.printf("Invalid CPU index %u\n", cpunum);
- return false;
- }
-}
-
-
-/// \brief Validate a parameter as a CPU
-///
-/// Validates a parameter as a CPU identifier. Uses the same rules as
-/// #validate_device_parameter to identify devices, but additionally
-/// checks that the device is a "CPU" for the debugger's purposes.
-/// \param [in] The parameter string.
-/// \param [out] result The device on success, or unchanged on failure.
-/// \return true if the parameter refers to a CPU-like device in the
-/// current system, or false otherwise.
-bool debugger_commands::validate_cpu_parameter(std::string_view param, device_t *&result)
-{
- // first do the standard device thing
- device_t *device;
- if (!validate_device_parameter(param, device))
- return false;
-
- // check that it's a "CPU" for the debugger's purposes
- device_execute_interface const *execute;
- if (device->interface(execute))
- {
- result = device;
- return true;
- }
-
- m_console.printf("Device %s is not a CPU\n", device->name());
- return false;
-}
-
-
-/// \brief Validate a parameter as an address space identifier
-///
-/// Validates a parameter as an address space identifier. Uses the same
-/// rules as #validate_device_parameter to identify devices. If the
-/// default address space number is negative, the first address space
-/// exposed by the device will be used as the default.
-/// \param [in] The parameter string.
-/// \param [in] spacenum The default address space index. If negative,
-/// the first address space exposed by the device (i.e. the address
-/// space with the lowest index) will be used as the default.
-/// \param [out] result The address space on success, or unchanged on
-/// failure.
-/// \return true if the parameter refers to an address space in the
-/// current system, or false otherwise.
-bool debugger_commands::validate_device_space_parameter(std::string_view param, int spacenum, address_space *&result)
-{
- device_t *device;
- std::string spacename;
- if (param.empty())
- {
- // if no parameter, use the visible CPU
- device = m_console.get_visible_cpu();
- if (!device)
- {
- m_console.printf("No valid CPU is currently selected\n");
- return false;
- }
- }
- else
- {
- // look for a tag match on the whole parameter value
- std::string_view relative = param;
- device_t &base = get_device_search_base(relative);
- device = base.subdevice(strmakelower(relative));
-
- // if that failed, treat the last component as an address space
- if (!device)
- {
- auto const delimiter = relative.find_last_of(":^");
- bool const found = std::string_view::npos != delimiter;
- if (!found || (':' == relative[delimiter]))
- {
- spacename = strmakelower(relative.substr(found ? (delimiter + 1) : 0));
- relative = relative.substr(0, !found ? 0 : !delimiter ? 1 : delimiter);
- if (!relative.empty())
- device = base.subdevice(strmakelower(relative));
- else if (m_console.get_visible_cpu())
- device = m_console.get_visible_cpu();
- else
- device = &m_machine.root_device();
- }
- }
- }
-
- // if still no device found, evaluate as an expression
- if (!device)
- {
- u64 cpunum;
- try
- {
- cpunum = parsed_expression(m_console.visible_symtable(), param).execute();
- }
- catch (expression_error const &)
- {
- // parsing failed - assume it was a tag
- m_console.printf("Unable to find device '%s'\n", param);
- return false;
- }
-
- // attempt to find by numerical index
- device = get_cpu_by_index(cpunum);
- if (!device)
- {
- // if out of range, complain
- m_console.printf("Invalid CPU index %u\n", cpunum);
- return false;
- }
- }
-
- // ensure the device implements the memory interface
- device_memory_interface *memory;
- if (!device->interface(memory))
- {
- m_console.printf("No memory interface found for device %s\n", device->name());
- return false;
- }
-
- // fall back to supplied default space if appropriate
- if (spacename.empty() && (0 <= spacenum))
- {
- if (memory->has_space(spacenum))
- {
- result = &memory->space(spacenum);
- return true;
- }
- else
- {
- m_console.printf("No matching memory space found for device '%s'\n", device->tag());
- return false;
- }
- }
-
- // otherwise find the specified space or fall back to the first populated space
- for (int i = 0; memory->max_space_count() > i; ++i)
- {
- if (memory->has_space(i) && (spacename.empty() || (memory->space(i).name() == spacename)))
- {
- result = &memory->space(i);
- return true;
- }
- }
-
- // report appropriate error message
- if (spacename.empty())
- m_console.printf("No memory spaces found for device '%s'\n", device->tag());
- else
- m_console.printf("Memory space '%s' not found found for device '%s'\n", spacename, device->tag());
- return false;
-}
-
-
-/// \brief Validate a parameter as a target address
-///
-/// Validates a parameter as an numeric expression to use as an address
-/// optionally followed by a colon and a device identifier. If the
-/// device identifier is not presnt, the current CPU with debugger focus
-/// is assumed. See #validate_device_parameter for information on how
-/// device parametersare interpreted.
-/// \param [in] The parameter string.
-/// \param [in] spacenum The default address space index. If negative,
-/// the first address space exposed by the device (i.e. the address
-/// space with the lowest index) will be used as the default.
-/// \param [out] space The address space on success, or unchanged on
-/// failure.
-/// \param [out] addr The address on success, or unchanged on failure.
-/// \return true if the address is a valid expression evaluating to a
-/// number and the address space is found, or false otherwise.
-bool debugger_commands::validate_target_address_parameter(std::string_view param, int spacenum, address_space *&space, u64 &addr)
-{
- // check for the device delimiter
- std::string_view::size_type const devdelim = find_delimiter(param, [] (char ch) { return ':' == ch; });
- std::string_view device;
- if (devdelim != std::string::npos)
- device = param.substr(devdelim + 1);
-
- // parse the address first
- u64 addrval;
- if (!validate_number_parameter(param.substr(0, devdelim), addrval))
- return false;
-
- // find the address space
- if (!validate_device_space_parameter(device, spacenum, space))
- return false;
-
- // set the address now that we have the space
- addr = addrval;
- return true;
-}
-
-
-/// \brief Validate a parameter as a memory region
-///
-/// Validates a parameter as a memory region tag and retrieves the
-/// specified memory region.
-/// \param [in] The parameter string.
-/// \param [out] result The memory region on success, or unchanged on
-/// failure.
-/// \return true if the parameter refers to a memory region in the
-/// current system, or false otherwise.
-bool debugger_commands::validate_memory_region_parameter(std::string_view param, memory_region *&result)
-{
- auto const &regions = m_machine.memory().regions();
- std::string_view relative = param;
- device_t &base = get_device_search_base(relative);
- auto const iter = regions.find(base.subtag(strmakelower(relative)));
- if (regions.end() != iter)
- {
- result = iter->second.get();
- return true;
- }
- else
- {
- m_console.printf("No matching memory region found for '%s'\n", param);
- return false;
- }
-}
-
-
-/// \brief Get search base for device or address space parameter
-///
-/// Handles prefix prefixes used to indicate that a device tag should be
-/// interpreted relative to the selected CPU. Removes the recognised
-/// prefixes from the parameter value.
-/// \param [in,out] param The parameter string. Recognised prefixes
-/// affecting the search base are removed, leaving a tag relative to
-/// the base device.
-/// \return A reference to the base device that the tag should be
-/// interpreted relative to.
-device_t &debugger_commands::get_device_search_base(std::string_view &param)
-{
- if (!param.empty())
- {
- // handle ".:" or ".^" prefix for tag relative to current CPU if any
- if (('.' == param[0]) && ((param.size() == 1) || (':' == param[1]) || ('^' == param[1])))
- {
- param.remove_prefix(((param.size() > 1) && (':' == param[1])) ? 2 : 1);
- device_t *const current = m_console.get_visible_cpu();
- return current ? *current : m_machine.root_device();
- }
-
- // a sibling path makes most sense relative to current CPU
- if ('^' == param[0])
- {
- device_t *const current = m_console.get_visible_cpu();
- return current ? *current : m_machine.root_device();
- }
- }
-
-
- // default to root device
- return m_machine.root_device();
-}
-
-
-/// \brief Get CPU by index
-///
-/// Looks up a CPU by the number the debugger assigns it based on its
-/// position in the device tree relative to other CPUs.
-/// \param [in] cpunum Zero-based index of the CPU to find.
-/// \return A pointer to the CPU if found, or \c nullptr if no CPU has
-/// the specified index.
-device_t *debugger_commands::get_cpu_by_index(u64 cpunum)
-{
- unsigned index = 0;
- for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device()))
- {
- // real CPUs should have pcbase
- device_state_interface const *state;
- if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE))
- {
- if (index++ == cpunum)
- {
- return &exec.device();
- }
- }
- }
- return nullptr;
-}
-
-
-/*-------------------------------------------------
- debug_command_parameter_expression - validates
- an expression parameter
--------------------------------------------------*/
-
-bool debugger_commands::debug_command_parameter_expression(std::string_view param, parsed_expression &result)
-{
- try
- {
- // parse the expression; success if no error
- result.parse(param);
- return true;
- }
- catch (expression_error const &err)
- {
- // output an error
- m_console.printf("Error in expression: %s\n", param);
- m_console.printf(" %*s^", err.offset(), "");
- m_console.printf("%s\n", err.code_string());
- return false;
- }
-}
-
-
-/*-------------------------------------------------
- debug_command_parameter_command - validates a
- command parameter
--------------------------------------------------*/
-
-bool debugger_commands::debug_command_parameter_command(const char *param)
-{
- /* nullptr parameter does nothing and returns no error */
- if (param == nullptr)
- return true;
-
- /* validate the comment; success if no error */
- CMDERR err = m_console.validate_command(param);
- if (err.error_class() == CMDERR::NONE)
- return true;
-
- /* output an error */
- m_console.printf("Error in command: %s\n", param);
- m_console.printf(" %*s^", err.error_offset(), "");
- m_console.printf("%s\n", debugger_console::cmderr_to_string(err));
- return 0;
-}
+//**************************************************************************
+// COMMAND IMPLEMENTATIONS
+//**************************************************************************
/*-------------------------------------------------
execute_help - execute the help command
-------------------------------------------------*/
-void debugger_commands::execute_help(const std::vector<std::string> &params)
+void debugger_commands::execute_help(const std::vector<std::string_view> &params)
{
if (params.size() == 0)
m_console.printf_wrap(80, "%s\n", debug_get_help(std::string_view()));
@@ -923,12 +450,12 @@ void debugger_commands::execute_help(const std::vector<std::string> &params)
execute_print - execute the print command
-------------------------------------------------*/
-void debugger_commands::execute_print(const std::vector<std::string> &params)
+void debugger_commands::execute_print(const std::vector<std::string_view> &params)
{
/* validate the other parameters */
u64 values[MAX_COMMAND_PARAMS];
for (int i = 0; i < params.size(); i++)
- if (!validate_number_parameter(params[i], values[i]))
+ if (!m_console.validate_number_parameter(params[i], values[i]))
return;
/* then print each one */
@@ -942,131 +469,177 @@ void debugger_commands::execute_print(const std::vector<std::string> &params)
mini_printf - safe printf to a buffer
-------------------------------------------------*/
-int debugger_commands::mini_printf(char *buffer, const char *format, int params, u64 *param)
+bool debugger_commands::mini_printf(std::ostream &stream, const std::vector<std::string_view> &params)
{
- const char *f = format;
- char *p = buffer;
+ std::string_view const format(params[0]);
+ auto f = format.begin();
+
+ int param = 1;
+ u64 number;
- /* parse the string looking for % signs */
- for (;;)
+ // parse the string looking for % signs
+ while (f != format.end())
{
char c = *f++;
- if (!c) break;
- /* escape sequences */
+ // escape sequences
if (c == '\\')
{
+ if (f == format.end()) break;
c = *f++;
- if (!c) break;
switch (c)
{
- case '\\': *p++ = c; break;
- case 'n': *p++ = '\n'; break;
+ case '\\': stream << c; break;
+ case 'n': stream << '\n'; break;
default: break;
}
continue;
}
- /* formatting */
+ // formatting
else if (c == '%')
{
+ bool left_justify = false;
+ bool zero_fill = false;
int width = 0;
- int zerofill = 0;
+ int precision = 0;
- /* parse out the width */
- for (;;)
+ // parse optional left justification flag
+ if (f != format.end() && *f == '-')
{
- c = *f++;
- if (!c || c < '0' || c > '9') break;
- if (c == '0' && width == 0)
- zerofill = 1;
- width = width * 10 + (c - '0');
+ left_justify = true;
+ f++;
+ }
+
+ // parse optional zero fill flag
+ if (f != format.end() && *f == '0')
+ {
+ zero_fill = true;
+ f++;
+ }
+
+ // parse optional width
+ while (f != format.end() && isdigit(*f))
+ width = width * 10 + (*f++ - '0');
+ if (f == format.end())
+ break;
+
+ // apply left justification
+ if (left_justify)
+ width = -width;
+
+ if ((c = *f++) == '.')
+ {
+ // parse optional precision
+ while (f != format.end() && isdigit(*f))
+ precision = precision * 10 + (*f++ - '0');
+
+ // get the format
+ if (f != format.end())
+ c = *f++;
+ else
+ break;
}
- if (!c) break;
- /* get the format */
switch (c)
{
case '%':
- *p++ = c;
+ stream << c;
break;
case 'X':
+ if (param < params.size() && m_console.validate_number_parameter(params[param++], number))
+ util::stream_format(stream, zero_fill ? "%0*X" : "%*X", width, number);
+ else
+ {
+ m_console.printf("Not enough parameters for format!\n");
+ return false;
+ }
+ break;
case 'x':
- if (params == 0)
+ if (param < params.size() && m_console.validate_number_parameter(params[param++], number))
+ util::stream_format(stream, zero_fill ? "%0*x" : "%*x", width, number);
+ else
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
- if (u32(*param >> 32) != 0)
- p += sprintf(p, zerofill ? "%0*X" : "%*X", (width <= 8) ? 1 : width - 8, u32(*param >> 32));
- else if (width > 8)
- p += sprintf(p, zerofill ? "%0*X" : "%*X", width - 8, 0);
- p += sprintf(p, zerofill ? "%0*X" : "%*X", (width < 8) ? width : 8, u32(*param));
- param++;
- params--;
break;
case 'O':
case 'o':
- if (params == 0)
- {
- m_console.printf("Not enough parameters for format!\n");
- return 0;
- }
- if (u32(*param >> 60) != 0)
- {
- p += sprintf(p, zerofill ? "%0*o" : "%*o", (width <= 20) ? 1 : width - 20, u32(*param >> 60));
- p += sprintf(p, "%0*o", 10, u32(BIT(*param, 30, 30)));
- }
+ if (param < params.size() && m_console.validate_number_parameter(params[param++], number))
+ util::stream_format(stream, zero_fill ? "%0*o" : "%*o", width, number);
else
{
- if (width > 20)
- p += sprintf(p, zerofill ? "%0*o" : "%*o", width - 20, 0);
- if (u32(BIT(*param, 30, 30)) != 0)
- p += sprintf(p, zerofill ? "%0*o" : "%*o", (width <= 10) ? 1 : width - 10, u32(BIT(*param, 30, 30)));
- else if (width > 10)
- p += sprintf(p, zerofill ? "%0*o" : "%*o", width - 10, 0);
+ m_console.printf("Not enough parameters for format!\n");
+ return false;
}
- p += sprintf(p, zerofill ? "%0*o" : "%*o", (width < 10) ? width : 10, u32(BIT(*param, 0, 30)));
- param++;
- params--;
break;
case 'D':
case 'd':
- if (params == 0)
+ if (param < params.size() && m_console.validate_number_parameter(params[param++], number))
+ util::stream_format(stream, zero_fill ? "%0*d" : "%*d", width, number);
+ else
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
- p += sprintf(p, zerofill ? "%0*d" : "%*d", width, u32(*param));
- param++;
- params--;
break;
+
case 'C':
case 'c':
- if (params == 0)
+ if (param < params.size() && m_console.validate_number_parameter(params[param++], number))
+ stream << char(number);
+ else
{
m_console.printf("Not enough parameters for format!\n");
- return 0;
+ return false;
}
- p += sprintf(p, "%c", char(*param));
- param++;
- params--;
break;
+ case 's':
+ {
+ address_space *space;
+ if (param < params.size() && m_console.validate_target_address_parameter(params[param++], -1, space, number))
+ {
+ address_space *tspace;
+ std::string s;
+
+ for (u32 address = u32(number), taddress; space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, taddress = address, tspace); address++)
+ {
+ u8 const data = tspace->read_byte(taddress);
+
+ if (!data)
+ break;
+
+ s += data;
+
+ if (precision == 1)
+ break;
+ else if (precision)
+ precision--;
+ }
+
+ util::stream_format(stream, "%*s", width, s);
+ }
+ else
+ {
+ m_console.printf("Not enough parameters for format!\n");
+ return false;
+ }
+ }
+ break;
}
}
- /* normal stuff */
+ // normal stuff
else
- *p++ = c;
+ stream << c;
}
- /* NULL-terminate and exit */
- *p = 0;
- return 1;
+ return true;
}
@@ -1076,12 +649,12 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
-------------------------------------------------*/
template <typename T>
-void debugger_commands::execute_index_command(std::vector<std::string> const &params, T &&apply, char const *unused_message)
+void debugger_commands::execute_index_command(std::vector<std::string_view> const &params, T &&apply, char const *unused_message)
{
std::vector<u64> index(params.size());
for (int paramnum = 0; paramnum < params.size(); paramnum++)
{
- if (!validate_number_parameter(params[paramnum], index[paramnum]))
+ if (!m_console.validate_number_parameter(params[paramnum], index[paramnum]))
return;
}
@@ -1105,18 +678,12 @@ void debugger_commands::execute_index_command(std::vector<std::string> const &pa
execute_printf - execute the printf command
-------------------------------------------------*/
-void debugger_commands::execute_printf(const std::vector<std::string> &params)
+void debugger_commands::execute_printf(const std::vector<std::string_view> &params)
{
- /* validate the other parameters */
- u64 values[MAX_COMMAND_PARAMS];
- for (int i = 1; i < params.size(); i++)
- if (!validate_number_parameter(params[i], values[i]))
- return;
-
/* then do a printf */
- char buffer[1024];
- if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
- m_console.printf("%s\n", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, params))
+ m_console.printf("%s\n", std::move(buffer).str());
}
@@ -1124,18 +691,12 @@ void debugger_commands::execute_printf(const std::vector<std::string> &params)
execute_logerror - execute the logerror command
-------------------------------------------------*/
-void debugger_commands::execute_logerror(const std::vector<std::string> &params)
+void debugger_commands::execute_logerror(const std::vector<std::string_view> &params)
{
- /* validate the other parameters */
- u64 values[MAX_COMMAND_PARAMS];
- for (int i = 1; i < params.size(); i++)
- if (!validate_number_parameter(params[i], values[i]))
- return;
-
/* then do a printf */
- char buffer[1024];
- if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
- m_machine.logerror("%s", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, params))
+ m_machine.logerror("%s", std::move(buffer).str());
}
@@ -1143,18 +704,12 @@ void debugger_commands::execute_logerror(const std::vector<std::string> &params)
execute_tracelog - execute the tracelog command
-------------------------------------------------*/
-void debugger_commands::execute_tracelog(const std::vector<std::string> &params)
+void debugger_commands::execute_tracelog(const std::vector<std::string_view> &params)
{
- /* validate the other parameters */
- u64 values[MAX_COMMAND_PARAMS];
- for (int i = 1; i < params.size(); i++)
- if (!validate_number_parameter(params[i], values[i]))
- return;
-
/* then do a printf */
- char buffer[1024];
- if (mini_printf(buffer, params[0].c_str(), params.size() - 1, &values[1]))
- m_console.get_visible_cpu()->debug()->trace_printf("%s", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, params))
+ m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str());
}
@@ -1162,11 +717,10 @@ void debugger_commands::execute_tracelog(const std::vector<std::string> &params)
execute_tracesym - execute the tracesym command
-------------------------------------------------*/
-void debugger_commands::execute_tracesym(const std::vector<std::string> &params)
+void debugger_commands::execute_tracesym(const std::vector<std::string_view> &params)
{
// build a format string appropriate for the parameters and validate them
std::stringstream format;
- u64 values[MAX_COMMAND_PARAMS];
for (int i = 0; i < params.size(); i++)
{
// find this symbol
@@ -1181,16 +735,16 @@ void debugger_commands::execute_tracesym(const std::vector<std::string> &params)
util::stream_format(format, "%s=%s ",
params[i],
sym->format().empty() ? "%16X" : sym->format());
-
- // validate the parameter
- if (!validate_number_parameter(params[i], values[i]))
- return;
}
+ // build parameters for printf
+ std::vector<std::string_view> printf_params(params);
+ printf_params.insert(printf_params.begin(), format.str());
+
// then do a printf
- char buffer[1024];
- if (mini_printf(buffer, format.str().c_str(), params.size(), values))
- m_console.get_visible_cpu()->debug()->trace_printf("%s", buffer);
+ std::ostringstream buffer;
+ if (mini_printf(buffer, printf_params))
+ m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str());
}
@@ -1198,7 +752,7 @@ void debugger_commands::execute_tracesym(const std::vector<std::string> &params)
execute_cls - execute the cls command
-------------------------------------------------*/
-void debugger_commands::execute_cls(const std::vector<std::string> &params)
+void debugger_commands::execute_cls(const std::vector<std::string_view> &params)
{
text_buffer_clear(m_console.get_console_textbuf());
}
@@ -1208,7 +762,7 @@ void debugger_commands::execute_cls(const std::vector<std::string> &params)
execute_quit - execute the quit command
-------------------------------------------------*/
-void debugger_commands::execute_quit(const std::vector<std::string> &params)
+void debugger_commands::execute_quit(const std::vector<std::string_view> &params)
{
osd_printf_warning("Exited via the debugger\n");
m_machine.schedule_exit();
@@ -1219,10 +773,10 @@ void debugger_commands::execute_quit(const std::vector<std::string> &params)
execute_do - execute the do command
-------------------------------------------------*/
-void debugger_commands::execute_do(const std::vector<std::string> &params)
+void debugger_commands::execute_do(const std::vector<std::string_view> &params)
{
u64 dummy;
- validate_number_parameter(params[0], dummy);
+ m_console.validate_number_parameter(params[0], dummy);
}
@@ -1230,11 +784,11 @@ void debugger_commands::execute_do(const std::vector<std::string> &params)
execute_step - execute the step command
-------------------------------------------------*/
-void debugger_commands::execute_step(const std::vector<std::string> &params)
+void debugger_commands::execute_step(const std::vector<std::string_view> &params)
{
/* if we have a parameter, use it */
u64 steps = 1;
- if (params.size() > 0 && !validate_number_parameter(params[0], steps))
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], steps))
return;
m_console.get_visible_cpu()->debug()->single_step(steps);
@@ -1245,11 +799,11 @@ void debugger_commands::execute_step(const std::vector<std::string> &params)
execute_over - execute the over command
-------------------------------------------------*/
-void debugger_commands::execute_over(const std::vector<std::string> &params)
+void debugger_commands::execute_over(const std::vector<std::string_view> &params)
{
/* if we have a parameter, use it */
u64 steps = 1;
- if (params.size() > 0 && !validate_number_parameter(params[0], steps))
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], steps))
return;
m_console.get_visible_cpu()->debug()->single_step_over(steps);
@@ -1260,7 +814,7 @@ void debugger_commands::execute_over(const std::vector<std::string> &params)
execute_out - execute the out command
-------------------------------------------------*/
-void debugger_commands::execute_out(const std::vector<std::string> &params)
+void debugger_commands::execute_out(const std::vector<std::string_view> &params)
{
m_console.get_visible_cpu()->debug()->single_step_out();
}
@@ -1270,12 +824,12 @@ void debugger_commands::execute_out(const std::vector<std::string> &params)
execute_go - execute the go command
-------------------------------------------------*/
-void debugger_commands::execute_go(const std::vector<std::string> &params)
+void debugger_commands::execute_go(const std::vector<std::string_view> &params)
{
u64 addr = ~0;
/* if we have a parameter, use it instead */
- if (params.size() > 0 && !validate_number_parameter(params[0], addr))
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], addr))
return;
m_console.get_visible_cpu()->debug()->go(addr);
@@ -1287,7 +841,7 @@ void debugger_commands::execute_go(const std::vector<std::string> &params)
command
-------------------------------------------------*/
-void debugger_commands::execute_go_vblank(const std::vector<std::string> &params)
+void debugger_commands::execute_go_vblank(const std::vector<std::string_view> &params)
{
m_console.get_visible_cpu()->debug()->go_vblank();
}
@@ -1297,12 +851,12 @@ void debugger_commands::execute_go_vblank(const std::vector<std::string> &params
execute_go_interrupt - execute the goint command
-------------------------------------------------*/
-void debugger_commands::execute_go_interrupt(const std::vector<std::string> &params)
+void debugger_commands::execute_go_interrupt(const std::vector<std::string_view> &params)
{
u64 irqline = -1;
/* if we have a parameter, use it instead */
- if (params.size() > 0 && !validate_number_parameter(params[0], irqline))
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], irqline))
return;
m_console.get_visible_cpu()->debug()->go_interrupt(irqline);
@@ -1312,16 +866,16 @@ void debugger_commands::execute_go_interrupt(const std::vector<std::string> &par
execute_go_exception - execute the goex command
-------------------------------------------------*/
-void debugger_commands::execute_go_exception(const std::vector<std::string> &params)
+void debugger_commands::execute_go_exception(const std::vector<std::string_view> &params)
{
u64 exception = -1;
/* if we have a parameter, use it instead */
- if (params.size() > 0 && !validate_number_parameter(params[0], exception))
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], exception))
return;
parsed_expression condition(m_console.visible_symtable());
- if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition))
+ if (params.size() > 1 && !m_console.validate_expression_parameter(params[1], condition))
return;
m_console.get_visible_cpu()->debug()->go_exception(exception, condition.is_empty() ? "1" : condition.original_string());
@@ -1332,12 +886,12 @@ void debugger_commands::execute_go_exception(const std::vector<std::string> &par
execute_go_time - execute the gtime command
-------------------------------------------------*/
-void debugger_commands::execute_go_time(const std::vector<std::string> &params)
+void debugger_commands::execute_go_time(const std::vector<std::string_view> &params)
{
u64 milliseconds = -1;
/* if we have a parameter, use it instead */
- if (params.size() > 0 && !validate_number_parameter(params[0], milliseconds))
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], milliseconds))
return;
m_console.get_visible_cpu()->debug()->go_milliseconds(milliseconds);
@@ -1348,20 +902,76 @@ void debugger_commands::execute_go_time(const std::vector<std::string> &params)
/*-------------------------------------------------
execute_go_privilege - execute the gp command
-------------------------------------------------*/
-void debugger_commands::execute_go_privilege(const std::vector<std::string> &params)
+void debugger_commands::execute_go_privilege(const std::vector<std::string_view> &params)
{
parsed_expression condition(m_console.visible_symtable());
- if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition))
+ if (params.size() > 0 && !m_console.validate_expression_parameter(params[0], condition))
return;
m_console.get_visible_cpu()->debug()->go_privilege((condition.is_empty()) ? "1" : condition.original_string());
}
+
+/*-------------------------------------------------
+ execute_go_branch - execute gbt or gbf command
+-------------------------------------------------*/
+
+void debugger_commands::execute_go_branch(bool sense, const std::vector<std::string_view> &params)
+{
+ parsed_expression condition(m_console.visible_symtable());
+ if (params.size() > 0 && !m_console.validate_expression_parameter(params[0], condition))
+ return;
+
+ m_console.get_visible_cpu()->debug()->go_branch(sense, (condition.is_empty()) ? "1" : condition.original_string());
+}
+
+
+/*-------------------------------------------------
+ execute_go_next_instruction - execute gni command
+-------------------------------------------------*/
+
+void debugger_commands::execute_go_next_instruction(const std::vector<std::string_view> &params)
+{
+ u64 count = 1;
+ static constexpr u64 MAX_COUNT = 512;
+
+ // if we have a parameter, use it instead */
+ if (params.size() > 0 && !m_console.validate_number_parameter(params[0], count))
+ return;
+ if (count == 0)
+ return;
+ if (count > MAX_COUNT)
+ {
+ m_console.printf("Too many instructions (must be %d or fewer)\n", MAX_COUNT);
+ return;
+ }
+
+ device_state_interface *stateintf;
+ device_t *cpu = m_console.get_visible_cpu();
+ if (!cpu->interface(stateintf))
+ {
+ m_console.printf("No state interface available for %s\n", cpu->name());
+ return;
+ }
+ u32 pc = stateintf->pcbase();
+
+ debug_disasm_buffer buffer(*cpu);
+ while (count-- != 0)
+ {
+ // disassemble the current instruction and get the length
+ u32 result = buffer.disassemble_info(pc);
+ pc = buffer.next_pc_wrap(pc, result & util::disasm_interface::LENGTHMASK);
+ }
+
+ cpu->debug()->go(pc);
+}
+
+
/*-------------------------------------------------
execute_next - execute the next command
-------------------------------------------------*/
-void debugger_commands::execute_next(const std::vector<std::string> &params)
+void debugger_commands::execute_next(const std::vector<std::string_view> &params)
{
m_console.get_visible_cpu()->debug()->go_next_device();
}
@@ -1371,11 +981,11 @@ void debugger_commands::execute_next(const std::vector<std::string> &params)
execute_focus - execute the focus command
-------------------------------------------------*/
-void debugger_commands::execute_focus(const std::vector<std::string> &params)
+void debugger_commands::execute_focus(const std::vector<std::string_view> &params)
{
// validate params
device_t *cpu;
- if (!validate_cpu_parameter(params[0], cpu))
+ if (!m_console.validate_cpu_parameter(params[0], cpu))
return;
// first clear the ignore flag on the focused CPU
@@ -1393,7 +1003,7 @@ void debugger_commands::execute_focus(const std::vector<std::string> &params)
execute_ignore - execute the ignore command
-------------------------------------------------*/
-void debugger_commands::execute_ignore(const std::vector<std::string> &params)
+void debugger_commands::execute_ignore(const std::vector<std::string_view> &params)
{
if (params.empty())
{
@@ -1425,7 +1035,7 @@ void debugger_commands::execute_ignore(const std::vector<std::string> &params)
// validate parameters
for (int paramnum = 0; paramnum < params.size(); paramnum++)
- if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
+ if (!m_console.validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
return;
// set the ignore flags
@@ -1456,7 +1066,7 @@ void debugger_commands::execute_ignore(const std::vector<std::string> &params)
execute_observe - execute the observe command
-------------------------------------------------*/
-void debugger_commands::execute_observe(const std::vector<std::string> &params)
+void debugger_commands::execute_observe(const std::vector<std::string_view> &params)
{
if (params.empty())
{
@@ -1488,7 +1098,7 @@ void debugger_commands::execute_observe(const std::vector<std::string> &params)
// validate parameters
for (int paramnum = 0; paramnum < params.size(); paramnum++)
- if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
+ if (!m_console.validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
return;
// clear the ignore flags
@@ -1504,7 +1114,7 @@ void debugger_commands::execute_observe(const std::vector<std::string> &params)
execute_suspend - suspend execution on cpu
-------------------------------------------------*/
-void debugger_commands::execute_suspend(const std::vector<std::string> &params)
+void debugger_commands::execute_suspend(const std::vector<std::string_view> &params)
{
// if there are no parameters, dump the ignore list
if (params.empty())
@@ -1534,7 +1144,7 @@ void debugger_commands::execute_suspend(const std::vector<std::string> &params)
// validate parameters
for (int paramnum = 0; paramnum < params.size(); paramnum++)
- if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
+ if (!m_console.validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
return;
for (int paramnum = 0; paramnum < params.size(); paramnum++)
@@ -1563,7 +1173,7 @@ void debugger_commands::execute_suspend(const std::vector<std::string> &params)
execute_resume - Resume execution on CPU
-------------------------------------------------*/
-void debugger_commands::execute_resume(const std::vector<std::string> &params)
+void debugger_commands::execute_resume(const std::vector<std::string_view> &params)
{
// if there are no parameters, dump the ignore list
if (params.empty())
@@ -1593,7 +1203,7 @@ void debugger_commands::execute_resume(const std::vector<std::string> &params)
// validate parameters
for (int paramnum = 0; paramnum < params.size(); paramnum++)
- if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
+ if (!m_console.validate_cpu_parameter(params[paramnum], devicelist[paramnum]))
return;
for (int paramnum = 0; paramnum < params.size(); paramnum++)
@@ -1608,7 +1218,7 @@ void debugger_commands::execute_resume(const std::vector<std::string> &params)
// execute_cpulist - list all CPUs
//-------------------------------------------------
-void debugger_commands::execute_cpulist(const std::vector<std::string> &params)
+void debugger_commands::execute_cpulist(const std::vector<std::string_view> &params)
{
int index = 0;
for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device()))
@@ -1619,20 +1229,29 @@ void debugger_commands::execute_cpulist(const std::vector<std::string> &params)
}
}
+//-------------------------------------------------
+// execute_time - execute the time command
+//-------------------------------------------------
+
+void debugger_commands::execute_time(const std::vector<std::string_view> &params)
+{
+ m_console.printf("%s\n", m_machine.time().as_string());
+}
+
/*-------------------------------------------------
execute_comment - add a comment to a line
-------------------------------------------------*/
-void debugger_commands::execute_comment_add(const std::vector<std::string> &params)
+void debugger_commands::execute_comment_add(const std::vector<std::string_view> &params)
{
// param 1 is the address for the comment
u64 address;
- if (!validate_number_parameter(params[0], address))
+ if (!m_console.validate_number_parameter(params[0], address))
return;
// CPU parameter is implicit
device_t *cpu;
- if (!validate_cpu_parameter(std::string_view(), cpu))
+ if (!m_console.validate_cpu_parameter(std::string_view(), cpu))
return;
// make sure param 2 exists
@@ -1643,7 +1262,8 @@ void debugger_commands::execute_comment_add(const std::vector<std::string> &para
}
// Now try adding the comment
- cpu->debug()->comment_add(address, params[1].c_str(), 0x00ff0000);
+ std::string const text(params[1]);
+ cpu->debug()->comment_add(address, text.c_str(), 0x00ff0000);
cpu->machine().debug_view().update_all(DVT_DISASSEMBLY);
}
@@ -1652,16 +1272,16 @@ void debugger_commands::execute_comment_add(const std::vector<std::string> &para
execute_comment_del - remove a comment from an addr
--------------------------------------------------------*/
-void debugger_commands::execute_comment_del(const std::vector<std::string> &params)
+void debugger_commands::execute_comment_del(const std::vector<std::string_view> &params)
{
// param 1 can either be a command or the address for the comment
u64 address;
- if (!validate_number_parameter(params[0], address))
+ if (!m_console.validate_number_parameter(params[0], address))
return;
// CPU parameter is implicit
device_t *cpu;
- if (!validate_cpu_parameter(std::string_view(), cpu))
+ if (!m_console.validate_cpu_parameter(std::string_view(), cpu))
return;
// If it's a number, it must be an address
@@ -1671,25 +1291,25 @@ void debugger_commands::execute_comment_del(const std::vector<std::string> &para
}
/**
- * @fn void execute_comment_list(const std::vector<std::string> &params)
+ * @fn void execute_comment_list(const std::vector<std::string_view> &params)
* @brief Print current list of comments in debugger
*
*
*/
-void debugger_commands::execute_comment_list(const std::vector<std::string> &params)
+void debugger_commands::execute_comment_list(const std::vector<std::string_view> &params)
{
if (!m_machine.debugger().cpu().comment_load(false))
m_console.printf("Error while parsing XML file\n");
}
/**
- * @fn void execute_comment_commit(const std::vector<std::string> &params)
+ * @fn void execute_comment_commit(const std::vector<std::string_view> &params)
* @brief Add and Save current list of comments in debugger
*
*/
-void debugger_commands::execute_comment_commit(const std::vector<std::string> &params)
+void debugger_commands::execute_comment_commit(const std::vector<std::string_view> &params)
{
execute_comment_add(params);
execute_comment_save(params);
@@ -1699,7 +1319,7 @@ void debugger_commands::execute_comment_commit(const std::vector<std::string> &p
execute_comment - add a comment to a line
-------------------------------------------------*/
-void debugger_commands::execute_comment_save(const std::vector<std::string> &params)
+void debugger_commands::execute_comment_save(const std::vector<std::string_view> &params)
{
if (m_machine.debugger().cpu().comment_save())
m_console.printf("Comment successfully saved\n");
@@ -1709,7 +1329,7 @@ void debugger_commands::execute_comment_save(const std::vector<std::string> &par
// TODO: add color hex editing capabilities for comments, see below for more info
/**
- * @fn void execute_comment_color(const std::vector<std::string> &params)
+ * @fn void execute_comment_color(const std::vector<std::string_view> &params)
* @brief Modifies comment given at address $xx with given color
* Useful for marking comment with a different color scheme (for example by marking start and end of a given function visually).
* @param[in] "address,color" First is the comment address in the current context, color can be hexadecimal or shorthanded to common 1bpp RGB names.
@@ -1726,12 +1346,12 @@ void debugger_commands::execute_comment_save(const std::vector<std::string> &par
command
-------------------------------------------------*/
-void debugger_commands::execute_bpset(const std::vector<std::string> &params)
+void debugger_commands::execute_bpset(const std::vector<std::string_view> &params)
{
// param 1 is the address/CPU
u64 address;
address_space *space;
- if (!validate_target_address_parameter(params[0], AS_PROGRAM, space, address))
+ if (!m_console.validate_target_address_parameter(params[0], AS_PROGRAM, space, address))
return;
device_execute_interface const *execute;
@@ -1750,12 +1370,12 @@ void debugger_commands::execute_bpset(const std::vector<std::string> &params)
// param 2 is the condition
parsed_expression condition(debug->symtable());
- if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition))
+ if (params.size() > 1 && !m_console.validate_expression_parameter(params[1], condition))
return;
// param 3 is the action
- const char *action = nullptr;
- if (params.size() > 2 && !debug_command_parameter_command(action = params[2].c_str()))
+ std::string_view action;
+ if (params.size() > 2 && !m_console.validate_command_parameter(action = params[2]))
return;
// set the breakpoint
@@ -1769,7 +1389,7 @@ void debugger_commands::execute_bpset(const std::vector<std::string> &params)
clear command
-------------------------------------------------*/
-void debugger_commands::execute_bpclear(const std::vector<std::string> &params)
+void debugger_commands::execute_bpclear(const std::vector<std::string_view> &params)
{
if (params.empty()) // if no parameters, clear all
{
@@ -1798,7 +1418,7 @@ void debugger_commands::execute_bpclear(const std::vector<std::string> &params)
disable/enable commands
-------------------------------------------------*/
-void debugger_commands::execute_bpdisenable(bool enable, const std::vector<std::string> &params)
+void debugger_commands::execute_bpdisenable(bool enable, const std::vector<std::string_view> &params)
{
if (params.empty()) // if no parameters, disable/enable all
{
@@ -1827,7 +1447,7 @@ void debugger_commands::execute_bpdisenable(bool enable, const std::vector<std::
command
-------------------------------------------------*/
-void debugger_commands::execute_bplist(const std::vector<std::string> &params)
+void debugger_commands::execute_bplist(const std::vector<std::string_view> &params)
{
int printed = 0;
std::string buffer;
@@ -1856,7 +1476,7 @@ void debugger_commands::execute_bplist(const std::vector<std::string> &params)
if (!params.empty())
{
device_t *cpu;
- if (!validate_cpu_parameter(params[0], cpu))
+ if (!m_console.validate_cpu_parameter(params[0], cpu))
return;
apply(*cpu);
if (!printed)
@@ -1878,13 +1498,13 @@ void debugger_commands::execute_bplist(const std::vector<std::string> &params)
command
-------------------------------------------------*/
-void debugger_commands::execute_wpset(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_wpset(int spacenum, const std::vector<std::string_view> &params)
{
u64 address, length;
address_space *space;
// param 1 is the address/CPU
- if (!validate_target_address_parameter(params[0], spacenum, space, address))
+ if (!m_console.validate_target_address_parameter(params[0], spacenum, space, address))
return;
device_execute_interface const *execute;
@@ -1896,31 +1516,35 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector<std::strin
device_debug *const debug = space->device().debug();
// param 2 is the length
- if (!validate_number_parameter(params[1], length))
+ if (!m_console.validate_number_parameter(params[1], length))
return;
// param 3 is the type
read_or_write type;
- if (!core_stricmp(params[2].c_str(), "r"))
- type = read_or_write::READ;
- else if (!core_stricmp(params[2].c_str(), "w"))
- type = read_or_write::WRITE;
- else if (!core_stricmp(params[2].c_str(), "rw") || !core_stricmp(params[2].c_str(), "wr"))
- type = read_or_write::READWRITE;
- else
{
- m_console.printf("Invalid watchpoint type: expected r, w, or rw\n");
- return;
+ using util::streqlower;
+ using namespace std::literals;
+ if (streqlower(params[2], "r"sv))
+ type = read_or_write::READ;
+ else if (streqlower(params[2], "w"sv))
+ type = read_or_write::WRITE;
+ else if (streqlower(params[2], "rw"sv) || streqlower(params[2], "wr"sv))
+ type = read_or_write::READWRITE;
+ else
+ {
+ m_console.printf("Invalid watchpoint type: expected r, w, or rw\n");
+ return;
+ }
}
// param 4 is the condition
parsed_expression condition(debug->symtable());
- if (params.size() > 3 && !debug_command_parameter_expression(params[3], condition))
+ if (params.size() > 3 && !m_console.validate_expression_parameter(params[3], condition))
return;
// param 5 is the action
- const char *action = nullptr;
- if (params.size() > 4 && !debug_command_parameter_command(action = params[4].c_str()))
+ std::string_view action;
+ if (params.size() > 4 && !m_console.validate_command_parameter(action = params[4]))
return;
// set the watchpoint
@@ -1934,7 +1558,7 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector<std::strin
clear command
-------------------------------------------------*/
-void debugger_commands::execute_wpclear(const std::vector<std::string> &params)
+void debugger_commands::execute_wpclear(const std::vector<std::string_view> &params)
{
if (params.empty()) // if no parameters, clear all
{
@@ -1963,7 +1587,7 @@ void debugger_commands::execute_wpclear(const std::vector<std::string> &params)
disable/enable commands
-------------------------------------------------*/
-void debugger_commands::execute_wpdisenable(bool enable, const std::vector<std::string> &params)
+void debugger_commands::execute_wpdisenable(bool enable, const std::vector<std::string_view> &params)
{
if (params.empty()) // if no parameters, disable/enable all
{
@@ -1992,7 +1616,7 @@ void debugger_commands::execute_wpdisenable(bool enable, const std::vector<std::
command
-------------------------------------------------*/
-void debugger_commands::execute_wplist(const std::vector<std::string> &params)
+void debugger_commands::execute_wplist(const std::vector<std::string_view> &params)
{
int printed = 0;
std::string buffer;
@@ -2033,7 +1657,7 @@ void debugger_commands::execute_wplist(const std::vector<std::string> &params)
if (!params.empty())
{
device_t *cpu;
- if (!validate_cpu_parameter(params[0], cpu))
+ if (!m_console.validate_cpu_parameter(params[0], cpu))
return;
apply(*cpu);
if (!printed)
@@ -2055,21 +1679,21 @@ void debugger_commands::execute_wplist(const std::vector<std::string> &params)
command
-------------------------------------------------*/
-void debugger_commands::execute_rpset(const std::vector<std::string> &params)
+void debugger_commands::execute_rpset(const std::vector<std::string_view> &params)
{
// CPU is implicit
device_t *cpu;
- if (!validate_cpu_parameter(std::string_view(), cpu))
+ if (!m_console.validate_cpu_parameter(std::string_view(), cpu))
return;
// param 1 is the condition
parsed_expression condition(cpu->debug()->symtable());
- if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition))
+ if (params.size() > 0 && !m_console.validate_expression_parameter(params[0], condition))
return;
// param 2 is the action
- const char *action = nullptr;
- if (params.size() > 1 && !debug_command_parameter_command(action = params[1].c_str()))
+ std::string_view action;
+ if (params.size() > 1 && !m_console.validate_command_parameter(action = params[1]))
return;
// set the registerpoint
@@ -2083,7 +1707,7 @@ void debugger_commands::execute_rpset(const std::vector<std::string> &params)
clear command
-------------------------------------------------*/
-void debugger_commands::execute_rpclear(const std::vector<std::string> &params)
+void debugger_commands::execute_rpclear(const std::vector<std::string_view> &params)
{
if (params.empty()) // if no parameters, clear all
{
@@ -2112,7 +1736,7 @@ void debugger_commands::execute_rpclear(const std::vector<std::string> &params)
disable/enable commands
-------------------------------------------------*/
-void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::string> &params)
+void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::string_view> &params)
{
if (params.empty()) // if no parameters, disable/enable all
{
@@ -2136,12 +1760,154 @@ void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::
}
+//-------------------------------------------------
+// execute_epset - execute the exception point
+// set command
+//-------------------------------------------------
+
+void debugger_commands::execute_epset(const std::vector<std::string_view> &params)
+{
+ // CPU is implicit
+ device_t *cpu;
+ if (!m_console.validate_cpu_parameter(std::string_view(), cpu))
+ return;
+
+ // param 1 is the exception type
+ u64 type;
+ if (!m_console.validate_number_parameter(params[0], type))
+ return;
+
+ // param 2 is the condition
+ parsed_expression condition(cpu->debug()->symtable());
+ if (params.size() > 1 && !m_console.validate_expression_parameter(params[1], condition))
+ return;
+
+ // param 3 is the action
+ std::string_view action;
+ if (params.size() > 2 && !m_console.validate_command_parameter(action = params[2]))
+ return;
+
+ // set the exception point
+ int epnum = cpu->debug()->exceptionpoint_set(type, (condition.is_empty()) ? nullptr : condition.original_string(), action);
+ m_console.printf("Exception point %X set\n", epnum);
+}
+
+
+//-------------------------------------------------
+// execute_epclear - execute the exception point
+// clear command
+//-------------------------------------------------
+
+void debugger_commands::execute_epclear(const std::vector<std::string_view> &params)
+{
+ if (params.empty()) // if no parameters, clear all
+ {
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ device.debug()->exceptionpoint_clear_all();
+ m_console.printf("Cleared all exception points\n");
+ }
+ else // otherwise, clear the specific ones
+ {
+ execute_index_command(
+ params,
+ [this] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->exceptionpoint_clear(param))
+ return false;
+ m_console.printf("Exception point %X cleared\n", param);
+ return true;
+ },
+ "Invalid exception point number %X\n");
+ }
+}
+
+
+//-------------------------------------------------
+// execute_epdisenable - execute the exception
+// point disable/enable commands
+//-------------------------------------------------
+
+void debugger_commands::execute_epdisenable(bool enable, const std::vector<std::string_view> &params)
+{
+ if (params.empty()) // if no parameters, disable/enable all
+ {
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ device.debug()->exceptionpoint_enable_all(enable);
+ m_console.printf(enable ? "Enabled all exception points\n" : "Disabled all exception points\n");
+ }
+ else // otherwise, disable/enable the specific ones
+ {
+ execute_index_command(
+ params,
+ [this, enable] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->exceptionpoint_enable(param, enable))
+ return false;
+ m_console.printf(enable ? "Exception point %X enabled\n" : "Exception point %X disabled\n", param);
+ return true;
+ },
+ "Invalid exception point number %X\n");
+ }
+}
+
+
+//-------------------------------------------------
+// execute_eplist - execute the exception point
+// list command
+//-------------------------------------------------
+
+void debugger_commands::execute_eplist(const std::vector<std::string_view> &params)
+{
+ int printed = 0;
+ std::string buffer;
+ auto const apply =
+ [this, &printed, &buffer] (device_t &device)
+ {
+ if (!device.debug()->exceptionpoint_list().empty())
+ {
+ m_console.printf("Device '%s' exception points:\n", device.tag());
+
+ // loop over the exception points
+ for (const auto &epp : device.debug()->exceptionpoint_list())
+ {
+ debug_exceptionpoint &ep = *epp.second;
+ buffer = string_format("%c%4X : %X", ep.enabled() ? ' ' : 'D', ep.index(), ep.type());
+ if (std::string(ep.condition()).compare("1") != 0)
+ buffer.append(string_format(" if %s", ep.condition()));
+ if (!ep.action().empty())
+ buffer.append(string_format(" do %s", ep.action()));
+ m_console.printf("%s\n", buffer);
+ printed++;
+ }
+ }
+ };
+
+ if (!params.empty())
+ {
+ device_t *cpu;
+ if (!m_console.validate_cpu_parameter(params[0], cpu))
+ return;
+ apply(*cpu);
+ if (!printed)
+ m_console.printf("No exception points currently installed for CPU %s\n", cpu->tag());
+ }
+ else
+ {
+ // loop over all CPUs
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ apply(device);
+ if (!printed)
+ m_console.printf("No exception points currently installed\n");
+ }
+}
+
+
/*-------------------------------------------------
execute_rplist - execute the registerpoint list
command
-------------------------------------------------*/
-void debugger_commands::execute_rplist(const std::vector<std::string> &params)
+void debugger_commands::execute_rplist(const std::vector<std::string_view> &params)
{
int printed = 0;
std::string buffer;
@@ -2156,7 +1922,7 @@ void debugger_commands::execute_rplist(const std::vector<std::string> &params)
for (const auto &rp : device.debug()->registerpoint_list())
{
buffer = string_format("%c%4X if %s", rp.enabled() ? ' ' : 'D', rp.index(), rp.condition());
- if (rp.action() && *rp.action())
+ if (!rp.action().empty())
buffer.append(string_format(" do %s", rp.action()));
m_console.printf("%s\n", buffer);
printed++;
@@ -2167,7 +1933,7 @@ void debugger_commands::execute_rplist(const std::vector<std::string> &params)
if (!params.empty())
{
device_t *cpu;
- if (!validate_cpu_parameter(params[0], cpu))
+ if (!m_console.validate_cpu_parameter(params[0], cpu))
return;
apply(*cpu);
if (!printed)
@@ -2188,10 +1954,9 @@ void debugger_commands::execute_rplist(const std::vector<std::string> &params)
execute_statesave - execute the statesave command
-------------------------------------------------*/
-void debugger_commands::execute_statesave(const std::vector<std::string> &params)
+void debugger_commands::execute_statesave(const std::vector<std::string_view> &params)
{
- const std::string &filename(params[0]);
- m_machine.immediate_save(filename.c_str());
+ m_machine.immediate_save(params[0]);
m_console.printf("State save attempted. Please refer to window message popup for results.\n");
}
@@ -2200,10 +1965,9 @@ void debugger_commands::execute_statesave(const std::vector<std::string> &params
execute_stateload - execute the stateload command
-------------------------------------------------*/
-void debugger_commands::execute_stateload(const std::vector<std::string> &params)
+void debugger_commands::execute_stateload(const std::vector<std::string_view> &params)
{
- const std::string &filename(params[0]);
- m_machine.immediate_load(filename.c_str());
+ m_machine.immediate_load(params[0]);
// clear all PC & memory tracks
for (device_t &device : device_enumerator(m_machine.root_device()))
@@ -2219,7 +1983,7 @@ void debugger_commands::execute_stateload(const std::vector<std::string> &params
execute_rewind - execute the rewind command
-------------------------------------------------*/
-void debugger_commands::execute_rewind(const std::vector<std::string> &params)
+void debugger_commands::execute_rewind(const std::vector<std::string_view> &params)
{
bool success = m_machine.rewind_step();
if (success)
@@ -2238,15 +2002,15 @@ void debugger_commands::execute_rewind(const std::vector<std::string> &params)
execute_save - execute the save command
-------------------------------------------------*/
-void debugger_commands::execute_save(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_save(int spacenum, const std::vector<std::string_view> &params)
{
u64 offset, endoffset, length;
address_space *space;
// validate parameters
- if (!validate_target_address_parameter(params[1], spacenum, space, offset))
+ if (!m_console.validate_target_address_parameter(params[1], spacenum, space, offset))
return;
- if (!validate_number_parameter(params[2], length))
+ if (!m_console.validate_number_parameter(params[2], length))
return;
// determine the addresses to write
@@ -2255,7 +2019,8 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
endoffset++;
// open the file
- FILE *const f = fopen(params[0].c_str(), "wb");
+ std::string const filename(params[0]);
+ FILE *const f = fopen(filename.c_str(), "wb");
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -2270,8 +2035,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++)
{
offs_t curaddr = i;
- u64 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ?
- space->read_qword(curaddr) : space->unmap();
+ address_space *tspace;
+ u64 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
+ tspace->read_qword(curaddr) : space->unmap();
fwrite(&data, 8, 1, f);
}
break;
@@ -2279,8 +2045,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++)
{
offs_t curaddr = i;
- u32 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ?
- space->read_dword(curaddr) : space->unmap();
+ address_space *tspace;
+ u32 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
+ tspace->read_dword(curaddr) : space->unmap();
fwrite(&data, 4, 1, f);
}
break;
@@ -2288,8 +2055,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++)
{
offs_t curaddr = i;
- u16 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ?
- space->read_word(curaddr) : space->unmap();
+ address_space *tspace;
+ u16 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
+ tspace->read_word(curaddr) : space->unmap();
fwrite(&data, 2, 1, f);
}
break;
@@ -2297,8 +2065,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i++)
{
offs_t curaddr = i;
- u8 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ?
- space->read_byte(curaddr) : space->unmap();
+ address_space *tspace;
+ u8 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
+ tspace->read_byte(curaddr) : space->unmap();
fwrite(&data, 1, 1, f);
}
break;
@@ -2308,8 +2077,9 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
for (u64 i = offset; i != endoffset; i+=16)
{
offs_t curaddr = i;
- u16 data = space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr) ?
- space->read_word(curaddr) : space->unmap();
+ address_space *tspace;
+ u16 data = space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace) ?
+ tspace->read_word(curaddr) : space->unmap();
fwrite(&data, 2, 1, f);
}
break;
@@ -2325,17 +2095,17 @@ void debugger_commands::execute_save(int spacenum, const std::vector<std::string
execute_saveregion - execute the save command on region memory
-------------------------------------------------*/
-void debugger_commands::execute_saveregion(const std::vector<std::string> &params)
+void debugger_commands::execute_saveregion(const std::vector<std::string_view> &params)
{
u64 offset, length;
memory_region *region;
// validate parameters
- if (!validate_number_parameter(params[1], offset))
+ if (!m_console.validate_number_parameter(params[1], offset))
return;
- if (!validate_number_parameter(params[2], length))
+ if (!m_console.validate_number_parameter(params[2], length))
return;
- if (!validate_memory_region_parameter(params[3], region))
+ if (!m_console.validate_memory_region_parameter(params[3], region))
return;
if (offset >= region->bytes())
@@ -2347,7 +2117,8 @@ void debugger_commands::execute_saveregion(const std::vector<std::string> &param
length = region->bytes() - offset;
/* open the file */
- FILE *f = fopen(params[0].c_str(), "wb");
+ std::string const filename(params[0]);
+ FILE *f = fopen(filename.c_str(), "wb");
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -2364,20 +2135,21 @@ void debugger_commands::execute_saveregion(const std::vector<std::string> &param
execute_load - execute the load command
-------------------------------------------------*/
-void debugger_commands::execute_load(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_load(int spacenum, const std::vector<std::string_view> &params)
{
u64 offset, endoffset, length = 0;
address_space *space;
// validate parameters
- if (!validate_target_address_parameter(params[1], spacenum, space, offset))
+ if (!m_console.validate_target_address_parameter(params[1], spacenum, space, offset))
return;
- if (params.size() > 2 && !validate_number_parameter(params[2], length))
+ if (params.size() > 2 && !m_console.validate_number_parameter(params[2], length))
return;
// open the file
std::ifstream f;
- f.open(params[0], std::ifstream::in | std::ifstream::binary);
+ std::string const fname(params[0]);
+ f.open(fname, std::ifstream::in | std::ifstream::binary);
if (f.fail())
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -2411,8 +2183,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i;
u64 data;
f.read((char *)&data, 8);
- if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr))
- space->write_qword(curaddr, data);
+ address_space *tspace;
+ if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
+ tspace->write_qword(curaddr, data);
}
break;
case -2:
@@ -2421,8 +2194,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i;
u32 data;
f.read((char *)&data, 4);
- if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr))
- space->write_dword(curaddr, data);
+ address_space *tspace;
+ if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
+ tspace->write_dword(curaddr, data);
}
break;
case -1:
@@ -2431,8 +2205,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i;
u16 data;
f.read((char *)&data, 2);
- if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr))
- space->write_word(curaddr, data);
+ address_space *tspace;
+ if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
+ tspace->write_word(curaddr, data);
}
break;
case 0:
@@ -2441,8 +2216,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i;
u8 data;
f.read((char *)&data, 1);
- if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr))
- space->write_byte(curaddr, data);
+ address_space *tspace;
+ if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
+ tspace->write_byte(curaddr, data);
}
break;
case 3:
@@ -2453,8 +2229,9 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
offs_t curaddr = i;
u16 data;
f.read((char *)&data, 2);
- if (f && space->device().memory().translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, curaddr))
- space->write_word(curaddr, data);
+ address_space *tspace;
+ if (f && space->device().memory().translate(space->spacenum(), device_memory_interface::TR_WRITE, curaddr, tspace))
+ tspace->write_word(curaddr, data);
}
break;
}
@@ -2472,17 +2249,17 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
execute_loadregion - execute the load command on region memory
-------------------------------------------------*/
-void debugger_commands::execute_loadregion(const std::vector<std::string> &params)
+void debugger_commands::execute_loadregion(const std::vector<std::string_view> &params)
{
u64 offset, length;
memory_region *region;
// validate parameters
- if (!validate_number_parameter(params[1], offset))
+ if (!m_console.validate_number_parameter(params[1], offset))
return;
- if (!validate_number_parameter(params[2], length))
+ if (!m_console.validate_number_parameter(params[2], length))
return;
- if (!validate_memory_region_parameter(params[3], region))
+ if (!m_console.validate_memory_region_parameter(params[3], region))
return;
if (offset >= region->bytes())
@@ -2494,7 +2271,8 @@ void debugger_commands::execute_loadregion(const std::vector<std::string> &param
length = region->bytes() - offset;
// open the file
- FILE *const f = fopen(params[0].c_str(), "rb");
+ std::string filename(params[0]);
+ FILE *const f = fopen(filename.c_str(), "rb");
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -2520,28 +2298,28 @@ void debugger_commands::execute_loadregion(const std::vector<std::string> &param
execute_dump - execute the dump command
-------------------------------------------------*/
-void debugger_commands::execute_dump(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_dump(int spacenum, const std::vector<std::string_view> &params)
{
// validate parameters
address_space *space;
u64 offset;
- if (!validate_target_address_parameter(params[1], spacenum, space, offset))
+ if (!m_console.validate_target_address_parameter(params[1], spacenum, space, offset))
return;
u64 length;
- if (!validate_number_parameter(params[2], length))
+ if (!m_console.validate_number_parameter(params[2], length))
return;
u64 width = 0;
- if (params.size() > 3 && !validate_number_parameter(params[3], width))
+ if (params.size() > 3 && !m_console.validate_number_parameter(params[3], width))
return;
bool ascii = true;
- if (params.size() > 4 && !validate_boolean_parameter(params[4], ascii))
+ if (params.size() > 4 && !m_console.validate_boolean_parameter(params[4], ascii))
return;
u64 rowsize = space->byte_to_address(16);
- if (params.size() > 5 && !validate_number_parameter(params[5], rowsize))
+ if (params.size() > 5 && !m_console.validate_number_parameter(params[5], rowsize))
return;
int shift = space->addr_shift();
@@ -2572,7 +2350,8 @@ void debugger_commands::execute_dump(int spacenum, const std::vector<std::string
offset = offset & space->addrmask();
// open the file
- FILE *const f = fopen(params[0].c_str(), "w");
+ std::string filename(params[0]);
+ FILE *const f = fopen(filename.c_str(), "w");
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -2602,21 +2381,22 @@ void debugger_commands::execute_dump(int spacenum, const std::vector<std::string
if (i + j <= endoffset)
{
offs_t curaddr = i + j;
- if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr))
+ address_space *tspace;
+ if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace))
{
switch (width)
{
case 8:
- util::stream_format(output, " %016X", space->read_qword_unaligned(i+j));
+ util::stream_format(output, " %016X", tspace->read_qword_unaligned(i+j));
break;
case 4:
- util::stream_format(output, " %08X", space->read_dword_unaligned(i+j));
+ util::stream_format(output, " %08X", tspace->read_dword_unaligned(i+j));
break;
case 2:
- util::stream_format(output, " %04X", space->read_word_unaligned(i+j));
+ util::stream_format(output, " %04X", tspace->read_word_unaligned(i+j));
break;
case 1:
- util::stream_format(output, " %02X", space->read_byte(i+j));
+ util::stream_format(output, " %02X", tspace->read_byte(i+j));
break;
}
}
@@ -2636,22 +2416,23 @@ void debugger_commands::execute_dump(int spacenum, const std::vector<std::string
for (u64 j = 0; j < rowsize && (i + j) <= endoffset; j += delta)
{
offs_t curaddr = i + j;
- if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr))
+ address_space *tspace;
+ if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace))
{
u64 data = 0;
switch (width)
{
case 8:
- data = space->read_qword_unaligned(i+j);
+ data = tspace->read_qword_unaligned(i+j);
break;
case 4:
- data = space->read_dword_unaligned(i+j);
+ data = tspace->read_dword_unaligned(i+j);
break;
case 2:
- data = space->read_word_unaligned(i+j);
+ data = tspace->read_word_unaligned(i+j);
break;
case 1:
- data = space->read_byte(i+j);
+ data = tspace->read_byte(i+j);
break;
}
for (unsigned int b = 0; b != width; b++) {
@@ -2681,23 +2462,23 @@ void debugger_commands::execute_dump(int spacenum, const std::vector<std::string
// execute_strdump - execute the strdump command
//-------------------------------------------------
-void debugger_commands::execute_strdump(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_strdump(int spacenum, const std::vector<std::string_view> &params)
{
// validate parameters
u64 offset;
- if (!validate_number_parameter(params[1], offset))
+ if (!m_console.validate_number_parameter(params[1], offset))
return;
u64 length;
- if (!validate_number_parameter(params[2], length))
+ if (!m_console.validate_number_parameter(params[2], length))
return;
u64 term = 0;
- if (params.size() > 3 && !validate_number_parameter(params[3], term))
+ if (params.size() > 3 && !m_console.validate_number_parameter(params[3], term))
return;
address_space *space;
- if (!validate_device_space_parameter((params.size() > 4) ? params[4] : std::string_view(), spacenum, space))
+ if (!m_console.validate_device_space_parameter((params.size() > 4) ? params[4] : std::string_view(), spacenum, space))
return;
// further validation
@@ -2708,7 +2489,8 @@ void debugger_commands::execute_strdump(int spacenum, const std::vector<std::str
}
// open the file
- FILE *f = fopen(params[0].c_str(), "w");
+ std::string filename(params[0]);
+ FILE *f = fopen(filename.c_str(), "w");
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -2746,28 +2528,29 @@ void debugger_commands::execute_strdump(int spacenum, const std::vector<std::str
// get the character data
u64 data = 0;
offs_t curaddr = offset;
- if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr))
+ address_space *tspace;
+ if (space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, curaddr, tspace))
{
switch (width)
{
case 1:
- data = space->read_byte(curaddr);
+ data = tspace->read_byte(curaddr);
break;
case 2:
- data = space->read_word(curaddr);
+ data = tspace->read_word(curaddr);
if (be)
data = swapendian_int16(data);
break;
case 4:
- data = space->read_dword(curaddr);
+ data = tspace->read_dword(curaddr);
if (be)
data = swapendian_int32(data);
break;
case 8:
- data = space->read_qword(curaddr);
+ data = tspace->read_qword(curaddr);
if (be)
data = swapendian_int64(data);
break;
@@ -2857,7 +2640,7 @@ void debugger_commands::execute_strdump(int spacenum, const std::vector<std::str
cheats
-------------------------------------------------*/
-void debugger_commands::execute_cheatrange(bool init, const std::vector<std::string> &params)
+void debugger_commands::execute_cheatrange(bool init, const std::vector<std::string_view> &params)
{
address_space *space = m_cheat.space;
if (!space && !init)
@@ -2874,7 +2657,7 @@ void debugger_commands::execute_cheatrange(bool init, const std::vector<std::str
// first argument is sign/size/swap flags
if (!params.empty())
{
- std::string const &srtpnt = params[0];
+ std::string_view const &srtpnt = params[0];
if (!srtpnt.empty())
{
width = 1;
@@ -2927,7 +2710,7 @@ void debugger_commands::execute_cheatrange(bool init, const std::vector<std::str
}
// fourth argument is device/space
- if (!validate_device_space_parameter((params.size() > 3) ? params[3] : std::string_view(), -1, space))
+ if (!m_console.validate_device_space_parameter((params.size() > 3) ? params[3] : std::string_view(), -1, space))
return;
}
@@ -2937,9 +2720,9 @@ void debugger_commands::execute_cheatrange(bool init, const std::vector<std::str
{
// validate parameters
u64 offset, length;
- if (!validate_number_parameter(params[init ? 1 : 0], offset))
+ if (!m_console.validate_number_parameter(params[init ? 1 : 0], offset))
return;
- if (!validate_number_parameter(params[init ? 2 : 1], length))
+ if (!m_console.validate_number_parameter(params[init ? 2 : 1], length))
return;
// force region to the specified range
@@ -3026,7 +2809,7 @@ void debugger_commands::execute_cheatrange(bool init, const std::vector<std::str
execute_cheatnext - execute the search
-------------------------------------------------*/
-void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::string> &params)
+void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::string_view> &params)
{
enum
{
@@ -3054,36 +2837,40 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::s
}
u64 comp_value = 0;
- if (params.size() > 1 && !validate_number_parameter(params[1], comp_value))
+ if (params.size() > 1 && !m_console.validate_number_parameter(params[1], comp_value))
return;
comp_value = m_cheat.sign_extend(comp_value);
// decode condition
u8 condition;
- if (!core_stricmp(params[0].c_str(), "all"))
- condition = CHEAT_ALL;
- else if (!core_stricmp(params[0].c_str(), "equal") || !core_stricmp(params[0].c_str(), "eq"))
- condition = (params.size() > 1) ? CHEAT_EQUALTO : CHEAT_EQUAL;
- else if (!core_stricmp(params[0].c_str(), "notequal") || !core_stricmp(params[0].c_str(), "ne"))
- condition = (params.size() > 1) ? CHEAT_NOTEQUALTO : CHEAT_NOTEQUAL;
- else if (!core_stricmp(params[0].c_str(), "decrease") || !core_stricmp(params[0].c_str(), "de") || params[0] == "-")
- condition = (params.size() > 1) ? CHEAT_DECREASEOF : CHEAT_DECREASE;
- else if (!core_stricmp(params[0].c_str(), "increase") || !core_stricmp(params[0].c_str(), "in") || params[0] == "+")
- condition = (params.size() > 1) ? CHEAT_INCREASEOF : CHEAT_INCREASE;
- else if (!core_stricmp(params[0].c_str(), "decreaseorequal") || !core_stricmp(params[0].c_str(), "deeq"))
- condition = CHEAT_DECREASE_OR_EQUAL;
- else if (!core_stricmp(params[0].c_str(), "increaseorequal") || !core_stricmp(params[0].c_str(), "ineq"))
- condition = CHEAT_INCREASE_OR_EQUAL;
- else if (!core_stricmp(params[0].c_str(), "smallerof") || !core_stricmp(params[0].c_str(), "lt") || params[0] == "<")
- condition = CHEAT_SMALLEROF;
- else if (!core_stricmp(params[0].c_str(), "greaterof") || !core_stricmp(params[0].c_str(), "gt") || params[0] == ">")
- condition = CHEAT_GREATEROF;
- else if (!core_stricmp(params[0].c_str(), "changedby") || !core_stricmp(params[0].c_str(), "ch") || params[0] == "~")
- condition = CHEAT_CHANGEDBY;
- else
{
- m_console.printf("Invalid condition type\n");
- return;
+ using util::streqlower;
+ using namespace std::literals;
+ if (streqlower(params[0], "all"sv))
+ condition = CHEAT_ALL;
+ else if (streqlower(params[0], "equal"sv) || streqlower(params[0], "eq"sv))
+ condition = (params.size() > 1) ? CHEAT_EQUALTO : CHEAT_EQUAL;
+ else if (streqlower(params[0], "notequal"sv) || streqlower(params[0], "ne"sv))
+ condition = (params.size() > 1) ? CHEAT_NOTEQUALTO : CHEAT_NOTEQUAL;
+ else if (streqlower(params[0], "decrease"sv) || streqlower(params[0], "de"sv) || params[0] == "-"sv)
+ condition = (params.size() > 1) ? CHEAT_DECREASEOF : CHEAT_DECREASE;
+ else if (streqlower(params[0], "increase"sv) || streqlower(params[0], "in"sv) || params[0] == "+"sv)
+ condition = (params.size() > 1) ? CHEAT_INCREASEOF : CHEAT_INCREASE;
+ else if (streqlower(params[0], "decreaseorequal"sv) || streqlower(params[0], "deeq"sv))
+ condition = CHEAT_DECREASE_OR_EQUAL;
+ else if (streqlower(params[0], "increaseorequal"sv) || streqlower(params[0], "ineq"sv))
+ condition = CHEAT_INCREASE_OR_EQUAL;
+ else if (streqlower(params[0], "smallerof"sv) || streqlower(params[0], "lt"sv) || params[0] == "<"sv)
+ condition = CHEAT_SMALLEROF;
+ else if (streqlower(params[0], "greaterof"sv) || streqlower(params[0], "gt"sv) || params[0] == ">"sv)
+ condition = CHEAT_GREATEROF;
+ else if (streqlower(params[0], "changedby"sv) || streqlower(params[0], "ch"sv) || params[0] == "~"sv)
+ condition = CHEAT_CHANGEDBY;
+ else
+ {
+ m_console.printf("Invalid condition type\n");
+ return;
+ }
}
m_cheat.undo++;
@@ -3190,7 +2977,7 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::s
}
if (active_cheat <= 5)
- execute_cheatlist(std::vector<std::string>());
+ execute_cheatlist(std::vector<std::string_view>());
m_console.printf("%u cheats found\n", active_cheat);
}
@@ -3200,7 +2987,7 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::s
execute_cheatlist - show a list of active cheat
-------------------------------------------------*/
-void debugger_commands::execute_cheatlist(const std::vector<std::string> &params)
+void debugger_commands::execute_cheatlist(const std::vector<std::string_view> &params)
{
address_space *const space = m_cheat.space;
if (!space)
@@ -3212,7 +2999,8 @@ void debugger_commands::execute_cheatlist(const std::vector<std::string> &params
FILE *f = nullptr;
if (params.size() > 0)
{
- f = fopen(params[0].c_str(), "w");
+ std::string filename(params[0]);
+ f = fopen(filename.c_str(), "w");
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -3317,7 +3105,7 @@ void debugger_commands::execute_cheatlist(const std::vector<std::string> &params
execute_cheatundo - undo the last search
-------------------------------------------------*/
-void debugger_commands::execute_cheatundo(const std::vector<std::string> &params)
+void debugger_commands::execute_cheatundo(const std::vector<std::string_view> &params)
{
if (m_cheat.undo > 0)
{
@@ -3346,15 +3134,15 @@ void debugger_commands::execute_cheatundo(const std::vector<std::string> &params
execute_find - execute the find command
-------------------------------------------------*/
-void debugger_commands::execute_find(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_find(int spacenum, const std::vector<std::string_view> &params)
{
u64 offset, length;
address_space *space;
// validate parameters
- if (!validate_target_address_parameter(params[0], spacenum, space, offset))
+ if (!m_console.validate_target_address_parameter(params[0], spacenum, space, offset))
return;
- if (!validate_number_parameter(params[1], length))
+ if (!m_console.validate_number_parameter(params[1], length))
return;
// further validation
@@ -3370,11 +3158,11 @@ void debugger_commands::execute_find(int spacenum, const std::vector<std::string
int data_count = 0;
for (int i = 2; i < params.size(); i++)
{
- char const *pdata = params[i].c_str();
- auto const pdatalen = params[i].length() - 1;
+ std::string_view pdata = params[i];
- if (pdata[0] == '"' && pdata[pdatalen] == '"') // check for a string
+ if (!pdata.empty() && pdata.front() == '"' && pdata.back() == '"') // check for a string
{
+ auto const pdatalen = params[i].length() - 1;
for (int j = 1; j < pdatalen; j++)
{
data_to_find[data_count] = pdata[j];
@@ -3385,17 +3173,20 @@ void debugger_commands::execute_find(int spacenum, const std::vector<std::string
{
// check for a 'b','w','d',or 'q' prefix
data_size[data_count] = cur_data_size;
- if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 1; pdata += 2; }
- if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 2; pdata += 2; }
- if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 4; pdata += 2; }
- if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 8; pdata += 2; }
+ if (pdata.length() >= 2)
+ {
+ if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 1; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 2; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 4; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 8; pdata.remove_prefix(2); }
+ }
// look for a wildcard
- if (!strcmp(pdata, "?"))
+ if (pdata == "?")
data_size[data_count++] |= 0x10;
// otherwise, validate as a number
- else if (!validate_number_parameter(params[i], data_to_find[data_count++]))
+ else if (!m_console.validate_number_parameter(pdata, data_to_find[data_count++]))
return;
}
}
@@ -3413,36 +3204,37 @@ void debugger_commands::execute_find(int spacenum, const std::vector<std::string
for (int j = 0; j < data_count && match; j++)
{
offs_t address = space->byte_to_address(i + suboffset);
+ address_space *tspace;
switch (data_size[j])
{
case 1:
address &= space->logaddrmask();
- if (memory.translate(space->spacenum(), TRANSLATE_READ_DEBUG, address))
- match = space->read_byte(address) == u8(data_to_find[j]);
+ if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
+ match = tspace->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]);
+ if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
+ match = tspace->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]);
+ if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
+ match = tspace->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]);
+ if (memory.translate(space->spacenum(), device_memory_interface::TR_READ, address, tspace))
+ match = tspace->read_qword_unaligned(address) == u64(data_to_find[j]);
else
match = false;
break;
@@ -3472,15 +3264,15 @@ void debugger_commands::execute_find(int spacenum, const std::vector<std::string
// execute_fill - execute the fill command
//-------------------------------------------------
-void debugger_commands::execute_fill(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_fill(int spacenum, const std::vector<std::string_view> &params)
{
u64 offset, length;
address_space *space;
// validate parameters
- if (!validate_target_address_parameter(params[0], spacenum, space, offset))
+ if (!m_console.validate_target_address_parameter(params[0], spacenum, space, offset))
return;
- if (!validate_number_parameter(params[1], length))
+ if (!m_console.validate_number_parameter(params[1], length))
return;
// further validation
@@ -3495,12 +3287,12 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
int data_count = 0;
for (int i = 2; i < params.size(); i++)
{
- const char *pdata = params[i].c_str();
- size_t pdatalen = strlen(pdata) - 1;
+ std::string_view pdata = params[i];
// check for a string
- if (pdata[0] == '"' && pdata[pdatalen] == '"')
+ if (!pdata.empty() && pdata.front() == '"' && pdata.back() == '"')
{
+ auto const pdatalen = pdata.length() - 1;
for (int j = 1; j < pdatalen; j++)
{
fill_data[data_count] = pdata[j];
@@ -3513,13 +3305,16 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
{
// check for a 'b','w','d',or 'q' prefix
fill_data_size[data_count] = cur_data_size;
- if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 1; pdata += 2; }
- if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 2; pdata += 2; }
- if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 4; pdata += 2; }
- if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 8; pdata += 2; }
+ if (pdata.length() >= 2)
+ {
+ if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 1; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 2; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 4; pdata.remove_prefix(2); }
+ if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { fill_data_size[data_count] = cur_data_size = 8; pdata.remove_prefix(2); }
+ }
// validate as a number
- if (!validate_number_parameter(pdata, fill_data[data_count++]))
+ if (!m_console.validate_number_parameter(pdata, fill_data[data_count++]))
return;
}
}
@@ -3536,7 +3331,8 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
for (int j = 0; j < data_count; j++)
{
offs_t address = space->byte_to_address(offset) & space->logaddrmask();
- if (!memory.translate(space->spacenum(), TRANSLATE_WRITE_DEBUG, address))
+ address_space *tspace;
+ if (!memory.translate(space->spacenum(), device_memory_interface::TR_WRITE, address, tspace))
{
m_console.printf("Fill aborted due to page fault at %0*X\n", space->logaddrchars(), space->byte_to_address(offset) & space->logaddrmask());
length = 0;
@@ -3545,19 +3341,19 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
switch (fill_data_size[j])
{
case 1:
- space->write_byte(address, fill_data[j]);
+ tspace->write_byte(address, fill_data[j]);
break;
case 2:
- space->write_word_unaligned(address, fill_data[j]);
+ tspace->write_word_unaligned(address, fill_data[j]);
break;
case 4:
- space->write_dword_unaligned(address, fill_data[j]);
+ tspace->write_dword_unaligned(address, fill_data[j]);
break;
case 8:
- space->read_qword_unaligned(address, fill_data[j]);
+ tspace->read_qword_unaligned(address, fill_data[j]);
break;
}
offset += fill_data_size[j];
@@ -3577,20 +3373,20 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
execute_dasm - execute the dasm command
-------------------------------------------------*/
-void debugger_commands::execute_dasm(const std::vector<std::string> &params)
+void debugger_commands::execute_dasm(const std::vector<std::string_view> &params)
{
u64 offset, length;
bool bytes = true;
address_space *space;
// validate parameters
- if (!validate_number_parameter(params[1], offset))
+ if (!m_console.validate_number_parameter(params[1], offset))
return;
- if (!validate_number_parameter(params[2], length))
+ if (!m_console.validate_number_parameter(params[2], length))
return;
- if (params.size() > 3 && !validate_boolean_parameter(params[3], bytes))
+ if (params.size() > 3 && !m_console.validate_boolean_parameter(params[3], bytes))
return;
- if (!validate_device_space_parameter(params.size() > 4 ? params[4] : std::string_view(), AS_PROGRAM, space))
+ if (!m_console.validate_device_space_parameter(params.size() > 4 ? params[4] : std::string_view(), AS_PROGRAM, space))
return;
// determine the width of the bytes
@@ -3636,7 +3432,8 @@ void debugger_commands::execute_dasm(const std::vector<std::string> &params)
}
/* write the data */
- std::ofstream f(params[0]);
+ std::string fname(params[0]);
+ std::ofstream f(fname);
if (!f.good())
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -3675,32 +3472,32 @@ void debugger_commands::execute_dasm(const std::vector<std::string> &params)
trace over and trace info
-------------------------------------------------*/
-void debugger_commands::execute_trace(const std::vector<std::string> &params, bool trace_over)
+void debugger_commands::execute_trace(const std::vector<std::string_view> &params, bool trace_over)
{
- const char *action = nullptr;
+ std::string_view action;
bool detect_loops = true;
bool logerror = false;
- device_t *cpu;
- const char *mode;
- std::string filename = params[0];
+ std::string filename(params[0]);
// replace macros
strreplace(filename, "{game}", m_machine.basename());
// validate parameters
- if (!validate_cpu_parameter(params.size() > 1 ? params[1] : std::string_view(), cpu))
+ device_t *cpu;
+ if (!m_console.validate_cpu_parameter(params.size() > 1 ? params[1] : std::string_view(), cpu))
return;
if (params.size() > 2)
{
std::stringstream stream;
- stream.str(params[2]);
+ stream.str(std::string(params[2]));
std::string flag;
while (std::getline(stream, flag, '|'))
{
- if (!core_stricmp(flag.c_str(), "noloop"))
+ using namespace std::literals;
+ if (util::streqlower(flag, "noloop"sv))
detect_loops = false;
- else if (!core_stricmp(flag.c_str(), "logerror"))
+ else if (util::streqlower(flag, "logerror"sv))
logerror = true;
else
{
@@ -3709,24 +3506,27 @@ void debugger_commands::execute_trace(const std::vector<std::string> &params, bo
}
}
}
- if (!debug_command_parameter_command(action = (params.size() > 3) ? params[3].c_str() : nullptr))
+ if (params.size() > 3 && !m_console.validate_command_parameter(action = params[3]))
return;
// open the file
- FILE *f = nullptr;
- if (core_stricmp(filename.c_str(), "off") != 0)
+ std::unique_ptr<std::ofstream> f;
+ using namespace std::literals;
+ if (!util::streqlower(filename, "off"sv))
{
- mode = "w";
+ std::ios_base::openmode mode = std::ios_base::out;
// opening for append?
if ((filename[0] == '>') && (filename[1] == '>'))
{
- mode = "a";
+ mode |= std::ios_base::ate;
filename = filename.substr(2);
}
+ else
+ mode |= std::ios_base::trunc;
- f = fopen(filename.c_str(), mode);
- if (!f)
+ f = std::make_unique<std::ofstream>(filename.c_str(), mode);
+ if (f->fail())
{
m_console.printf("Error opening file '%s'\n", params[0]);
return;
@@ -3734,8 +3534,9 @@ void debugger_commands::execute_trace(const std::vector<std::string> &params, bo
}
// do it
- cpu->debug()->trace(f, trace_over, detect_loops, logerror, action);
- if (f)
+ bool const on(f);
+ cpu->debug()->trace(std::move(f), trace_over, detect_loops, logerror, action);
+ if (on)
m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename);
else
m_console.printf("Stopped tracing on CPU '%s'\n", cpu->tag());
@@ -3746,7 +3547,7 @@ void debugger_commands::execute_trace(const std::vector<std::string> &params, bo
execute_traceflush - execute the trace flush command
-------------------------------------------------*/
-void debugger_commands::execute_traceflush(const std::vector<std::string> &params)
+void debugger_commands::execute_traceflush(const std::vector<std::string_view> &params)
{
m_machine.debugger().cpu().flush_traces();
}
@@ -3756,15 +3557,15 @@ void debugger_commands::execute_traceflush(const std::vector<std::string> &param
execute_history - execute the history command
-------------------------------------------------*/
-void debugger_commands::execute_history(const std::vector<std::string> &params)
+void debugger_commands::execute_history(const std::vector<std::string_view> &params)
{
// validate parameters
device_t *device;
- if (!validate_cpu_parameter(!params.empty() ? params[0] : std::string_view(), device))
+ if (!m_console.validate_cpu_parameter(!params.empty() ? params[0] : std::string_view(), device))
return;
u64 count = device_debug::HISTORY_SIZE;
- if (params.size() > 1 && !validate_number_parameter(params[1], count))
+ if (params.size() > 1 && !m_console.validate_number_parameter(params[1], count))
return;
// further validation
@@ -3781,13 +3582,13 @@ void debugger_commands::execute_history(const std::vector<std::string> &params)
}
// loop over lines
- debug_disasm_buffer buffer(*device);
std::string instruction;
for (int index = int(unsigned(count)); index > 0; index--)
{
auto const pc = debug->history_pc(1 - index);
if (pc.second)
{
+ debug_disasm_buffer buffer(*device);
offs_t next_offset;
offs_t size;
u32 info;
@@ -3804,16 +3605,16 @@ void debugger_commands::execute_history(const std::vector<std::string> &params)
execute_trackpc - execute the trackpc command
-------------------------------------------------*/
-void debugger_commands::execute_trackpc(const std::vector<std::string> &params)
+void debugger_commands::execute_trackpc(const std::vector<std::string_view> &params)
{
// Gather the on/off switch (if present)
bool turnOn = true;
- if (params.size() > 0 && !validate_boolean_parameter(params[0], turnOn))
+ if (params.size() > 0 && !m_console.validate_boolean_parameter(params[0], turnOn))
return;
// Gather the cpu id (if present)
device_t *cpu = nullptr;
- if (!validate_cpu_parameter((params.size() > 1) ? params[1] : std::string_view(), cpu))
+ if (!m_console.validate_cpu_parameter((params.size() > 1) ? params[1] : std::string_view(), cpu))
return;
const device_state_interface *state;
@@ -3825,7 +3626,7 @@ void debugger_commands::execute_trackpc(const std::vector<std::string> &params)
// Should we clear the existing data?
bool clear = false;
- if (params.size() > 2 && !validate_boolean_parameter(params[2], clear))
+ if (params.size() > 2 && !m_console.validate_boolean_parameter(params[2], clear))
return;
cpu->debug()->set_track_pc((bool)turnOn);
@@ -3853,11 +3654,11 @@ void debugger_commands::execute_trackpc(const std::vector<std::string> &params)
execute_trackmem - execute the trackmem command
-------------------------------------------------*/
-void debugger_commands::execute_trackmem(const std::vector<std::string> &params)
+void debugger_commands::execute_trackmem(const std::vector<std::string_view> &params)
{
// Gather the on/off switch (if present)
bool turnOn = true;
- if (params.size() > 0 && !validate_boolean_parameter(params[0], turnOn))
+ if (params.size() > 0 && !m_console.validate_boolean_parameter(params[0], turnOn))
return;
// Gather the cpu id (if present)
@@ -3865,17 +3666,17 @@ void debugger_commands::execute_trackmem(const std::vector<std::string> &params)
if (params.size() > 1)
cpuparam = params[1];
device_t *cpu = nullptr;
- if (!validate_cpu_parameter(cpuparam, cpu))
+ if (!m_console.validate_cpu_parameter(cpuparam, cpu))
return;
// Should we clear the existing data?
bool clear = false;
- if (params.size() > 2 && !validate_boolean_parameter(params[2], clear))
+ if (params.size() > 2 && !m_console.validate_boolean_parameter(params[2], clear))
return;
// Get the address space for the given cpu
address_space *space;
- if (!validate_device_space_parameter(cpuparam, AS_PROGRAM, space))
+ if (!m_console.validate_device_space_parameter(cpuparam, AS_PROGRAM, space))
return;
// Inform the CPU it's time to start tracking memory writes
@@ -3891,17 +3692,18 @@ void debugger_commands::execute_trackmem(const std::vector<std::string> &params)
execute_pcatmem - execute the pcatmem command
-------------------------------------------------*/
-void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::string_view> &params)
{
// Gather the required target address/space parameter
u64 address;
address_space *space;
- if (!validate_target_address_parameter(params[0], spacenum, space, address))
+ if (!m_console.validate_target_address_parameter(params[0], spacenum, space, address))
return;
// Translate the address
offs_t a = address & space->logaddrmask();
- if (!space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, a))
+ address_space *tspace;
+ if (!space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, a, tspace))
{
m_console.printf("Address translation failed\n");
return;
@@ -3913,19 +3715,19 @@ void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::str
switch (space->data_width())
{
case 8:
- data = space->read_byte(a);
+ data = tspace->read_byte(a);
break;
case 16:
- data = space->read_word_unaligned(a);
+ data = tspace->read_word_unaligned(a);
break;
case 32:
- data = space->read_dword_unaligned(a);
+ data = tspace->read_dword_unaligned(a);
break;
case 64:
- data = space->read_qword_unaligned(a);
+ data = tspace->read_qword_unaligned(a);
break;
}
@@ -3942,7 +3744,7 @@ void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::str
execute_snap - execute the snapshot command
-------------------------------------------------*/
-void debugger_commands::execute_snap(const std::vector<std::string> &params)
+void debugger_commands::execute_snap(const std::vector<std::string_view> &params)
{
/* if no params, use the default behavior */
if (params.empty())
@@ -3954,8 +3756,9 @@ void debugger_commands::execute_snap(const std::vector<std::string> &params)
/* otherwise, we have to open the file ourselves */
else
{
- const char *filename = params[0].c_str();
- int scrnum = (params.size() > 1) ? atoi(params[1].c_str()) : 0;
+ u64 scrnum = 0;
+ if (params.size() > 1 && !m_console.validate_number_parameter(params[1], scrnum))
+ return;
screen_device_enumerator iter(m_machine.root_device());
screen_device *screen = iter.byindex(scrnum);
@@ -3966,7 +3769,7 @@ void debugger_commands::execute_snap(const std::vector<std::string> &params)
return;
}
- std::string fname(filename);
+ std::string fname(params[0]);
if (fname.find(".png") == -1)
fname.append(".png");
emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
@@ -3974,12 +3777,12 @@ void debugger_commands::execute_snap(const std::vector<std::string> &params)
if (filerr)
{
- m_console.printf("Error creating file '%s' (%s:%d %s)\n", filename, filerr.category().name(), filerr.value(), filerr.message());
+ m_console.printf("Error creating file '%s' (%s:%d %s)\n", params[0], filerr.category().name(), filerr.value(), filerr.message());
return;
}
screen->machine().video().save_snapshot(screen, file);
- m_console.printf("Saved screen #%d snapshot as '%s'\n", scrnum, filename);
+ m_console.printf("Saved screen #%d snapshot as '%s'\n", scrnum, params[0]);
}
}
@@ -3988,9 +3791,10 @@ void debugger_commands::execute_snap(const std::vector<std::string> &params)
execute_source - execute the source command
-------------------------------------------------*/
-void debugger_commands::execute_source(const std::vector<std::string> &params)
+void debugger_commands::execute_source(const std::vector<std::string_view> &params)
{
- m_console.source_script(params[0].c_str());
+ std::string filename(params[0]);
+ m_console.source_script(filename.c_str());
}
@@ -3998,27 +3802,29 @@ void debugger_commands::execute_source(const std::vector<std::string> &params)
execute_map - execute the map command
-------------------------------------------------*/
-void debugger_commands::execute_map(int spacenum, const std::vector<std::string> &params)
+void debugger_commands::execute_map(int spacenum, const std::vector<std::string_view> &params)
{
// validate parameters
u64 address;
address_space *space;
- if (!validate_target_address_parameter(params[0], spacenum, space, address))
+ if (!m_console.validate_target_address_parameter(params[0], spacenum, space, address))
return;
+ address &= space->logaddrmask();
// do the translation first
- for (int intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++)
+ for (int intention = device_memory_interface::TR_READ; intention <= device_memory_interface::TR_FETCH; intention++)
{
static const char *const intnames[] = { "Read", "Write", "Fetch" };
- offs_t taddress = address & space->addrmask();
- if (space->device().memory().translate(space->spacenum(), intention, taddress))
+ offs_t taddress = address;
+ address_space *tspace;
+ if (space->device().memory().translate(space->spacenum(), intention, taddress, tspace))
{
- std::string mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress);
+ std::string mapname = tspace->get_handler_string((intention == device_memory_interface::TR_WRITE) ? read_or_write::WRITE : read_or_write::READ, taddress);
m_console.printf(
- "%7s: %0*X logical == %0*X physical -> %s\n",
+ "%7s: %0*X logical %s == %0*X physical %s -> %s\n",
intnames[intention & 3],
- space->logaddrchars(), address,
- space->addrchars(), taddress,
+ space->logaddrchars(), address, space->name(),
+ tspace->addrchars(), taddress, tspace->name(),
mapname);
}
else
@@ -4031,14 +3837,15 @@ void debugger_commands::execute_map(int spacenum, const std::vector<std::string>
execute_memdump - execute the memdump command
-------------------------------------------------*/
-void debugger_commands::execute_memdump(const std::vector<std::string> &params)
+void debugger_commands::execute_memdump(const std::vector<std::string_view> &params)
{
device_t *root = &m_machine.root_device();
- if ((params.size() >= 2) && !validate_device_parameter(params[1], root))
+ if ((params.size() >= 2) && !m_console.validate_device_parameter(params[1], root))
return;
- char const *const filename = params.empty() ? "memdump.log" : params[0].c_str();
- FILE *const file = fopen(filename, "w");
+ using namespace std::literals;
+ std::string filename = params.empty() ? "memdump.log"s : std::string(params[0]);
+ FILE *const file = fopen(filename.c_str(), "w");
if (!file)
{
m_console.printf("Error opening file %s\n", filename);
@@ -4097,7 +3904,7 @@ void debugger_commands::execute_memdump(const std::vector<std::string> &params)
execute_symlist - execute the symlist command
-------------------------------------------------*/
-void debugger_commands::execute_symlist(const std::vector<std::string> &params)
+void debugger_commands::execute_symlist(const std::vector<std::string_view> &params)
{
const char *namelist[1000];
symbol_table *symtable;
@@ -4107,7 +3914,7 @@ void debugger_commands::execute_symlist(const std::vector<std::string> &params)
{
// validate parameters
device_t *cpu;
- if (!validate_cpu_parameter(params[0], cpu))
+ if (!m_console.validate_cpu_parameter(params[0], cpu))
return;
symtable = &cpu->debug()->symtable();
m_console.printf("CPU '%s' symbols:\n", cpu->tag());
@@ -4159,7 +3966,7 @@ void debugger_commands::execute_symlist(const std::vector<std::string> &params)
execute_softreset - execute the softreset command
-------------------------------------------------*/
-void debugger_commands::execute_softreset(const std::vector<std::string> &params)
+void debugger_commands::execute_softreset(const std::vector<std::string_view> &params)
{
m_machine.schedule_soft_reset();
}
@@ -4169,7 +3976,7 @@ void debugger_commands::execute_softreset(const std::vector<std::string> &params
execute_hardreset - execute the hardreset command
-------------------------------------------------*/
-void debugger_commands::execute_hardreset(const std::vector<std::string> &params)
+void debugger_commands::execute_hardreset(const std::vector<std::string_view> &params)
{
m_machine.schedule_hard_reset();
}
@@ -4179,7 +3986,7 @@ void debugger_commands::execute_hardreset(const std::vector<std::string> &params
mounted files
-------------------------------------------------*/
-void debugger_commands::execute_images(const std::vector<std::string> &params)
+void debugger_commands::execute_images(const std::vector<std::string_view> &params)
{
image_interface_enumerator iter(m_machine.root_device());
for (device_image_interface &img : iter)
@@ -4209,16 +4016,25 @@ void debugger_commands::execute_images(const std::vector<std::string> &params)
execute_mount - execute the image mount command
-------------------------------------------------*/
-void debugger_commands::execute_mount(const std::vector<std::string> &params)
+void debugger_commands::execute_mount(const std::vector<std::string_view> &params)
{
for (device_image_interface &img : image_interface_enumerator(m_machine.root_device()))
{
if ((img.instance_name() == params[0]) || (img.brief_instance_name() == params[0]))
{
- if (img.load(params[1]) != image_init_result::PASS)
- m_console.printf("Unable to mount file %s on %s\n", params[1], params[0]);
- else
+ auto [err, msg] = img.load(params[1]);
+ if (!err)
+ {
m_console.printf("File %s mounted on %s\n", params[1], params[0]);
+ }
+ else
+ {
+ m_console.printf(
+ "Unable to mount file %s on %s: %s\n",
+ params[1],
+ params[0],
+ !msg.empty() ? msg : err.message());
+ }
return;
}
}
@@ -4229,7 +4045,7 @@ void debugger_commands::execute_mount(const std::vector<std::string> &params)
execute_unmount - execute the image unmount command
-------------------------------------------------*/
-void debugger_commands::execute_unmount(const std::vector<std::string> &params)
+void debugger_commands::execute_unmount(const std::vector<std::string_view> &params)
{
for (device_image_interface &img : image_interface_enumerator(m_machine.root_device()))
{
@@ -4256,9 +4072,9 @@ void debugger_commands::execute_unmount(const std::vector<std::string> &params)
natural keyboard input
-------------------------------------------------*/
-void debugger_commands::execute_input(const std::vector<std::string> &params)
+void debugger_commands::execute_input(const std::vector<std::string_view> &params)
{
- m_machine.natkeyboard().post_coded(params[0].c_str());
+ m_machine.natkeyboard().post_coded(params[0]);
}
@@ -4267,15 +4083,15 @@ void debugger_commands::execute_input(const std::vector<std::string> &params)
keyboard codes
-------------------------------------------------*/
-void debugger_commands::execute_dumpkbd(const std::vector<std::string> &params)
+void debugger_commands::execute_dumpkbd(const std::vector<std::string_view> &params)
{
// was there a file specified?
- const char *filename = !params.empty() ? params[0].c_str() : nullptr;
+ std::string filename = !params.empty() ? std::string(params[0]) : std::string();
FILE *file = nullptr;
- if (filename != nullptr)
+ if (!filename.empty())
{
// if so, open it
- file = fopen(filename, "w");
+ file = fopen(filename.c_str(), "w");
if (file == nullptr)
{
m_console.printf("Cannot open \"%s\"\n", filename);