summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/express.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-10-13 10:59:38 +1100
committer Vas Crabb <vas@vastheman.com>2021-10-13 10:59:38 +1100
commitca338f73720ec7dedfcf8430d9dc9e481ada6378 (patch)
treeaa0a8a6e25d898db6c129a4134a129b2e400551f /src/emu/debug/express.cpp
parent9bcd5a2b95c9164199f5d890630113d6bb1fb6c2 (diff)
Various improvements to the user experience:
Extended the memory access prefixes in debugger expressions to support address space names. Made the debugger history command aware of how much history it has collected, and added a help topic for it to the built-in debugger help. Started updating the documentation for the web site, and corrected some of the more misleading built-in debugger help. Made some corrections to Chinese localisation after discussion with YuiFAN. Darkened the UI red colour a little. cpu/m6502/st2205u.h: Marked sound imperfect.
Diffstat (limited to 'src/emu/debug/express.cpp')
-rw-r--r--src/emu/debug/express.cpp319
1 files changed, 136 insertions, 183 deletions
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));
}