diff options
Diffstat (limited to 'src/emu/debug/express.cpp')
| -rw-r--r-- | src/emu/debug/express.cpp | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index 219ed6a89ef..4408d621460 100644 --- a/src/emu/debug/express.cpp +++ b/src/emu/debug/express.cpp @@ -319,7 +319,7 @@ std::string expression_error::code_string() const case TOO_MANY_STRINGS: return "too many strings"; case INVALID_MEMORY_SIZE: return "invalid memory size (b/w/d/q expected)"; case NO_SUCH_MEMORY_SPACE: return "non-existent memory space"; - case INVALID_MEMORY_SPACE: return "invalid memory space (p/d/i/o/r/m expected)"; + case INVALID_MEMORY_SPACE: return "invalid memory space (p/d/i/o/r/m/s expected)"; case INVALID_MEMORY_NAME: return "invalid memory name"; case MISSING_MEMORY_NAME: return "missing memory name"; default: return "unknown error"; @@ -673,6 +673,11 @@ u64 symbol_table::memory_value(const char *name, expression_space spacenum, u32 return read_memory_region(name, address, size); break; + case EXPSPACE_SHARE: + if (name) + return read_memory_share(name, address, size); + break; + default: break; } @@ -783,6 +788,55 @@ u64 symbol_table::read_memory_region(const char *rgntag, offs_t address, int siz //------------------------------------------------- +// read_memory_share - read memory from a +// memory share +//------------------------------------------------- + +u64 symbol_table::read_memory_share(const char *shatag, offs_t address, int size) +{ + auto search = get_device_search(m_machine, m_memintf, shatag); + memory_share *const share = search.first.memshare(search.second); + u64 result = ~u64(0) >> (64 - 8*size); + + // make sure we get a valid base before proceeding + if (share) + { + // call ourself recursively until we are byte-sized + if (size > 1) + { + int halfsize = size / 2; + u64 r0, r1; + + // read each half, from lower address to upper address + r0 = read_memory_share(shatag, address + 0, halfsize); + r1 = read_memory_share(shatag, address + halfsize, halfsize); + + // assemble based on the target endianness + if (share->endianness() == ENDIANNESS_LITTLE) + result = r0 | (r1 << (8 * halfsize)); + else + result = r1 | (r0 << (8 * halfsize)); + } + + // only process if we're within range + else if (address < share->bytes()) + { + // lowmask specified which address bits are within the databus width + u32 lowmask = share->bytewidth() - 1; + u8 *base = reinterpret_cast<u8 *>(share->ptr()) + (address & ~lowmask); + + // if we have a valid base, return the appropriate byte + if (share->endianness() == ENDIANNESS_LITTLE) + result = base[BYTE8_XOR_LE(address) & lowmask]; + else + result = base[BYTE8_XOR_BE(address) & lowmask]; + } + } + return result; +} + + +//------------------------------------------------- // set_memory_value - write 1,2,4 or 8 bytes at // the given offset in the given address space //------------------------------------------------- @@ -831,6 +885,11 @@ void symbol_table::set_memory_value(const char *name, expression_space spacenum, write_memory_region(name, address, size, data); break; + case EXPSPACE_SHARE: + if (name) + write_memory_share(name, address, size, data); + break; + default: break; } @@ -954,6 +1013,65 @@ void symbol_table::write_memory_region(const char *rgntag, offs_t address, int s //------------------------------------------------- +// write_memory_share - write memory to a +// memory share +//------------------------------------------------- + +void symbol_table::write_memory_share(const char *shatag, offs_t address, int size, u64 data) +{ + auto search = get_device_search(m_machine, m_memintf, shatag); + memory_share *const share = search.first.memshare(search.second); + + // make sure we get a valid base before proceeding + if (share) + { + // call ourself recursively until we are byte-sized + if (size > 1) + { + int halfsize = size / 2; + + // break apart based on the target endianness + u64 halfmask = ~u64(0) >> (64 - 8 * halfsize); + u64 r0, r1; + if (share->endianness() == ENDIANNESS_LITTLE) + { + r0 = data & halfmask; + r1 = (data >> (8 * halfsize)) & halfmask; + } + else + { + r0 = (data >> (8 * halfsize)) & halfmask; + r1 = data & halfmask; + } + + // write each half, from lower address to upper address + write_memory_share(shatag, address + 0, halfsize, r0); + write_memory_share(shatag, address + halfsize, halfsize, r1); + } + + // only process if we're within range + else if (address < share->bytes()) + { + // lowmask specified which address bits are within the databus width + u32 lowmask = share->bytewidth() - 1; + u8 *base = reinterpret_cast<u8 *>(share->ptr()) + (address & ~lowmask); + + // if we have a valid base, set the appropriate byte + if (share->endianness() == ENDIANNESS_LITTLE) + { + base[BYTE8_XOR_LE(address) & lowmask] = data; + } + else + { + base[BYTE8_XOR_BE(address) & lowmask] = data; + } + notify_memory_modified(); + } + } +} + + +//------------------------------------------------- // memory_valid - return true if the given // memory name/space/offset combination is valid //------------------------------------------------- @@ -998,6 +1116,20 @@ expression_error::error_code symbol_table::memory_valid(const char *name, expres } break; + case EXPSPACE_SHARE: + if (!name) + { + return expression_error::MISSING_MEMORY_NAME; + } + else + { + auto search = get_device_search(m_machine, m_memintf, name); + memory_share *const share = search.first.memshare(search.second); + if (!share || !share->ptr()) + return expression_error::INVALID_MEMORY_NAME; + } + break; + default: return expression_error::NO_SUCH_MEMORY_SPACE; } @@ -1618,6 +1750,7 @@ void parsed_expression::parse_memory_operator(parse_token &token, const char *st case 'r': memspace = EXPSPACE_PRGDIRECT; break; case 'o': memspace = EXPSPACE_OPDIRECT; break; case 'm': memspace = EXPSPACE_REGION; break; + case 's': memspace = EXPSPACE_SHARE; break; default: throw expression_error(expression_error::INVALID_MEMORY_SPACE, token.offset() + (string - startstring)); } |
