Beispiel #1
0
void debug_view::set_source(const debug_view_source &source)
{
	if (&source != m_source)
	{
		begin_update();
		m_source = &source;
		m_update_pending = true;
		view_notify(VIEW_NOTIFY_SOURCE_CHANGED);
		end_update();
	}
}
Beispiel #2
0
void debug_view::set_cursor_visible(bool visible)
{
	if (visible != m_cursor_visible)
	{
		begin_update();
		m_cursor_visible = visible;
		m_update_pending = true;
		view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
		end_update();
	}
}
Beispiel #3
0
void debug_view::set_cursor_position(debug_view_xy pos)
{
	if (pos.x != m_cursor.x || pos.y != m_cursor.y)
	{
		begin_update();
		m_cursor = pos;
		m_update_pending = true;
		view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
		end_update();
	}
}
Beispiel #4
0
void debug_view::set_visible_position(debug_view_xy pos)
{
	if (pos.x != m_topleft.x || pos.y != m_topleft.y)
	{
		begin_update();
		m_topleft = pos;
		m_update_pending = true;
		view_notify(VIEW_NOTIFY_VISIBLE_CHANGED);
		end_update();
	}
}
Beispiel #5
0
void debug_view::set_visible_size(debug_view_xy size)
{
	if (size.x != m_visible.x || size.y != m_visible.y)
	{
		begin_update();
		m_visible = size;
		m_update_pending = true;
		view_notify(VIEW_NOTIFY_VISIBLE_CHANGED);
		end_update();
	}
}
Beispiel #6
0
void debug_view_disasm::view_click(const int button, const debug_view_xy& pos)
{
	const debug_view_xy origcursor = m_cursor;
	m_cursor = pos;

	/* cursor popup|toggle */
	bool cursorVisible = true;
	if (m_cursor.y == origcursor.y)
	{
		cursorVisible = !m_cursor_visible;
	}

	/* send a cursor changed notification */
	begin_update();
	m_cursor_visible = cursorVisible;
	view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
	m_update_pending = true;
	end_update();
}
Beispiel #7
0
void debug_view_disasm::view_update()
{
	const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);

	offs_t pc = source.m_device.safe_pc();
	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
	UINT64 previous = m_expression.last_value();
	UINT64 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
		UINT32 row;
		for (row = 0; row < m_byteaddress.size(); row++)
			if (m_byteaddress[row] == resultbyte)
				break;

		// if we didn't find it, or if it's really close to the bottom, recompute
		if (row == m_byteaddress.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.m_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_byteaddress.empty() && m_last_change_count != source.m_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_byteaddress[0]), 0, m_total.y);
		}
		else
		{
			// determine the addresses of what we will display
			offs_t backpc = find_pc_backwards((UINT32)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;
	}

	// 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 (UINT32 row = 0; row < m_visible.y; row++)
		{
			UINT32 effrow = m_topleft.y + row;
			if (effrow >= m_byteaddress.size())
				break;
			if (pcbyte == m_byteaddress[effrow])
			{
				// see if we changed
				bool changed = recompute(pc, effrow, 1);
				if (changed && !recomputed_this_time)
				{
					m_recompute = true;
					goto recompute;
				}

				// set the effective row and PC
				m_cursor.y = effrow;
				view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
			}
		}
		m_last_pcbyte = pcbyte;
	}

	// loop over visible rows
	debug_view_char *dest = &m_viewdata[0];
	int row_width = m_dasm.size() / m_byteaddress.size();
	for (UINT32 row = 0; row < m_visible.y; row++)
	{
		UINT32 effrow = m_topleft.y + row;
		UINT32 col = 0;

		// if this visible row is valid, add it to the buffer
		UINT8 attrib = DCA_NORMAL;
		if (effrow < m_byteaddress.size())
		{
			// if we're on the line with the PC, recompute and hilight it
			if (pcbyte == m_byteaddress[effrow])
				attrib = DCA_CURRENT;

			// if we're on a line with a breakpoint, tag it changed
			else
			{
				for (device_debug::breakpoint *bp = source.m_device.debug()->breakpoint_first(); bp != NULL; bp = bp->next())
					if (m_byteaddress[effrow] == (source.m_space.address_to_byte(bp->address()) & source.m_space.logbytemask()))
						attrib = DCA_CHANGED;
			}

			// if we're on the active column and everything is couth, highlight it
			if (m_cursor_visible && effrow == m_cursor.y)
				attrib |= DCA_SELECTED;

			// if we've visited this pc, mark it as such
			if (source.m_device.debug()->track_pc_visited(m_byteaddress[effrow]))
				attrib |= DCA_VISITED;

			// get the effective string
			const char *data = &m_dasm[effrow * row_width];
			UINT32 len = (UINT32)strlen(data);

			// copy data
			UINT32 effcol = m_topleft.x;
			while (col < m_visible.x && effcol < len)
			{
				dest->byte = data[effcol++];
				dest->attrib = (effcol <= m_divider1 || effcol >= m_divider2) ? (attrib | DCA_ANCILLARY) : attrib;

				// comments are just green for now - maybe they shouldn't even be this?
				if (effcol >= m_divider2 && m_right_column == DASM_RIGHTCOL_COMMENTS)
					attrib |= DCA_COMMENT;

				dest++;
				col++;
			}
		}

		// fill the rest with blanks
		while (col < m_visible.x)
		{
			dest->byte = ' ';
			dest->attrib = (effrow < m_total.y) ? (attrib | DCA_ANCILLARY) : attrib;
			dest++;
			col++;
		}
	}
}
Beispiel #8
0
void debug_view_disasm::view_char(int chval)
{
	debug_view_xy origcursor = m_cursor;
	UINT8 end_buffer = 3;
	INT32 temp;

	switch (chval)
	{
		case DCH_UP:
			if (m_cursor.y > 0)
				m_cursor.y--;
			break;

		case DCH_DOWN:
			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)
				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)
				m_cursor.y = m_total.y - 1;
			else
				m_cursor.y = temp;
			break;

		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.m_device.safe_pc()) & source.m_space.logbytemask();

			// figure out which row the pc is on
			for (unsigned int curline = 0; curline < m_byteaddress.size(); curline++)
				if (m_byteaddress[curline] == pc)
					m_cursor.y = curline;
			break;
		}

		case DCH_CTRLHOME:
			m_cursor.y = 0;
			break;

		case DCH_CTRLEND:
			m_cursor.y = m_total.y - 1;
			break;
	}

	/* send a cursor changed notification */
	if (m_cursor.y != origcursor.y)
	{
		begin_update();
		view_notify(VIEW_NOTIFY_CURSOR_CHANGED);
		m_update_pending = true;
		end_update();
	}
}