summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/dvdisasm.cpp
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2017-07-05 11:44:49 +0200
committer Olivier Galibert <galibert@pobox.com>2017-11-26 17:41:27 +0100
commit6caef2579a1490f05d28bcede731cbdd45fc5c65 (patch)
tree8055384e183be3cb27e7d0894ac53dc96c09e6fa /src/emu/debug/dvdisasm.cpp
parent34b222062c89adbeed822f56be6130421777e11f (diff)
dvdisasm: Overhaul [O. Galibert]
Disassemblers are now independant classes. Not only the code is cleaner, but unidasm has access to all the cpu cores again. The interface to the disassembly method has changed from byte buffers to objects that give a result to read methods. This also adds support for lfsr and/or paged PCs.
Diffstat (limited to 'src/emu/debug/dvdisasm.cpp')
-rw-r--r--src/emu/debug/dvdisasm.cpp514
1 files changed, 186 insertions, 328 deletions
diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp
index 1051365c561..9ad6cb968c2 100644
--- a/src/emu/debug/dvdisasm.cpp
+++ b/src/emu/debug/dvdisasm.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Olivier Galibert
/*********************************************************************
dvdisasm.c
@@ -14,7 +14,6 @@
#include "debugcpu.h"
#include "debugger.h"
-
//**************************************************************************
// DEBUG VIEW DISASM SOURCE
//**************************************************************************
@@ -25,7 +24,6 @@
debug_view_disasm_source::debug_view_disasm_source(const char *name, device_t &device)
: debug_view_source(name, &device),
- m_disasmintf(dynamic_cast<device_disasm_interface *>(&device)),
m_space(device.memory().space(AS_PROGRAM)),
m_decrypted_space(device.memory().has_space(AS_OPCODES) ? device.memory().space(AS_OPCODES) : device.memory().space(AS_PROGRAM))
{
@@ -49,23 +47,17 @@ debug_view_disasm::debug_view_disasm(running_machine &machine, debug_view_osd_up
m_right_column(DASM_RIGHTCOL_RAW),
m_backwards_steps(3),
m_dasm_width(DEFAULT_DASM_WIDTH),
- m_last_direct_raw(nullptr),
- m_last_direct_decrypted(nullptr),
- m_last_change_count(0),
- m_last_pcbyte(0),
- m_divider1(0),
- m_divider2(0),
- m_divider3(0),
+ m_previous_pc(1),
m_expression(machine)
{
// fail if no available sources
enumerate_sources();
- if (m_source_list.count() == 0)
+ if(m_source_list.count() == 0)
throw std::bad_alloc();
// count the number of comments
int total_comments = 0;
- for (const debug_view_source &source : m_source_list)
+ for(const debug_view_source &source : m_source_list)
{
const debug_view_disasm_source &dasmsource = downcast<const debug_view_disasm_source &>(source);
total_comments += dasmsource.device()->debug()->comment_count();
@@ -98,10 +90,10 @@ void debug_view_disasm::enumerate_sources()
// iterate over devices with disassembly interfaces
std::string name;
- for (device_disasm_interface &dasm : disasm_interface_iterator(machine().root_device()))
+ for(device_disasm_interface &dasm : disasm_interface_iterator(machine().root_device()))
{
name = string_format("%s '%s'", dasm.device().name(), dasm.device().tag());
- if (dasm.device().memory().space_config(AS_PROGRAM)!=nullptr)
+ if(dasm.device().memory().space_config(AS_PROGRAM)!=nullptr)
m_source_list.append(*global_alloc(debug_view_disasm_source(name.c_str(), dasm.device())));
}
@@ -117,10 +109,10 @@ void debug_view_disasm::enumerate_sources()
void debug_view_disasm::view_notify(debug_view_notification type)
{
- if (type == VIEW_NOTIFY_CURSOR_CHANGED)
+ if(type == VIEW_NOTIFY_CURSOR_CHANGED)
adjust_visible_y_for_cursor();
- else if (type == VIEW_NOTIFY_SOURCE_CHANGED)
+ else if(type == VIEW_NOTIFY_SOURCE_CHANGED)
m_expression.set_context(&downcast<const debug_view_disasm_source *>(m_source)->device()->debug()->symtable());
}
@@ -136,29 +128,29 @@ void debug_view_disasm::view_char(int chval)
u8 end_buffer = 3;
s32 temp;
- switch (chval)
+ switch(chval)
{
case DCH_UP:
- if (m_cursor.y > 0)
+ if(m_cursor.y > 0)
m_cursor.y--;
break;
case DCH_DOWN:
- if (m_cursor.y < m_total.y - 1)
+ if(m_cursor.y < m_total.y - 1)
m_cursor.y++;
break;
case DCH_PUP:
- temp = m_cursor.y - (m_visible.y - end_buffer);
- if (temp < 0)
+ temp = m_cursor.y -(m_visible.y - end_buffer);
+ if(temp < 0)
m_cursor.y = 0;
else
m_cursor.y = temp;
break;
case DCH_PDOWN:
- temp = m_cursor.y + (m_visible.y - end_buffer);
- if (temp > m_total.y - 1)
+ temp = m_cursor.y +(m_visible.y - end_buffer);
+ if(temp > m_total.y - 1)
m_cursor.y = m_total.y - 1;
else
m_cursor.y = temp;
@@ -167,11 +159,11 @@ void debug_view_disasm::view_char(int chval)
case DCH_HOME: // set the active column to the PC
{
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
- offs_t pc = source.m_space.address_to_byte(source.device()->safe_pcbase()) & source.m_space.logbytemask();
+ offs_t pc = source.device()->safe_pcbase() & source.m_space.logaddrmask();
// figure out which row the pc is on
- for (unsigned int curline = 0; curline < m_dasm.size(); curline++)
- if (m_dasm[curline].m_byteaddress == pc)
+ for(unsigned int curline = 0; curline < m_dasm.size(); curline++)
+ if(m_dasm[curline].m_address == pc)
m_cursor.y = curline;
break;
}
@@ -186,7 +178,7 @@ void debug_view_disasm::view_char(int chval)
}
/* send a cursor changed notification */
- if (m_cursor.y != origcursor.y)
+ if(m_cursor.y != origcursor.y)
{
begin_update();
view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
@@ -208,7 +200,7 @@ void debug_view_disasm::view_click(const int button, const debug_view_xy& pos)
/* cursor popup|toggle */
bool cursorVisible = true;
- if (m_cursor.y == origcursor.y)
+ if(m_cursor.y == origcursor.y)
{
cursorVisible = !m_cursor_visible;
}
@@ -221,218 +213,174 @@ void debug_view_disasm::view_click(const int button, const debug_view_xy& pos)
end_update();
}
+void debug_view_disasm::generate_from_address(debug_disasm_buffer &buffer, offs_t address)
+{
+ m_dasm.clear();
+ for(int i=0; i != m_total.y; i++) {
+ std::string dasm;
+ offs_t size;
+ offs_t next_address;
+ u32 info;
+ buffer.disassemble(address, dasm, next_address, size, info);
+ m_dasm.emplace_back(address, size, dasm);
+ address = next_address;
+ }
+}
-//-------------------------------------------------
-// find_pc_backwards - back up the specified
-// number of instructions from the given PC
-//-------------------------------------------------
-
-offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs)
+bool debug_view_disasm::generate_with_pc(debug_disasm_buffer &buffer, offs_t pc)
{
- auto dis = machine().disable_side_effect();
+ // Consider that instructions are 64 bytes max
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
+ int shift = source.m_space.addrbus_shift();
- // compute the increment
- int minlen = source.m_space.byte_to_address(source.m_disasmintf->min_opcode_bytes());
- if (minlen == 0) minlen = 1;
- int maxlen = source.m_space.byte_to_address(source.m_disasmintf->max_opcode_bytes());
- if (maxlen == 0) maxlen = 1;
-
- // start off numinstrs back
- offs_t curpc = targetpc - minlen * numinstrs;
- if (curpc > targetpc)
- curpc = 0;
-
- /* loop until we find what we are looking for */
- offs_t targetpcbyte = source.m_space.address_to_byte(targetpc) & source.m_space.logbytemask();
- offs_t fillpcbyte = targetpcbyte;
- offs_t lastgoodpc = targetpc;
- while (1)
- {
- // fill the buffer up to the target
- offs_t curpcbyte = source.m_space.address_to_byte(curpc) & source.m_space.logbytemask();
- u8 opbuf[1024], argbuf[1024];
- while (curpcbyte < fillpcbyte)
- {
- fillpcbyte--;
- opbuf[1000 + fillpcbyte - targetpcbyte] = machine().debugger().cpu().read_opcode(source.m_decrypted_space, fillpcbyte, 1);
- argbuf[1000 + fillpcbyte - targetpcbyte] = machine().debugger().cpu().read_opcode(source.m_space, fillpcbyte, 1);
+ offs_t backwards_offset;
+ if(shift < 0)
+ backwards_offset = 64 >> -shift;
+ else if(shift == 0)
+ backwards_offset = 64;
+ else
+ backwards_offset = 64 << shift;
+
+ m_dasm.clear();
+ offs_t address = (pc - m_backwards_steps*backwards_offset) & source.m_space.logaddrmask();
+ // Handle wrap at 0
+ if(address > pc)
+ address = 0;
+
+ util::disasm_interface *intf = dynamic_cast<device_disasm_interface &>(*source.device()).get_disassembler();
+ if(intf->interface_flags() & util::disasm_interface::NONLINEAR_PC) {
+ offs_t lpc = intf->pc_real_to_linear(pc);
+ while(intf->pc_real_to_linear(address) < lpc) {
+ std::string dasm;
+ offs_t size;
+ offs_t next_address;
+ u32 info;
+ buffer.disassemble(address, dasm, next_address, size, info);
+ m_dasm.emplace_back(address, size, dasm);
+ if(intf->pc_real_to_linear(address) > intf->pc_real_to_linear(next_address))
+ return false;
+ address = next_address;
}
- // loop until we get past the target instruction
- int instcount = 0;
- int instlen;
- offs_t scanpc;
- for (scanpc = curpc; scanpc < targetpc; scanpc += instlen)
- {
- offs_t scanpcbyte = source.m_space.address_to_byte(scanpc) & source.m_space.logbytemask();
- offs_t physpcbyte = scanpcbyte;
-
- // get the disassembly, but only if mapped
- instlen = 1;
- if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH, physpcbyte))
- {
- std::ostringstream dasmbuffer;
- instlen = source.m_disasmintf->disassemble(dasmbuffer, scanpc, &opbuf[1000 + scanpcbyte - targetpcbyte], &argbuf[1000 + scanpcbyte - targetpcbyte]) & DASMFLAG_LENGTHMASK;
- }
-
- // count this one
- instcount++;
+ } else {
+ while(address < pc) {
+ std::string dasm;
+ offs_t size;
+ offs_t next_address;
+ u32 info;
+ buffer.disassemble(address, dasm, next_address, size, info);
+ m_dasm.emplace_back(address, size, dasm);
+ if(address > next_address)
+ return false;
+ address = next_address;
}
+ }
- // if we ended up right on targetpc, this is a good candidate
- if (scanpc == targetpc && instcount <= numinstrs)
- lastgoodpc = curpc;
-
- // we're also done if we go back too far
- if (targetpc - curpc >= numinstrs * maxlen)
- break;
+ if(address != pc)
+ return false;
- // and if we hit 0, we're done
- if (curpc == 0)
- break;
+ if(m_dasm.size() > m_backwards_steps)
+ m_dasm.erase(m_dasm.begin(), m_dasm.begin() + (m_dasm.size() - m_backwards_steps));
- // back up one more and try again
- curpc -= minlen;
- if (curpc > targetpc)
- curpc = 0;
+ while(m_dasm.size() < m_total.y) {
+ std::string dasm;
+ offs_t size;
+ offs_t next_address;
+ u32 info;
+ buffer.disassemble(address, dasm, next_address, size, info);
+ m_dasm.emplace_back(address, size, dasm);
+ address = next_address;
}
-
- return lastgoodpc;
+ return true;
}
-
-//-------------------------------------------------
-// generate_bytes - generate the opcode byte
-// values
-//-------------------------------------------------
-
-std::string debug_view_disasm::generate_bytes(offs_t pcbyte, int numbytes, int granularity, bool encrypted)
+int debug_view_disasm::address_position(offs_t pc) const
{
- const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
- const int char_num = source.m_space.is_octal() ? 3 : 2;
- std::ostringstream ostr;
-
- for (int byte = 0; byte < numbytes; byte += granularity) {
- if (byte)
- ostr << ' ';
- util::stream_format(ostr, source.m_space.is_octal() ? "%0*o" : "%0*X", granularity * char_num, machine().debugger().cpu().read_opcode(encrypted ? source.m_space : source.m_decrypted_space, pcbyte + byte, granularity));
- }
-
- return ostr.str();
+ for(int i=0; i != int(m_dasm.size()); i++)
+ if(m_dasm[i].m_address == pc)
+ return i;
+ return -1;
}
-
-//-------------------------------------------------
-// recompute - recompute selected info for the
-// disassembly view
-//-------------------------------------------------
-
-bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
+void debug_view_disasm::generate_dasm(debug_disasm_buffer &buffer, offs_t pc)
{
- auto dis = machine().disable_side_effect();
-
- bool changed = false;
- const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
- const int char_num = source.m_space.is_octal() ? 3 : 2;
-
- // determine how many characters we need for an address and set the divider
- m_divider1 = 1 + (source.m_space.logaddrchars()/2*char_num) + 1;
+ bool pc_changed = pc != m_previous_pc;
+ m_previous_pc = pc;
+ if(strcmp(m_expression.string(), "curpc")) {
+ if(m_expression.dirty()) {
+ m_topleft.x = 0;
+ m_topleft.y = 0;
+ }
+ generate_from_address(buffer, m_expression.value());
+ return;
+ }
- // assume a fixed number of characters for the disassembly
- m_divider2 = m_divider1 + 1 + m_dasm_width + 1;
+ if(address_position(pc) != -1) {
+ generate_from_address(buffer, m_dasm[0].m_address);
+ int pos = address_position(pc);
+ if(pos != -1) {
+ if(!pc_changed)
+ return;
+ if(pos >= m_topleft.y && pos < m_topleft.y + m_visible.y)
+ return;
+ if(pos < m_total.y - m_visible.y) {
+ m_topleft.x = 0;
+ m_topleft.y = pos - m_backwards_steps;
+ return;
+ }
+ }
+ }
- // determine how many bytes we might need to display
- const int minbytes = source.m_disasmintf->min_opcode_bytes();
- const int maxbytes = source.m_disasmintf->max_opcode_bytes();
+ m_topleft.x = 0;
+ m_topleft.y = 0;
- // ensure that the PC is aligned to the minimum opcode size
- pc &= ~source.m_space.byte_to_address_end(minbytes - 1);
+ if(generate_with_pc(buffer, pc))
+ return;
- // set the width of the third column according to display mode
- if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED)
- {
- int const maxbytes_clamped = (std::min)(maxbytes, DASM_MAX_BYTES);
- m_total.x = m_divider2 + 1 + char_num * maxbytes_clamped + (maxbytes_clamped / minbytes - 1) + 1;
- }
- else if (m_right_column == DASM_RIGHTCOL_COMMENTS)
- m_total.x = m_divider2 + 1 + 50; // DEBUG_COMMENT_MAX_LINE_LENGTH
- else
- m_total.x = m_divider2 + 1;
+ generate_from_address(buffer, pc);
+}
- // allocate dasm array
- m_dasm.resize(m_total.y);
+void debug_view_disasm::complete_information(const debug_view_disasm_source &source, debug_disasm_buffer &buffer, offs_t pc)
+{
+ for(auto &dasm : m_dasm) {
+ offs_t adr = dasm.m_address;
- // comparison buffer to detect whether data changed when doing only one line
- dasm_line comparison_buffer;
+ dasm.m_tadr = buffer.pc_to_string(adr);
+ dasm.m_topcodes = buffer.data_to_string(adr, dasm.m_size, true);
+ dasm.m_tparams = buffer.data_to_string(adr, dasm.m_size, false);
- // iterate over lines
- for (int line = 0; line < lines; line++)
- {
- // convert PC to a byte offset
- const offs_t pcbyte = source.m_space.address_to_byte(pc) & source.m_space.logbytemask();
-
- // save a copy of the previous line as a backup if we're only doing one line
- const auto instr = startline + line;
- if (lines == 1)
- comparison_buffer = m_dasm[instr];
-
- // convert back and set the address of this instruction
- std::ostringstream oadr;
- m_dasm[instr].m_byteaddress = pcbyte;
- util::stream_format(oadr,
- source.m_space.is_octal() ? " %0*o " : " %0*X ",
- source.m_space.logaddrchars()/2*char_num, source.m_space.byte_to_address(pcbyte));
- m_dasm[instr].m_adr = oadr.str();
-
- // make sure we can translate the address, and then disassemble the result
- std::ostringstream dasm;
- int numbytes = 0;
- offs_t physpcbyte = pcbyte;
- if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte))
- {
- u8 opbuf[64], argbuf[64];
+ dasm.m_is_pc = adr == pc;
- // fetch the bytes up to the maximum
- for (numbytes = 0; numbytes < maxbytes; numbytes++)
- {
- opbuf[numbytes] = machine().debugger().cpu().read_opcode(source.m_decrypted_space, pcbyte + numbytes, 1);
- argbuf[numbytes] = machine().debugger().cpu().read_opcode(source.m_space, pcbyte + numbytes, 1);
+ dasm.m_is_bp = false;
+ for(device_debug::breakpoint *bp = source.device()->debug()->breakpoint_first(); bp != nullptr; bp = bp->next())
+ if(adr ==(bp->address() & source.m_space.logaddrmask())) {
+ dasm.m_is_bp = true;
+ break;
}
- // disassemble the result
- pc += numbytes = source.m_disasmintf->disassemble(dasm, pc & source.m_space.logaddrmask(), opbuf, argbuf) & DASMFLAG_LENGTHMASK;
- }
- else
- dasm << "<unmapped>";
-
- m_dasm[instr].m_dasm = dasm.str();
+ dasm.m_is_visited = source.device()->debug()->track_pc_visited(adr);
- // generate the byte views
- std::ostringstream bytes_raw;
- numbytes = source.m_space.address_to_byte(numbytes) & source.m_space.logbytemask();
- m_dasm[instr].m_rawdata = generate_bytes(pcbyte, numbytes, minbytes, false);
- m_dasm[instr].m_encdata = generate_bytes(pcbyte, numbytes, minbytes, true);
+ const char *comment = source.device()->debug()->comment_text(adr);
+ if(comment)
+ dasm.m_comment = comment;
+ }
+}
- // get and add the comment, if present
- const offs_t comment_address = source.m_space.byte_to_address(m_dasm[instr].m_byteaddress);
- const char *const text = source.device()->debug()->comment_text(comment_address);
- if (text != nullptr)
- m_dasm[instr].m_comment = text;
+//-------------------------------------------------
+// view_update - update the contents of the
+// disassembly view
+//-------------------------------------------------
- // see if the line changed at all
- if (lines == 1 && m_dasm[instr] != comparison_buffer)
- changed = true;
- }
+void debug_view_disasm::view_update()
+{
+ const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
+ debug_disasm_buffer buffer(*source.device());
+ offs_t pc = source.device()->safe_pcbase() & source.m_space.logaddrmask();
- // update opcode base information
- m_last_direct_decrypted = source.m_decrypted_space.direct().ptr();
- m_last_direct_raw = source.m_space.direct().ptr();
- m_last_change_count = source.device()->debug()->comment_change_count();
+ generate_dasm(buffer, pc);
- // no longer need to recompute
- m_recompute = false;
- return changed;
+ complete_information(source, buffer, pc);
+ redraw();
}
@@ -443,11 +391,11 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
void debug_view_disasm::print(int row, std::string text, int start, int end, u8 attrib)
{
int view_end = end - m_topleft.x;
- if (view_end < 0)
+ if(view_end < 0)
return;
int string_0 = start - m_topleft.x;
- if (string_0 >= m_visible.x)
+ if(string_0 >= m_visible.x)
return;
int view_start = string_0 > 0 ? string_0 : 0;
@@ -458,152 +406,63 @@ void debug_view_disasm::print(int row, std::string text, int start, int end, u8
for(int pos = view_start; pos < view_end; pos++) {
int spos = pos - string_0;
- if (spos >= int(text.size()))
+ if(spos >= int(text.size()))
*dest++ = { ' ', attrib };
else
*dest++ = { u8(text[spos]), attrib };
- }
+ }
}
+
//-------------------------------------------------
-// view_update - update the contents of the
-// disassembly view
+// redraw - update the view from the data
//-------------------------------------------------
-void debug_view_disasm::view_update()
+void debug_view_disasm::redraw()
{
- const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
-
- offs_t pc = source.device()->safe_pcbase();
- offs_t pcbyte = source.m_space.address_to_byte(pc) & source.m_space.logbytemask();
-
- // update our context; if the expression is dirty, recompute
- if (m_expression.dirty())
- m_recompute = true;
-
- // if we're tracking a value, make sure it is visible
- u64 previous = m_expression.last_value();
- u64 result = m_expression.value();
- if (result != previous)
- {
- offs_t resultbyte = source.m_space.address_to_byte(result) & source.m_space.logbytemask();
-
- // see if the new result is an address we already have
- u32 row;
- for (row = 0; row < m_dasm.size(); row++)
- if (m_dasm[row].m_byteaddress == resultbyte)
- break;
-
- // if we didn't find it, or if it's really close to the bottom, recompute
- if (row == m_dasm.size() || row >= m_total.y - m_visible.y)
- m_recompute = true;
-
- // otherwise, if it's not visible, adjust the view so it is
- else if (row < m_topleft.y || row >= m_topleft.y + m_visible.y - 2)
- m_topleft.y = (row > 3) ? row - 3 : 0;
- }
-
- // if the opcode base has changed, rework things
- if (source.m_decrypted_space.direct().ptr() != m_last_direct_decrypted || source.m_space.direct().ptr() != m_last_direct_raw)
- m_recompute = true;
-
- // if the comments have changed, redo it
- if (m_last_change_count != source.device()->debug()->comment_change_count())
- m_recompute = true;
-
- // if we need to recompute, do it
- bool recomputed_this_time = false;
-recompute:
- if (m_recompute)
- {
- // recompute the view
- if (!m_dasm.empty() && m_last_change_count != source.device()->debug()->comment_change_count())
- {
- // smoosh us against the left column, but not the top row
- m_topleft.x = 0;
-
- // recompute from where we last recomputed!
- recompute(source.m_space.byte_to_address(m_dasm[0].m_byteaddress), 0, m_total.y);
- }
- else
- {
- // determine the addresses of what we will display
- offs_t backpc = find_pc_backwards(u32(m_expression.value()), m_backwards_steps);
-
- // put ourselves back in the top left
- m_topleft.y = 0;
- m_topleft.x = 0;
-
- recompute(backpc, 0, m_total.y);
- }
- recomputed_this_time = true;
- }
+ // determine how many characters we need for an address and set the divider
+ int m_divider1 = 1 + m_dasm[0].m_tadr.size() + 1;
- // figure out the row where the PC is and recompute the disassembly
- if (pcbyte != m_last_pcbyte)
- {
- // find the row with the PC on it
- for (u32 row = 0; row < m_visible.y; row++)
- {
- u32 effrow = m_topleft.y + row;
- if (effrow >= m_dasm.size())
- break;
- if (pcbyte == m_dasm[effrow].m_byteaddress)
- {
- // see if we changed
- bool changed = recompute(pc, effrow, 1);
- if (changed && !recomputed_this_time)
- {
- m_recompute = true;
- goto recompute;
- }
+ // assume a fixed number of characters for the disassembly
+ int m_divider2 = m_divider1 + 1 + m_dasm_width + 1;
- // set the effective row and PC
- m_cursor.y = effrow;
- view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
- }
- }
- m_last_pcbyte = pcbyte;
- }
+ // set the width of the third column to max comment length
+ m_total.x = m_divider2 + 1 + 50; // DEBUG_COMMENT_MAX_LINE_LENGTH
// loop over visible rows
- for (u32 row = 0; row < m_visible.y; row++)
+ for(u32 row = 0; row < m_visible.y; row++)
{
u32 effrow = m_topleft.y + row;
// if this visible row is valid, add it to the buffer
u8 attrib = DCA_NORMAL;
- if (effrow < m_dasm.size())
+ if(effrow < m_dasm.size())
{
- // if we're on the line with the PC, recompute and hilight it
- if (pcbyte == m_dasm[effrow].m_byteaddress)
+ // if we're on the line with the PC, hilight it
+ if(m_dasm[effrow].m_is_pc)
attrib = DCA_CURRENT;
// if we're on a line with a breakpoint, tag it changed
- else
- {
- for (device_debug::breakpoint *bp = source.device()->debug()->breakpoint_first(); bp != nullptr; bp = bp->next())
- if (m_dasm[effrow].m_byteaddress == (source.m_space.address_to_byte(bp->address()) & source.m_space.logbytemask()))
- attrib = DCA_CHANGED;
- }
+ else if(m_dasm[effrow].m_is_bp)
+ attrib = DCA_CHANGED;
// if we're on the active column and everything is couth, highlight it
- if (m_cursor_visible && effrow == m_cursor.y)
+ if(m_cursor_visible && effrow == m_cursor.y)
attrib |= DCA_SELECTED;
// if we've visited this pc, mark it as such
- if (source.device()->debug()->track_pc_visited(m_dasm[effrow].m_byteaddress))
+ if(m_dasm[effrow].m_is_visited)
attrib |= DCA_VISITED;
- print(row, m_dasm[effrow].m_adr, 0, m_divider1, attrib | DCA_ANCILLARY);
+ print(row, ' ' + m_dasm[effrow].m_tadr, 0, m_divider1, attrib | DCA_ANCILLARY);
print(row, ' ' + m_dasm[effrow].m_dasm, m_divider1, m_divider2, attrib);
- if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED) {
- std::string text = ' ' + (m_right_column == DASM_RIGHTCOL_RAW ? m_dasm[effrow].m_rawdata : m_dasm[effrow].m_encdata);
+ if(m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED) {
+ std::string text = ' ' +(m_right_column == DASM_RIGHTCOL_RAW ? m_dasm[effrow].m_topcodes : m_dasm[effrow].m_tparams);
print(row, text, m_divider2, m_visible.x, attrib | DCA_ANCILLARY);
if(int(text.size()) > m_visible.x - m_divider2) {
int base = m_total.x - 3;
- if (base < m_divider2)
+ if(base < m_divider2)
base = m_divider2;
print(row, "...", base, m_visible.x, attrib | DCA_ANCILLARY);
}
@@ -624,7 +483,7 @@ recompute:
offs_t debug_view_disasm::selected_address()
{
flush_updates();
- return downcast<const debug_view_disasm_source &>(*m_source).m_space.byte_to_address(m_dasm[m_cursor.y].m_byteaddress);
+ return m_dasm[m_cursor.y].m_address;
}
@@ -679,7 +538,7 @@ void debug_view_disasm::set_disasm_width(u32 width)
{
begin_update();
m_dasm_width = width;
- m_recompute = m_update_pending = true;
+ m_update_pending = true;
end_update();
}
@@ -692,10 +551,9 @@ void debug_view_disasm::set_disasm_width(u32 width)
void debug_view_disasm::set_selected_address(offs_t address)
{
const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
- offs_t byteaddress = source.m_space.address_to_byte(address) & source.m_space.logbytemask();
- for (int line = 0; line < m_total.y; line++)
- if (m_dasm[line].m_byteaddress == byteaddress)
- {
+ address = address & source.m_space.logaddrmask();
+ for(int line = 0; line < m_total.y; line++)
+ if(m_dasm[line].m_address == address) {
m_cursor.y = line;
set_cursor_position(m_cursor);
break;