summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/m6502/st2205u.h2
-rw-r--r--src/emu/debug/debugcmd.cpp69
-rw-r--r--src/emu/debug/debugcpu.cpp37
-rw-r--r--src/emu/debug/debugcpu.h10
-rw-r--r--src/emu/debug/debughlp.cpp167
-rw-r--r--src/emu/debug/express.cpp319
-rw-r--r--src/emu/debug/express.h10
-rw-r--r--src/frontend/mame/ui/ui.h2
8 files changed, 317 insertions, 299 deletions
diff --git a/src/devices/cpu/m6502/st2205u.h b/src/devices/cpu/m6502/st2205u.h
index f414234fd7f..4182793a3bb 100644
--- a/src/devices/cpu/m6502/st2205u.h
+++ b/src/devices/cpu/m6502/st2205u.h
@@ -56,6 +56,8 @@ public:
ST_LVCTR
};
+ static constexpr feature_type imperfect_features() { return feature::SOUND; }
+
protected:
st2205u_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map, int data_bits, bool has_banked_ram);
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index 8bde2af72ea..1d2bf4e13b6 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -9,21 +9,25 @@
*********************************************************************/
#include "emu.h"
-#include "emuopts.h"
-#include "debugger.h"
#include "debugcmd.h"
+
+#include "debugbuf.h"
#include "debugcon.h"
#include "debugcpu.h"
-#include "debugbuf.h"
-#include "express.h"
#include "debughlp.h"
#include "debugvw.h"
+#include "express.h"
#include "points.h"
+
+#include "debugger.h"
+#include "emuopts.h"
#include "natkeyboard.h"
#include "render.h"
+
#include "corestr.h"
-#include <cctype>
+
#include <algorithm>
+#include <cctype>
#include <fstream>
@@ -2353,6 +2357,7 @@ void debugger_commands::execute_load(int spacenum, const std::vector<std::string
u64 i = 0;
// now read the data in, ignore endoffset and load entire file if length has been set to zero (offset-1)
+ auto dis = space->device().machine().disable_side_effects();
switch (space->addr_shift())
{
case -3:
@@ -3479,7 +3484,8 @@ void debugger_commands::execute_fill(int spacenum, const std::vector<std::string
void debugger_commands::execute_dasm(const std::vector<std::string> &params)
{
- u64 offset, length, bytes = 1;
+ u64 offset, length;
+ bool bytes = true;
address_space *space;
// validate parameters
@@ -3487,7 +3493,7 @@ void debugger_commands::execute_dasm(const std::vector<std::string> &params)
return;
if (!validate_number_parameter(params[2], length))
return;
- if (params.size() > 3 && !validate_number_parameter(params[3], bytes))
+ if (params.size() > 3 && !validate_boolean_parameter(params[3], bytes))
return;
if (!validate_device_space_parameter(params.size() > 4 ? params[4] : std::string_view(), AS_PROGRAM, space))
return;
@@ -3523,11 +3529,11 @@ void debugger_commands::execute_dasm(const std::vector<std::string> &params)
topcodes.emplace_back(buffer.data_to_string(offset, size, true));
int osize = topcodes.back().size();
- if(osize > max_opcodes_size)
+ if (osize > max_opcodes_size)
max_opcodes_size = osize;
int dsize = instructions.back().size();
- if(dsize > max_disasm_size)
+ if (dsize > max_disasm_size)
max_disasm_size = dsize;
i += size;
@@ -3544,7 +3550,7 @@ void debugger_commands::execute_dasm(const std::vector<std::string> &params)
if (bytes)
{
- for(unsigned int i=0; i != pcs.size(); i++)
+ for (unsigned int i=0; i != pcs.size(); i++)
{
const char *comment = space->device().debug()->comment_text(pcs[i]);
if (comment)
@@ -3555,7 +3561,7 @@ void debugger_commands::execute_dasm(const std::vector<std::string> &params)
}
else
{
- for(unsigned int i=0; i != pcs.size(); i++)
+ for (unsigned int i=0; i != pcs.size(); i++)
{
const char *comment = space->device().debug()->comment_text(pcs[i]);
if (comment)
@@ -3678,8 +3684,8 @@ void debugger_commands::execute_traceflush(const std::vector<std::string> &param
void debugger_commands::execute_history(const std::vector<std::string> &params)
{
// validate parameters
- address_space *space;
- if (!validate_device_space_parameter(!params.empty() ? params[0] : std::string_view(), AS_PROGRAM, space))
+ device_t *device;
+ if (!validate_cpu_parameter(!params.empty() ? params[0] : std::string_view(), device))
return;
u64 count = device_debug::HISTORY_SIZE;
@@ -3690,34 +3696,31 @@ void debugger_commands::execute_history(const std::vector<std::string> &params)
if (count > device_debug::HISTORY_SIZE)
count = device_debug::HISTORY_SIZE;
- device_execute_interface const *execute;
- if (!space->device().interface(execute))
- {
- m_console.printf("Device %s is not a CPU\n", space->device().name());
- return;
- }
- device_debug *const debug = space->device().debug();
+ device_debug *const debug = device->debug();
- // loop over lines
device_disasm_interface *dasmintf;
- if (!space->device().interface(dasmintf))
+ if (!device->interface(dasmintf))
{
- m_console.printf("No disassembler available for device %s\n", space->device().name());
+ m_console.printf("No disassembler available for device %s\n", device->name());
return;
}
- debug_disasm_buffer buffer(space->device());
-
- for (int index = 0; index < (int) count; index++)
+ // loop over lines
+ debug_disasm_buffer buffer(*device);
+ std::string instruction;
+ for (int index = int(unsigned(count)); index > 0; index--)
{
- offs_t const pc = debug->history_pc(-index);
- std::string instruction;
- offs_t next_offset;
- offs_t size;
- u32 info;
- buffer.disassemble(pc, instruction, next_offset, size, info);
+ auto const pc = debug->history_pc(1 - index);
+ if (pc.second)
+ {
+ offs_t next_offset;
+ offs_t size;
+ u32 info;
+ instruction.clear();
+ buffer.disassemble(pc.first, instruction, next_offset, size, info);
- m_console.printf("%s: %s\n", buffer.pc_to_string(pc), instruction);
+ m_console.printf("%s: %s\n", buffer.pc_to_string(pc.first), instruction);
+ }
}
}
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 04cce887484..403d0b104ee 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -434,6 +434,7 @@ device_debug::device_debug(device_t &device)
, m_total_cycles(0)
, m_last_total_cycles(0)
, m_pc_history_index(0)
+ , m_pc_history_valid(0)
, m_bplist()
, m_rplist(std::make_unique<std::forward_list<debug_registerpoint>>())
, m_triggered_breakpoint(nullptr)
@@ -722,7 +723,10 @@ void device_debug::instruction_hook(offs_t curpc)
debugcpu.set_within_instruction(true);
// update the history
- m_pc_history[m_pc_history_index++ % HISTORY_SIZE] = curpc;
+ m_pc_history[m_pc_history_index] = curpc;
+ m_pc_history_index = (m_pc_history_index + 1) % std::size(m_pc_history);
+ if (std::size(m_pc_history) > m_pc_history_valid)
+ ++m_pc_history_valid;
// update total cycles
m_last_total_cycles = m_total_cycles;
@@ -1352,13 +1356,28 @@ void device_debug::registerpoint_enable_all(bool enable)
// history
//-------------------------------------------------
-offs_t device_debug::history_pc(int index) const
+std::pair<offs_t, bool> device_debug::history_pc(int index) const
{
- if (index > 0)
- index = 0;
- if (index <= -HISTORY_SIZE)
- index = -HISTORY_SIZE + 1;
- return m_pc_history[(m_pc_history_index + std::size(m_pc_history) - 1 + index) % std::size(m_pc_history)];
+ if ((index <= 0) && (-index < m_pc_history_valid))
+ {
+ int const i = (m_pc_history_index + std::size(m_pc_history) - 1 + index) % std::size(m_pc_history);
+ return std::make_pair(m_pc_history[i], true);
+ }
+ else
+ {
+ return std::make_pair(offs_t(0), false);
+ }
+}
+
+
+//-------------------------------------------------
+// set_track_pc - turn visited PC tracking on or
+// off
+//-------------------------------------------------
+
+void device_debug::set_track_pc(bool value)
+{
+ m_track_pc = value;
}
@@ -1369,7 +1388,7 @@ offs_t device_debug::history_pc(int index) const
// TODO: Take a CPU context as input
//-------------------------------------------------
-bool device_debug::track_pc_visited(const offs_t& pc) const
+bool device_debug::track_pc_visited(offs_t pc) const
{
if (m_track_pc_set.empty())
return false;
@@ -1383,7 +1402,7 @@ bool device_debug::track_pc_visited(const offs_t& pc) const
// TODO: Take a CPU context as input
//-------------------------------------------------
-void device_debug::set_track_pc_visited(const offs_t& pc)
+void device_debug::set_track_pc_visited(offs_t pc)
{
const u32 crc = compute_opcode_crc32(pc);
m_track_pc_set.insert(dasm_pc_tag(pc, crc));
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index eba89367c2c..9e3d23d8d7f 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -14,6 +14,7 @@
#pragma once
#include <set>
+#include <utility>
//**************************************************************************
@@ -129,12 +130,12 @@ public:
u32 compute_opcode_crc32(offs_t pc) const;
// history
- offs_t history_pc(int index) const;
+ std::pair<offs_t, bool> history_pc(int index) const;
// pc tracking
- void set_track_pc(bool value) { m_track_pc = value; }
- bool track_pc_visited(const offs_t& pc) const;
- void set_track_pc_visited(const offs_t& pc);
+ void set_track_pc(bool value);
+ bool track_pc_visited(offs_t pc) const;
+ void set_track_pc_visited(offs_t pc);
void track_pc_data_clear() { m_track_pc_set.clear(); }
// memory tracking
@@ -200,6 +201,7 @@ private:
// history
offs_t m_pc_history[HISTORY_SIZE]; // history of recent PCs
u32 m_pc_history_index; // current history index
+ u32 m_pc_history_valid; // number of valid PC history entries
// breakpoints and watchpoints
std::multimap<offs_t, std::unique_ptr<debug_breakpoint>> m_bplist; // list of breakpoints
diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp
index ead08937c15..322c760bbbb 100644
--- a/src/emu/debug/debughlp.cpp
+++ b/src/emu/debug/debughlp.cpp
@@ -68,7 +68,7 @@ const help_item f_static_help_list[] =
" logerror <format>[,<item>[,...]] -- outputs one or more <item>s to the error.log\n"
" tracelog <format>[,<item>[,...]] -- outputs one or more <item>s to the trace file using <format>\n"
" tracesym <item>[,...]] -- outputs one or more <item>s to the trace file\n"
- " history [<CPU>,<length>] -- outputs a brief history of visited opcodes\n"
+ " history [<CPU>,[<length>]] -- outputs a brief history of visited opcodes\n"
" trackpc [<bool>,[<CPU>,[<bool>]]] -- visually track visited opcodes [boolean to turn on and off, for CPU, clear]\n"
" trackmem [<bool>,[<CPU>,[<bool>]]] -- record which PC writes to each memory address [boolean to turn on and off, for CPU, clear]\n"
" pcatmem <address>[:<space>] -- query which PC wrote to a given memory address\n"
@@ -391,21 +391,43 @@ const help_item f_static_help_list[] =
"tracelog \"PC=%04X\",pc\n"
" Outputs PC=<pcval> where <pcval> is displayed in hexadecimal with 4 digits with zero-fill.\n"
"\n"
- "printf \"A=%d, B=%d\\nC=%d\",a,b,a+b\n"
+ "tracelog \"A=%d, B=%d\\nC=%d\",a,b,a+b\n"
" Outputs A=<aval>, B=<bval> on one line, and C=<a+bval> on a second line.\n"
},
{
"tracesym",
"\n"
" tracesym <item>[,...]\n"
- "\n"
- "The tracesym command prints the specified symbols and routes the output to the currently open trace "
- "file (see the 'trace' command for details). If no file is currently open, tracesym does nothing. "
- "\n"
- "Examples:\n"
- "\n"
- "tracelog pc\n"
- " Outputs PC=<pcval> where <pcval> is displayed in the default format.\n"
+ "\n"
+ "The tracesym command prints the specified symbols and routes the output to the currently open trace "
+ "file (see the 'trace' command for details). If no file is currently open, tracesym does nothing. "
+ "\n"
+ "Examples:\n"
+ "\n"
+ "tracesym pc\n"
+ " Outputs PC=<pcval> where <pcval> is displayed in the default format.\n"
+ },
+ {
+ "history",
+ "\n"
+ " history [<CPU>,[<length>]]\n"
+ "\n"
+ "The history command displays recently visited PC addresses, and the disassembly of the "
+ "instructions at those addresses. If present, the first argument is a CPU selector "
+ "(either a tag or a CPU number); if no CPU is specified, the current CPU is assumed. "
+ "The second argument, if present, limits the maximum number of addresses shown. "
+ "Addresses are shown in order from least to most recently visited.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "history ,5\n"
+ " Displays up to five most recently visited PC addresses for the current CPU.\n"
+ "\n"
+ "history 3\n"
+ " Displays recently visited PC addresses for CPU 3.\n"
+ "\n"
+ "history audiocpu,1\n"
+ " Displays the most recently visited PC addresses for the CPU ':audiocpu'.\n"
},
{
"trackpc",
@@ -445,20 +467,21 @@ const help_item f_static_help_list[] =
" Begin tracking memory writes for the current CPU.\n"
"\n"
"trackmem 1, 0, 1\n"
- " Continue tracking memory writes on CPU 0, but clear existing track info.\n"
+ " Continue tracking memory writes on CPU 0, but clear existing tracking data.\n"
},
{
"pcatmem",
"\n"
" pcatmem[{d|i|o}] <address>[:<space>]\n"
"\n"
- "The pcatmem command returns which PC wrote to a given memory address for the current CPU. "
- "The argument is the requested address, optionally followed by a colon and a CPU and/or "
- "address space. The CPU may be specified as a tag or debugger CPU number; if no CPU is "
- "specified, the CPU currently visible in the debugger is assumed. If an address space is "
- "not specified, the command suffix sets the address space: 'pcatmem' defaults to the first "
- "space exposed by the device, 'pcatmemd' defaults to the data space, 'pcatmemi' defaults to "
- "the I/O space, and 'pcatmemo' defaults to the opcodes space.\n"
+ "The pcatmem command returns which PC value at the time the specified address was most "
+ "recently written. The argument is the requested address, optionally followed by a colon "
+ "and a CPU and/or address space. The CPU may be specified as a tag or debugger CPU number; "
+ "if no CPU is specified, the CPU currently visible in the debugger is assumed. If an "
+ "address space is not specified, the command suffix sets the address space: 'pcatmem' "
+ "defaults to the first space exposed by the device, 'pcatmemd' defaults to the data space, "
+ "'pcatmemi' defaults to the I/O space, and 'pcatmemo' defaults to the opcodes space.\n"
+ "\n"
"Right-clicking in a memory view will also display the logged PC for the given address.\n"
"\n"
"Examples:\n"
@@ -521,22 +544,25 @@ const help_item f_static_help_list[] =
{
"snap",
"\n"
- " snap [[<filename>], <scrnum>]\n"
+ " snap [<filename>[,<scrnum>]]\n"
"\n"
- "The snap command takes a snapshot of the current video display and saves it to the configured "
- "snapshot directory. If <filename> is specified explicitly, a single screenshot for <scrnum> is "
- "saved under the requested filename. If <filename> is omitted, all screens are saved using the "
- "same default rules as the \"save snapshot\" key in MAME proper.\n"
+ "Takes a snapshot of the emulated video display and saves it to the configured snapshot "
+ "directory. If a filename is specified, a single screenshot for the specified screen is "
+ "saved using the specified filename (or the first emulated screen in the system if a screen "
+ "is not specified). If a file name is not specified, the configured snapshot view and file "
+ "name pattern are used.\n"
+ "\n"
+ "If a file name is specified, the .png extension is automatically appended. The screen "
+ "number is specified as a zero-based index.\n"
"\n"
"Examples:\n"
"\n"
"snap\n"
- " Takes a snapshot of the current video screen and saves to the next non-conflicting filename "
- " in the configured snapshot directory.\n"
+ " Takes a snapshot using the configured snapshot view and file name options.\n"
"\n"
"snap shinobi\n"
- " Takes a snapshot of the current video screen and saves it as 'shinobi.png' in the configured "
- " snapshot directory.\n"
+ " Takes a snapshot of the first emulated video screen and saves it as 'shinobi.png' in the "
+ " configured snapshot directory.\n"
},
{
"source",
@@ -595,15 +621,14 @@ const help_item f_static_help_list[] =
"opcodes space.\n"
"\n"
"The <data> can either be a quoted string or a numeric value or expression or the wildcard "
- "character '?'. By default, strings by default imply a byte-sized search; by default "
- "non-string data is searched using the native word size of the address space. To override "
- "the search size for non-string data, you can prefix values with b. to force byte-sized "
- "search, w. for word-sized search, d. for dword-sized search, and q. for qword-sized "
- "search. Overrides propagate to subsequent values, so if you want to search for a sequence "
- "of words, you need only prefix the first value with a w. Also note that you can intermix "
- "sizes to perform more complex searches. The entire range <address> through "
- "<address>+<length>-1, inclusive, will be searched for the sequence, and all occurrences "
- "will be displayed.\n"
+ "character '?'. By default, strings imply a byte-sized search; by default non-string data "
+ "is searched using the native word size of the address space. To override the search size "
+ "for non-string data, you can prefix values with b. to force byte-sized search, w. for "
+ "word-sized search, d. for dword-sized search, and q. for qword-sized search. Overrides "
+ "propagate to subsequent values, so if you want to search for a sequence of words, you need "
+ "only prefix the first value with a w. Also note that you can intermix sizes to perform "
+ "more complex searches. The entire range <address> through <address>+<length>-1, "
+ "inclusive, will be searched for the sequence, and all occurrences will be displayed.\n"
"\n"
"Examples:\n"
"\n"
@@ -613,7 +638,7 @@ const help_item f_static_help_list[] =
"\n"
"find 300:tms9918a,100,w.abcd,4567\n"
" Searches the address range 300-3ff in the first address space exposed by the device "
- "':tms9918a' memory for the word-sized value abcd followed by the word-sized value 4567.\n"
+ "':tms9918a' for the word-sized value abcd followed by the word-sized value 4567.\n"
"\n"
"find 0,8000,\"AAR\",d.0,\"BEN\",w.0\n"
" Searches the address range 0000-7fff for the string \"AAR\" followed by a dword-sized 0 "
@@ -640,7 +665,7 @@ const help_item f_static_help_list[] =
"non-string data is written using the native word size of the address space. To override "
"the data size for non-string data, you can prefix values with b. to force byte-sized fill, "
"w. for word-sized fill, d. for dword-sized fill, and q. for qword-sized fill. Overrides "
- "propagate to subsequent value, so if you want to fill with a series of words, you need "
+ "propagate to subsequent values, so if you want to fill with a series of words, you need "
"only prefix the first value with a w. Also note that you can intermix sizes to perform "
"more complex fills. The fill operation may be truncated if a page fault occurs or if part "
"of the sequence or string would fall beyond <address>+<length>-1.\n"
@@ -750,10 +775,14 @@ const help_item f_static_help_list[] =
"saving from, and the <length> specifies how much memory to save. The range <address> "
"through <address>+<length>-1, inclusive, will be output to the file.\n"
"\n"
- "Example:\n"
+ "Examples:\n"
"\n"
- "saver harddriv.bin,80000,40000,:maincpu\n"
- " Saves :maincpu region addresses 80000-bffff to the binary file 'harddriv.bin'.\n"
+ "saver data.bin,200,100,:monitor\n"
+ " Saves ':monitor' region addresses 200-2ff to the binary file 'data.bin'.\n"
+ "\n"
+ "saver cpurom.bin,1000,400,.\n"
+ " Saves addresses 1000-13ff from the memory region with the same tag as the visible CPU to "
+ "the binary file 'cpurom.bin'.\n"
},
{
"load",
@@ -773,8 +802,10 @@ const help_item f_static_help_list[] =
"file. If the <length> is omitted, if it is zero, or if it is greater than the total "
"length of the file, the entire contents of the file will be loaded but no more.\n"
"\n"
- "NOTE: This will only actually write memory that is possible to overwrite via a memory "
- "view.\n"
+ "NOTE: this has the same effect as writing to the address space from a debugger memory "
+ "view, or using memory accessors in debugger expressions. Read-only memory will not be "
+ "overwritten, and writing to I/O addresses may have effects beyond setting register "
+ "values.\n"
"\n"
"Examples:\n"
"\n"
@@ -797,16 +828,20 @@ const help_item f_static_help_list[] =
" loadr <filename>,<address>,<length>,<region>\n"
"\n"
"The loadr command loads raw memory in the memory region <region> from the binary file "
- "specified in the <filename> parameter. The <address> indicates the address to start "
+ "specified by the <filename> parameter. The <address> specifies the address to start "
"loading to, and the <length> specifies how much memory to load. The range <address> "
"through <address>+<length>-1, inclusive, will be read in from the file. If the <length> "
"is zero, or is greater than the total length of the file, the entire contents of the file "
"will be loaded but no more.\n"
"\n"
- "Example:\n"
+ "Examples:\n"
+ "\n"
+ "loadr data.bin,200,100,:monitor\n"
+ " Loads ':monitor' region addresses 200-2ff from the binary file 'data.bin'.\n"
"\n"
- "loadr harddriv.bin,80000,40000,:maincpu\n"
- " Loads addresses 80000-bffff in the :maincpu region from the binary file 'harddriv.bin'.\n"
+ "loadr cpurom.bin,1000,400,.\n"
+ " Loads addresses 1000-13ff in the memory region with the same tag as the visible CPU from "
+ "the binary file 'cpurom.bin'.\n"
},
{
"step",
@@ -1384,22 +1419,22 @@ const help_item f_static_help_list[] =
" map[{d|i|o}] <address>[:<space>]\n"
"\n"
"The map commands map a logical memory address to the corresponding physical address, as "
- "well as specifying the bank. The address may optionally be followed by a colon and device "
- "and/or address space. The device may be specified as a tag or a debugger CPU number; if "
- "no device is specified, the CPU currently visible in the debugger is assumed. If an "
- "address space is not specified, the command suffix sets the address space: 'map' defaults "
- "to the first address space exposed by the device, 'mapd' defaults to the data space, "
- "'mapi' defaults to the I/O space, and 'mapo' defaults to the opcodes space.\n"
+ "well as reporting the handler name. The address may optionally be followed by a colon "
+ "and device and/or address space. The device may be specified as a tag or a debugger CPU "
+ "number; if no device is specified, the CPU currently visible in the debugger is assumed. "
+ "If an address space is not specified, the command suffix sets the address space: 'map' "
+ "defaults to the first address space exposed by the device, 'mapd' defaults to the data "
+ "space, 'mapi' defaults to the I/O space, and 'mapo' defaults to the opcodes space.\n"
"\n"
- "Example:\n"
+ "Examples:\n"
"\n"
"map 152d0\n"
- " Gives physical address and bank for logical address 152d0 in program memory for the "
- "currently visible CPU.\n"
+ " Gives physical address and handler name for logical address 152d0 in program memory for "
+ "the currently visible CPU.\n"
"\n"
"map 107:sms_vdp\n"
- " Gives physical address and bank for logical address 107 in the first address space for "
- "the device ':sms_vdp'.\n"
+ " Gives physical address and handler name for logical address 107 in the first address "
+ "space for the device ':sms_vdp'.\n"
},
{ "mapd", "#map" },
{ "mapi", "#map" },
@@ -1410,20 +1445,24 @@ const help_item f_static_help_list[] =
" memdump [<filename>,[<device>]]\n"
"\n"
"Dumps the current memory maps to the file specified by <filename>, or memdump.log if "
- "omitted. If <device> is specified it must be the tag of a device, and only memory maps "
- "for the part of the device tree rooted on this device will be dumped.\n"
+ "omitted. If <device> is specified, only memory maps for the part of the device tree "
+ "rooted at this device will be dumped. Devices may be specified using tags or CPU "
+ "numbers.\n"
"\n"
"Examples:\n"
"\n"
"memdump mylog.log\n"
- " Dumps all memory maps to the file mylog.log.\n"
+ " Dumps memory maps for all devices in the system to the file mylog.log.\n"
"\n"
"memdump\n"
- " Dumps all memory maps to the file memdump.log.\n"
+ " Dumps memory maps for all devices in the system to the file memdump.log.\n"
"\n"
"memdump audiomaps.log,audiopcb\n"
" Dumps memory maps for device ':audiopcb' and all its child devices to the file "
"audiomaps.log.\n"
+ "\n"
+ "memdump mylog.log,1\n"
+ " Dumps memory maps for the CPU 1 and all its child devices to the file mylog.log.\n"
},
{
"comlist",
@@ -1466,10 +1505,10 @@ const help_item f_static_help_list[] =
"Examples:\n"
"\n"
"commit 0, hello world.\n"
- " Adds the comment 'hello world.' to the code at address 0x0\n"
+ " Adds the comment 'hello world.' to the code at address 0x0 and saves comments\n"
"\n"
"/* 10, undocumented opcode!\n"
- " Adds the comment 'undocumented opcode!' to the code at address 0x10\n"
+ " Adds the comment 'undocumented opcode!' to the code at address 0x10 and saves comments\n"
"\n"
},
{
diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp
index c4b2662e3bb..bc90ddaf52e 100644
--- a/src/emu/debug/express.cpp
+++ b/src/emu/debug/express.cpp
@@ -540,14 +540,73 @@ void symbol_table::write_memory(address_space &space, offs_t address, u64 data,
//-------------------------------------------------
-// expression_get_device - return a device
+// expression_get_space - return a space
// based on a case insensitive tag search
//-------------------------------------------------
-device_t *symbol_table::expression_get_device(const char *tag)
+expression_error symbol_table::expression_get_space(const char *tag, int &spacenum, device_memory_interface *&memory)
{
- // convert to lowercase then lookup the name (tags are enforced to be all lower case)
- return m_machine.root_device().subdevice(strmakelower(tag));
+ device_t *device = nullptr;
+ std::string spacename;
+ if (tag)
+ {
+ // convert to lowercase then lookup the name (tags are enforced to be all lower case)
+ device_t *base;
+ if ((('^' == tag[0]) || (('.' == tag[0]) && ((':' == tag[1]) || !tag[1]))) && m_memintf)
+ base = &m_memintf->device();
+ else
+ base = &m_machine.root_device();
+ device = base->subdevice(strmakelower(tag));
+
+ // if that failed, treat the last component as an address space
+ if (!device)
+ {
+ std::string_view t = tag;
+ auto const delimiter = t.find_last_of(":^");
+ bool const found = std::string_view::npos != delimiter;
+ if (!found || (':' == t[delimiter]))
+ {
+ spacename = strmakelower(t.substr(found ? (delimiter + 1) : 0));
+ t = t.substr(0, !found ? 0 : !delimiter ? 1 : delimiter);
+ if (!t.empty())
+ device = base->subdevice(strmakelower(t));
+ else
+ device = m_memintf ? &m_memintf->device() : &m_machine.root_device();
+ }
+ }
+ }
+ else if (m_memintf)
+ {
+ device = &m_memintf->device();
+ }
+
+ // if still no device, report error
+ if (!device)
+ {
+ memory = nullptr;
+ return expression_error::INVALID_MEMORY_NAME;
+ }
+
+ // ensure device has memory interface, and check for space if search not required
+ if (!device->interface(memory) || (spacename.empty() && (0 <= spacenum) && !memory->has_space(spacenum)))
+ {
+ memory = nullptr;
+ return expression_error::NO_SUCH_MEMORY_SPACE;
+ }
+
+ // find space by name or take 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)))
+ {
+ spacenum = i;
+ return expression_error::NONE;
+ }
+ }
+
+ // space not found
+ memory = nullptr;
+ return expression_error::NO_SUCH_MEMORY_SPACE;
}
@@ -574,76 +633,45 @@ u64 symbol_table::memory_value(const char *name, expression_space spacenum, u32
{
device_memory_interface *memory = m_memintf;
+ bool logical = true;
+ int space = -1;
switch (spacenum)
{
- case EXPSPACE_PROGRAM_LOGICAL:
- case EXPSPACE_DATA_LOGICAL:
- case EXPSPACE_IO_LOGICAL:
- case EXPSPACE_SPACE3_LOGICAL:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
- {
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
- auto dis = m_machine.disable_side_effects(disable_se);
- return read_memory(space, address, size, true);
- }
- break;
-
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
- case EXPSPACE_SPACE3_PHYSICAL:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
- {
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
- auto dis = m_machine.disable_side_effects(disable_se);
- return read_memory(space, address, size, false);
- }
- break;
-
- case EXPSPACE_RAMWRITE:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_PROGRAM))
+ case EXPSPACE_OPCODE_PHYSICAL:
+ spacenum = expression_space(spacenum - (EXPSPACE_PROGRAM_PHYSICAL - EXPSPACE_PROGRAM_LOGICAL));
+ logical = false;
+ [[fallthrough]];
+ case EXPSPACE_PROGRAM_LOGICAL:
+ case EXPSPACE_DATA_LOGICAL:
+ case EXPSPACE_IO_LOGICAL:
+ case EXPSPACE_OPCODE_LOGICAL:
+ space = AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL);
+ expression_get_space(name, space, memory);
+ if (memory)
{
auto dis = m_machine.disable_side_effects(disable_se);
- return read_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size);
+ return read_memory(memory->space(space), address, size, logical);
}
break;
- case EXPSPACE_OPCODE:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_OPCODES))
+ case EXPSPACE_PRGDIRECT:
+ case EXPSPACE_OPDIRECT:
+ space = (spacenum == EXPSPACE_OPDIRECT) ? AS_OPCODES : AS_PROGRAM;
+ expression_get_space(name, space, memory);
+ if (memory)
{
auto dis = m_machine.disable_side_effects(disable_se);
- return read_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size);
+ return read_program_direct(memory->space(space), (spacenum == EXPSPACE_OPDIRECT) ? 1 : 0, address, size);
}
break;
case EXPSPACE_REGION:
- if (name == nullptr)
- break;
- return read_memory_region(name, address, size);
+ if (name)
+ return read_memory_region(name, address, size);
+ break;
default:
break;
@@ -762,78 +790,44 @@ void symbol_table::set_memory_value(const char *name, expression_space spacenum,
{
device_memory_interface *memory = m_memintf;
+ bool logical = true;
+ int space = -1;
switch (spacenum)
{
- case EXPSPACE_PROGRAM_LOGICAL:
- case EXPSPACE_DATA_LOGICAL:
- case EXPSPACE_IO_LOGICAL:
- case EXPSPACE_SPACE3_LOGICAL:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
- {
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
- auto dis = m_machine.disable_side_effects(disable_se);
- write_memory(space, address, data, size, true);
- }
- break;
-
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
- case EXPSPACE_SPACE3_PHYSICAL:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
- {
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
- auto dis = m_machine.disable_side_effects(disable_se);
- write_memory(space, address, data, size, false);
- }
- break;
-
- case EXPSPACE_RAMWRITE: {
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_PROGRAM))
+ case EXPSPACE_OPCODE_PHYSICAL:
+ spacenum = expression_space(spacenum - (EXPSPACE_PROGRAM_PHYSICAL - EXPSPACE_PROGRAM_LOGICAL));
+ logical = false;
+ [[fallthrough]];
+ case EXPSPACE_PROGRAM_LOGICAL:
+ case EXPSPACE_DATA_LOGICAL:
+ case EXPSPACE_IO_LOGICAL:
+ case EXPSPACE_OPCODE_LOGICAL:
+ space = AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL);
+ expression_get_space(name, space, memory);
+ if (memory)
{
auto dis = m_machine.disable_side_effects(disable_se);
- write_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size, data);
+ write_memory(memory->space(space), address, data, size, logical);
}
break;
- }
- case EXPSPACE_OPCODE: {
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device != nullptr)
- device->interface(memory);
- }
- if (memory != nullptr && memory->has_space(AS_OPCODES))
+ case EXPSPACE_PRGDIRECT:
+ case EXPSPACE_OPDIRECT:
+ space = (spacenum == EXPSPACE_OPDIRECT) ? AS_OPCODES : AS_PROGRAM;
+ expression_get_space(name, space, memory);
+ if (memory)
{
auto dis = m_machine.disable_side_effects(disable_se);
- write_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size, data);
+ write_program_direct(memory->space(space), (spacenum == EXPSPACE_OPDIRECT) ? 1 : 0, address, size, data);
}
break;
- }
case EXPSPACE_REGION:
- if (name == nullptr)
- break;
- write_memory_region(name, address, size, data);
+ if (name)
+ write_memory_region(name, address, size, data);
break;
default:
@@ -966,73 +960,27 @@ expression_error::error_code symbol_table::memory_valid(const char *name, expres
{
device_memory_interface *memory = m_memintf;
+ int spaceno = -1;
switch (space)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
case EXPSPACE_IO_LOGICAL:
- case EXPSPACE_SPACE3_LOGICAL:
- if (name != nullptr)
- {
- device_t *device = expression_get_device(name);
- if (device == nullptr)
- return expression_error::INVALID_MEMORY_NAME;
- if (!device->interface(memory))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- }
- else if (memory == nullptr)
- return expression_error::MISSING_MEMORY_NAME;
- if (!memory->has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL)))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
+ case EXPSPACE_OPCODE_LOGICAL:
+ spaceno = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL);
+ return expression_get_space(name, spaceno, memory);
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
- case EXPSPACE_SPACE3_PHYSICAL:
- if (name)
- {
- device_t *device = expression_get_device(name);
- if (device == nullptr)
- return expression_error::INVALID_MEMORY_NAME;
- if (!device->interface(memory))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- }
- else if (memory == nullptr)
- return expression_error::MISSING_MEMORY_NAME;
- if (!memory->has_space(AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL)))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
-
- case EXPSPACE_RAMWRITE:
- if (name)
- {
- device_t *device = expression_get_device(name);
- if (device == nullptr)
- return expression_error::INVALID_MEMORY_NAME;
- if (!device->interface(memory))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- }
- else if (memory == nullptr)
- return expression_error::MISSING_MEMORY_NAME;
- if (!memory->has_space(AS_PROGRAM))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
+ case EXPSPACE_OPCODE_PHYSICAL:
+ spaceno = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL);
+ return expression_get_space(name, spaceno, memory);
- case EXPSPACE_OPCODE:
- if (name)
- {
- device_t *device = expression_get_device(name);
- if (device == nullptr)
- return expression_error::INVALID_MEMORY_NAME;
- if (!device->interface(memory))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- }
- else if (memory == nullptr)
- return expression_error::MISSING_MEMORY_NAME;
- if (!memory->has_space(AS_OPCODES))
- return expression_error::NO_SUCH_MEMORY_SPACE;
- break;
+ case EXPSPACE_PRGDIRECT:
+ case EXPSPACE_OPDIRECT:
+ spaceno = (space == EXPSPACE_OPDIRECT) ? AS_OPCODES : AS_PROGRAM;
+ return expression_get_space(name, spaceno, memory);
case EXPSPACE_REGION:
if (!name)
@@ -1044,6 +992,7 @@ expression_error::error_code symbol_table::memory_valid(const char *name, expres
default:
return expression_error::NO_SUCH_MEMORY_SPACE;
}
+
return expression_error::NONE;
}
@@ -1375,12 +1324,15 @@ void parsed_expression::parse_symbol_or_number(parse_token &token, const char *&
// check for memory @ and ! operators
if (string[0] == '@' || string[0] == '!')
{
- try {
+ try
+ {
bool disable_se = string[0] == '@';
parse_memory_operator(token, buffer.c_str(), disable_se);
string += 1;
return;
- } catch(const expression_error &) {
+ }
+ catch (const expression_error &)
+ {
// Try some other operator instead
}
}
@@ -1614,13 +1566,13 @@ void parsed_expression::parse_memory_operator(parse_token &token, const char *st
string = dot + 1;
}
- // length 3 means logical/physical, then space, then size
int length = (int)strlen(string);
bool physical = false;
int space = 'p';
int size;
if (length == 3)
{
+ // length 3 means logical/physical, then space, then size
if (string[0] != 'l' && string[0] != 'p')
throw expression_error(expression_error::INVALID_MEMORY_SPACE, token.offset() + (string - startstring));
if (string[1] != 'p' && string[1] != 'd' && string[1] != 'i' && string[1] != '3')
@@ -1629,21 +1581,22 @@ void parsed_expression::parse_memory_operator(parse_token &token, const char *st
space = string[1];
size = string[2];
}
-
- // length 2 means space then size
else if (length == 2)
{
+ // length 2 means space then size
space = string[0];
size = string[1];
}
-
- // length 1 means size
else if (length == 1)
+ {
+ // length 1 means size
size = string[0];
-
- // anything else is invalid
+ }
else
+ {
+ // anything else is invalid
throw expression_error(expression_error::INVALID_TOKEN, token.offset());
+ }
// convert the space to flags
expression_space memspace;
@@ -1652,9 +1605,9 @@ void parsed_expression::parse_memory_operator(parse_token &token, const char *st
case 'p': memspace = physical ? EXPSPACE_PROGRAM_PHYSICAL : EXPSPACE_PROGRAM_LOGICAL; break;
case 'd': memspace = physical ? EXPSPACE_DATA_PHYSICAL : EXPSPACE_DATA_LOGICAL; break;
case 'i': memspace = physical ? EXPSPACE_IO_PHYSICAL : EXPSPACE_IO_LOGICAL; break;
- case '3': memspace = physical ? EXPSPACE_SPACE3_PHYSICAL : EXPSPACE_SPACE3_LOGICAL; break;
- case 'o': memspace = EXPSPACE_OPCODE; break;
- case 'r': memspace = EXPSPACE_RAMWRITE; break;
+ case '3': memspace = physical ? EXPSPACE_OPCODE_PHYSICAL : EXPSPACE_OPCODE_LOGICAL; break;
+ case 'r': memspace = EXPSPACE_PRGDIRECT; break;
+ case 'o': memspace = EXPSPACE_OPDIRECT; break;
case 'm': memspace = EXPSPACE_REGION; break;
default: throw expression_error(expression_error::INVALID_MEMORY_SPACE, token.offset() + (string - startstring));
}
diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h
index c87b9370f7d..23284193f47 100644
--- a/src/emu/debug/express.h
+++ b/src/emu/debug/express.h
@@ -34,13 +34,13 @@ enum expression_space
EXPSPACE_PROGRAM_LOGICAL,
EXPSPACE_DATA_LOGICAL,
EXPSPACE_IO_LOGICAL,
- EXPSPACE_SPACE3_LOGICAL,
+ EXPSPACE_OPCODE_LOGICAL,
EXPSPACE_PROGRAM_PHYSICAL,
EXPSPACE_DATA_PHYSICAL,
EXPSPACE_IO_PHYSICAL,
- EXPSPACE_SPACE3_PHYSICAL,
- EXPSPACE_OPCODE,
- EXPSPACE_RAMWRITE,
+ EXPSPACE_OPCODE_PHYSICAL,
+ EXPSPACE_PRGDIRECT,
+ EXPSPACE_OPDIRECT,
EXPSPACE_REGION
};
@@ -204,7 +204,7 @@ private:
u64 read_memory_region(const char *rgntag, offs_t address, int size);
void write_program_direct(address_space &space, int opcode, offs_t address, int size, u64 data);
void write_memory_region(const char *rgntag, offs_t address, int size, u64 data);
- device_t *expression_get_device(const char *tag);
+ expression_error expression_get_space(const char *tag, int &spacenum, device_memory_interface *&memory);
void notify_memory_modified();
// internal state
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index 9607ca24a91..44727703a20 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -56,7 +56,7 @@ class laserdisc_device;
/* handy colors */
#define UI_GREEN_COLOR rgb_t(0xef,0x0a,0x66,0x0a)
#define UI_YELLOW_COLOR rgb_t(0xef,0xcc,0x7a,0x28)
-#define UI_RED_COLOR rgb_t(0xef,0xcc,0x14,0x14)
+#define UI_RED_COLOR rgb_t(0xef,0xb2,0x00,0x00)
/* cancel return value for a UI handler */
#define UI_HANDLER_CANCEL ((uint32_t)~0)