summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/debugcpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/debugcpu.cpp')
-rw-r--r--src/emu/debug/debugcpu.cpp471
1 files changed, 39 insertions, 432 deletions
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 46ad9e04683..e6f65b7d0c9 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -47,6 +47,9 @@ debugger_cpu::debugger_cpu(running_machine &machine)
, m_visiblecpu(nullptr)
, m_breakcpu(nullptr)
, m_symtable(nullptr)
+ , m_within_instruction_hook(false)
+ , m_vblank_occurred(false)
+ , m_memory_modified(false)
, m_execution_state(EXECUTION_STATE_STOPPED)
, m_bpindex(1)
, m_wpindex(1)
@@ -350,408 +353,6 @@ bool debugger_cpu::comment_load(bool is_inline)
/***************************************************************************
- DEBUGGER MEMORY ACCESSORS
-***************************************************************************/
-
-/*-------------------------------------------------
- read_byte - return a byte from the specified
- memory space
--------------------------------------------------*/
-
-u8 debugger_cpu::read_byte(address_space &space, offs_t address, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- /* translate if necessary; if not mapped, return 0xff */
- u8 result;
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- {
- result = 0xff;
- }
- else
- { /* otherwise, call the byte reading function for the translated address */
- result = space.read_byte(address);
- }
-
- return result;
-}
-
-
-/*-------------------------------------------------
- read_word - return a word from the specified
- memory space
--------------------------------------------------*/
-
-u16 debugger_cpu::read_word(address_space &space, offs_t address, bool apply_translation)
-{
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- u16 result;
- if (!WORD_ALIGNED(address))
- { /* if this is misaligned read, or if there are no word readers, just read two bytes */
- u8 byte0 = read_byte(space, address + 0, apply_translation);
- u8 byte1 = read_byte(space, address + 1, apply_translation);
-
- /* based on the endianness, the result is assembled differently */
- if (space.endianness() == ENDIANNESS_LITTLE)
- result = byte0 | (byte1 << 8);
- else
- result = byte1 | (byte0 << 8);
- }
- else
- { /* otherwise, this proceeds like the byte case */
- device_memory_interface &memory = space.device().memory();
-
- /* translate if necessary; if not mapped, return 0xffff */
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- {
- result = 0xffff;
- }
- else
- { /* otherwise, call the byte reading function for the translated address */
- result = space.read_word(address);
- }
- }
-
- return result;
-}
-
-
-/*-------------------------------------------------
- read_dword - return a dword from the specified
- memory space
--------------------------------------------------*/
-
-u32 debugger_cpu::read_dword(address_space &space, offs_t address, bool apply_translation)
-{
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- u32 result;
- if (!DWORD_ALIGNED(address))
- { /* if this is a misaligned read, or if there are no dword readers, just read two words */
- u16 word0 = read_word(space, address + 0, apply_translation);
- u16 word1 = read_word(space, address + 2, apply_translation);
-
- /* based on the endianness, the result is assembled differently */
- if (space.endianness() == ENDIANNESS_LITTLE)
- result = word0 | (word1 << 16);
- else
- result = word1 | (word0 << 16);
- }
- else
- { /* otherwise, this proceeds like the byte case */
- device_memory_interface &memory = space.device().memory();
-
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- { /* translate if necessary; if not mapped, return 0xffffffff */
- result = 0xffffffff;
- }
- else
- { /* otherwise, call the byte reading function for the translated address */
- result = space.read_dword(address);
- }
- }
-
- return result;
-}
-
-
-/*-------------------------------------------------
- read_qword - return a qword from the specified
- memory space
--------------------------------------------------*/
-
-u64 debugger_cpu::read_qword(address_space &space, offs_t address, bool apply_translation)
-{
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- u64 result;
- if (!QWORD_ALIGNED(address))
- { /* if this is a misaligned read, or if there are no qword readers, just read two dwords */
- u32 dword0 = read_dword(space, address + 0, apply_translation);
- u32 dword1 = read_dword(space, address + 4, apply_translation);
-
- /* based on the endianness, the result is assembled differently */
- if (space.endianness() == ENDIANNESS_LITTLE)
- result = dword0 | (u64(dword1) << 32);
- else
- result = dword1 | (u64(dword0) << 32);
- }
- else
- { /* otherwise, this proceeds like the byte case */
- device_memory_interface &memory = space.device().memory();
-
- /* translate if necessary; if not mapped, return 0xffffffffffffffff */
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_READ_DEBUG, address))
- {
- result = ~u64(0);
- }
- else
- { /* otherwise, call the byte reading function for the translated address */
- result = space.read_qword(address);
- }
- }
-
- return result;
-}
-
-
-/*-------------------------------------------------
- read_memory - return 1,2,4 or 8 bytes
- from the specified memory space
--------------------------------------------------*/
-
-u64 debugger_cpu::read_memory(address_space &space, offs_t address, int size, bool apply_translation)
-{
- u64 result = ~u64(0) >> (64 - 8*size);
- switch (size)
- {
- case 1: result = read_byte(space, address, apply_translation); break;
- case 2: result = read_word(space, address, apply_translation); break;
- case 4: result = read_dword(space, address, apply_translation); break;
- case 8: result = read_qword(space, address, apply_translation); break;
- }
- return result;
-}
-
-
-/*-------------------------------------------------
- write_byte - write a byte to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_byte(address_space &space, offs_t address, u8 data, bool apply_translation)
-{
- device_memory_interface &memory = space.device().memory();
-
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- /* translate if necessary; if not mapped, we're done */
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- ;
-
- /* otherwise, call the byte reading function for the translated address */
- else
- space.write_byte(address, data);
-
- m_memory_modified = true;
-}
-
-
-/*-------------------------------------------------
- write_word - write a word to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_word(address_space &space, offs_t address, u16 data, bool apply_translation)
-{
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- /* if this is a misaligned write, or if there are no word writers, just read two bytes */
- if (!WORD_ALIGNED(address))
- {
- if (space.endianness() == ENDIANNESS_LITTLE)
- {
- write_byte(space, address + 0, data >> 0, apply_translation);
- write_byte(space, address + 1, data >> 8, apply_translation);
- }
- else
- {
- write_byte(space, address + 0, data >> 8, apply_translation);
- write_byte(space, address + 1, data >> 0, apply_translation);
- }
- }
-
- /* otherwise, this proceeds like the byte case */
- else
- {
- device_memory_interface &memory = space.device().memory();
-
- /* translate if necessary; if not mapped, we're done */
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- ;
-
- /* otherwise, call the byte reading function for the translated address */
- else
- space.write_word(address, data);
-
- m_memory_modified = true;
- }
-}
-
-
-/*-------------------------------------------------
- write_dword - write a dword to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_dword(address_space &space, offs_t address, u32 data, bool apply_translation)
-{
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- /* if this is a misaligned write, or if there are no dword writers, just read two words */
- if (!DWORD_ALIGNED(address))
- {
- if (space.endianness() == ENDIANNESS_LITTLE)
- {
- write_word(space, address + 0, data >> 0, apply_translation);
- write_word(space, address + 2, data >> 16, apply_translation);
- }
- else
- {
- write_word(space, address + 0, data >> 16, apply_translation);
- write_word(space, address + 2, data >> 0, apply_translation);
- }
- }
-
- /* otherwise, this proceeds like the byte case */
- else
- {
- device_memory_interface &memory = space.device().memory();
-
- /* translate if necessary; if not mapped, we're done */
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- ;
-
- /* otherwise, call the byte reading function for the translated address */
- else
- space.write_dword(address, data);
-
- m_memory_modified = true;
- }
-}
-
-
-/*-------------------------------------------------
- write_qword - write a qword to the specified
- memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_qword(address_space &space, offs_t address, u64 data, bool apply_translation)
-{
- /* mask against the logical byte mask */
- address &= space.logbytemask();
-
- /* if this is a misaligned write, or if there are no qword writers, just read two dwords */
- if (!QWORD_ALIGNED(address))
- {
- if (space.endianness() == ENDIANNESS_LITTLE)
- {
- write_dword(space, address + 0, data >> 0, apply_translation);
- write_dword(space, address + 4, data >> 32, apply_translation);
- }
- else
- {
- write_dword(space, address + 0, data >> 32, apply_translation);
- write_dword(space, address + 4, data >> 0, apply_translation);
- }
- }
-
- /* otherwise, this proceeds like the byte case */
- else
- {
- device_memory_interface &memory = space.device().memory();
-
- /* translate if necessary; if not mapped, we're done */
- if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address))
- ;
-
- /* otherwise, call the byte reading function for the translated address */
- else
- space.write_qword(address, data);
-
- m_memory_modified = true;
- }
-}
-
-
-/*-------------------------------------------------
- write_memory - write 1,2,4 or 8 bytes to the
- specified memory space
--------------------------------------------------*/
-
-void debugger_cpu::write_memory(address_space &space, offs_t address, u64 data, int size, bool apply_translation)
-{
- switch (size)
- {
- case 1: write_byte(space, address, data, apply_translation); break;
- case 2: write_word(space, address, data, apply_translation); break;
- case 4: write_dword(space, address, data, apply_translation); break;
- case 8: write_qword(space, address, data, apply_translation); break;
- }
-}
-
-
-/*-------------------------------------------------
- read_opcode - read 1,2,4 or 8 bytes at the
- given offset from opcode space
--------------------------------------------------*/
-
-u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size)
-{
- device_memory_interface &memory = space.device().memory();
-
- u64 result = ~u64(0) & (~u64(0) >> (64 - 8*size));
-
- /* keep in logical range */
- address &= space.logbytemask();
-
- /* if we're bigger than the address bus, break into smaller pieces */
- if (size > space.data_width() / 8)
- {
- int halfsize = size / 2;
- u64 r0 = read_opcode(space, address + 0, halfsize);
- u64 r1 = read_opcode(space, address + halfsize, halfsize);
-
- if (space.endianness() == ENDIANNESS_LITTLE)
- return r0 | (r1 << (8 * halfsize));
- else
- return r1 | (r0 << (8 * halfsize));
- }
-
- /* translate to physical first */
- if (!memory.translate(space.spacenum(), TRANSLATE_FETCH_DEBUG, address))
- return result;
-
- /* keep in physical range */
- address &= space.bytemask();
-
- /* switch off the size and handle unaligned accesses */
- switch (size)
- {
- case 1:
- result = space.read_byte(address);
- break;
-
- case 2:
- result = space.read_word_unaligned(address);
- break;
-
- case 4:
- result = space.read_dword_unaligned(address);
- break;
-
- case 6:
- case 8:
- result = space.read_qword_unaligned(address);
- break;
- }
-
- return result;
-}
-
-
-
-/***************************************************************************
INTERNAL HELPERS
***************************************************************************/
@@ -842,9 +443,9 @@ device_t* debugger_cpu::expression_get_device(const char *tag)
space
-------------------------------------------------*/
-u64 debugger_cpu::expression_read_memory(void *param, const char *name, expression_space spacenum, u32 address, int size, bool disable_se)
+u64 debugger_cpu::expression_read_memory(void *param, const char *name, expression_space space, u32 address, int size, bool disable_se)
{
- switch (spacenum)
+ switch (space)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
@@ -861,11 +462,11 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi
device = get_visible_cpu();
memory = &device->memory();
}
- if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
+ int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL);
+ if (memory->has_space(spacenum))
{
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
auto dis = m_machine.disable_side_effect(disable_se);
- return read_memory(space, space.address_to_byte(address), size, true);
+ return memory->read_memory(spacenum, memory->space(spacenum).address_to_byte(address), size, TRANSLATE_READ_DEBUG);
}
break;
}
@@ -885,11 +486,11 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi
device = get_visible_cpu();
memory = &device->memory();
}
- if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
+ int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL);
+ if (memory->has_space(spacenum))
{
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
auto dis = m_machine.disable_side_effect(disable_se);
- return read_memory(space, space.address_to_byte(address), size, false);
+ return memory->read_memory(spacenum, memory->space(spacenum).address_to_byte(address), size, TRANSLATE_NONE);
}
break;
}
@@ -907,7 +508,7 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi
memory = &device->memory();
}
auto dis = m_machine.disable_side_effect(disable_se);
- return expression_read_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size);
+ return expression_read_program_direct(memory->space(AS_PROGRAM), (space == EXPSPACE_OPCODE), address, size);
break;
}
@@ -924,7 +525,7 @@ u64 debugger_cpu::expression_read_memory(void *param, const char *name, expressi
memory = &device->memory();
}
auto dis = m_machine.disable_side_effect(disable_se);
- return expression_read_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size);
+ return expression_read_program_direct(memory->space(AS_OPCODES), (space == EXPSPACE_OPCODE), address, size);
break;
}
@@ -1048,17 +649,18 @@ u64 debugger_cpu::expression_read_memory_region(const char *rgntag, offs_t addre
space
-------------------------------------------------*/
-void debugger_cpu::expression_write_memory(void *param, const char *name, expression_space spacenum, u32 address, int size, u64 data, bool disable_se)
+void debugger_cpu::expression_write_memory(void *param, const char *name, expression_space space, u32 address, int size, u64 data, bool disable_se)
{
device_t *device = nullptr;
device_memory_interface *memory;
- switch (spacenum)
+ switch (space)
{
case EXPSPACE_PROGRAM_LOGICAL:
case EXPSPACE_DATA_LOGICAL:
case EXPSPACE_IO_LOGICAL:
case EXPSPACE_SPACE3_LOGICAL:
+ {
if (name != nullptr)
device = expression_get_device(name);
if (device == nullptr || !device->interface(memory))
@@ -1066,18 +668,20 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres
device = get_visible_cpu();
memory = &device->memory();
}
- if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL)))
+ int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_LOGICAL);
+ if (memory->has_space(spacenum))
{
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_LOGICAL));
auto dis = m_machine.disable_side_effect(disable_se);
- write_memory(space, space.address_to_byte(address), data, size, true);
+ memory->write_memory(spacenum, memory->space(spacenum).address_to_byte(address), data, size, TRANSLATE_WRITE_DEBUG);
}
break;
+ }
case EXPSPACE_PROGRAM_PHYSICAL:
case EXPSPACE_DATA_PHYSICAL:
case EXPSPACE_IO_PHYSICAL:
case EXPSPACE_SPACE3_PHYSICAL:
+ {
if (name != nullptr)
device = expression_get_device(name);
if (device == nullptr || !device->interface(memory))
@@ -1085,15 +689,17 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres
device = get_visible_cpu();
memory = &device->memory();
}
- if (memory->has_space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL)))
+ int spacenum = AS_PROGRAM + (space - EXPSPACE_PROGRAM_PHYSICAL);
+ if (memory->has_space(spacenum))
{
- address_space &space = memory->space(AS_PROGRAM + (spacenum - EXPSPACE_PROGRAM_PHYSICAL));
auto dis = m_machine.disable_side_effect(disable_se);
- write_memory(space, space.address_to_byte(address), data, size, false);
+ memory->write_memory(spacenum, memory->space(spacenum).address_to_byte(address), data, size, TRANSLATE_NONE);
}
break;
+ }
- case EXPSPACE_RAMWRITE: {
+ case EXPSPACE_RAMWRITE:
+ {
if (name != nullptr)
device = expression_get_device(name);
if (device == nullptr || !device->interface(memory))
@@ -1102,11 +708,12 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres
memory = &device->memory();
}
auto dis = m_machine.disable_side_effect(disable_se);
- expression_write_program_direct(memory->space(AS_PROGRAM), (spacenum == EXPSPACE_OPCODE), address, size, data);
+ expression_write_program_direct(memory->space(AS_PROGRAM), (space == EXPSPACE_OPCODE), address, size, data);
break;
}
- case EXPSPACE_OPCODE: {
+ case EXPSPACE_OPCODE:
+ {
if (name != nullptr)
device = expression_get_device(name);
if (device == nullptr || !device->interface(memory))
@@ -1115,7 +722,7 @@ void debugger_cpu::expression_write_memory(void *param, const char *name, expres
memory = &device->memory();
}
auto dis = m_machine.disable_side_effect(disable_se);
- expression_write_program_direct(memory->space(AS_OPCODES), (spacenum == EXPSPACE_OPCODE), address, size, data);
+ expression_write_program_direct(memory->space(AS_OPCODES), (space == EXPSPACE_OPCODE), address, size, data);
break;
}
@@ -1182,7 +789,7 @@ void debugger_cpu::expression_write_program_direct(address_space &space, int opc
base[BYTE8_XOR_LE(address) & lowmask] = data;
else
base[BYTE8_XOR_BE(address) & lowmask] = data;
- m_memory_modified = true;
+ set_memory_modified(true);
}
}
}
@@ -1240,7 +847,7 @@ void debugger_cpu::expression_write_memory_region(const char *rgntag, offs_t add
{
base[BYTE8_XOR_BE(address) & lowmask] = data;
}
- m_memory_modified = true;
+ set_memory_modified(true);
}
}
}
@@ -2487,7 +2094,7 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const
assert(m_memory != nullptr);
// determine the adjusted PC
- address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM);
+ int opcode_spacenum = m_memory->has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM;
address_space &space = m_memory->space(AS_PROGRAM);
offs_t pcbyte = space.address_to_byte(pc) & space.bytemask();
@@ -2496,8 +2103,8 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const
int maxbytes = (m_disasm != nullptr) ? m_disasm->max_opcode_bytes() : 1;
for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1);
+ opbuf[numbytes] = m_memory->read_opcode(opcode_spacenum, pcbyte + numbytes, 1);
+ argbuf[numbytes] = m_memory->read_opcode(AS_PROGRAM, pcbyte + numbytes, 1);
}
u32 numbytes = maxbytes;
@@ -2891,7 +2498,7 @@ u32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc)
assert(m_memory != nullptr && m_disasm != nullptr);
// determine the adjusted PC
- address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM);
+ int opcode_spacenum = m_memory->has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM;
address_space &space = m_memory->space(AS_PROGRAM);
offs_t pcbyte = space.address_to_byte(pc) & space.bytemask();
@@ -2900,8 +2507,8 @@ u32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc)
int maxbytes = m_disasm->max_opcode_bytes();
for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1);
+ opbuf[numbytes] = m_memory->read_opcode(opcode_spacenum, pcbyte + numbytes, 1);
+ argbuf[numbytes] = m_memory->read_opcode(AS_PROGRAM, pcbyte + numbytes, 1);
}
// disassemble to our buffer