예제 #1
0
파일: dvdisasm.c 프로젝트: dinkc64/mame
bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
{
	bool changed = false;
	const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source);
	int char_num =  source.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;

	// assume a fixed number of characters for the disassembly
	m_divider2 = m_divider1 + 1 + m_dasm_width + 1;

	// determine how many bytes we might need to display
	int minbytes = source.m_disasmintf->min_opcode_bytes();
	int maxbytes = source.m_disasmintf->max_opcode_bytes();

	// ensure that the PC is aligned to the minimum opcode size
	pc &= ~source.m_space.byte_to_address_end(minbytes - 1);

	// 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 maxbytes_clamped = 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;

	// allocate address array
	m_byteaddress.resize(m_total.y);

	// allocate disassembly buffer
	m_dasm.resize(m_total.x * m_total.y);

	// iterate over lines
	int row_width = m_total.x;
	for (int line = 0; line < lines; line++)
	{
		// convert PC to a byte offset
		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
		int instr = startline + line;
		char *destbuf = &m_dasm[instr * row_width];
		char oldbuf[100];
		if (lines == 1)
			strncpy(oldbuf, destbuf, MIN(sizeof(oldbuf), row_width));

		// convert back and set the address of this instruction
		m_byteaddress[instr] = pcbyte;
		sprintf(&destbuf[0], " %s  ", core_i64_format(source.m_space.byte_to_address(pcbyte), source.m_space.logaddrchars()/2*char_num, source.is_octal()));

		// make sure we can translate the address, and then disassemble the result
		char buffer[100];
		int numbytes = 0;
		offs_t physpcbyte = pcbyte;
		if (debug_cpu_translate(source.m_space, TRANSLATE_FETCH_DEBUG, &physpcbyte))
		{
			UINT8 opbuf[64], argbuf[64];

			// fetch the bytes up to the maximum
			for (numbytes = 0; numbytes < maxbytes; numbytes++)
			{
				opbuf[numbytes] = debug_read_opcode(source.m_decrypted_space, pcbyte + numbytes, 1);
				argbuf[numbytes] = debug_read_opcode(source.m_space, pcbyte + numbytes, 1);
			}

			// disassemble the result
			pc += numbytes = source.m_device.debug()->disassemble(buffer, pc & source.m_space.logaddrmask(), opbuf, argbuf) & DASMFLAG_LENGTHMASK;
		}
		else
			strcpy(buffer, "<unmapped>");

		// append the disassembly to the buffer
		sprintf(&destbuf[m_divider1 + 1], "%-*s  ", m_dasm_width, buffer);

		// output the right column
		if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED)
		{
			// get the bytes
			numbytes = source.m_space.address_to_byte(numbytes) & source.m_space.logbytemask();
			generate_bytes(pcbyte, numbytes, minbytes, &destbuf[m_divider2], row_width - m_divider2, m_right_column == DASM_RIGHTCOL_ENCRYPTED);
		}
		else if (m_right_column == DASM_RIGHTCOL_COMMENTS)
		{
			// get and add the comment, if present
			offs_t comment_address = source.m_space.byte_to_address(m_byteaddress[instr]);
			const char *text = source.m_device.debug()->comment_text(comment_address);
			if (text != NULL)
				sprintf(&destbuf[m_divider2], "// %.*s", row_width - m_divider2 - 4, text);
		}

		// see if the line changed at all
		if (lines == 1 && strncmp(oldbuf, destbuf, MIN(sizeof(oldbuf), row_width)) != 0)
			changed = true;
	}

	// 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.m_device.debug()->comment_change_count();

	// no longer need to recompute
	m_recompute = false;
	return changed;
}
예제 #2
0
파일: dvdisasm.cpp 프로젝트: RalfVB/mame
bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
{
	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;

	// assume a fixed number of characters for the disassembly
	m_divider2 = m_divider1 + 1 + m_dasm_width + 1;

	// 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();

	// ensure that the PC is aligned to the minimum opcode size
	pc &= ~source.m_space.byte_to_address_end(minbytes - 1);

	// 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;

	// allocate address array
	m_byteaddress.resize(m_total.y);

	// allocate disassembly buffer
	const auto total_bytes = m_total.x * m_total.y;
	m_dasm.clear();
	m_dasm.reserve(total_bytes).seekp(total_bytes);

	// 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;
		const auto base = instr * m_total.x;
		char oldbuf[100];
		if (lines == 1)
			std::memcpy(oldbuf, &m_dasm.vec()[base], (std::min<std::size_t>)(sizeof(oldbuf), m_total.x));

		// convert back and set the address of this instruction
		m_byteaddress[instr] = pcbyte;
		m_dasm.clear();
		util::stream_format(m_dasm.seekp(base),
			source.m_space.is_octal() ? " %0*o  " : " %0*X  ",
			source.m_space.logaddrchars()/2*char_num, source.m_space.byte_to_address(pcbyte));

		// make sure we can translate the address, and then disassemble the result
		char buffer[100];
		int numbytes = 0;
		offs_t physpcbyte = pcbyte;
		if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte))
		{
			UINT8 opbuf[64], argbuf[64];

			// 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);
			}

			// disassemble the result
			pc += numbytes = source.m_disasmintf->disassemble(buffer, pc & source.m_space.logaddrmask(), opbuf, argbuf) & DASMFLAG_LENGTHMASK;
		}
		else
			strcpy(buffer, "<unmapped>");

		// append the disassembly to the buffer
		util::stream_format(m_dasm.seekp(base + m_divider1 + 1), "%2$-*1$.*1$s  ", m_dasm_width, buffer);

		// output the right column
		if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED)
		{
			// get the bytes
			numbytes = source.m_space.address_to_byte(numbytes) & source.m_space.logbytemask();
			m_dasm.seekp(base + m_divider2);
			generate_bytes(pcbyte, numbytes, minbytes, m_total.x - m_divider2, m_right_column == DASM_RIGHTCOL_ENCRYPTED);
		}
		else if (m_right_column == DASM_RIGHTCOL_COMMENTS)
		{
			// get and add the comment, if present
			const offs_t comment_address = source.m_space.byte_to_address(m_byteaddress[instr]);
			const char *const text = source.device()->debug()->comment_text(comment_address);
			if (text != nullptr)
				util::stream_format(m_dasm.seekp(base + m_divider2), "// %.*s", m_total.x - m_divider2 - 4, text);
		}
		m_dasm.put('\0');

		// see if the line changed at all
		if (lines == 1 && strncmp(oldbuf, &m_dasm.vec()[base], (std::min<std::size_t>)(sizeof(oldbuf), m_total.x)) != 0)
			changed = true;
	}

	// 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();

	// no longer need to recompute
	m_recompute = false;
	return changed;
}