diff options
| author | 2021-10-13 10:59:38 +1100 | |
|---|---|---|
| committer | 2021-10-13 10:59:38 +1100 | |
| commit | ca338f73720ec7dedfcf8430d9dc9e481ada6378 (patch) | |
| tree | aa0a8a6e25d898db6c129a4134a129b2e400551f /src/emu/debug/express.cpp | |
| parent | 9bcd5a2b95c9164199f5d890630113d6bb1fb6c2 (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.cpp | 319 |
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)); } |
